Skip to content

Commit 4b72a04

Browse files
committed
* Basic concepts
1 parent b4b2e48 commit 4b72a04

11 files changed

Lines changed: 49 additions & 22 deletions

File tree

spreadsheet/chapter.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,37 @@ How many features can a Web application offer in 99 lines? Let’s see it in act
1616

1717
## Overview
1818

19-
The [spreadsheet](https://github.com/aosabook/500lines/tree/master/spreadsheet) directory contains our showcase for the latest evolution of the three languages: [HTML5](http://www.w3.org/TR/html5/) for structure, [CSS3](http://www.w3.org/TR/css3-ui/) for presentation, and the JS [ES6 “Harmony”](http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts) standard for interaction.
19+
The [spreadsheet](https://github.com/aosabook/500lines/tree/master/spreadsheet) directory contains our showcase for the latest evolution of the three languages: [HTML5](http://www.w3.org/TR/html5/) for structure, [CSS3](http://www.w3.org/TR/css3-ui/) for presentation, and the JS [ES6 “Harmony”](http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts) standard for interaction. We also use [Web Storage](http://www.whatwg.org/specs/web-apps/current-work/multipage/webstorage.html) for data persistence, and [Web Worker](http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html) for running JS code in the background. Since 2012, these web standards are supported by Firefox, Chrome, Internet Explorer 10+, as well as mobile browsers on iOS 5+ and Android 4+.
2020

21-
We also use [Web Storage](http://www.whatwg.org/specs/web-apps/current-work/multipage/webstorage.html) for data persistence, and [Web Worker](http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html) for running JS code in the background. Since 2012, these two web standards are supported by major browsers, such as Firefox, Chrome, Internet Explorer (version 10+), iOS Safari (version 5+) and Android Browser (version 4+).
21+
Now let’s open http://audreyt.github.io/500lines/spreadsheet/ in a browser:
2222

23-
Now let’s open <http://audreyt.github.io/500lines/spreadsheet/> in a browser:
23+
![Initial Screen](./images/01-initial.png)
2424

25-
![Initial Screen](http://user-image.logdown.io/user/6443/blog/6432/static_page/8659/Bx8iguS5mmVbkh3cuBiA_%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202014-06-08%20%E4%B8%8B%E5%8D%8812.03.58.png)
25+
### Basic Concepts
26+
27+
The _spreadsheet_ as shown on the screen is a grid that spans in two dimensions, with _columns_ starting from `A`, and _rows_ starting from `1`. Each _cell_ has a unique _coordinate_ (such as `A1`) and its _content_ (`1874`), which belongs to one of four _types_:
28+
29+
* Text: `+` in `B1` and `` in `D1`, aligned to the left.
30+
* Number: `1874` in `A1` and `2046` in `C1`, aligned to the right.
31+
* Formula: `=A1+C1` in `E1`, which _calculates_ to the _value_ `3920`, displayed with a light blue background.
32+
* Empty: All cells in row `2` are currently empty.
33+
34+
Click `3920` to set _focus_ on `E1`, revealing its formula in an _input box_:
35+
36+
![Input Box](./images/02-input.png)
37+
38+
Now let’s set focus on `A1` and _change_ its content to `1`, causing `E1` to _recalculate_ its value to `2047`:
39+
40+
![Changed Content](./images/03-changed.png)
41+
42+
Press `ENTER` to set focus to `A2` and change its content to `=Date()`, then press `TAB`, change the content of `B2` to `=alert()`, then press `TAB` again to set focus to `C2`:
43+
44+
![Formula Error](./images/04-error.png)
45+
46+
This shows that a formula may calculates to a number (`2047` in `E1`), a text (the current time in `A2`, aligned to the left), or an _error_ (red letters in`B2`, aligned to the center).
47+
48+
Next, let’s try entering `=for(;;){}`, the JS code for an infinite loop that never terminates. The spreadsheet will prevent us from entering that code, automatically _undo_ the edit after half a second has passed.
49+
50+
Now reload the page in the browser with `Ctrl-R` or `Cmd-R` to verify that the spreadsheet content is _persistent_, staying the same across browser sessions.
51+
52+
Finally, press the `` button on the top-left corner to _reset_ the spreadsheet to its original content.

spreadsheet/es5/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!DOCTYPE html><html><head><meta charset="utf-8">
22
<script src="main.js"></script>
3-
<script>if (!window.Spreadsheet) { location.href = "es5/index.html" }</script>
3+
<script>if (!window.Spreadsheet) { window.stop(); location.href = "es5/index.html" }</script>
44
<script src="worker.js"></script>
55
<script src="lib/angular.js"></script>
66
<link href="styles.css" rel="stylesheet">
@@ -12,7 +12,7 @@
1212
<th>{{ row }}</th>
1313
<td ng-repeat="col in Cols" ng-class="{ formula: ( '=' === sheet[col+row][0] ) }">
1414
<input id="{{ col+row }}" ng-model="sheet[col+row]" ng-change="calc()" ng-keydown="keydown($event, col, row)">
15-
<div ng-class="{ error: errs[col+row] }">{{ errs[col+row] || vals[col+row] }}&nbsp;</div>
15+
<div ng-class="{ error: errs[col+row], text: vals[col+row][0] }">{{ errs[col+row] || vals[col+row] }}&nbsp;</div>
1616
</td>
1717
</tr></table>
1818
</body></html>

spreadsheet/es5/main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,10 +2163,10 @@ window.Spreadsheet = (function($scope, $timeout) {
21632163
$scope.reset = (function() {
21642164
$scope.sheet = {
21652165
A1: 1874,
2166-
B1: '',
2166+
B1: '+',
21672167
C1: 2046,
21682168
D1: '⇒',
2169-
E1: '=A1*C1'
2169+
E1: '=A1+C1'
21702170
};
21712171
});
21722172
($scope.init = (function() {

spreadsheet/es5/styles.css

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
input {
2-
position: absolute; border: 0; padding: 0; width: 120px; height: 1.3em;
3-
font-size: 100%; color: transparent; background: transparent;
4-
}
1+
input { position: absolute; border: 0; padding: 0;
2+
width: 120px; height: 1.3em; font-size: 100%;
3+
color: transparent; background: transparent; }
54
input:focus { color: #111; background: #efe; }
65
input:focus + div { white-space: nowrap; }
76
table { border-collapse: collapse; }
8-
td div { width: 120px; overflow: hidden; text-overflow: ellipsis; }
9-
td div.error { color: #600; }
7+
td div { width: 120px; overflow: hidden; text-overflow: ellipsis; text-align: right }
8+
td div.text { text-align: left; }
9+
td div.error { color: #800; text-align: center; font-size: 90%; border: solid 1px #800 }
1010
td.formula { background: #eef; }
1111
th { width: 30px; background: #ddd; }
1212
td, th { border: 1px solid #ccc; }

spreadsheet/images/01-initial.png

19.4 KB
Loading

spreadsheet/images/02-input.png

19.8 KB
Loading

spreadsheet/images/03-changed.png

18.2 KB
Loading

spreadsheet/images/04-error.png

44.9 KB
Loading

spreadsheet/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<th>{{ row }}</th>
1313
<td ng-repeat="col in Cols" ng-class="{ formula: ( '=' === sheet[col+row][0] ) }">
1414
<input id="{{ col+row }}" ng-model="sheet[col+row]" ng-change="calc()" ng-keydown="keydown($event, col, row)">
15-
<div ng-class="{ error: errs[col+row] }">{{ errs[col+row] || vals[col+row] }}&nbsp;</div>
15+
<div ng-class="{ error: errs[col+row], text: vals[col+row][0] }">{{ errs[col+row] || vals[col+row] }}&nbsp;</div>
1616
</td>
1717
</tr></table>
1818
</body></html>

spreadsheet/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ window.Spreadsheet = ($scope, $timeout)=>{
1010
$scope.Rows = [ for (row of range( 1, 20 )) row ];
1111

1212
// Default sheet content, with some data cells and one formula cell.
13-
$scope.reset = ()=>{ $scope.sheet = { A1: 1874, B1: '', C1: 2046, D1: '⇒', E1: '=A1*C1' } };
13+
$scope.reset = ()=>{ $scope.sheet = { A1: 1874, B1: '+', C1: 2046, D1: '⇒', E1: '=A1+C1' } };
1414

1515
// Define the initializer, and immediately call it
1616
($scope.init = ()=>{

0 commit comments

Comments
 (0)