scms 1.7.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +0 -0
  3. data/assets/blank-app-template/application.xml +57 -0
  4. data/assets/blank-app-template/cert.p12 +0 -0
  5. data/assets/blank-app-template/config.yml +32 -0
  6. data/assets/blank-app-template/debug.cmd +6 -0
  7. data/assets/blank-app-template/package.cmd +16 -0
  8. data/assets/blank-app-template/public/ico/favicon.ico +0 -0
  9. data/assets/blank-app-template/public/ico/logo-128.png +0 -0
  10. data/assets/blank-app-template/public/ico/logo-16.png +0 -0
  11. data/assets/blank-app-template/public/ico/logo-32.png +0 -0
  12. data/assets/blank-app-template/public/ico/logo-48.png +0 -0
  13. data/assets/blank-app-template/public/images/glyphicons-halflings-white.png +0 -0
  14. data/assets/blank-app-template/public/images/glyphicons-halflings.png +0 -0
  15. data/assets/blank-app-template/public/robots.txt +4 -0
  16. data/assets/blank-app-template/public/scripts/air/AIRAliases.js +240 -0
  17. data/assets/blank-app-template/public/scripts/air/AIRIntrospector.js +1949 -0
  18. data/assets/blank-app-template/public/scripts/air/AIRMenuBuilder.js +1322 -0
  19. data/assets/blank-app-template/public/scripts/air/applicationupdater.swf +0 -0
  20. data/assets/blank-app-template/public/scripts/air/applicationupdater_ui.swf +0 -0
  21. data/assets/blank-app-template/public/scripts/air/servicemonitor.swf +0 -0
  22. data/assets/blank-app-template/public/scripts/libs/bootstrap.js +2027 -0
  23. data/assets/blank-app-template/public/scripts/libs/jquery-1.8.2.min.js +2 -0
  24. data/assets/blank-app-template/public/scripts/libs/jquery.fn.custom.js +67 -0
  25. data/assets/blank-app-template/public/scripts/libs/knockout-2.1.0-min.js +86 -0
  26. data/assets/blank-app-template/public/scripts/presenters/dashboard-presenter.js +3 -0
  27. data/assets/blank-app-template/public/scripts/presenters/global-presenter.js +8 -0
  28. data/assets/blank-app-template/public/scripts/shared/data-persistance.js +22 -0
  29. data/assets/blank-app-template/public/scripts/shared/utils.js +107 -0
  30. data/assets/blank-app-template/public/stylesheets/bootstrap-responsive.css +1058 -0
  31. data/assets/blank-app-template/public/stylesheets/bootstrap.css +5774 -0
  32. data/assets/blank-app-template/public/stylesheets/style.css +0 -0
  33. data/assets/blank-app-template/s3config.template.yml +9 -0
  34. data/assets/blank-app-template/templates/menu.xml +5 -0
  35. data/assets/blank-app-template/templates/skin.erb.html +84 -0
  36. data/assets/blank-app-template/tools/msxsl.exe +0 -0
  37. data/assets/blank-app-template/tools/update-descriptor.xsl +18 -0
  38. data/assets/blank-app-template/tools/version.xsl +10 -0
  39. data/assets/blank-app-template/views/about.html +15 -0
  40. data/assets/blank-app-template/views/dashboard.html +7 -0
  41. data/assets/blank-template/config.yml +30 -0
  42. data/assets/blank-template/public/images/glyphicons-halflings-white.png +0 -0
  43. data/assets/blank-template/public/images/glyphicons-halflings.png +0 -0
  44. data/assets/blank-template/public/robots.txt +4 -0
  45. data/assets/blank-template/public/scripts/air-monkey-hook.js +63 -0
  46. data/assets/blank-template/public/scripts/bootstrap.js +2027 -0
  47. data/assets/blank-template/public/scripts/jquery-1.8.2.min.js +2 -0
  48. data/assets/blank-template/public/scripts/script.js +0 -0
  49. data/assets/blank-template/public/stylesheets/bootstrap-responsive.css +1058 -0
  50. data/assets/blank-template/public/stylesheets/bootstrap.css +5774 -0
  51. data/assets/blank-template/public/stylesheets/style.css +0 -0
  52. data/assets/blank-template/s3config.template.yml +10 -0
  53. data/assets/blank-template/templates/menu.xml +5 -0
  54. data/assets/blank-template/templates/skin.erb.html +108 -0
  55. data/assets/blank-template/views/about-intro.html +1 -0
  56. data/assets/blank-template/views/about-main.html +2 -0
  57. data/assets/blank-template/views/home-intro.html +3 -0
  58. data/assets/blank-template/views/home-main.html +15 -0
  59. data/assets/mime.types +68 -0
  60. data/bin/scms +127 -0
  61. data/lib/scms.rb +426 -0
  62. data/lib/scms/s3deploy.rb +45 -0
  63. data/lib/scms/scms_utils.rb +73 -0
  64. data/lib/scms/version.rb +3 -0
  65. data/scms.gemspec +24 -0
  66. data/scripts/build.bat +4 -0
  67. data/staticcms.sublime-project +8 -0
  68. data/staticcms.sublime-workspace +417 -0
  69. metadata +180 -0
