diff --git a/packages/liveui/domutils.js b/packages/liveui/domutils.js deleted file mode 100644 index 16cc1479f4..0000000000 --- a/packages/liveui/domutils.js +++ /dev/null @@ -1,150 +0,0 @@ -Meteor.ui = Meteor.ui || {}; - -// returns true if element a properly contains element b -Meteor.ui._elementContains = function(a, b) { - // Note: Some special-casing would be required to implement this method - // where a and b aren't necessarily elements, e.g. b is a text node, - // because contains() doesn't seem to work reliably on some browsers - // including IE. - if (a.nodeType !== 1 || b.nodeType !== 1) { - return false; // a and b are not both elements - } - if (a.compareDocumentPosition) { - return a.compareDocumentPosition(b) & 0x10; - } else { - // Should be only old IE and maybe other old browsers here. - // Modern Safari has both methods but seems to get contains() wrong. - return a !== b && a.contains(b); - } -}; - -// Returns an array of element nodes matching `selector`, where -// the selector is interpreted as rooted at `contextNode`. -// This means that all nodes that participate in the selector -// must be descendents of contextNode. -// -// jQuery dependency to eventually replace with querySelectorAll -// backed up by Sizzle in Old IE. Note that querySelectorAll doesn't -// provide the needed semantics for scoping the selector to contextNode; -// for example, myDiv.querySelectorAll("body *") will match all of myDiv's -// descendents, while $(myDiv).find("body *") won't match any. The latter -// behavior is definitely better, and the way to implement it is to temporarily -// assign an ID to contextNode (if it doesn't have one). -Meteor.ui._findElement = function(contextNode, selector) { - if (contextNode.nodeType === 11 /* DocumentFragment */) { - // Sizzle doesn't work on a DocumentFragment, but it does work on - // a descendent of one. - var frag = contextNode; - var container = DomUtils.fragmentToContainer(frag); - var results = $(container).find(selector); - // put nodes back into frag - while (container.firstChild) - frag.appendChild(container.firstChild); - return results; - } else { - return $(contextNode).find(selector); - } -}; - -// Returns 0 if the nodes are the same or either one contains the other; -// otherwise, 1 if a comes before b, or else -1 if b comes before a in -// document order. -// Requires: `a` and `b` are element nodes in the same document tree. -Meteor.ui._elementOrder = function(a, b) { - // See http://ejohn.org/blog/comparing-document-position/ - if (a === b) - return 0; - if (a.compareDocumentPosition) { - var n = a.compareDocumentPosition(b); - return ((n & 0x18) ? 0 : ((n & 0x4) ? 1 : -1)); - } else { - // Only old IE is known to not have compareDocumentPosition (though Safari - // originally lacked it). Thankfully, IE gives us a way of comparing elements - // via the "sourceIndex" property. - if (a.contains(b) || b.contains(a)) - return 0; - return (a.sourceIndex < b.sourceIndex ? 1 : -1); - } -}; - -// Like `findElement` but searches the nodes from `start` to `end` -// inclusive. `start` and `end` must be siblings, and they participate -// in the search (they can be used to match selector components, and -// they can appear in the returned results). It's as if the parent of -// `start` and `end` serves as contextNode, but matches from children -// that aren't between `start` and `end` (inclusive) are ignored. -// -// If `selector` involves sibling selectors, child index selectors, or -// the like, the results are undefined. -Meteor.ui._findElementInRange = function(start, end, selector) { - end = (end || start); - - var container = start.parentNode; - if (! container) { - if (start === end && (start.nodeType === 9 /* Document */ || - start.nodeType === 11 /* DocumentFragment */)) - return Meteor.ui._findElement(start, selector); - throw new Error("Can't find element in range on detached node"); - } - if (end.parentNode !== container) - throw new Error("Bad range"); - - // narrow the range to exclude top-level non-elements (which can't be - // or contain matches) by moving the `start` pointer forward and `end` - // backward. - while (start !== end && start.nodeType !== 1) - start = start.nextSibling; - while (start !== end && end.nodeType !== 1) - end = end.previousSibling; - if (start.nodeType !== 1) - return []; // no top-level elements! start === end and it's not an element - - // resultsPlus includes matches that are contained by the range's - // parent, but are outside of start..end, i.e. are descended from - // (or are) a different sibling. - var resultsPlus = Meteor.ui._findElement(container, selector); - - // Filter the list of nodes to remove nodes that occur before start - // or after end. - return _.reject(resultsPlus, function(n) { - // reject node if (n,start) are in order or (end,n) are in order - return (Meteor.ui._elementOrder(n, start) > 0) || - (Meteor.ui._elementOrder(end, n) > 0); - }); -}; - -// Check whether a node is contained in the document. -Meteor.ui._isNodeOnscreen = function (node) { - // Deal with all cases where node is not an element - // node descending from the body first... - if (node === document) - return true; - - if (node.nodeType !== 1 /* Element */) - node = node.parentNode; - if (! (node && node.nodeType === 1)) - return false; - if (node === document.body) - return true; - - return Meteor.ui._elementContains(document.body, node); -}; - -// Wraps the contents of `frag`, a DocumentFragment, if necessary -// to insert the fragment into `container`, a DOM element. -// For example, if `frag` has TR nodes as children and container -// is a TABLE, the children of `frag` will be wrapped with a -// TBODY in place to work around IE quirks. -Meteor.ui._wrapFragmentForContainer = function(frag, container) { - if (container && container.nodeName === "TABLE" && - _.any(frag.childNodes, - function(n) { return n.nodeName === "TR"; })) { - // Avoid putting a TR directly in a TABLE without an - // intervening TBODY, because it doesn't work in IE. We do - // the same thing on all browsers for ease of testing - // and debugging. - var tbody = document.createElement("TBODY"); - tbody.appendChild(frag); - frag.appendChild(tbody); - } -}; diff --git a/packages/liveui/innerhtml.js b/packages/liveui/innerhtml.js deleted file mode 100644 index 62289ea77e..0000000000 --- a/packages/liveui/innerhtml.js +++ /dev/null @@ -1,160 +0,0 @@ -Meteor.ui = Meteor.ui || {}; - -// Define Meteor.ui._htmlToFragment and Meteor.ui._fragmentToHtml. -// Adapted from jquery's html() and "clean" routines. -// -// _fragmentToHtml is only used in test code and could be moved -// into a non-core package. -_.extend(Meteor.ui, (function() { - - // --- One-time set-up: - - var testDiv = document.createElement("div"); - testDiv.innerHTML = "
"; - - // Tests that, if true, indicate browser quirks present. - var quirks = { - // IE loses initial whitespace when setting innerHTML. - leadingWhitespaceKilled: (testDiv.firstChild.nodeType !== 3), - - // IE may insert an empty tbody tag in a table. - tbodyInsertion: testDiv.getElementsByTagName("tbody").length > 0, - - // IE loses some tags in some environments (requiring extra wrapper). - tagsLost: testDiv.getElementsByTagName("link").length === 0 - }; - - // Set up map of wrappers for different nodes. - var wrapMap = { - option: [ 1, "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }; - _.extend(wrapMap, { - optgroup: wrapMap.option, - tbody: wrapMap.thead, - tfoot: wrapMap.thead, - colgroup: wrapMap.thead, - caption: wrapMap.thead, - th: wrapMap.td - }); - if (quirks.tagsLost) { - // trick from jquery. initial text is ignored when we take lastChild. - wrapMap._default = [ 1, "div
", "
" ]; - } - - var rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /"); - // Use first tag to determine wrapping needed. - var firstTagMatch = rtagName.exec(html); - var firstTag = (firstTagMatch ? firstTagMatch[1].toLowerCase() : ""); - var wrapData = wrapMap[firstTag] || wrapMap._default; - - var container = doc.createElement("div"); - // insert wrapped HTML into a DIV - container.innerHTML = wrapData[1] + html + wrapData[2]; - // set "container" to inner node of wrapper - var unwraps = wrapData[0]; - while (unwraps--) { - container = container.lastChild; - } - - if (quirks.tbodyInsertion && ! rtbody.test(html)) { - // Any tbody we find was created by the browser. - var tbodies = container.getElementsByTagName("tbody"); - _.each(tbodies, function(n) { - if (! n.firstChild) { - // spurious empty tbody - n.parentNode.removeChild(n); - } - }); - } - - if (quirks.leadingWhitespaceKilled) { - var wsMatch = rleadingWhitespace.exec(html); - if (wsMatch) { - container.insertBefore(doc.createTextNode(wsMatch[0]), - container.firstChild); - } - } - - // Reparent children of container to frag. - while (container.firstChild) - frag.appendChild(container.firstChild); - } - - return frag; - }, - // Put children of frag into a suitable DOM node, e.g. a DIV - // or a TABLE as appropriate, for the purpose of using - // innerHTML or a Sizzle/jQuery selectors. - _fragmentToContainer: function(frag) { - var doc = document; // node factory - - var firstElement = frag.firstChild; - while (firstElement && firstElement.nodeType !== 1) { - firstElement = firstElement.nextSibling; - } - - var container = doc.createElement("div"); - - if (! firstElement) { - // no tags! - container.appendChild(frag); - } else { - var firstTag = firstElement.nodeName; - var wrapData = wrapMap[firstTag] || wrapMap._default; - - container.innerHTML = wrapData[1] + wrapData[2]; - var unwraps = wrapData[0]; - while (unwraps--) { - container = container.lastChild; - } - - container.appendChild(frag); - } - - return container; - }, - _fragmentToHtml: function(frag) { - frag = frag.cloneNode(true); // deep copy, don't touch original! - - return Meteor.ui._fragmentToContainer(frag).innerHTML; - }, - _rangeToHtml: function(liverange) { - var frag = document.createDocumentFragment(); - for(var n = liverange.firstNode(), - after = liverange.lastNode().nextSibling; - n && n !== after; - n = n.nextSibling) - frag.appendChild(n.cloneNode(true)); // deep copy - return Meteor.ui._fragmentToHtml(frag); - } - }; -})()); - diff --git a/packages/liveui/package.js b/packages/liveui/package.js index a02b2cf6f9..2ba701351d 100644 --- a/packages/liveui/package.js +++ b/packages/liveui/package.js @@ -13,11 +13,10 @@ Package.on_use(function (api) { // you still want the event object normalization that jquery provides?) api.use('jquery'); - api.add_files(['domutils.js'], 'client'); api.add_files(['liveevents_w3c.js', 'liveevents_now3c.js'], 'client'); api.add_files(['liveevents.js'], 'client'); api.add_files(['livedocument.js'], 'client'); - api.add_files(['liveui.js', 'innerhtml.js', 'patcher.js'], + api.add_files(['liveui.js', 'patcher.js'], 'client'); });