Team:SYSU-China/temp/SpryWidget.js

From 2011.igem.org

Revision as of 20:54, 5 October 2011 by Zhzhlun (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

// SpryWidget.js - version 0.16 - Spry Pre-Release 1.7 // // Copyright (c) 2009. Adobe Systems Incorporated. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Adobe Systems Incorporated nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE.

(function() { // BeginSpryComponent

if (typeof Spry == "undefined" || !Spry.Utils || !Spry.$$) { alert("SpryWidget.js requires SpryDOMUtils.js"); return; }

if (!Spry.Widget) Spry.Widget = {};

Spry.Widget.setOptions = function(obj, optionsObj, ignoreUndefinedProps) { if (obj && optionsObj) { for (var optionName in optionsObj) { var v = optionsObj[optionName]; if (!ignoreUndefinedProps || v != undefined) obj[optionName] = v; } } return obj; };

Spry.Widget.onLoadDidFire = false; Spry.Widget.onLoadQueue = [];

Spry.Widget.addCallbackToOnLoadQueue = function(callbackFunc, context) { if (callbackFunc) { if (context) { var cf = callbackFunc; callbackFunc = function() { cf.call(context); }; }

Spry.Widget.onLoadQueue.push(callbackFunc); } };

Spry.Widget.triggerCallbackAfterOnLoad = function(callbackFunc, context) { if (Spry.Widget.onLoadDidFire) callbackFunc.call(context); else Spry.Widget.addCallbackToOnLoadQueue(callbackFunc, context);

};

Spry.Widget.processOnLoadQueue = function() { Spry.Widget.onLoadDidFire = true; var q = Spry.Widget.onLoadQueue; while (q.length) (q.shift())(); };

Spry.Utils.addLoadListener(Spry.Widget.processOnLoadQueue);

Spry.Widget.Base = function() { Spry.Widget.Base.Notifier.call(this); };

Spry.Widget.Base.Notifier = function() { this.observers = []; this.suppressNotifications = 0; };

Spry.Widget.Base.Notifier.prototype.addObserver = function(observer) { if (!observer) return;

// Make sure the observer isn't already on the list.

var len = this.observers.length; for (var i = 0; i < len; i++) { if (this.observers[i] == observer) return; } this.observers[len] = observer; };

Spry.Widget.Base.Notifier.prototype.removeObserver = function(observer) { if (!observer) return;

for (var i = 0; i < this.observers.length; i++) { if (this.observers[i] == observer) { this.observers.splice(i, 1); break; } } };

Spry.Widget.Base.Notifier.prototype.notifyObservers = function(methodName, data) { if (!methodName) return;

if (!this.suppressNotifications) { var len = this.observers.length; for (var i = 0; i < len; i++) { var obs = this.observers[i]; if (obs) { if (typeof obs == "function") obs(methodName, this, data); else if (obs[methodName]) obs[methodName](this, data); } } } };

Spry.Widget.Base.Notifier.prototype.enableNotifications = function() { if (--this.suppressNotifications < 0) { this.suppressNotifications = 0; Spry.Debug.reportError("Unbalanced enableNotifications() call!\n"); } };

Spry.Widget.Base.Notifier.prototype.disableNotifications = function() { ++this.suppressNotifications; };

Spry.Widget.Base.prototype = new Spry.Widget.Base.Notifier(); Spry.Widget.Base.prototype.constructor = Spry.Widget.Base;

Spry.Widget.Base.getElement = function(ele) { return Spry.$(ele); };

Spry.Widget.Base.getElements = function(elements) { var eType = typeof elements; if (eType == "string") return Spry.$$(elements); else if (eType == "object") { if (elements.constructor == Array) { var result = []; for (var i = 0; i < elements.length; i++) result = result.concat(Spry.Widget.Base.getElements(elements[i])); return result; } else return [elements]; }

return []; };

Spry.Widget.Base.getElementsByClassName = function(root, className) { var results = [];

if (typeof root.getElementsByClassName != "undefined") { // Browser has a native getElementsByClassName(), so use it.

var nodeList = root.getElementsByClassName(className); for (var i = 0; i < nodeList.length; i++) results.push(nodeList.item(i)); } else { // Browser has no native getElementsByClassName() implementation // so do a manual search.

var re = new RegExp("\\b" + className + "\\b"); var nodeList = root.getElementsByTagName("*"); for (var i = 0; i < nodeList.length; i++) { var ele = nodeList.item(i); if (ele.className.search(re) != -1) results.push(ele); } }

return results; };

Spry.Widget.Base.prototype.getElementChildren = function(element) { var children = []; if (element) { var child = element.firstChild; while (child) { if (child.nodeType == 1 /* Node.ELEMENT_NODE */) children.push(child); child = child.nextSibling; } } return children; };

Spry.Widget.Base.prototype.groupContentByDelimeter = function(delimeterElements) { var results = new Array();

var numDelims = delimeterElements.length; for (var i = 0; i < numDelims; i++) { var delim = delimeterElements[i]; var group = new Array(); group.push(delim);

var nextDelim = delimeterElements[i+1]; var sib = delim.nextSibling; while (sib && sib != nextDelim) { group.push(sib); sib = sib.nextSibling; }

results.push(group); }

return results; };

Spry.Widget.Base.prototype.createElement = function(elementName, className, parent, child) { var ele = document.createElement(elementName); if (className) ele.className = className; if (parent) parent.appendChild(ele); if (child) ele.appendChild(child); return ele; };

Spry.Widget.Base.prototype.sliceLeftClassStr = "Left"; Spry.Widget.Base.prototype.sliceRightClassStr = "Right"; Spry.Widget.Base.prototype.sliceCenterClassStr = "Center"; Spry.Widget.Base.prototype.sliceTopClassStr = "Top"; Spry.Widget.Base.prototype.sliceBottomClassStr = "Bottom";

Spry.Widget.Base.prototype.sliceFuncs = {};

Spry.Widget.Base.prototype.sliceFuncs["2slice"] = function(root, eleName, baseClassName) { var a = root ? root : document.createElement(eleName); var b = document.createElement(eleName);

this.appendChildNodes(b, this.extractChildNodes(a)); // Transfer any children into the new content container.

a.appendChild(b);

this.addClassName(a, baseClassName + this.sliceLeftClassStr); b.className = baseClassName + this.sliceRightClassStr;

a.contentContainer = b;

return a; };

Spry.Widget.Base.prototype.sliceFuncs["3slice"] = function(root, eleName, baseClassName) { var a = root ? root : document.createElement(eleName); var b = document.createElement(eleName); var c = document.createElement(eleName);

this.appendChildNodes(c, this.extractChildNodes(a)); // Transfer any children into the new content container.

a.appendChild(b); b.appendChild(c);

this.addClassName(a, baseClassName + this.sliceLeftClassStr); b.className = baseClassName + this.sliceRightClassStr; c.className = baseClassName + this.sliceCenterClassStr;

a.contentContainer = c;

return a; };

Spry.Widget.Base.prototype.sliceFuncs["3sliceStacked"] = function(root, eleName, baseClassName) { root = root ? root : document.createElement(eleName);

var l = document.createElement(eleName); var m = document.createElement(eleName); var r = document.createElement(eleName);

this.appendChildNodes(m, this.extractChildNodes(root)); // Transfer any children into the new content container.

root.appendChild(l); root.appendChild(m); root.appendChild(r);

this.addClassName(root, baseClassName); l.className = baseClassName + this.sliceLeftClassStr; m.className = baseClassName + this.sliceCenterClassStr; r.className = baseClassName + this.sliceRightClassStr;

root.contentContainer = m;

return root; };

Spry.Widget.Base.prototype.sliceFuncs["9slice"] = function(root, eleName, baseClassName) { if (!root) root = document.createElement(eleName); this.addClassName(root, baseClassName);

var t = this.create3SliceStructure(null, eleName, baseClassName + this.sliceTopClassStr); var m = this.create3SliceStructure(null, eleName, baseClassName); var b = this.create3SliceStructure(null, eleName, baseClassName + this.sliceBottomClassStr);

this.appendChildNodes(m.contentContainer, this.extractChildNodes(root)); // Transfer any children into the new content container.

root.appendChild(t); root.appendChild(m); root.appendChild(b);

var contentContainer = m.contentContainer; root.contentContainer = contentContainer; contentContainer.rootContainer = root;

return root; };

// XXX: REMOVE THESE AFTER WIDGETS HAVE BEEN CLEANED UP! Spry.Widget.Base.prototype.create3SliceStructure = Spry.Widget.Base.prototype.sliceFuncs["3slice"]; Spry.Widget.Base.prototype.create9SliceStructure = Spry.Widget.Base.prototype.sliceFuncs["9slice"]; // XXX

Spry.Widget.Base.prototype.createOptionalSlicedStructure = function(root, eleName, className, sliceMap, childEleName) { // root - null or the dom element that will serve as the root of the sliced structure. // If null, this function will create the root container using the element name specified. // eleName - The tag to use when creating the sliced structure. // className - The class names placed on each element within the sliced structure will be derived from this name. // If a space delimited list is passed in, all of the names are assigned to the root element, but children // derive their classnames from just the first class in the list. // sliceMap - null or a dictionary of class name keys whose values are either "9slice", "3slice", or "none". // If null, the widget's sliceMap property is used. // childEleName - If specified, the eleName arg will only be used for the first element created within the structure. All // other elements will be created with the specified childEleName.

if (!sliceMap) sliceMap = this.sliceMap ? this.sliceMap : {};

if (!childEleName) childEleName = eleName;

var sliceType = sliceMap[className]; sliceType = sliceType ? sliceType : "none";

if (!root) root = document.createElement(eleName); this.addClassName(root, className);

var baseClass = (className || "").split(/\s+/)[0]; var sliceFunc = this.sliceFuncs[sliceType]; if (sliceFunc) root = sliceFunc.call(this, root, childEleName, baseClass); else root.contentContainer = root;

return root; };

Spry.Widget.Base.prototype.extractChildNodes = function(ele) { var children = []; while (ele.firstChild) { var c = ele.firstChild; children.push(c); ele.removeChild(c); } return children; };

Spry.Widget.Base.prototype.appendChildNodes = function(ele, nodes) { for (var i = 0; i < nodes.length; i++) ele.appendChild(nodes[i]); };

Spry.Widget.Base.prototype.setOptions = Spry.Widget.setOptions; Spry.Widget.Base.prototype.getOnLoadDidFire = function() { return Spry.Widget.onLoadDidFire; }; Spry.Widget.Base.prototype.addCallbackToOnLoadQueue = Spry.Widget.addCallbackToOnLoadQueue; Spry.Widget.Base.prototype.triggerCallbackAfterOnLoad = Spry.Widget.triggerCallbackAfterOnLoad;

Spry.Widget.Base.prototype.getElement = Spry.Widget.Base.getElement; Spry.Widget.Base.prototype.getElements = Spry.Widget.Base.getElements; Spry.Widget.Base.prototype.addClassName = Spry.Utils.addClassName; Spry.Widget.Base.prototype.hasClassName = Spry.Utils.hasClassName; Spry.Widget.Base.prototype.removeClassName = Spry.Utils.removeClassName; Spry.Widget.Base.prototype.addEventListener = Spry.Utils.addEventListener; Spry.Widget.Base.prototype.removeEventListener = Spry.Utils.removeEventListener;

Spry.Widget.Base.prototype.indexOf = function(a, v) { // IE6 doesn't support indexOf on Arrays so we need to check // for built-in support first. If not found manually do the // search. if (a) { if (a.indexOf) return a.indexOf(v); for (var i = 0; i < a.length; i++) if (a[i] == v) return i; } return -1; };

Spry.Widget.Base.prototype.initializePlugIns = function(defaultPlugIns, widgetOpts) { var evt = new Spry.Widget.Event(this); this.notifyObservers("onPreInitializePlugIns", evt); if (!evt.performDefaultAction) return;

// Both defaultPlugIns and widgetOpts are optional so make sure // we have always have something to work with.

var opts = widgetOpts ? widgetOpts : {}; var useDefaults = (typeof opts.useDefaultPlugIns == "undefined") ? true : opts.useDefaultPlugIns;

var dp = (useDefaults && defaultPlugIns) ? defaultPlugIns : []; var np = opts.plugIns ? opts.plugIns : [];

// Build a list of unique plugins from the default and user-specified sets.

var plugIns = []; var plist = dp.concat(np); for (var i = 0; i < plist.length; i++) { var p = plist[i]; if (this.indexOf(plugIns, p) < 0) plugIns.push(p); }

// Sort the resulting set of plugins based on priority.

plugIns = plugIns.sort(function(a, b) { var ap = (typeof a.priority == "undefined") ? 50 : a.priority; var bp = (typeof b.priority == "undefined") ? 50 : b.priority; return ap - bp; });

// Store the sorted list of plugins on the widget.

this.plugIns = plugIns;

// Instantiate each plugin.

for (var i = 0; plugIns && i < plugIns.length; i++) { if (plugIns[i].initialize) plugIns[i].initialize(this); }

this.notifyObservers("onPostInitializePlugIns", evt); };

Spry.Widget.Base.prototype.getClientPosition = function(ele) { var pos = new Object; pos.x = ele.offsetLeft; pos.y = ele.offsetTop; var parent = ele.offsetParent; while (parent) { pos.x += parent.offsetLeft; pos.y += parent.offsetTop; parent = parent.offsetParent; } return pos; };

Spry.Widget.Base.prototype.getStyleProp = function(element, prop) { var value; var camelized = Spry.Utils.camelizeString(prop); try { if (element.style) value = element.style[camelized];

if (!value) { if (document.defaultView && document.defaultView.getComputedStyle) { var css = document.defaultView.getComputedStyle(element, null); value = css ? css.getPropertyValue(prop) : null; } else if (element.currentStyle) { value = element.currentStyle[camelized]; } } } catch (e) {}

return value == 'auto' ? null : value; };

Spry.Widget.Base.prototype.makePositioned = function(element) { var pos = this.getStyleProp(element, 'position'); if (!pos || pos == 'static') { element.style.position = 'relative';

// Opera returns the offset relative to the positioning context, when an // element is position relative but top and left have not been defined if (window.opera) { element.style.top = 0; element.style.left = 0; } } };

Spry.Widget.Base.prototype.clearIEAlphaFilter = function(ele) { var filter = ele.style.filter;

// IE uses an alpha() filter for opacity. The filter style // property can contain multiple commands, so the idea here // is to just strip out the alpha(filter) and append a new // one, leaving any other filters untouched.

if (filter) { filter = filter.replace(/alpha\([^\)]*\)/, ""); filter = filter.replace(/^\s+|\s+$/, ""); ele.style.filter = filter; } else filter = "";

return filter; };

Spry.Widget.Base.prototype.setOpacity = function(ele, opacity) { ele.style.opacity = "" + opacity;

var filter = this.clearIEAlphaFilter(ele); if (filter) filter += " ";

ele.style.filter = filter + "alpha(opacity=" + (opacity*100) + ")"; };

Spry.Widget.Event = function(widget, opts) { this.widget = widget; Spry.Widget.setOptions(this, opts); this.performDefaultAction = true; };

Spry.Widget.Event.prototype.preventDefault = function() { this.performDefaultAction = false; };

////////////////////////////////////////////////////////

Spry.Widget.Button = function(ele, opts) { Spry.Widget.Base.call(this);

this.element = Spry.$$(ele)[0];

// Initialize the button object with the global defaults.

this.setOptions(this, Spry.Widget.Button.config);

// Override the defaults with any options passed into the constructor.

this.setOptions(this, opts);

var self = this;

this.addEventListener(this.element, "mousedown", function(e) { return self.handleMouseDown(e); }, false); this.addEventListener(this.element, "mouseover", function(e) { return self.handleMouseOver(e); }, false); this.addEventListener(this.element, "mouseout", function(e) { return self.handleMouseOut(e); }, false);

// XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't // rely on adding the tabindex attribute if it is missing to enable keyboard navigation // by default.

// Find the first element within the tab container that has a tabindex or the first // anchor tag. this.focusElement = this.getFocusElement(this.element); if (this.focusElement) { this.addEventListener(this.focusElement, "focus", function(e) { return self.handleFocus(e); }, false); this.addEventListener(this.focusElement, "blur", function(e) { return self.handleBlur(e); }, false); this.addEventListener(this.focusElement, "keydown", function(e) { return self.handleKeyDown(e); }, false); }

// We need to eat the onclick event so that buttons made // from links don't follow the link.

this.addEventListener(this.element, "click", function(e) { return false; }, false);

this.mouseUpCallback = function(evt) { return self.handleMouseUp(evt); }; };

Spry.Widget.Button.config = { disabled: false, mouseOutCancelsClick: true, onclick: null, downClass: "ButtonDown", hoverClass: "ButtonHover", disabledClass: "ButtonDisabled", focusedClass: "ButtonFocused" };


Spry.Widget.Button.prototype = new Spry.Widget.Base(); Spry.Widget.Button.prototype.constructor = Spry.Widget.Button;

Spry.Widget.Button.prototype.handleMouseDown = function(evt) { if (this.disabled) return false;

this.addClassName(this.element, this.downClass); this.addEventListener(document, "mouseup", this.mouseUpCallback, true);

this.notifyObservers("onButtonDown", { event: evt }); };

Spry.Widget.Button.prototype.handleMouseUp = function(evt) { if (this.disabled) return false;

this.removeClassName(this.element, this.downClass); this.removeEventListener(document, "mouseup", this.mouseUpCallback, true);

if (this.onclick) this.onclick(evt);

this.notifyObservers("onButtonUp"); this.notifyObservers("onButtonClick"); };

Spry.Widget.Button.prototype.handleMouseOver = function(evt) { if (this.disabled) return false;

this.addClassName(this.element, this.hoverClass); this.notifyObservers("onButtonEnter"); };

Spry.Widget.Button.prototype.handleMouseOut = function(evt) { if (this.disabled) return false;

var ele = this.element; this.removeClassName(ele, this.hoverClass);

if (this.mouseOutCancelsClick) { this.removeClassName(ele, this.downClass); this.removeEventListener(document, "mouseup", this.mouseUpCallback, true); }

this.notifyObservers("onButtonExit"); };

Spry.Widget.Button.prototype.handleFocus = function(evt) { if (this.disabled) return false;

this.addClassName(this.element, this.focusedClass); this.notifyObservers("onButtonFocused"); };

Spry.Widget.Button.prototype.handleBlur = function(evt) { if (this.disabled) return false;

this.removeClassName(this.element, this.focusedClass); this.notifyObservers("onButtonBlur"); };

Spry.Widget.Button.prototype.handleKeyDown = function(evt) { if (this.disabled) return false; this.notifyObservers("onButtonKeyDown", {event: evt, element: this.element}); };

Spry.Widget.Button.prototype.getFocusElement = function(element) { var focusElement = null; var indexEle = null; var anchorEle = null;

this.preorderTraversal(element, function(node) { if (node.nodeType == 1 /* NODE.ELEMENT_NODE */) { var tabIndexAttr = element.attributes.getNamedItem("tabindex"); if (tabIndexAttr) { indexEle = node; return true; } if (!anchorEle && node.nodeName.toLowerCase() == "a") anchorEle = node; } return false; });

if (indexEle) focusElement = indexEle; else if (anchorEle) focusElement = anchorEle; return focusElement; };

Spry.Widget.Button.prototype.preorderTraversal = function(root, func) { var stopTraversal = false; if (root) { stopTraversal = func(root); if (root.hasChildNodes()) { var child = root.firstChild; while (!stopTraversal && child) { stopTraversal = this.preorderTraversal(child, func); try { child = child.nextSibling; } catch (e) { child = null; } } } } return stopTraversal; };

Spry.Widget.Button.prototype.disable = function() { this.disabled = true; this.removeClassName(this.element, this.downClass); this.removeClassName(this.element, this.hoverClass); this.addClassName(this.element, this.disabledClass); this.removeEventListener(document, "mouseup", this.mouseUpCallback, true); };

Spry.Widget.Button.prototype.enable = function() { this.disabled = false; this.removeClassName(this.element, this.disabledClass); };

Spry.Widget.Button.prototype.focus = function() { if (this.disabled) return false;

if (this.focusElement) this.focusElement.focus(); };


})(); // EndSpryComponent