18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScriptController.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "ScriptableDocumentParser.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Event.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "FrameLoaderClient.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GCController.h"
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "HTMLPlugInElement.h"
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorInstrumentation.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDocument.h"
33e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "JSMainThreadExecState.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NP_jsobject.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PageGroup.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ScriptSourceCode.h"
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ScriptValue.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h"
40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "StorageNamespace.h"
4121939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "UserGestureIndicator.h"
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "WebCoreJSClientData.h"
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "npruntime_impl.h"
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "runtime_root.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <debugger/Debugger.h>
463a209a6ece975c026508762103516b7d0e55c18aSteve Block#include <runtime/InitializeThreading.h>
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <runtime/JSLock.h>
4821939df44de1705786c545cd1bf519d47250322dBen Murdoch#include <wtf/Threading.h>
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC;
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace std;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
553a209a6ece975c026508762103516b7d0e55c18aSteve Blockvoid ScriptController::initializeThreading()
563a209a6ece975c026508762103516b7d0e55c18aSteve Block{
573a209a6ece975c026508762103516b7d0e55c18aSteve Block    JSC::initializeThreading();
5821939df44de1705786c545cd1bf519d47250322dBen Murdoch    WTF::initializeMainThread();
593a209a6ece975c026508762103516b7d0e55c18aSteve Block}
603a209a6ece975c026508762103516b7d0e55c18aSteve Block
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectScriptController::ScriptController(Frame* frame)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_frame(frame)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sourceURL(0)
64cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    , m_inExecuteScript(false)
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_processingTimerCallback(false)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_paused(false)
675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_allowPopupsFromPlugin(false)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_windowScriptNPObject(0)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(MAC)
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_windowScriptObject(0)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7521939df44de1705786c545cd1bf519d47250322dBen Murdoch#if PLATFORM(MAC) && ENABLE(JAVA_BRIDGE)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool initializedJavaJSBindings;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!initializedJavaJSBindings) {
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initializedJavaJSBindings = true;
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initJavaJSBindings();
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectScriptController::~ScriptController()
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    disconnectPlatformScriptObjects();
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
88545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (m_cacheableBindingRootObject) {
89545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        m_cacheableBindingRootObject->invalidate();
90545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        m_cacheableBindingRootObject = 0;
91545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
92545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // It's likely that destroying m_windowShells will create a lot of garbage.
94cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!m_windowShells.isEmpty()) {
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        while (!m_windowShells.isEmpty())
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            destroyWindowShell(m_windowShells.begin()->first.get());
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gcController().garbageCollectSoon();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid ScriptController::destroyWindowShell(DOMWrapperWorld* world)
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(m_windowShells.contains(world));
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_windowShells.remove(world);
105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    world->didDestroyWindowShell(this);
106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSDOMWindowShell* ScriptController::createWindowShell(DOMWrapperWorld* world)
109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(!m_windowShells.contains(world));
1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    Strong<JSDOMWindowShell> windowShell(*world->globalData(), new JSDOMWindowShell(m_frame->domWindow(), world));
1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    Strong<JSDOMWindowShell> windowShell2(windowShell);
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_windowShells.add(world, windowShell);
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    world->didCreateWindowShell(this);
11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return windowShell.get();
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1182fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld* world)
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    const SourceCode& jsSourceCode = sourceCode.jsSourceCode();
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    String sourceURL = ustringToString(jsSourceCode.provider()->url());
122cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // evaluate code. Returns the JS return value or 0
124d0825bca7fe65beaee391d30da42e937db621564Steve Block    // if there was none, an error occurred or the type couldn't be converted.
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // inlineCode is true for <a href="javascript:doSomething()">
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and false for <script>doSomething()</script>. Check if it has the
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // expected value in all cases.
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See smart window.open policy for where this is used.
130cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    JSDOMWindowShell* shell = windowShell(world);
131cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    ExecState* exec = shell->window()->globalExec();
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const String* savedSourceURL = m_sourceURL;
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_sourceURL = &sourceURL;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Frame> protect = m_frame;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, sourceURL, sourceCode.startLine());
140643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
141cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    exec->globalData().timeoutChecker.start();
142e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    Completion comp = JSMainThreadExecState::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell);
143cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    exec->globalData().timeoutChecker.stop();
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentation::didEvaluateScript(cookie);
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Evaluating the JavaScript could cause the frame to be deallocated
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // so we start the keep alive timer here.
1495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_frame->keepAlive();
1505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (comp.complType() == Normal || comp.complType() == ReturnValue) {
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_sourceURL = savedSourceURL;
15381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return ScriptValue(exec->globalData(), comp.value());
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (comp.complType() == Throw || comp.complType() == Interrupted)
157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        reportException(exec, comp.value());
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_sourceURL = savedSourceURL;
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return ScriptValue();
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1632fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return evaluateInWorld(sourceCode, mainThreadNormalWorld());
166cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
167cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
168643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockPassRefPtr<DOMWrapperWorld> ScriptController::createWorld()
169cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return DOMWrapperWorld::create(JSDOMWindow::commonJSGlobalData());
171cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid ScriptController::getAllWorlds(Vector<DOMWrapperWorld*>& worlds)
174cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static_cast<WebCoreJSClientData*>(JSDOMWindow::commonJSGlobalData()->clientData)->getAllWorlds(worlds);
176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
178e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid ScriptController::clearWindowShell(bool goingIntoPageCache)
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (m_windowShells.isEmpty())
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
1845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) {
18681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        JSDOMWindowShell* windowShell = iter->second.get();
187d0825bca7fe65beaee391d30da42e937db621564Steve Block
188d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Clear the debugger from the current window before setting the new window.
189d0825bca7fe65beaee391d30da42e937db621564Steve Block        attachDebugger(windowShell, 0);
190d0825bca7fe65beaee391d30da42e937db621564Steve Block
191cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        windowShell->window()->willRemoveFromWindowShell();
192cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        windowShell->setWindow(m_frame->domWindow());
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
19428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // An m_cacheableBindingRootObject persists between page navigations
19528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // so needs to know about the new JSDOMWindow.
19628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (m_cacheableBindingRootObject)
19728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            m_cacheableBindingRootObject->updateGlobalObject(windowShell->window());
19828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
199cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (Page* page = m_frame->page()) {
200d0825bca7fe65beaee391d30da42e937db621564Steve Block            attachDebugger(windowShell, page->debugger());
201cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            windowShell->window()->setProfileGroup(page->group().identifier());
202cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        }
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
205e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // It's likely that resetting our windows created a lot of garbage, unless
206e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // it went in a back/forward cache.
207e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (!goingIntoPageCache)
208e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        gcController().garbageCollectSoon();
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
211cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockJSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world)
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
213cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    ASSERT(!m_windowShells.contains(world));
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
217dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSDOMWindowShell* windowShell = createWindowShell(world);
218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    windowShell->window()->updateDocument();
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (Page* page = m_frame->page()) {
222d0825bca7fe65beaee391d30da42e937db621564Steve Block        attachDebugger(windowShell, page->debugger());
223cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        windowShell->window()->setProfileGroup(page->group().identifier());
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
226643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_frame->loader()->dispatchDidClearWindowObjectInWorld(world);
227cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
228cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return windowShell;
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenint ScriptController::eventHandlerLineNumber() const
23206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
23306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // JSC expects 1-based line numbers, so we must add one here to get it right.
234ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    ScriptableDocumentParser* parser = m_frame->document()->scriptableDocumentParser();
235ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (parser)
23606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return parser->lineNumber() + 1;
23706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return 0;
23806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
239ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
240f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickbool ScriptController::processingUserGesture()
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
242f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    ExecState* exec = JSMainThreadExecState::currentState();
243f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    Frame* frame = exec ? toDynamicFrame(exec) : 0;
244f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // No script is running, so it is user-initiated unless the gesture stack
245f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // explicitly says it is not.
246f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (!frame)
247f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return UserGestureIndicator::getUserGestureState() != DefinitelyNotProcessingUserGesture;
248f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
249f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // FIXME: We check the plugin popup flag and javascript anchor navigation
250f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // from the dynamic frame becuase they should only be initiated on the
251f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // dynamic frame in which execution began if they do happen.
252f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    ScriptController* scriptController = frame->script();
253f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    ASSERT(scriptController);
254f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (scriptController->allowPopupsFromPlugin() || scriptController->isJavaScriptAnchorNavigation())
25521939df44de1705786c545cd1bf519d47250322dBen Murdoch        return true;
256635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
25721939df44de1705786c545cd1bf519d47250322dBen Murdoch    // If a DOM event is being processed, check that it was initiated by the user
25821939df44de1705786c545cd1bf519d47250322dBen Murdoch    // and that it is in the whitelist of event types allowed to generate pop-ups.
259f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (JSDOMWindowShell* shell = scriptController->existingWindowShell(currentWorld(exec)))
26021939df44de1705786c545cd1bf519d47250322dBen Murdoch        if (Event* event = shell->window()->currentEvent())
26121939df44de1705786c545cd1bf519d47250322dBen Murdoch            return event->fromUserGesture();
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26321939df44de1705786c545cd1bf519d47250322dBen Murdoch    return UserGestureIndicator::processingUserGesture();
264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// FIXME: This seems like an insufficient check to verify a click on a javascript: anchor.
267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ScriptController::isJavaScriptAnchorNavigation() const
268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // This is the <a href="javascript:window.open('...')> case -> we let it through
270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_sourceURL && m_sourceURL->isNull() && !m_processingTimerCallback)
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return true;
272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // This is the <script>window.open(...)</script> case or a timer callback -> block it
274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ScriptController::anyPageIsProcessingUserGesture() const
278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Page* page = m_frame->page();
280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!page)
281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return false;
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    const HashSet<Page*>& pages = page->group().pages();
284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    HashSet<Page*>::const_iterator end = pages.end();
285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
2875e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            ScriptController* script = frame->script();
2885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
2895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            if (script->m_allowPopupsFromPlugin)
2905e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block                return true;
2915e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
2925e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            const ShellMap::const_iterator iterEnd = m_windowShells.end();
2935e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            for (ShellMap::const_iterator iter = m_windowShells.begin(); iter != iterEnd; ++iter) {
2945e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block                JSDOMWindowShell* shell = iter->second.get();
2955e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block                Event* event = shell->window()->currentEvent();
2965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block                if (event && event->fromUserGesture())
2975e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block                    return true;
2985e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            }
2995e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
3005e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            if (isJavaScriptAnchorNavigation())
301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return true;
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockbool ScriptController::canAccessFromCurrentOrigin(Frame *frame)
309e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{
310e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    ExecState* exec = JSMainThreadExecState::currentState();
311e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (exec)
312e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return allowsAccessFromFrame(exec, frame);
313e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // If the current state is 0 we're in a call path where the DOM security
314e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // check doesn't apply (eg. parser).
315e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    return true;
316e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block}
317e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
318d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid ScriptController::attachDebugger(JSC::Debugger* debugger)
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
320d0825bca7fe65beaee391d30da42e937db621564Steve Block    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
32181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        attachDebugger(iter->second.get(), debugger);
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
324d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid ScriptController::attachDebugger(JSDOMWindowShell* shell, JSC::Debugger* debugger)
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
326cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!shell)
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
329cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    JSDOMWindow* globalObject = shell->window();
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (debugger)
331cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        debugger->attach(globalObject);
332cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    else if (JSC::Debugger* currentDebugger = globalObject->debugger())
333cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        currentDebugger->detach(globalObject);
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ScriptController::updateDocument()
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_frame->document())
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
342cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        iter->second->window()->updateDocument();
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ScriptController::updateSecurityOrigin()
347635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
348635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Our bindings do not do anything in this case.
349635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
351545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochBindings::RootObject* ScriptController::cacheableBindingRootObject()
352545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
353545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!canExecuteScripts(NotAboutToExecuteScript))
354545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return 0;
355545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
356545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!m_cacheableBindingRootObject) {
357545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        JSLock lock(SilenceAssertionsOnly);
358545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        m_cacheableBindingRootObject = Bindings::RootObject::create(0, globalObject(pluginWorld()));
359545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
360545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return m_cacheableBindingRootObject.get();
361545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
362545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectBindings::RootObject* ScriptController::bindingRootObject()
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!canExecuteScripts(NotAboutToExecuteScript))
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_bindingRootObject) {
3690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        JSLock lock(SilenceAssertionsOnly);
370cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_bindingRootObject = Bindings::RootObject::create(0, globalObject(pluginWorld()));
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_bindingRootObject.get();
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Bindings::RootObject> ScriptController::createRootObject(void* nativeHandle)
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootObjectMap::iterator it = m_rootObjects.find(nativeHandle);
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (it != m_rootObjects.end())
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return it->second;
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
381cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    RefPtr<Bindings::RootObject> rootObject = Bindings::RootObject::create(nativeHandle, globalObject(pluginWorld()));
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_rootObjects.set(nativeHandle, rootObject);
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return rootObject.release();
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
387967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(INSPECTOR)
388967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid ScriptController::setCaptureCallStackForUncaughtExceptions(bool)
389967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
390967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
391967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif
392967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNPObject* ScriptController::windowScriptNPObject()
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_windowScriptNPObject) {
398dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (canExecuteScripts(NotAboutToExecuteScript)) {
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // JavaScript is enabled, so there is a JavaScript window object.
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Return an NPObject bound to the window object.
4010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JSC::JSLock lock(SilenceAssertionsOnly);
402cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            JSObject* win = windowShell(pluginWorld())->window();
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(win);
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Bindings::RootObject* root = bindingRootObject();
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root);
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object.
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object.
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_windowScriptNPObject = _NPN_CreateNoScriptObject();
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_windowScriptNPObject;
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObject* object = jsObjectForPluginElement(plugin);
4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!object)
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return _NPN_CreateNoScriptObject();
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Wrap the JSObject in an NPObject
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return _NPN_CreateScriptObject(0, object, bindingRootObject());
4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianJSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin)
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Can't create JSObjects when JavaScript is disabled
431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!canExecuteScripts(NotAboutToExecuteScript))
4328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
4338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create a JSObject bound to this element
4350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
436cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    JSDOMWindow* globalObj = globalObject(pluginWorld());
437cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // FIXME: is normal okay? - used for NP plugins?
438cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    JSValue jsElementValue = toJS(globalObj->globalExec(), globalObj, plugin);
439635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!jsElementValue || !jsElementValue.isObject())
4408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
4418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return jsElementValue.getObject();
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if !PLATFORM(MAC)
4468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
447635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ScriptController::updatePlatformScriptObjects()
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ScriptController::disconnectPlatformScriptObjects()
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootObjectMap::iterator it = m_rootObjects.find(nativeHandle);
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (it == m_rootObjects.end())
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    it->second->invalidate();
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_rootObjects.remove(it);
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ScriptController::clearScriptObjects()
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootObjectMap::const_iterator end = m_rootObjects.end();
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RootObjectMap::const_iterator it = m_rootObjects.begin(); it != end; ++it)
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        it->second->invalidate();
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_rootObjects.clear();
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_bindingRootObject) {
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_bindingRootObject->invalidate();
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_bindingRootObject = 0;
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_windowScriptNPObject) {
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // script object properly.
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point.
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        _NPN_DeallocateObject(m_windowScriptNPObject);
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_windowScriptNPObject = 0;
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4942fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture)
495cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
496a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->document()->url());
497cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
498dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!canExecuteScripts(AboutToExecuteScript) || isPaused())
499cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return ScriptValue();
500cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
501cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    bool wasInExecuteScript = m_inExecuteScript;
502cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_inExecuteScript = true;
503cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
5042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ScriptValue result = evaluateInWorld(sourceCode, world);
505cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
506cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!wasInExecuteScript) {
507cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_inExecuteScript = false;
508cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        Document::updateStyleForAllDocuments();
509cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
510cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
511cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return result;
512cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
513cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
515