Revision: 5570
Author: [email protected]
Date: Wed Aug 21 21:36:49 2013 UTC
Log: a.href now returns a virtualized URL and fragment for the current
page.
https://codereview.appspot.com/12834046
* jQuery UI tabs expects that <a href="#foo">.href ===
window.location + '#foo', so implement that.
* Fix toString overrides in Domado not working in ES5/3 mode with the +
operator.
Fixes <http://code.google.com/p/google-caja/issues/detail?id=1835>.
[email protected]
http://code.google.com/p/google-caja/source/detail?r=5570
Modified:
/trunk/src/com/google/caja/plugin/domado.js
/trunk/tests/com/google/caja/plugin/test-domado-dom-guest.html
/trunk/tests/com/google/caja/plugin/test-domado-global-location.js
/trunk/tests/com/google/caja/plugin/third-party-tests.json
=======================================
--- /trunk/src/com/google/caja/plugin/domado.js Wed Aug 21 20:22:22 2013 UTC
+++ /trunk/src/com/google/caja/plugin/domado.js Wed Aug 21 21:36:49 2013 UTC
@@ -323,8 +323,15 @@
* Alias for a common pattern: non-enumerable toString method.
*/
function setToString(obj, fn) {
- Object.defineProperty(obj, 'toString',
- allowNonWritableOverride(obj, 'toString', {value: fn}));
+ // ES5/3's virtualization of toString does not work properly w/
+ // defineProperty
+ if ('USELESS' in cajaVM) { // TODO(kpreid): Better condition/kill
this code
+ // Under ES5/3, this will have the overridable semantics we wanted
anyway
+ obj.toString = fn;
+ } else {
+ Object.defineProperty(obj, 'toString',
+ allowNonWritableOverride(obj, 'toString', {value: fn}));
+ }
}
/**
@@ -1827,6 +1834,8 @@
var window = bridalMaker.getWindow(outerContainerNode,
makeDOMAccessible);
window = makeDOMAccessible(window);
+ makeDOMAccessible(document.location);
+
// Note that feralPseudoWindow may be an Element or a Window
depending.
var feralPseudoDocument, feralPseudoWindow;
if (outerContainerNode.nodeType === 9) { // Document node
@@ -2178,6 +2187,14 @@
return fail;
}
}
+
+ /** Split a URI reference into URI and fragment (still escaped). */
+ function splitURIFragment(uriString) {
+ var parsed = URI.parse(uriString);
+ var frag = parsed.getRawFragment();
+ parsed.setRawFragment('');
+ return {frag: frag, uri: parsed.toString()};
+ }
var ID_LIST_PARTS_PATTERN = new RegExp(
'([^' + XML_SPACE + ']+)([' + XML_SPACE + ']+|$)', 'g');
@@ -2199,7 +2216,19 @@
if (realValue && '#' === realValue.charAt(0)) {
return unsuffix(realValue, idSuffix, realValue);
} else {
- return realValue;
+ // convert "http://hostpage#fragment-suffix___" into
+ // "http://guestpage#fragment"
+ var valueSplit = splitURIFragment(realValue);
+ var baseSplit = splitURIFragment(
+ // .baseURI not available on IE
+ document.baseURI || document.location.href);
+ // compare against document's base URL
+ if (valueSplit.uri === baseSplit.uri) {
+ valueSplit.uri = domicile.pseudoLocation.href;
+ }
+ return valueSplit.uri +
+ (valueSplit.frag === null ? '' : '#' +
+ unsuffix(valueSplit.frag, idSuffix,
valueSplit.frag));
}
case html4.atype.URI_FRAGMENT:
if (realValue && '#' === realValue.charAt(0)) {
@@ -2779,6 +2808,25 @@
// configuration.
var NP_writePolicyOnly = PT.filter(false, identity, true, identity);
+ function NP_UriValuedProperty(schemaEl, schemaAttr) {
+ return Props.markPropMaker(function(env) {
+ var prop = env.prop;
+ return {
+ // this is not just an attribute wrapper because the .href is
+ // expected to be absolute even if the attribute is not.
+ // But we can still use the same virt logic.
+ get: env.amplifying(function(privates) {
+ return virtualizeAttributeValue(
+ html4.atype.URI, privates.feral[prop]);
+ }),
+ set: env.amplifying(function(privates, value) {
+ privates.feral.href = rewriteAttribute(
+ schemaEl, schemaAttr, html4.atype.URI, value);
+ })
+ };
+ });
+ }
+
var nodeClassNoImplWarnings = {};
var elementTamerCache = {};
function makeTameNodeByType(node) {
@@ -4609,8 +4657,7 @@
false,
// TODO(felix8a): add suffix if href is self
identity),
- // TODO(felix8a): fragment rewriting?
- href: NP_writePolicyOnly
+ href: NP_UriValuedProperty('a', 'href')
}; }
});
=======================================
--- /trunk/tests/com/google/caja/plugin/test-domado-dom-guest.html Wed Aug
14 04:56:12 2013 UTC
+++ /trunk/tests/com/google/caja/plugin/test-domado-dom-guest.html Wed Aug
21 21:36:49 2013 UTC
@@ -3254,28 +3254,30 @@
</script>
<div class="testcontainer" id="testHash">
- <a id='test-hash' href="#foo">test a.hash</a>
+ <a id='test-hash' href="#foo">test a.hash and hash in a.href</a>
</div>
<script type="text/javascript">
jsunitRegister('testHash', function testHash() {
var a = document.getElementById('test-hash');
+
assertEquals('#foo', a.hash);
// a.href is an absolute url; a.getAttribute('href') is just the hash
assertEquals('#foo', a.getAttribute('href'));
- // TODO(felix8a): maybe this should succeed?
- //assertEquals('#foo', a.href.substr(-4));
+ assertEquals(window.location + '#foo', a.href);
+
a.hash = '#bar';
assertEquals('#bar', a.hash);
// setting a.hash forces a.getAttribute('href') to be a resolved url
- // TODO(felix8a): maybe this should succeed?
- //assertEquals('#bar', a.href.substr(-4));
- pass('testHash');
+ assertEquals(window.location + '#bar', a.getAttribute('href'));
+ assertEquals(window.location + '#bar', a.href);
+
+ pass();
});
</script>
<div class="testcontainer" id="testBaseURI"></div>
<script type="text/javascript">
- jsunitRegister('testBaseURI', function testHash() {
+ jsunitRegister('testBaseURI', function testBaseURI() {
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-baseURI
var loc = window.location;
assertEquals(
=======================================
--- /trunk/tests/com/google/caja/plugin/test-domado-global-location.js Wed
Aug 14 04:56:12 2013 UTC
+++ /trunk/tests/com/google/caja/plugin/test-domado-global-location.js Wed
Aug 21 21:36:49 2013 UTC
@@ -50,6 +50,8 @@
'',
window.location.search);
}
+
+ assertEquals('implicit toString', window.location.href, '' +
window.location);
// document.location is an identical property to window.location
assertTrue('document.location', window.location === document.location);
=======================================
--- /trunk/tests/com/google/caja/plugin/third-party-tests.json Tue Aug 13
22:39:24 2013 UTC
+++ /trunk/tests/com/google/caja/plugin/third-party-tests.json Wed Aug 21
21:36:49 2013 UTC
@@ -124,7 +124,7 @@
},
{
"guest": "css",
- "expected-pass": { "firefox": 239, "chrome": 241 },
+ "expected-pass": { "firefox": 237, "chrome": 241 },
"comment": [
"Current failure categories:",
"Not yet examined."
@@ -222,7 +222,7 @@
},
{
"guest": "dialog",
- "expected-pass": { "firefox": 294, "chrome": 306 },
+ "expected-pass": { "firefox": 291, "chrome": 306 },
"comment": [
"Current failure categories:",
"What may be event simulation failures",
@@ -271,7 +271,7 @@
},
{
"guest": "tabs",
- "expected-pass": { "firefox": 487, "chrome": 519 },
+ "expected-pass": { "firefox": 547, "chrome": 594 },
"comment": [
"Current modifications made to test suite:",
"Work around lost-signal problems due to lack of event
simulation",
--
---
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.