summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webkit/data/layout_tests/chrome/fast/dom/resources/wrapper-context-inner.html28
-rw-r--r--webkit/data/layout_tests/chrome/fast/dom/wrapper-context-expected.txt1
-rw-r--r--webkit/data/layout_tests/chrome/fast/dom/wrapper-context.html33
-rw-r--r--webkit/port/bindings/v8/v8_custom.cpp10
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp18
5 files changed, 86 insertions, 4 deletions
diff --git a/webkit/data/layout_tests/chrome/fast/dom/resources/wrapper-context-inner.html b/webkit/data/layout_tests/chrome/fast/dom/resources/wrapper-context-inner.html
new file mode 100644
index 0000000..c47aa6e
--- /dev/null
+++ b/webkit/data/layout_tests/chrome/fast/dom/resources/wrapper-context-inner.html
@@ -0,0 +1,28 @@
+<html>
+<body onload="RunTest()">
+<script>
+// Used from the top frame to know when this frame has been loaded.
+var loaded = false;
+
+// After the top frame has accessed the document of this frame, we
+// test that the document wrapper was created in this context and
+// not in the top context.
+function RunTest() {
+ loaded = true;
+ if (top.innerDocument) {
+ var paragraph = document.createElement('p');
+ if (HTMLElement.prototype.isPrototypeOf(paragraph)) {
+ top.WriteOutput("PASS");
+ } else {
+ top.WriteOutput("FAIL");
+ }
+ if (window.layoutTestController) {
+ layoutTestController.notifyDone();
+ }
+ } else {
+ setTimeout(RunTest, 100);
+ }
+}
+</script>
+</body>
+</html>
diff --git a/webkit/data/layout_tests/chrome/fast/dom/wrapper-context-expected.txt b/webkit/data/layout_tests/chrome/fast/dom/wrapper-context-expected.txt
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/webkit/data/layout_tests/chrome/fast/dom/wrapper-context-expected.txt
@@ -0,0 +1 @@
+PASS
diff --git a/webkit/data/layout_tests/chrome/fast/dom/wrapper-context.html b/webkit/data/layout_tests/chrome/fast/dom/wrapper-context.html
new file mode 100644
index 0000000..3f038d8
--- /dev/null
+++ b/webkit/data/layout_tests/chrome/fast/dom/wrapper-context.html
@@ -0,0 +1,33 @@
+<html>
+<body onload="AccessInnerDocument()">
+<div id="output"></div>
+<iframe id="inner" src="resources/wrapper-context-inner.html"></iframe>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+}
+
+// Write to the output div.
+function WriteOutput(s) {
+ var paragraph = document.createElement("p");
+ paragraph.innerHTML = s;
+ document.getElementById("output").appendChild(paragraph);
+}
+
+// Used from the inner frame to know when this frame has accessed
+// the document of the inner frame.
+var innerDocument;
+
+// Once the inner frame has loaded, access it's document and assign
+// the wrapper to innerDocument.
+function AccessInnerDocument() {
+ if (inner.loaded) {
+ innerDocument = inner.document;
+ } else {
+ setTimeout(AccessInnerDocument, 100);
+ }
+}
+</script>
+</body>
+</html>
diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp
index 78a0160..9e70dd6 100644
--- a/webkit/port/bindings/v8/v8_custom.cpp
+++ b/webkit/port/bindings/v8/v8_custom.cpp
@@ -2600,16 +2600,18 @@ static String WriteHelper_GetString(const v8::Arguments& args) {
CALLBACK_FUNC_DECL(HTMLDocumentWrite) {
INC_STATS(L"DOM.HTMLDocument.write()");
HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
- imp->write(WriteHelper_GetString(args),
- V8Proxy::retrieveWindow()->document());
+ Frame* frame = V8Proxy::retrieveActiveFrame();
+ ASSERT(frame);
+ imp->write(WriteHelper_GetString(args), frame->document());
return v8::Undefined();
}
CALLBACK_FUNC_DECL(HTMLDocumentWriteln) {
INC_STATS(L"DOM.HTMLDocument.writeln()");
HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
- imp->writeln(WriteHelper_GetString(args),
- V8Proxy::retrieveWindow()->document());
+ Frame* frame = V8Proxy::retrieveActiveFrame();
+ ASSERT(frame);
+ imp->writeln(WriteHelper_GetString(args), frame->document());
return v8::Undefined();
}
diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp
index a30231a..0857184 100644
--- a/webkit/port/bindings/v8/v8_proxy.cpp
+++ b/webkit/port/bindings/v8/v8_proxy.cpp
@@ -2390,10 +2390,28 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) {
type = V8ClassIndex::NODE;
}
+ // Find the context to which the node belongs and create the wrapper
+ // in that context. If the node is not in a document, the current
+ // context is used.
+ v8::Local<v8::Context> context;
+ Document* doc = node->document();
+ if (doc) {
+ context = V8Proxy::GetContext(doc->frame());
+ }
+ if (!context.IsEmpty()) {
+ context->Enter();
+ }
+
// Set the peer object for future access.
// InstantiateV8Object automatically casts node to Peerable*.
v8::Local<v8::Object> result =
InstantiateV8Object(type, V8ClassIndex::NODE, node);
+
+ // Exit the node's context if it was entered.
+ if (!context.IsEmpty()) {
+ context->Exit();
+ }
+
if (result.IsEmpty()) {
// If instantiation failed it's important not to add the result
// to the DOM node map. Instead we return an empty handle, which