rufus-decision 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ function createHttpRequest () {
2
+ var fs = [
3
+ function () { return new XMLHttpRequest(); },
4
+ function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
5
+ function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
6
+ ];
7
+ for (var i = 0; i < fs.length; i++) {
8
+ try { var r = fs[i](); if (r) return r; } catch (e) { continue; }
9
+ }
10
+ }
11
+ function httpGet (uri) {
12
+ var req = createHttpRequest();
13
+ req.open('GET', uri, false); // asynchronous ? false
14
+ req.send(null); // no body
15
+ return req.responseText;
16
+ }
17
+ function httpPost(uri, data) {
18
+ var req = createHttpRequest();
19
+ req.open('POST', uri, false); // asynchronous ? false
20
+ //req.setRequestHeader('Content-Length', data.length); // utf ???
21
+ req.send(data);
22
+ return req.responseText;
23
+ }
@@ -0,0 +1,584 @@
1
+ /*
2
+ * Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ *
22
+ * Made in Japan.
23
+ */
24
+
25
+ var RuoteSheets = function() {
26
+
27
+ var DEFAULT_CELL_WIDTH = 150;
28
+
29
+ //
30
+ // MISC FUNCTIONS
31
+
32
+ function dwrite (msg) {
33
+ document.body.appendChild(document.createTextNode(msg));
34
+ document.body.appendChild(document.createElement('br'));
35
+ }
36
+
37
+ function findElt (i) {
38
+ if ((typeof i) == 'string') return document.getElementById(i);
39
+ else return i;
40
+ }
41
+
42
+ function createElement (parentNode, tag, klass, atts) {
43
+ var e = document.createElement(tag);
44
+ if (parentNode) parentNode.appendChild(e);
45
+ if (klass) e.setAttribute('class', klass);
46
+ if (atts) { for (k in atts) { e.setAttribute(k, atts[k]); } }
47
+ return e;
48
+ }
49
+
50
+ function addClass (elt, klass) {
51
+ elt.setAttribute('class', elt.getAttribute('class') + ' ' + klass);
52
+ }
53
+ function removeClass (elt, klass) {
54
+ // warning : naive on the right border (after word)
55
+ elt.setAttribute(
56
+ 'class', elt.getAttribute('class').replace(' ' + klass, ''));
57
+ }
58
+
59
+ function placeAfter (elt, newElt) {
60
+ var p = elt.parentNode;
61
+ var n = elt.nextSibling;
62
+ if (n) p.insertBefore(newElt, n);
63
+ else p.appendChild(newElt);
64
+ }
65
+
66
+ //
67
+ // EVENT HANDLERS
68
+
69
+ function cellOnFocus (evt) {
70
+ var e = evt || window.event;
71
+ var sheet = e.target.parentNode.parentNode;
72
+ unfocusSheet(sheet);
73
+ setCurrentCell(sheet, e.target);
74
+ }
75
+
76
+ function cellOnKeyDown (evt) {
77
+ var e = evt || window.event;
78
+ var cell = e.target;
79
+ if ( ! cell.previousValue) {
80
+ save(cell.parentNode.parentNode);
81
+ cell.previousValue = cell.value;
82
+ }
83
+ return true;
84
+ }
85
+
86
+ function cellOnKeyUp (evt) {
87
+ var e = evt || window.event;
88
+ var c = e.charCode || e.keyCode;
89
+ //alert("" + c + " / " + e.ctrlKey + " - " + e.altKey + " - " + e.shiftKey);
90
+ if (c == 38 || c == 40) move(e, c);
91
+ if (isCellEmpty(e.target) && (c == 37 || c == 39)) move(e, c);
92
+ return (c != 13);
93
+ }
94
+
95
+ function cellOnChange (evt) {
96
+ var e = evt || window.event;
97
+ e.target.previousValue = null; // cleaning
98
+ }
99
+
100
+ function handleOnMouseDown (evt) {
101
+ var e = evt || window.event;
102
+ var headcell = e.target.parentNode;
103
+ var headrow = headcell.parentNode;
104
+ var col = determineRowCol(headcell)[1];
105
+ headrow.down = [ e.target.parentNode, e.clientX, col ];
106
+ }
107
+
108
+ function rowOnMouseDown (evt) {
109
+
110
+ var e = evt || window.event;
111
+ var sheet = e.target.parentNode.parentNode;
112
+ sheet.mouseDownCell = e.target;
113
+ }
114
+
115
+ function rowOnMouseUp (evt) {
116
+
117
+ var e = evt || window.event;
118
+
119
+ var sheet = e.target.parentNode.parentNode;
120
+
121
+ var c0 = sheet.mouseDownCell;
122
+ if ( ! c0) return;
123
+
124
+ var c1 = findCellByCoordinates(sheet, e.clientX, e.clientY);
125
+ if ( ! c1) c1 = c0;
126
+
127
+ var rc0 = determineRowCol(c0);
128
+ var rc1 = determineRowCol(c1);
129
+ var minx = Math.min(rc0[1], rc1[1]);
130
+ var miny = Math.min(rc0[0], rc1[0]);
131
+ var maxx = Math.max(rc0[1], rc1[1]);
132
+ var maxy = Math.max(rc0[0], rc1[0]);
133
+
134
+ //dwrite('' + minx + '/' + miny + ' // ' + maxx + '/' + maxy);
135
+ iterate(sheet, function (t, x, y, e) {
136
+ if (t != 'cell') return false;
137
+ if (x < minx || x > maxx) return false;
138
+ if (y < miny || y > maxy) return false;
139
+ addClass(e, 'focused');
140
+ });
141
+ }
142
+
143
+ function getHeadRow (elt) {
144
+ var t = getRuseType(elt);
145
+ if (t == 'headcell') return getHeadRow(elt.parentNode);
146
+ if (t == 'headrow') return elt;
147
+ return null;
148
+ }
149
+
150
+ function handleOnMouseUp (evt) {
151
+
152
+ var e = evt || window.event;
153
+
154
+ var hr = getHeadRow(e.target);
155
+
156
+ if ( ! hr.down) return;
157
+
158
+ var d = e.clientX - hr.down[1];
159
+ var w = hr.down[0].offsetWidth + d;
160
+ if (w < 12) w = 12; // minimal width
161
+
162
+ save(hr.parentNode);
163
+
164
+ iterate(hr.parentNode, function (t, x, y, e) {
165
+ if ((t == 'cell' || t == 'headcell') && x == hr.down[2]) {
166
+ e.style.width = '' + w + 'px';
167
+ }
168
+ });
169
+ hr.down = null;
170
+ }
171
+
172
+ //
173
+ // ...
174
+
175
+ function unfocusSheet (sheet) {
176
+ iterate(sheet, function (t, x, y, e) {
177
+ if (t == 'cell') removeClass(e, 'focused');
178
+ });
179
+ }
180
+
181
+ function getCurrentCell (sheet) {
182
+
183
+ sheet = findElt(sheet);
184
+
185
+ if (( ! sheet.currentCell) ||
186
+ ( ! sheet.currentCell.parentNode) ||
187
+ ( ! sheet.currentCell.parentNode.parentNode)) {
188
+
189
+ sheet.currentCell = null;
190
+ return findCell(sheet, 0, 0);
191
+ }
192
+ return sheet.currentCell;
193
+ }
194
+
195
+ function setCurrentCell (sheet, cell) {
196
+
197
+ findElt(sheet).currentCell = cell;
198
+ }
199
+
200
+ function isCellEmpty (elt) {
201
+
202
+ return (elt.value == '');
203
+ }
204
+
205
+ function move (e, c) {
206
+
207
+ var rc = determineRowCol(e.target);
208
+ var row = rc[0]; var col = rc[1];
209
+
210
+ if (c == 38) row--;
211
+ else if (c == 40) row++;
212
+ else if (c == 37) col--;
213
+ else if (c == 39) col++;
214
+
215
+ var cell = findCell(e.target.parentNode.parentNode, row, col);
216
+
217
+ if (cell != null) {
218
+ cell.focus();
219
+ addClass(cell, 'focused'); // not using :focus
220
+ setCurrentCell(cell.parentNode.parentNode, cell);
221
+ }
222
+ }
223
+
224
+ function determineRowCol (elt) {
225
+
226
+ var cc = elt.getAttribute('class').split(' ');
227
+ return [ cc[1].split('_')[1], cc[2].split('_')[1] ];
228
+ }
229
+
230
+ function findRow (sheet, y) {
231
+ var row = iterate(sheet, function (t, x, yy, e) {
232
+ if (t == 'row' && yy == y) return e;
233
+ });
234
+ return row ? row[0] : null;
235
+ }
236
+
237
+ function findCell (sheet, y, x) {
238
+
239
+ var row = findRow(sheet, y);
240
+ if (row == null) return null;
241
+
242
+ for (var i = 0; i < row.childNodes.length; i++) {
243
+ var c = row.childNodes[i];
244
+ if (getRuseType(c) != 'cell') continue;
245
+ if (c.getAttribute('class').match(' column_' + x)) return c;
246
+ }
247
+ return null;
248
+ }
249
+
250
+ function computeColumns (data) {
251
+
252
+ var cols = 0;
253
+
254
+ for (var y = 0; y < data.length; y++) {
255
+ var row = data[y];
256
+ if (row.length > cols) cols = row.length;
257
+ }
258
+ return cols;
259
+ }
260
+
261
+ function getWidths (sheet) {
262
+ var widths = [];
263
+ iterate(sheet, function (t, x, y, e) {
264
+ if (t == 'headcell') widths.push(e.offsetWidth);
265
+ });
266
+ return widths;
267
+ }
268
+
269
+ function getRuseType (elt) {
270
+ if (elt.nodeType != 1) return false;
271
+ var c = elt.getAttribute('class');
272
+ if ( ! c) return false;
273
+ var m = c.match(/^ruse_([^ ]+)/);
274
+ return m ? m[1] : false;
275
+ }
276
+
277
+ function renderHeadCell (headrow, x, w) {
278
+
279
+ var c = createElement(headrow, 'div', 'ruse_headcell row_-1 column_' + x);
280
+
281
+ c.style.width = '' + (w || DEFAULT_CELL_WIDTH) + 'px';
282
+
283
+ createElement(c, 'div', 'ruse_headcell_left');
284
+
285
+ var handle = createElement(c, 'div', 'ruse_headcell_handle');
286
+ handle.onmousedown = handleOnMouseDown;
287
+
288
+ return c;
289
+ }
290
+
291
+ function renderHeadRow (sheet, widths, cols) {
292
+
293
+ var headrow = createElement(sheet, 'div', 'ruse_headrow');
294
+ headrow.onmouseup = handleOnMouseUp;
295
+
296
+ for (var x = 0; x < cols; x++) { renderHeadCell(headrow, x, widths[x]); }
297
+
298
+ createElement(headrow, 'div', null, { style: 'clear: both;' });
299
+ }
300
+
301
+ function createRow (sheet) {
302
+ var row = createElement(sheet, 'div', 'ruse_row');
303
+ row.onmousedown = rowOnMouseDown;
304
+ row.onmouseup = rowOnMouseUp;
305
+ return row;
306
+ }
307
+
308
+ function createCell (row, value, width) {
309
+
310
+ if (value == undefined) value = '';
311
+ if ((typeof value) != 'string') value = '' + value;
312
+
313
+ if ( ! width) width = DEFAULT_CELL_WIDTH;
314
+
315
+ var cell = createElement(row, 'input', 'ruse_cell');
316
+
317
+ cell.setAttribute('type', 'text');
318
+
319
+ cell.onkeydown = cellOnKeyDown;
320
+ cell.onkeyup = cellOnKeyUp;
321
+ cell.onfocus = cellOnFocus;
322
+ cell.onchange = cellOnChange;
323
+
324
+ cell.value = value;
325
+ cell.style.width = width + 'px';
326
+
327
+ return cell;
328
+ }
329
+
330
+ function render (sheet, data, widths) {
331
+
332
+ sheet = findElt(sheet);
333
+
334
+ while (sheet.firstChild) { sheet.removeChild(sheet.firstChild); }
335
+
336
+ if ( ! widths) {
337
+ widths = getWidths(sheet);
338
+ }
339
+ if ( ! widths) {
340
+ widths = [];
341
+ for (var x = 0; x < cols; x++) { widths.push(DEFAULT_CELL_WIDTH); }
342
+ }
343
+
344
+ sheet = findElt(sheet);
345
+
346
+ var rows = data.length;
347
+ var cols = computeColumns(data);
348
+
349
+ renderHeadRow(sheet, widths, cols);
350
+
351
+ for (var y = 0; y < rows; y++) {
352
+
353
+ var rdata = data[y];
354
+ var row = createRow(sheet);
355
+ for (var x = 0; x < cols; x++) { createCell(row, rdata[x], widths[x]); }
356
+ }
357
+
358
+ reclass(sheet);
359
+ }
360
+
361
+ function renderEmpty (container, rows, cols) {
362
+
363
+ container = findElt(container);
364
+
365
+ var data = [];
366
+ for (var y = 0; y < rows; y++) {
367
+ var row = [];
368
+ for (var x = 0; x < cols; x++) row.push('');
369
+ data.push(row);
370
+ }
371
+ render(container, data);
372
+ }
373
+
374
+ // exit if func returns something than is considered true
375
+ //
376
+ function iterate (sheet, func) {
377
+
378
+ sheet = findElt(sheet);
379
+
380
+ var y = 0;
381
+
382
+ for (var yy = 0; yy < sheet.childNodes.length; yy++) {
383
+
384
+ var e = sheet.childNodes[yy];
385
+
386
+ var rowType = getRuseType(e);
387
+ if ( ! rowType) continue;
388
+
389
+ var x = 0;
390
+
391
+ var r = func.call(null, rowType, x, y, e);
392
+ if (r) return [ r, rowType, x, y, e ];
393
+
394
+ for (var xx = 0; xx < e.childNodes.length; xx++) {
395
+
396
+ var ee = e.childNodes[xx];
397
+
398
+ var cellType = getRuseType(ee);
399
+ if ( ! cellType) continue;
400
+
401
+ var r = func.call(null, cellType, x, y, ee);
402
+ if (r) return [ r, cellType, x, y, ee ];
403
+
404
+ x++;
405
+ }
406
+ if (rowType == 'row') y++;
407
+ }
408
+ }
409
+
410
+ function findCellByCoordinates (sheet, x, y) { // mouse coordinates
411
+
412
+ var r = iterate(sheet, function (t, xx, yy, e) {
413
+
414
+ if (t != 'cell') return false;
415
+
416
+ var ex = e.offsetLeft; var ey = e.offsetTop;
417
+ var ew = ex + e.offsetWidth; var eh = ey + e.offsetHeight;
418
+ if (x < ex || x > ew) return false;
419
+ if (y < ey || y > eh) return false;
420
+
421
+ return e;
422
+ });
423
+
424
+ return r ? r[0] : null;
425
+ }
426
+
427
+ function countRows (sheet) {
428
+ return toArray(sheet).length;
429
+ }
430
+
431
+ function countCols (sheet) {
432
+ return (toArray(sheet)[0] || []).length;
433
+ }
434
+
435
+ function reclass (sheet) {
436
+ iterate(sheet, function (t, x, y, e) {
437
+ if (t == 'row')
438
+ e.setAttribute('class', 'ruse_row row_' + y);
439
+ else if (t == 'cell')
440
+ e.setAttribute('class', 'ruse_cell row_' + y + ' column_' + x);
441
+ else if (t == 'headcell')
442
+ e.setAttribute('class', 'ruse_headcell row_-1 column_' + x);
443
+ });
444
+ }
445
+
446
+ function toArray (sheet) {
447
+
448
+ var a = [];
449
+ var row = null;
450
+
451
+ iterate(sheet, function (t, x, y, e) {
452
+ if (t == 'row') { row = []; a.push(row); }
453
+ else if (t == 'cell') { row.push(e.value); }
454
+ });
455
+
456
+ return a;
457
+ }
458
+
459
+ function focusedToArray (sheet) {
460
+ var a = [];
461
+ var r = null;
462
+ iterate(sheet, function (t, x, y, e) {
463
+ if (t == 'row') { r = []; a.push(r); }
464
+ if (t != 'cell') return false;
465
+ if (e.getAttribute('class').match(/ focused/)) r.push(e.value);
466
+ });
467
+ var aa = [];
468
+ for (var y = 0; y < a.length; y++) {
469
+ var row = a[y];
470
+ if (row.length > 0) aa.push(row);
471
+ }
472
+ return aa;
473
+ }
474
+
475
+ function currentCol (sheet, col) {
476
+ if (col == undefined) {
477
+ var cell = getCurrentCell(sheet);
478
+ col = determineRowCol(cell)[1];
479
+ }
480
+ return col;
481
+ }
482
+
483
+ function currentRow (sheet, row) {
484
+ if (row == undefined) {
485
+ var cell = getCurrentCell(sheet);
486
+ return cell.parentNode;
487
+ }
488
+ return findRow(sheet, row);
489
+ }
490
+
491
+ function addRow (sheet, row) {
492
+
493
+ save(sheet);
494
+
495
+ row = currentRow(sheet, row);
496
+ var cols = countCols(sheet);
497
+ var newRow = createRow(null);
498
+ var widths = getWidths(sheet);
499
+ placeAfter(row, newRow);
500
+ for (var x = 0; x < cols; x++) { createCell(newRow, '', widths[x]); }
501
+ reclass(sheet);
502
+ }
503
+
504
+ function addCol (sheet, col) {
505
+
506
+ save(sheet);
507
+
508
+ col = currentCol(sheet, col);
509
+
510
+ var cells = [];
511
+ iterate(sheet, function (t, x, y, e) {
512
+ if ((t == 'cell' || t == 'headcell') && x == col) cells.push(e);
513
+ });
514
+ var headcell = cells[0];
515
+ var newHeadCell = renderHeadCell(headcell.parentNode, col);
516
+ placeAfter(headcell, newHeadCell);
517
+ for (var y = 1; y < cells.length; y++) {
518
+ var cell = cells[y];
519
+ var newCell = createCell(cell.parentNode, '');
520
+ placeAfter(cell, newCell);
521
+ }
522
+ reclass(sheet);
523
+ }
524
+
525
+ function deleteCol (sheet, col) {
526
+
527
+ if (countCols(sheet) <= 1) return;
528
+
529
+ save(sheet);
530
+
531
+ col = currentCol(sheet, col);
532
+ var cells = [];
533
+ iterate(sheet, function (t, x, y, e) {
534
+ if ((t == 'cell' || t == 'headcell') && x == col) cells.push(e);
535
+ });
536
+ for (var y = 0; y < cells.length; y++) {
537
+ var cell = cells[y];
538
+ cell.parentNode.removeChild(cell);
539
+ }
540
+ reclass(sheet);
541
+ }
542
+
543
+ function deleteRow (sheet, row) {
544
+
545
+ if (countRows(sheet) <= 1) return;
546
+
547
+ save(sheet);
548
+
549
+ var forgetCurrent = (row == undefined);
550
+ row = currentRow(sheet, row);
551
+ row.parentNode.removeChild(row);
552
+ reclass(sheet);
553
+ if (forgetCurrent) setCurrentCell(sheet, null);
554
+ }
555
+
556
+ function save (sheet) {
557
+ sheet = findElt(sheet);
558
+ if ( ! sheet.stack) sheet.stack = [];
559
+ sheet.stack.push([ toArray(sheet), getWidths(sheet) ]);
560
+ while (sheet.stack.length > 100) { sheet.stack.shift(); }
561
+ }
562
+
563
+ function undo (sheet) {
564
+ sheet = findElt(sheet);
565
+ if ( ! sheet.stack || sheet.stack.length < 1) return;
566
+ var state = sheet.stack.pop();
567
+ render(sheet, state[0], state[1]);
568
+ }
569
+
570
+ return { // the 'public' stuff
571
+
572
+ render: render,
573
+ renderEmpty: renderEmpty,
574
+ addRow: addRow,
575
+ addCol: addCol,
576
+ deleteRow: deleteRow,
577
+ deleteCol: deleteCol,
578
+ undo: undo,
579
+ toArray: toArray, // returns the current table as a JS array
580
+ getWidths: getWidths, // returns the current widths (a JS array)
581
+ focusedToArray: focusedToArray,
582
+ };
583
+ }();
584
+