diff --git a/src/wrappers.js b/src/wrappers.js index 7e89655..d0bb3c2 100644 --- a/src/wrappers.js +++ b/src/wrappers.js @@ -127,28 +127,39 @@ window.ShadowDOMPolyfill = {}; function() { return this.impl[name].apply(this.impl, arguments); }; } - function installProperty(source, target, allowMethod) { - Object.getOwnPropertyNames(source).forEach(function(name) { + function getDescriptor(source, name) { + try { + return Object.getOwnPropertyDescriptor(source, name); + } catch (ex) { + // JSC and V8 both use data properties instead of accessors which can + // cause getting the property desciptor to throw an exception. + // https://bugs.webkit.org/show_bug.cgi?id=49739 + return dummyDescriptor; + } + } + + function installProperty(source, target, allowMethod, opt_blacklist) { + var names = Object.getOwnPropertyNames(source); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + if (name === 'polymerBlackList_') + continue; + if (name in target) - return; + continue; + + if (source.polymerBlackList_ && source.polymerBlackList_[name]) + continue; if (isFirefox) { // Tickle Firefox's old bindings. source.__lookupGetter__(name); } - var descriptor; - try { - descriptor = Object.getOwnPropertyDescriptor(source, name); - } catch (ex) { - // JSC and V8 both use data properties instead of accessors which can - // cause getting the property desciptor to throw an exception. - // https://bugs.webkit.org/show_bug.cgi?id=49739 - descriptor = dummyDescriptor; - } + var descriptor = getDescriptor(source, name); var getter, setter; if (allowMethod && typeof descriptor.value === 'function') { target[name] = getMethod(name); - return; + continue; } var isEvent = isEventHandlerName(name); @@ -170,7 +181,7 @@ window.ShadowDOMPolyfill = {}; configurable: descriptor.configurable, enumerable: descriptor.enumerable }); - }); + } } /** diff --git a/src/wrappers/events.js b/src/wrappers/events.js index 032f6a8..7c4f945 100644 --- a/src/wrappers/events.js +++ b/src/wrappers/events.js @@ -375,6 +375,7 @@ }; var OriginalEvent = window.Event; + OriginalEvent.prototype.polymerBlackList_ = {returnValue: true}; /** * Creates a new Event wrapper or wraps an existin native Event object. @@ -563,6 +564,19 @@ configureEventConstructor('FocusEvent', {relatedTarget: null}, 'UIEvent'); } + function BeforeUnloadEvent(impl) { + Event.call(this); + } + BeforeUnloadEvent.prototype = Object.create(Event.prototype); + mixin(BeforeUnloadEvent.prototype, { + get returnValue() { + return this.impl.returnValue; + }, + set returnValue(v) { + this.impl.returnValue = v; + } + }); + function isValidListener(fun) { if (typeof fun === 'function') return true; @@ -736,6 +750,7 @@ scope.muteMutationEvents = muteMutationEvents; scope.unmuteMutationEvents = unmuteMutationEvents; scope.wrapEventTargetMethods = wrapEventTargetMethods; + scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent; scope.wrappers.CustomEvent = CustomEvent; scope.wrappers.Event = Event; scope.wrappers.EventTarget = EventTarget; diff --git a/test/js/events.js b/test/js/events.js index af4aac1..822d9a6 100644 --- a/test/js/events.js +++ b/test/js/events.js @@ -1328,4 +1328,9 @@ test('retarget order (multiple shadow roots)', function() { assert.equal(count, 1); }); + test('returnValue', function() { + var e = new Event('x'); + assert.isFalse('returnValue' in e); + }); + });