2150 |
mathias |
1 |
if(!dojo._hasResource["dojox.presentation._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
|
|
2 |
dojo._hasResource["dojox.presentation._base"] = true;
|
|
|
3 |
dojo.provide("dojox.presentation._base");
|
|
|
4 |
dojo.experimental("dojox.presentation");
|
|
|
5 |
|
|
|
6 |
dojo.require("dijit._Widget");
|
|
|
7 |
dojo.require("dijit._Container");
|
|
|
8 |
dojo.require("dijit._Templated");
|
|
|
9 |
dojo.require("dijit.layout.StackContainer");
|
|
|
10 |
dojo.require("dijit.layout.ContentPane");
|
|
|
11 |
dojo.require("dojo.fx");
|
|
|
12 |
|
|
|
13 |
dojo.declare("dojox.presentation.Deck", [ dijit.layout.StackContainer, dijit._Templated ], {
|
|
|
14 |
// summary:
|
|
|
15 |
// dojox.presentation class
|
|
|
16 |
// basic powerpoint esque engine for handling transitons and control
|
|
|
17 |
// in a page-by-page and part-by-part way
|
|
|
18 |
//
|
|
|
19 |
// FIXME: parsing part(s)/widget(s) in href="" Slides not working
|
|
|
20 |
// TODO: make auto actions progress.
|
|
|
21 |
// FIXME: Safari keydown/press/up listener not working.
|
|
|
22 |
// noClick=true prevents progression of slides in that broweser
|
|
|
23 |
//
|
|
|
24 |
// fullScreen: Boolean
|
|
|
25 |
// unsupported (that i know of) just yet. Default it to take control
|
|
|
26 |
// of window. Would be nice to be able to contain presentation in a
|
|
|
27 |
// styled container, like StackContainer ... theoretically possible.
|
|
|
28 |
// [and may not need this variable?]
|
|
|
29 |
fullScreen: true,
|
|
|
30 |
|
|
|
31 |
// useNav: Boolean
|
|
|
32 |
// true to allow navigation popup, false to disallow
|
|
|
33 |
useNav: true,
|
|
|
34 |
|
|
|
35 |
// navDuration: Integer
|
|
|
36 |
// time in MS fadein/out of popup nav [default: 250]
|
|
|
37 |
navDuration: 250,
|
|
|
38 |
|
|
|
39 |
// noClick: Boolean
|
|
|
40 |
// if true, prevents _any_ click events to propagate actions
|
|
|
41 |
// (limiting control to keyboard and/or action.on="auto" or action.delay=""
|
|
|
42 |
// actions.
|
|
|
43 |
noClick: false,
|
|
|
44 |
|
|
|
45 |
// setHash: Boolean
|
|
|
46 |
// if true, window location bar will get a #link to slide for direct
|
|
|
47 |
// access to a particular slide number.
|
|
|
48 |
setHash: true,
|
|
|
49 |
|
|
|
50 |
// just to over-ride:
|
|
|
51 |
templateString: null,
|
|
|
52 |
templateString:"<div class=\"dojoShow\" dojoAttachPoint=\"showHolder\">\n\t<div class=\"dojoShowNav\" dojoAttachPoint=\"showNav\" dojoAttachEvent=\"onmouseover: _showNav, onmouseout: _hideNav\">\n\t<div class=\"dojoShowNavToggler\" dojoAttachPoint=\"showToggler\">\n\t\t<img dojoAttachPoint=\"prevNode\" src=\"${prevIcon}\" dojoAttachEvent=\"onclick:previousSlide\">\n\t\t<select dojoAttachEvent=\"onchange:_onEvent\" dojoAttachPoint=\"select\">\n\t\t\t<option dojoAttachPoint=\"_option\">Title</option>\n\t\t</select>\n\t\t<img dojoAttachPoint=\"nextNode\" src=\"${nextIcon}\" dojoAttachEvent=\"onclick:nextSlide\">\n\t</div>\n\t</div>\n\t<div dojoAttachPoint=\"containerNode\"></div>\n</div>\n",
|
|
|
53 |
|
|
|
54 |
// nextIcon: String
|
|
|
55 |
// icon for navigation "next" button
|
|
|
56 |
nextIcon: dojo.moduleUrl('dojox.presentation','resources/icons/next.png'),
|
|
|
57 |
|
|
|
58 |
// prevIcon: String
|
|
|
59 |
// icon for navigation "previous" button
|
|
|
60 |
prevIcon: dojo.moduleUrl('dojox.presentation','resources/icons/prev.png'),
|
|
|
61 |
|
|
|
62 |
_navOpacMin: 0,
|
|
|
63 |
_navOpacMax: 0.85,
|
|
|
64 |
_slideIndex: 0,
|
|
|
65 |
|
|
|
66 |
// Private:
|
|
|
67 |
_slides: [],
|
|
|
68 |
_navShowing: true,
|
|
|
69 |
_inNav: false,
|
|
|
70 |
|
|
|
71 |
startup: function(){
|
|
|
72 |
// summary: connect to the various handlers and controls for this presention
|
|
|
73 |
dojox.presentation.Deck.superclass.startup.call(this);
|
|
|
74 |
|
|
|
75 |
if(this.useNav){
|
|
|
76 |
this._hideNav();
|
|
|
77 |
}else{
|
|
|
78 |
this.showNav.style.display = "none";
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
this.connect(document,'onclick', '_onEvent');
|
|
|
82 |
this.connect(document,'onkeypress', '_onEvent');
|
|
|
83 |
|
|
|
84 |
// only if this.fullScreen == true?
|
|
|
85 |
this.connect(window, 'onresize', '_resizeWindow');
|
|
|
86 |
this._resizeWindow();
|
|
|
87 |
|
|
|
88 |
this._updateSlides();
|
|
|
89 |
|
|
|
90 |
this._readHash();
|
|
|
91 |
this._setHash();
|
|
|
92 |
},
|
|
|
93 |
|
|
|
94 |
moveTo: function(/* Integer */ number){
|
|
|
95 |
// summary: jump to slide based on param
|
|
|
96 |
var slideIndex = number - 1;
|
|
|
97 |
|
|
|
98 |
if(slideIndex < 0)
|
|
|
99 |
slideIndex = 0;
|
|
|
100 |
|
|
|
101 |
if(slideIndex > this._slides.length - 1)
|
|
|
102 |
slideIndex = this._slides.length - 1;
|
|
|
103 |
|
|
|
104 |
this._gotoSlide(slideIndex);
|
|
|
105 |
},
|
|
|
106 |
|
|
|
107 |
onMove: function (number){
|
|
|
108 |
// summary: stub function? TODOC: ?
|
|
|
109 |
},
|
|
|
110 |
|
|
|
111 |
nextSlide: function(/*Event*/ evt){
|
|
|
112 |
// summary: transition to the next slide.
|
|
|
113 |
if (!this.selectedChildWidget.isLastChild) {
|
|
|
114 |
this._gotoSlide(this._slideIndex+1);
|
|
|
115 |
}
|
|
|
116 |
if (evt) { evt.stopPropagation(); }
|
|
|
117 |
},
|
|
|
118 |
|
|
|
119 |
previousSlide: function(/*Event*/ evt){
|
|
|
120 |
// summary: transition to the previous slide
|
|
|
121 |
if (!this.selectedChildWidget.isFirstChild) {
|
|
|
122 |
|
|
|
123 |
this._gotoSlide(this._slideIndex-1);
|
|
|
124 |
|
|
|
125 |
} else { this.selectedChildWidget._reset(); }
|
|
|
126 |
if (evt) { evt.stopPropagation();}
|
|
|
127 |
},
|
|
|
128 |
|
|
|
129 |
getHash: function(id){
|
|
|
130 |
// summary: get the current hash to set in localtion
|
|
|
131 |
return this.id+"_SlideNo_"+id;
|
|
|
132 |
},
|
|
|
133 |
|
|
|
134 |
_hideNav: function(evt){
|
|
|
135 |
// summary: hides navigation
|
|
|
136 |
if(this._navAnim){ this._navAnim.stop(); }
|
|
|
137 |
this._navAnim = dojo.animateProperty({
|
|
|
138 |
node:this.showNav,
|
|
|
139 |
duration:this.navDuration,
|
|
|
140 |
properties: {
|
|
|
141 |
opacity: { end:this._navOpacMin }
|
|
|
142 |
}
|
|
|
143 |
}).play();
|
|
|
144 |
},
|
|
|
145 |
|
|
|
146 |
_showNav: function(evt){
|
|
|
147 |
// summary: shows navigation
|
|
|
148 |
if(this._navAnim){ this._navAnim.stop(); }
|
|
|
149 |
this._navAnim = dojo.animateProperty({
|
|
|
150 |
node:this.showNav,
|
|
|
151 |
duration:this.navDuration,
|
|
|
152 |
properties: {
|
|
|
153 |
opacity: { end:this._navOpacMax }
|
|
|
154 |
}
|
|
|
155 |
}).play();
|
|
|
156 |
},
|
|
|
157 |
|
|
|
158 |
_handleNav: function(evt){
|
|
|
159 |
// summary: does nothing? _that_ seems useful.
|
|
|
160 |
evt.stopPropagation();
|
|
|
161 |
},
|
|
|
162 |
|
|
|
163 |
_updateSlides: function(){
|
|
|
164 |
// summary:
|
|
|
165 |
// populate navigation select list with refs to slides call this
|
|
|
166 |
// if you add a node to your presentation dynamically.
|
|
|
167 |
this._slides = this.getChildren();
|
|
|
168 |
if(this.useNav){
|
|
|
169 |
// populate the select box with top-level slides
|
|
|
170 |
var i=0;
|
|
|
171 |
dojo.forEach(this._slides,dojo.hitch(this,function(slide){
|
|
|
172 |
i++;
|
|
|
173 |
var tmp = this._option.cloneNode(true);
|
|
|
174 |
tmp.text = slide.title+" ("+i+") ";
|
|
|
175 |
this._option.parentNode.insertBefore(tmp,this._option);
|
|
|
176 |
}));
|
|
|
177 |
if(this._option.parentNode){
|
|
|
178 |
this._option.parentNode.removeChild(this._option);
|
|
|
179 |
}
|
|
|
180 |
// dojo._destroyElement(this._option);
|
|
|
181 |
}
|
|
|
182 |
},
|
|
|
183 |
|
|
|
184 |
_onEvent: function(/* Event */ evt){
|
|
|
185 |
// summary:
|
|
|
186 |
// main presentation function, determines next 'best action' for a
|
|
|
187 |
// specified event.
|
|
|
188 |
var _node = evt.target;
|
|
|
189 |
var _type = evt.type;
|
|
|
190 |
|
|
|
191 |
if(_type == "click" || _type == "change"){
|
|
|
192 |
if(_node.index && _node.parentNode == this.select){
|
|
|
193 |
this._gotoSlide(_node.index);
|
|
|
194 |
}else if(_node == this.select){
|
|
|
195 |
this._gotoSlide(_node.selectedIndex);
|
|
|
196 |
}else{
|
|
|
197 |
if (this.noClick || this.selectedChildWidget.noClick || this._isUnclickable(evt)) return;
|
|
|
198 |
this.selectedChildWidget._nextAction(evt);
|
|
|
199 |
}
|
|
|
200 |
}else if(_type=="keydown" || _type == "keypress"){
|
|
|
201 |
|
|
|
202 |
// FIXME: safari doesn't report keydown/keypress?
|
|
|
203 |
|
|
|
204 |
var key = (evt.charCode == dojo.keys.SPACE ? dojo.keys.SPACE : evt.keyCode);
|
|
|
205 |
switch(key){
|
|
|
206 |
case dojo.keys.DELETE:
|
|
|
207 |
case dojo.keys.BACKSPACE:
|
|
|
208 |
case dojo.keys.LEFT_ARROW:
|
|
|
209 |
case dojo.keys.UP_ARROW:
|
|
|
210 |
case dojo.keys.PAGE_UP:
|
|
|
211 |
case 80: // key 'p'
|
|
|
212 |
this.previousSlide(evt);
|
|
|
213 |
break;
|
|
|
214 |
|
|
|
215 |
case dojo.keys.ENTER:
|
|
|
216 |
case dojo.keys.SPACE:
|
|
|
217 |
case dojo.keys.RIGHT_ARROW:
|
|
|
218 |
case dojo.keys.DOWN_ARROW:
|
|
|
219 |
case dojo.keys.PAGE_DOWN:
|
|
|
220 |
case 78: // key 'n'
|
|
|
221 |
this.selectedChildWidget._nextAction(evt);
|
|
|
222 |
break;
|
|
|
223 |
|
|
|
224 |
case dojo.keys.HOME: this._gotoSlide(0);
|
|
|
225 |
}
|
|
|
226 |
}
|
|
|
227 |
this._resizeWindow();
|
|
|
228 |
evt.stopPropagation();
|
|
|
229 |
},
|
|
|
230 |
|
|
|
231 |
_gotoSlide: function(/* Integer */ slideIndex){
|
|
|
232 |
// summary: goes to slide
|
|
|
233 |
this.selectChild(this._slides[slideIndex]);
|
|
|
234 |
this.selectedChildWidget._reset();
|
|
|
235 |
|
|
|
236 |
this._slideIndex = slideIndex;
|
|
|
237 |
|
|
|
238 |
if(this.useNav){
|
|
|
239 |
this.select.selectedIndex = slideIndex;
|
|
|
240 |
}
|
|
|
241 |
|
|
|
242 |
if(this.setHash){
|
|
|
243 |
this._setHash();
|
|
|
244 |
}
|
|
|
245 |
this.onMove(this._slideIndex+1);
|
|
|
246 |
},
|
|
|
247 |
|
|
|
248 |
_isUnclickable: function(/* Event */ evt){
|
|
|
249 |
// summary: returns true||false base of a nodes click-ability
|
|
|
250 |
var nodeName = evt.target.nodeName.toLowerCase();
|
|
|
251 |
// TODO: check for noClick='true' in target attrs & return true
|
|
|
252 |
// TODO: check for relayClick='true' in target attrs & return false
|
|
|
253 |
switch(nodeName){
|
|
|
254 |
case 'a' :
|
|
|
255 |
case 'input' :
|
|
|
256 |
case 'textarea' : return true; break;
|
|
|
257 |
}
|
|
|
258 |
return false;
|
|
|
259 |
},
|
|
|
260 |
|
|
|
261 |
_readHash: function(){
|
|
|
262 |
var th = window.location.hash;
|
|
|
263 |
if (th.length && this.setHash) {
|
|
|
264 |
var parts = (""+window.location).split(this.getHash(''));
|
|
|
265 |
if(parts.length>1){
|
|
|
266 |
this._gotoSlide(parseInt(parts[1])-1);
|
|
|
267 |
}
|
|
|
268 |
}
|
|
|
269 |
},
|
|
|
270 |
|
|
|
271 |
_setHash: function(){
|
|
|
272 |
// summary: sets url #mark to direct slide access
|
|
|
273 |
if(this.setHash){
|
|
|
274 |
var slideNo = this._slideIndex+1;
|
|
|
275 |
window.location.href = "#"+this.getHash(slideNo);
|
|
|
276 |
}
|
|
|
277 |
},
|
|
|
278 |
|
|
|
279 |
_resizeWindow: function(/*Event*/ evt){
|
|
|
280 |
// summary: resize this and children to fix this window/container
|
|
|
281 |
|
|
|
282 |
// only if this.fullScreen?
|
|
|
283 |
dojo.body().style.height = "auto";
|
|
|
284 |
var wh = dijit.getViewport();
|
|
|
285 |
var h = Math.max(
|
|
|
286 |
document.documentElement.scrollHeight || dojo.body().scrollHeight,
|
|
|
287 |
wh.h);
|
|
|
288 |
var w = wh.w;
|
|
|
289 |
this.selectedChildWidget.domNode.style.height = h +'px';
|
|
|
290 |
this.selectedChildWidget.domNode.style.width = w +'px';
|
|
|
291 |
},
|
|
|
292 |
|
|
|
293 |
_transition: function(newWidget,oldWidget){
|
|
|
294 |
// summary: over-ride stackcontainers _transition method
|
|
|
295 |
// but atm, i find it to be ugly with not way to call
|
|
|
296 |
// _showChild() without over-riding it too. hopefull
|
|
|
297 |
// basic toggles in superclass._transition will be available
|
|
|
298 |
// in dijit, and this won't be necessary.
|
|
|
299 |
var anims = [];
|
|
|
300 |
if(oldWidget){
|
|
|
301 |
/*
|
|
|
302 |
anims.push(dojo.fadeOut({ node: oldWidget.domNode,
|
|
|
303 |
duration:250,
|
|
|
304 |
onEnd: dojo.hitch(this,function(){
|
|
|
305 |
this._hideChild(oldWidget);
|
|
|
306 |
})
|
|
|
307 |
}));
|
|
|
308 |
*/
|
|
|
309 |
this._hideChild(oldWidget);
|
|
|
310 |
}
|
|
|
311 |
if(newWidget){
|
|
|
312 |
/*
|
|
|
313 |
anims.push(dojo.fadeIn({
|
|
|
314 |
node:newWidget.domNode, start:0, end:1,
|
|
|
315 |
duration:300,
|
|
|
316 |
onEnd: dojo.hitch(this,function(){
|
|
|
317 |
this._showChild(newWidget);
|
|
|
318 |
newWidget._reset();
|
|
|
319 |
})
|
|
|
320 |
})
|
|
|
321 |
);
|
|
|
322 |
*/
|
|
|
323 |
this._showChild(newWidget);
|
|
|
324 |
newWidget._reset();
|
|
|
325 |
}
|
|
|
326 |
//dojo.fx.combine(anims).play();
|
|
|
327 |
}
|
|
|
328 |
});
|
|
|
329 |
|
|
|
330 |
dojo.declare(
|
|
|
331 |
"dojox.presentation.Slide",
|
|
|
332 |
[dijit.layout.ContentPane,dijit._Contained,dijit._Container,dijit._Templated],
|
|
|
333 |
{
|
|
|
334 |
// summary:
|
|
|
335 |
// a Comonent of a dojox.presentation, and container for each 'Slide'
|
|
|
336 |
// made up of direct HTML (no part/action relationship), and dojox.presentation.Part(s),
|
|
|
337 |
// and their attached Actions.
|
|
|
338 |
|
|
|
339 |
// templatPath: String
|
|
|
340 |
// make a ContentPane templated, and style the 'titleNode'
|
|
|
341 |
templateString:"<div dojoAttachPoint=\"showSlide\" class=\"dojoShowPrint dojoShowSlide\">\n\t<h1 class=\"showTitle\" dojoAttachPoint=\"slideTitle\"><span class=\"dojoShowSlideTitle\" dojoAttachPoint=\"slideTitleText\">${title}</span></h1>\n\t<div class=\"dojoShowBody\" dojoAttachPoint=\"containerNode\"></div>\n</div>\n",
|
|
|
342 |
|
|
|
343 |
// title: String
|
|
|
344 |
// string to insert into titleNode, title of Slide
|
|
|
345 |
title: "",
|
|
|
346 |
|
|
|
347 |
// inherited from ContentPane FIXME: don't seem to work ATM?
|
|
|
348 |
refreshOnShow: true,
|
|
|
349 |
preLoad: false,
|
|
|
350 |
doLayout: true,
|
|
|
351 |
parseContent: true,
|
|
|
352 |
|
|
|
353 |
// noClick: Boolean
|
|
|
354 |
// true on slide tag prevents clicking, false allows
|
|
|
355 |
// (can also be set on base presentation for global control)
|
|
|
356 |
noClick: false,
|
|
|
357 |
|
|
|
358 |
// private holders:
|
|
|
359 |
_parts: [],
|
|
|
360 |
_actions: [],
|
|
|
361 |
_actionIndex: 0,
|
|
|
362 |
_runningDelay: false,
|
|
|
363 |
|
|
|
364 |
startup: function(){
|
|
|
365 |
// summary: setup this slide with actions and components (Parts)
|
|
|
366 |
this.slideTitleText.innerHTML = this.title;
|
|
|
367 |
var children = this.getChildren();
|
|
|
368 |
this._actions = [];
|
|
|
369 |
dojo.forEach(children,function(child){
|
|
|
370 |
var tmpClass = child.declaredClass.toLowerCase();
|
|
|
371 |
switch(tmpClass){
|
|
|
372 |
case "dojox.presentation.part" : this._parts.push(child); break;
|
|
|
373 |
case "dojox.presentation.action" : this._actions.push(child); break;
|
|
|
374 |
}
|
|
|
375 |
},this);
|
|
|
376 |
},
|
|
|
377 |
|
|
|
378 |
|
|
|
379 |
_nextAction: function(evt){
|
|
|
380 |
// summary: gotoAndPlay current cached action
|
|
|
381 |
var tmpAction = this._actions[this._actionIndex] || 0;
|
|
|
382 |
if (tmpAction){
|
|
|
383 |
// is this action a delayed action? [auto? thoughts?]
|
|
|
384 |
if(tmpAction.on == "delay"){
|
|
|
385 |
this._runningDelay = setTimeout(
|
|
|
386 |
dojo.hitch(tmpAction,"_runAction"),tmpAction.delay
|
|
|
387 |
);
|
|
|
388 |
console.debug('started delay action',this._runningDelay);
|
|
|
389 |
}else{
|
|
|
390 |
tmpAction._runAction();
|
|
|
391 |
}
|
|
|
392 |
|
|
|
393 |
// FIXME: it gets hairy here. maybe runAction should
|
|
|
394 |
// call _actionIndex++ onEnd? if a delayed action is running, do
|
|
|
395 |
// we want to prevent action++?
|
|
|
396 |
var tmpNext = this._getNextAction();
|
|
|
397 |
this._actionIndex++;
|
|
|
398 |
|
|
|
399 |
if(tmpNext.on == "delay"){
|
|
|
400 |
// FIXME: yeah it looks like _runAction() onend should report
|
|
|
401 |
// _actionIndex++
|
|
|
402 |
console.debug('started delay action',this._runningDelay);
|
|
|
403 |
setTimeout(dojo.hitch(tmpNext,"_runAction"),tmpNext.delay);
|
|
|
404 |
}
|
|
|
405 |
}else{
|
|
|
406 |
// no more actions in this slide
|
|
|
407 |
this.getParent().nextSlide(evt);
|
|
|
408 |
}
|
|
|
409 |
},
|
|
|
410 |
|
|
|
411 |
_getNextAction: function(){
|
|
|
412 |
// summary: returns the _next action in this sequence
|
|
|
413 |
return this._actions[this._actionIndex+1] || 0;
|
|
|
414 |
},
|
|
|
415 |
|
|
|
416 |
_reset: function(){
|
|
|
417 |
// summary: set action chain back to 0 and re-init each Part
|
|
|
418 |
this._actionIndex = [0];
|
|
|
419 |
dojo.forEach(this._parts,function(part){
|
|
|
420 |
part._reset();
|
|
|
421 |
},this);
|
|
|
422 |
}
|
|
|
423 |
});
|
|
|
424 |
|
|
|
425 |
dojo.declare("dojox.presentation.Part", [dijit._Widget,dijit._Contained], {
|
|
|
426 |
// summary:
|
|
|
427 |
// a node in a presentation.Slide that inherits control from a
|
|
|
428 |
// dojox.presentation.Action
|
|
|
429 |
// can be any element type, and requires styling before parsing
|
|
|
430 |
//
|
|
|
431 |
// as: String
|
|
|
432 |
// like an ID, attach to Action via (part) as="" / (action) forSlide="" tags
|
|
|
433 |
// this should be unique identifier?
|
|
|
434 |
as: null,
|
|
|
435 |
|
|
|
436 |
// startVisible: boolean
|
|
|
437 |
// true to leave in page on slide startup/reset
|
|
|
438 |
// false to hide on slide startup/reset
|
|
|
439 |
startVisible: false,
|
|
|
440 |
|
|
|
441 |
// isShowing: Boolean,
|
|
|
442 |
// private holder for _current_ state of Part
|
|
|
443 |
_isShowing: false,
|
|
|
444 |
|
|
|
445 |
postCreate: function(){
|
|
|
446 |
// summary: override and init() this component
|
|
|
447 |
this._reset();
|
|
|
448 |
},
|
|
|
449 |
|
|
|
450 |
_reset: function(){
|
|
|
451 |
// summary: set part back to initial calculate state
|
|
|
452 |
// these _seem_ backwards, but quickToggle flips it
|
|
|
453 |
this._isShowing =! this.startVisible;
|
|
|
454 |
this._quickToggle();
|
|
|
455 |
},
|
|
|
456 |
|
|
|
457 |
_quickToggle: function(){
|
|
|
458 |
// summary: ugly [unworking] fix to test setting state of component
|
|
|
459 |
// before/after an animation. display:none prevents fadeIns?
|
|
|
460 |
if(this._isShowing){
|
|
|
461 |
dojo.style(this.domNode,'display','none');
|
|
|
462 |
dojo.style(this.domNode,'visibility','hidden');
|
|
|
463 |
dojo.style(this.domNode,'opacity',0);
|
|
|
464 |
}else{
|
|
|
465 |
dojo.style(this.domNode,'display','');
|
|
|
466 |
dojo.style(this.domNode,'visibility','visible');
|
|
|
467 |
dojo.style(this.domNode,'opacity',1);
|
|
|
468 |
}
|
|
|
469 |
this._isShowing =! this._isShowing;
|
|
|
470 |
}
|
|
|
471 |
});
|
|
|
472 |
|
|
|
473 |
dojo.declare("dojox.presentation.Action", [dijit._Widget,dijit._Contained], {
|
|
|
474 |
// summary:
|
|
|
475 |
// a widget to attach to a dojox.presentation.Part to control
|
|
|
476 |
// it's properties based on an inherited chain of events ...
|
|
|
477 |
//
|
|
|
478 |
//
|
|
|
479 |
// on: String
|
|
|
480 |
// FIXME: only 'click' supported ATM. plans include on="delay",
|
|
|
481 |
// on="end" of="", and on="auto". those should make semantic sense
|
|
|
482 |
// to you.
|
|
|
483 |
on: 'click',
|
|
|
484 |
|
|
|
485 |
// forSlide: String
|
|
|
486 |
// attach this action to a dojox.presentation.Part with a matching 'as' attribute
|
|
|
487 |
forSlide: null,
|
|
|
488 |
|
|
|
489 |
// toggle: String
|
|
|
490 |
// will toggle attached [matching] node(s) via forSlide/as relationship(s)
|
|
|
491 |
toggle: 'fade',
|
|
|
492 |
|
|
|
493 |
// delay: Integer
|
|
|
494 |
//
|
|
|
495 |
delay: 0,
|
|
|
496 |
|
|
|
497 |
// duration: Integer
|
|
|
498 |
// default time in MS to run this action effect on it's 'forSlide' node
|
|
|
499 |
duration: 1000,
|
|
|
500 |
|
|
|
501 |
// private holders:
|
|
|
502 |
_attached: [],
|
|
|
503 |
_nullAnim: false,
|
|
|
504 |
|
|
|
505 |
_runAction: function(){
|
|
|
506 |
// summary: runs this action on attached node(s)
|
|
|
507 |
|
|
|
508 |
var anims = [];
|
|
|
509 |
// executes the action for each attached 'Part'
|
|
|
510 |
dojo.forEach(this._attached,function(node){
|
|
|
511 |
// FIXME: this is ugly, and where is toggle class? :(
|
|
|
512 |
var dir = (node._isShowing) ? "Out" : "In";
|
|
|
513 |
// node._isShowing =! node._isShowing;
|
|
|
514 |
node._quickToggle(); // (?) this is annoying
|
|
|
515 |
//var _anim = dojox.fx[ this.toggle ? this.toggle+dir : "fade"+dir]({
|
|
|
516 |
var _anim = dojo.fadeIn({
|
|
|
517 |
node:node.domNode,
|
|
|
518 |
duration: this.duration
|
|
|
519 |
//beforeBegin: dojo.hitch(node,"_quickToggle")
|
|
|
520 |
});
|
|
|
521 |
anims.push(_anim);
|
|
|
522 |
},this);
|
|
|
523 |
var _anim = dojo.fx.combine(anims);
|
|
|
524 |
if(_anim){ _anim.play(); }
|
|
|
525 |
},
|
|
|
526 |
|
|
|
527 |
_getSiblingsByType: function(/* String */ declaredClass){
|
|
|
528 |
// summary: quick replacement for getChildrenByType("class"), but in
|
|
|
529 |
// a child here ... so it's getSiblings. courtesy bill in #dojo
|
|
|
530 |
// could be moved into parent, and just call this.getChildren(),
|
|
|
531 |
// which makes more sense.
|
|
|
532 |
var siblings = dojo.filter( this.getParent().getChildren(), function(widget){
|
|
|
533 |
return widget.declaredClass==declaredClass;
|
|
|
534 |
}
|
|
|
535 |
);
|
|
|
536 |
return siblings; // dijit._Widget
|
|
|
537 |
},
|
|
|
538 |
|
|
|
539 |
postCreate: function(){
|
|
|
540 |
// summary: run this once, should this be startup: function()?
|
|
|
541 |
|
|
|
542 |
// prevent actions from being visible, _always_
|
|
|
543 |
dojo.style(this.domNode,"display","none");
|
|
|
544 |
var parents = this._getSiblingsByType('dojox.presentation.Part');
|
|
|
545 |
// create a list of "parts" we are attached to via forSlide/as
|
|
|
546 |
this._attached = [];
|
|
|
547 |
dojo.forEach(parents,function(parentPart){
|
|
|
548 |
if(this.forSlide == parentPart.as){
|
|
|
549 |
this._attached.push(parentPart);
|
|
|
550 |
}
|
|
|
551 |
},this);
|
|
|
552 |
}
|
|
|
553 |
|
|
|
554 |
});
|
|
|
555 |
|
|
|
556 |
}
|