/[suikacvs]/webroot/www/js/jste/tutorial.js
Suika

Contents of /webroot/www/js/jste/tutorial.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download) (as text)
Sun Jan 4 12:44:00 2009 UTC (16 years, 7 months ago) by wakaba
Branch: MAIN
File MIME type: application/javascript
Initial

1 wakaba 1.1
2     if (typeof (JSTE) === "undefined") var JSTE = {};
3    
4     JSTE.WATNS = 'http://suika.fam.cx/ns/wat';
5     JSTE.SpaceChars = /[\x09\x0A\x0C\x0D\x20]+/;
6    
7     JSTE.Class = function (constructor, prototype) {
8     return JSTE.Subclass (constructor, JSTE.EventTarget, prototype);
9     }; // Class
10    
11     JSTE.Class.addClassMethods = function (classObject, methods) {
12     new JSTE.Hash (methods).forEach (function (n, v) {
13     if (!classObject[n]) {
14     classObject[n] = v;
15     }
16     });
17     }; // addClassMethods
18    
19     JSTE.Subclass = function (constructor, superclass, prototype) {
20     constructor.prototype = new superclass;
21     for (var n in prototype) {
22     constructor.prototype[n] = prototype[n];
23     }
24     constructor.prototype.constructor = constructor;
25     constructor.prototype._super = superclass;
26     return constructor;
27     }; // Subclass
28    
29     JSTE.EventTarget = new JSTE.Subclass (function () {
30    
31     }, function () {}, {
32     addEventListener: function (eventType, handler, useCapture) {
33     if (useCapture) return;
34     if (!this.eventListeners) this.eventListeners = {};
35     if (!this.eventListeners[eventType]) {
36     this.eventListeners[eventType] = new JSTE.List;
37     }
38     this.eventListeners[eventType].push (handler);
39     }, // addEventListener
40     removeEventListener: function (eventType, handler, useCapture) {
41     if (useCapture) return;
42     if (!this.eventListeners) return;
43     if (!this.eventListeners[eventType]) return;
44     this.eventListeners[eventType].remove (handler);
45     }, // removeEventListener
46     dispatchEvent: function (e) {
47     if (!this.eventListeners) return;
48     var handlers = this.eventListeners[e.type];
49     if (!handlers) return;
50     e.currentTarget = this;
51     e.target = this;
52     var preventDefault;
53     handlers.forEach (function (handler) {
54     if (handler.apply (this, [e])) {
55     preventDefault = true;
56     }
57     });
58     return preventDefault || e.isDefaultPrevented ();
59     } // dispatchEvent
60     }); // EventTarget
61    
62     JSTE.Event = new JSTE.Class (function (eventType, canBubble, cancelable) {
63     this.type = eventType;
64     this.bubbles = canBubble;
65     this.cancelable = cancelable;
66     }, {
67     preventDefault: function () {
68     this.defaultPrevented = true;
69     }, // preventDefault
70     isDefaultPrevented: function () {
71     return this.defaultPrevented;
72     } // isDefaultPrevented
73     });
74    
75     JSTE.Observer = new JSTE.Class (function (eventType, target, onevent) {
76     this.eventType = eventType;
77     if (target.addEventListener) {
78     this.target = target;
79     this.code = onevent;
80     target.addEventListener (eventType, this.code, false);
81     } else if (target.attachEvent) {
82     this.code = function () {
83     onevent (event);
84     };
85     this.target = target;
86     target.attachEvent ("on" + eventType, this.code);
87     }
88     }, {
89     stop: function () {
90     if (this.target.removeEventListener) {
91     this.target.removeEventListener (this.eventType, this.code, false);
92     } else if (this.detachEvent) {
93     this.target.detachEvent ("on" + this.eventType, this.code);
94     }
95     } // stop
96     }); // Observer
97    
98     JSTE.List = new JSTE.Class (function (arrayLike) {
99     this.list = arrayLike || [];
100     }, {
101     getLast: function () {
102     if (this.list.length) {
103     return this.list[this.list.length - 1];
104     } else {
105     return null;
106     }
107     }, // getLast
108    
109     forEach: function (code) {
110     var length = this.list.length;
111     for (var i = 0; i < length; i++) {
112     var r = code (this.list[i]);
113     if (r && r.stop) return r.returnValue;
114     }
115     return null;
116     }, // forEach
117    
118     clone: function () {
119     var newList = [];
120     this.forEach (function (item) {
121     newList.push (item);
122     });
123     return new this.constructor (newList);
124     }, // clone
125    
126     grep: function (code) {
127     var newList = [];
128     this.forEach (function (item) {
129     if (code (item)) {
130     newList.push (item);
131     }
132     });
133     return new this.constructor (newList);
134     }, // grep
135     onlyNonNull: function () {
136     return this.grep (function (item) {
137     return item != null; /* Intentionally "!=" */
138     });
139     }, // onlyNonNull
140    
141     getFirstMatch: function (code) {
142     return this.forEach (function (item) {
143     if (code (item)) {
144     return new JSTE.List.Return (item);
145     }
146     });
147     }, // getFirstMatch
148    
149     switchByElementType: function () {
150     var cases = new JSTE.List (arguments);
151     this.forEach (function (n) {
152     cases.forEach (function (c) {
153     if (c.namespaceURI == n.namespaceURI) {
154     return new JSTE.List.Return (c.execute (n));
155     }
156     });
157     });
158     }, // switchByElementType
159    
160     push: function (item) {
161     this.list.push (item);
162     }, // push
163     pushCloneOfLast: function () {
164     this.list.push (this.getLast ().clone ());
165     }, // pushCloneOfLast
166     append: function (list) {
167     var self = this;
168     list.forEach (function (n) {
169     self.list.push (n);
170     });
171     }, // append
172    
173     pop: function () {
174     return this.list.pop ();
175     }, // pop
176     remove: function (removedItem) {
177     var length = this.list.length;
178     for (var i = length - 1; i >= 0; --i) {
179     var item = this.list[i];
180     if (item == removedItem) { // Intentionally "=="
181     this.list.splice (i, 1);
182     }
183     }
184     }, // remove
185     clear: function () {
186     this.list.splice (0, this.list.length);
187     } // clear
188    
189     }); // List
190    
191     JSTE.List.Return = new JSTE.Class (function (rv) {
192     this.stop = true;
193     this.returnValue = rv;
194     }, {
195    
196     }); // Return
197    
198     JSTE.List.SpaceSeparated = function (v) {
199     return new JSTE.List ((v || '').split (JSTE.SpaceChars)).grep (function (v) {
200     return v.length;
201     });
202     }; // SpaceSeparated
203    
204     JSTE.List.SwitchByLocalName = new JSTE.Class (function (ns, cases, ow) {
205     this.namespaceURI = ns;
206     this.cases = cases;
207     this.otherwise = ow || function (n) { };
208     }, {
209     execute: function (n) {
210     for (var ln in this.cases) {
211     if (JSTE.Element.matchLocalName (n, ln)) {
212     return this.cases[ln] (n);
213     }
214     }
215     return this.otherwise (n);
216     }
217     });
218    
219     JSTE.Hash = new JSTE.Class (function (hash) {
220     this.hash = hash || {};
221     }, {
222     forEach: function (code) {
223     for (var n in this.hash) {
224     var r = code (n, this.hash[n]);
225     if (r && r.stop) break;
226     }
227     }, // forEach
228     clone: function (code) {
229     var newHash = {};
230     this.forEach (function (n, v) {
231     newHash[n] = v;
232     });
233     return new this.constructor (newHash);
234     }, // clone
235    
236     getNamedItem: function (n) {
237     return this.hash[n];
238     }, // getNamedItem
239     setNamedItem: function (n, v) {
240     return this.hash[n] = v;
241     } // setNamedItem
242     });
243    
244     if (!JSTE.Node) JSTE.Node = {};
245    
246     JSTE.Class.addClassMethods (JSTE.Node, {
247     querySelector: function (node, selectors) {
248     if (node.querySelector) {
249     var el;
250     try {
251     el = node.querySelector (selectors);
252     } catch (e) {
253     el = null;
254     }
255     return el;
256     } else if (window.uu && uu.css) {
257     if (selectors != "") {
258     /* NOTE: uu.css return all elements for "" or ",xxx" */
259     return uu.css (selectors, node)[0];
260     } else {
261     return null;
262     }
263     } else if (window.Ten && Ten.DOM && Ten.DOM.getElementsBySelector) {
264     return Ten.DOM.getElementsBySelector (selectors)[0];
265     } else {
266     return null;
267     }
268     }, // querySelector
269     querySelectorAll: function (node, selectors) {
270     if (node.querySelectorAll) {
271     var nl;
272     try {
273     nl = node.querySelectorAll (selectors);
274     } catch (e) {
275     nl = null;
276     }
277     return new JSTE.List (nl);
278     } else if (window.uu && uu.css) {
279     if (selectors != "") {
280     /* NOTE: uu.css return all elements for "" or ",xxx" */
281     return new JSTE.List (uu.css (selectors, node));
282     } else {
283     return new JSTE.List;
284     }
285     } else if (window.Ten && Ten.DOM && Ten.DOM.getElementsBySelector) {
286     return new JSTE.List (Ten.DOM.getElementsBySelector (selectors));
287     } else {
288     return new JSTE.List;
289     }
290     } // querySelectorAll
291     });
292    
293     if (!JSTE.Element) JSTE.Element = {};
294    
295     JSTE.Class.addClassMethods (JSTE.Element, {
296     getLocalName: function (el) {
297     var localName = el.localName;
298     if (!localName) {
299     localName = el.nodeName;
300     if (el.prefix) {
301     localName = localName.substring (el.prefix.length + 1);
302     }
303     }
304     return localName;
305     }, // getLocalName
306    
307     match: function (el, ns, ln) {
308     if (el.nodeType !== 1) return false;
309     if (el.namespaceURI !== ns) return false;
310     return JSTE.Element.matchLocalName (el, ln);
311     }, // match
312     matchLocalName: function (el, ln) {
313     var localName = JSTE.Element.getLocalName (el);
314     if (ln instanceof RegExp) {
315     if (!localName.match (ln)) return false;
316     } else {
317     if (localName !== ln) return false;
318     }
319     return true;
320     }, // matchLocalName
321    
322     getChildElement: function (el, ns, ln) {
323     return new JSTE.List (el.childNodes).getFirstMatch (function (item) {
324     return JSTE.Element.match (item, ns, ln);
325     });
326     }, // getChildElement
327     getChildElements: function (el, ns, ln) {
328     return new JSTE.List (el.childNodes).grep (function (item) {
329     return JSTE.Element.match (item, ns, ln);
330     });
331     }, // getChildElements
332    
333     appendText: function (el, s) {
334     return el.appendChild (el.ownerDocument.createTextNode (s));
335     }, // appendText
336    
337     createTemplate: function (doc, node) {
338     var df = doc.createDocumentFragment ();
339     new JSTE.List (node.childNodes).forEach (function (n) {
340     if (n.nodeType == 1) {
341     var c = doc.createElement (JSTE.Element.getLocalName (n));
342     new JSTE.List (c.attributes).forEach (function (n) {
343     c.setAttribute (n.name, n.value);
344     });
345     c.appendChild (JSTE.Element.createTemplate (doc, n));
346     df.appendChild (c);
347     } else if (n.nodeType == 3 || n.nodeType == 4) {
348     df.appendChild (doc.createTextNode (n.data));
349     }
350     });
351     return df;
352     }, // createTemplate
353    
354     hasAttribute: function (el, localName) {
355     if (el.hasAttribute) {
356     return el.hasAttribute (localName);
357     } else {
358     return el.getAttribute (localName) != null;
359     }
360     }, // hasAttribute
361    
362     getClassNames: function (el) {
363     return new JSTE.List (el.className.split (JSTE.SpaceChars));
364     }, // getClassNames
365     addClassName: function (el, newClassName) {
366     el.className = el.className + ' ' + newClassName;
367     }, // deleteClassName
368     deleteClassName: function (el, oldClassName) {
369     var classNames = el.className.split (JSTE.SpaceChars);
370     var newClasses = [];
371     for (var n in classNames) {
372     if (classNames[n] != oldClassName) {
373     newClasses.push (classNames[n]);
374     }
375     }
376     el.className = newClasses.join (' ');
377     }, // deleteClassName
378     replaceClassName: function (el, oldClassName, newClassName) {
379     var classNames = el.className.split (JSTE.SpaceChars);
380     var newClasses = [newClassName];
381     for (var n in classNames) {
382     if (classNames[n] != oldClassName) {
383     newClasses.push (classNames[n]);
384     }
385     }
386     el.className = newClasses.join (' ');
387     }, // replaceClassName
388    
389     getIds: function (el) {
390     return new JSTE.List (el.id != "" ? [el.id] : []);
391     } // getIds
392    
393     }); // JSTE.Element
394    
395     /* Events: load, close, shown, hidden */
396     JSTE.Message = new JSTE.Class (function (doc, template, commandTarget) {
397     if (!doc) return;
398     this._targetDocument = doc;
399     this._template = template || doc.createDocumentFragment ();
400     this._commandTarget = commandTarget;
401     this.hidden = true;
402     this.select = "";
403    
404     var e = new JSTE.Event ('load');
405     this.dispatchEvent (e);
406     }, {
407     render: function () {
408     var self = this;
409     var doc = this._targetDocument;
410    
411     var msgContainer = doc.createElement ('section');
412     msgContainer.appendChild (this._template);
413    
414     var buttonContainer = doc.createElement ('menu');
415    
416     var backButton = new JSTE.Message.Button
417     ("Back", this._commandTarget, "back");
418     buttonContainer.appendChild (backButton.element);
419    
420     var nextButton = new JSTE.Message.Button
421     ("Next", this._commandTarget, "next");
422     buttonContainer.appendChild (nextButton.element);
423    
424     this._outermostElement = this._render (msgContainer, buttonContainer);
425    
426     this.show ();
427     }, // render
428     _render: function (msgContainer, buttonContainer) {
429     var doc = this._targetDocument;
430    
431     var container = doc.createElement ('article');
432     var style = doc.createElement ('style');
433     style.innerHTML = this.select + ' { outline: red 2px solid }';
434     container.appendChild (style);
435    
436     container.appendChild (msgContainer);
437     container.appendChild (buttonContainer);
438     doc.documentElement.appendChild (container);
439    
440     return container;
441     }, // _render
442     remove: function () {
443     this.hide ();
444    
445     this._remove ();
446    
447     if (this._outermostElement && this._outermostElement.parentNode) {
448     this._outermostElement.parentNode.removeChild (this._outermostElement);
449     }
450    
451     var e = new JSTE.Event ("close");
452     this.dispatchEvent (e);
453     }, // remove
454     _remove: function () {
455    
456     }, // remove
457    
458     show: function () {
459     if (!this.hidden) return;
460     this.hidden = false;
461     if (this._outermostElement) {
462     JSTE.Element.replaceClassName
463     (this._outermostElement, "jste-hidden", "jste-shown");
464     }
465    
466     var e = new JSTE.Event ("shown");
467     this.dispatchEvent (e);
468     }, // show
469     hide: function () {
470     if (this.hidden) return;
471     this.hidden = true;
472     if (this._outermostElement) {
473     JSTE.Element.replaceClassName
474     (this._outermostElement, "jste-shown", "jste-hidden");
475     }
476    
477     var e = new JSTE.Event ("hidden");
478     this.dispatchEvent (e);
479     }, // hide
480    
481     setTimeout: function () {
482     /* TODO: ... */
483    
484     }
485    
486     }); // Message
487    
488     JSTE.Message.Button =
489     new JSTE.Class (function (labelText, commandTarget, commandName, commandArgs) {
490     labelText = labelText != null ? labelText : "";
491     var className;
492     if (commandTarget && commandTarget instanceof Function) {
493     this._command = commandTarget;
494     } else if (commandTarget) {
495     this._command = function () {
496     return commandTarget.executeCommand.apply
497     (commandTarget, [commandName, commandArgs]);
498     };
499     className = 'jste-command-' + commandName;
500     } else {
501     this._command = function () { };
502     }
503    
504     try {
505     this.element = document.createElement ('button');
506     this.element.setAttribute ('type', 'button');
507     } catch (e) {
508     this.element = document.createElement ('<button type=button>');
509     }
510     JSTE.Element.appendText (this.element, labelText);
511     if (className) this.element.className = className;
512    
513     var self = this;
514     new JSTE.Observer ("click", this.element, function (e) {
515     self._command.apply (self, [e]);
516     });
517     }, {
518    
519     }); // Button
520    
521     JSTE.Course = new JSTE.Class (function (doc) {
522     this._targetDocument = doc;
523    
524     this._entryPointsByURL = {};
525     this._entryPointsById = {};
526     this._entryPointsByClassName = {};
527    
528     this._stepsState = new JSTE.List ([new JSTE.Hash]);
529     this._steps = new JSTE.Hash;
530    
531     var nullState = new JSTE.Step;
532     nullState.uid = "";
533     this._steps.setNamedItem (nullState.uid, nullState);
534     this._initialStepUid = nullState.uid;
535     }, {
536     _processStepsContent: function (el) {
537     var self = this;
538     new JSTE.List (el.childNodes).switchByElementType (
539     new JSTE.List.SwitchByLocalName (JSTE.WATNS, {
540     steps: function (n) { self._processStepsElement (n) },
541     step: function (n) { self._processStepElement (n) },
542     jump: function (n) { self._processJumpElement (n) },
543     entry: function (n) { self._processEntryElement (n) }
544     })
545     );
546     }, // _processStepsContent
547     _processStepsElement: function (e) {
548     this._stepsState.pushCloneOfLast ();
549     this._stepsState.getLast ().prevStep = null;
550     this._processStepsContent (e);
551     this._stepsState.pop ();
552     }, // _processStepsElement
553    
554     _processEntryElement: function (e) {
555     if (JSTE.Element.hasAttribute (e, 'url')) {
556     this.setEntryPointByURL
557     (e.getAttribute ('url'), e.getAttribute ('step'));
558     } else if (JSTE.Element.hasAttribute (e, 'root-id')) {
559     this.setEntryPointById
560     (e.getAttribute ('root-id'), e.getAttribute ('step'));
561     } else if (JSTE.Element.hasAttribute (e, 'root-class')) {
562     this.setEntryPointByClassName
563     (e.getAttribute ('root-class'), e.getAttribute ('step'));
564     }
565     }, // _processEntryElement
566     setEntryPointByURL: function (url, stepName) {
567     this._entryPointsByURL[url] = stepName || '';
568     }, // setEntryPointByURL
569     setEntryPointById: function (id, stepName) {
570     this._entryPointsById[id] = stepName || '';
571     }, // setEntryPointById
572     setEntryPointByClassName: function (className, stepName) {
573     this._entryPointsByClassName[className] = stepName || '';
574     }, // setEntryPointByClassName
575     findEntryPoint: function (doc) {
576     var self = this;
577     var td = this._targetDocument;
578     var stepName;
579    
580     var url = doc.URL;
581     if (url) {
582     stepName = self._entryPointsByURL[url];
583     if (stepName) return 'id-' + stepName;
584     }
585    
586     var docEl = td.documentElement;
587     if (docEl) {
588     var docElId = JSTE.Element.getIds (docEl).forEach (function (i) {
589     stepName = self._entryPointsById[i];
590     if (stepName) return new JSTE.List.Return (stepName);
591     });
592     if (stepName) return 'id-' + stepName;
593    
594     stepName = JSTE.Element.getClassNames (docEl).forEach (function (c) {
595     stepName = self._entryPointsByClassName[c];
596     if (stepName) return new JSTE.List.Return (stepName);
597     });
598     if (stepName) return 'id-' + stepName;
599     }
600    
601     var bodyEl = td.body;
602     if (bodyEl) {
603     var bodyElId = JSTE.Element.getIds (bodyEl).forEach (function (i) {
604     stepName = self._entryPointsById[i];
605     if (stepName) return new JSTE.List.Return (stepName);
606     });
607     if (stepName) return 'id-' + stepName;
608    
609     stepName = JSTE.Element.getClassNames (bodyEl).forEach (function (c) {
610     stepName = self._entryPointsByClassName[c];
611     if (stepName) return new JSTE.List.Return (stepName);
612     });
613     if (stepName) return 'id-' + stepName;
614     }
615    
616     return this._initialStepUid;
617     }, // findEntryPoint
618    
619     _processStepElement: function (e) {
620     var step = new JSTE.Step (e.getAttribute ('id'));
621     step.setPreviousStep (this._stepsState.getLast ().prevStep);
622     step.select = e.getAttribute ('select') || "";
623     step.nextEvents.append
624     (JSTE.List.SpaceSeparated (e.getAttribute ('next-event')));
625     var msgEl = JSTE.Element.getChildElement (e, JSTE.WATNS, 'message');
626     if (msgEl) {
627     var msg = JSTE.Element.createTemplate (this._targetDocument, msgEl);
628     step.setMessageTemplate (msg);
629     }
630     var nextEls = JSTE.Element.getChildElements (e, JSTE.WATNS, 'next-step');
631     if (nextEls.length) {
632     nextEls.forEach (function (nextEl) {
633     step.addNextStep
634     (nextEl.getAttribute ('if'), nextEl.getAttribute ('step'));
635     });
636     this._stepsState.getLast ().prevStep = null;
637     } else {
638     this._stepsState.getLast ().prevStep = step;
639     }
640     /* TODO: @save */
641    
642     this._steps.setNamedItem (step.uid, step);
643     if (!this._initialStepUid) {
644     this._initialStepUid = step.uid;
645     }
646     }, // _processStepElement
647    
648     _processJumpElement: function (e) {
649    
650     }, // _processJumpElement
651    
652     getStep: function (uid) {
653     return this._steps.getNamedItem (uid);
654     } // getStep
655     }); // Course
656    
657     JSTE.Course.createFromDocument = function (doc, targetDoc) {
658     var course = new JSTE.Course (targetDoc);
659     var docEl = doc.documentElement;
660     if (!docEl) return course;
661     if (!JSTE.Element.match (docEl, JSTE.WATNS, 'course')) return course;
662     course._processStepsContent (docEl);
663     return course;
664     }; // createFromDocument
665    
666     JSTE.Step = new JSTE.Class (function (id) {
667     if (id != null && id != '') {
668     this.uid = 'id-' + id;
669     } else {
670     this.uid = 'rand-' + Math.random ();
671     }
672     this._nextSteps = new JSTE.List;
673     this.nextEvents = new JSTE.List;
674     this.select = "";
675     }, {
676     setMessageTemplate: function (msg) {
677     this._messageTemplate = msg;
678     }, // setMessageTemplate
679     hasMessage: function () {
680     return this._messageTemplate ? true : false;
681     }, // hasMessage
682     createMessage: function (msg, doc, commandTarget) {
683     var msg;
684     if (this._messageTemplate) {
685     var clone = JSTE.Element.createTemplate (doc, this._messageTemplate);
686     msg = new msg (doc, clone, commandTarget);
687     } else {
688     msg = new msg (doc, null, commandTarget);
689     }
690     msg.select = this.select;
691     return msg;
692     }, // createMessage
693    
694     addNextStep: function (condition, stepId) {
695     this._nextSteps.push ([condition, stepId]);
696     }, // addNextStep
697     setPreviousStep: function (prevStep) {
698     if (!prevStep) return;
699     if (prevStep._defaultNextStepUid) return;
700     prevStep._defaultNextStepUid = this.uid;
701     }, // setPreviousStep
702    
703     getNextStepUid: function (doc) {
704     var m = this._nextSteps.getFirstMatch (function (item) {
705     var condition = item[0];
706     if (condition) {
707     return JSTE.Node.querySelector (doc, condition) != null;
708     } else {
709     return true;
710     }
711     });
712     if (m) {
713     return 'id-' + m[1];
714     } else if (this._defaultNextStepUid) {
715     return this._defaultNextStepUid;
716     } else {
717     return null;
718     }
719     } // getNextStepUid
720    
721     }); // Step
722    
723     /* Events: load, error */
724     JSTE.Tutorial = new JSTE.Class (function (doc, course, args) {
725     this._course = course;
726     this._targetDocument = doc;
727     this._messageClass = JSTE.Message;
728     if (args) {
729     if (args.messageClass) this._messageClass = args.messageClass;
730     }
731    
732     this._currentMessages = new JSTE.List;
733     this._currentObservers = new JSTE.List;
734     this._prevStepUids = new JSTE.List;
735    
736     var stepUid = this._course.findEntryPoint (document);
737     this._currentStep = this._getStepOrError (stepUid);
738     if (this._currentStep) {
739     var e = new JSTE.Event ('load');
740     this.dispatchEvent (e);
741    
742     this._renderCurrentStep ();
743     return this;
744     } else {
745     return {};
746     }
747     }, {
748     _getStepOrError: function (stepUid) {
749     var step = this._course.getStep (stepUid);
750     if (step) {
751     return step;
752     } else {
753     var e = new JSTE.Event ('error');
754     e.errorMessage = 'Step not found';
755     e.errorArguments = [this._currentStepUid];
756     this.dispatchEvent (e);
757     return null;
758     }
759     }, // _getStepOrError
760    
761     _renderCurrentStep: function () {
762     var self = this;
763     var step = this._currentStep;
764    
765     /* Message */
766     var msg = step.createMessage
767     (this._messageClass, this._targetDocument, this);
768     msg.render ();
769     this._currentMessages.push (msg);
770    
771     /* Next-events */
772     var selectedNodes = JSTE.Node.querySelectorAll
773     (this._targetDocument, step.select);
774     var handler = function () {
775     self.executeCommand ("next");
776     };
777     selectedNodes.forEach (function (node) {
778     step.nextEvents.forEach (function (eventType) {
779     self._currentObservers.push
780     (new JSTE.Observer (eventType, node, handler));
781     });
782     });
783     }, // _renderCurrentStep
784     clearMessages: function () {
785     this._currentMessages.forEach (function (msg) {
786     msg.remove ();
787     });
788     this._currentMessages.clear ();
789    
790     this._currentObservers.forEach (function (ob) {
791     ob.stop ();
792     });
793     this._currentObservers.clear ();
794     }, // clearMessages
795    
796     executeCommand: function (commandName, commandArgs) {
797     if (this[commandName]) {
798     return this[commandName].apply (this, commandArgs || []);
799     } else {
800     var e = new JSTE.Event ('error');
801     e.errorMessage = 'Command not found';
802     e.errorArguments = [commandName];
803     return null;
804     }
805     }, // executeCommand
806    
807     startTutorial: function () {
808     this.resetVisited ();
809    
810     }, // startTutorial
811     continueTutorial: function () {
812    
813     }, // continueTutorial
814    
815     saveVisited: function () {
816    
817     }, // saveVisited
818     resetVisited: function () {
819    
820     }, // resetVisited
821    
822     back: function () {
823     var prevStepUid = this._prevStepUids.pop ();
824     var prevStep = this._getStepOrError (prevStepUid);
825     if (prevStep) {
826     this.clearMessages ();
827     this._currentStep = prevStep;
828     this._renderCurrentStep ();
829     }
830     }, // back
831     next: function () {
832     var nextStepUid = this._currentStep.getNextStepUid (this._targetDocument);
833     var nextStep = this._getStepOrError (nextStepUid);
834     if (nextStep) {
835     this._prevStepUids.push (this._currentStep.uid);
836     this.clearMessages ();
837     this._currentStep = nextStep;
838     this._renderCurrentStep ();
839     }
840     } // next
841    
842     }); // Tutorial

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24