[483] | 1 | define("dojox/html/ellipsis",["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "dojo/colors"], function(d){ |
---|
| 2 | /*===== |
---|
| 3 | return { |
---|
| 4 | // summary: |
---|
| 5 | // offers cross-browser support for text-overflow: ellipsis |
---|
| 6 | // description: |
---|
| 7 | // Add "dojoxEllipsis" on any node that you want to ellipsis-ize. In order to function properly, |
---|
| 8 | // the node with the dojoxEllipsis class set on it should be a child of a node with a defined width. |
---|
| 9 | // It should also be a block-level element (i.e. `<div>`) - it will not work on td elements. |
---|
| 10 | // NOTE: When using the dojoxEllipsis class within tables, the table needs to have the table-layout: fixed style |
---|
| 11 | }; |
---|
| 12 | =====*/ |
---|
| 13 | |
---|
| 14 | if(d.isFF < 7){ //TODO: feature detect text-overflow in computed style? |
---|
| 15 | // The delay (in ms) to wait so that we don't keep querying when many |
---|
| 16 | // changes happen at once - set config "dojoxFFEllipsisDelay" if you |
---|
| 17 | // want a different value |
---|
| 18 | var delay = 1; |
---|
| 19 | if("dojoxFFEllipsisDelay" in d.config){ |
---|
| 20 | delay = Number(d.config.dojoxFFEllipsisDelay); |
---|
| 21 | if(isNaN(delay)){ |
---|
| 22 | delay = 1; |
---|
| 23 | } |
---|
| 24 | } |
---|
| 25 | try{ |
---|
| 26 | var createXULEllipsis = (function(){ |
---|
| 27 | // Create our stub XUL elements for cloning later |
---|
| 28 | // NOTE: this no longer works as of FF 4.0: |
---|
| 29 | // https://developer.mozilla.org/En/Firefox_4_for_developers#Remote_XUL_support_removed |
---|
| 30 | var sNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; |
---|
| 31 | var xml = document.createElementNS(sNS, 'window'); |
---|
| 32 | var label = document.createElementNS(sNS, 'description'); |
---|
| 33 | label.setAttribute('crop', 'end'); |
---|
| 34 | xml.appendChild(label); |
---|
| 35 | |
---|
| 36 | return function(/* Node */ n){ |
---|
| 37 | // Summary: |
---|
| 38 | // Given a node, it creates the XUL and sets its |
---|
| 39 | // content so that it will have an ellipsis |
---|
| 40 | var x = xml.cloneNode(true); |
---|
| 41 | x.firstChild.setAttribute('value', n.textContent); |
---|
| 42 | n.innerHTML = ''; |
---|
| 43 | n.appendChild(x); |
---|
| 44 | }; |
---|
| 45 | })(); |
---|
| 46 | }catch(e){} |
---|
| 47 | |
---|
| 48 | // Create our iframe elements for cloning later |
---|
| 49 | var create = d.create; |
---|
| 50 | var dd = d.doc; |
---|
| 51 | var dp = d.place; |
---|
| 52 | var iFrame = create("iframe", {className: "dojoxEllipsisIFrame", |
---|
| 53 | src: "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'", style: {display: "none"}}); |
---|
| 54 | var rollRange = function(/* W3C Range */ r, /* int? */ cnt){ |
---|
| 55 | // summary: |
---|
| 56 | // Rolls the given range back one character from the end |
---|
| 57 | // r: W3C Range |
---|
| 58 | // The range to roll back |
---|
| 59 | // cnt: int? |
---|
| 60 | // An optional number of times to roll back (defaults 1) |
---|
| 61 | if(r.collapsed){ |
---|
| 62 | // Do nothing - we are already collapsed |
---|
| 63 | return; |
---|
| 64 | } |
---|
| 65 | if(cnt > 0){ |
---|
| 66 | do{ |
---|
| 67 | rollRange(r); |
---|
| 68 | cnt--; |
---|
| 69 | }while(cnt); |
---|
| 70 | return; |
---|
| 71 | } |
---|
| 72 | if(r.endContainer.nodeType == 3 && r.endOffset > 0){ |
---|
| 73 | r.setEnd(r.endContainer, r.endOffset - 1); |
---|
| 74 | }else if(r.endContainer.nodeType == 3){ |
---|
| 75 | r.setEndBefore(r.endContainer); |
---|
| 76 | rollRange(r); |
---|
| 77 | return; |
---|
| 78 | }else if(r.endOffset && r.endContainer.childNodes.length >= r.endOffset){ |
---|
| 79 | var nCont = r.endContainer.childNodes[r.endOffset - 1]; |
---|
| 80 | if(nCont.nodeType == 3){ |
---|
| 81 | r.setEnd(nCont, nCont.length - 1); |
---|
| 82 | }else if(nCont.childNodes.length){ |
---|
| 83 | r.setEnd(nCont, nCont.childNodes.length); |
---|
| 84 | rollRange(r); |
---|
| 85 | return; |
---|
| 86 | }else{ |
---|
| 87 | r.setEndBefore(nCont); |
---|
| 88 | rollRange(r); |
---|
| 89 | return; |
---|
| 90 | } |
---|
| 91 | }else{ |
---|
| 92 | r.setEndBefore(r.endContainer); |
---|
| 93 | rollRange(r); |
---|
| 94 | return; |
---|
| 95 | } |
---|
| 96 | }; |
---|
| 97 | var createIFrameEllipsis = function(/* Node */ n){ |
---|
| 98 | // summary: |
---|
| 99 | // Given a node, it creates an iframe and and ellipsis div and |
---|
| 100 | // sets up the connections so that they will work correctly. |
---|
| 101 | // This function is used when createXULEllipsis is not able |
---|
| 102 | // to be used (because there is markup within the node) - it's |
---|
| 103 | // a bit slower, but does the trick |
---|
| 104 | var c = create("div", {className: "dojoxEllipsisContainer"}); |
---|
| 105 | var e = create("div", {className: "dojoxEllipsisShown", style: {display: "none"}}); |
---|
| 106 | n.parentNode.replaceChild(c, n); |
---|
| 107 | c.appendChild(n); |
---|
| 108 | c.appendChild(e); |
---|
| 109 | var i = iFrame.cloneNode(true); |
---|
| 110 | var ns = n.style; |
---|
| 111 | var es = e.style; |
---|
| 112 | var ranges; |
---|
| 113 | var resizeNode = function(){ |
---|
| 114 | ns.display = ""; |
---|
| 115 | es.display = "none"; |
---|
| 116 | if(n.scrollWidth <= n.offsetWidth){ return; } |
---|
| 117 | var r = dd.createRange(); |
---|
| 118 | r.selectNodeContents(n); |
---|
| 119 | ns.display = "none"; |
---|
| 120 | es.display = ""; |
---|
| 121 | var done = false; |
---|
| 122 | do{ |
---|
| 123 | var numRolls = 1; |
---|
| 124 | dp(r.cloneContents(), e, "only"); |
---|
| 125 | var sw = e.scrollWidth, ow = e.offsetWidth; |
---|
| 126 | done = (sw <= ow); |
---|
| 127 | var pct = (1 - ((ow * 1) / sw)); |
---|
| 128 | if(pct > 0){ |
---|
| 129 | numRolls = Math.max(Math.round(e.textContent.length * pct) - 1, 1); |
---|
| 130 | } |
---|
| 131 | rollRange(r, numRolls); |
---|
| 132 | }while(!r.collapsed && !done); |
---|
| 133 | }; |
---|
| 134 | i.onload = function(){ |
---|
| 135 | i.contentWindow.onresize = resizeNode; |
---|
| 136 | resizeNode(); |
---|
| 137 | }; |
---|
| 138 | c.appendChild(i); |
---|
| 139 | }; |
---|
| 140 | |
---|
| 141 | // Function for updating the ellipsis |
---|
| 142 | var hc = d.hasClass; |
---|
| 143 | var doc = d.doc; |
---|
| 144 | var s, fn, opt; |
---|
| 145 | if(doc.querySelectorAll){ |
---|
| 146 | s = doc; |
---|
| 147 | fn = "querySelectorAll"; |
---|
| 148 | opt = ".dojoxEllipsis"; |
---|
| 149 | }else if(doc.getElementsByClassName){ |
---|
| 150 | s = doc; |
---|
| 151 | fn = "getElementsByClassName"; |
---|
| 152 | opt = "dojoxEllipsis"; |
---|
| 153 | }else{ |
---|
| 154 | s = d; |
---|
| 155 | fn = "query"; |
---|
| 156 | opt = ".dojoxEllipsis"; |
---|
| 157 | } |
---|
| 158 | fx = function(){ |
---|
| 159 | d.forEach(s[fn].apply(s, [opt]), function(n){ |
---|
| 160 | if(!n || n._djx_ellipsis_done){ return; } |
---|
| 161 | n._djx_ellipsis_done = true; |
---|
| 162 | if(createXULEllipsis && n.textContent == n.innerHTML && !hc(n, "dojoxEllipsisSelectable")){ |
---|
| 163 | // We can do the faster XUL version, instead of calculating |
---|
| 164 | createXULEllipsis(n); |
---|
| 165 | }else{ |
---|
| 166 | createIFrameEllipsis(n); |
---|
| 167 | } |
---|
| 168 | }); |
---|
| 169 | }; |
---|
| 170 | |
---|
| 171 | d.addOnLoad(function(){ |
---|
| 172 | // Apply our initial stuff |
---|
| 173 | var t = null; |
---|
| 174 | var c = null; |
---|
| 175 | var connFx = function(){ |
---|
| 176 | if(c){ |
---|
| 177 | // disconnect us - so we don't fire anymore |
---|
| 178 | d.disconnect(c); |
---|
| 179 | c = null; |
---|
| 180 | } |
---|
| 181 | if(t){ clearTimeout(t); } |
---|
| 182 | t = setTimeout(function(){ |
---|
| 183 | t = null; |
---|
| 184 | fx(); |
---|
| 185 | // Connect to the modified function so that we can catch |
---|
| 186 | // our next change |
---|
| 187 | c = d.connect(d.body(), "DOMSubtreeModified", connFx); |
---|
| 188 | }, delay); |
---|
| 189 | }; |
---|
| 190 | connFx(); |
---|
| 191 | }); |
---|
| 192 | } |
---|
| 193 | }); |
---|