diff options
Diffstat (limited to 'js/dojo-1.7.2/dojox/html')
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/README | 48 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/_base.js | 386 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/ellipsis.js | 194 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/entities.js | 206 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/ext-dojo/style.js | 457 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/format.js | 478 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/metrics.js | 179 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/resources/ellipsis.css | 34 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/html/styles.js | 309 |
9 files changed, 2291 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/html/README b/js/dojo-1.7.2/dojox/html/README new file mode 100644 index 0000000..1f0abb8 --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/README @@ -0,0 +1,48 @@ +------------------------------------------------------------------------------- +dojox.html +------------------------------------------------------------------------------- +Version 0.2 +Release date: 04/24/2008 +------------------------------------------------------------------------------- +Project state: +beta +------------------------------------------------------------------------------- +Credits + Eugene Lazutkin (eugene.lazutkin AT gmail.com) + Scott J. Miles (sjmiles AT activegrid.com) + Steve Orvell (sorvell AT activegrid.com) + Tom Trenka (ttrenka AT gmail.com) + Bryan Forbes (bryan AT reigndropsfall.net) + Mike Wilcox - dojox.html.styles (anm8tr AT yahoo.com) + Jared Jurkiewicz - dojox.html.entites, dojox.html.format (jared.jurkiewicz AT gmail.com) +------------------------------------------------------------------------------- +Project description + +This project aims to add html functions that aren't used often enough to +warrant going into Dojo Core but should not be duplicated. For instance, font +measurement routines aren't used by the majority of developers, but are complex +enough to not be duplicated. +Styles adds the ability to create and remove dynamic cssRules, as well as +manipulate document style sheets. +Ellipsis adds support to match text-overflow: ellipsis for Firefox. +------------------------------------------------------------------------------- +Dependencies: + +dojox.html nor dojox.html.styles have dependencies, outside of Dojo Core. +------------------------------------------------------------------------------- +Documentation + +To automatically initialize the font resize callback, add "fontSizeWatch: true" +to your djConfig. +------------------------------------------------------------------------------- +Installation instructions + +Grab the following from the Dojo SVN Repository: +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html.js +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/* +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/styles.js +Install into the following directory structure: +/dojox/html/ + +...which should be at the same level as your Dojo checkout. +------------------------------------------------------------------------------- diff --git a/js/dojo-1.7.2/dojox/html/_base.js b/js/dojo-1.7.2/dojox/html/_base.js new file mode 100644 index 0000000..bbd960d --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/_base.js @@ -0,0 +1,386 @@ +//>>built +define("dojox/html/_base", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/xhr", + "dojo/_base/window", + "dojo/_base/sniff", + "dojo/_base/url", + "dojo/dom-construct", + "dojo/html", + "dojo/_base/declare" +], function (dojo, lang, xhrUtil, windowUtil, has, _Url, domConstruct, htmlUtil) { +/* + Status: dont know where this will all live exactly + Need to pull in the implementation of the various helper methods + Some can be static method, others maybe methods of the ContentSetter (?) + + Gut the ContentPane, replace its _setContent with our own call to dojox.html.set() + + +*/ + var html = dojo.getObject("dojox.html", true); + + if(has("ie")){ + var alphaImageLoader = /(AlphaImageLoader\([^)]*?src=(['"]))(?![a-z]+:|\/)([^\r\n;}]+?)(\2[^)]*\)\s*[;}]?)/g; + } + + // css at-rules must be set before any css declarations according to CSS spec + // match: + // @import 'http://dojotoolkit.org/dojo.css'; + // @import 'you/never/thought/' print; + // @import url("it/would/work") tv, screen; + // @import url(/did/you/now.css); + // but not: + // @namespace dojo "http://dojotoolkit.org/dojo.css"; /* namespace URL should always be a absolute URI */ + // @charset 'utf-8'; + // @media print{ #menuRoot {display:none;} } + + // we adjust all paths that dont start on '/' or contains ':' + //(?![a-z]+:|\/) + + var cssPaths = /(?:(?:@import\s*(['"])(?![a-z]+:|\/)([^\r\n;{]+?)\1)|url\(\s*(['"]?)(?![a-z]+:|\/)([^\r\n;]+?)\3\s*\))([a-z, \s]*[;}]?)/g; + + var adjustCssPaths = html._adjustCssPaths = function(cssUrl, cssText){ + // summary: + // adjusts relative paths in cssText to be relative to cssUrl + // a path is considered relative if it doesn't start with '/' and not contains ':' + // description: + // Say we fetch a HTML page from level1/page.html + // It has some inline CSS: + // @import "css/page.css" tv, screen; + // ... + // background-image: url(images/aplhaimage.png); + // + // as we fetched this HTML and therefore this CSS + // from level1/page.html, these paths needs to be adjusted to: + // @import 'level1/css/page.css' tv, screen; + // ... + // background-image: url(level1/images/alphaimage.png); + // + // In IE it will also adjust relative paths in AlphaImageLoader() + // filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/alphaimage.png'); + // will be adjusted to: + // filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='level1/images/alphaimage.png'); + // + // Please note that any relative paths in AlphaImageLoader in external css files wont work, as + // the paths in AlphaImageLoader is MUST be declared relative to the HTML page, + // not relative to the CSS file that declares it + + if(!cssText || !cssUrl){ return; } + + // support the ImageAlphaFilter if it exists, most people use it in IE 6 for transparent PNGs + // We are NOT going to kill it in IE 7 just because the PNGs work there. Somebody might have + // other uses for it. + // If user want to disable css filter in IE6 he/she should + // unset filter in a declaration that just IE 6 doesn't understands + // like * > .myselector { filter:none; } + if(alphaImageLoader){ + cssText = cssText.replace(alphaImageLoader, function(ignore, pre, delim, url, post){ + return pre + (new _Url(cssUrl, './'+url).toString()) + post; + }); + } + + return cssText.replace(cssPaths, function(ignore, delimStr, strUrl, delimUrl, urlUrl, media){ + if(strUrl){ + return '@import "' + (new _Url(cssUrl, './'+strUrl).toString()) + '"' + media; + }else{ + return 'url(' + (new _Url(cssUrl, './'+urlUrl).toString()) + ')' + media; + } + }); + }; + + // attributepaths one tag can have multiple paths, example: + // <input src="..." style="url(..)"/> or <a style="url(..)" href=".."> + // <img style='filter:progid...AlphaImageLoader(src="noticeTheSrcHereRunsThroughHtmlSrc")' src="img"> + var htmlAttrPaths = /(<[a-z][a-z0-9]*\s[^>]*)(?:(href|src)=(['"]?)([^>]*?)\3|style=(['"]?)([^>]*?)\5)([^>]*>)/gi; + + var adjustHtmlPaths = html._adjustHtmlPaths = function(htmlUrl, cont){ + var url = htmlUrl || "./"; + + return cont.replace(htmlAttrPaths, + function(tag, start, name, delim, relUrl, delim2, cssText, end){ + return start + (name ? + (name + '=' + delim + (new _Url(url, relUrl).toString()) + delim) + : ('style=' + delim2 + adjustCssPaths(url, cssText) + delim2) + ) + end; + } + ); + }; + + var snarfStyles = html._snarfStyles = function (/*String*/cssUrl, /*String*/cont, /*Array*/styles){ + /**************** cut out all <style> and <link rel="stylesheet" href=".."> **************/ + // also return any attributes from this tag (might be a media attribute) + // if cssUrl is set it will adjust paths accordingly + styles.attributes = []; + + return cont.replace(/(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi, + function(ignore, styleAttr, cssText, linkAttr, delim, href){ + // trim attribute + var i, attr = (styleAttr||linkAttr||"").replace(/^\s*([\s\S]*?)\s*$/i, "$1"); + if(cssText){ + i = styles.push(cssUrl ? adjustCssPaths(cssUrl, cssText) : cssText); + }else{ + i = styles.push('@import "' + href + '";'); + attr = attr.replace(/\s*(?:rel|href)=(['"])?[^\s]*\1\s*/gi, ""); // remove rel=... and href=... + } + if(attr){ + attr = attr.split(/\s+/);// split on both "\n", "\t", " " etc + var atObj = {}, tmp; + for(var j = 0, e = attr.length; j < e; j++){ + tmp = attr[j].split('='); // split name='value' + atObj[tmp[0]] = tmp[1].replace(/^\s*['"]?([\s\S]*?)['"]?\s*$/, "$1"); // trim and remove '' + } + styles.attributes[i - 1] = atObj; + } + return ""; + } + ); + }; + + var snarfScripts = html._snarfScripts = function(cont, byRef){ + // summary + // strips out script tags from cont + // invoke with + // byRef = {errBack:function(){/*add your download error code here*/, downloadRemote: true(default false)}} + // byRef will have {code: 'jscode'} when this scope leaves + byRef.code = ""; + + //Update script tags nested in comments so that the script tag collector doesn't pick + //them up. + cont = cont.replace(/<[!][-][-](.|\s)*?[-][-]>/g, + function(comment){ + return comment.replace(/<(\/?)script\b/ig,"<$1Script"); + } + ); + + function download(src){ + if(byRef.downloadRemote){ + // console.debug('downloading',src); + //Fix up src, in case there were entity character encodings in it. + //Probably only need to worry about a subset. + src = src.replace(/&([a-z0-9#]+);/g, function(m, name) { + switch(name) { + case "amp" : return "&"; + case "gt" : return ">"; + case "lt" : return "<"; + default: + return name.charAt(0)=="#" ? String.fromCharCode(name.substring(1)) : "&"+name+";"; + } + }); + xhrUtil.get({ + url: src, + sync: true, + load: function(code){ + byRef.code += code+";"; + }, + error: byRef.errBack + }); + } + } + + // match <script>, <script type="text/..., but not <script type="dojo(/method)... + return cont.replace(/<script\s*(?![^>]*type=['"]?(?:dojo\/|text\/html\b))(?:[^>]*?(?:src=(['"]?)([^>]*?)\1[^>]*)?)*>([\s\S]*?)<\/script>/gi, + function(ignore, delim, src, code){ + if(src){ + download(src); + }else{ + byRef.code += code; + } + return ""; + } + ); + }; + + var evalInGlobal = html.evalInGlobal = function(code, appendNode){ + // we do our own eval here as dojo.eval doesn't eval in global crossbrowser + // This work X browser but but it relies on a DOM + // plus it doesn't return anything, thats unrelevant here but not for dojo core + appendNode = appendNode || windowUtil.doc.body; + var n = appendNode.ownerDocument.createElement('script'); + n.type = "text/javascript"; + appendNode.appendChild(n); + n.text = code; // DOM 1 says this should work + }; + + html._ContentSetter = dojo.declare(/*===== "dojox.html._ContentSetter", =====*/ htmlUtil._ContentSetter, { + // adjustPaths: Boolean + // Adjust relative paths in html string content to point to this page + // Only useful if you grab content from a another folder than the current one + adjustPaths: false, + referencePath: ".", + renderStyles: false, + + executeScripts: false, + scriptHasHooks: false, + scriptHookReplacement: null, + + _renderStyles: function(styles){ + // insert css from content into document head + this._styleNodes = []; + var st, att, cssText, doc = this.node.ownerDocument; + var head = doc.getElementsByTagName('head')[0]; + + for(var i = 0, e = styles.length; i < e; i++){ + cssText = styles[i]; att = styles.attributes[i]; + st = doc.createElement('style'); + st.setAttribute("type", "text/css"); // this is required in CSS spec! + + for(var x in att){ + st.setAttribute(x, att[x]); + } + + this._styleNodes.push(st); + head.appendChild(st); // must insert into DOM before setting cssText + + if(st.styleSheet){ // IE + st.styleSheet.cssText = cssText; + }else{ // w3c + st.appendChild(doc.createTextNode(cssText)); + } + } + }, + + empty: function() { + this.inherited("empty", arguments); + + // empty out the styles array from any previous use + this._styles = []; + }, + + onBegin: function() { + // summary + // Called after instantiation, but before set(); + // It allows modification of any of the object properties - including the node and content + // provided - before the set operation actually takes place + // This implementation extends that of dojo.html._ContentSetter + // to add handling for adjustPaths, renderStyles on the html string content before it is set + this.inherited("onBegin", arguments); + + var cont = this.content, + node = this.node; + + var styles = this._styles;// init vars + + if(lang.isString(cont)){ + if(this.adjustPaths && this.referencePath){ + cont = adjustHtmlPaths(this.referencePath, cont); + } + + if(this.renderStyles || this.cleanContent){ + cont = snarfStyles(this.referencePath, cont, styles); + } + + // because of a bug in IE, script tags that is first in html hierarchy doesnt make it into the DOM + // when content is innerHTML'ed, so we can't use dojo.query to retrieve scripts from DOM + if(this.executeScripts){ + var _t = this; + var byRef = { + downloadRemote: true, + errBack:function(e){ + _t._onError.call(_t, 'Exec', 'Error downloading remote script in "'+_t.id+'"', e); + } + }; + cont = snarfScripts(cont, byRef); + this._code = byRef.code; + } + } + this.content = cont; + }, + + onEnd: function() { + // summary + // Called after set(), when the new content has been pushed into the node + // It provides an opportunity for post-processing before handing back the node to the caller + // This implementation extends that of dojo.html._ContentSetter + + var code = this._code, + styles = this._styles; + + // clear old stylenodes from the DOM + // these were added by the last set call + // (in other words, if you dont keep and reuse the ContentSetter for a particular node + // .. you'll have no practical way to do this) + if(this._styleNodes && this._styleNodes.length){ + while(this._styleNodes.length){ + domConstruct.destroy(this._styleNodes.pop()); + } + } + // render new style nodes + if(this.renderStyles && styles && styles.length){ + this._renderStyles(styles); + } + + if(this.executeScripts && code){ + if(this.cleanContent){ + // clean JS from html comments and other crap that browser + // parser takes care of in a normal page load + code = code.replace(/(<!--|(?:\/\/)?-->|<!\[CDATA\[|\]\]>)/g, ''); + } + if(this.scriptHasHooks){ + // replace _container_ with this.scriptHookReplace() + // the scriptHookReplacement can be a string + // or a function, which when invoked returns the string you want to substitute in + code = code.replace(/_container_(?!\s*=[^=])/g, this.scriptHookReplacement); + } + try{ + evalInGlobal(code, this.node); + }catch(e){ + this._onError('Exec', 'Error eval script in '+this.id+', '+e.message, e); + } + } + this.inherited("onEnd", arguments); + }, + tearDown: function() { + this.inherited(arguments); + delete this._styles; + // only tear down -or another set() - will explicitly throw away the + // references to the style nodes we added + if(this._styleNodes && this._styleNodes.length){ + while(this._styleNodes.length){ + domConstruct.destroy(this._styleNodes.pop()); + } + } + delete this._styleNodes; + // reset the defaults from the prototype + // XXX: not sure if this is the correct intended behaviour, it was originally + // dojo.getObject(this.declaredClass).prototype which will not work with anonymous + // modules + dojo.mixin(this, html._ContentSetter.prototype); + } + + }); + + html.set = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont, /* Object? */ params){ + // TODO: add all the other options + // summary: + // inserts (replaces) the given content into the given node + // node: + // the parent element that will receive the content + // cont: + // the content to be set on the parent element. + // This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes + // params: + // Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter + // example: + // A safe string/node/nodelist content replacement/injection with hooks for extension + // Example Usage: + // dojo.html.set(node, "some string"); + // dojo.html.set(node, contentNode, {options}); + // dojo.html.set(node, myNode.childNodes, {options}); + + if(!params){ + // simple and fast + return htmlUtil._setNodeContent(node, cont, true); + }else{ + // more options but slower + var op = new html._ContentSetter(dojo.mixin( + params, + { content: cont, node: node } + )); + return op.set(); + } + }; + + return html; +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/html/ellipsis.js b/js/dojo-1.7.2/dojox/html/ellipsis.js new file mode 100644 index 0000000..f670637 --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/ellipsis.js @@ -0,0 +1,194 @@ +//>>built +define("dojox/html/ellipsis",["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "dojo/colors"], function(d){ + /*===== + dojox.html.ellipsis = { + // summary: offers cross-browser support for text-overflow: ellipsis + // + // description: Add "dojoxEllipsis" on any node that you want to ellipsis-ize. In order to function properly, + // the node with the dojoxEllipsis class set on it should be a child of a node with a defined width. + // It should also be a block-level element (i.e. <div>) - it will not work on td elements. + // NOTE: When using the dojoxEllipsis class within tables, the table needs to have the table-layout: fixed style + } + =====*/ + + if(d.isFF < 7){ //TODO: feature detect text-overflow in computed style? + // The delay (in ms) to wait so that we don't keep querying when many + // changes happen at once - set config "dojoxFFEllipsisDelay" if you + // want a different value + var delay = 1; + if("dojoxFFEllipsisDelay" in d.config){ + delay = Number(d.config.dojoxFFEllipsisDelay); + if(isNaN(delay)){ + delay = 1; + } + } + try{ + var createXULEllipsis = (function(){ + // Create our stub XUL elements for cloning later + // NOTE: this no longer works as of FF 4.0: + // https://developer.mozilla.org/En/Firefox_4_for_developers#Remote_XUL_support_removed + var sNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; + var xml = document.createElementNS(sNS, 'window'); + var label = document.createElementNS(sNS, 'description'); + label.setAttribute('crop', 'end'); + xml.appendChild(label); + + return function(/* Node */ n){ + // Summary: + // Given a node, it creates the XUL and sets its + // content so that it will have an ellipsis + var x = xml.cloneNode(true); + x.firstChild.setAttribute('value', n.textContent); + n.innerHTML = ''; + n.appendChild(x); + }; + })(); + }catch(e){} + + // Create our iframe elements for cloning later + var create = d.create; + var dd = d.doc; + var dp = d.place; + var iFrame = create("iframe", {className: "dojoxEllipsisIFrame", + src: "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'"}); + var rollRange = function(/* W3C Range */ r, /* int? */ cnt){ + // Summary: + // Rolls the given range back one character from the end + // + // r: W3C Range + // The range to roll back + // cnt: int? + // An optional number of times to roll back (defaults 1) + if(r.collapsed){ + // Do nothing - we are already collapsed + return; + } + if(cnt > 0){ + do{ + rollRange(r); + cnt--; + }while(cnt); + return; + } + if(r.endContainer.nodeType == 3 && r.endOffset > 0){ + r.setEnd(r.endContainer, r.endOffset - 1); + }else if(r.endContainer.nodeType == 3){ + r.setEndBefore(r.endContainer); + rollRange(r); + return; + }else if(r.endOffset && r.endContainer.childNodes.length >= r.endOffset){ + var nCont = r.endContainer.childNodes[r.endOffset - 1]; + if(nCont.nodeType == 3){ + r.setEnd(nCont, nCont.length - 1); + }else if(nCont.childNodes.length){ + r.setEnd(nCont, nCont.childNodes.length); + rollRange(r); + return; + }else{ + r.setEndBefore(nCont); + rollRange(r); + return; + } + }else{ + r.setEndBefore(r.endContainer); + rollRange(r); + return; + } + }; + var createIFrameEllipsis = function(/* Node */ n){ + // Summary: + // Given a node, it creates an iframe and and ellipsis div and + // sets up the connections so that they will work correctly. + // This function is used when createXULEllipsis is not able + // to be used (because there is markup within the node) - it's + // a bit slower, but does the trick + var c = create("div", {className: "dojoxEllipsisContainer"}); + var e = create("div", {className: "dojoxEllipsisShown", style: {display: "none"}}); + n.parentNode.replaceChild(c, n); + c.appendChild(n); + c.appendChild(e); + var i = iFrame.cloneNode(true); + var ns = n.style; + var es = e.style; + var ranges; + var resizeNode = function(){ + ns.display = ""; + es.display = "none"; + if(n.scrollWidth <= n.offsetWidth){ return; } + var r = dd.createRange(); + r.selectNodeContents(n); + ns.display = "none"; + es.display = ""; + var done = false; + do{ + var numRolls = 1; + dp(r.cloneContents(), e, "only"); + var sw = e.scrollWidth, ow = e.offsetWidth; + done = (sw <= ow); + var pct = (1 - ((ow * 1) / sw)); + if(pct > 0){ + numRolls = Math.max(Math.round(e.textContent.length * pct) - 1, 1); + } + rollRange(r, numRolls); + }while(!r.collapsed && !done); + }; + i.onload = function(){ + i.contentWindow.onresize = resizeNode; + resizeNode(); + }; + c.appendChild(i); + }; + + // Function for updating the ellipsis + var hc = d.hasClass; + var doc = d.doc; + var s, fn, opt; + if(doc.querySelectorAll){ + s = doc; + fn = "querySelectorAll"; + opt = ".dojoxEllipsis"; + }else if(doc.getElementsByClassName){ + s = doc; + fn = "getElementsByClassName"; + opt = "dojoxEllipsis"; + }else{ + s = d; + fn = "query"; + opt = ".dojoxEllipsis"; + } + fx = function(){ + d.forEach(s[fn].apply(s, [opt]), function(n){ + if(!n || n._djx_ellipsis_done){ return; } + n._djx_ellipsis_done = true; + if(createXULEllipsis && n.textContent == n.innerHTML && !hc(n, "dojoxEllipsisSelectable")){ + // We can do the faster XUL version, instead of calculating + createXULEllipsis(n); + }else{ + createIFrameEllipsis(n); + } + }); + }; + + d.addOnLoad(function(){ + // Apply our initial stuff + var t = null; + var c = null; + var connFx = function(){ + if(c){ + // disconnect us - so we don't fire anymore + d.disconnect(c); + c = null; + } + if(t){ clearTimeout(t); } + t = setTimeout(function(){ + t = null; + fx(); + // Connect to the modified function so that we can catch + // our next change + c = d.connect(d.body(), "DOMSubtreeModified", connFx); + }, delay); + }; + connFx(); + }); + } +}); diff --git a/js/dojo-1.7.2/dojox/html/entities.js b/js/dojo-1.7.2/dojox/html/entities.js new file mode 100644 index 0000000..d1981ee --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/entities.js @@ -0,0 +1,206 @@ +//>>built +define("dojox/html/entities", ["dojo/_base/lang"], function(lang) { + // dojox.html.entities.html [public] Array + // Entity characters for HTML, represented as an array of + // character code, entity name (minus & and ; wrapping. + // The function wrapper is to fix global leking with the build tools. + var dhe = lang.getObject("dojox.html.entities",true); + + var _applyEncodingMap = function(str, map){ + // summary: + // Private internal function for performing encoding of entity characters. + // tags: + // private + + // Check to see if we have genned and cached a regexp for this map yet + // If we have, use it, if not, gen it, cache, then use. + var mapper, regexp; + if(map._encCache && + map._encCache.regexp && + map._encCache.mapper && + map.length == map._encCache.length){ + mapper = map._encCache.mapper; + regexp = map._encCache.regexp; + }else{ + mapper = {}; + regexp = ["["]; + var i; + for(i = 0; i < map.length; i++){ + mapper[map[i][0]] = "&" + map[i][1] + ";"; + regexp.push(map[i][0]); + } + regexp.push("]"); + regexp = new RegExp(regexp.join(""), "g"); + map._encCache = { + mapper: mapper, + regexp: regexp, + length: map.length + }; + } + str = str.replace(regexp, function(c){ + return mapper[c]; + }); + return str; + }; + + var _applyDecodingMap = function(str, map){ + // summary: + // Private internal function for performing decoding of entity characters. + // tags: + // private + var mapper, regexp; + if(map._decCache && + map._decCache.regexp && + map._decCache.mapper && + map.length == map._decCache.length){ + mapper = map._decCache.mapper; + regexp = map._decCache.regexp; + }else{ + mapper = {}; + regexp = ["("]; + var i; + for(i = 0; i < map.length; i++){ + var e = "&" + map[i][1] + ";"; + if(i){regexp.push("|");} + mapper[e] = map[i][0]; + regexp.push(e); + } + regexp.push(")"); + regexp = new RegExp(regexp.join(""), "g"); + map._decCache = { + mapper: mapper, + regexp: regexp, + length: map.length + }; + } + str = str.replace(regexp, function(c){ + return mapper[c]; + }); + return str; + }; + + dhe.html = [ + ["\u0026","amp"], ["\u0022","quot"],["\u003C","lt"], ["\u003E","gt"], + ["\u00A0","nbsp"] + ]; + + // dojox.html.entities.latin [public] Array + // Entity characters for Latin characters and similar, represented as an array of + // character code, entity name (minus & and ; wrapping. + dhe.latin = [ + ["\u00A1","iexcl"],["\u00A2","cent"],["\u00A3","pound"],["\u20AC","euro"], + ["\u00A4","curren"],["\u00A5","yen"],["\u00A6","brvbar"],["\u00A7","sect"], + ["\u00A8","uml"],["\u00A9","copy"],["\u00AA","ordf"],["\u00AB","laquo"], + ["\u00AC","not"],["\u00AD","shy"],["\u00AE","reg"],["\u00AF","macr"], + ["\u00B0","deg"],["\u00B1","plusmn"],["\u00B2","sup2"],["\u00B3","sup3"], + ["\u00B4","acute"],["\u00B5","micro"],["\u00B6","para"],["\u00B7","middot"], + ["\u00B8","cedil"],["\u00B9","sup1"],["\u00BA","ordm"],["\u00BB","raquo"], + ["\u00BC","frac14"],["\u00BD","frac12"],["\u00BE","frac34"],["\u00BF","iquest"], + ["\u00C0","Agrave"],["\u00C1","Aacute"],["\u00C2","Acirc"],["\u00C3","Atilde"], + ["\u00C4","Auml"],["\u00C5","Aring"],["\u00C6","AElig"],["\u00C7","Ccedil"], + ["\u00C8","Egrave"],["\u00C9","Eacute"],["\u00CA","Ecirc"],["\u00CB","Euml"], + ["\u00CC","Igrave"],["\u00CD","Iacute"],["\u00CE","Icirc"],["\u00CF","Iuml"], + ["\u00D0","ETH"],["\u00D1","Ntilde"],["\u00D2","Ograve"],["\u00D3","Oacute"], + ["\u00D4","Ocirc"],["\u00D5","Otilde"],["\u00D6","Ouml"],["\u00D7","times"], + ["\u00D8","Oslash"],["\u00D9","Ugrave"],["\u00DA","Uacute"],["\u00DB","Ucirc"], + ["\u00DC","Uuml"],["\u00DD","Yacute"],["\u00DE","THORN"],["\u00DF","szlig"], + ["\u00E0","agrave"],["\u00E1","aacute"],["\u00E2","acirc"],["\u00E3","atilde"], + ["\u00E4","auml"],["\u00E5","aring"],["\u00E6","aelig"],["\u00E7","ccedil"], + ["\u00E8","egrave"],["\u00E9","eacute"],["\u00EA","ecirc"],["\u00EB","euml"], + ["\u00EC","igrave"],["\u00ED","iacute"],["\u00EE","icirc"],["\u00EF","iuml"], + ["\u00F0","eth"],["\u00F1","ntilde"],["\u00F2","ograve"],["\u00F3","oacute"], + ["\u00F4","ocirc"],["\u00F5","otilde"],["\u00F6","ouml"],["\u00F7","divide"], + ["\u00F8","oslash"],["\u00F9","ugrave"],["\u00FA","uacute"],["\u00FB","ucirc"], + ["\u00FC","uuml"],["\u00FD","yacute"],["\u00FE","thorn"],["\u00FF","yuml"], + ["\u0192","fnof"],["\u0391","Alpha"],["\u0392","Beta"],["\u0393","Gamma"], + ["\u0394","Delta"],["\u0395","Epsilon"],["\u0396","Zeta"],["\u0397","Eta"], + ["\u0398","Theta"], ["\u0399","Iota"],["\u039A","Kappa"],["\u039B","Lambda"], + ["\u039C","Mu"],["\u039D","Nu"],["\u039E","Xi"],["\u039F","Omicron"], + ["\u03A0","Pi"],["\u03A1","Rho"],["\u03A3","Sigma"],["\u03A4","Tau"], + ["\u03A5","Upsilon"],["\u03A6","Phi"],["\u03A7","Chi"],["\u03A8","Psi"], + ["\u03A9","Omega"],["\u03B1","alpha"],["\u03B2","beta"],["\u03B3","gamma"], + ["\u03B4","delta"],["\u03B5","epsilon"],["\u03B6","zeta"],["\u03B7","eta"], + ["\u03B8","theta"],["\u03B9","iota"],["\u03BA","kappa"],["\u03BB","lambda"], + ["\u03BC","mu"],["\u03BD","nu"],["\u03BE","xi"],["\u03BF","omicron"], + ["\u03C0","pi"],["\u03C1","rho"],["\u03C2","sigmaf"],["\u03C3","sigma"], + ["\u03C4","tau"],["\u03C5","upsilon"],["\u03C6","phi"],["\u03C7","chi"], + ["\u03C8","psi"],["\u03C9","omega"],["\u03D1","thetasym"],["\u03D2","upsih"], + ["\u03D6","piv"],["\u2022","bull"],["\u2026","hellip"],["\u2032","prime"], + ["\u2033","Prime"],["\u203E","oline"],["\u2044","frasl"],["\u2118","weierp"], + ["\u2111","image"],["\u211C","real"],["\u2122","trade"],["\u2135","alefsym"], + ["\u2190","larr"],["\u2191","uarr"],["\u2192","rarr"],["\u2193","darr"], + ["\u2194","harr"],["\u21B5","crarr"],["\u21D0","lArr"],["\u21D1","uArr"], + ["\u21D2","rArr"],["\u21D3","dArr"],["\u21D4","hArr"],["\u2200","forall"], + ["\u2202","part"],["\u2203","exist"],["\u2205","empty"],["\u2207","nabla"], + ["\u2208","isin"],["\u2209","notin"],["\u220B","ni"],["\u220F","prod"], + ["\u2211","sum"],["\u2212","minus"],["\u2217","lowast"],["\u221A","radic"], + ["\u221D","prop"],["\u221E","infin"],["\u2220","ang"],["\u2227","and"], + ["\u2228","or"],["\u2229","cap"],["\u222A","cup"],["\u222B","int"], + ["\u2234","there4"],["\u223C","sim"],["\u2245","cong"],["\u2248","asymp"], + ["\u2260","ne"],["\u2261","equiv"],["\u2264","le"],["\u2265","ge"], + ["\u2282","sub"],["\u2283","sup"],["\u2284","nsub"],["\u2286","sube"], + ["\u2287","supe"],["\u2295","oplus"],["\u2297","otimes"],["\u22A5","perp"], + ["\u22C5","sdot"],["\u2308","lceil"],["\u2309","rceil"],["\u230A","lfloor"], + ["\u230B","rfloor"],["\u2329","lang"],["\u232A","rang"],["\u25CA","loz"], + ["\u2660","spades"],["\u2663","clubs"],["\u2665","hearts"],["\u2666","diams"], + ["\u0152","Elig"],["\u0153","oelig"],["\u0160","Scaron"],["\u0161","scaron"], + ["\u0178","Yuml"],["\u02C6","circ"],["\u02DC","tilde"],["\u2002","ensp"], + ["\u2003","emsp"],["\u2009","thinsp"],["\u200C","zwnj"],["\u200D","zwj"], + ["\u200E","lrm"],["\u200F","rlm"],["\u2013","ndash"],["\u2014","mdash"], + ["\u2018","lsquo"],["\u2019","rsquo"],["\u201A","sbquo"],["\u201C","ldquo"], + ["\u201D","rdquo"],["\u201E","bdquo"],["\u2020","dagger"],["\u2021","Dagger"], + ["\u2030","permil"],["\u2039","lsaquo"],["\u203A","rsaquo"] + ]; + + dhe.encode = function(str/*string*/, m /*array?*/){ + // summary: + // Function to obtain an entity encoding for a specified character + // str: + // The string to process for possible entity encoding. + // m: + // An optional list of character to entity name mappings (array of + // arrays). If not provided, it uses the and Latin entities as the + // set to map and escape. + // tags: + // public + if(str){ + if(!m){ + // Apply the basic mappings. HTML should always come first when decoding + // as well. + str = _applyEncodingMap(str, dhe.html); + str = _applyEncodingMap(str, dhe.latin); + + }else{ + str = _applyEncodingMap(str, m); + } + } + return str; + }; + + dhe.decode = function(str/*string*/, m /*array?*/){ + // summary: + // Function to obtain an entity encoding for a specified character + // str: + // The string to process for possible entity encoding to decode. + // m: + // An optional list of character to entity name mappings (array of + // arrays). If not provided, it uses the HTML and Latin entities as the + // set to map and decode. + // tags: + // public + if(str){ + if(!m){ + // Apply the basic mappings. HTML should always come first when decoding + // as well. + str = _applyDecodingMap(str, dhe.html); + str = _applyDecodingMap(str, dhe.latin); + + }else{ + str = _applyDecodingMap(str, m); + } + } + return str; + }; + return dhe; +}); + diff --git a/js/dojo-1.7.2/dojox/html/ext-dojo/style.js b/js/dojo-1.7.2/dojox/html/ext-dojo/style.js new file mode 100644 index 0000000..c4cb6cc --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/ext-dojo/style.js @@ -0,0 +1,457 @@ +//>>built +define("dojox/html/ext-dojo/style", ["dojo/_base/kernel", "dojo/dom-style", "dojo/_base/lang", "dojo/_base/html", "dojo/_base/sniff", + "dojo/_base/window", "dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/dom-attr"], + function(kernel, domStyle, lang, Html, has, win, DOM, DOMConstruct, DOMStyle, DOMAttr){ + kernel.experimental("dojox.html.ext-dojo.style"); + var st = lang.getObject("dojox.html.ext-dojo.style", true); + var HtmlX = lang.getObject("dojox.html"); + // summary: Extensions to dojo.style adding the css3 "transform" and "transform-origin" properties on IE5.5+ + // description: + // A Package to extend the dojo.style function + // Supported transformation functions: + // matrix, translate, translateX, translateY, scale, scaleX, scaleY, rotate, skewX, skewY, skew + lang.mixin(HtmlX["ext-dojo"].style, { + supportsTransform: true, + _toPx: function(measure){ + var ds = Html.style, _conversion = this._conversion; + if(typeof measure === "number"){ + return measure + "px"; + }else if(measure.toLowerCase().indexOf("px") != -1){ + return measure; + } + // "native" conversion in px + !_conversion.parentNode && DOMConstruct.place(_conversion, win.body()); + ds(_conversion, "margin", measure); + return ds(_conversion, "margin"); + }, + init: function(){ + var docStyle = win.doc.documentElement.style, extStyle = HtmlX["ext-dojo"].style, + sget = DOMStyle.get, sset = DOMStyle.set; + DOMStyle.get = function(/*DOMNode|String*/ node, /*String|Object*/ name){ + var tr = (name == "transform"), + to = (name == "transformOrigin"); + if(tr){ + return extStyle.getTransform(node); + }else if(to){ + return extStyle.getTransformOrigin(node); + }else{ + return arguments.length == 2 ? sget(node, name) : sget(node); + } + }; + DOMStyle.set = function(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + var tr = (name == "transform"), + to = (name == "transformOrigin"), + n = DOM.byId(node) + ; + if(tr){ + return extStyle.setTransform(n, value, true); + }else if(to){ + return extStyle.setTransformOrigin(n, value); + }else{ + return arguments.length == 3 ? sset(n, name, value) : sset(n, name); + } + }; + // prefixes and property names + for(var i = 0, tPrefix = ["WebkitT", "MozT", "OT", "msT", "t"]; i < tPrefix.length; i++){ + if(typeof docStyle[tPrefix[i] + "ransform"] !== "undefined"){ + this.tPropertyName = tPrefix[i] + "ransform"; + } + if(typeof docStyle[tPrefix[i] + "ransformOrigin"] !== "undefined"){ + this.toPropertyName = tPrefix[i] + "ransformOrigin"; + } + } + if(this.tPropertyName){ + this.setTransform = function(/*DomNode*/node, /*String*/ transform){ + return DOMStyle.set(node, this.tPropertyName, transform); + }; + this.getTransform = function(/*DomNode*/node){ + return DOMStyle.get(node, this.tPropertyName); + }; + }else if(has("ie")){ + this.setTransform = this._setTransformFilter; + this.getTransform = this._getTransformFilter; + } + if(this.toPropertyName){ + this.setTransformOrigin = function(/*DomNode*/node, /*String*/ transformOrigin){ + return sset(node, this.toPropertyName, transformOrigin); + }; + this.getTransformOrigin = function(/*DomNode*/node){ + return sget(node, this.toPropertyName); + }; + }else if(has("ie")){ + this.setTransformOrigin = this._setTransformOriginFilter; + this.getTransformOrigin = this._getTransformOriginFilter; + }else{ + this.supportsTransform = false; + } + this._conversion = DOMConstruct.create("div", { + style: { + position: "absolute", + top: "-100px", + left: "-100px", + fontSize: 0, + width: "0", + backgroundPosition: "50% 50%" + } + }); + }, + _notSupported: function(){ + console.warn("Sorry, this browser doesn't support transform and transform-origin"); + }, + _setTransformOriginFilter: function(/*DomNode*/ node, /*String*/ transformOrigin){ + var to = lang.trim(transformOrigin) + .replace(" top", " 0") + .replace("left ", "0 ") + .replace(" center", "50%") + .replace("center ", "50% ") + .replace(" bottom", " 100%") + .replace("right ", "100% ") + .replace(/\s+/, " "), + toAry = to.split(" "), + n = DOM.byId(node), + t = this.getTransform(n), + validOrigin = true + ; + for(var i = 0; i < toAry.length; i++){ + validOrigin = validOrigin && /^0|(\d+(%|px|pt|in|pc|mm|cm))$/.test(toAry[i]); + if(toAry[i].indexOf("%") == -1){ + toAry[i] = this._toPx(toAry[i]); + } + } + if(!validOrigin || !toAry.length || toAry.length > 2 ){ + return transformOrigin; + } + Html.attr(n, "dojo-transform-origin", toAry.join(" ")); + t && this.setTransform(node, t); + return transformOrigin; + }, + _getTransformOriginFilter: function(/*DomNode*/ node){ + return Html.attr(node, "dojo-transform-origin") || "50% 50%"; + }, + _setTransformFilter: function(/*DomNode*/ node, /*String*/ transform){ + // Using the Matrix Filter to implement the transform property on IE + var t = transform.replace(/\s/g, ""), + n = DOM.byId(node), + transforms = t.split(")"), + toRad = 1, toRad1 = 1, + mstr = "DXImageTransform.Microsoft.Matrix", + hasAttr = DOMAttr.has, + attr = Html.attr, + // Math functions + PI = Math.PI, cos = Math.cos, sin = Math.sin, tan = Math.tan, max = Math.max, min = Math.min, abs = Math.abs, + degToRad = PI/180, gradToRad = PI/200, + + // current transform + ct = "", currentTransform = "", + matchingTransforms = [], + x0 = 0, y0 = 0, dx = 0, dy = 0, xc = 0, yc = 0, a = 0, + + // default transform, identity matrix + m11 = 1, m12 = 0, m21 = 0, m22 = 1, + + // no translation + tx = 0, ty = 0, + props = [m11, m12, m21, m22, tx, ty], + hasMatrix = false, + ds = Html.style, + newPosition = ds(n, "position") == "absolute" ? "absolute" : "relative", + w = ds(n, "width") + ds(n, "paddingLeft") + ds(n, "paddingRight"), + h = ds(n, "height") + ds(n, "paddingTop") + ds(n, "paddingBottom"), + toPx = this._toPx + ; + + !hasAttr(n, "dojo-transform-origin") && this.setTransformOrigin(n, "50% 50%"); + + for(var i = 0, l = transforms.length; i < l; i++){ + matchingTransforms = transforms[i].match(/matrix|rotate|scaleX|scaleY|scale|skewX|skewY|skew|translateX|translateY|translate/); + currentTransform = matchingTransforms ? matchingTransforms[0] : ""; + switch(currentTransform){ + case "matrix": + // generic transformation + // + // matrix: + // m11 m12 + // + // m21 m22 + // + ct = transforms[i].replace(/matrix\(|\)/g, ""); + var matrix = ct.split(","); + m11 = props[0]*matrix[0] + props[1]*matrix[2]; + m12 = props[0]*matrix[1] + props[1]*matrix[3]; + m21 = props[2]*matrix[0] + props[3]*matrix[2]; + m22 = props[2]*matrix[1] + props[3]*matrix[3]; + tx = props[4] + matrix[4]; + ty = props[5] + matrix[5]; + break; + case "rotate": + // rotate + // + // rotation angle: + // a (rad, deg or grad) + // + // matrix: + // cos(a) -sin(a) + // + // sin(a) cos(a) + // + ct = transforms[i].replace(/rotate\(|\)/g, ""); + toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1; + a = parseFloat(ct)*toRad; + var s = sin(a), + c = cos(a) + ; + m11 = props[0]*c + props[1]*s; + m12 = -props[0]*s + props[1]*c; + m21 = props[2]*c + props[3]*s; + m22 = -props[2]*s + props[3]*c; + break; + case "skewX": + // skewX + // + // skew angle: + // a (rad, deg or grad) + // + // matrix: + // 1 tan(a) + // + // 0 1 + // + ct = transforms[i].replace(/skewX\(|\)/g, ""); + toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1; + var ta = tan(parseFloat(ct)*toRad); + m11 = props[0]; + m12 = props[0]*ta + props[1]; + m21 = props[2]; + m22 = props[2]*ta + props[3]; + break; + case "skewY": + // skewY + // + // skew angle: + // a (rad, deg or grad) + // + // matrix: + // 1 0 + // + // tan(a) 1 + // + ct = transforms[i].replace(/skewY\(|\)/g, ""); + toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1; + ta = tan(parseFloat(ct)*toRad); + m11 = props[0] + props[1]*ta; + m12 = props[1]; + m21 = props[2] + props[3]*ta; + m22 = props[3]; + break; + case "skew": + // skew + // + // skew angles: + // a0 (rad, deg or grad) + // a1 (rad, deg or grad) + // + // matrix: + // 1 tan(a0) + // + // tan(a1) 1 + // + ct = transforms[i].replace(/skew\(|\)/g, ""); + var skewAry = ct.split(","); + skewAry[1] = skewAry[1] || "0"; + toRad = skewAry[0].indexOf("deg") != -1 ? degToRad : skewAry[0].indexOf("grad") != -1 ? gradToRad : 1; + toRad1 = skewAry[1].indexOf("deg") != -1 ? degToRad : skewAry[1].indexOf("grad") != -1 ? gradToRad : 1; + var a0 = tan(parseFloat(skewAry[0])*toRad), + a1 = tan(parseFloat(skewAry[1])*toRad1) + ; + m11 = props[0] + props[1]*a1; + m12 = props[0]*a0 + props[1]; + m21 = props[2]+ props[3]*a1; + m22 = props[2]*a0 + props[3]; + break; + case "scaleX": + // scaleX + // + // scale factor: + // sx + // + // matrix: + // sx 0 + // + // 0 1 + // + ct = parseFloat(transforms[i].replace(/scaleX\(|\)/g, "")) || 1; + m11 = props[0]*ct; + m12 = props[1]; + m21 = props[2]*ct; + m22 = props[3]; + break; + case "scaleY": + // scaleY + // + // scale factor: + // sy + // + // matrix: + // 1 0 + // + // 0 sy + // + ct = parseFloat(transforms[i].replace(/scaleY\(|\)/g, "")) || 1; + m11 = props[0]; + m12 = props[1]*ct; + m21 = props[2]; + m22 = props[3]*ct; + break; + case "scale": + // scale + // + // scale factor: + // sx, sy + // + // matrix: + // sx 0 + // + // 0 sy + // + ct = transforms[i].replace(/scale\(|\)/g, ""); + var scaleAry = ct.split(","); + scaleAry[1] = scaleAry[1] || scaleAry[0]; + m11 = props[0]*scaleAry[0]; + m12 = props[1]*scaleAry[1]; + m21 = props[2]*scaleAry[0]; + m22 = props[3]*scaleAry[1]; + break; + case "translateX": + ct = parseInt(transforms[i].replace(/translateX\(|\)/g, "")) || 1; + m11 = props[0]; + m12 = props[1]; + m21 = props[2]; + m22 = props[3]; + tx = toPx(ct); + tx && attr(n, "dojo-transform-matrix-tx", tx); + break; + case "translateY": + ct = parseInt(transforms[i].replace(/translateY\(|\)/g, "")) || 1; + m11 = props[0]; + m12 = props[1]; + m21 = props[2]; + m22 = props[3]; + ty = toPx(ct); + ty && attr(n, "dojo-transform-matrix-ty", ty); + break; + case "translate": + ct = transforms[i].replace(/translate\(|\)/g, ""); + m11 = props[0]; + m12 = props[1]; + m21 = props[2]; + m22 = props[3]; + var translateAry = ct.split(","); + translateAry[0] = parseInt(toPx(translateAry[0])) || 0; + translateAry[1] = parseInt(toPx(translateAry[1])) || 0; + tx = translateAry[0]; + ty = translateAry[1]; + tx && attr(n, "dojo-transform-matrix-tx", tx); + ty && attr(n, "dojo-transform-matrix-ty", ty); + break; + } + props = [m11, m12, m21, m22, tx, ty]; + } + // test + var Bx = min(w*m11 + h*m12, min(min(w*m11, h*m12), 0)), + By = min(w*m21 + h*m22, min(min(w*m21, h*m22), 0)) + ; + dx = -Bx; + dy = -By; + if(has("ie") < 8){ + // on IE < 8 the node must have hasLayout = true + n.style.zoom = "1"; + if(newPosition != "absolute"){ + var parentWidth = ds(node.parentNode, "width"), + tw = abs(w*m11), + th = abs(h*m12), + wMax = max(tw + th, max(max(th, tw), 0)) + ; + dx -= (wMax - w) / 2 - (parentWidth > wMax ? 0 : (wMax - parentWidth) / 2); + } + }else if(has("ie") == 8){ + // IE8 bug, a filter is applied to positioned descendants + // only if the parent has z-index + ds(n, "zIndex") == "auto" && (n.style.zIndex = "0"); + } + + try{ + hasMatrix = !!n.filters.item(mstr); + }catch(e){ + hasMatrix = false; + } + if(hasMatrix){ + n.filters.item(mstr).M11 = m11; + n.filters.item(mstr).M12 = m12; + n.filters.item(mstr).M21 = m21; + n.filters.item(mstr).M22 = m22; + // use 'nearest' for a faster transform + n.filters.item(mstr).filterType = 'bilinear'; + n.filters.item(mstr).Dx = 0; + n.filters.item(mstr).Dy = 0; + n.filters.item(mstr).sizingMethod = 'auto expand'; + }else{ + n.style.filter += + " progid:" + mstr + "(M11=" + m11 + + ",M12=" + m12 + + ",M21=" + m21 + + ",M22=" + m22 + + ",FilterType='bilinear',Dx=0,Dy=0,sizingMethod='auto expand')" + ; + } + tx = parseInt(attr(n, "dojo-transform-matrix-tx") || "0"); + ty = parseInt(attr(n, "dojo-transform-matrix-ty") || "0"); + + // transform origin + var toAry = attr(n, "dojo-transform-origin").split(" "); + + for(i = 0; i < 2; i++){ + toAry[i] = toAry[i] || "50%"; + } + xc = (toAry[0].toString().indexOf("%") != -1) ? w * parseInt(toAry[0]) * .01 : toAry[0]; + yc = (toAry[1].toString().indexOf("%") != -1) ? h * parseInt(toAry[1]) * .01 : toAry[1]; + if(hasAttr(n, "dojo-startX")){ + x0 = parseInt(attr(n, "dojo-startX")); + }else{ + x0 = parseInt(ds(n, "left")); + attr(n, "dojo-startX", newPosition == "absolute" ? x0 : "0"); + } + if(hasAttr(n, "dojo-startY")){ + y0 = parseInt(attr(n, "dojo-startY")); + }else{ + y0 = parseInt(ds(n, "top")); + attr(n, "dojo-startY", newPosition == "absolute" ? y0 : "0"); + } + ds(n, { + position: newPosition, + left: x0 - parseInt(dx) + parseInt(xc) - ((parseInt(xc) - tx)*m11 + (parseInt(yc) - ty)*m12) + "px", + top: y0 - parseInt(dy) + parseInt(yc) - ((parseInt(xc) - tx)*m21 + (parseInt(yc) - ty)*m22) + "px" + }); + return transform; + }, + _getTransformFilter: function(/*DomNode*/ node){ + try{ + var n = DOM.byId(node), + item = n.filters.item(0) + ; + return "matrix(" + item.M11 + ", " + item.M12 + ", " + item.M21 + ", " + + item.M22 + ", " + (Html.attr(node, "dojo-transform-tx") || "0") + ", " + (Html.attr(node, "dojo-transform-ty") || "0") + ")"; + }catch(e){ + return "matrix(1, 0, 0, 1, 0, 0)"; + } + }, + setTransform: function(){ + this._notSupported(); + }, + setTransformOrigin: function(){ + this._notSupported(); + } + }); + + HtmlX["ext-dojo"].style.init(); + return Html.style; +}); diff --git a/js/dojo-1.7.2/dojox/html/format.js b/js/dojo-1.7.2/dojox/html/format.js new file mode 100644 index 0000000..8ce646c --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/format.js @@ -0,0 +1,478 @@ +//>>built +define("dojox/html/format", ["dojo/_base/kernel", "./entities", "dojo/_base/array", "dojo/_base/window", "dojo/_base/sniff"], + function(lang, Entities, ArrayUtil, Window, has) { + var dhf = lang.getObject("dojox.html.format",true); + + dhf.prettyPrint = function(html/*String*/, indentBy /*Integer?*/, maxLineLength /*Integer?*/, map/*Array?*/, /*boolean*/ xhtml){ + // summary: + // Function for providing a 'pretty print' version of HTML content from + // the provided string. It's nor perfect by any means, but it does + // a 'reasonable job'. + // html: String + // The string of HTML to try and generate a 'pretty' formatting. + // indentBy: Integer + // Optional input for the number of spaces to use when indenting. + // If not defined, zero, negative, or greater than 10, will just use tab + // as the indent. + // maxLineLength: Integer + // Optional input for the number of characters a text line should use in + // the document, including the indent if possible. + // map: Array + // Optional array of entity mapping characters to use when processing the + // HTML Text content. By default it uses the default set used by the + // dojox.html.entities.encode function. + // xhtml: boolean + // Optional parameter that declares that the returned HTML should try to be 'xhtml' compatible. + // This means normally unclosed tags are terminated with /> instead of >. Example: <hr> -> <hr /> + var content = []; + var indentDepth = 0; + var closeTags = []; + var iTxt = "\t"; + var textContent = ""; + var inlineStyle = []; + var i; + + // Compile regexps once for this call. + var rgxp_fixIEAttrs = /[=]([^"']+?)(\s|>)/g; + var rgxp_styleMatch = /style=("[^"]*"|'[^']*'|\S*)/gi; + var rgxp_attrsMatch = /[\w-]+=("[^"]*"|'[^']*'|\S*)/gi; + + // Check to see if we want to use spaces for indent instead + // of tab. + if(indentBy && indentBy > 0 && indentBy < 10){ + iTxt = ""; + for(i = 0; i < indentBy; i++){ + iTxt += " "; + } + } + + //Build the content outside of the editor so we can walk + //via DOM and build a 'pretty' output. + var contentDiv = Window.doc.createElement("div"); + contentDiv.innerHTML = html; + + // Use the entity encode/decode functions, they cache on the map, + // so it won't multiprocess a map. + var encode = Entities.encode; + var decode = Entities.decode; + + /** Define a bunch of formatters to format the output. **/ + var isInlineFormat = function(tag){ + // summary: + // Function to determine if the current tag is an inline + // element that does formatting, as we don't want to + // break/indent around it, as it can screw up text. + // tag: + // The tag to examine + switch(tag){ + case "a": + case "b": + case "strong": + case "s": + case "strike": + case "i": + case "u": + case "em": + case "sup": + case "sub": + case "span": + case "font": + case "big": + case "cite": + case "q": + case "small": + return true; + default: + return false; + } + }; + + //Create less divs. + var div = contentDiv.ownerDocument.createElement("div"); + var outerHTML = function(node){ + // summary: + // Function to return the outer HTML of a node. + // Yes, IE has a function like this, but using cloneNode + // allows avoiding looking at any child nodes, because in this + // case, we don't want them. + var clone = node.cloneNode(false); + div.appendChild(clone); + var html = div.innerHTML; + div.innerHTML = ""; + return html; + }; + + var sizeIndent = function(){ + var i, txt = ""; + for(i = 0; i < indentDepth; i++){ + txt += iTxt; + } + return txt.length; + } + + var indent = function(){ + // summary: + // Function to handle indent depth. + var i; + for(i = 0; i < indentDepth; i++){ + content.push(iTxt); + } + }; + var newline = function(){ + // summary: + // Function to handle newlining. + content.push("\n"); + }; + + var processTextNode = function(n){ + // summary: + // Function to process the text content for doc + // insertion + // n: + // The text node to process. + textContent += encode(n.nodeValue, map); + }; + + var formatText = function(txt){ + // summary: + // Function for processing the text content encountered up to a + // point and inserting it into the formatted document output. + // txt: + // The text to format. + var i; + var _iTxt; + + // Clean up any indention organization since we're going to rework it + // anyway. + var _lines = txt.split("\n"); + for(i = 0; i < _lines.length; i++){ + _lines[i] = lang.trim(_lines[i]); + } + txt = _lines.join(" "); + txt = lang.trim(txt); + if(txt !== ""){ + var lines = []; + if(maxLineLength && maxLineLength > 0){ + var indentSize = sizeIndent(); + var maxLine = maxLineLength; + if(maxLineLength > indentSize){ + maxLine -= indentSize; + } + while(txt){ + if(txt.length > maxLineLength){ + for(i = maxLine; (i > 0 && txt.charAt(i) !== " "); i--){ + // Do nothing, we're just looking for a space to split at. + } + if(!i){ + // Couldn't find a split going back, so go forward. + for(i = maxLine; (i < txt.length && txt.charAt(i) !== " "); i++){ + // Do nothing, we're just looking for a space to split at. + } + } + var line = txt.substring(0, i); + line = lang.trim(line); + // Shift up the text string to the next chunk. + txt = lang.trim(txt.substring((i == txt.length)?txt.length:i + 1, txt.length)); + if(line){ + _iTxt = ""; + for(i = 0; i < indentDepth; i++){ + _iTxt += iTxt; + } + line = _iTxt + line + "\n"; + } + lines.push(line); + }else{ + // Line is shorter than out desired length, so use it. + // as/is + _iTxt = ""; + for(i = 0; i < indentDepth; i++){ + _iTxt += iTxt; + } + txt = _iTxt + txt + "\n"; + lines.push(txt); + txt = null; + } + } + return lines.join(""); + }else{ + _iTxt = ""; + for(i = 0; i < indentDepth; i++){ + _iTxt += iTxt; + } + txt = _iTxt + txt + "\n"; + return txt; + } + }else{ + return ""; + } + }; + + var processScriptText = function(txt){ + // summary: + // Function to clean up potential escapes in the script code. + if(txt){ + txt = txt.replace(/"/gi, "\""); + txt = txt.replace(/>/gi, ">"); + txt = txt.replace(/</gi, "<"); + txt = txt.replace(/&/gi, "&"); + } + return txt; + }; + + var formatScript = function(txt){ + // summary: + // Function to rudimentary formatting of script text. + // Not perfect, but it helps get some level of organization + // in there. + // txt: + // The script text to try to format a bit. + if(txt){ + txt = processScriptText(txt); + var i, t, c, _iTxt; + var indent = 0; + var scriptLines = txt.split("\n"); + var newLines = []; + for (i = 0; i < scriptLines.length; i++){ + var line = scriptLines[i]; + var hasNewlines = (line.indexOf("\n") > -1); + line = lang.trim(line); + if(line){ + var iLevel = indent; + // Not all blank, so we need to process. + for(c = 0; c < line.length; c++){ + var ch = line.charAt(c); + if(ch === "{"){ + indent++; + }else if(ch === "}"){ + indent--; + // We want to back up a bit before the + // line is written. + iLevel = indent; + } + } + _iTxt = ""; + for(t = 0; t < indentDepth + iLevel; t++){ + _iTxt += iTxt; + } + newLines.push(_iTxt + line + "\n"); + }else if(hasNewlines && i === 0){ + // Just insert a newline for blank lines as + // long as it's not the first newline (we + // already inserted that in the openTag handler) + newLines.push("\n"); + } + + } + // Okay, create the script text, hopefully reasonably + // formatted. + txt = newLines.join(""); + } + return txt; + }; + + var openTag = function(node){ + // summary: + // Function to open a new tag for writing content. + var name = node.nodeName.toLowerCase(); + // Generate the outer node content (tag with attrs) + var nText = lang.trim(outerHTML(node)); + var tag = nText.substring(0, nText.indexOf(">") + 1); + + // Also thanks to IE, we need to check for quotes around + // attributes and insert if missing. + tag = tag.replace(rgxp_fixIEAttrs,'="$1"$2'); + + // And lastly, thanks IE for changing style casing and end + // semi-colon and webkit adds spaces, so lets clean it up by + // sorting, etc, while we're at it. + tag = tag.replace(rgxp_styleMatch, function(match){ + var sL = match.substring(0,6); + var style = match.substring(6, match.length); + var closure = style.charAt(0); + style = lang.trim(style.substring(1,style.length -1)); + style = style.split(";"); + var trimmedStyles = []; + ArrayUtil.forEach(style, function(s){ + s = lang.trim(s); + if(s){ + // Lower case the style name, leave the value alone. Mainly a fixup for IE. + s = s.substring(0, s.indexOf(":")).toLowerCase() + s.substring(s.indexOf(":"), s.length); + trimmedStyles.push(s); + } + }); + trimmedStyles = trimmedStyles.sort(); + + // Reassemble and return the styles in sorted order. + style = trimmedStyles.join("; "); + var ts = lang.trim(style); + if(!ts || ts === ";"){ + // Just remove any style attrs that are empty. + return ""; + }else{ + style += ";"; + return sL + closure + style + closure; + } + }); + + // Try and sort the attributes while we're at it. + var attrs = []; + tag = tag.replace(rgxp_attrsMatch, function(attr){ + attrs.push(lang.trim(attr)); + return ""; + }); + attrs = attrs.sort(); + + // Reassemble the tag with sorted attributes! + tag = "<" + name; + if(attrs.length){ + tag += " " + attrs.join(" "); + } + + // Determine closure status. If xhtml, + // then close the tag properly as needed. + if(nText.indexOf("</") != -1){ + closeTags.push(name); + tag += ">"; + }else{ + if(xhtml){ + tag += " />"; + }else{ + tag += ">"; + } + closeTags.push(false); + } + + var inline = isInlineFormat(name); + inlineStyle.push(inline); + if(textContent && !inline){ + // Process any text content we have that occurred + // before the open tag of a non-inline. + content.push(formatText(textContent)); + textContent = ""; + } + + // Determine if this has a closing tag or not! + if(!inline){ + indent(); + content.push(tag); + newline(); + indentDepth++; + }else{ + textContent += tag; + } + + }; + + var closeTag = function(){ + // summary: + // Function to close out a tag if necessary. + var inline = inlineStyle.pop(); + if(textContent && !inline){ + // Process any text content we have that occurred + // before the close tag. + content.push(formatText(textContent)); + textContent = ""; + } + var ct = closeTags.pop(); + if(ct){ + ct = "</" + ct + ">"; + if(!inline){ + indentDepth--; + indent(); + content.push(ct); + newline(); + }else{ + textContent += ct; + } + }else{ + indentDepth--; + } + }; + + var processCommentNode = function(n){ + // summary: + // Function to handle processing a comment node. + // n: + // The comment node to process. + + //Make sure contents aren't double-encoded. + var commentText = decode(n.nodeValue, map); + indent(); + content.push("<!--"); + newline(); + indentDepth++; + content.push(formatText(commentText)); + indentDepth--; + indent(); + content.push("-->"); + newline(); + }; + + var processNode = function(node) { + // summary: + // Entrypoint for processing all the text! + var children = node.childNodes; + if(children){ + var i; + for(i = 0; i < children.length; i++){ + var n = children[i]; + if(n.nodeType === 1){ + var tg = lang.trim(n.tagName.toLowerCase()); + if(has("ie") && n.parentNode != node){ + // IE is broken. DOMs are supposed to be a tree. + // But in the case of malformed HTML, IE generates a graph + // meaning one node ends up with multiple references + // (multiple parents). This is totally wrong and invalid, but + // such is what it is. We have to keep track and check for + // this because otherwise the source output HTML will have dups. + continue; + } + if(tg && tg.charAt(0) === "/"){ + // IE oddity. Malformed HTML can put in odd tags like: + // </ >, </span>. It treats a mismatched closure as a new + // start tag. So, remove them. + continue; + }else{ + //Process non-dup, seemingly wellformed elements! + openTag(n); + if(tg === "script"){ + content.push(formatScript(n.innerHTML)); + }else if(tg === "pre"){ + var preTxt = n.innerHTML; + if(has("mozilla")){ + //Mozilla screws this up, so fix it up. + preTxt = preTxt.replace("<br>", "\n"); + preTxt = preTxt.replace("<pre>", ""); + preTxt = preTxt.replace("</pre>", ""); + } + // Add ending newline, if needed. + if(preTxt.charAt(preTxt.length - 1) !== "\n"){ + preTxt += "\n"; + } + content.push(preTxt); + }else{ + processNode(n); + } + closeTag(); + } + }else if(n.nodeType === 3 || n.nodeType === 4){ + processTextNode(n); + }else if(n.nodeType === 8){ + processCommentNode(n); + } + } + } + }; + + //Okay, finally process the input string. + processNode(contentDiv); + if(textContent){ + // Insert any trailing text. See: #10854 + content.push(formatText(textContent)); + textContent = ""; + } + return content.join(""); //String + }; + return dhf; +}); + diff --git a/js/dojo-1.7.2/dojox/html/metrics.js b/js/dojo-1.7.2/dojox/html/metrics.js new file mode 100644 index 0000000..776378f --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/metrics.js @@ -0,0 +1,179 @@ +//>>built +define("dojox/html/metrics", ["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready", "dojo/_base/unload", + "dojo/_base/window", "dojo/dom-geometry"], + function(kernel,lang,has,ready,UnloadUtil,Window,DOMGeom){ + var dhm = lang.getObject("dojox.html.metrics",true); + var dojox = lang.getObject("dojox"); + + // derived from Morris John's emResized measurer + dhm.getFontMeasurements = function(){ + // summary + // Returns an object that has pixel equivilents of standard font size values. + var heights = { + '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0, + 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0 + }; + + if(has("ie")){ + // we do a font-size fix if and only if one isn't applied already. + // NOTE: If someone set the fontSize on the HTML Element, this will kill it. + Window.doc.documentElement.style.fontSize="100%"; + } + + // set up the measuring node. + var div=Window.doc.createElement("div"); + var ds = div.style; + ds.position="absolute"; + ds.left="-100px"; + ds.top="0"; + ds.width="30px"; + ds.height="1000em"; + ds.borderWidth="0"; + ds.margin="0"; + ds.padding="0"; + ds.outline="0"; + ds.lineHeight="1"; + ds.overflow="hidden"; + Window.body().appendChild(div); + + // do the measurements. + for(var p in heights){ + ds.fontSize = p; + heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000; + } + + Window.body().removeChild(div); + div = null; + return heights; // object + }; + + var fontMeasurements = null; + + dhm.getCachedFontMeasurements = function(recalculate){ + if(recalculate || !fontMeasurements){ + fontMeasurements = dhm.getFontMeasurements(); + } + return fontMeasurements; + }; + + var measuringNode = null, empty = {}; + dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){ + var m, s; + if(!measuringNode){ + m = measuringNode = Window.doc.createElement("div"); + // Container that we can set contraints on so that it doesn't + // trigger a scrollbar. + var c = Window.doc.createElement("div"); + c.appendChild(m); + s = c.style; + s.overflow='scroll'; + s.position = "absolute"; + s.left = "0px"; + s.top = "-10000px"; + s.width = "1px"; + s.height = "1px"; + s.visibility = "hidden"; + s.borderWidth = "0"; + s.margin = "0"; + s.padding = "0"; + s.outline = "0"; + Window.body().appendChild(c); + }else{ + m = measuringNode; + } + // reset styles + m.className = ""; + s = m.style; + s.borderWidth = "0"; + s.margin = "0"; + s.padding = "0"; + s.outline = "0"; + // set new style + if(arguments.length > 1 && style){ + for(var i in style){ + if(i in empty){ continue; } + s[i] = style[i]; + } + } + // set classes + if(arguments.length > 2 && className){ + m.className = className; + } + // take a measure + m.innerHTML = text; + var box = DOMGeom.position(m); + // position doesn't report right (reports 1, since parent is 1) + // So we have to look at the scrollWidth to get the real width + // Height is right. + box.w = m.parentNode.scrollWidth; + return box; + }; + + // determine the scrollbar sizes on load. + var scroll={ w:16, h:16 }; + dhm.getScrollbar=function(){ return { w:scroll.w, h:scroll.h }; }; + + dhm._fontResizeNode = null; + + dhm.initOnFontResize = function(interval){ + var f = dhm._fontResizeNode = Window.doc.createElement("iframe"); + var fs = f.style; + fs.position = "absolute"; + fs.width = "5em"; + fs.height = "10em"; + fs.top = "-10000px"; + if(has("ie")){ + f.onreadystatechange = function(){ + if(f.contentWindow.document.readyState == "complete"){ + f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize; + } + }; + }else{ + f.onload = function(){ + f.contentWindow.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize; + }; + } + //The script tag is to work around a known firebug race condition. See comments in bug #9046 + f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'"); + Window.body().appendChild(f); + dhm.initOnFontResize = function(){}; + }; + + dhm.onFontResize = function(){}; + dhm._fontresize = function(){ + dhm.onFontResize(); + } + + UnloadUtil.addOnUnload(function(){ + // destroy our font resize iframe if we have one + var f = dhm._fontResizeNode; + if(f){ + if(has("ie") && f.onresize){ + f.onresize = null; + }else if(f.contentWindow && f.contentWindow.onresize){ + f.contentWindow.onresize = null; + } + dhm._fontResizeNode = null; + } + }); + + ready(function(){ + // getScrollbar metrics node + try{ + var n=Window.doc.createElement("div"); + n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;"; + Window.body().appendChild(n); + scroll.w = n.offsetWidth - n.clientWidth; + scroll.h = n.offsetHeight - n.clientHeight; + Window.body().removeChild(n); + //console.log("Scroll bar dimensions: ", scroll); + delete n; + }catch(e){} + + // text size poll setup + if("fontSizeWatch" in kernel.config && !!kernel.config.fontSizeWatch){ + dhm.initOnFontResize(); + } + }); + return dhm; +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/html/resources/ellipsis.css b/js/dojo-1.7.2/dojox/html/resources/ellipsis.css new file mode 100644 index 0000000..d4152e5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/resources/ellipsis.css @@ -0,0 +1,34 @@ +.dojoxEllipsis, +.dojoxEllipsisShown { + white-space: nowrap; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -webkit-text-overflow: ellipsis; +} + +.dojoxEllipsis window { + width:100%; + -moz-user-focus:normal; + -moz-user-select:text; +} +.dojoxEllipsis description{ + -moz-user-focus:normal; + -moz-user-select:text; +} +.dojoxEllipsisIFrame{ + white-space: normal; + border: none; + width: 100%; + display: block; + height: 1px; + margin-top: -1px; + clear: both; +} +.dojoxEllipsisContainer{ + width: 100%; +} +.dojoxEllipsisShown:after{ + content: "\2026" +} diff --git a/js/dojo-1.7.2/dojox/html/styles.js b/js/dojo-1.7.2/dojox/html/styles.js new file mode 100644 index 0000000..8306ed5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/html/styles.js @@ -0,0 +1,309 @@ +//>>built +define("dojox/html/styles", ["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/sniff"], + function(lang, ArrayUtil, Window, has) { + // summary: + // Methods for creating and manipulating dynamic CSS Styles and Style Sheets + // + // example: + // | dojox.html.createStyle("#myDiv input", "font-size:24px"); + // Creates Style #myDiv input, which can now be applied to myDiv, and + // the inner input will be targeted + // | dojox.html.createStyle(".myStyle", "color:#FF0000"); + // Now the class myStyle can be assigned to a node's className + var dh = lang.getObject("dojox.html",true); + var dynamicStyleMap = {}; + var pageStyleSheets = {}; + var titledSheets = []; + + dh.insertCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){ + // summary: + // Creates a style and attaches it to a dynamically created stylesheet + // arguments: + // selector: + // A fully qualified class name, as it would appear in + // a CSS dojo.doc. Start classes with periods, target + // nodes with '#'. Large selectors can also be created + // like: + // | "#myDiv.myClass span input" + // declaration: + // A single string that would make up a style block, not + // including the curly braces. Include semi-colons between + // statements. Do not use JavaScript style declarations + // in camel case, use as you would in a CSS dojo.doc: + // | "color:#ffoooo;font-size:12px;margin-left:5px;" + // styleSheetName: ( optional ) + // Name of the dynamic style sheet this rule should be + // inserted into. If is not found by that name, it is + // created. If no name is passed, the name "default" is + // used. + // + var ss = dh.getDynamicStyleSheet(styleSheetName); + var styleText = selector + " {" + declaration + "}"; + console.log("insertRule:", styleText); + if(has("ie")){ + // Note: check for if(ss.cssText) does not work + ss.cssText+=styleText; + console.log("ss.cssText:", ss.cssText); + }else if(ss.sheet){ + ss.sheet.insertRule(styleText, ss._indicies.length); + }else{ + ss.appendChild(Window.doc.createTextNode(styleText)); + } + ss._indicies.push(selector+" "+declaration); + return selector; // String + }; + + dh.removeCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){ + // summary: + // Removes a cssRule base on the selector and declaration passed + // The declaration is needed for cases of dupe selectors + // description: Only removes DYNAMICALLY created cssRules. If you + // created it with dh.insertCssRule, it can be removed. + // + var ss; + var index=-1; + var nm; + var i; + for(nm in dynamicStyleMap){ + if(styleSheetName && styleSheetName !== nm) {continue;} + ss = dynamicStyleMap[nm]; + for(i=0;i<ss._indicies.length;i++){ + if(selector+" "+declaration === ss._indicies[i]){ + index = i; + break; + } + } + if(index>-1) { break; } + } + if(!ss){ + console.warn("No dynamic style sheet has been created from which to remove a rule."); + return false; + } + if(index===-1){ + console.warn("The css rule was not found and could not be removed."); + return false; + } + ss._indicies.splice(index, 1); + if(has("ie")){ + // Note: check for if(ss.removeRule) does not work + ss.removeRule(index); + }else if(ss.sheet){ + ss.sheet.deleteRule(index); + } + return true; //Boolean + }; + + dh.modifyCssRule = function(selector, declaration, styleSheetName){ + //Not implemented - it seems to have some merit for changing some complex + //selectors. It's not much use for changing simple ones like "span". + //For now, simply write a new rule which will cascade over the first. + // summary + // Modfies an existing cssRule + }; + + dh.getStyleSheet = function(/*String*/styleSheetName){ + // summary: + // Returns a style sheet based on the argument. + // Searches dynamic style sheets first. If no matches, + // searches document style sheets. + // + // argument: (optional) + // A title or an href to a style sheet. Title can be + // an attribute in a tag, or a dynamic style sheet + // reference. Href can be the name of the file. + // If no argument, the assumed created dynamic style + // sheet is used. + // try dynamic sheets first + if(dynamicStyleMap[styleSheetName || "default"]){ + return dynamicStyleMap[styleSheetName || "default"]; + } + if(!styleSheetName){ + // no arg is nly good for the default style sheet + // and it has not been created yet. + return false; + } + var allSheets = dh.getStyleSheets(); + // now try document style sheets by name + if(allSheets[styleSheetName]){ + return dh.getStyleSheets()[styleSheetName]; + } + // check for partial matches in hrefs (so that a fully + //qualified name does not have to be passed) + var nm; + for ( nm in allSheets){ + if( allSheets[nm].href && allSheets[nm].href.indexOf(styleSheetName)>-1){ + return allSheets[nm]; + } + } + return false; //StyleSheet or false + }; + + dh.getDynamicStyleSheet = function(/*String*/styleSheetName){ + // summary: + // Creates and returns a dynamically created style sheet + // used for dynamic styles + // + // argument: + // styleSheetName /* optional String */ + // The name given the style sheet so that multiple + // style sheets can be created and referenced. If + // no argument is given, the name "default" is used. + // + if(!styleSheetName){ styleSheetName="default"; } + if(!dynamicStyleMap[styleSheetName]){ + if(Window.doc.createStyleSheet){ //IE + dynamicStyleMap[styleSheetName] = Window.doc.createStyleSheet(); + if(has("ie") < 9) { + // IE9 calls this read-only. Loving the new browser so far. + dynamicStyleMap[styleSheetName].title = styleSheetName; + } + }else{ + dynamicStyleMap[styleSheetName] = Window.doc.createElement("style"); + dynamicStyleMap[styleSheetName].setAttribute("type", "text/css"); + Window.doc.getElementsByTagName("head")[0].appendChild(dynamicStyleMap[styleSheetName]); + console.log(styleSheetName, " ss created: ", dynamicStyleMap[styleSheetName].sheet); + } + dynamicStyleMap[styleSheetName]._indicies = []; + } + return dynamicStyleMap[styleSheetName]; //StyleSheet + }; + + dh.enableStyleSheet = function(/*String*/styleSheetName){ + // summary: + // Enables the style sheet with the name passed in the + // argument. Deafults to the default style sheet. + // + var ss = dh.getStyleSheet(styleSheetName); + if(ss){ + if(ss.sheet){ + ss.sheet.disabled = false; + }else{ + ss.disabled = false; + } + } + }; + + dh.disableStyleSheet = function(styleSheetName){ + // summary: + // Disables the dynamic style sheet with the name passed in the + // argument. If no arg is passed, defaults to the default style sheet. + // + var ss = dh.getStyleSheet(styleSheetName); + if(ss){ + if(ss.sheet){ + ss.sheet.disabled = true; + }else{ + ss.disabled = true; + } + } + }; + + dh.activeStyleSheet = function(/*?String*/title){ + // summary: + // Getter/Setter + // description: + // If passed a title, enables a that style sheet. All other + // toggle-able style sheets are disabled. + // If no argument is passed, returns currently enabled + // style sheet. + // + var sheets = dh.getToggledStyleSheets(); + var i; + if(arguments.length === 1){ + //console.log("sheets:", sheets); + ArrayUtil.forEach(sheets, function(s){ + s.disabled = (s.title === title) ? false : true; + }); + }else{ + for(i=0;i<sheets.length;i++){ + if(sheets[i].disabled === false){ + return sheets[i]; + } + } + } + return true; //StyleSheet or Boolean - FIXME - doesn't make a lot of sense + }; + + dh.getPreferredStyleSheet = function(){ + // summary + // Returns the style sheet that was initially enabled + // on document launch. + //TODO + }; + + dh.getToggledStyleSheets = function(){ + // summary: + // Searches HTML for style sheets that are "toggle-able" - + // can be enabled and disabled. These would include sheets + // with the title attribute, as well as the REL attribute. + // returns: + // An array of all toggle-able style sheets + // TODO: Sets of style sheets could be grouped according to + // an ID and used in sets, much like different + // groups of radio buttons. It would not however be + // according to W3C spec + // + var nm; + if(!titledSheets.length){ + var sObjects = dh.getStyleSheets(); + for(nm in sObjects){ + if(sObjects[nm].title){ + titledSheets.push(sObjects[nm]); + } + } + } + return titledSheets; //Array + }; + + dh.getStyleSheets = function(){ + // summary: + // Collects all the style sheets referenced in the HTML page, + // including any incuded via @import. + // + // returns: + // An hash map of all the style sheets. + // + //TODO: Does not recursively search for @imports, so it will + // only go one level deep. + // + if(pageStyleSheets.collected) {return pageStyleSheets;} + var sheets = Window.doc.styleSheets; + ArrayUtil.forEach(sheets, function(n){ + var s = (n.sheet) ? n.sheet : n; + var name = s.title || s.href; + if(has("ie")){ + // IE attaches a style sheet for VML - do not include this + if(s.cssText.indexOf("#default#VML") === -1){ + if(s.href){ + // linked + pageStyleSheets[name] = s; + }else if(s.imports.length){ + // Imported via @import + ArrayUtil.forEach(s.imports, function(si){ + pageStyleSheets[si.title || si.href] = si; + }); + }else{ + //embedded within page + pageStyleSheets[name] = s; + } + } + }else{ + //linked or embedded + pageStyleSheets[name] = s; + pageStyleSheets[name].id = s.ownerNode.id; + ArrayUtil.forEach(s.cssRules, function(r){ + if(r.href){ + // imported + pageStyleSheets[r.href] = r.styleSheet; + pageStyleSheets[r.href].id = s.ownerNode.id; + } + }); + } + }); + //console.log("pageStyleSheets:", pageStyleSheets); + pageStyleSheets.collected = true; + return pageStyleSheets; //Object + }; + + return dh; +}); |
