Skip to content

Commit

Permalink
fixes #15879, Allow insertion and removal in Rotator
Browse files Browse the repository at this point in the history
  • Loading branch information
jason0x43 authored and dylans committed Feb 24, 2017
1 parent b7607e5 commit cc13d35
Show file tree
Hide file tree
Showing 2 changed files with 234 additions and 95 deletions.
174 changes: 129 additions & 45 deletions widget/Rotator.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,7 @@ define([
idm = _t._idMap = {},
tp = _t.transitionParams = eval("({ " + _t.transitionParams + " })"),
node = _t._domNode = dom.byId(node),
cb = _t._domNodeContentBox = domGeometry.getContentBox(node), // we are going to assume the rotator will not be changing size

// default styles to apply to all the container node and rotator's panes
p = {
left: 0,
top: 0
},

warn = function(bt, dt){
console.warn(_t.declaredClass, ' - Unable to find transition "', bt, '", defaulting to "', dt, '".');
};
cb = _t._domNodeContentBox = domGeometry.getContentBox(node); // we are going to assume the rotator will not be changing size

// if we don't have an id, then generate one
_t.id = node.id || (new Date()).getTime();
Expand All @@ -136,7 +126,7 @@ define([
// create our object for caching transition objects
tt[t] = lang.getObject(t);
if(!tt[t]){
warn(t, _defaultTransition);
this._transitionWarn(t, _defaultTransition);
tt[_t.transition = _defaultTransition] = lang.getObject(_defaultTransition);
}

Expand All @@ -151,60 +141,97 @@ define([
});

// zero out our panes array to store the real pane instance
var pp = _t.panes = [];
_t.panes = [];

// find and initialize the panes
query("> *", node).forEach(function(n, i){
var q = { node: n, idx: i, params: lang.mixin({}, tp, eval("({ " + (domAttr.get(n, "transitionParams") || "") + " })")) },
r = q.trans = domAttr.get(n, "transition") || _t.transition;
_t._initializePane(n, i);
});

// cache each pane's title, duration, and waitForEvent attributes
array.forEach(["id", "title", "duration", "waitForEvent"], function(a){
q[a] = domAttr.get(n, a);
});
_t._controlSub = topic.subscribe(_t.id + "/rotator/control", lang.hitch(_t, this.control));
},

if(q.id){
idm[q.id] = i;
}
insert: function(/*DomNode*/node, /*number?*/index){
// summary:
// Inserts a new pane into the rotator at a given index. If no index is
// given, the new pane is inserted at the end of the pane list.
var pane,
panes = this.panes,
paneNode;

if (index == null) {
index = panes.length;
}

// cache the transition function
if(!tt[r] && !(tt[r] = lang.getObject(r))){
warn(r, q.trans = _t.transition);
}
if (index < panes.length) {
pane = panes[index];
domConstruct.place(node, pane.node, 'before');
}
else {
domConstruct.place(node, this._domNode, 'last');
}

p.position = "absolute";
p.display = _noneStr;
this._initializePane(node, index);
},

// find the selected pane and initialize styles
if(_t.idx == null || domAttr.get(n, "selected")){
if(_t.idx != null){
domStyle.set(pp[_t.idx].node, _displayStr, _noneStr);
remove: function(/*DomNode|number*/nodeOrIndex){
// summary:
// Removes a pane from the rotator.
function removeFromPanes(idx) {
var removed = panes.splice(idx, 1)[0];
if (removed) {
if (removed.id) {
_t._idMap[removed.id] = undefined;
}
_t.idx = i;
p.display = "";
_t._domNode.removeChild(removed.node);
}
domStyle.set(n, p);
}

var index,
_t = this,
panes = this.panes;

// check for any declarative script blocks
query("> script[type^='dojo/method']", n).orphan().forEach(function(s){
var e = domAttr.get(s, "event");
if(e){
q[e] = parser._functionFromScript(s);
if (typeof nodeOrIndex === "number") {
index = nodeOrIndex;
}
else {
for (var i = 0; i < panes.length; i++) {
if (panes.node === nodeOrIndex) {
index = i;
break;
}
});
}

// add this pane to the array of panes
pp.push(q);
});
if (index == null) {
return;
}
}

_t._controlSub = topic.subscribe(_t.id + "/rotator/control", lang.hitch(_t, this.control));
if (index === this.idx) {
var def = this.go(this.idx - 1);
if (def) {
return def.then(function () {
removeFromPanes(index);
});
}
else {
removeFromPanes(index);
}
}
else {
removeFromPanes(index);
if (this.idx > index) {
this.idx--;
}
}
},

destroy: function(){
// summary:
// Destroys the Rotator and its DOM node.
array.forEach([this._controlSub, this.wfe], function(wfe) { wfe.remove() });
domConstruct.destroy(this._domNode);
this.panes = [];
},

next: function(){
Expand Down Expand Up @@ -323,6 +350,59 @@ define([
topic.publish(this.id + "/rotator/update", type, this, params || {});
},

_initializePane: function(/*node*/node, /*number*/index) {
// summary:
// Initializes a new pane node.
var tp = this.transitionParams,
q = { node: node, idx: index, params: lang.mixin({}, tp, eval("({ " + (domAttr.get(node, "transitionParams") || "") + " })")) },
r = q.trans = domAttr.get(node, "transition") || this.transition,
tt = this._transitions,
panes = this.panes,
// default styles to apply to all the container node and rotator's panes
p = {
left: 0,
top: 0,
position: "absolute",
display: _noneStr
};

// cache each pane's title, duration, and waitForEvent attributes
array.forEach(["id", "title", "duration", "waitForEvent"], function(a){
q[a] = domAttr.get(node, a);
});

if(q.id){
this._idMap[q.id] = index;
}

// cache the transition function
if(!tt[r] && !(tt[r] = lang.getObject(r))){
this._transitionWarn(r, q.trans = this.transition);
}

// find the selected pane and initialize styles
if(this.idx == null || domAttr.get(node, "selected")){
if(this.idx != null){
domStyle.set(panes[this.idx].node, _displayStr, _noneStr);
}
this.idx = index;
p.display = "";
}
domStyle.set(node, p);

// check for any declarative script blocks
// TODO: The way declarative scripts are handled here needs to be updated to no conflict with dojo/parser
query("> script[type^='dojo/method']", node).orphan().forEach(function(s){
var e = domAttr.get(s, "event");
if(e){
q[e] = parser._functionFromScript(s);
}
});

// add this pane to the array of panes
panes.splice(index, 0, q);
},

_resetWaitForEvent: function(){
// summary:
// If there is a waitForEvent pending, kill it.
Expand Down Expand Up @@ -367,6 +447,10 @@ define([
onManualChange: function(){
// summary:
// Stub function that can be overriden or connected to.
},

_transitionWarn(bt, dt){
console.warn(this.declaredClass, ' - Unable to find transition "', bt, '", defaulting to "', dt, '".');
}
});

Expand Down
155 changes: 105 additions & 50 deletions widget/tests/test_Rotator.html
Original file line number Diff line number Diff line change
Expand Up @@ -686,56 +686,62 @@ <h2>Wipe Transition with Easing</h2>
</div>
</div>

<h2>Declarative Event Hooks</h2>

<p>The 2nd pane will output when the onBeforeIn/Out and onAfterIn/Out events are fired.</p>

<p>
<button onclick="myRotator12.prev();">Prev</button>
<button onclick="myRotator12.next();">Next</button>
<button onclick="myRotator12.go(0);">Goto 0 (Nexaweb, Renkoo) [pan left]</button>
<button onclick="myRotator12.go(1);">Goto 1 (Sitepen, Tibco) [pan down]</button>
<button onclick="myRotator12.go(2);">Goto 2 (Webtide, OpenLaszlo) [pan right]</button>
<button onclick="myRotator12.go(3);">Goto 3 (Sun, Google) [pan up]</button>
</p>

<table><tr><td>

<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator12"
data-dojo-props="transition: 'dojox.widget.rotator.panLeft'">
<div class="pane">
<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
</div>
<div class="pane" transition="dojox.widget.rotator.panDown">
<script type="dojo/method" data-dojo-event="onBeforeIn" data-dojo-args="args">
log("myRotator12Log", "onBeforeIn - get dom nodes ready to be displayed, wire events");
</script>
<script type="dojo/method" data-dojo-event="onAfterIn" data-dojo-args="args">
log("myRotator12Log", "onAfterIn - this pane is now visible, so do cool stuff!");
</script>
<script type="dojo/method" data-dojo-event="onBeforeOut" data-dojo-args="args">
log("myRotator12Log", "onBeforeOut - stop any animations, disconnect events, etc");
</script>
<script type="dojo/method" data-dojo-event="onAfterOut" data-dojo-args="args">
log("myRotator12Log", "onAfterOut - clean up dom, reset state, disconnect events, etc");
</script>
<a href="http://www.sitepen.com" target="_new"><img src="images/rotator_sitepen.png" width="130" alt="Sitepen"/></a>
<a href="http://www.tibco.com" target="_new"><img src="images/rotator_tibco.png" width="130" alt="Tibco"/></a>
</div>
<div class="pane" transition="dojox.widget.rotator.panRight">
<a href="http://www.webtide.com/" target="_new"><img src="images/rotator_webtide.png" width="130" alt="Webtide"/></a>
<a href="http://www.openlaszlo.com" target="_new"><img src="images/rotator_openlaszlo.png" width="150" alt="OpenLaszlo"/></a>
</div>
<div class="pane" transition="dojox.widget.rotator.panUp">
<a href="http://www.sun.com" target="_new"><img src="images/rotator_sun.png" width="130" alt="Sun"/></a>
<a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a>
</div>
</div>

</td><td>
<div class="logWindow" id="myRotator12Log"></div>
</td></tr></table>
<!--
TODO: Declarative event hooks as implemented here don't work. They're intended to be handled by dojox/widget/Rotator, but
the syntax here is setup for dojo/parser. The example here actually causes an error in dojo/parser because the script tags
aren't direct children of a node with a data-dojo-type.
-->

<!-- <h2>Declarative Event Hooks</h2> -->

<!-- <p>The 2nd pane will output when the onBeforeIn/Out and onAfterIn/Out events are fired.</p> -->

<!-- <p> -->
<!-- <button onclick="myRotator12.prev();">Prev</button> -->
<!-- <button onclick="myRotator12.next();">Next</button> -->
<!-- <button onclick="myRotator12.go(0);">Goto 0 (Nexaweb, Renkoo) [pan left]</button> -->
<!-- <button onclick="myRotator12.go(1);">Goto 1 (Sitepen, Tibco) [pan down]</button> -->
<!-- <button onclick="myRotator12.go(2);">Goto 2 (Webtide, OpenLaszlo) [pan right]</button> -->
<!-- <button onclick="myRotator12.go(3);">Goto 3 (Sun, Google) [pan up]</button> -->
<!-- </p> -->

<!-- <table><tr><td> -->

<!-- <div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator12" -->
<!-- data-dojo-props="transition: 'dojox.widget.rotator.panLeft'"> -->
<!-- <div class="pane"> -->
<!-- <a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a> -->
<!-- <a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a> -->
<!-- </div> -->
<!-- <div class="pane" transition="dojox.widget.rotator.panDown"> -->
<!-- <script type="dojo/method" data-dojo-event="onBeforeIn" data-dojo-args="args"> -->
<!-- log("myRotator12Log", "onBeforeIn - get dom nodes ready to be displayed, wire events"); -->
<!-- </script> -->
<!-- <script type="dojo/method" data-dojo-event="onAfterIn" data-dojo-args="args"> -->
<!-- log("myRotator12Log", "onAfterIn - this pane is now visible, so do cool stuff!"); -->
<!-- </script> -->
<!-- <script type="dojo/method" data-dojo-event="onBeforeOut" data-dojo-args="args"> -->
<!-- log("myRotator12Log", "onBeforeOut - stop any animations, disconnect events, etc"); -->
<!-- </script> -->
<!-- <script type="dojo/method" data-dojo-event="onAfterOut" data-dojo-args="args"> -->
<!-- log("myRotator12Log", "onAfterOut - clean up dom, reset state, disconnect events, etc"); -->
<!-- </script> -->
<!-- <a href="http://www.sitepen.com" target="_new"><img src="images/rotator_sitepen.png" width="130" alt="Sitepen"/></a> -->
<!-- <a href="http://www.tibco.com" target="_new"><img src="images/rotator_tibco.png" width="130" alt="Tibco"/></a> -->
<!-- </div> -->
<!-- <div class="pane" transition="dojox.widget.rotator.panRight"> -->
<!-- <a href="http://www.webtide.com/" target="_new"><img src="images/rotator_webtide.png" width="130" alt="Webtide"/></a> -->
<!-- <a href="http://www.openlaszlo.com" target="_new"><img src="images/rotator_openlaszlo.png" width="150" alt="OpenLaszlo"/></a> -->
<!-- </div> -->
<!-- <div class="pane" transition="dojox.widget.rotator.panUp"> -->
<!-- <a href="http://www.sun.com" target="_new"><img src="images/rotator_sun.png" width="130" alt="Sun"/></a> -->
<!-- <a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a> -->
<!-- </div> -->
<!-- </div> -->

<!-- </td><td> -->
<!-- <div class="logWindow" id="myRotator12Log"></div> -->
<!-- </td></tr></table> -->

<h2>Programmatic Example with Fade Transition</h2>

Expand Down Expand Up @@ -826,5 +832,54 @@ <h2>Bad Global Transition</h2>
</div>
</div>

<h2>Insertion and removal</h2>

<p>Inserts and removes panes.</p>

<script>
function myRotator15Insert(index) {
var child = document.createElement('div');
child.className = 'pane';
switch (myRotator15Inserted) {
case 0:
child.innerHTML = '<a href="http://www.sitepen.com" target="_new"><img src="images/rotator_sitepen.png" width="130" alt="Sitepen"/></a>' +
'<a href="http://www.tibco.com" target="_new"><img src="images/rotator_tibco.png" width="130" alt="Tibco"/></a>';
break;
case 1:
child.innerHTML = '<a href="http://www.webtide.com/" target="_new"><img src="images/rotator_webtide.png" width="130" alt="Webtide"/></a>' +
'<a href="http://www.openlaszlo.com" target="_new"><img src="images/rotator_openlaszlo.png" width="150" alt="OpenLaszlo"/></a>';
break;
case 2:
child.innerHTML = '<a href="http://www.sun.com" target="_new"><img src="images/rotator_sun.png" width="130" alt="Sun"/></a>' +
'<a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a>';
break;
}
myRotator15.insert(child, index);
myRotator15Inserted = (myRotator15Inserted + 1) % 3
}

function myRotator15Remove() {
myRotator15.remove(1);
}

var myRotator15Inserted = 0;
</script>

<p>
<button onclick="myRotator15.prev();">Prev</button>
<button onclick="myRotator15.next();">Next</button>
<button onclick="myRotator15Insert();">Append</button>
<button onclick="myRotator15Insert(1);">Insert</button>
<button onclick="myRotator15Remove();">Remove</button>
</p>

<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator15"
data-dojo-props="transition: 'dojox.widget.rotator.crossFade'">
<div class="pane">
<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
</div>
</div>

</body>
</html>

0 comments on commit cc13d35

Please sign in to comment.