Revision: 5365
Author: [email protected]
Date: Mon Apr 22 11:12:00 2013
Log: Allow overriding inherited properties of Domado objects by
assignment.
https://codereview.appspot.com/8649044
* ExpandoProxyHandler no longer treats defineProperty of a property
name which exists somewhere in the prototype chain differently for
no good reason.
* ExpandoProxyHandler's reimplementation of assignment no longer
acts according to the "override mistake" (needed for ES5/3).
Fixes <https://code.google.com/p/google-caja/issues/detail?id=1650>.
[email protected]
http://code.google.com/p/google-caja/source/detail?r=5365
Modified:
/trunk/src/com/google/caja/plugin/domado.js
/trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html
=======================================
--- /trunk/src/com/google/caja/plugin/domado.js Wed Apr 17 11:08:30 2013
+++ /trunk/src/com/google/caja/plugin/domado.js Mon Apr 22 11:12:00 2013
@@ -689,8 +689,8 @@
if (name === weakMapMagicName) {
if (descriptor.set === null) descriptor.set = undefined;
Object.defineProperty(this, 'weakMapMagic', descriptor);
- } else if (Object.prototype.hasOwnProperty(this.target, name)) {
- // Forwards everything already defined (not expando).
+ } else if (Object.prototype.hasOwnProperty.call(this.target, name)) {
+ // Forward attempted redefinitions of own properties to the target.
return ProxyHandler.prototype.defineProperty.call(this, name,
descriptor);
} else {
@@ -703,8 +703,8 @@
ExpandoProxyHandler.prototype['delete'] = function (name) {
if (name === weakMapMagicName) {
return false;
- } else if (Object.prototype.hasOwnProperty(this.target, name)) {
- // Forwards everything already defined (not expando).
+ } else if (Object.prototype.hasOwnProperty.call(this.target, name)) {
+ // Forward attempted deletions of own properties to the target.
return ProxyHandler.prototype['delete'].call(this, name);
} else {
if (!this.editable) { throw new Error(NOT_EDITABLE); }
@@ -769,11 +769,22 @@
desc = this.getPropertyDescriptor(name);
if (desc) {
if ('writable' in desc) {
- if (desc.writable) {
- // fall through
- } else {
- return false;
- }
+ // The commenting-out of the below code corresponds to "fixing
the
+ // override mistake". For further information, see
+ // Object.prototype.w___ in ES5/3 and makeTamperProof in SES.
+ //
+ // We need to do the 'fix' here because this proxy trap is a
+ // reimplementation of what otherwise would be JS runtime
internal
+ // algorithms, and so not doing the fix would break code which
+ // optimizes on the knowledge that the platform has the fix.
+ // (In particular, cajaVM.def uses nonwritable data properties
instead
+ // of accessor properties whenever possible.)
+ //
+ // if (desc.writable) {
+ // // fall through
+ // } else {
+ // return false;
+ // }
} else { // accessor
if (desc.set) {
desc.set.call(receiver, val);
=======================================
--- /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html Thu
Apr 18 11:36:23 2013
+++ /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html Mon
Apr 22 11:12:00 2013
@@ -561,6 +561,26 @@
});
</script>
+<p id="testExpandoOverride" class="testcontainer">
+ testExpandoOverride: can replace methods on instances
+</p>
+<script type="text/javascript">
+ jsunitRegister('testExpandoOverride',
+ function testExpandoOverride() {
+ // Example from Angular -- happens to be an event
+ var obj = document.createEvent('HTMLEvents');
+ obj.preventDefault = function() { return 'boo'; };
+ assertEquals('boo', obj.preventDefault());
+
+ // similarly for nodes
+ var obj = document.createElement('span');
+ obj.blur = function() { return 'boo'; };
+ assertEquals('boo', obj.blur());
+
+ pass('testExpandoOverride');
+ });
+</script>
+
<p id="testEditabilityInNodeLists" class="testcontainer">
editability in node lists<br>
</p>
--
---
You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.