Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
Merge pull request #215 from Polymer/master
Browse files Browse the repository at this point in the history
8/16 master -> stable hotfix
  • Loading branch information
dfreedm committed Aug 16, 2013
2 parents 9d8aa3b + bba9ead commit 8d23e7c
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 34 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"grunt": "*",
"grunt-contrib-uglify": "*",
"grunt-contrib-yuidoc": "~0.4.0",
"grunt-karma": "~0.5.0",
"grunt-karma": "*",
"karma-mocha": "*",
"karma-script-launcher": "*",
"karma-crbot-reporter": "*"
Expand Down
8 changes: 1 addition & 7 deletions src/ShadowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
var Node = scope.wrappers.Node;
var assert = scope.assert;
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var unwrap = scope.unwrap;
var wrap = scope.wrap;

Expand Down Expand Up @@ -190,13 +191,6 @@
].join('|') + ')');


function oneOf(object, propertyNames) {
for (var i = 0; i < propertyNames.length; i++) {
if (propertyNames[i] in object)
return propertyNames[i];
}
}

/**
* @param {Element} node
* @oaram {Element} point The insertion point element.
Expand Down
10 changes: 9 additions & 1 deletion src/wrappers.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ var ShadowDOMPolyfill = {};
return to;
};

function oneOf(object, propertyNames) {
for (var i = 0; i < propertyNames.length; i++) {
if (propertyNames[i] in object)
return propertyNames[i];
}
}

// Mozilla's old DOM bindings are bretty busted:
// https://bugzilla.mozilla.org/show_bug.cgi?id=855844
// Make sure they are create before we start modifying things.
Expand Down Expand Up @@ -308,7 +315,7 @@ var ShadowDOMPolyfill = {};
constructors.forEach(function(constructor) {
names.forEach(function(name) {
constructor.prototype[name] = function() {
var w = wrap(this);
var w = wrapIfNeeded(this);
return w[name].apply(w, arguments);
};
});
Expand All @@ -323,6 +330,7 @@ var ShadowDOMPolyfill = {};
scope.isWrapperFor = isWrapperFor;
scope.mixin = mixin;
scope.nativePrototypeTable = nativePrototypeTable;
scope.oneOf = oneOf;
scope.registerObject = registerObject;
scope.registerWrapper = register;
scope.rewrap = rewrap;
Expand Down
13 changes: 10 additions & 3 deletions src/wrappers/Document.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
var defineWrapGetter = scope.defineWrapGetter;
var elementFromPoint = scope.elementFromPoint;
var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
var matchesName = scope.matchesName;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
Expand Down Expand Up @@ -59,6 +60,11 @@
var originalAdoptNode = document.adoptNode;
var originalWrite = document.write;

function adoptNodeNoRemove(node, doc) {
originalAdoptNode.call(doc.impl, unwrap(node));
adoptSubtree(node, doc);
}

function adoptSubtree(node, doc) {
if (node.shadowRoot)
doc.adoptNode(node.shadowRoot);
Expand All @@ -79,8 +85,7 @@
adoptNode: function(node) {
if (node.parentNode)
node.parentNode.removeChild(node);
originalAdoptNode.call(this.impl, unwrap(node));
adoptSubtree(node, this);
adoptNodeNoRemove(node, this);
return node;
},
elementFromPoint: function(x, y) {
Expand Down Expand Up @@ -200,6 +205,7 @@
'querySelectorAll',
'removeChild',
'replaceChild',
matchesName,
]);

forwardMethodsToWrapper([
Expand Down Expand Up @@ -284,7 +290,8 @@
'hasFeature',
]);

scope.wrappers.Document = Document;
scope.adoptNodeNoRemove = adoptNodeNoRemove;
scope.wrappers.DOMImplementation = DOMImplementation;
scope.wrappers.Document = Document;

})(this.ShadowDOMPolyfill);
19 changes: 14 additions & 5 deletions src/wrappers/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@
var SelectorsInterface = scope.SelectorsInterface;
var addWrapNodeListMethod = scope.addWrapNodeListMethod;
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var registerWrapper = scope.registerWrapper;
var wrappers = scope.wrappers;

var shadowRootTable = new SideTable();
var OriginalElement = window.Element;

var originalMatches =
OriginalElement.prototype.matches ||
OriginalElement.prototype.mozMatchesSelector ||
OriginalElement.prototype.msMatchesSelector ||
OriginalElement.prototype.webkitMatchesSelector;

var matchesName = oneOf(OriginalElement.prototype, [
'matches',
'mozMatchesSelector',
'msMatchesSelector',
'webkitMatchesSelector',
]);

var originalMatches = OriginalElement.prototype[matchesName];

function invalidateRendererBasedOnAttribute(element, name) {
// Only invalidate if parent node is a shadow host.
Expand Down Expand Up @@ -74,6 +78,10 @@
}
});

Element.prototype[matchesName] = function(selector) {
return this.matches(selector);
};

if (OriginalElement.prototype.webkitCreateShadowRoot) {
Element.prototype.webkitCreateShadowRoot =
Element.prototype.createShadowRoot;
Expand Down Expand Up @@ -110,5 +118,6 @@

// TODO(arv): Export setterDirtiesAttribute and apply it to more bindings
// that reflect attributes.
scope.matchesName = matchesName;
scope.wrappers.Element = Element;
})(this.ShadowDOMPolyfill);
19 changes: 15 additions & 4 deletions src/wrappers/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,26 @@
return nodes;
}

function adoptIfNeeded(node, doc) {
if (doc !== node.ownerDocument)
scope.adoptNodeNoRemove(node, doc);
}

function unwrapNodesForInsertion(owner, nodes) {
var length = nodes.length;

if (length === 1)
return unwrap(nodes[0]);
if (length === 1) {
var node = nodes[0];
adoptIfNeeded(node, owner.ownerDocument);
return unwrap(node);
}

var df = unwrap(owner.ownerDocument.createDocumentFragment());
var ownerDoc = owner.ownerDocument;
var df = unwrap(ownerDoc.createDocumentFragment());
for (var i = 0; i < length; i++) {
df.appendChild(unwrap(nodes[i]));
var node = nodes[i];
adoptIfNeeded(node, ownerDoc);
df.appendChild(unwrap(node));
}
return df;
}
Expand Down
12 changes: 9 additions & 3 deletions src/wrappers/Range.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;

var OriginalRange = window.Range;

function Range(impl) {
this.impl = impl;
}
Expand Down Expand Up @@ -73,12 +75,16 @@
},
intersectsNode: function(node) {
return this.impl.intersectsNode(unwrapIfNeeded(node));
},
createContextualFragment: function(html) {
return wrap(this.impl.createContextualFragment(html));
}
};

// IE9 does not have createContextualFragment.
if (OriginalRange.prototype.createContextualFragment) {
Range.prototype.createContextualFragment = function(html) {
return wrap(this.impl.createContextualFragment(html));
};
}

registerWrapper(window.Range, Range);

scope.wrappers.Range = Range;
Expand Down
12 changes: 12 additions & 0 deletions test/js/HTMLHtmlElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,16 @@ suite('HTMLHtmlElement', function() {
assert.equal(doc.documentElement.lastChild, b);
});

test('matches', function() {
// From jQuery.
var html = document.documentElement;
var matches = html.matchesSelector ||
html.mozMatchesSelector ||
html.webkitMatchesSelector ||
html.msMatchesSelector;

assert.isTrue(matches.call(document.body, 'body'));
assert.isTrue(matches.call(wrap(document.body), 'body'));
});

});
28 changes: 28 additions & 0 deletions test/js/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

suite('Node', function() {

var wrap = ShadowDOMPolyfill.wrap;

var DOCUMENT_POSITION_DISCONNECTED = Node.DOCUMENT_POSITION_DISCONNECTED;
var DOCUMENT_POSITION_PRECEDING = Node.DOCUMENT_POSITION_PRECEDING;
var DOCUMENT_POSITION_FOLLOWING = Node.DOCUMENT_POSITION_FOLLOWING;
Expand Down Expand Up @@ -57,4 +59,30 @@ suite('Node', function() {
DOCUMENT_POSITION_DISCONNECTED, 0)
});

test('ownerDocument with template and shadow root', function() {
var div = document.createElement('div');
div.innerHTML = '<template><span></span></template>';

var content1 = div.firstChild.content;
var host = content1.firstChild;

div.innerHTML = '<template>hello world</template>';
var content2 = div.firstChild.content;
var x = content2.firstChild;

var sr = host.createShadowRoot();
sr.appendChild(content2);

assert.equal(x.parentNode, sr);
assert.equal(x.ownerDocument, sr.ownerDocument);
assert.equal(sr.ownerDocument, host.ownerDocument);

var doc = wrap(document);
doc.body.appendChild(host);
assert.equal(host.ownerDocument, doc);
assert.equal(sr.ownerDocument, doc);
assert.equal(x.ownerDocument, doc);

doc.body.removeChild(host);
});
});
19 changes: 12 additions & 7 deletions test/js/Range.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ suite('Range', function() {
});

test('createContextualFragment', function() {
var range = document.createRange();
var container = document.body || document.head;
// IE9 does not support createContextualFragment.
if (!Range.prototype.createContextualFragment)
return;

range.selectNode(container);
var fragment = range.createContextualFragment('<b></b>');
var range = document.createRange();
var container = document.body || document.head;

range.selectNode(container);

var fragment = range.createContextualFragment('<b></b>');

assert.instanceOf(fragment, DocumentFragment);
assert.equal(fragment.firstChild.localName, 'b');
assert.equal(fragment.childNodes.length, 1);
assert.instanceOf(fragment, DocumentFragment);
assert.equal(fragment.firstChild.localName, 'b');
assert.equal(fragment.childNodes.length, 1);
});

});
12 changes: 9 additions & 3 deletions test/js/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ suite('Shadow DOM', function() {
testRender(':checked',
'<input type=checkbox><input type=checkbox checked>',
'<content select=":checked"></content>',
/Firefox/.test(navigator.userAgent) ?
/Firefox|MSIE 9/.test(navigator.userAgent) ?
'<input checked="" type="checkbox">' :
'<input type="checkbox" checked="">');
testRender(':indeterminate',
Expand Down Expand Up @@ -321,7 +321,10 @@ suite('Shadow DOM', function() {
assert.equal(calls, 1);

a.setAttribute('id', 'a');
assert.equal(getVisualInnerHtml(host), '<a foo="bar" id="a"></a>');
var visHTML = getVisualInnerHtml(host);
// IE orders the attributes differently.
assert.isTrue(visHTML === '<a foo="bar" id="a"></a>' ||
visHTML === '<a id="a" foo="bar"></a>');
assert.equal(calls, 2);

a.removeAttribute('foo');
Expand Down Expand Up @@ -365,7 +368,10 @@ suite('Shadow DOM', function() {
assert.equal(calls, 1);

a.setAttribute('class', 'a');
assert.equal(getVisualInnerHtml(host), '<a foo="bar" class="a"></a>');
var visHTML = getVisualInnerHtml(host);
// IE orders the attributes differently.
assert.isTrue(visHTML === '<a foo="bar" class="a"></a>' ||
visHTML === '<a class="a" foo="bar"></a>');
assert.equal(calls, 2);

a.removeAttribute('foo');
Expand Down

0 comments on commit 8d23e7c

Please sign in to comment.