mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Clean up DomRange, phase 1
- Get rid of DomRange "host objects" (too confusing) - start to use `r instanceof DomRange` instead of `'dom' in r` Ported domrange tests; all tests pass
This commit is contained in:
@@ -172,7 +172,7 @@ html_scanner = {
|
||||
});
|
||||
|
||||
// We may be one of many `<body>` tags.
|
||||
results.js += "\nUI.body.contentParts.push(UI.Component.extend({render: " + renderFuncCode + "}));\nMeteor.startup(function () { if (! UI.body.INSTANTIATED) { UI.body.INSTANTIATED = true; UI.materialize(UI.body, document.body); } });\n";
|
||||
results.js += "\nUI.body.contentParts.push(UI.Component.extend({render: " + renderFuncCode + "}));\nMeteor.startup(function () { if (! UI.body.INSTANTIATED) { UI.body.INSTANTIATED = true; UI.DomRange.insert(UI.render(UI.body).dom, document.body); } });\n";
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.scanner) {
|
||||
|
||||
@@ -355,18 +355,5 @@ UI.Component.notifyParented = function () {
|
||||
}
|
||||
};
|
||||
|
||||
// XXX we don't really want this to be a user-visible callback,
|
||||
// it's just a particular signal we need from DomRange.
|
||||
UI.Component.removed = function () {
|
||||
var self = this;
|
||||
self.isDestroyed = true;
|
||||
if (self.destroyed) {
|
||||
Deps.nonreactive(function () {
|
||||
updateTemplateInstance(self);
|
||||
self.destroyed.call(self.templateInstance);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// past compat
|
||||
UI.Component.preserve = function () {};
|
||||
|
||||
@@ -114,15 +114,15 @@ var rangeParented = function (range) {
|
||||
});
|
||||
}
|
||||
|
||||
if (range.component.notifyParented)
|
||||
if (range.component && range.component.notifyParented)
|
||||
range.component.notifyParented();
|
||||
|
||||
// recurse on member ranges
|
||||
var members = range.members;
|
||||
for (var k in members) {
|
||||
var mem = members[k];
|
||||
if ('dom' in mem)
|
||||
rangeParented(mem.dom);
|
||||
if (mem instanceof DomRange)
|
||||
rangeParented(mem);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -137,8 +137,8 @@ var rangeRemoved = function (range) {
|
||||
// XXX clean up events in $_uievents
|
||||
|
||||
// notify component of removal
|
||||
if (range.component.removed)
|
||||
range.component.removed();
|
||||
if (range.removed)
|
||||
range.removed();
|
||||
|
||||
membersRemoved(range);
|
||||
}
|
||||
@@ -148,7 +148,7 @@ var nodeRemoved = function (node, viaBackend) {
|
||||
if (node.nodeType === 1) { // ELEMENT
|
||||
var comps = DomRange.getComponents(node);
|
||||
for (var i = 0, N = comps.length; i < N; i++)
|
||||
rangeRemoved(comps[i].dom);
|
||||
rangeRemoved(comps[i]);
|
||||
|
||||
if (! viaBackend)
|
||||
DomBackend.removeElement(node);
|
||||
@@ -159,8 +159,8 @@ var membersRemoved = function (range) {
|
||||
var members = range.members;
|
||||
for (var k in members) {
|
||||
var mem = members[k];
|
||||
if ('dom' in mem)
|
||||
rangeRemoved(mem.dom);
|
||||
if (mem instanceof DomRange)
|
||||
rangeRemoved(mem);
|
||||
else
|
||||
nodeRemoved(mem);
|
||||
}
|
||||
@@ -168,34 +168,16 @@ var membersRemoved = function (range) {
|
||||
|
||||
var nextGuid = 1;
|
||||
|
||||
var DomRange = function (component) {
|
||||
// This code supports IE 8 if `createTextNode` is changed
|
||||
// to `createComment`. What we really should do is:
|
||||
// - use comments in IE 8
|
||||
// - use TextNodes in all other browsers
|
||||
// - keep a list of all DomRanges to avoid IE 9+ GC of
|
||||
// TextNodes; this will probably help DomRange removal
|
||||
// detection too.
|
||||
var DomRange = function () {
|
||||
var start = createMarkerNode();
|
||||
var end = createMarkerNode();
|
||||
var fragment = DomBackend.newFragment([start, end]);
|
||||
fragment.$_uiIsOffscreen = true;
|
||||
|
||||
if (component) {
|
||||
this.component = component;
|
||||
component.dom = this;
|
||||
// must NOT set `this.dom` to anything (even `null`)
|
||||
// in this case.
|
||||
} else {
|
||||
// self-host
|
||||
this.component = this;
|
||||
this.dom = this;
|
||||
}
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
start.$ui = this.component;
|
||||
end.$ui = this.component;
|
||||
start.$ui = this;
|
||||
end.$ui = this;
|
||||
|
||||
this.members = {};
|
||||
this.nextMemberId = 1;
|
||||
@@ -296,9 +278,9 @@ _extend(DomRange.prototype, {
|
||||
var members = this.members;
|
||||
if (members.hasOwnProperty(id)) {
|
||||
var oldMember = members[id];
|
||||
if ('dom' in oldMember) {
|
||||
if (oldMember instanceof DomRange) {
|
||||
// range, does it still exist?
|
||||
var oldRange = oldMember.dom;
|
||||
var oldRange = oldMember;
|
||||
if (oldRange.start.parentNode !== parentNode) {
|
||||
delete members[id];
|
||||
oldRange.owner = null;
|
||||
@@ -318,12 +300,10 @@ _extend(DomRange.prototype, {
|
||||
}
|
||||
}
|
||||
|
||||
if ('dom' in newMember) {
|
||||
if (! newMember.dom)
|
||||
throw new Error("Component not built");
|
||||
if (newMember instanceof DomRange) {
|
||||
// Range
|
||||
var range = newMember.dom;
|
||||
range.owner = this.component;
|
||||
var range = newMember;
|
||||
range.owner = this;
|
||||
var nodes = range.getNodes();
|
||||
|
||||
if (tbodyFixNeeded(nodes, parentNode))
|
||||
@@ -345,7 +325,7 @@ _extend(DomRange.prototype, {
|
||||
// can't attach `$ui` to a TextNode in IE 8, so
|
||||
// don't bother on any browser.
|
||||
if (node.nodeType !== 3)
|
||||
node.$ui = this.component;
|
||||
node.$ui = this;
|
||||
|
||||
if (tbodyFixNeeded(node, parentNode))
|
||||
// may cause a refresh(); important that the
|
||||
@@ -384,14 +364,14 @@ _extend(DomRange.prototype, {
|
||||
if (! parentNode)
|
||||
return;
|
||||
|
||||
if ('dom' in member) {
|
||||
if (member instanceof DomRange) {
|
||||
// Range
|
||||
var range = member.dom;
|
||||
var range = member;
|
||||
range.owner = null;
|
||||
// Don't mind if range (specifically its start
|
||||
// marker) has been removed already.
|
||||
if (range.start.parentNode === parentNode)
|
||||
member.dom.remove();
|
||||
member.remove();
|
||||
} else {
|
||||
// Node
|
||||
var node = member;
|
||||
@@ -418,9 +398,9 @@ _extend(DomRange.prototype, {
|
||||
if (! parentNode)
|
||||
return;
|
||||
|
||||
if ('dom' in member) {
|
||||
if (member instanceof DomRange) {
|
||||
// Range
|
||||
var range = member.dom;
|
||||
var range = member;
|
||||
// Don't mind if range (specifically its start marker)
|
||||
// has been removed already.
|
||||
if (range.start.parentNode === parentNode) {
|
||||
@@ -458,9 +438,9 @@ _extend(DomRange.prototype, {
|
||||
for (var k in members) {
|
||||
// mem is a component (hosting a Range) or a Node
|
||||
var mem = members[k];
|
||||
if ('dom' in mem) {
|
||||
if (mem instanceof DomRange) {
|
||||
// Range
|
||||
var range = mem.dom;
|
||||
var range = mem;
|
||||
if (range.start.parentNode === parentNode) {
|
||||
rangeFunc && rangeFunc(range); // still there
|
||||
} else {
|
||||
@@ -517,6 +497,7 @@ _extend(DomRange.prototype, {
|
||||
// see `getInsertionPoint`. Adding multiple members
|
||||
// at once using `add(array)` is faster.
|
||||
refresh: function () {
|
||||
|
||||
var parentNode = this.parentNode();
|
||||
if (! parentNode)
|
||||
return;
|
||||
@@ -579,14 +560,13 @@ _extend(DomRange.prototype, {
|
||||
|
||||
var nodeOwner;
|
||||
if (node.$ui &&
|
||||
(nodeOwner = node.$ui.dom) &&
|
||||
(nodeOwner = node.$ui) &&
|
||||
((nodeOwner === this &&
|
||||
node !== this.start &&
|
||||
node !== this.end &&
|
||||
isSignificantNode(node)) ||
|
||||
(nodeOwner !== this &&
|
||||
nodeOwner.owner &&
|
||||
nodeOwner.owner.dom === this &&
|
||||
nodeOwner.owner === this &&
|
||||
nodeOwner.start === node))) {
|
||||
// found a member range or node
|
||||
// (excluding "insignificant" empty text nodes,
|
||||
@@ -602,10 +582,10 @@ _extend(DomRange.prototype, {
|
||||
// can't attach `$ui` to a TextNode in IE 8, so
|
||||
// don't bother on any browser.
|
||||
if (n.nodeType !== 3)
|
||||
n.$ui = this.component;
|
||||
n.$ui = this;
|
||||
}
|
||||
}
|
||||
if (node.$ui.dom === this) {
|
||||
if (node.$ui === this) {
|
||||
// Node
|
||||
firstNode = (firstNode || node);
|
||||
lastNode = node;
|
||||
@@ -614,7 +594,7 @@ _extend(DomRange.prototype, {
|
||||
// skip it and include its nodes in
|
||||
// firstNode/lastNode.
|
||||
firstNode = (firstNode || node);
|
||||
node = node.$ui.dom.end;
|
||||
node = node.$ui.end;
|
||||
lastNode = node;
|
||||
}
|
||||
}
|
||||
@@ -626,12 +606,12 @@ _extend(DomRange.prototype, {
|
||||
// nodes as well.
|
||||
for (var n;
|
||||
(n = firstNode.previousSibling) &&
|
||||
(n.$ui && n.$ui.dom === this ||
|
||||
(n.$ui && n.$ui === this ||
|
||||
_contains(textNodes, n));)
|
||||
firstNode = n;
|
||||
for (var n;
|
||||
(n = lastNode.nextSibling) &&
|
||||
(n.$ui && n.$ui.dom === this ||
|
||||
(n.$ui && n.$ui === this ||
|
||||
_contains(textNodes, n));)
|
||||
lastNode = n;
|
||||
// adjust our start/end pointers
|
||||
@@ -665,9 +645,9 @@ _extend(DomRange.prototype, {
|
||||
beforeId = ' ' + beforeId;
|
||||
var mem = members[beforeId];
|
||||
|
||||
if ('dom' in mem) {
|
||||
if (mem instanceof DomRange) {
|
||||
// Range
|
||||
var range = mem.dom;
|
||||
var range = mem;
|
||||
if (range.start.parentNode === parentNode) {
|
||||
// still there
|
||||
range.refresh();
|
||||
@@ -723,25 +703,22 @@ DomRange.refresh = function (element) {
|
||||
var comps = DomRange.getComponents(element);
|
||||
|
||||
for (var i = 0, N = comps.length; i < N; i++)
|
||||
comps[i].dom.refresh();
|
||||
comps[i].refresh();
|
||||
};
|
||||
|
||||
DomRange.getComponents = function (element) {
|
||||
var topLevelComps = [];
|
||||
for (var n = element.firstChild;
|
||||
n; n = n.nextSibling) {
|
||||
if (n.$ui && n === n.$ui.dom.start &&
|
||||
! n.$ui.dom.owner)
|
||||
if (n.$ui && n === n.$ui.start &&
|
||||
! n.$ui.owner)
|
||||
topLevelComps.push(n.$ui);
|
||||
}
|
||||
return topLevelComps;
|
||||
};
|
||||
|
||||
// `parentNode` must be an ELEMENT, not a fragment
|
||||
DomRange.insert = function (component, parentNode, nextNode) {
|
||||
var range = component.dom;
|
||||
if (! range)
|
||||
throw new Error("Expected a component with a DomRange");
|
||||
DomRange.insert = function (range, parentNode, nextNode) {
|
||||
var nodes = range.getNodes();
|
||||
if (tbodyFixNeeded(nodes, parentNode))
|
||||
parentNode = makeOrFindTbody(parentNode, nextNode);
|
||||
@@ -801,7 +778,7 @@ var makeOrFindTbody = function (parent, next) {
|
||||
|
||||
var moveWithOwnersIntoTbody = function (range) {
|
||||
while (range.owner)
|
||||
range = range.owner.dom;
|
||||
range = range.owner;
|
||||
|
||||
var nodes = range.getNodes(); // causes refresh
|
||||
var tbody = makeOrFindTbody(range.parentNode(),
|
||||
@@ -826,9 +803,9 @@ DomRange.prototype.contains = function (compOrNode) {
|
||||
return false;
|
||||
|
||||
var range;
|
||||
if ('dom' in compOrNode) {
|
||||
if (compOrNode instanceof DomRange) {
|
||||
// Component
|
||||
range = compOrNode.dom;
|
||||
range = compOrNode;
|
||||
var pn = range.parentNode();
|
||||
if (! pn)
|
||||
return false;
|
||||
@@ -849,14 +826,14 @@ DomRange.prototype.contains = function (compOrNode) {
|
||||
while (node.parentNode !== parentNode)
|
||||
node = node.parentNode;
|
||||
|
||||
range = node.$ui && node.$ui.dom;
|
||||
range = node.$ui;
|
||||
}
|
||||
|
||||
// Now see if `range` is truthy and either `this`
|
||||
// or an immediate subrange
|
||||
|
||||
while (range && range !== this)
|
||||
range = range.owner && range.owner.dom;
|
||||
range = range.owner;
|
||||
|
||||
return range === this;
|
||||
};
|
||||
@@ -960,7 +937,7 @@ var HandlerRec = function (elem, type, selector, handler, $ui) {
|
||||
if ((! h.selector) && evt.currentTarget !== evt.target)
|
||||
// no selector means only fire on target
|
||||
return;
|
||||
if (! h.$ui.dom.contains(evt.currentTarget))
|
||||
if (! h.$ui.contains(evt.currentTarget))
|
||||
return;
|
||||
return h.handler.call(h.$ui, evt);
|
||||
};
|
||||
@@ -1075,17 +1052,16 @@ DomRange.prototype.on = function (events, selector, handler) {
|
||||
}
|
||||
var handlerList = info.handlers;
|
||||
var handlerRec = new HandlerRec(
|
||||
parentNode, type, selector, handler, this.component);
|
||||
parentNode, type, selector, handler, this);
|
||||
handlerRec.bind();
|
||||
handlerList.push(handlerRec);
|
||||
// move handlers of enclosing ranges to end
|
||||
for (var r = (this.owner && this.owner.dom);
|
||||
r; r = (r.owner && r.owner.dom)) {
|
||||
for (var r = this.owner; r; r = r.owner) {
|
||||
// r is an enclosing DomRange
|
||||
for (var j = 0, Nj = handlerList.length;
|
||||
j < Nj; j++) {
|
||||
var h = handlerList[j];
|
||||
if (h.$ui && h.$ui.dom === r) {
|
||||
if (h.$ui === r) {
|
||||
h.unbind();
|
||||
h.bind();
|
||||
handlerList.splice(j, 1); // remove handlerList[j]
|
||||
|
||||
@@ -5,23 +5,23 @@ var parseHTML = UI.DomBackend.parseHTML;
|
||||
// fake component; DomRange host
|
||||
var Comp = function (which) {
|
||||
this.which = which;
|
||||
|
||||
new DomRange(this);
|
||||
this.dom = new DomRange;
|
||||
this.dom.component = this;
|
||||
};
|
||||
|
||||
var isStartMarker = function (n) {
|
||||
return (n.$ui && n === n.$ui.dom.start);
|
||||
return (n.$ui && n === n.$ui.start);
|
||||
};
|
||||
|
||||
var isEndMarker = function (n) {
|
||||
return (n.$ui && n === n.$ui.dom.end);
|
||||
return (n.$ui && n === n.$ui.end);
|
||||
};
|
||||
|
||||
var inDocument = function (range, func) {
|
||||
var onscreen = document.createElement("DIV");
|
||||
onscreen.style.display = 'none';
|
||||
document.body.appendChild(onscreen);
|
||||
DomRange.insert(range.component, onscreen);
|
||||
DomRange.insert(range, onscreen);
|
||||
try {
|
||||
func(range);
|
||||
} finally {
|
||||
@@ -72,7 +72,6 @@ Tinytest.add("ui - DomRange - basic", function (test) {
|
||||
test.equal(div.previousSibling, rStart);
|
||||
test.equal(div.nextSibling, rEnd);
|
||||
test.equal(div.$ui, r);
|
||||
test.equal(div.$ui.dom, r);
|
||||
|
||||
// add a subrange
|
||||
var s = new DomRange;
|
||||
@@ -143,8 +142,8 @@ Tinytest.add("ui - DomRange - shuffling", function (test) {
|
||||
else
|
||||
str += '-';
|
||||
} else {
|
||||
if (n.$ui.which)
|
||||
str += n.$ui.which;
|
||||
if (n.$ui.component && n.$ui.component.which)
|
||||
str += n.$ui.component.which;
|
||||
else
|
||||
str += (n.nodeName || '?');
|
||||
}
|
||||
@@ -170,12 +169,12 @@ Tinytest.add("ui - DomRange - shuffling", function (test) {
|
||||
var X = new Comp('X');
|
||||
var Y = new Comp('Y');
|
||||
var Z = new Comp('Z');
|
||||
r.add('X', X, 'I');
|
||||
r.add('X', X.dom, 'I');
|
||||
X.dom.add(document.createElement("SPAN"));
|
||||
Y.dom.add(document.createElement("SPAN"));
|
||||
Z.dom.add(document.createElement("SPAN"));
|
||||
r.add('Y', Y, 'U');
|
||||
r.add('Z', Z);
|
||||
r.add('Y', Y.dom, 'U');
|
||||
r.add('Z', Z.dom);
|
||||
|
||||
test.equal(spellDom(), '(B(X)I(Y)U(Z))');
|
||||
|
||||
@@ -190,21 +189,22 @@ Tinytest.add("ui - DomRange - shuffling", function (test) {
|
||||
r.moveBefore('U', 'Y');
|
||||
test.equal(spellDom(), '((X)BAAIU(Y)(Z))');
|
||||
|
||||
|
||||
r.moveBefore('Z', 'X');
|
||||
r.moveBefore('Y', 'X');
|
||||
test.equal(spellDom(), '((Z)(Y)(X)BAAIU)');
|
||||
|
||||
test.equal(r.get('X'), X);
|
||||
test.equal(r.get('Y'), Y);
|
||||
test.equal(r.get('Z'), Z);
|
||||
test.equal(r.get('B'), B);
|
||||
test.equal(r.get('I'), I);
|
||||
test.equal(r.get('U'), U);
|
||||
test.isTrue(r.get('X') === X.dom);
|
||||
test.isTrue(r.get('Y') === Y.dom);
|
||||
test.isTrue(r.get('Z') === Z.dom);
|
||||
test.isTrue(r.get('B') === B);
|
||||
test.isTrue(r.get('I') === I);
|
||||
test.isTrue(r.get('U') === U);
|
||||
|
||||
test.isFalse(r.owner);
|
||||
test.equal(X.dom.owner, r);
|
||||
test.equal(Y.dom.owner, r);
|
||||
test.equal(Z.dom.owner, r);
|
||||
test.isTrue(X.dom.owner === r);
|
||||
test.isTrue(Y.dom.owner === r);
|
||||
test.isTrue(Z.dom.owner === r);
|
||||
|
||||
r.remove('Y');
|
||||
test.equal(spellDom(), '((Z)(X)BAAIU)');
|
||||
@@ -226,9 +226,9 @@ Tinytest.add("ui - DomRange - nested", function (test) {
|
||||
_.each(frag.childNodes, function (n) {
|
||||
var ui = n.$ui;
|
||||
if (isStartMarker(n))
|
||||
str += (ui.which ? ui.which : '(');
|
||||
str += (ui.component ? ui.component.which : '(');
|
||||
else if (isEndMarker(n))
|
||||
str += (ui.which ? ui.which.toLowerCase() : ')');
|
||||
str += (ui.component ? ui.component.which.toLowerCase() : ')');
|
||||
else
|
||||
str += '?';
|
||||
});
|
||||
@@ -240,16 +240,16 @@ Tinytest.add("ui - DomRange - nested", function (test) {
|
||||
var A,B,C,D,E,F;
|
||||
|
||||
test.equal(spellDom(), '()');
|
||||
r.add(A = new Comp('A'));
|
||||
r.add((A = new Comp('A')).dom);
|
||||
test.equal(spellDom(), '(Aa)');
|
||||
r.add('B', B = new Comp('B'));
|
||||
r.add('C', C = new Comp('C'), 'B');
|
||||
r.add('B', (B = new Comp('B')).dom);
|
||||
r.add('C', (C = new Comp('C')).dom, 'B');
|
||||
test.equal(spellDom(), '(AaCcBb)');
|
||||
|
||||
r.get('B').dom.add('D', D = new Comp('D'));
|
||||
D.dom.add('E', new Comp('E'));
|
||||
r.get('B').add('D', (D = new Comp('D')).dom);
|
||||
D.dom.add('E', (E = new Comp('E')).dom);
|
||||
test.equal(spellDom(), '(AaCcBDEedb)');
|
||||
B.dom.add('F', F = new Comp('F'));
|
||||
B.dom.add('F', (F = new Comp('F')).dom);
|
||||
test.equal(spellDom(), '(AaCcBDEedFfb)');
|
||||
|
||||
r.moveBefore('B', 'C');
|
||||
@@ -305,7 +305,7 @@ Tinytest.add("ui - DomRange - external moves", function (test) {
|
||||
de.dom.add('Z', Z);
|
||||
de.dom.add(wsp());
|
||||
cf.dom.add(wsp());
|
||||
cf.dom.add('de', de);
|
||||
cf.dom.add('de', de.dom);
|
||||
cf.dom.add(wsp());
|
||||
var gl = new Comp('gl');
|
||||
var hk = new Comp('hk');
|
||||
@@ -316,12 +316,12 @@ Tinytest.add("ui - DomRange - external moves", function (test) {
|
||||
// i-W-j
|
||||
test.equal(ij.dom.getNodes().length, 5);
|
||||
gl.dom.add(wsp());
|
||||
gl.dom.add('hk', hk);
|
||||
gl.dom.add('hk', hk.dom);
|
||||
gl.dom.add(wsp());
|
||||
// g-hk-l
|
||||
test.equal(gl.dom.getNodes().length, 6);
|
||||
hk.dom.add(wsp());
|
||||
hk.dom.add('ij', ij);
|
||||
hk.dom.add('ij', ij.dom);
|
||||
hk.dom.add(wsp());
|
||||
// h-i-W-j-k
|
||||
test.equal(hk.dom.getNodes().length, 9);
|
||||
@@ -329,12 +329,12 @@ Tinytest.add("ui - DomRange - external moves", function (test) {
|
||||
test.equal(gl.dom.getNodes().length, 13);
|
||||
|
||||
var r = new DomRange;
|
||||
r.dom.add('ab', ab);
|
||||
r.dom.add(wsp());
|
||||
r.dom.add('cf', cf);
|
||||
r.dom.add(wsp());
|
||||
r.dom.add('gl', gl);
|
||||
r.dom.add('V', V);
|
||||
r.add('ab', ab.dom);
|
||||
r.add(wsp());
|
||||
r.add('cf', cf.dom);
|
||||
r.add(wsp());
|
||||
r.add('gl', gl.dom);
|
||||
r.add('V', V);
|
||||
|
||||
var spellDom = function () {
|
||||
var frag = r.parentNode();
|
||||
@@ -342,9 +342,9 @@ Tinytest.add("ui - DomRange - external moves", function (test) {
|
||||
_.each(frag.childNodes, function (n) {
|
||||
var ui = n.$ui;
|
||||
if (isStartMarker(n))
|
||||
str += (ui.which ? ui.which.charAt(0) : '(');
|
||||
str += (ui.component ? ui.component.which.charAt(0) : '(');
|
||||
else if (isEndMarker(n))
|
||||
str += (ui.which ? ui.which.charAt(1) : ')');
|
||||
str += (ui.component ? ui.component.which.charAt(1) : ')');
|
||||
else if (n.nodeType === 3)
|
||||
str += '-';
|
||||
else
|
||||
@@ -359,12 +359,12 @@ Tinytest.add("ui - DomRange - external moves", function (test) {
|
||||
test.equal(spellDom(),
|
||||
strip('(a-X-b - c-d-Y-Z-e-f - g-h-i-W-j-k-l V)'));
|
||||
|
||||
test.equal(ab.dom.owner, r);
|
||||
test.equal(cf.dom.owner, r);
|
||||
test.equal(de.dom.owner, cf);
|
||||
test.equal(gl.dom.owner, r);
|
||||
test.equal(hk.dom.owner, gl);
|
||||
test.equal(ij.dom.owner, hk);
|
||||
test.isTrue(ab.dom.owner === r);
|
||||
test.isTrue(cf.dom.owner === r);
|
||||
test.isTrue(de.dom.owner === cf.dom);
|
||||
test.isTrue(gl.dom.owner === r);
|
||||
test.isTrue(hk.dom.owner === gl.dom);
|
||||
test.isTrue(ij.dom.owner === hk.dom);
|
||||
|
||||
// all right, now let's mess around with these elements!
|
||||
|
||||
@@ -491,11 +491,13 @@ Tinytest.add("ui - DomRange - external moves", function (test) {
|
||||
|
||||
Tinytest.add("ui - DomRange - tables", function (test) {
|
||||
var range = function (x) {
|
||||
new DomRange(x);
|
||||
// create a range x.dom containing an element x.el,
|
||||
// inside that element, the range x.content.dom
|
||||
x.dom = new DomRange;
|
||||
if (x.el) {
|
||||
x.dom.add(x.el);
|
||||
if (x.content)
|
||||
DomRange.insert(x.content, x.el);
|
||||
DomRange.insert(x.content.dom, x.el);
|
||||
}
|
||||
return x;
|
||||
};
|
||||
@@ -525,7 +527,7 @@ Tinytest.add("ui - DomRange - tables", function (test) {
|
||||
test.equal(table.el.childNodes.length, 0);
|
||||
|
||||
table.content = range({});
|
||||
DomRange.insert(table.content, table.el);
|
||||
DomRange.insert(table.content.dom, table.el);
|
||||
// table has two children (start/end markers), no elements
|
||||
test.equal(table.el.childNodes.length, 2);
|
||||
test.notEqual(table.el.firstChild.nodeType, 1);
|
||||
@@ -545,11 +547,11 @@ Tinytest.add("ui - DomRange - tables", function (test) {
|
||||
test.equal(table.el.childNodes.length, 0);
|
||||
|
||||
table.content = range({});
|
||||
DomRange.insert(table.content, table.el);
|
||||
DomRange.insert(table.content.dom, table.el);
|
||||
var a1 = range({});
|
||||
var a2 = range({});
|
||||
a1.dom.add(a2);
|
||||
table.content.dom.add(a1);
|
||||
a1.dom.add(a2.dom);
|
||||
table.content.dom.add(a1.dom);
|
||||
// 6 marker nodes in table, no elements
|
||||
test.equal(table.el.childNodes.length, 6);
|
||||
test.equal($(table.el).find("*").length, 0);
|
||||
@@ -567,17 +569,17 @@ Tinytest.add("ui - DomRange - tables", function (test) {
|
||||
test.equal(table.el.childNodes.length, 0);
|
||||
|
||||
table.content = range({});
|
||||
DomRange.insert(table.content, table.el);
|
||||
DomRange.insert(table.content.dom, table.el);
|
||||
var b1 = range({});
|
||||
var b2 = range({});
|
||||
table.content.dom.add(b1);
|
||||
table.content.dom.add(b1.dom);
|
||||
b2.dom.add(document.createElement('tr'));
|
||||
// 4 marker nodes in table, no elements
|
||||
test.equal(table.el.childNodes.length, 4);
|
||||
test.equal($(table.el).find("*").length, 0);
|
||||
// shazam, adding b2, which contains a TR,
|
||||
// should move all the ranges into a TBODY.
|
||||
b1.dom.add(b2);
|
||||
b1.dom.add(b2.dom);
|
||||
test.equal(table.el.childNodes.length, 1);
|
||||
test.equal(table.el.firstChild.nodeName, 'TBODY');
|
||||
test.equal(table.el.firstChild.childNodes.length, 7);
|
||||
@@ -594,8 +596,8 @@ Tinytest.add("ui - DomRange - tables", function (test) {
|
||||
|
||||
var c1 = range({});
|
||||
var c2 = range({});
|
||||
DomRange.insert(c1, table.el);
|
||||
DomRange.insert(c2, table.el);
|
||||
DomRange.insert(c1.dom, table.el);
|
||||
DomRange.insert(c2.dom, table.el);
|
||||
test.equal(table.el.childNodes.length, 4);
|
||||
test.equal($(table.el).find("*").length, 0);
|
||||
c2.dom.add(document.createElement('tr'));
|
||||
@@ -745,22 +747,15 @@ Tinytest.add("ui - DomRange - contains", function (test) {
|
||||
|
||||
Tinytest.add("ui - DomRange - constructor", function (test) {
|
||||
var r = new DomRange;
|
||||
test.isTrue(r.dom === r);
|
||||
test.isTrue(r.component === r);
|
||||
|
||||
var x = {};
|
||||
var s = new DomRange(x);
|
||||
test.isTrue(x.dom === s);
|
||||
test.isTrue(s.component === x);
|
||||
test.isTrue(r.parentNode());
|
||||
|
||||
test.isTrue(s.parentNode());
|
||||
|
||||
test.isTrue(s.start.$ui === x);
|
||||
test.isTrue(s.end.$ui === x);
|
||||
test.isTrue(r.start.$ui === r);
|
||||
test.isTrue(r.end.$ui === r);
|
||||
|
||||
var div = document.createElement('div');
|
||||
s.add(div);
|
||||
test.isTrue(div.$ui === x);
|
||||
r.add(div);
|
||||
test.isTrue(div.$ui === r);
|
||||
});
|
||||
|
||||
Tinytest.add("ui - DomRange - get", function (test) {
|
||||
@@ -803,16 +798,6 @@ Tinytest.add("ui - DomRange - get", function (test) {
|
||||
|
||||
test.isTrue(r.get('c') === c);
|
||||
test.isTrue(r.get('toString') === d);
|
||||
|
||||
var x = {};
|
||||
var s = new DomRange(x);
|
||||
|
||||
test.throws(function () {
|
||||
r.add('s', s);
|
||||
});
|
||||
|
||||
r.add('x', x);
|
||||
test.isTrue(r.get('x') === x);
|
||||
});
|
||||
|
||||
// This test targets IE 9 and 10, which allow properties
|
||||
|
||||
@@ -100,7 +100,7 @@ UI.Each = Component.extend({
|
||||
beforeId = LocalCollection._idStringify(beforeId);
|
||||
|
||||
var renderedItem = UI.render(content.withData(dataFunc), self);
|
||||
range.add(id, renderedItem, beforeId);
|
||||
range.add(id, renderedItem.dom, beforeId);
|
||||
},
|
||||
removed: function (id, item) {
|
||||
addToCount(-1);
|
||||
@@ -112,7 +112,7 @@ UI.Each = Component.extend({
|
||||
beforeId && LocalCollection._idStringify(beforeId));
|
||||
},
|
||||
changed: function (id, newItem) {
|
||||
range.get(LocalCollection._idStringify(id)).data.$set(newItem);
|
||||
range.get(LocalCollection._idStringify(id)).component.data.$set(newItem);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -159,13 +159,11 @@ UI.emboxValue = function (funcOrValue, equals) {
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
UI.insert = UI.DomRange && UI.DomRange.insert;
|
||||
|
||||
// Insert a DOM node or DomRange into a DOM element or DomRange.
|
||||
//
|
||||
// One of three things happens depending on what needs to be inserted into what:
|
||||
// - `range.add` (anything into DomRange)
|
||||
// - `UI.insert` (DomRange into element)
|
||||
// - `UI.DomRange.insert` (DomRange into element)
|
||||
// - `elem.insertBefore` (node into element)
|
||||
//
|
||||
// The optional `before` argument is an existing node or id to insert before in
|
||||
@@ -174,12 +172,11 @@ var insert = function (nodeOrRange, parent, before) {
|
||||
if (! parent)
|
||||
throw new Error("Materialization parent required");
|
||||
|
||||
if (parent.component && parent.component.dom) {
|
||||
// parent is DomRange; add node or range
|
||||
parent.add(nodeOrRange.component || nodeOrRange, before);
|
||||
} else if (nodeOrRange.component && nodeOrRange.component.dom) {
|
||||
if (parent instanceof UI.DomRange) {
|
||||
parent.add(nodeOrRange, before);
|
||||
} else if (nodeOrRange instanceof UI.DomRange) {
|
||||
// parent is an element; inserting a range
|
||||
UI.insert(nodeOrRange.component, parent, before);
|
||||
UI.DomRange.insert(nodeOrRange, parent, before);
|
||||
} else {
|
||||
// parent is an element; inserting an element
|
||||
parent.insertBefore(nodeOrRange, before || null); // `null` for IE
|
||||
@@ -243,10 +240,13 @@ UI.render = function (kind, parentComponent) {
|
||||
|
||||
var content = content = (inst.render && inst.render());
|
||||
|
||||
var range = new UI.DomRange(inst);
|
||||
var range = new UI.DomRange;
|
||||
inst.dom = range;
|
||||
range.component = inst;
|
||||
|
||||
materialize(content, range, null, inst);
|
||||
|
||||
inst.removed = function () {
|
||||
range.removed = function () {
|
||||
inst.isDestroyed = true;
|
||||
if (inst.destroyed) {
|
||||
updateTemplateInstance(inst);
|
||||
|
||||
Reference in New Issue
Block a user