webengine/osswebengine/WebCore/bindings/js/kjs_proxy.cpp
changeset 0 dd21522fd290
child 13 10e98eab6f85
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
       
     3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
       
     4  *  Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
       
     5  *
       
     6  *  This library is free software; you can redistribute it and/or
       
     7  *  modify it under the terms of the GNU Lesser General Public
       
     8  *  License as published by the Free Software Foundation; either
       
     9  *  version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  *  This library is distributed in the hope that it will be useful,
       
    12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  *  Lesser General Public License for more details.
       
    15  *
       
    16  *  You should have received a copy of the GNU Lesser General Public
       
    17  *  License along with this library; if not, write to the Free Software
       
    18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
       
    19  */
       
    20 
       
    21 #include "config.h"
       
    22 #include "kjs_proxy.h"
       
    23 
       
    24 #include "Chrome.h"
       
    25 #include "Document.h"
       
    26 #include "Frame.h"
       
    27 #include "FrameLoader.h"
       
    28 #include "GCController.h"
       
    29 #include "JSDocument.h"
       
    30 #include "JSDOMWindow.h"
       
    31 #include "Page.h"
       
    32 #include "Settings.h"
       
    33 #include "kjs_events.h"
       
    34 #include "kjs_window.h"
       
    35 
       
    36 #if ENABLE(SVG)
       
    37 #include "JSSVGLazyEventListener.h"
       
    38 #endif
       
    39 
       
    40 using namespace KJS;
       
    41 
       
    42 namespace WebCore {
       
    43 
       
    44 KJSProxy::KJSProxy(Frame* frame)
       
    45 {
       
    46     m_frame = frame;
       
    47     m_handlerLineno = 0;
       
    48 }
       
    49 
       
    50 KJSProxy::~KJSProxy()
       
    51 {
       
    52     // Check for <rdar://problem/4876466>. In theory, no JS should be executing
       
    53     // in our interpreter. 
       
    54     ASSERT(!m_script || !m_script->context());
       
    55     
       
    56     if (m_script) {
       
    57         m_script = 0;
       
    58     
       
    59         // It's likely that destroying the interpreter has created a lot of garbage.
       
    60         gcController().garbageCollectSoon();
       
    61     }
       
    62 }
       
    63 
       
    64 JSValue* KJSProxy::evaluate(const String& filename, int baseLine, const String& str) 
       
    65 {
       
    66     // evaluate code. Returns the JS return value or 0
       
    67     // if there was none, an error occured or the type couldn't be converted.
       
    68 
       
    69     initScriptIfNeeded();
       
    70     // inlineCode is true for <a href="javascript:doSomething()">
       
    71     // and false for <script>doSomething()</script>. Check if it has the
       
    72     // expected value in all cases.
       
    73     // See smart window.open policy for where this is used.
       
    74     bool inlineCode = filename.isNull();
       
    75 
       
    76     m_script->setInlineCode(inlineCode);
       
    77 
       
    78     JSLock lock;
       
    79 
       
    80     // Evaluating the JavaScript could cause the frame to be deallocated
       
    81     // so we start the keep alive timer here.
       
    82     m_frame->keepAlive();
       
    83     
       
    84     JSValue* thisNode = Window::retrieve(m_frame);
       
    85   
       
    86     m_script->startTimeoutCheck();
       
    87     Completion comp = m_script->evaluate(filename, baseLine, reinterpret_cast<const KJS::UChar*>(str.characters()), str.length(), thisNode);
       
    88     m_script->stopTimeoutCheck();
       
    89   
       
    90     if (comp.complType() == Normal || comp.complType() == ReturnValue)
       
    91         return comp.value();
       
    92 
       
    93     if (comp.complType() == Throw) {
       
    94         UString errorMessage = comp.value()->toString(m_script->globalExec());
       
    95         int lineNumber = comp.value()->toObject(m_script->globalExec())->get(m_script->globalExec(), "line")->toInt32(m_script->globalExec());
       
    96         UString sourceURL = comp.value()->toObject(m_script->globalExec())->get(m_script->globalExec(), "sourceURL")->toString(m_script->globalExec());
       
    97         if (Page* page = m_frame->page())
       
    98             page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, sourceURL);
       
    99     }
       
   100 
       
   101     return 0;
       
   102 }
       
   103 
       
   104 void KJSProxy::clear() {
       
   105   // clear resources allocated by the interpreter, and make it ready to be used by another page
       
   106   // We have to keep it, so that the Window object for the frame remains the same.
       
   107   // (we used to delete and re-create it, previously)
       
   108   if (m_script) {
       
   109     Window *win = Window::retrieveWindow(m_frame);
       
   110     if (win)
       
   111         win->clear();
       
   112   }
       
   113 }
       
   114 
       
   115 EventListener* KJSProxy::createHTMLEventHandler(const String& functionName, const String& code, Node* node)
       
   116 {
       
   117     initScriptIfNeeded();
       
   118     JSLock lock;
       
   119     return new JSLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno);
       
   120 }
       
   121 
       
   122 #if ENABLE(SVG)
       
   123 EventListener* KJSProxy::createSVGEventHandler(const String& functionName, const String& code, Node* node)
       
   124 {
       
   125     initScriptIfNeeded();
       
   126     JSLock lock;
       
   127     return new JSSVGLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno);
       
   128 }
       
   129 #endif
       
   130 
       
   131 void KJSProxy::finishedWithEvent(Event* event)
       
   132 {
       
   133   // This is called when the DOM implementation has finished with a particular event. This
       
   134   // is the case in sitations where an event has been created just for temporary usage,
       
   135   // e.g. an image load or mouse move. Once the event has been dispatched, it is forgotten
       
   136   // by the DOM implementation and so does not need to be cached still by the interpreter
       
   137   m_script->forgetDOMObject(event);
       
   138 }
       
   139 
       
   140 ScriptInterpreter* KJSProxy::interpreter()
       
   141 {
       
   142   initScriptIfNeeded();
       
   143   ASSERT(m_script);
       
   144   return m_script.get();
       
   145 }
       
   146 
       
   147 void KJSProxy::initScriptIfNeeded()
       
   148 {
       
   149   if (m_script)
       
   150     return;
       
   151 
       
   152   // Build the global object - which is a Window instance
       
   153   JSLock lock;
       
   154   JSObject* globalObject = new JSDOMWindow(m_frame->domWindow());
       
   155 
       
   156   // Create a KJS interpreter for this frame
       
   157   m_script = new ScriptInterpreter(globalObject, m_frame);
       
   158 
       
   159   String userAgent = m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->URL() : KURL());
       
   160   if (userAgent.find("Microsoft") >= 0 || userAgent.find("MSIE") >= 0)
       
   161     m_script->setCompatMode(Interpreter::IECompat);
       
   162   else
       
   163     // If we find "Mozilla" but not "(compatible, ...)" we are a real Netscape
       
   164     if (userAgent.find("Mozilla") >= 0 && userAgent.find("compatible") == -1)
       
   165       m_script->setCompatMode(Interpreter::NetscapeCompat);
       
   166 
       
   167   m_frame->loader()->dispatchWindowObjectAvailable();
       
   168 }
       
   169     
       
   170 void KJSProxy::clearDocumentWrapper() 
       
   171 {
       
   172     if (!m_script)
       
   173         return;
       
   174 
       
   175     JSLock lock;
       
   176     m_script->globalObject()->removeDirect("document");
       
   177 }
       
   178 
       
   179 }