diff options
author | mbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-12 17:03:48 +0000 |
---|---|---|
committer | mbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-12 17:03:48 +0000 |
commit | 3632c58208e0dc2d93fd5450bcd9c731fecb555f (patch) | |
tree | 94b72c71f4bec13af7acfaeab06737d1d416d525 /webkit/port/bindings/v8/v8_custom.cpp | |
parent | 34591ebee0bdd1f1062c0f340b53641f10280f54 (diff) | |
download | chromium_src-3632c58208e0dc2d93fd5450bcd9c731fecb555f.zip chromium_src-3632c58208e0dc2d93fd5450bcd9c731fecb555f.tar.gz chromium_src-3632c58208e0dc2d93fd5450bcd9c731fecb555f.tar.bz2 |
Changes to unfork DOMWindow.
* Unfork some of the DOMWindow.idl.
Required small changes to the idl parser.
* Move DOMWindow related functions from v8_custom.cpp into Webkit's V8DOMWindowCustom
(see separate CL for the Webkit tree)
* Moves timers from DOMWindow code into the Webkit DOMTimer code.
* Removed a couple of junker methods (forward()/back()) from the IDL. I think they were not needed.
NOTE:
This is dependent on a webkit-tree change. Will roll deps in order to test this.
Review URL: http://codereview.chromium.org/21262
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9657 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/bindings/v8/v8_custom.cpp')
-rw-r--r-- | webkit/port/bindings/v8/v8_custom.cpp | 679 |
1 files changed, 29 insertions, 650 deletions
diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp index 5001a4a..4a3f392 100644 --- a/webkit/port/bindings/v8/v8_custom.cpp +++ b/webkit/port/bindings/v8/v8_custom.cpp @@ -55,6 +55,7 @@ #include "Console.h" #include "DOMParser.h" #include "DOMStringList.h" +#include "DOMTimer.h" #include "DOMWindow.h" #include "Document.h" #include "DocumentFragment.h" @@ -65,9 +66,7 @@ #include "FloatRect.h" #include "Frame.h" #include "FrameLoader.h" -#include "FrameLoadRequest.h" #include "FrameTree.h" -#include "FrameView.h" #include "HTMLBodyElement.h" #include "HTMLCanvasElement.h" #include "HTMLDocument.h" @@ -93,20 +92,17 @@ #include "MouseEvent.h" #include "NodeIterator.h" #include "NodeList.h" -#include "Page.h" -#include "PlatformScreen.h" #include "RGBColor.h" #include "RenderPartObject.h" #include "RenderWidget.h" #include "ScheduledAction.h" #include "ScriptState.h" #include "ScriptController.h" +#include "ScriptSourceCode.h" #include "SecurityOrigin.h" -#include "Settings.h" #include "StyleSheetList.h" #include "TreeWalker.h" #include "WebKitCSSMatrix.h" -#include "WindowFeatures.h" #include "XMLSerializer.h" #include "XPathEvaluator.h" #include "XPathResult.h" @@ -121,10 +117,6 @@ #include "Navigator.h" -// Horizontal and vertical offset, from the parent content area, around newly -// opened popups that don't specify a location. -static const int kPopupTilePixels = 10; - namespace WebCore { class V8ScheduledAction : public ScheduledAction { @@ -134,18 +126,19 @@ class V8ScheduledAction : public ScheduledAction { explicit V8ScheduledAction(const WebCore::String& code) : m_argc(0), m_argv(0), m_code(code) { } virtual ~V8ScheduledAction(); - virtual void execute(DOMWindow* window); + virtual void execute(ScriptExecutionContext* window); private: v8::Persistent<v8::Function> m_func; int m_argc; v8::Persistent<v8::Value>* m_argv; - String m_code; + ScriptSourceCode m_code; }; V8ScheduledAction::V8ScheduledAction(v8::Handle<v8::Function> func, int argc, - v8::Handle<v8::Value> argv[]) { + v8::Handle<v8::Value> argv[]) + : m_code(String(), KURL(), 0) { m_func = v8::Persistent<v8::Function>::New(func); #ifndef NDEBUG @@ -188,31 +181,30 @@ V8ScheduledAction::~V8ScheduledAction() { } -void V8ScheduledAction::execute(DOMWindow* window) { +void V8ScheduledAction::execute(ScriptExecutionContext* script_context) { // TODO(ager): Timeouts for running the javascript code are not set. - Frame* frame = window->frame(); - if (!frame) return; + V8Proxy* proxy = V8Proxy::retrieve(script_context); + if (!proxy) return; v8::HandleScope handle_scope; - v8::Local<v8::Context> context = V8Proxy::GetContext(frame); + v8::Local<v8::Context> context = proxy->GetContext(); if (context.IsEmpty()) return; // JS may not be enabled. v8::Context::Scope scope(context); - V8Proxy* proxy = V8Proxy::retrieve(frame); proxy->setTimerCallback(true); if (!m_func.IsEmpty() && m_func->IsFunction()) { proxy->CallFunction(v8::Persistent<v8::Function>::Cast(m_func), context->Global(), m_argc, m_argv); } else { - // TODO: why cannot just compile and run m_code? - // check what's in V8Proxy::Evaluate - frame->loader()->executeScript(m_code); + proxy->Evaluate(m_code.url(), m_code.startLine() - 1, m_code.source(), 0); } - if (Document* doc = frame->document()) + if (script_context->isDocument()) { + Document* doc = static_cast<Document*>(script_context); doc->updateRendering(); + } proxy->setTimerCallback(false); } @@ -531,45 +523,8 @@ ACCESSOR_SETTER(DocumentLocation) { return; DOMWindow* window = imp->frame()->domWindow(); - // DOMWindow::setLocation does security checks. - window->setLocation(ToWebCoreString(value)); -} - - -ACCESSOR_SETTER(DOMWindowLocation) { - v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper( - V8ClassIndex::DOMWINDOW, info.This()); - if (holder.IsEmpty()) - return; - - DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, holder); - imp->setLocation(ToWebCoreString(value)); -} - - -ACCESSOR_SETTER(DOMWindowOpener) { - DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, info.Holder()); - - if (!V8Proxy::CanAccessFrame(imp->frame(), true)) - return; - - // Opener can be shadowed if it is in the same domain. - // Have a special handling of null value to behave - // like Firefox. See bug 1224887 & 791706. - if (value->IsNull()) { - // imp->frame() cannot be null, - // otherwise, SameOrigin check would have failed. - ASSERT(imp->frame()); - imp->frame()->loader()->setOpener(0); - } - - // Delete the accessor from this object. - info.Holder()->Delete(name); - - // Put property on the front (this) object. - info.This()->Set(name, value); + // WindowSetLocation does security checks. // XXXMB- verify! + WindowSetLocation(window, ToWebCoreString(value)); } @@ -642,580 +597,6 @@ CALLBACK_FUNC_DECL(DOMStringListItem) { } -CALLBACK_FUNC_DECL(DOMWindowAddEventListener) { - INC_STATS("DOM.DOMWindow.addEventListener()"); - DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, args.Holder()); - - if (!V8Proxy::CanAccessFrame(imp->frame(), true)) - return v8::Undefined(); - - if (!imp->frame()) - return v8::Undefined(); // DOMWindow could be disconnected from the frame - - Document* doc = imp->frame()->document(); - if (!doc) - return v8::Undefined(); - - // TODO: Check if there is not enough arguments - V8Proxy* proxy = V8Proxy::retrieve(imp->frame()); - if (!proxy) - return v8::Undefined(); - - RefPtr<EventListener> listener = - proxy->FindOrCreateV8EventListener(args[1], false); - - if (listener) { - String event_type = ToWebCoreString(args[0]); - bool useCapture = args[2]->BooleanValue(); - doc->addWindowEventListener(event_type, listener, useCapture); - } - - return v8::Undefined(); -} - - -CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener) { - INC_STATS("DOM.DOMWindow.removeEventListener()"); - DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, args.Holder()); - - if (!V8Proxy::CanAccessFrame(imp->frame(), true)) - return v8::Undefined(); - - if (!imp->frame()) - return v8::Undefined(); - - Document* doc = imp->frame()->document(); - if (!doc) - return v8::Undefined(); - - V8Proxy* proxy = V8Proxy::retrieve(imp->frame()); - if (!proxy) - return v8::Undefined(); - - RefPtr<EventListener> listener = - proxy->FindV8EventListener(args[1], false); - - if (listener) { - String event_type = ToWebCoreString(args[0]); - bool useCapture = args[2]->BooleanValue(); - doc->removeWindowEventListener(event_type, listener.get(), useCapture); - } - - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(DOMWindowPostMessage) { - INC_STATS("DOM.DOMWindow.postMessage()"); - DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, args.Holder()); - - DOMWindow* source = V8Proxy::retrieveActiveFrame()->domWindow(); - ASSERT(source->frame()); - - String uri = source->frame()->loader()->url().string(); - - v8::TryCatch try_catch; - - String message = ToWebCoreString(args[0]); - MessagePort* port = NULL; - String domain; - - // This function has variable arguments and can either be: - // postMessage(message, port, domain); - // or - // postMessage(message, domain); - if (args.Length() > 2) { - if (V8Proxy::IsWrapperOfType(args[1], V8ClassIndex::MESSAGEPORT)) { - port = V8Proxy::ToNativeObject<MessagePort>( - V8ClassIndex::MESSAGEPORT, args[1]); - } - domain = valueToStringWithNullOrUndefinedCheck(args[2]); - } else { - domain = valueToStringWithNullOrUndefinedCheck(args[1]); - } - - if (try_catch.HasCaught()) return v8::Undefined(); - - ExceptionCode ec = 0; - window->postMessage(message, port, domain, source, ec); - if (ec) - V8Proxy::SetDOMException(ec); - - return v8::Undefined(); -} - -static bool canShowModalDialogNow(const Frame* frame) { - // A frame can out live its page. See bug 1219613. - if (!frame || !frame->page()) - return false; - return frame->page()->chrome()->canRunModalNow(); -} - -static bool allowPopUp() { - Frame* frame = V8Proxy::retrieveActiveFrame(); - - ASSERT(frame); - if (frame->script()->processingUserGesture()) return true; - Settings* settings = frame->settings(); - return settings && settings->JavaScriptCanOpenWindowsAutomatically(); -} - -static HashMap<String, String> parseModalDialogFeatures( - const String& features_arg) { - HashMap<String, String> map; - - Vector<String> features; - features_arg.split(';', features); - Vector<String>::const_iterator end = features.end(); - for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) { - String s = *it; - int pos = s.find('='); - int colonPos = s.find(':'); - if (pos >= 0 && colonPos >= 0) - continue; // ignore any strings that have both = and : - if (pos < 0) - pos = colonPos; - if (pos < 0) { - // null string for value means key without value - map.set(s.stripWhiteSpace().lower(), String()); - } else { - String key = s.left(pos).stripWhiteSpace().lower(); - String val = s.substring(pos + 1).stripWhiteSpace().lower(); - int spacePos = val.find(' '); - if (spacePos != -1) - val = val.left(spacePos); - map.set(key, val); - } - } - - return map; -} - - -static Frame* createWindow(Frame* opener_frame, - const String& url, - const String& frame_name, - const WindowFeatures& window_features, - v8::Local<v8::Value> dialog_args) { - Frame* active_frame = V8Proxy::retrieveActiveFrame(); - - ResourceRequest request; - if (active_frame) - request.setHTTPReferrer(active_frame->loader()->outgoingReferrer()); - FrameLoadRequest frame_request(request, frame_name); - - // FIXME: It's much better for client API if a new window starts with a URL, - // here where we know what URL we are going to open. Unfortunately, this code - // passes the empty string for the URL, but there's a reason for that. - // Before loading we have to set up the opener, openedByDOM, - // and dialogArguments values. Also, to decide whether to use the URL - // we currently do an allowsAccessFrom call using the window we create, - // which can't be done before creating it. We'd have to resolve all those - // issues to pass the URL instead of "". - - bool created; - // We pass in the opener frame here so it can be used for looking up the frame - // name, in case the active frame is different from the opener frame, and - // the name references a frame relative to the opener frame, for example - // "_self" or "_parent". - Frame* new_frame = active_frame->loader()->createWindow( - opener_frame->loader(), frame_request, window_features, created); - if (!new_frame) - return 0; - - new_frame->loader()->setOpener(opener_frame); - new_frame->loader()->setOpenedByDOM(); - - // Set dialog arguments on the global object of the new frame. - if (!dialog_args.IsEmpty()) { - v8::Local<v8::Context> context = V8Proxy::GetContext(new_frame); - if (!context.IsEmpty()) { - v8::Context::Scope scope(context); - context->Global()->Set(v8::String::New("dialogArguments"), dialog_args); - } - } - - if (!parseURL(url).startsWith("javascript:", false) || - ScriptController::isSafeScript(new_frame)) { - KURL completed_url = - url.isEmpty() ? KURL("") : active_frame->document()->completeURL(url); - bool user_gesture = active_frame->script()->processingUserGesture(); - - if (created) { - new_frame->loader()->changeLocation( - completed_url, - active_frame->loader()->outgoingReferrer(), - false, - user_gesture); - } else if (!url.isEmpty()) { - new_frame->loader()->scheduleLocationChange( - completed_url.string(), - active_frame->loader()->outgoingReferrer(), - false, - user_gesture); - } - } - - return new_frame; -} - - -CALLBACK_FUNC_DECL(DOMWindowShowModalDialog) { - INC_STATS("DOM.DOMWindow.showModalDialog()"); - DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, args.Holder()); - Frame* frame = window->frame(); - - if (!frame || !V8Proxy::CanAccessFrame(frame, true)) - return v8::Undefined(); - - if (!canShowModalDialogNow(frame) || !allowPopUp()) - return v8::Undefined(); - - String url = valueToStringWithNullOrUndefinedCheck(args[0]); - v8::Local<v8::Value> dialog_args = args[1]; - String feature_args = valueToStringWithNullOrUndefinedCheck(args[2]); - - const HashMap<String, String> features = - parseModalDialogFeatures(feature_args); - - const bool trusted = false; - - FloatRect screenRect = screenAvailableRect(frame->view()); - - WindowFeatures wargs; - // default here came from frame size of dialog in MacIE. - wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, - screenRect.width(), 620); - wargs.widthSet = true; - // default here came from frame size of dialog in MacIE. - wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, - screenRect.height(), 450); - wargs.heightSet = true; - - wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), - screenRect.right() - wargs.width, - -1); - wargs.xSet = wargs.x > 0; - wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), - screenRect.bottom() - wargs.height, - -1); - wargs.ySet = wargs.y > 0; - - if (WindowFeatures::boolFeature(features, "center", true)) { - if (!wargs.xSet) { - wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; - wargs.xSet = true; - } - if (!wargs.ySet) { - wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; - wargs.ySet = true; - } - } - - wargs.dialog = true; - wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); - wargs.scrollbarsVisible = - WindowFeatures::boolFeature(features, "scroll", true); - wargs.statusBarVisible = - WindowFeatures::boolFeature(features, "status", !trusted); - wargs.menuBarVisible = false; - wargs.toolBarVisible = false; - wargs.locationBarVisible = false; - wargs.fullscreen = false; - - Frame* dialog_frame = createWindow(frame, url, "", wargs, dialog_args); - if (!dialog_frame) - return v8::Undefined(); - - // Hold on to the context of the dialog window long enough to retrieve the - // value of the return value property. - v8::Local<v8::Context> context = V8Proxy::GetContext(dialog_frame); - - // Run the dialog. - dialog_frame->page()->chrome()->runModal(); - - // Extract the return value property from the dialog window. - v8::Local<v8::Value> return_value; - if (!context.IsEmpty()) { - v8::Context::Scope scope(context); - return_value = context->Global()->Get(v8::String::New("returnValue")); - } - - if (!return_value.IsEmpty()) { - return return_value; - } - - return v8::Undefined(); -} - - -CALLBACK_FUNC_DECL(DOMWindowOpen) { - INC_STATS("DOM.DOMWindow.open()"); - DOMWindow* parent = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, args.Holder()); - Frame* frame = parent->frame(); - - if (!V8Proxy::CanAccessFrame(frame, true)) - return v8::Undefined(); - - Frame* active_frame = V8Proxy::retrieveActiveFrame(); - if (!active_frame) - return v8::Undefined(); - - Page* page = frame->page(); - if (!page) - return v8::Undefined(); - - String url_string = valueToStringWithNullOrUndefinedCheck(args[0]); - AtomicString frame_name = (args[1]->IsUndefined() || args[1]->IsNull()) ? - "_blank" : AtomicString(ToWebCoreString(args[1])); - - // Because FrameTree::find() returns true for empty strings, we must check - // for empty framenames. Otherwise, illegitimate window.open() calls with - // no name will pass right through the popup blocker. - if (!allowPopUp() && - (frame_name.isEmpty() || - !frame->tree()->find(frame_name))) { - return v8::Undefined(); - } - - // Get the target frame for the special cases of _top and _parent. In those - // cases, we can schedule a location change right now and return early. - bool top_or_parent = false; - if (frame_name == "_top") { - frame = frame->tree()->top(); - top_or_parent = true; - } else if (frame_name == "_parent") { - if (Frame* parent = frame->tree()->parent()) { - frame = parent; - } - top_or_parent = true; - } - if (top_or_parent) { - if (!active_frame->loader()->shouldAllowNavigation(frame)) { - return v8::Undefined(); - } - - String completed_url; - if (!url_string.isEmpty()) { - completed_url = active_frame->document()->completeURL(url_string); - } - - if (!completed_url.isEmpty() && - (!parseURL(url_string).startsWith("javascript:", false) || - ScriptController::isSafeScript(frame))) { - bool user_gesture = active_frame->script()->processingUserGesture(); - frame->loader()->scheduleLocationChange( - completed_url, - active_frame->loader()->outgoingReferrer(), - false, - user_gesture); - } - return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow()); - } - - // In the case of a named frame or a new window, we'll use the createWindow() - // helper. - - // Parse the values, and then work with a copy of the parsed values - // so we can restore the values we may not want to overwrite after - // we do the multiple monitor fixes. - WindowFeatures raw_features( - valueToStringWithNullOrUndefinedCheck(args[2])); - WindowFeatures window_features(raw_features); - FloatRect screen_rect = screenAvailableRect(page->mainFrame()->view()); - - // Set default size and location near parent window if none were specified. - // These may be further modified by adjustWindowRect, below. - if (!window_features.xSet) { - window_features.x = parent->screenX() - screen_rect.x() + kPopupTilePixels; - window_features.xSet = true; - } - if (!window_features.ySet) { - window_features.y = parent->screenY() - screen_rect.y() + kPopupTilePixels; - window_features.ySet = true; - } - if (!window_features.widthSet) { - window_features.width = parent->innerWidth(); - window_features.widthSet = true; - } - if (!window_features.heightSet) { - window_features.height = parent->innerHeight(); - window_features.heightSet = true; - } - - FloatRect window_rect(window_features.x, window_features.y, - window_features.width, window_features.height); - - // The new window's location is relative to its current screen, so shift - // it in case it's on a secondary monitor. See http://b/viewIssue?id=967905. - window_rect.move(screen_rect.x(), screen_rect.y()); - WebCore::DOMWindow::adjustWindowRect(screen_rect, window_rect, window_rect); - - window_features.x = window_rect.x(); - window_features.y = window_rect.y(); - window_features.height = window_rect.height(); - window_features.width = window_rect.width(); - - // If either of the origin coordinates weren't set in the original - // string, make sure they aren't set now. - if (!raw_features.xSet) { - window_features.x = 0; - window_features.xSet = false; - } - if (!raw_features.ySet) { - window_features.y = 0; - window_features.ySet = false; - } - - frame = createWindow(frame, url_string, frame_name, - window_features, v8::Local<v8::Value>()); - - if (!frame) return v8::Undefined(); - - return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow()); -} - - -INDEXED_PROPERTY_GETTER(DOMWindow) { - INC_STATS("DOM.DOMWindow.IndexedPropertyGetter"); - v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper( - V8ClassIndex::DOMWINDOW, info.This()); - if (holder.IsEmpty()) - return v8::Handle<v8::Value>(); - - DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, holder); - if (!window) - return v8::Handle<v8::Value>(); - - Frame* frame = window->frame(); - if (!frame) - return v8::Handle<v8::Value>(); - - Frame* child = frame->tree()->child(index); - if (child) { - return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow()); - } - - return v8::Handle<v8::Value>(); -} - - -NAMED_PROPERTY_GETTER(DOMWindow) { - INC_STATS("DOM.DOMWindow.NamedPropertyGetter"); - // The key must be a string. - if (!name->IsString()) - return v8::Handle<v8::Value>(); - - v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper( - V8ClassIndex::DOMWINDOW, info.This()); - if (holder.IsEmpty()) - return v8::Handle<v8::Value>(); - - DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>( - V8ClassIndex::DOMWINDOW, holder); - if (!window) - return v8::Handle<v8::Value>(); - - String prop_name = ToWebCoreString(name); - - Frame* frame = window->frame(); - // window is detached from a frame. - if (!frame) - return v8::Handle<v8::Value>(); - - // Search sub-frames. - Frame* child = frame->tree()->child(prop_name); - if (child) - return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow()); - - // Search IDL functions defined in the prototype - v8::Handle<v8::Value> result = - holder->GetRealNamedPropertyInPrototypeChain(name); - if (!result.IsEmpty()) - return result; - - // Lazy initialization map keeps global properties that can be lazily - // initialized. The value is the code to instantiate the property. - // It must return the value of property after initialization. - static HashMap<String, String> kLazyInitMap; - if (kLazyInitMap.isEmpty()) { - // "new Image()" does not appear to be well-defined in a spec, but Safari, - // Opera, and Firefox all consider it to always create an HTML image - // element, regardless of the current doctype. - kLazyInitMap.set("Image", - "function Image() { \ - return document.createElementNS( \ - 'http://www.w3.org/1999/xhtml', 'img'); \ - }; \ - Image"); - kLazyInitMap.set("Option", - "function Option(text, value, defaultSelected, selected) { \ - var option = document.createElement('option'); \ - if (text == null) return option; \ - option.text = text; \ - if (value == null) return option; \ - option.value = value; \ - if (defaultSelected == null) return option; \ - option.defaultSelected = defaultSelected; \ - if (selected == null) return option; \ - option.selected = selected; \ - return option; \ - }; \ - Option"); - } - - String code = kLazyInitMap.get(prop_name); - if (!code.isEmpty()) { - v8::Local<v8::Context> context = V8Proxy::GetContext(window->frame()); - // Bail out if we cannot get the context for the frame. - if (context.IsEmpty()) return v8::Handle<v8::Value>(); - - // switch to the target object's environment. - v8::Context::Scope scope(context); - - // Set the property name to undefined to make sure that the - // property exists. This is necessary because this getter - // might be called when evaluating 'var RangeException = value' - // to figure out if we have a property named 'RangeException' before - // we set RangeException to the new value. In that case, we will - // evaluate 'var RangeException = {}' and enter an infinite loop. - // Setting the property name to undefined on the global object - // ensures that we do not have to ask this getter to figure out - // that we have the property. - // - // TODO(ager): We probably should implement the Has method - // for the interceptor instead of using the default Has method - // that calls Get. - context->Global()->Set(v8String(prop_name), v8::Undefined()); - V8Proxy* proxy = V8Proxy::retrieve(window->frame()); - ASSERT(proxy); - - v8::Local<v8::Value> result = proxy->Evaluate(prop_name, 0, code, 0); - return result; - } - - // Search named items in the document. - Document* doc = frame->document(); - if (doc) { - RefPtr<HTMLCollection> items = doc->windowNamedItems(prop_name); - if (items->length() >= 1) { - if (items->length() == 1) { - return V8Proxy::NodeToV8Object(items->firstItem()); - } else { - return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, items.get()); - } - } - } - - return v8::Handle<v8::Value>(); -} - - NAMED_PROPERTY_DELETER(HTMLDocument) { // Only handle document.all. Insert the marker object into the // shadow internal field to signal that document.all is no longer @@ -2392,6 +1773,9 @@ ACCESSOR_SETTER(HTMLIFrameElementSrc) { } +// TODO(mbelshe): This should move into V8DOMWindowCustom.cpp +// Can't move it right now because it depends on V8ScheduledAction, +// which is private to this file (v8_custom.cpp). v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, bool single_shot) { int num_arguments = args.Length(); @@ -2401,9 +1785,15 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( V8ClassIndex::DOMWINDOW, args.Holder()); + if (!imp->frame()) + return v8::Undefined(); + if (!V8Proxy::CanAccessFrame(imp->frame(), true)) return v8::Undefined(); + ScriptExecutionContext* script_context = + static_cast<ScriptExecutionContext*>(imp->frame()->document()); + v8::Handle<v8::Value> function = args[0]; int32_t timeout = 0; @@ -2417,8 +1807,9 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, if (string_function.length() == 0) return v8::Undefined(); - id = imp->installTimeout(new V8ScheduledAction(string_function), - timeout, single_shot); + id = DOMTimer::install(script_context, + new V8ScheduledAction(string_function), timeout, + single_shot); } else if (function->IsFunction()) { int param_count = num_arguments >= 2 ? num_arguments - 2 : 0; v8::Local<v8::Value>* params = 0; @@ -2435,7 +1826,7 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, delete[] params; - id = imp->installTimeout(action, timeout, single_shot); + id = DOMTimer::install(script_context, action, timeout, single_shot); } else { // TODO(fqian): what's the right return value if failed. return v8::Undefined(); @@ -2444,18 +1835,6 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, } -CALLBACK_FUNC_DECL(DOMWindowSetTimeout) { - INC_STATS("DOM.DOMWindow.setTimeout()"); - return WindowSetTimeoutImpl(args, true); -} - - -CALLBACK_FUNC_DECL(DOMWindowSetInterval) { - INC_STATS("DOM.DOMWindow.setInterval()"); - return WindowSetTimeoutImpl(args, false); -} - - // HTMLDocument ---------------------------------------------------------------- // Concatenates "args" to a string. If args is empty, returns empty string. |