@@ -0,0 +1,1322 @@
1
+ /* AIRMenuBuilder.js - Revision: 1.5 */
2
+
3
+ /*
4
+ ADOBE SYSTEMS INCORPORATED
5
+ Copyright 2007-2008 Adobe Systems Incorporated. All Rights Reserved.
6
+
7
+ NOTICE: Adobe permits you to modify and distribute this file only in accordance with
8
+ the terms of Adobe AIR SDK license agreement. You may have received this file from a
9
+ source other than Adobe. Nonetheless, you may modify or
10
+ distribute this file only in accordance with such agreement.
11
+ */
12
+
13
+ (function AIRMenuBuilder () {
14
+
15
+ function constructor ( ) {
16
+ window ['air'] = window ['air'] || {};
17
+ window.air['ui'] = window.air['ui'] || {};
18
+ window.air.ui['Menu'] = new Menu();
19
+ registry = new FieldsRegistry();
20
+ currentOS = runtime.flash.system.Capabilities.os;
21
+ }
22
+
23
+ var currentOS = null;
24
+ var registry = null;
25
+
26
+ var File = runtime.flash.filesystem.File;
27
+ var FileStream = runtime.flash.filesystem.FileStream;
28
+ var FileMode = runtime.flash.filesystem.FileMode;
29
+ var NativeMenu = runtime.flash.display.NativeMenu;
30
+ var NativeMenuItem = runtime.flash.display.NativeMenuItem;
31
+ var SELECT = runtime.flash.events.Event.SELECT;
32
+ var KEYBOARD = runtime.flash.ui.Keyboard;
33
+ var COMPLETE = runtime.flash.events.Event.COMPLETE;
34
+ var IO_ERROR = runtime.flash.events.IOErrorEvent.IO_ERROR;
35
+ var NativeApplication = runtime.flash.desktop.NativeApplication;
36
+ var NativeWindow = runtime.flash.display.NativeWindow;
37
+ var Loader = runtime.flash.display.Loader;
38
+ var URLRequest = runtime.flash.net.URLRequest;
39
+ var BitmapData = runtime.flash.display.BitmapData;
40
+
41
+ /**
42
+ * CLASS FieldsRegistry
43
+ * @class
44
+ * @private
45
+ */
46
+ function FieldsRegistry () {
47
+
48
+ this.proof = function (name, value) {
49
+ if (!validateName(name)) { return null };
50
+ switch (name) {
51
+ case FieldsRegistry.ENABLED:
52
+ case FieldsRegistry.ALT_KEY:
53
+ case FieldsRegistry.SHIFT_KEY:
54
+ case FieldsRegistry.CMD_KEY:
55
+ case FieldsRegistry.CTRL_KEY:
56
+ case FieldsRegistry.TOGGLED:
57
+ case FieldsRegistry.DEFAULT_KEY:
58
+ return (typeof value == 'boolean')?
59
+ value: (typeof value == 'string')?
60
+ (value.toLowerCase() == 'false')? false :
61
+ true : getDefault (name);
62
+ case FieldsRegistry.KEY_EQUIVALENT:
63
+ var d;
64
+ return (typeof value == 'string')?
65
+ (value.length == 1)? value :
66
+ getDefault (name) : getDefault (name);
67
+ case FieldsRegistry.LABEL:
68
+ return (typeof value == 'string')?
69
+ (value.length != 0)? value:
70
+ getDefault (name) : getDefault (name);
71
+ case FieldsRegistry.MNEMONIC_INDEX:
72
+ var n;
73
+ return (typeof value == 'number')?
74
+ value: (typeof value == 'string')?
75
+ (!isNaN ( n = parseInt(value) ))? n :
76
+ getDefault (name) : getDefault (name);
77
+ case FieldsRegistry.TYPE:
78
+ return (typeof value == 'string') ?
79
+ (validateType(value))? value :
80
+ getDefault (name) : getDefault (name);
81
+ case FieldsRegistry.ON_SELECT:
82
+ var f;
83
+ return (typeof value == 'function')?
84
+ value : (typeof value == 'string')?
85
+ (typeof (f = window[value]) == 'function')?
86
+ f : getDefault (name) : getDefault (name);
87
+ }
88
+ }
89
+
90
+ this.iterateFields = function (callback, scope) {
91
+ var f, n, fr = FieldsRegistry;
92
+ for (f in fr) {
93
+ n = fr [f] !== fr.prototype? fr [f] : null;
94
+ if (n && !validateType(n)) {
95
+ callback.call ( scope || window, n )
96
+ };
97
+ }
98
+ }
99
+
100
+ var validateType = function (type) {
101
+ return type == FieldsRegistry.REGULAR ||
102
+ type == FieldsRegistry.SEPARATOR ||
103
+ type == FieldsRegistry.CHECK;
104
+ }
105
+
106
+ var validateName = function (fieldName) {
107
+ for (var f in FieldsRegistry) {
108
+ if (FieldsRegistry[f] == fieldName) { return true };
109
+ }
110
+ return false;
111
+ }
112
+
113
+
114
+ var getDefault = function (fieldName) {
115
+ switch (fieldName) {
116
+ case FieldsRegistry.ALT_KEY:
117
+ case FieldsRegistry.SHIFT_KEY:
118
+ case FieldsRegistry.TOGGLED:
119
+ return false;
120
+ case FieldsRegistry.ENABLED:
121
+ case FieldsRegistry.DEFAULT_KEY:
122
+ return true;
123
+ case FieldsRegistry.KEY_EQUIVALENT:
124
+ case FieldsRegistry.ON_SELECT:
125
+ return null;
126
+ case FieldsRegistry.LABEL:
127
+ return ' ';
128
+ case FieldsRegistry.MNEMONIC_INDEX:
129
+ return -1;
130
+ case FieldsRegistry.TYPE:
131
+ return FieldsRegistry.REGULAR;
132
+ case FieldsRegistry.CMD_KEY:
133
+ case FieldsRegistry.CTRL_KEY:
134
+ default:
135
+ return null;
136
+ }
137
+ }
138
+
139
+ }
140
+ FieldsRegistry.ALT_KEY = 'altKey';
141
+ FieldsRegistry.CMD_KEY = 'cmdKey';
142
+ FieldsRegistry.CTRL_KEY = 'ctrlKey';
143
+ FieldsRegistry.ENABLED = 'enabled';
144
+ FieldsRegistry.KEY_EQUIVALENT = 'keyEquivalent';
145
+ FieldsRegistry.LABEL = 'label';
146
+ FieldsRegistry.MNEMONIC_INDEX = 'mnemonicIndex';
147
+ FieldsRegistry.SHIFT_KEY = 'shiftKey';
148
+ FieldsRegistry.TOGGLED = 'toggled';
149
+ FieldsRegistry.TYPE = 'type';
150
+ FieldsRegistry.ON_SELECT = 'onSelect';
151
+ FieldsRegistry.DEFAULT_KEY = 'defaultKeyEquivalentModifiers';
152
+ FieldsRegistry.SEPARATOR = 'separator';
153
+ FieldsRegistry.CHECK = 'check';
154
+ FieldsRegistry.REGULAR = 'regular';
155
+
156
+ /**
157
+ * CLASS Menu
158
+ * Description
159
+ * Loads a user menu defined as XML or JSON, and sets it as one of the
160
+ * supported menu types.
161
+ * @class
162
+ * @author ciacob
163
+ */
164
+ function Menu() {
165
+
166
+ var buildMenu = function (source, type) {
167
+ var b = new Builder();
168
+ b.loadData (source, type);
169
+ return b.build();
170
+ }
171
+
172
+ var attachMenu = function (menu, type, target, icons) {
173
+ var s = new Shell();
174
+ s.link(menu, type, target, icons);
175
+ }
176
+
177
+ /**
178
+ * Load a menu defined in XML format.
179
+ * @param source
180
+ * An object containing XML menu(s) to be loaded for various OS-es.
181
+ * @return
182
+ * A NativeMenu object built from the given XML source.
183
+ */
184
+ this.createFromXML = function ( source ) {
185
+ return buildMenu ( source, Builder.XML );
186
+ }
187
+
188
+ /**
189
+ * Same as air.ui.Menu.fromXML, except it handles JSON data.
190
+ */
191
+ this.createFromJSON = function ( source ) {
192
+ return buildMenu ( source, Builder.JSON );
193
+ }
194
+
195
+ /**
196
+ * - on Windows: sets the given nativeMenu object as the NativeWindow's
197
+ * menu;
198
+ * - on Mac: inserts the items of the given nativeMenu object between
199
+ * the 'Edit' and 'Window' default menus;
200
+ * @param nativeMenu
201
+ * A NativeMenu returned by one of the air.ui.Menu.from...
202
+ * functions.
203
+ * @param overwrite
204
+ * A boolean that will change the behavior on Mac. If true, the
205
+ * default menus will be replaced entirely by the given nativeMenu
206
+ */
207
+ this.setAsMenu = function ( nativeMenu, overwrite ) {
208
+ if (!arguments.length) {
209
+ throw (new Error(
210
+ "No argument given for the 'setAsMenu()' method."
211
+ ));
212
+ }
213
+ var style = overwrite? Shell.MENU | Shell.OVERWRITE : Shell.MENU;
214
+ attachMenu (nativeMenu, style);
215
+ }
216
+
217
+ /**
218
+ * Displays the given menu as a contextual menu when the user right
219
+ * clicks a certain DOM element.
220
+ * @param nativeMenu
221
+ * A NativeMenu returned by one of the air.ui.Menu.from...
222
+ * functions.
223
+ * @param domElement
224
+ * The DOM Element to link with the given nativeMenu. The
225
+ * contextual menu will only show when the user right clicks over
226
+ * domElement. This attribute is optional. If missing, the context
227
+ * menu will display on every right-click over the application.
228
+ */
229
+ this.setAsContextMenu = function ( nativeMenu, domElement ) {
230
+ if (!arguments.length) {
231
+ throw (new Error(
232
+ "No argument given for the 'setAsContextMenu()' method."
233
+ ));
234
+ }
235
+ if (arguments.length < 2) { domElement = Shell.UNSPECIFIED };
236
+ attachMenu (nativeMenu, Shell.CONTEXT, domElement);
237
+ }
238
+
239
+ /**
240
+ * Sets the given nativeMenu as the
241
+ * ''NativeApplication.nativeApplication.icon.menu'' property.
242
+ * @param nativeMenu
243
+ * A NativeMenu returned by one of the air.ui.Menu.from...
244
+ * functions.
245
+ * @param icons
246
+ * An array holding icon file paths or bitmap data objects.
247
+ * If specified, these will be used as the application's
248
+ * tray/dock icons.
249
+ * @throws
250
+ * If no bitmap data was set for the ''icon'' object and no default
251
+ * icons are specified in the application descriptor.
252
+ */
253
+ this.setAsIconMenu = function ( nativeMenu, icons ) {
254
+ if (!arguments.length) {
255
+ throw (new Error(
256
+ "No argument given for the 'setAsIconMenu()' method."
257
+ ));
258
+ }
259
+ attachMenu (nativeMenu, Shell.ICON, null, icons);
260
+ }
261
+
262
+ }
263
+
264
+ /**
265
+ * CLASS DataSource
266
+ * @public
267
+ * @abstract
268
+ */
269
+ function DataSource() {
270
+ var _this = this;
271
+
272
+ var legalExtensions = ['xml', 'js'];
273
+
274
+ var rSeed = null;
275
+
276
+ var DATA_OBJECT = 1;
277
+ var INLINE_STRING = 2;
278
+ var FILE_PATH = 3;
279
+ var FILE_OBJECT = 4;
280
+ var ILLEGAL_TYPE = 5;
281
+
282
+ function getFileContent (file) {
283
+ var ret = '';
284
+ var fileStream = new FileStream();
285
+ fileStream.open(file, FileMode.READ);
286
+ try {
287
+ ret = fileStream.readUTFBytes(file.size);
288
+ } catch(e) {
289
+ throw(
290
+ new Error(["Error\n", "ID: ", e.errorID, "\n", "Message: ",
291
+ e.message, "\n"].join(''))
292
+ );
293
+ }
294
+ fileStream.close();
295
+ return ret;
296
+ }
297
+
298
+ function checkExtension (url, whiteList) {
299
+ var match = url.match(/\.([^\.]*)$/);
300
+ var extension = match? match[1] : null;
301
+ for(var i=0; i<whiteList.length; i++) {
302
+ if (whiteList[i] == extension) {
303
+ return true;
304
+ }
305
+ }
306
+ return false;
307
+ }
308
+
309
+ function sniffSource(src) {
310
+ if (typeof src == "object") {
311
+ if (src.constructor === (new File()).constructor) {
312
+ return FILE_OBJECT;
313
+ }
314
+ if (src.nodeType && src.nodeType == src.DOCUMENT_NODE) {
315
+ return DATA_OBJECT;
316
+ }
317
+ }
318
+ if (typeof src == "string") {
319
+ if (checkExtension(src, legalExtensions)) {
320
+ return FILE_PATH;
321
+ }
322
+ return INLINE_STRING;
323
+ }
324
+ return ILLEGAL_TYPE;
325
+ }
326
+
327
+ this.document = null;
328
+
329
+ this.type = null;
330
+
331
+ this.$DataSource = function(rawSource) {
332
+ if(rawSource) {
333
+ var srcType = sniffSource(rawSource);
334
+ if (srcType == ILLEGAL_TYPE) {
335
+ throw (new Error(['Could not instantiate DataSource class:',
336
+ 'An illegal data was provided. Legal types are:',
337
+ '- JavaScript Object',
338
+ '- Inline JSON or XML String',
339
+ '- *.XML or *.JS app root-relative file path',
340
+ '- flash.filesystem.File object, pointing to the above'
341
+ ].join('\n')));
342
+ }
343
+ var parsableCnt = _this.getParsableContent(rawSource, srcType);
344
+ if (srcType != DATA_OBJECT) {
345
+ this.parseContent(parsableCnt);
346
+ } else {
347
+ this.document = parsableCnt;
348
+ }
349
+ } else {
350
+ throw (new Error(['Could not instantiate DataSource class:',
351
+ 'Data provided is null.'].join(' ')));
352
+ }
353
+ }
354
+
355
+ this.getParsableContent = function (rawSource, sourceType) {
356
+ var url = null;
357
+ switch (sourceType) {
358
+ case DATA_OBJECT:
359
+ case INLINE_STRING:
360
+ return rawSource;
361
+ case FILE_OBJECT:
362
+ url = rawSource.url;
363
+ case FILE_PATH:
364
+ if (!url) { url = rawSource };
365
+ var localFile = Shell.resolve(url);
366
+ if (!localFile.exists) {
367
+ throw (new Error([
368
+ 'Could not instantiate DataSource class.',
369
+ 'Could not resolve this path:', url
370
+ ].join('\n')));
371
+ return null;
372
+ }
373
+ var cnt = getFileContent(localFile);
374
+ return cnt;
375
+ }
376
+ }
377
+
378
+ this.generateUID = function() {
379
+ if (!rSeed) {
380
+ var r = Math.floor(Math.random() * 1e5);
381
+ rSeed = r;
382
+ return ['id', r].join('');
383
+ }
384
+ var add = Math.floor(Math.random() * 10) + 1;
385
+ rSeed += add;
386
+ return ['id', rSeed].join('');
387
+ }
388
+
389
+ this.getSummary = function (node) {
390
+ var ret = {};
391
+ var func = function (fieldName) {
392
+ ret[fieldName] = this.getProperty (node, fieldName);
393
+ }
394
+ registry.iterateFields (func, this);
395
+ return ret;
396
+ }
397
+
398
+ this.parseContent = function (content) {
399
+ // subclass must overwrite;
400
+ }
401
+
402
+ this.getRoot = function() {
403
+ // subclass must overwrite;
404
+ }
405
+
406
+ this.getChildren = function(node) {
407
+ // subclass must overwrite;
408
+ }
409
+
410
+ this.getNextSibling = function(node) {
411
+ // subclass must overwrite;
412
+ }
413
+
414
+ this.getParent = function(node) {
415
+ // subclass must overwrite;
416
+ }
417
+
418
+ this.hasChildren = function(node) {
419
+ // subclass must overwrite;
420
+ }
421
+
422
+ this.addChildAt = function(node, newChild, index) {
423
+ // subclass must overwrite;
424
+ }
425
+
426
+ this.removeChildAt = function(node, index) {
427
+ // subclass must overwrite;
428
+ }
429
+
430
+ this.createNode = function(node, index) {
431
+ // subclass must overwrite;
432
+ }
433
+
434
+ this.getProperty = function(node, propName) {
435
+ // subclass must overwrite;
436
+ }
437
+
438
+ this.setProperty = function(node, propName, propValue) {
439
+ // subclass must overwrite;
440
+ }
441
+ }
442
+
443
+ /**
444
+ * CLASS XMLDataSource inherits DataSource
445
+ * @private
446
+ * @class
447
+ */
448
+ function XMLDataSource() {
449
+
450
+ this.__proto__ = new DataSource();
451
+
452
+ this.$XMLDataSource = function (rawSource) {
453
+ this.__proto__.$DataSource.call (this.__proto__, rawSource);
454
+ that.type = Builder.XML;
455
+ }
456
+
457
+ var that = this.__proto__;
458
+
459
+ that.parseContent = function (content) {
460
+ if (content) {
461
+ var p = new DOMParser();
462
+ var doc = p.parseFromString(content, "text/xml");
463
+ var err = 'parsererror';
464
+ var r = doc.documentElement;
465
+ var isError = (r.nodeName == err) ||
466
+ (doc.getElementsByTagName(err).length > 0);
467
+ if (isError) {
468
+ var errText = doc.getElementsByTagName(err)[0].innerText;
469
+ var msg = errText.split(':');
470
+ msg.length -= 1;
471
+ msg = msg.join(':\n');
472
+ throw (new Error ([
473
+ 'Could not parse data: malformed XML file.', msg
474
+ ].join('\n')));
475
+ }
476
+ that.document = doc;
477
+ }
478
+ }
479
+
480
+ that.getRoot = function() {
481
+ return that.document.documentElement;
482
+ }
483
+
484
+ that.getChildren = function (node) {
485
+ var ret = [];
486
+ if(node) {
487
+ if(node.hasChildNodes && node.hasChildNodes()){
488
+ var children = node.childNodes;
489
+ for(var i=0; i<children.length; i++) {
490
+ var child = children.item(i);
491
+ if(child.nodeType == child.ELEMENT_NODE) {
492
+ if (that.getProperty (child, 'id') == null) {
493
+ that.setProperty (child, 'id',
494
+ that.generateUID());
495
+ }
496
+ ret.push(child);
497
+ }
498
+ }
499
+ }
500
+ }
501
+ return ret;
502
+ }
503
+
504
+ that.getNextSibling = function (node) {
505
+ if(node) {
506
+ var checkIfLegalType = function(el) {
507
+ return (el.nodeType == el.ELEMENT_NODE);
508
+ }
509
+ var isLegalType = checkIfLegalType(node);
510
+ if(isLegalType) {
511
+ var testNode = node;
512
+ while(testNode = testNode.nextSibling) {
513
+ var isNextLegal = checkIfLegalType(testNode);
514
+ if(isNextLegal) { return testNode };
515
+ }
516
+ }
517
+ }
518
+ return null;
519
+ }
520
+
521
+ that.getParent = function (node) {
522
+ if(node) {
523
+ var isLegalType = (node.nodeType == node.ELEMENT_NODE);
524
+ if(isLegalType) {
525
+ if (node === that.getRoot()) { return null };
526
+ // make it headless, to accommodate the JSON
527
+ if (node.parentNode === that.getRoot()) { return null };
528
+ return node.parentNode;
529
+ }
530
+ }
531
+ return null;
532
+ }
533
+
534
+ that.hasChildren = function (node) {
535
+ if (node && (node.nodeType == node.ELEMENT_NODE)) {
536
+ if(!node.hasChildNodes()) { return false };
537
+ var childElements = node.getElementsByTagName('*');
538
+ if (childElements.length) { return true };
539
+ }
540
+ return null;
541
+ }
542
+
543
+ that.addChildAt = function (node, newChild, index) {
544
+ if (node && newChild && (typeof index != "undefined")) {
545
+ var nodeIsLegal = node.nodeType &&
546
+ (node.nodeType == node.ELEMENT_NODE);
547
+ var newIsLegal = newChild.nodeType &&
548
+ (newChild.nodeType == newChild.ELEMENT_NODE);
549
+ var indexIsLegal = !isNaN(parseInt(index));
550
+ if (nodeIsLegal && newIsLegal && indexIsLegal) {
551
+ var children = that.getChildren(node);
552
+ index = Math.min(Math.max(0, index), children.length);
553
+ var refNode = children [index+1] || null;
554
+ var success = false;
555
+ try {
556
+ node.insertBefore (newChild, refNode);
557
+ success = true;
558
+ } catch (e) {
559
+ throw ( new Error([
560
+ 'Could not add new child. A DOM error has occured:',
561
+ e.message
562
+ ].join('\n')) );
563
+ }
564
+ return success;
565
+ }
566
+ }
567
+ return null;
568
+ }
569
+
570
+ that.removeChildAt = function (node, index) {
571
+ if (node && (typeof index!= "undefined")) {
572
+ var nodeIsLegal = node.nodeType &&
573
+ (node.nodeType == node.ELEMENT_NODE);
574
+ var indexIsLegal = !isNaN(parseInt(index));
575
+ if (nodeIsLegal && indexIsLegal) {
576
+ var children = that.getChildren(node);
577
+ index = Math.min(Math.max(0, index), children.length-1);
578
+ try {
579
+ return node.removeChild (children[index]);
580
+ } catch (e) {
581
+ throw ( new Error([
582
+ 'Could not remove child. A DOM error has occured:',
583
+ e.message
584
+ ].join('\n')) );
585
+ }
586
+ }
587
+ }
588
+ return null;
589
+ }
590
+
591
+ that.createNode = function (properties) {
592
+ var node = that.document.createElement('menuItem');
593
+ for (var p in properties) {
594
+ that.setProperty (node, p, properties[p])
595
+ }
596
+ if (that.getProperty (node, 'id') == null) {
597
+ that.setProperty (node, 'id', that.generateUID());
598
+ }
599
+ return node;
600
+ }
601
+
602
+
603
+
604
+ that.getProperty = function (node, propName) {
605
+ if (node) {
606
+ var nodeIsLegal = node.nodeType &&
607
+ (node.nodeType == node.ELEMENT_NODE);
608
+ if (nodeIsLegal) {
609
+ return registry.proof(propName, node.getAttribute(propName));
610
+ }
611
+ }
612
+ return null;
613
+ }
614
+
615
+ that.setProperty = function (node, propName, propValue) {
616
+ if (node) {
617
+ var nodeIsLegal = node.nodeType &&
618
+ (node.nodeType == node.ELEMENT_NODE);
619
+ if (nodeIsLegal) {
620
+ var val = registry.proof(propName, propValue);
621
+ node.setAttribute(propName, val);
622
+ }
623
+ }
624
+ }
625
+
626
+ this.$XMLDataSource.apply (this, arguments);
627
+ }
628
+
629
+ /**
630
+ * CLASS JSONDataSource inherits DataSource
631
+ * @private
632
+ * @class
633
+ */
634
+ function JSONDataSource() {
635
+
636
+ this.__proto__ = new DataSource();
637
+
638
+ this.$JSONDataSource = function (rawSource) {
639
+ this.__proto__.$DataSource.call (this.__proto__, rawSource);
640
+ that.type = Builder.XML;
641
+ }
642
+
643
+ var that = this.__proto__;
644
+
645
+ that.parseContent = function (content) {
646
+ var doc = null;
647
+ if(content) {
648
+ try {
649
+ doc = eval(content);
650
+ this.document = doc;
651
+ } catch (e) {
652
+ var specificErr = null;
653
+ if (e instanceof ReferenceError) {
654
+ specificErr = [
655
+ 'Unknown reference given.',
656
+ 'Common mistakes include specifying non-global',
657
+ 'function names for the onSelect field.'].join('\n');
658
+ } else if (e instanceof SyntaxError) {
659
+ specificErr = "Your JSON string is malformed";
660
+ }
661
+ var err = [
662
+ e.message,
663
+ ['on line:', e.line].join(' ')
664
+ ];
665
+ if(specificErr) {
666
+ err.reverse();
667
+ err.push(specificErr);
668
+ err.reverse();
669
+ }
670
+ throw (new Error(err.join('\n')));
671
+ }
672
+ }
673
+ }
674
+
675
+ that.getRoot = function() {
676
+ return that.document;
677
+ }
678
+
679
+ that.getChildren = function (node) {
680
+ var ret = [];
681
+ if (node) {
682
+ var iterable = (node === that.getRoot())? node:
683
+ (node ['items'])? node ['items']: null;
684
+ if (iterable) {
685
+ var par = (node === that.getRoot())? null: node;
686
+ for (var i=0; i<iterable.length; i++) {
687
+ var child = iterable[i];
688
+ if (that.getProperty (child, 'id') == null) {
689
+ that.setProperty (child, 'id', that.generateUID())};
690
+ ret[i] = child;
691
+ child['parent'] = par;
692
+ if (i > 0) {
693
+ var prev = iterable[i-1];
694
+ prev['nextSibling'] = child;
695
+ }
696
+ }
697
+ }
698
+ }
699
+ return ret;
700
+ }
701
+
702
+ that.getNextSibling = function (node) {
703
+ if (node) {
704
+ if(node !== that.getRoot()) {
705
+ if (node['nextSibling']) { return node['nextSibling'] };
706
+ }
707
+ }
708
+ return null;
709
+ }
710
+
711
+ that.getParent = function (node) {
712
+ if (node) {
713
+ if(node !== that.getRoot()) {
714
+ if (node['parent']) { return node['parent'] };
715
+ }
716
+ }
717
+ return null;
718
+ }
719
+
720
+ that.hasChildren = function (node) {
721
+ if (node) {
722
+ var iterable = (node === that.getRoot())? node:
723
+ (node ['items'])? node ['items']: null;
724
+ if (iterable) {
725
+ return iterable.length && iterable.length > 0;
726
+ }
727
+ return false;
728
+ }
729
+ return false;
730
+ }
731
+
732
+ that.addChildAt = function (node, newChild, index) {
733
+ if (node && newChild) {
734
+ var children = that.getChildren (node) || (function() {
735
+ node['items'] = [];
736
+ return node['items'];
737
+ })();
738
+ index = Math.min(Math.max(0, index), children.length);
739
+ children.splice (index, 0, newChild);
740
+ if (index > 0) {
741
+ children [index-1]['nextSibling'] = children [index]
742
+ };
743
+ if (index < children.length-1) {
744
+ children[index]['nextSibling'] = children [index]+1
745
+ };
746
+ node['items'] = children;
747
+ }
748
+ }
749
+
750
+ that.removeChildAt = function (node, index) {
751
+ if (node) {
752
+ var children = that.getChildren (node) || (function() {
753
+ node['items'] = [];
754
+ return node['items'];
755
+ })();
756
+ index = Math.min(Math.max(0, index), children.length);
757
+ var removed = children [index];
758
+ children.splice (index, 1);
759
+ if(index > 0 && index < children.length) {
760
+ children [index-1]['nextSibling'] = children [index];
761
+ }
762
+ node['items'] = children;
763
+ return removed;
764
+ }
765
+ return null;
766
+ }
767
+
768
+ that.createNode = function (properties) {
769
+ var node = {};
770
+ for (var p in properties) {
771
+ that.setProperty (node, p, properties[p])
772
+ };
773
+ if (that.getProperty (node, 'id') == null) {
774
+ that.setProperty (node, 'id', that.generateUID());
775
+ }
776
+ return node;
777
+ }
778
+
779
+ that.getProperty = function (node, propName) {
780
+ if (node) { return registry.proof(propName, node[propName]) };
781
+ return null;
782
+ }
783
+
784
+ that.setProperty = function (node, propName, propValue) {
785
+ if (node) {
786
+ node[propName] = registry.proof(propName, propValue);
787
+ }
788
+ }
789
+
790
+ this.$JSONDataSource.apply (this, arguments);
791
+ }
792
+
793
+ /**
794
+ * CLASS Builder
795
+ * @private
796
+ * @class
797
+ */
798
+ function Builder() {
799
+
800
+ var ds, root = null;
801
+
802
+ function createDataSource (source, type) {
803
+ var ret = null;
804
+ if (type == Builder.XML) { ret = new XMLDataSource ( source ) };
805
+ if (type == Builder.JSON) { ret = new JSONDataSource( source )};
806
+ return ret;
807
+ }
808
+
809
+ function buildMenu() {
810
+ var w = new Walker(ds, buildItem);
811
+ w.walk ();
812
+ }
813
+
814
+ function buildItem (item) {
815
+
816
+ // Get & parse info about the item to be built:
817
+ var summary = ds.getSummary (item);
818
+ var isFirstLevel = (!ds.getParent(item));
819
+ var isItemDisabled = (!summary[FieldsRegistry.ENABLED]);
820
+ var hasChildren = ds.hasChildren(item);
821
+ var isItemSeparator = (summary [FieldsRegistry.TYPE] ==
822
+ FieldsRegistry.SEPARATOR);
823
+ var isItemAToggle = (summary [FieldsRegistry.TYPE] ==
824
+ FieldsRegistry.CHECK);
825
+
826
+ // Build the NativeMenuItem to represent this item:
827
+ var ret = parseLabelForMnemonic (summary [FieldsRegistry.LABEL]);
828
+ var nmi = new NativeMenuItem ( ret[0], isItemSeparator );
829
+
830
+
831
+ // Attach features for this item:
832
+ var parsedMnemonicIndex = ret[1];
833
+ if (parsedMnemonicIndex >= 0) {
834
+ summary [FieldsRegistry.MNEMONIC_INDEX] = parsedMnemonicIndex;
835
+ };
836
+ var mnemonicIndex = summary [FieldsRegistry.MNEMONIC_INDEX];
837
+ if (mnemonicIndex != -1) { nmi.mnemonicIndex = mnemonicIndex };
838
+ if (isItemAToggle) {
839
+ var toggler = function (event) {
840
+ var val = !ds.getProperty (item,
841
+ FieldsRegistry.TOGGLED);
842
+ ds.setProperty (item, FieldsRegistry.TOGGLED, val);
843
+ nmi.checked = val;
844
+ }
845
+ nmi.addEventListener (SELECT, toggler);
846
+ nmi.checked = summary [FieldsRegistry.TOGGLED];
847
+ }
848
+ if (summary [FieldsRegistry.ON_SELECT]) {
849
+ var f = function (event) {
850
+ var target = event.target;
851
+ summary [FieldsRegistry.ON_SELECT].call (
852
+ window, event, summary
853
+ );
854
+ }
855
+ nmi.addEventListener (SELECT, f);
856
+ }
857
+ attachKeyEquivalentHandler (nmi, summary);
858
+ if ( isItemDisabled ) { nmi.enabled = false };
859
+
860
+ // Attach our item within the menu structure:
861
+ item['_widget_'] = nmi;
862
+ if (hasChildren) { nmi.submenu = new NativeMenu() };
863
+ var data = nmi.data || (nmi.data = {});
864
+ data['item'] = item;
865
+ var parMnu = null;
866
+ var parItem = ds.getParent(item);
867
+ if (parItem) {
868
+ var parWidget = parItem['_widget_'];
869
+ parMnu = parWidget.submenu;
870
+ if (!parMnu) { return };
871
+ } else {
872
+ parMnu = root || ( root = new NativeMenu() );
873
+ }
874
+ parMnu.addItem(nmi);
875
+ }
876
+
877
+ function qReplace (tStr, searchStr , replaceStr) {
878
+ var index;
879
+ while ((index = tStr.indexOf (searchStr)) >= 0) {
880
+ var arr = tStr.split('');
881
+ arr.splice (index, searchStr.length,
882
+ replaceStr);
883
+ tStr = arr.join('');
884
+ }
885
+ return tStr;
886
+ }
887
+
888
+ function parseLabelForMnemonic (label) {
889
+ var l = label;
890
+ if (l) {
891
+ l = qReplace(l, '__', '[UNDERSCORE]');
892
+ l = qReplace(l, '_', '[MNEMONIC]');
893
+ l = qReplace(l, '[UNDERSCORE]', '_');
894
+ var mi = l.indexOf ('[MNEMONIC]');
895
+ l = qReplace(l, '[MNEMONIC]', '');
896
+ if (mi >= 0) { return [l, mi] };
897
+ }
898
+ return [l, -1];
899
+ }
900
+
901
+ function attachKeyEquivalentHandler (nativeItem, summary) {
902
+ if (summary[FieldsRegistry.DEFAULT_KEY]) {
903
+ // Linux implementation needs this check:
904
+ var def = nativeItem.keyEquivalentModifiers &&
905
+ nativeItem.keyEquivalentModifiers[0]?
906
+ nativeItem.keyEquivalentModifiers[0] : null;
907
+ if (def && typeof def != "undefined") {
908
+ if (summary[FieldsRegistry.CTRL_KEY] === false) {
909
+ if (def == KEYBOARD.CONTROL) { def = null };
910
+ }
911
+ if (summary[FieldsRegistry.CMD_KEY] === false) {
912
+ if (def == KEYBOARD.COMMAND) { def = null };
913
+ }
914
+ }
915
+ }
916
+ var key;
917
+ if (key = summary[FieldsRegistry.KEY_EQUIVALENT]) {
918
+ var mods = [];
919
+ if (def) { mods.push(def) };
920
+ if (summary[FieldsRegistry.CTRL_KEY]) {
921
+ mods.push (KEYBOARD.CONTROL);
922
+ }
923
+ if (summary[FieldsRegistry.CMD_KEY]) {
924
+ mods.push (KEYBOARD.COMMAND);
925
+ }
926
+ if (summary[FieldsRegistry.ALT_KEY]) {
927
+ mods.push (KEYBOARD.ALTERNATE);
928
+ }
929
+ key = (summary[FieldsRegistry.SHIFT_KEY])?
930
+ key.toUpperCase() : key.toLowerCase();
931
+ nativeItem.keyEquivalent = key;
932
+ nativeItem.keyEquivalentModifiers = mods;
933
+ }
934
+ }
935
+
936
+ this.loadData = function (source, type) {
937
+ if (source) { ds = createDataSource (source, type) }
938
+ else { throw new Error([
939
+ "Cannot create menu. ",
940
+ "Provided data source is null"
941
+ ].join('')) }
942
+ }
943
+
944
+ this.build = function() {
945
+ if(ds) {buildMenu()};
946
+ return root;
947
+ }
948
+ }
949
+ Builder.XML = 0x10;
950
+ Builder.JSON = 0x20;
951
+
952
+ /**
953
+ * CLASS NIConnector
954
+ * @private
955
+ * @class
956
+ */
957
+ function NIConnector () {
958
+
959
+ var that = this;
960
+
961
+ var LAST = 0x1;
962
+ var BEFORE_LAST = 0x2;
963
+
964
+ var ni;
965
+ var nativeMenu;
966
+ var overwrite;
967
+ var allSet;
968
+ var isMac;
969
+
970
+ function $NIConnector (oNi, oNewNativeMenu, bOverwriteExisting) {
971
+ if (oNi && oNewNativeMenu) {
972
+ allSet = true;
973
+ ni = oNi;
974
+ nativeMenu = oNewNativeMenu;
975
+ overwrite = bOverwriteExisting;
976
+ isMac = currentOS.indexOf('Mac') >= 0;
977
+ if (typeof NIConnector.defaultMenu == "undefined") {
978
+ var app = NativeApplication.nativeApplication;
979
+ NIConnector.defaultMenu = app.menu;
980
+ }
981
+ }
982
+ }
983
+
984
+
985
+ function isDefaultApplicationMenu () {
986
+ var app = NativeApplication.nativeApplication;
987
+ return (app.menu == NIConnector.defaultMenu);
988
+ }
989
+
990
+ function purge () {
991
+ while (ni.menu.numItems) { ni.menu.removeItemAt (0) }
992
+ }
993
+
994
+ function add ( style ) {
995
+ if (!ni.menu) {
996
+ replace();
997
+ return;
998
+ }
999
+ var addFunction = (style == LAST)?
1000
+ ni.menu.addItem : function (item) {
1001
+ ni.menu.addItemAt (item, ni.menu.numItems-1);
1002
+ }
1003
+ var item;
1004
+ while (nativeMenu.numItems && (item = nativeMenu.removeItemAt(0))) {
1005
+ if(isMac && !item.submenu) { continue };
1006
+ addFunction.call (that, item);
1007
+ }
1008
+ }
1009
+
1010
+ function replace () {
1011
+ ni.menu = nativeMenu;
1012
+ }
1013
+
1014
+ this.doConnect = function () {
1015
+ if (allSet) {
1016
+ if (overwrite) {
1017
+ if (isMac) {
1018
+ purge ();
1019
+ add (LAST);
1020
+ }
1021
+ else { replace() };
1022
+ }
1023
+ else {
1024
+ if (isMac) {
1025
+ if (isDefaultApplicationMenu()) { add (BEFORE_LAST) }
1026
+ else { add (LAST) };
1027
+ } else { add (LAST) };
1028
+ }
1029
+ }
1030
+ }
1031
+
1032
+ $NIConnector.apply (this, arguments);
1033
+ }
1034
+ NIConnector.defaultMenu;
1035
+
1036
+
1037
+ /**
1038
+ * CLASS Shell
1039
+ * @private
1040
+ * @class
1041
+ */
1042
+ function Shell() {
1043
+
1044
+ function $Shell(){}
1045
+
1046
+ var that = this;
1047
+
1048
+ var CONTEXT_MENU = 'contextmenu';
1049
+ var app = NativeApplication.nativeApplication;
1050
+
1051
+ var uidSeed = 0;
1052
+ var DEFAULT_ID = "DEFAULT_ID";
1053
+
1054
+ var isMac = currentOS.indexOf('Mac') >= 0;
1055
+
1056
+ var isBitmapData = function(obj) {
1057
+ return obj &&
1058
+ obj.constructor &&
1059
+ obj.constructor === (new BitmapData (1, 1));
1060
+ }
1061
+
1062
+ var resolveDomEl = function (obj) {
1063
+ var ret = null;
1064
+ if (obj) {
1065
+ if (typeof obj == 'object' && obj.nodeType == 1) { ret = obj };
1066
+ if (typeof obj == 'string') {
1067
+ var el;
1068
+ if (el = document.getElementById(obj)) { ret = el };
1069
+ }
1070
+ }
1071
+ return ret;
1072
+ }
1073
+
1074
+ var checkUserIcon = function (obj) {
1075
+ var icon = app.icon;
1076
+ return icon.bitmaps.length > 0;
1077
+ }
1078
+
1079
+ var getIcons = function (userIcons) {
1080
+ var ret = [];
1081
+ var entries = [];
1082
+ if (userIcons && userIcons.length) {
1083
+ entries = userIcons;
1084
+ } else {
1085
+ var p = new DOMParser();
1086
+ var descr = String(app.applicationDescriptor);
1087
+ var descrDoc = p.parseFromString(descr, "text/xml");
1088
+ var appEl = descrDoc.getElementsByTagName('application')[0];
1089
+ var iconEl = appEl.getElementsByTagName('icon')[0];
1090
+ if (iconEl) {
1091
+ var iconEntries = iconEl.getElementsByTagName('*');
1092
+ for (var i=0; i<iconEntries.length; i++) {
1093
+ if (iconEntries[i].firstChild) {
1094
+ var path = iconEntries[i].firstChild.nodeValue;
1095
+ entries.push (path);
1096
+ }
1097
+ }
1098
+ }
1099
+ }
1100
+ for (var i=0; i<entries.length; i++) {
1101
+ var entry = entries[i];
1102
+ if (isBitmapData(entry)) {
1103
+ ret.push (entry)
1104
+ } else {
1105
+ var file = Shell.resolve(entry);
1106
+ if (!file.exists) {
1107
+ throw (new Error([
1108
+ 'Could not set icon(s) for the iconMenu.',
1109
+ 'Could not resolve this path:', file.url
1110
+ ].join('\n')));
1111
+ };
1112
+ ret.push (file);
1113
+ }
1114
+ }
1115
+ return ret;
1116
+ }
1117
+
1118
+ var loadDefaultBitmaps = function (icons, callback) {
1119
+ var bmpDataObjects = [];
1120
+ var completeHandler = function (event){
1121
+ var bitmap = event.target.loader.content;
1122
+ bmpDataObjects.push(bitmap.bitmapData);
1123
+ loadNext();
1124
+ }
1125
+ var ioErrorHandler = function(event){};
1126
+ var loadNext = function(){
1127
+ var icon = icons.pop();
1128
+ if (icon) {
1129
+ if (icon.url) {
1130
+ var iconURL = icon.url;
1131
+ var request = new URLRequest(iconURL);
1132
+ loader.load(request);
1133
+ } else { bmpDataObjects.push(icon) };
1134
+ } else {
1135
+ if (typeof callback == 'function') {
1136
+ callback.call(this, bmpDataObjects);
1137
+ }
1138
+ }
1139
+ }
1140
+ var loader = new Loader();
1141
+ loader.contentLoaderInfo.addEventListener(COMPLETE,completeHandler);
1142
+ loader.contentLoaderInfo.addEventListener(IO_ERROR,ioErrorHandler);
1143
+ loadNext();
1144
+ }
1145
+
1146
+ var setBitmaps = function (bitmaps) {
1147
+ var icon = app.icon;
1148
+ icon.bitmaps = bitmaps;
1149
+ }
1150
+
1151
+ var linkMenu = function (menu, doOverwrite) {
1152
+ var target = NativeWindow.supportsMenu? window.nativeWindow:
1153
+ NativeApplication.supportsMenu?
1154
+ NativeApplication.nativeApplication:
1155
+ null;
1156
+ var nic = new NIConnector(target, menu, doOverwrite);
1157
+ return nic.doConnect();
1158
+ }
1159
+
1160
+ var generateUID = function () { return ['el', ++uidSeed].join('_') };
1161
+
1162
+ var linkContextMenu = function (menu, domEl) {
1163
+ var stage = window.htmlLoader.stage;
1164
+ var listener = function (e) {
1165
+ if (e.returnValue && menu) { menu.display(stage, e.x, e.y)};
1166
+ e.preventDefault();
1167
+ e.stopPropagation();
1168
+ }
1169
+ var target = (domEl == Shell.UNSPECIFIED)? window :
1170
+ resolveDomEl(domEl);
1171
+ if (!target) {
1172
+ throw (new Error ([
1173
+ "Cannot set contextual menu.",
1174
+ "The DOM element that you specified was not found."
1175
+ ].join('\n')));
1176
+ }
1177
+ target.addEventListener (CONTEXT_MENU, listener, false);
1178
+ }
1179
+
1180
+ var linkIconMenu = function (menu, userIcons) {
1181
+ var haveCustomIcons = (typeof userIcons != "undefined" &&
1182
+ userIcons && userIcons.length);
1183
+ var haveIcon = checkUserIcon();
1184
+ if (!haveCustomIcons && haveIcon) { app.icon.menu = menu }
1185
+ else {
1186
+ var defaultIcons = getIcons (userIcons);
1187
+ var haveDefaultIcons = defaultIcons.length > 0;
1188
+ if (!haveDefaultIcons) {
1189
+ if (!isMac) {
1190
+ throw (new Error([
1191
+ "Cannot set the icon menu.",
1192
+ "On operating systems that do not provide a default",
1193
+ "tray icon, you must specify one before calling",
1194
+ "setAsIconMenu().",
1195
+ "Alternativelly, you can specify default icons in the",
1196
+ "application's XML descriptor."
1197
+ ].join('\n')));
1198
+ }
1199
+ }
1200
+ var doAttach = function(bitmaps){
1201
+ setBitmaps (bitmaps);
1202
+ app.icon.menu = menu;
1203
+ }
1204
+ if (defaultIcons) {
1205
+ loadDefaultBitmaps(defaultIcons, doAttach);
1206
+ }
1207
+ }
1208
+ }
1209
+
1210
+ this.link = function (oMenu, style, target, icons) {
1211
+ if (Shell.MENU & style) {
1212
+ var bOverwrite = style & Shell.OVERWRITE;
1213
+ return linkMenu(oMenu, bOverwrite);
1214
+ }
1215
+ if (Shell.CONTEXT & style) {return linkContextMenu(oMenu, target)};
1216
+ if (Shell.ICON & style) { return linkIconMenu(oMenu, icons) };
1217
+ }
1218
+
1219
+ $Shell.apply (this, arguments);
1220
+ }
1221
+ Shell.UNSPECIFIED = -1;
1222
+ Shell.MENU = 1;
1223
+ Shell.CONTEXT = 2;
1224
+ Shell.ICON = 4;
1225
+ Shell.OVERWRITE = 8;
1226
+
1227
+ Shell.resolve = function (pathOrFile) {
1228
+ var file = null;
1229
+ try {
1230
+ file = File(pathOrFile);
1231
+ } catch(e) {
1232
+ file = File.applicationDirectory.resolvePath (pathOrFile);
1233
+ if (!file.exists) {
1234
+ try {
1235
+ file = new File (pathOrFile);
1236
+ } catch(e) {
1237
+ // must be a path, both 'relative' AND 'non-existing'.
1238
+ }
1239
+ }
1240
+ }
1241
+ return file;
1242
+ }
1243
+
1244
+ /**
1245
+ * CLASS Walker
1246
+ * @class
1247
+ * @private
1248
+ */
1249
+ function Walker() {
1250
+ var t, c, currentItem, allSet, item;
1251
+
1252
+ function $Walker (target, callback) {
1253
+ if (target && target instanceof DataSource) {
1254
+ t = target;
1255
+ }
1256
+ if (callback && typeof callback == "function") {
1257
+ c = callback;
1258
+ }
1259
+ if (t && c) { allSet = true };
1260
+ }
1261
+
1262
+ function getNearestAncestorSibling(node) {
1263
+ while (node) {
1264
+ node = t.getParent(node);
1265
+ if(node) {
1266
+ var s = t.getNextSibling(node);
1267
+ if (s) { return s };
1268
+ }
1269
+ }
1270
+ return null;
1271
+ }
1272
+
1273
+ function getFirstChildOfRoot() {
1274
+ return t.getChildren(t.getRoot())[0] || null;
1275
+ }
1276
+
1277
+ function doTraverse() {
1278
+ if (allSet) {
1279
+ while (item = getNext()) { c.call (window, item) };
1280
+
1281
+ } else {
1282
+ throw (new Error([
1283
+ 'Cannot traverse data tree.',
1284
+ 'Please check the arguments you provided to the Walker class.',
1285
+ ].join('\n')));
1286
+ }
1287
+ }
1288
+
1289
+ function getNext() {
1290
+ if (currentItem === null) { return null };
1291
+
1292
+ if (typeof currentItem == 'undefined') {
1293
+ currentItem = getFirstChildOfRoot();
1294
+ }
1295
+
1296
+ if (t.hasChildren(currentItem)) {
1297
+ var parentNode = currentItem;
1298
+ currentItem = t.getChildren(currentItem)[0];
1299
+ return parentNode;
1300
+ }
1301
+
1302
+ if(t.getNextSibling(currentItem)) {
1303
+ var current = currentItem;
1304
+ currentItem = t.getNextSibling(currentItem);
1305
+ return current;
1306
+ }
1307
+
1308
+ var ci = currentItem;
1309
+ currentItem = getNearestAncestorSibling(currentItem);
1310
+ return ci;
1311
+ }
1312
+
1313
+ this.walk = function (callback) {
1314
+ doTraverse();
1315
+ if (typeof callback == "function") { callback.call (this) };
1316
+ }
1317
+
1318
+ $Walker.apply (this, arguments);
1319
+ }
1320
+
1321
+ constructor.apply (this, arguments);
1322
+ })();