Revision: 5418
Author:   [email protected]
Date:     Wed May 22 14:02:57 2013
Log: document.body should return null if no documentElement, and have a setter.
https://codereview.appspot.com/9667044

Fixes <https://code.google.com/p/google-caja/issues/detail?id=1722>.

[email protected]

http://code.google.com/p/google-caja/source/detail?r=5418

Modified:
 /trunk/src/com/google/caja/plugin/domado.js
 /trunk/tests/com/google/caja/plugin/es53-test-domado-global.js

=======================================
--- /trunk/src/com/google/caja/plugin/domado.js Tue May 21 13:19:02 2013
+++ /trunk/src/com/google/caja/plugin/domado.js Wed May 22 14:02:57 2013
@@ -5746,14 +5746,60 @@
           return fakeNodeList([], 'HTMLCollection');
         })},
         parentNode: P_constant(null),
-        body: { enumerable: true, get: innocuous(function() {
- for (var n = this.documentElement.firstChild; n; n = n.nextSibling) { - // Note: Standard def. also includes FRAMESET elements but we don't
-            // currently support them.
-            if (n.nodeName === "BODY") { return n; }
-          }
-          return null;
-        })},
+        body: {
+          enumerable: true,
+          get: innocuous(function() {
+ // "The body element of a document is the first child of the html + // element that is either a body element or a frameset element. If
+            // there is no such element, it is null."
+ // TODO(kpreid): should be internal .documentElement getter only
+            var htmlEl = this.documentElement;
+            if (!htmlEl) { return null; }
+            for (var n = htmlEl.firstChild; n; n = n.nextSibling) {
+              if (n.nodeName === 'BODY' || n.nodeName === 'FRAMESET') {
+                return n;
+              }
+            }
+            return null;
+          }),
+          set: innocuous(function(newBody) {
+ // "If the new value is not a body or frameset element, then throw a
+            // HierarchyRequestError exception and abort these steps."
+            newBody = TameNodeT.coerce(newBody);
+            if (!(newBody.nodeName === 'BODY' ||
+                newBody.nodeName === 'FRAMESET')) {
+              // should be HierarchyRequestError
+              throw new Error(
+ 'Cannot set document.body except to <body> or <frameset>.');
+            }
+ // "Otherwise, if the new value is the same as the body element, do
+            // nothing. Abort these steps."
+            // TODO(kpreid): should be internal .body getter only
+            var currentBody = this.body;
+            if (newBody === currentBody) { return; }
+ // "Otherwise, if the body element is not null, then replace that + // element with the new value in the DOM, as if the root element's + // replaceChild() method had been called with the new value and the + // incumbent body element as its two arguments respectively, then
+            // abort these steps."
+ // TODO(kpreid): should be internal .documentElement getter only
+            var htmlEl = this.documentElement;
+            if (currentBody !== null) {
+              htmlEl.replaceChild(newBody, currentBody);
+              return;
+            }
+            // "Otherwise, if there is no root element, throw a
+            // HierarchyRequestError exception and abort these steps."
+            if (!htmlEl) {
+              // should be HierarchyRequestError
+              throw new Error(
+                  'Cannot set document.body with no <html>.');
+            }
+ // "Otherwise, the body element is null, but there's a root element.
+            // Append the new value to the root element."
+            htmlEl.appendChild(newBody);
+          })
+        },
         documentElement: {
           enumerable: true,
           get: innocuous(function() {
=======================================
--- /trunk/tests/com/google/caja/plugin/es53-test-domado-global.js Wed May 15 14:13:15 2013 +++ /trunk/tests/com/google/caja/plugin/es53-test-domado-global.js Wed May 22 14:02:57 2013
@@ -162,7 +162,21 @@
           '      document.getElementsByTagName("head")[0].innerHTML);' +
           '};</script>');

-      // TODO(kpreid): Test document.body
+      // Behavior of document.body without any *document* element present.
+      registerGuestTest('testNoElementBodyProp',
+          '<body>old body' +
+          '<script>window.globalGuestTest =' +
+          '    function globalGuestTest() {' +
+          '  document.removeChild(document.documentElement);' +
+          '  assertTrue("null", null === document.body);' +
+          '  var newBody = document.createElement("body");' +
+          '  expectFailure(function() { document.body = newBody; });' +
+          '  document.appendChild(document.createElement("html"));' +
+          '  document.body = newBody;' +
+          '  assertEquals(document.documentElement.innerHTML, ' +
+          '    "<body></body>");' +
+          '  assertTrue("final body", document.body === newBody);' +
+          '};</script>');
     })();

     /**

--

--- 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.


Reply via email to