diff options
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 |