Browse code
initial working sample
fiddlerwoaroof authored on 26/06/2016 06:08:20
Showing 6 changed files
Showing 6 changed files
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,50 @@ |
1 |
+# JIM: The Javascript Interface Manager |
|
2 |
+ |
|
3 |
+Simple implementation of commands and presentation types mimicing some of the |
|
4 |
+nice features of CLIM. |
|
5 |
+ |
|
6 |
+The idea is that you assign types to the various things displayed on the page |
|
7 |
+and then define commands that operate on those types. |
|
8 |
+ |
|
9 |
+When you execute a command, the page activates the types corresponding to the |
|
10 |
+various arguments of the command in order. |
|
11 |
+ |
|
12 |
+## API |
|
13 |
+ |
|
14 |
+To make a new presentation type, either call `PresentationType(name)` directly |
|
15 |
+or call it via `new`. `name` specifies the new type's name, which is used to |
|
16 |
+determine whether something is of that type. This is also used as a element |
|
17 |
+class name in order to determine which elements are of this type. |
|
18 |
+ |
|
19 |
+``` |
|
20 |
+var myType = new PresentationType('mytype'); |
|
21 |
+``` |
|
22 |
+ |
|
23 |
+Next, the presentation type must be bound to the corresponding tags. This is |
|
24 |
+done using `bindTags()` which returns the presentation type to allow for |
|
25 |
+chaining. This function iterates through the elements having `this.name` as one |
|
26 |
+of their classes and then attaches a presentation type to them using `data-bind` |
|
27 |
+to determine which events to bind (defaults to 'click', if not specified) and |
|
28 |
+uses either the value of the `value` attribute or of the `data-value` attribute, |
|
29 |
+as the "value" of the new instance of the presentation stype, if either is |
|
30 |
+specified. Otherwise, it defaults to the textContent of the tag. |
|
31 |
+ |
|
32 |
+``` |
|
33 |
+myType.bindTags(); // bind the corresponding tags, returns myType |
|
34 |
+``` |
|
35 |
+ |
|
36 |
+makeTag has any of these signatures: |
|
37 |
+ |
|
38 |
+``` |
|
39 |
+makeTag(value, tagName) |
|
40 |
+makeTag(value, tagName, content) |
|
41 |
+makeTag(value, tagName, bindTypes, content) |
|
42 |
+``` |
|
43 |
+ |
|
44 |
+`value` refers to the value associated with the object. `content` represents |
|
45 |
+the text displayed that represents this value, it defaults to value if `content` |
|
46 |
+is not specified. `tagName` specifies the kind of tag to be created. |
|
47 |
+`bindTypes` is an Array of strings indicating which events the presentation type |
|
48 |
+should handle. If this is specified, you should either add functions with the |
|
49 |
+corresponding name to the type or setup receivers that can handle the event |
|
50 |
+using `addReceiver(receiver)`. |
0 | 51 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,57 @@ |
1 |
+/* Styles go here */ |
|
2 |
+h1 > li { |
|
3 |
+ display: inline; |
|
4 |
+} |
|
5 |
+ |
|
6 |
+li.activated { |
|
7 |
+ color: blue; |
|
8 |
+ text-decoration: underline; |
|
9 |
+ cursor: pointer; |
|
10 |
+} |
|
11 |
+ |
|
12 |
+.current { |
|
13 |
+ font-weight: bold; |
|
14 |
+} |
|
15 |
+ |
|
16 |
+.listbox { |
|
17 |
+ width: 32%; |
|
18 |
+ float: left; |
|
19 |
+} |
|
20 |
+ |
|
21 |
+button { |
|
22 |
+ clear: both; |
|
23 |
+} |
|
24 |
+ |
|
25 |
+.listbox:first-child { |
|
26 |
+ clear: left; |
|
27 |
+} |
|
28 |
+ |
|
29 |
+.listbox:last-child { |
|
30 |
+ float: right; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+ul,li { |
|
34 |
+ list-style: none; |
|
35 |
+ margin: 0px; |
|
36 |
+ padding: 0px; |
|
37 |
+} |
|
38 |
+ |
|
39 |
+.subject { |
|
40 |
+ color: #880000; |
|
41 |
+} |
|
42 |
+ |
|
43 |
+.verb { |
|
44 |
+ color: #888800; |
|
45 |
+} |
|
46 |
+ |
|
47 |
+.object { |
|
48 |
+ color: #008800; |
|
49 |
+} |
|
50 |
+ |
|
51 |
+#sentence li { |
|
52 |
+ display: inline; |
|
53 |
+} |
|
54 |
+ |
|
55 |
+#sentence li + li { |
|
56 |
+ margin-left: 0.5em; |
|
57 |
+} |
0 | 58 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,78 @@ |
1 |
+<!DOCTYPE html> |
|
2 |
+<html> |
|
3 |
+ |
|
4 |
+ <head> |
|
5 |
+ <link rel="stylesheet" href="css/style.css"> |
|
6 |
+ <script src="lib/PresentationType.js"></script> |
|
7 |
+ <script src="lib/Command.js"></script> |
|
8 |
+ <script src="js/script.js" defer></script> |
|
9 |
+ </head> |
|
10 |
+ |
|
11 |
+ <body> |
|
12 |
+ <h1><li class="name" data-bind="click">JIM</li>: The Javsascript Interface Manager!</h1> |
|
13 |
+ <div> |
|
14 |
+ <button id="randomSentence">Random Sentence!</button> |
|
15 |
+ <button id="pickSentence">Pick a Sentence</button> |
|
16 |
+ </div> |
|
17 |
+ <!-- |
|
18 |
+ <div class="listbox"> |
|
19 |
+ <h2>Names</h2> |
|
20 |
+ <ul id="names"> |
|
21 |
+ <li class="name">Mary</li> |
|
22 |
+ <li class="name">Jane</li> |
|
23 |
+ <li class="name">Anne</li> |
|
24 |
+ <li class="name">John</li> |
|
25 |
+ </ul> |
|
26 |
+ </div> |
|
27 |
+ <div class="listbox"> |
|
28 |
+ <h2>Occupations</h2> |
|
29 |
+ <ul id="occupations"> |
|
30 |
+ <li class="occupation">builder</li> |
|
31 |
+ <li class="occupation">interface builder</li> |
|
32 |
+ </ul> |
|
33 |
+ </div> |
|
34 |
+ --> |
|
35 |
+ |
|
36 |
+ <div id="sentence"></div> |
|
37 |
+ <div class="listbox"> |
|
38 |
+ <h2>Subject</h2> |
|
39 |
+ <ul id="subjects"> |
|
40 |
+ <li class="subject">Combat form</li> |
|
41 |
+ <li class="subject">Stock</li> |
|
42 |
+ <li class="subject">Application software</li> |
|
43 |
+ <li class="subject">The old st paul's stations</li> |
|
44 |
+ <li class="subject">The cat</li> |
|
45 |
+ <li class="subject">The dog</li> |
|
46 |
+ <li class="subject">Bob, the tomato,</li> |
|
47 |
+ <li class="subject">Midas</li> |
|
48 |
+ </ul> |
|
49 |
+ </div> |
|
50 |
+ <div class="listbox"> |
|
51 |
+ <h2>Verb</h2> |
|
52 |
+ <ul id="verbs"> |
|
53 |
+ <li class="verb">is four-armed monitor lizard analog with</li> |
|
54 |
+ <li class="verb">is drawn from</li> |
|
55 |
+ <li class="verb">needs</li> |
|
56 |
+ <li class="verb">were acquired in</li> |
|
57 |
+ <li class="verb">shook hands with</li> |
|
58 |
+ <li class="verb">sat on</li> |
|
59 |
+ <li class="verb">barked at</li> |
|
60 |
+ <li class="verb">chased</li> |
|
61 |
+ </ul> |
|
62 |
+ </div> |
|
63 |
+ <div class="listbox"> |
|
64 |
+ <h2>Object</h2> |
|
65 |
+ <ul id="objects"> |
|
66 |
+ <li class="object">Medusa.<li> |
|
67 |
+ <li class="object">the mat.</li> |
|
68 |
+ <li class="object">the cat.</li> |
|
69 |
+ <li class="object">Larry, the cucumber.</li> |
|
70 |
+ <li class="object">black skin.</li> |
|
71 |
+ <li class="object">european bloodline producers.</li> |
|
72 |
+ <li class="object">powerful processor.</li> |
|
73 |
+ <li class="object">1995 in poor state.</li> |
|
74 |
+ </ul> |
|
75 |
+ </div> |
|
76 |
+ </body> |
|
77 |
+ |
|
78 |
+</html> |
0 | 79 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,108 @@ |
1 |
+// Code goes here |
|
2 |
+ |
|
3 |
+subjectType = PresentationType('subject').bindTags(); |
|
4 |
+verbType = PresentationType('verb').bindTags(); |
|
5 |
+objectType = PresentationType('object').bindTags(); |
|
6 |
+ |
|
7 |
+pickSentence = new Command(['subject', 'verb', 'object']); |
|
8 |
+pickSentence.execute = function(subject, verb, object) { |
|
9 |
+ var parent = document.querySelector('#sentence'); |
|
10 |
+ |
|
11 |
+ if (parent.hasChildNodes()) { |
|
12 |
+ document.querySelector('#subjects').appendChild( |
|
13 |
+ parent.querySelector(subjectType.selector) |
|
14 |
+ ); |
|
15 |
+ |
|
16 |
+ document.querySelector('#verbs').appendChild( |
|
17 |
+ parent.querySelector(verbType.selector) |
|
18 |
+ ); |
|
19 |
+ |
|
20 |
+ document.querySelector('#objects').appendChild( |
|
21 |
+ parent.querySelector(objectType.selector) |
|
22 |
+ ) |
|
23 |
+ } |
|
24 |
+ |
|
25 |
+ [subject,verb,object].forEach(function (el) { |
|
26 |
+ parent.appendChild(el.tag); |
|
27 |
+ }); |
|
28 |
+ |
|
29 |
+} |
|
30 |
+ |
|
31 |
+randomSentence = new Command([]); |
|
32 |
+randomSentence.execute = function() { |
|
33 |
+ var subjects = subjectType.selectAll(); |
|
34 |
+ var verbs = verbType.selectAll(); |
|
35 |
+ var objects = objectType.selectAll(); |
|
36 |
+ |
|
37 |
+ pickSentence.execute( |
|
38 |
+ subjects[Math.floor(Math.random()*3)], |
|
39 |
+ verbs[Math.floor(Math.random()*3)], |
|
40 |
+ objects[Math.floor(Math.random()*3)] |
|
41 |
+ ); |
|
42 |
+} |
|
43 |
+ |
|
44 |
+document.querySelector('#pickSentence').addEventListener('click', pickSentence, false); |
|
45 |
+document.querySelector('#randomSentence').addEventListener('click', randomSentence, false); |
|
46 |
+ |
|
47 |
+/* |
|
48 |
+nameType = PresentationType('name'); |
|
49 |
+nameType.bindTags(); |
|
50 |
+ |
|
51 |
+occupationType = PresentationType('occupation').bindTags(); |
|
52 |
+ |
|
53 |
+names = ['Bill', 'Bob', 'John']; |
|
54 |
+ |
|
55 |
+names.forEach(function(name) { |
|
56 |
+ var theTag = nameType.makeTag( |
|
57 |
+ name.toLowerCase(), |
|
58 |
+ 'div', |
|
59 |
+ ['click'], |
|
60 |
+ name |
|
61 |
+ ); |
|
62 |
+ document.querySelector('#names').appendChild(theTag.tag); |
|
63 |
+}); |
|
64 |
+ |
|
65 |
+occupations = ['carpenter', 'weaver', 'fisher']; |
|
66 |
+ |
|
67 |
+occupations.forEach(function(occupation) { |
|
68 |
+ var theTag = occupationType.makeTag( |
|
69 |
+ occupation.toLowerCase(), |
|
70 |
+ 'div', |
|
71 |
+ ['click'], |
|
72 |
+ occupation |
|
73 |
+ ); |
|
74 |
+ |
|
75 |
+ document.querySelector('#occupations').appendChild(theTag.tag); |
|
76 |
+}); |
|
77 |
+ |
|
78 |
+getPhrase = new Command(['name', 'occupation']); |
|
79 |
+ |
|
80 |
+getPhrase.execute = function (name, occupation) { |
|
81 |
+ document.querySelectorAll('.current').forEach(function(el) { |
|
82 |
+ el.classList.remove('current'); |
|
83 |
+ }); |
|
84 |
+ |
|
85 |
+ name.tag.classList.add('current'); |
|
86 |
+ occupation.tag.classList.add('current'); |
|
87 |
+ |
|
88 |
+ var heading = document.querySelector('h1'); |
|
89 |
+ var oldname = heading.querySelector(nameType.selector); |
|
90 |
+ var oldoccupation = heading.querySelector(occupationType.selector); |
|
91 |
+ |
|
92 |
+ heading.textContent = ''; |
|
93 |
+ |
|
94 |
+ if (oldname !== null) { |
|
95 |
+ document.querySelector('#names').appendChild(oldname); |
|
96 |
+ } |
|
97 |
+ heading.appendChild(name.tag); |
|
98 |
+ |
|
99 |
+ heading.appendChild(document.createTextNode(' the ')); |
|
100 |
+ |
|
101 |
+ if (oldoccupation !== null) { |
|
102 |
+ document.querySelector('#occupations').appendChild(oldoccupation); |
|
103 |
+ } |
|
104 |
+ heading.appendChild(occupation.tag); |
|
105 |
+ |
|
106 |
+}; |
|
107 |
+*/ |
|
108 |
+ |
0 | 109 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,114 @@ |
1 |
+function PresentationTypeError(msg, expectedType, actualVal) { |
|
2 |
+ if (this instanceof TypeError) { |
|
3 |
+ return new TypeError(msg, expectedType, actualVal); |
|
4 |
+ } else { |
|
5 |
+ this.msg = msg; |
|
6 |
+ this.expectedType = expectedType; |
|
7 |
+ this.actualVal = actualVal; |
|
8 |
+ } |
|
9 |
+ |
|
10 |
+ |
|
11 |
+} |
|
12 |
+ |
|
13 |
+CursorAbort = {}; |
|
14 |
+Command = (function() { |
|
15 |
+ |
|
16 |
+ function TypeCursor(types) { |
|
17 |
+ if (! (this instanceof TypeCursor) ) { |
|
18 |
+ return new TypeCursor(types); |
|
19 |
+ } |
|
20 |
+ |
|
21 |
+ this.types = types; |
|
22 |
+ this.boundArgs = new Array(types.length); |
|
23 |
+ this.currentIdx = 0; |
|
24 |
+ |
|
25 |
+ var self = this; |
|
26 |
+ this.promise = new Promise(function (resolve, reject) { |
|
27 |
+ self.resolve = resolve; |
|
28 |
+ self.reject = reject; |
|
29 |
+ }); |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+ TypeCursor.prototype = { |
|
33 |
+ abort() { |
|
34 |
+ var currentType = this.types[this.currentIdx-1]; |
|
35 |
+ if (currentType !== undefined) { |
|
36 |
+ currentType.deactivateAll(); |
|
37 |
+ currentType.removeReceiver(this); |
|
38 |
+ } |
|
39 |
+ |
|
40 |
+ //this.reject(CursorAbort); |
|
41 |
+ }, |
|
42 |
+ |
|
43 |
+ activate() { |
|
44 |
+ if (this.currentIdx >= this.types.length) { |
|
45 |
+ this.resolve.bind(this.promise)(this.boundArgs); |
|
46 |
+ } else { |
|
47 |
+ var currentType = this.types[this.currentIdx++]; |
|
48 |
+ currentType.addReceiver(this); |
|
49 |
+ currentType.activateAll(); |
|
50 |
+ } |
|
51 |
+ return this.promise; |
|
52 |
+ }, |
|
53 |
+ |
|
54 |
+ receive(event, presentationType, arg) { |
|
55 |
+ var args = Array.prototype.splice(arguments); |
|
56 |
+ args.shift(); |
|
57 |
+ presentationType.removeReceiver(this); |
|
58 |
+ presentationType.deactivateAll(); |
|
59 |
+ |
|
60 |
+ if (presentationType.validate.apply(args)) { |
|
61 |
+ this.boundArgs[this.currentIdx-1] = presentationType; |
|
62 |
+ this.activate(); |
|
63 |
+ } else { |
|
64 |
+ this.reject(args); |
|
65 |
+ } |
|
66 |
+ } |
|
67 |
+ }; |
|
68 |
+ |
|
69 |
+ function Command(types) { |
|
70 |
+ if (! (this instanceof Command)) { |
|
71 |
+ throw "do \"new Command()\""; |
|
72 |
+ } |
|
73 |
+ |
|
74 |
+ this.types = types.map(function (type) { |
|
75 |
+ // Lookup or create a presentation type |
|
76 |
+ return PresentationType(type); |
|
77 |
+ }); |
|
78 |
+ |
|
79 |
+ this.nargs = this.types.length; |
|
80 |
+ } |
|
81 |
+ |
|
82 |
+ Command.prototype = { |
|
83 |
+ run(args) { |
|
84 |
+ if (args === undefined) { |
|
85 |
+ args = []; |
|
86 |
+ } else if (arguments.length > 1 || (! args instanceof Array)) { |
|
87 |
+ args = Array.prototype.slice.call(arguments); |
|
88 |
+ } |
|
89 |
+ |
|
90 |
+ for (var idx = 0; idx < args.length; idx++) { |
|
91 |
+ var type = this.types[idx]; |
|
92 |
+ var arg = args[idx]; |
|
93 |
+ console.log(this.types[idx], args[idx]); |
|
94 |
+ if ( type.name !== arg.name ) { |
|
95 |
+ throw new PresentationTypeError('wrong type', this.types[idx], args[idx]); |
|
96 |
+ } |
|
97 |
+ } |
|
98 |
+ this.execute.apply(this, args); |
|
99 |
+ }, |
|
100 |
+ |
|
101 |
+ handleEvent(theEvent) { |
|
102 |
+ if (this.cursor !== undefined) { |
|
103 |
+ this.cursor.abort(); |
|
104 |
+ } |
|
105 |
+ |
|
106 |
+ this.cursor = TypeCursor(this.types); |
|
107 |
+ this.cursor.activate().then(this.run.bind(this)); |
|
108 |
+ |
|
109 |
+ return true; |
|
110 |
+ } |
|
111 |
+ }; |
|
112 |
+ |
|
113 |
+ return Command; |
|
114 |
+})(); |
0 | 115 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,181 @@ |
1 |
+PresentationType = (function () { |
|
2 |
+ var presentationTypes = {}; |
|
3 |
+ |
|
4 |
+ // TODO: think through selector better: right now, I think we assume that it |
|
5 |
+ // is a class selector and things will break if it isn't we should, |
|
6 |
+ // however, probably let it be more general. |
|
7 |
+ function PresentationType(name, selector) { |
|
8 |
+ if (this instanceof PresentationType) { |
|
9 |
+ this.name = name; |
|
10 |
+ if (selector === undefined) { |
|
11 |
+ selector = '.'+this.name; |
|
12 |
+ } |
|
13 |
+ this.selector = selector; |
|
14 |
+ } else { |
|
15 |
+ var result = presentationTypes[name]; |
|
16 |
+ if (result === undefined) { |
|
17 |
+ result = new PresentationType(name); |
|
18 |
+ presentationTypes[result.name] = result; |
|
19 |
+ result.receivers = []; |
|
20 |
+ |
|
21 |
+ } |
|
22 |
+ return result; |
|
23 |
+ } |
|
24 |
+ } |
|
25 |
+ |
|
26 |
+ PresentationType.prototype = { |
|
27 |
+ presentationsTypes: presentationTypes, |
|
28 |
+ |
|
29 |
+ addReceiver(receiver) { |
|
30 |
+ this.receivers.push(receiver); |
|
31 |
+ return this.receivers.length - 1; |
|
32 |
+ }, |
|
33 |
+ |
|
34 |
+ removeReceiver(el) { |
|
35 |
+ var elIdx = this.receivers.indexOf(el); |
|
36 |
+ var result = elIdx !== -1; |
|
37 |
+ if (result) { |
|
38 |
+ this.receivers.splice(elIdx,1); |
|
39 |
+ } |
|
40 |
+ return result; |
|
41 |
+ }, |
|
42 |
+ |
|
43 |
+ notifyReceivers(theEvent) { |
|
44 |
+ var outerArgs = Array.prototype.slice.call(arguments); |
|
45 |
+ outerArgs.unshift(theEvent, this, this.value); |
|
46 |
+ |
|
47 |
+ this.receivers.forEach((function (theReceiver) { |
|
48 |
+ theReceiver.receive.apply(theReceiver, outerArgs); |
|
49 |
+ })); |
|
50 |
+ }, |
|
51 |
+ |
|
52 |
+ selectAllTags() { |
|
53 |
+ return document.querySelectorAll(this.selector); |
|
54 |
+ }, |
|
55 |
+ |
|
56 |
+ selectAll() { |
|
57 |
+ var allTags = this.selectAllTags(); |
|
58 |
+ return Array.prototype.map.call(allTags, function (el) { |
|
59 |
+ return el.ptObject; |
|
60 |
+ }); |
|
61 |
+ }, |
|
62 |
+ |
|
63 |
+ bindTags() { |
|
64 |
+ var els = this.selectAllTags(); |
|
65 |
+ |
|
66 |
+ els.forEach(function (theEl) { |
|
67 |
+ var content = theEl.textContent; |
|
68 |
+ var value = theEl.value; |
|
69 |
+ |
|
70 |
+ |
|
71 |
+ var bindTypes = theEl.dataset.bind; |
|
72 |
+ if (bindTypes !== undefined) { |
|
73 |
+ bindTypes = bindTypes.split(','); |
|
74 |
+ } else { |
|
75 |
+ bindTypes = ['click']; |
|
76 |
+ } |
|
77 |
+ |
|
78 |
+ console.log('bt',bindTypes); |
|
79 |
+ |
|
80 |
+ if (! theEl.hasAttribute('value') ) { |
|
81 |
+ var tmpVal = theEl.dataset.value; |
|
82 |
+ value = tmpVal === undefined ? content : theEl.dataset.value; |
|
83 |
+ } |
|
84 |
+ |
|
85 |
+ this.wrapTag(theEl, value, bindTypes, content); |
|
86 |
+ }, this); |
|
87 |
+ |
|
88 |
+ return this; |
|
89 |
+ }, |
|
90 |
+ |
|
91 |
+ wrapTag(tag, value, bindTypes, content) { |
|
92 |
+ var result = Object.assign(Object.create(this), { |
|
93 |
+ tag: tag, |
|
94 |
+ value: value, |
|
95 |
+ display: content, |
|
96 |
+ }); |
|
97 |
+ tag.ptObject = result; |
|
98 |
+ |
|
99 |
+ bindTypes.forEach(function (event) { |
|
100 |
+ console.log(event); |
|
101 |
+ tag.addEventListener(event, result, false); |
|
102 |
+ }); |
|
103 |
+ |
|
104 |
+ if (result.validate()) { |
|
105 |
+ return result; |
|
106 |
+ } else { |
|
107 |
+ this.doError(result); |
|
108 |
+ } |
|
109 |
+ }, |
|
110 |
+ |
|
111 |
+ makeTag(value, tagName, bindTypes, content) { |
|
112 |
+ var newTag = document.createElement(tagName); |
|
113 |
+ |
|
114 |
+ newTag.classList.add(this.name); |
|
115 |
+ |
|
116 |
+ if (bindTypes === undefined) { |
|
117 |
+ bindTypes = []; |
|
118 |
+ } else if (!(bindTypes instanceof Array)) { |
|
119 |
+ content = bindTypes; |
|
120 |
+ bindTypes = []; |
|
121 |
+ } |
|
122 |
+ |
|
123 |
+ if (content === undefined) { |
|
124 |
+ content = value; |
|
125 |
+ } |
|
126 |
+ |
|
127 |
+ newTag.textContent = content; |
|
128 |
+ return this.wrapTag(newTag, value, bindTypes, content); |
|
129 |
+ }, |
|
130 |
+ |
|
131 |
+ handleEvent(theEvent) { |
|
132 |
+ console.log('handling: ',theEvent); |
|
133 |
+ var handler = this[theEvent.type]; |
|
134 |
+ var result = true; |
|
135 |
+ if (handler !== undefined) { |
|
136 |
+ result = handler.bind(this)(theEvent); |
|
137 |
+ } |
|
138 |
+ this.notifyReceivers(theEvent); |
|
139 |
+ |
|
140 |
+ return result; |
|
141 |
+ }, |
|
142 |
+ |
|
143 |
+ doError(object) { |
|
144 |
+ return; |
|
145 |
+ }, |
|
146 |
+ |
|
147 |
+ validate() { |
|
148 |
+ return true; |
|
149 |
+ }, |
|
150 |
+ |
|
151 |
+ toggleAll() { |
|
152 |
+ var els = this.selectAllTags(); |
|
153 |
+ |
|
154 |
+ els.forEach(function (el) { |
|
155 |
+ el.classList.toggle('activated'); |
|
156 |
+ }); |
|
157 |
+ }, |
|
158 |
+ |
|
159 |
+ deactivateAll() { |
|
160 |
+ var els = this.selectAllTags(); |
|
161 |
+ |
|
162 |
+ els.forEach(function (el) { |
|
163 |
+ el.classList.remove('activated'); |
|
164 |
+ }); |
|
165 |
+ }, |
|
166 |
+ |
|
167 |
+ activateAll() { |
|
168 |
+ var els = this.selectAllTags(); |
|
169 |
+ |
|
170 |
+ els.forEach(function (el) { |
|
171 |
+ el.classList.add('activated'); |
|
172 |
+ }); |
|
173 |
+ |
|
174 |
+ return els; |
|
175 |
+ }, |
|
176 |
+ |
|
177 |
+ |
|
178 |
+ }; |
|
179 |
+ |
|
180 |
+ return PresentationType; |
|
181 |
+})(); |