/[suikacvs]/test/suikawebwww/style/ui/wizard.js.u8
Suika

Contents of /test/suikawebwww/style/ui/wizard.js.u8

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sun Dec 21 15:32:56 2008 UTC (17 years, 8 months ago) by wakaba
Branch: MAIN
New

1 wakaba 1.1 function WizardView (c) {
2     this.container = c;
3     this.events = [];
4     this.currentPage = -1;
5     this._init ();
6     } // WizardView
7    
8     WizardView.prototype.start = function () {
9     this.showFirstPage ();
10     this.enable ();
11     }; // start
12    
13     WizardView.prototype.enable = function () {
14     this.addClass (this.container, 'wizardview');
15    
16     var ev = new WizardView.Event ('enabled');
17     this.dispatchEvent (ev);
18     }; // enable
19    
20     WizardView.prototype.disable = function () {
21     this.deleteClass (this.container, 'wizardview');
22    
23     var ev = new WizardView.Event ('disabled');
24     this.dispatchEvent (ev);
25     }; // disable
26    
27     WizardView.prototype.getDisabled = function () {
28     return !this.hasClass (this.container, 'wizardview');
29     }; // getDisabled
30    
31     /* TODO: Hyperlink support (e.g. onhashchange) */
32    
33     WizardView.prototype._init = function () {
34     this._updateOutlineInfo ();
35     this._initPanel ();
36     this.showFirstPage ();
37     }; // _init
38    
39     WizardView.prototype._initPanel = function () {
40     var outline = this._createOutlineBox ();
41     this._insertOutlineBox (outline);
42    
43     var controller = this._createController ();
44     this._insertController (controller);
45     }; // _initPanel
46    
47     WizardView.prototype._updateOutlineInfo = function () {
48     this.pages = [];
49     this.__updateOutlineInfo (this.container, []);
50     }; // _updateOutlineInfo
51    
52     WizardView.prototype.__updateOutlineInfo = function (el, chain) {
53     var hasPage;
54     var elC = el.childNodes;
55     var elCL = elC.length;
56     for (var i = 0; i < elCL; i++) {
57     var child = elC[i];
58     if (child.nodeType == 1) {
59     if (this.isWizardContainerOrPage (child)) {
60     var newChain = chain.slice (0, chain.length);
61     newChain.push (child);
62     if (this.__updateOutlineInfo (child, newChain)) {
63     hasPage = true;
64     } else {
65     this.pages.push (newChain);
66     hasPage = true;
67     }
68     } else if (this.isTitle (child)) {
69     if (chain.length) {
70     chain[chain.length - 1].wizardTitle = this.getTitleText (child);
71     }
72     } else {
73     if (this.__updateOutlineInfo (child, chain)) {
74     hasPage = true;
75     }
76     }
77     }
78     }
79     return hasPage;
80     }; // _updateOutlineInfo
81    
82     WizardView.prototype._createOutlineBox = function () {
83     var list = document.createElement ('ol');
84     for (var i = 0; i < this.pages.length; i++) {
85     var page = this.pages[i];
86     var li = document.createElement ('li');
87     li.innerHTML = 'Page ' + (i + 1);
88     if (page[page.length - 1].wizardTitle) {
89     li.firstChild.data = page[page.length - 1].wizardTitle;
90     }
91     list.appendChild (li);
92     }
93     this.outlineBox = list;
94     return list;
95     }; // _createOutlineBox
96    
97     WizardView.prototype._markCurrentPageInOutlineBox = function (n) {
98     var list = this.outlineBox;
99     for (var i = 0; i < list.childNodes.length; i++) {
100     var li = list.childNodes[i];
101     if (i == n) {
102     this.addClass (li, 'selected');
103     } else {
104     this.deleteClass (li, 'selected');
105     }
106     }
107     }; // _markCurrentPageInOutlineBox
108    
109     WizardView.prototype.addEventListener = function (eventType, handler) {
110     if (!this.events[eventType]) this.events[eventType] = [];
111     this.events[eventType].push (handler);
112     }; // addEventListener
113    
114     WizardView.prototype.dispatchEvent = function (ev) {
115     var eventType = ev.type;
116     if (!this.events[eventType]) return true;
117     var handlers = this.events[eventType];
118     for (var i = 0; i < handlers.length; i++) {
119     handlers[i] (ev);
120     }
121     return !ev.defaultPrevented;
122     }; // dispatchEvent
123    
124     WizardView.prototype.createButton = function () {
125     var el;
126    
127     try {
128     el = document.createElement ('button');
129     el.type = 'button';
130     } catch (e) {
131     el = document.createElement ('<button type=button>');
132     }
133    
134     return el;
135     }; // createButton
136    
137     WizardView.prototype.getTextContent = function (el) {
138     var r = '';
139     var elC = el.childNodes;
140     var elCL = elC.length;
141     for (var i = 0; i < elCL; i++) {
142     var child = elC[i];
143     if (child.nodeType == 3 || child.nodeType == 4) {
144     r += child.data;
145     } else if (child.nodeType == 1) {
146     r += this.getTextContent (child);
147     }
148     }
149     return r;
150     }; // getTextContent
151    
152     WizardView.prototype.normalizeClassName = function (c) {
153     if (document.compatMode == 'BackCompat') {
154     return c.toLowerCase ();
155     } else {
156     return c;
157     }
158     }; // c
159    
160     WizardView.prototype.addClass = function (el, className) {
161     el.className += ' ' + className;
162     }; // addClass
163    
164     WizardView.prototype.deleteClass = function (el, className) {
165     var c = this.normalizeClassName (el.className).split (/\s+/);
166     className = this.normalizeClassName (className);
167     var C = [];
168     for (var i = 0; i < c.length; i++) {
169     if (c[i] != className) {
170     C.push (c[i]);
171     }
172     }
173     el.className = C.join (' ');
174     }; // deleteClass
175    
176     WizardView.prototype.hasClass = function (el, className) {
177     var c = this.normalizeClassName (el.className).split (/\s+/);
178     className = this.normalizeClassName (className);
179     for (var i = 0; i < c.length; i++) {
180     if (c[i] == className) {
181     return true;
182     }
183     }
184     return false;
185     }; // hasClass
186    
187     WizardView.prototype.getNextPageOf = function (n) {
188     while (++n < this.pages.length && n >= 0) {
189     var page = this.pages[n];
190     for (var i = 0; i < page.length; i++) {
191     if (!page[i].getAttribute ('hidden')) {
192     return n;
193     }
194     }
195     }
196     return null;
197     }; // getNextPageOf
198    
199     WizardView.prototype.getPreviousPageOf = function (n) {
200     while (--n >= 0 && n < this.pages.length) {
201     var page = this.pages[n];
202     for (var i = 0; i < page.length; i++) {
203     if (!page[i].getAttribute ('hidden')) {
204     return n;
205     }
206     }
207     }
208     return null;
209     }; // getPreviousPageOf
210    
211     WizardView.prototype.showPage = function (n) {
212     if (n == null) return;
213     if (n < 0 || n >= this.pages.length) return;
214     for (var i = 0; i < this.pages.length; i++) {
215     var page = this.pages[i];
216     for (var j = 0; j < page.length; j++) {
217     this.deleteClass (page[j], 'wizardview-active');
218     this.addClass (page[j], 'wizardview-inactive');
219     }
220     }
221     var page = this.pages[n];
222     for (var j = 0; j < page.length; j++) {
223     this.deleteClass (page[j], 'wizardview-inactive');
224     this.addClass (page[j], 'wizardview-active');
225     }
226    
227     this.currentPage = n;
228     this._markCurrentPageInOutlineBox (n);
229    
230     var ev = new WizardView.Event ('previouspagedisablednesschange');
231     ev.disabled = this.getPreviousPageOf (n) == null;
232     this.dispatchEvent (ev);
233    
234     var ev = new WizardView.Event ('nextpagedisablednesschange');
235     ev.disabled = this.getNextPageOf (n) == null;
236     this.dispatchEvent (ev);
237    
238     var ev = new WizardView.Event ('showpage');
239     ev,pageNumber = n;
240     this.dispatchEvent (ev);
241     }; // showPage
242    
243     WizardView.prototype.showFirstPage = function () {
244     this.showPage (this.getNextPageOf (-1));
245     }; // showFirstPage
246    
247     WizardView.prototype.showPreviousPage = function () {
248     this.showPage (this.getPreviousPageOf (this.currentPage));
249     }; // showPreviousPage
250    
251     WizardView.prototype.showNextPage = function () {
252     this.showPage (this.getNextPageOf (this.currentPage));
253     }; // showNextPage
254    
255    
256     WizardView.Event = function (eventType) {
257     this.type = eventType;
258     }; // Event
259    
260     WizardView.Event.prototype.preventDefault = function () {
261     this.defaultPrevented = true;
262     }; // preventDefault
263    
264    
265    
266     /* You might want to override methods below for customizing how wizard
267     pages are organized and to control page flow. */
268    
269     WizardView.prototype._insertOutlineBox = function (outline) {
270     this.container.appendChild (outline);
271     }; // _insertOutlineBox
272    
273     WizardView.prototype._createController = function () {
274     var self = this;
275    
276     var controller = document.createElement ('nav');
277    
278     var prevButton = this.createButton ();
279     prevButton.innerHTML = 'Back';
280     prevButton.onclick = function () { self.showPreviousPage () };
281     this.addEventListener ('previouspagedisablednesschange', function (e) {
282     prevButton.disabled = e.disabled;
283     });
284     controller.appendChild (prevButton);
285    
286     var nextButton = this.createButton ();
287     nextButton.innerHTML = 'Next';
288     nextButton.onclick = function () { self.showNextPage () };
289     this.addEventListener ('nextpagedisablednesschange', function (e) {
290     nextButton.disabled = e.disabled;
291     });
292     controller.appendChild (nextButton);
293    
294     var finButton = this.createButton ();
295     finButton.innerHTML = 'Finish';
296     finButton.onclick = function () { self.finish () };
297     this.addEventListener ('finishdisablednesschange', function (e) {
298     finButton.disabled = e.disabled;
299     });
300     controller.appendChild (finButton);
301    
302     var cancelButton = this.createButton ();
303     cancelButton.innerHTML = 'Cancel';
304     cancelButton.onclick = function () { self.cancel () };
305     this.addEventListener ('canceldisablednesschange', function (e) {
306     cancelButton.disabled = e.disabled;
307     });
308     controller.appendChild (cancelButton);
309    
310     return controller;
311     }; // _createController
312    
313     WizardView.prototype._insertController = function (controller) {
314     this.container.appendChild (controller);
315     }; // _insertController
316    
317     WizardView.prototype.finish = function () {
318    
319     }; // finish
320    
321     WizardView.prototype.cancel = function () {
322    
323     }; // cancel
324    
325     WizardView.prototype.isWizardContainerOrPage = function (el) {
326     var tagName = el.tagName.toLowerCase ();
327     if (tagName == 'section' ||
328     (tagName == 'div' && this.hasClass (el, 'section'))) {
329     return true;
330     } else {
331     return false;
332     }
333     }; // isWizardContainerOrPage
334    
335     WizardView.prototype.isTitle = function (el) {
336     if (el.tagName.match (/^[Hh][1-6]$/)) {
337     return true;
338     } else {
339     return false;
340     }
341     }; // isTitle
342    
343     WizardView.prototype.getTitleText = function (el) {
344     return el.title.length ? el.title : this.getTextContent (el);
345     }; // getTitleText
346    
347     if (window.WizardViewOnLoad) window.WizardViewOnLoad ();
348    
349     /*
350    
351     Usage:
352    
353     <script src="http://suika.fam.cx/www/style/ui/wizard.js" charset=utf-8></script>
354     <script>
355     window.onload = function () {
356     var w = new WizardView (container);
357     w.enable ();
358     };
359     </script>
360    
361     */
362    
363     /* ***** BEGIN LICENSE BLOCK *****
364     * Version: MPL 1.1/GPL 2.0/LGPL 2.1
365     *
366     * The contents of this file are subject to the Mozilla Public License Version
367     * 1.1 (the "License"); you may not use this file except in compliance with
368     * the License. You may obtain a copy of the License at
369     * <http://www.mozilla.org/MPL/>
370     *
371     * Software distributed under the License is distributed on an "AS IS" basis,
372     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
373     * for the specific language governing rights and limitations under the
374     * License.
375     *
376     * The Original Code is WizardView code.
377     *
378     * The Initial Developer of the Original Code is
379     * Wakaba <[email protected]>.
380     * Portions created by the Initial Developer are Copyright (C) 2008
381     * the Initial Developer. All Rights Reserved.
382     *
383     * Contributor(s):
384     * Wakaba <[email protected]>
385     *
386     * Alternatively, the contents of this file may be used under the terms of
387     * either the GNU General Public License Version 2 or later (the "GPL"), or
388     * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
389     * in which case the provisions of the GPL or the LGPL are applicable instead
390     * of those above. If you wish to allow use of your version of this file only
391     * under the terms of either the GPL or the LGPL, and not to allow others to
392     * use your version of this file under the terms of the MPL, indicate your
393     * decision by deleting the provisions above and replace them with the notice
394     * and other provisions required by the GPL or the LGPL. If you do not delete
395     * the provisions above, a recipient may use your version of this file under
396     * the terms of any one of the MPL, the GPL or the LGPL.
397     *
398     * ***** END LICENSE BLOCK ***** */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24