From 520811729924b719746613f3545e3d0fc15c29d1 Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Wed, 25 Nov 2015 16:41:48 +0000 Subject: [PATCH] Fix Wombat in Safari 9 In Safari 9, Object.getOwnPropertyDescriptor(domObject.prototype, prop) returns descriptors which have the correct structure but undefined getters and are marked as unconfigurable. See https://bugs.webkit.org/show_bug.cgi?id=49739#c19 for details. The getters cannot be retrieved via obj.__lookupGetter__() either. * Resolve the issue by skipping overrides for DOM properties where the property is not configurable, or the original getter for a property could not be retrieved. * Lookup the 'baseURI' property on the correct prototype (Node, not document) This fix also resolves the problem where accesses to document.baseURI on Edge would fail. --- pywb/static/wombat.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/pywb/static/wombat.js b/pywb/static/wombat.js index be3ec6b9..e86ae3d3 100644 --- a/pywb/static/wombat.js +++ b/pywb/static/wombat.js @@ -363,26 +363,31 @@ var wombat_internal = function($wbwindow) { } //============================================ - // Define custom property + // Override a DOM property function def_prop(obj, prop, set_func, get_func) { + // if the property is marked as non-configurable in the current + // browser, skip the override + var existingDescriptor = Object.getOwnPropertyDescriptor(obj, prop); + if (existingDescriptor && !existingDescriptor.configurable) { + return; + } + + // if no getter function was supplied, skip the override. + // See https://github.com/ikreymer/pywb/issues/147 for context + if (!get_func) { + return; + } + try { Object.defineProperty(obj, prop, { configurable: false, -// enumerable: true, set: set_func, get: get_func }); return true; } catch (e) { - var info = "Can't redefine prop " + prop; - console.warn(info); - //f (obj && obj.tagName) { - // info += " on " + obj.tagName; - //} - //if (value != obj[prop]) { - // obj[prop] = value; - //} + console.warn('Failed to redefine property %s', prop, e.message); return false; } } @@ -757,15 +762,16 @@ var wombat_internal = function($wbwindow) { def_prop($wbwindow.HTMLBaseElement.prototype, "href", undefined, base_href_get); // Shared baseURI - var orig_getter = $wbwindow.document.__lookupGetter__("baseURI"); + var orig_getter = get_orig_getter($wbwindow.Node, "baseURI"); + if (orig_getter) { + var get_baseURI = function() { + var res = orig_getter.call(this); + return extract_orig(res); + } - var get_baseURI = function() { - var res = orig_getter.call(this); - return extract_orig(res); + def_prop($wbwindow.HTMLElement.prototype, "baseURI", undefined, get_baseURI); + def_prop($wbwindow.HTMLDocument.prototype, "baseURI", undefined, get_baseURI); } - - def_prop($wbwindow.HTMLElement.prototype, "baseURI", undefined, get_baseURI); - def_prop($wbwindow.HTMLDocument.prototype, "baseURI", undefined, get_baseURI); } //============================================