diff options
author | ager@google.com <ager@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-03 10:49:10 +0000 |
---|---|---|
committer | ager@google.com <ager@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-03 10:49:10 +0000 |
commit | c3db21ff3446ac6bbb2d785c2441d0e5d5824bf5 (patch) | |
tree | 6bbd2100a39909cd94aa0a7f0e9fa43c6ca6ab05 /webkit | |
parent | 0eef7609fbb2c488aa821d60ac006d65fd359d68 (diff) | |
download | chromium_src-c3db21ff3446ac6bbb2d785c2441d0e5d5824bf5.zip chromium_src-c3db21ff3446ac6bbb2d785c2441d0e5d5824bf5.tar.gz chromium_src-c3db21ff3446ac6bbb2d785c2441d0e5d5824bf5.tar.bz2 |
Let's try this again. The regressions were caused by an incorrect use
of the current context instead of last entered context.
Create node wrappers in the context to which the nodes belong instead
of the context of the code accessing them. This fixes the issue where
the prototype library does not work if the JavaScript console is open.
Review URL: http://codereview.chromium.org/6442
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2826 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
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 |