From ba7fc34c9a390734a761d0aa13464a84919e2a78 Mon Sep 17 00:00:00 2001 From: Roger WANG Date: Fri, 26 Apr 2013 13:40:01 +0800 Subject: [PATCH] nwfaketop: Fix for more cases The following should be emulated as a top level window: "_top" navigation target window.frameElement location.ancestorOrigins see the comments in rogerwang/node-webkit#534 --- .../bindings/v8/custom/V8DOMWindowCustom.cpp | 21 ++++++++++++++++--- Source/WebCore/page/DOMWindow.cpp | 4 ++-- Source/WebCore/page/DOMWindow.idl | 2 +- Source/WebCore/page/FrameTree.cpp | 16 ++++++++++---- Source/WebCore/page/Location.cpp | 7 +++++-- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp index 4a128857f10..501352488f3 100644 --- a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp @@ -61,6 +61,7 @@ #include "V8GCForContextDispose.h" #include "V8HiddenPropertyName.h" #include "V8HTMLCollection.h" +#include "V8HTMLFrameElement.h" #include "V8Node.h" #include "V8Utilities.h" #include "WindowFeatures.h" @@ -156,15 +157,29 @@ v8::Handle V8DOMWindow::parentAttrGetterCustom(v8::Local } v8::Handle V8DOMWindow::topAttrGetterCustom(v8::Local name, const v8::AccessorInfo& info) +{ + DOMWindow* imp = V8DOMWindow::toNative(info.Holder()); + Frame* frame = imp->frame(); + for (Frame* f = frame; f; f = f->tree()->parent()) { + if (f->isNwFakeTop()) + return toV8Fast(f->document()->domWindow(), info, imp); + } + return toV8Fast(imp->top(), info, imp); +} + +v8::Handle V8DOMWindow::frameElementAttrGetterCustom(v8::Local name, const v8::AccessorInfo& info) { DOMWindow* imp = V8DOMWindow::toNative(info.Holder()); Frame* frame = imp->frame(); if (frame->isNwFakeTop()) - return toV8Fast(imp, info, imp); - else - return toV8Fast(imp->top(), info, imp); + return v8::Handle(v8Null(info.GetIsolate())); + if (!BindingSecurity::shouldAllowAccessToNode(BindingState::instance(), imp->frameElement())) + return v8::Handle(v8Null(info.GetIsolate())); + + return toV8Fast(imp->frameElement(), info, imp); } + v8::Handle V8DOMWindow::eventAttrGetterCustom(v8::Local name, const v8::AccessorInfo& info) { v8::Handle holder = info.This()->FindInstanceInPrototypeChain(V8DOMWindow::GetTemplate(info.GetIsolate(), worldTypeInMainThread(info.GetIsolate()))); diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp index 99071dff1d0..1a26590ec37 100644 --- a/Source/WebCore/page/DOMWindow.cpp +++ b/Source/WebCore/page/DOMWindow.cpp @@ -1935,10 +1935,10 @@ PassRefPtr DOMWindow::open(const String& urlString, const AtomicStrin // In those cases, we schedule a location change right now and return early. Frame* targetFrame = 0; if (frameName == "_top") - targetFrame = m_frame->tree()->top(); + targetFrame = m_frame->isNwFakeTop() ? m_frame : m_frame->tree()->top(); else if (frameName == "_parent") { if (Frame* parent = m_frame->tree()->parent()) - targetFrame = parent; + targetFrame = m_frame->isNwFakeTop() ? m_frame : parent; else targetFrame = m_frame; } diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl index 76eb02c390d..9543c97b278 100644 --- a/Source/WebCore/page/DOMWindow.idl +++ b/Source/WebCore/page/DOMWindow.idl @@ -62,7 +62,7 @@ DOMSelection getSelection(); - readonly attribute [CheckSecurityForNode] Element frameElement; + readonly attribute [CheckSecurityForNode, V8CustomGetter] Element frameElement; [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void focus(); [DoNotCheckSecurity] void blur(); diff --git a/Source/WebCore/page/FrameTree.cpp b/Source/WebCore/page/FrameTree.cpp index 1e0afe1ddc7..1975d7e11f8 100644 --- a/Source/WebCore/page/FrameTree.cpp +++ b/Source/WebCore/page/FrameTree.cpp @@ -257,12 +257,20 @@ Frame* FrameTree::find(const AtomicString& name) const { if (name == "_self" || name == "_current" || name.isEmpty()) return m_thisFrame; - - if (name == "_top") + + if (name == "_top") { + for (Frame* f = m_thisFrame; f; f = f->tree()->parent()) { + if (f->isNwFakeTop()) + return f; + } return top(); - - if (name == "_parent") + } + + if (name == "_parent") { + if (m_thisFrame->isNwFakeTop()) + return m_thisFrame; return parent() ? parent() : m_thisFrame; + } // Since "_blank" should never be any frame's name, the following just amounts to an optimization. if (name == "_blank") diff --git a/Source/WebCore/page/Location.cpp b/Source/WebCore/page/Location.cpp index 36b35c4dee3..9c43077c838 100644 --- a/Source/WebCore/page/Location.cpp +++ b/Source/WebCore/page/Location.cpp @@ -127,10 +127,13 @@ String Location::origin() const PassRefPtr Location::ancestorOrigins() const { RefPtr origins = DOMStringList::create(); - if (!m_frame) + if (!m_frame || m_frame->isNwFakeTop()) return origins.release(); - for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) + for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) { origins->append(frame->document()->securityOrigin()->toString()); + if (frame->isNwFakeTop()) + break; + } return origins.release(); }