Permalink
Browse files

Implement elementFromPoint for document and ShadowRoot

  • Loading branch information...
arv committed Apr 25, 2013
1 parent a937a83 commit 1a11be889a1f76ca45e09655f7e7ed5b2aeaa297
Showing with 94 additions and 6 deletions.
  1. +14 −6 src/wrappers/Document.js
  2. +17 −0 src/wrappers/EventTarget.js
  3. +5 −0 src/wrappers/ShadowRoot.js
  4. +28 −0 test/Document.js
  5. +29 −0 test/ShadowRoot.js
  6. +1 −0 test/test.main.js
View
@@ -6,17 +6,18 @@
'use strict';
var GetElementsByInterface = scope.GetElementsByInterface;
+ var Node = scope.wrappers.Node;
var ParentNodeInterface = scope.ParentNodeInterface;
var SelectorsInterface = scope.SelectorsInterface;
- var Node = scope.wrappers.Node;
var defineWrapGetter = scope.defineWrapGetter;
+ var elementFromPoint = scope.elementFromPoint;
+ var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrapEventTargetMethods = scope.wrapEventTargetMethods;
var wrapNodeList = scope.wrapNodeList;
- var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
var implementationTable = new SideTable();
@@ -55,10 +56,16 @@
].forEach(wrapMethod);
var originalAdoptNode = document.adoptNode;
- Document.prototype.adoptNode = function(node) {
- originalAdoptNode.call(this.impl, unwrap(node));
- return node;
- };
+
+ mixin(Document.prototype, {
+ adoptNode: function(node) {
+ originalAdoptNode.call(this.impl, unwrap(node));
+ return node;
+ },
+ elementFromPoint: function(x, y) {
+ return elementFromPoint(this, this, x, y);
+ }
+ });
// We also override some of the methods on document.body and document.head
// for convenience.
@@ -88,6 +95,7 @@
'createEvent',
'createEventNS',
'createTextNode',
+ 'elementFromPoint',
'getElementById',
]);
@@ -580,7 +580,24 @@
forwardMethodsToWrapper(constructors, methodNames);
}
+
+ var originalElementFromPoint = document.elementFromPoint;
+
+ function elementFromPoint(self, document, x, y) {
+ scope.renderAllPending();
+
+ var element = wrap(originalElementFromPoint.call(document.impl, x, y));
+ var targets = retarget(element, this)
+ for (var i = 0; i < targets.length; i++) {
+ var target = targets[i];
+ if (target.currentTarget === self)
+ return target.target;
+ }
+ return null;
+ }
+
scope.adjustRelatedTarget = adjustRelatedTarget;
+ scope.elementFromPoint = elementFromPoint;
scope.wrapEventTargetMethods = wrapEventTargetMethods;
scope.wrappers.CustomEvent = CustomEvent;
scope.wrappers.Event = Event;
@@ -6,6 +6,7 @@
'use strict';
var DocumentFragment = scope.wrappers.DocumentFragment;
+ var elementFromPoint = scope.elementFromPoint;
var getInnerHTML = scope.getInnerHTML;
var mixin = scope.mixin;
var rewrap = scope.rewrap;
@@ -42,6 +43,10 @@
invalidateShadowRenderer: function() {
return shadowHostTable.get(this).invalidateShadowRenderer();
+ },
+
+ elementFromPoint: function(x, y) {
+ return elementFromPoint(this, this.ownerDocument, x, y);
}
});
View
@@ -160,4 +160,32 @@ suite('Document', function() {
assert.equal(div, div3);
assert.equal(div.ownerDocument, doc2);
});
+
+ test('elementFromPoint', function() {
+ div = document.body.appendChild(document.createElement('div'));
+ div.style.cssText = 'position: fixed; background: green; ' +
+ 'width: 10px; height: 10px; top: 0; left: 0;';
+
+ assert.equal(document.elementFromPoint(5, 5), div);
+
+ var doc = wrap(document);
+ assert.equal(doc.elementFromPoint(5, 5), div);
+ });
+
+ test('elementFromPoint in shadow', function() {
+ div = document.body.appendChild(document.createElement('div'));
+ div.style.cssText = 'position: fixed; background: red; ' +
+ 'width: 10px; height: 10px; top: 0; left: 0;';
+ var sr = div.createShadowRoot();
+ sr.innerHTML = '<a></a>';
+ var a = sr.firstChild;
+ a.style.cssText = 'position: absolute; width: 100%; height: 100%; ' +
+ 'background: green';
+
+ assert.equal(document.elementFromPoint(5, 5), div);
+
+ var doc = wrap(document);
+ assert.equal(doc.elementFromPoint(5, 5), div);
+ });
+
});
View
@@ -0,0 +1,29 @@
+// Copyright 2013 The Toolkitchen Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+suite('ShadowRoot', function() {
+
+ var div;
+ teardown(function() {
+ if (div) {
+ if (div.parentNode)
+ div.parentNode.removeChild(div);
+ div = undefined;
+ }
+ });
+
+ test('elementFromPoint', function() {
+ div = document.body.appendChild(document.createElement('div'));
+ div.style.cssText = 'position: fixed; background: red; ' +
+ 'width: 10px; height: 10px; top: 0; left: 0;';
+ var sr = div.createShadowRoot();
+ sr.innerHTML = '<a></a>';
+ var a = sr.firstChild;
+ a.style.cssText = 'position: absolute; width: 100%; height: 100%; ' +
+ 'background: green';
+
+ assert.equal(sr.elementFromPoint(5, 5), a);
+ });
+
+});
View
@@ -80,6 +80,7 @@ var modules = [
'HTMLTemplateElement.js',
'MutationObserver.js',
'ParentNodeInterface.js',
+ 'ShadowRoot.js',
'Text.js',
'Window.js',
'custom-element.js',

0 comments on commit 1a11be8

Please sign in to comment.