From 80b8a47c587e88e3af355ee66b5eba1233ca1566 Mon Sep 17 00:00:00 2001 From: Erik Arvidsson Date: Mon, 14 Oct 2013 17:01:52 -0400 Subject: [PATCH] Make sure we handle both getter and setter for scrollTop etc --- src/wrappers/HTMLElement.js | 29 ++++++++++--- test/js/HTMLElement.js | 83 +++++++++++++++++++++++++++++++++++++ test/test.main.js | 1 + 3 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 test/js/HTMLElement.js diff --git a/src/wrappers/HTMLElement.js b/src/wrappers/HTMLElement.js index 1da4c50..4dff036 100644 --- a/src/wrappers/HTMLElement.js +++ b/src/wrappers/HTMLElement.js @@ -130,11 +130,15 @@ } }); - function getterRequiresRendering(name) { - defineGetter(HTMLElement, name, function() { + function getter(name) { + return function() { scope.renderAllPending(); return this.impl[name]; - }); + }; + } + + function getterRequiresRendering(name) { + defineGetter(HTMLElement, name, getter(name)); } [ @@ -147,11 +151,26 @@ 'offsetTop', 'offsetWidth', 'scrollHeight', - 'scrollLeft', - 'scrollTop', 'scrollWidth', ].forEach(getterRequiresRendering); + function getterAndSetterRequiresRendering(name) { + Object.defineProperty(HTMLElement.prototype, name, { + get: getter(name), + set: function(v) { + scope.renderAllPending(); + this.impl[name] = v; + }, + configurable: true, + enumerable: true + }); + } + + [ + 'scrollLeft', + 'scrollTop', + ].forEach(getterAndSetterRequiresRendering); + function methodRequiresRendering(name) { Object.defineProperty(HTMLElement.prototype, name, { value: function() { diff --git a/test/js/HTMLElement.js b/test/js/HTMLElement.js new file mode 100644 index 0000000..66f6166 --- /dev/null +++ b/test/js/HTMLElement.js @@ -0,0 +1,83 @@ +/* + * Copyright 2013 The Polymer 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('HTMLElement', function() { + + var div; + + setup(function() { + div = document.body.appendChild(document.createElement('div')); + div.style.cssText = + 'width: 100px; height: 100px; overflow: scroll;' + + 'position: absolute; top: 100px; left: 100px;' + + 'border: 10px solid red'; + var sr = div.createShadowRoot(); + var div2 = sr.appendChild(document.createElement('div')); + div2.style.cssText = 'width: 1000px; height: 1000px'; + }); + + teardown(function() { + if (div && div.parentNode) + div.parentNode.removeChild(div); + div = undefined; + }); + + test('scrollTop', function() { + assert.equal(div.scrollTop, 0); + div.scrollTop = 100; + assert.equal(div.scrollTop, 100); + }); + + test('scrollLeft', function() { + assert.equal(div.scrollLeft, 0); + div.scrollLeft = 100; + assert.equal(div.scrollLeft, 100); + }); + + test('scrollHeight', function() { + assert.equal(div.scrollHeight, 1000); + }); + + test('scrollWidth', function() { + assert.equal(div.scrollHeight, 1000); + }); + + test('clientHeight', function() { + div.style.overflow = 'hidden'; + assert.equal(div.clientHeight, 100); + }); + + test('clientLeft', function() { + div.style.overflow = 'hidden'; + assert.equal(div.clientLeft, 10); + }); + + test('clientTop', function() { + assert.equal(div.clientTop, 10); + }); + + test('clientWidth', function() { + div.style.overflow = 'hidden'; + assert.equal(div.clientWidth, 100); + }); + + test('offsetHeight', function() { + assert.equal(div.offsetHeight, 120); + }); + + test('offsetLeft', function() { + assert.equal(div.offsetLeft, 100); + }); + + test('offsetTop', function() { + assert.equal(div.offsetTop, 100); + }); + + test('offsetWidth', function() { + assert.equal(div.offsetWidth, 120); + }); + +}); diff --git a/test/test.main.js b/test/test.main.js index 5273f20..8f2f8fe 100644 --- a/test/test.main.js +++ b/test/test.main.js @@ -58,6 +58,7 @@ var modules = [ 'HTMLButtonElement.js', 'HTMLCanvasElement.js', 'HTMLContentElement.js', + 'HTMLElement.js', 'HTMLFieldSetElement.js', 'HTMLHeadElement.js', 'HTMLHtmlElement.js',