Bug 1280362 - Make browser.js's print() function write into the page in a way that never sets innerHTML or uses document.write. r=arai

--HG--
extra : rebase_source : 8f0f8d928a6ee8c4a1c09dea89a9bdf34e314d42
This commit is contained in:
Jeff Walden 2016-07-27 22:13:23 -07:00
parent a2197e632c
commit 18af58d6c1
2 changed files with 44 additions and 9 deletions

View File

@ -19,17 +19,34 @@
var ReflectApply = global.Reflect.apply;
// BEWARE: ObjectGetOwnPropertyDescriptor is only safe to use if its result
// is inspected using own-property-examining functionality. Directly
// accessing properties on a returned descriptor without first
// verifying the property's existence can invoke user-modifiable
// behavior.
var ObjectGetOwnPropertyDescriptor = global.Object.getOwnPropertyDescriptor;
var document = global.document;
var documentBody = global.document.body;
var documentDocumentElement = global.document.documentElement;
var DocumentCreateElement = global.document.createElement;
var HTMLDocumentPrototypeWrite = global.HTMLDocument.prototype.write;
var ElementInnerHTMLSetter =
Object.getOwnPropertyDescriptor(global.Element.prototype, "innerHTML").set;
ObjectGetOwnPropertyDescriptor(global.Element.prototype, "innerHTML").set;
var HTMLIFramePrototypeContentWindowGetter =
Object.getOwnPropertyDescriptor(global.HTMLIFrameElement.prototype, "contentWindow").get;
ObjectGetOwnPropertyDescriptor(global.HTMLIFrameElement.prototype, "contentWindow").get;
var HTMLIFramePrototypeRemove = global.HTMLIFrameElement.prototype.remove;
var NodePrototypeAppendChild = global.Node.prototype.appendChild;
var NodePrototypeTextContentSetter =
ObjectGetOwnPropertyDescriptor(global.Node.prototype, "textContent").set;
// Cached DOM nodes used by the test harness itself. (We assume the test
// doesn't misbehave in a way that actively interferes with what the test
// harness runner observes, e.g. navigating the page to a different location.
// Short of running every test in a worker -- which has its own problems --
// there's no way to isolate a test from the page to that extent.)
var printOutputContainer =
global.document.getElementById("jsreftest-print-output-container");
/****************************
* GENERAL HELPER FUNCTIONS *
@ -47,6 +64,10 @@
ReflectApply(ElementInnerHTMLSetter, element, [html]);
}
function SetTextContent(element, text) {
ReflectApply(NodePrototypeTextContentSetter, element, [text]);
}
/****************************
* UTILITY FUNCTION EXPORTS *
****************************/
@ -81,6 +102,17 @@
}
}
global.DocumentWrite = DocumentWrite;
// This function is *only* used by this file's |print()| function! It's only
// defined/exported here because |print| is defined outside this IIFE and
// because it needs access to unadulterated functionality as originally
// defined when this IIFE executed.
function AddPrintOutput(s) {
var msgDiv = CreateElement("div");
SetTextContent(msgDiv, s);
AppendChild(printOutputContainer, msgDiv);
}
global.AddPrintOutput = AddPrintOutput;
})(this);
@ -143,9 +175,8 @@ function print() {
dump( s + '\n');
}
s = s.replace(/[<>&]/g, htmlesc);
DocumentWrite(s);
// AddPrintOutput doesn't require HTML special characters be escaped.
AddPrintOutput(s);
}
function writeHeaderToLog( string ) {

View File

@ -9,11 +9,15 @@
using the default script language attributes, then execute the
test.
-->
<script type="text/javascript" src="shell.js">
</script>
<script type="text/javascript" src="browser.js">
</script>
</head>
<body>
<!--
print() appends div-element children to this, so this div must appear
before all script elements.
-->
<div id="jsreftest-print-output-container"></div>
<script type="text/javascript" src="shell.js"></script>
<script type="text/javascript" src="browser.js"></script>
</body>
</html>