Reviewed by Mitz.
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2007 07:19:08 +0000 (07:19 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2007 07:19:08 +0000 (07:19 +0000)
        Fix for http://bugs.webkit.org/show_bug.cgi?id=16466
        Move the JS Location object to its own file

        - Move Location into its own file and rename it JSLocation.

        * DerivedSources.make:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:
        * bindings/js/JSDocumentCustom.cpp:
        * bindings/js/JSLocation.cpp: Copied from WebCore/bindings/js/kjs_window.cpp.
        (WebCore::):
        (WebCore::JSLocation::JSLocation):
        (WebCore::JSLocation::getValueProperty):
        (WebCore::JSLocation::getOwnPropertySlot):
        (WebCore::JSLocation::put):
        (WebCore::JSLocationProtoFuncReplace::callAsFunction):
        (WebCore::JSLocationProtoFuncReload::callAsFunction):
        (WebCore::JSLocationProtoFuncAssign::callAsFunction):
        (WebCore::JSLocationProtoFuncToString::callAsFunction):
        * bindings/js/JSLocation.h: Copied from WebCore/bindings/js/kjs_window.h.
        (WebCore::JSLocation::):
        (WebCore::JSLocation::frame):
        (WebCore::JSLocation::classInfo):
        * bindings/js/kjs_window.cpp:
        (KJS::Window::location):
        * bindings/js/kjs_window.h:
        * history/CachedPage.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28798 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
WebCore/ChangeLog
WebCore/DerivedSources.make
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/bindings/js/JSDocumentCustom.cpp
WebCore/bindings/js/JSLocation.cpp [new file with mode: 0644]
WebCore/bindings/js/JSLocation.h [new file with mode: 0644]
WebCore/bindings/js/kjs_window.cpp
WebCore/bindings/js/kjs_window.h
WebCore/history/CachedPage.cpp

index 581763f5623d0753cde25e0b57011271bf4b2747..7cb36a82834cf3b33574c68b78d05ee9eae4fb23 100644 (file)
@@ -1,3 +1,37 @@
+2007-12-16  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Mitz.
+
+        Fix for http://bugs.webkit.org/show_bug.cgi?id=16466
+        Move the JS Location object to its own file
+
+        - Move Location into its own file and rename it JSLocation.
+
+        * DerivedSources.make:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * WebCoreSources.bkl:
+        * bindings/js/JSDocumentCustom.cpp:
+        * bindings/js/JSLocation.cpp: Copied from WebCore/bindings/js/kjs_window.cpp.
+        (WebCore::):
+        (WebCore::JSLocation::JSLocation):
+        (WebCore::JSLocation::getValueProperty):
+        (WebCore::JSLocation::getOwnPropertySlot):
+        (WebCore::JSLocation::put):
+        (WebCore::JSLocationProtoFuncReplace::callAsFunction):
+        (WebCore::JSLocationProtoFuncReload::callAsFunction):
+        (WebCore::JSLocationProtoFuncAssign::callAsFunction):
+        (WebCore::JSLocationProtoFuncToString::callAsFunction):
+        * bindings/js/JSLocation.h: Copied from WebCore/bindings/js/kjs_window.h.
+        (WebCore::JSLocation::):
+        (WebCore::JSLocation::frame):
+        (WebCore::JSLocation::classInfo):
+        * bindings/js/kjs_window.cpp:
+        (KJS::Window::location):
+        * bindings/js/kjs_window.h:
+        * history/CachedPage.cpp:
+
 2007-12-16  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Sam Weinig.
index f054731870a7177f1710f2d6b2222c0af49805b6..74bb413bde33031cde75aeb5a1d4c1a645cffd45 100644 (file)
@@ -409,6 +409,7 @@ all : \
     JSHTMLVideoElement.h \
     JSHistory.h \
     JSKeyboardEvent.h \
+    JSLocation.lut.h \
     JSMediaError.h \
     JSMediaList.h \
     JSMouseEvent.h \
index 29dadb5bdb3286e7772730d4a4341b50c82abd34..c086ef30354f7ce489c984ca684949134d418f45 100644 (file)
@@ -232,6 +232,7 @@ STYLESHEETS_EMBED = $$PWD/css/html4.css
 LUT_FILES += \
     bindings/js/JSDOMExceptionConstructor.cpp \
     bindings/js/JSEventTargetBase.cpp \
+    bindings/js/JSLocation.cpp \
     bindings/js/JSXMLHttpRequest.cpp \
     bindings/js/JSXSLTProcessor.cpp \
     bindings/js/kjs_css.cpp \
@@ -398,6 +399,7 @@ SOURCES += \
     bindings/js/JSHTMLOptionElementConstructor.cpp \
     bindings/js/JSHTMLOptionsCollectionCustom.cpp \
     bindings/js/JSHTMLSelectElementCustom.cpp \
+    bindings/js/JSLocation.cpp \
     bindings/js/JSNamedNodeMapCustom.cpp \
     bindings/js/JSNamedNodesCollection.cpp  \
     bindings/js/JSNodeCustom.cpp \
index 998b7b42fd38007b4e852e7f9a7c39b7916d04dc..cdc47ad98ad83fcfbf920f73e9913848e7cecf32 100644 (file)
                                RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSKeyboardEvent.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSLocation.lut.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSMediaList.cpp"\r
                                >\r
                                        RelativePath="..\bindings\js\JSHTMLSelectElementCustom.h"\r
                                        >\r
                                </File>\r
+                               <File\r
+                                       RelativePath="..\bindings\js\JSLocation.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\bindings\js\JSLocation.h"\r
+                                       >\r
+                               </File>\r
                                <File\r
                                        RelativePath="..\bindings\js\JSNamedNodeMapCustom.cpp"\r
                                        >\r
index c7e16b7785d07f6ca8d02247824b002225647fe2..325d1a7e1ea5aeeba101968b71ed0ed490518be2 100644 (file)
                BCA169A30BFD55B40019CA76 /* JSHTMLTableCaptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */; };
                BCA378160D15C64600B793D6 /* PausedTimeouts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA378140D15C64600B793D6 /* PausedTimeouts.cpp */; };
                BCA378170D15C64600B793D6 /* PausedTimeouts.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA378150D15C64600B793D6 /* PausedTimeouts.h */; };
+               BCA379140D163E5500B793D6 /* JSLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA379120D163E5500B793D6 /* JSLocation.cpp */; };
+               BCA379150D163E5500B793D6 /* JSLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA379130D163E5500B793D6 /* JSLocation.h */; };
+               BCA3793F0D1647E000B793D6 /* JSLocation.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA3793E0D1647E000B793D6 /* JSLocation.lut.h */; };
                BCA85A100C3AEAF4006F8308 /* DOMSVGNumberInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA85A0F0C3AEAF4006F8308 /* DOMSVGNumberInternal.h */; };
                BCAA90C30A7EBA60008B1229 /* ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCAA90C20A7EBA60008B1229 /* ScrollBar.cpp */; };
                BCB16B8B0979B01400467741 /* DeprecatedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16B880979B01400467741 /* DeprecatedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCA378150D15C64600B793D6 /* PausedTimeouts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PausedTimeouts.h; sourceTree = "<group>"; };
                BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduledAction.cpp; sourceTree = "<group>"; };
                BCA378BB0D15F64200B793D6 /* ScheduledAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScheduledAction.h; sourceTree = "<group>"; };
+               BCA379120D163E5500B793D6 /* JSLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSLocation.cpp; sourceTree = "<group>"; };
+               BCA379130D163E5500B793D6 /* JSLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLocation.h; sourceTree = "<group>"; };
+               BCA3793E0D1647E000B793D6 /* JSLocation.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLocation.lut.h; sourceTree = "<group>"; };
                BCA85A0F0C3AEAF4006F8308 /* DOMSVGNumberInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGNumberInternal.h; sourceTree = "<group>"; };
                BCAA90C20A7EBA60008B1229 /* ScrollBar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ScrollBar.cpp; path = platform/ScrollBar.cpp; sourceTree = SOURCE_ROOT; };
                BCB16B880979B01400467741 /* DeprecatedArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeprecatedArray.h; sourceTree = "<group>"; };
                                A8D06B380A265DCD005E7203 /* HTMLNames.cpp */,
                                A8D06B370A265DCD005E7203 /* HTMLNames.h */,
                                BCD9C2C40C17B6EC005C90A2 /* JSDOMExceptionConstructor.lut.h */,
+                               BCA3793E0D1647E000B793D6 /* JSLocation.lut.h */,
                                656581DA09D1508D000E61D7 /* kjs_css.lut.h */,
                                656581DC09D1508D000E61D7 /* kjs_events.lut.h */,
                                656581DE09D1508D000E61D7 /* kjs_navigator.lut.h */,
                                A80E7E630A1A82EC007FB8C5 /* JSHTMLInputElementBase.h */,
                                A826E8AD0A1A8F2300CD1BB6 /* JSHTMLOptionElementConstructor.cpp */,
                                A826E8AC0A1A8F2300CD1BB6 /* JSHTMLOptionElementConstructor.h */,
+                               BCA379120D163E5500B793D6 /* JSLocation.cpp */,
+                               BCA379130D163E5500B793D6 /* JSLocation.h */,
                                BCD9C26C0C17AA81005C90A2 /* JSNamedNodesCollection.cpp */,
                                BCD9C26D0C17AA81005C90A2 /* JSNamedNodesCollection.h */,
                                BCB7735E0C17853D00132BA4 /* JSNodeFilterCondition.cpp */,
                                BCB16C2D0979C3BD00467741 /* loader.h in Headers */,
                                93309DF8099E64920056E581 /* markup.h in Headers */,
                                93309E1E099E64920056E581 /* visible_units.h in Headers */,
+                               BCA379150D163E5500B793D6 /* JSLocation.h in Headers */,
+                               BCA3793F0D1647E000B793D6 /* JSLocation.lut.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                BCB16C2C0979C3BD00467741 /* loader.cpp in Sources */,
                                93309DF7099E64920056E581 /* markup.cpp in Sources */,
                                93309E1D099E64920056E581 /* visible_units.cpp in Sources */,
+                               BCA379140D163E5500B793D6 /* JSLocation.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index bf7b6ec48d4cf105b2415f5f5cac0c5d5ce9b8f8..47bbd17ae9c5004384c47a6fc399e9b0d91ed56d 100644 (file)
@@ -70,6 +70,7 @@ This file contains the list of files needed to build WebCore.
         bindings/js/JSHTMLOptionElementConstructor.cpp
         bindings/js/JSHTMLOptionsCollectionCustom.cpp
         bindings/js/JSHTMLSelectElementCustom.cpp
+        bindings/js/JSLocation.cpp
         bindings/js/JSNamedNodeMapCustom.cpp
         bindings/js/JSNamedNodesCollection.cpp
         bindings/js/JSNodeCustom.cpp
index 96a607be90a1c8d8b766c24cc7d6ab50df707770..309c575124a777eaa4fe63484cf6128c10146dcb 100644 (file)
@@ -27,6 +27,7 @@
 #include "HTMLDocument.h"
 #include "JSDOMWindow.h"
 #include "JSHTMLDocument.h"
+#include "JSLocation.h"
 #include "kjs_binding.h"
 #include "kjs_proxy.h"
 
diff --git a/WebCore/bindings/js/JSLocation.cpp b/WebCore/bindings/js/JSLocation.cpp
new file mode 100644 (file)
index 0000000..edad6fb
--- /dev/null
@@ -0,0 +1,277 @@
+// -*- c-basic-offset: 4 -*-
+/*
+ *  Copyright (C) 2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved.
+ *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+
+#include "config.h"
+#include "JSLocation.h"
+
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "PlatformString.h"
+#include "kjs_proxy.h"
+#include "kjs_window.h"
+
+#include "JSLocation.lut.h"
+
+using namespace KJS;
+
+namespace WebCore {
+
+const ClassInfo JSLocation::info = { "Location", 0, &JSLocationTable };
+
+/*
+@begin JSLocationTable 12
+  assign        &WebCore::JSLocationProtoFuncAssign::create        DontDelete|Function 1
+  hash          WebCore::JSLocation::Hash                          DontDelete
+  host          WebCore::JSLocation::Host                          DontDelete
+  hostname      WebCore::JSLocation::Hostname                      DontDelete
+  href          WebCore::JSLocation::Href                          DontDelete
+  pathname      WebCore::JSLocation::Pathname                      DontDelete
+  port          WebCore::JSLocation::Port                          DontDelete
+  protocol      WebCore::JSLocation::Protocol                      DontDelete
+  search        WebCore::JSLocation::Search                        DontDelete
+  toString      &WebCore::JSLocationProtoFuncToString::create      DontEnum|DontDelete|Function 0
+  replace       &WebCore::JSLocationProtoFuncReplace::create       DontDelete|Function 1
+  reload        &WebCore::JSLocationProtoFuncReload::create        DontDelete|Function 0
+@end
+*/
+
+JSLocation::JSLocation(Frame* frame)
+    : m_frame(frame)
+{
+}
+
+JSValue* JSLocation::getValueProperty(ExecState* exec, int token) const
+{
+  const KURL& url = m_frame->loader()->url();
+  switch (token) {
+  case Hash:
+    return jsString(url.ref().isNull() ? "" : "#" + url.ref());
+  case Host: {
+    // Note: this is the IE spec. The NS spec swaps the two, it says
+    // "The hostname property is the concatenation of the host and port properties, separated by a colon."
+    // Bleh.
+    UString str = url.host();
+    if (url.port())
+        str += ":" + String::number((int)url.port());
+    return jsString(str);
+  }
+  case Hostname:
+    return jsString(url.host());
+  case Href:
+    if (!url.hasPath())
+      return jsString(url.prettyURL() + "/");
+    return jsString(url.prettyURL());
+  case Pathname:
+    return jsString(url.path().isEmpty() ? "/" : url.path());
+  case Port:
+    return jsString(url.port() ? String::number((int)url.port()) : "");
+  case Protocol:
+    return jsString(url.protocol() + ":");
+  case Search:
+    return jsString(url.query());
+  default:
+    ASSERT_NOT_REACHED();
+    return jsUndefined();
+  }
+}
+
+bool JSLocation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+  if (!m_frame)
+    return false;
+
+  const Window* window = Window::retrieveWindow(m_frame);
+
+  const HashEntry* entry = Lookup::findEntry(&JSLocationTable, propertyName);
+  if (!entry || !(entry->attr & KJS::Function) || (entry->value.functionValue != &JSLocationProtoFuncReplace::create
+                                                   && entry->value.functionValue != &JSLocationProtoFuncReload::create
+                                                   && entry->value.functionValue != &JSLocationProtoFuncAssign::create))  {
+    if (!window || !window->allowsAccessFrom(exec)) {
+      slot.setUndefined(this);
+      return true;
+    }
+  }
+
+  return getStaticPropertySlot<JSLocation, JSObject>(exec, &JSLocationTable, this, propertyName, slot);
+}
+
+void JSLocation::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
+{
+  if (!m_frame)
+    return;
+
+  DeprecatedString str = value->toString(exec);
+  KURL url = m_frame->loader()->url();
+  const Window* window = Window::retrieveWindow(m_frame);
+  bool sameDomainAccess = window && window->allowsAccessFrom(exec);
+
+  const HashEntry* entry = Lookup::findEntry(&JSLocationTable, propertyName);
+
+  if (entry) {
+      // cross-domain access to the location is allowed when assigning the whole location,
+      // but not when assigning the individual pieces, since that might inadvertently
+      // disclose other parts of the original location.
+      if (entry->value.intValue != Href && !sameDomainAccess)
+          return;
+
+      switch (entry->value.intValue) {
+      case Href: {
+          Frame* frame = Window::retrieveActive(exec)->impl()->frame();
+          if (!frame)
+              return;
+          if (!frame->loader()->shouldAllowNavigation(m_frame))
+              return;
+          url = frame->loader()->completeURL(str);
+          break;
+      }
+      case Hash: {
+          if (str.startsWith("#"))
+              str = str.mid(1);
+          if (url.ref() == str)
+              return;
+          url.setRef(str);
+          break;
+      }
+      case Host: {
+          url.setHostAndPort(str);
+          break;
+      }
+      case Hostname:
+          url.setHost(str);
+          break;
+      case Pathname:
+          url.setPath(str);
+          break;
+      case Port:
+          url.setPort(str.toUInt());
+          break;
+      case Protocol:
+          url.setProtocol(str);
+          break;
+      case Search:
+          url.setQuery(str);
+          break;
+      default:
+          // Disallow changing other properties in JSLocationTable. e.g., "window.location.toString = ...".
+          // <http://bugs.webkit.org/show_bug.cgi?id=12720>
+          return;
+      }
+  } else {
+      if (sameDomainAccess)
+          JSObject::put(exec, propertyName, value, attr);
+      return;
+  }
+
+  Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
+  if (!url.deprecatedString().startsWith("javascript:", false) || sameDomainAccess) {
+    bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
+    m_frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture);
+  }
+}
+
+JSValue* JSLocationProtoFuncReplace::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
+{
+    if (!thisObj->inherits(&JSLocation::info))
+        return throwError(exec, TypeError);
+    JSLocation* location = static_cast<JSLocation*>(thisObj);
+    Frame* frame = location->frame();
+    if (!frame)
+        return jsUndefined();
+
+    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
+    if (activeFrame) {
+        if (!activeFrame->loader()->shouldAllowNavigation(frame))
+            return jsUndefined();
+        DeprecatedString str = args[0]->toString(exec);
+        const Window* window = Window::retrieveWindow(frame);
+        if (!str.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
+            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
+            frame->loader()->scheduleLocationChange(activeFrame->loader()->completeURL(str).string(), activeFrame->loader()->outgoingReferrer(), true, userGesture);
+        }
+    }
+
+    return jsUndefined();
+}
+
+JSValue* JSLocationProtoFuncReload::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
+{
+    if (!thisObj->inherits(&JSLocation::info))
+        return throwError(exec, TypeError);
+    JSLocation* location = static_cast<JSLocation*>(thisObj);
+    Frame* frame = location->frame();
+    if (!frame)
+        return jsUndefined();
+
+    Window* window = Window::retrieveWindow(frame);
+    if (!window->allowsAccessFrom(exec))
+        return jsUndefined();
+
+    if (!frame->loader()->url().deprecatedString().startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
+        bool userGesture = Window::retrieveActive(exec)->impl()->frame()->scriptProxy()->processingUserGesture();
+        frame->loader()->scheduleRefresh(userGesture);
+    }
+    return jsUndefined();
+}
+
+JSValue* JSLocationProtoFuncAssign::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
+{
+    if (!thisObj->inherits(&JSLocation::info))
+        return throwError(exec, TypeError);
+    JSLocation* location = static_cast<JSLocation*>(thisObj);
+    Frame* frame = location->frame();
+    if (!frame)
+        return jsUndefined();
+
+    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
+    if (activeFrame) {
+        if (!activeFrame->loader()->shouldAllowNavigation(frame))
+            return jsUndefined();
+        const Window* window = Window::retrieveWindow(frame);
+        String dstUrl = activeFrame->loader()->completeURL(args[0]->toString(exec)).string();
+        if (!dstUrl.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
+            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
+            // We want a new history item if this JS was called via a user gesture
+            frame->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), false, userGesture);
+        }
+    }
+
+    return jsUndefined();
+}
+
+JSValue* JSLocationProtoFuncToString::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
+{
+    if (!thisObj->inherits(&JSLocation::info))
+        return throwError(exec, TypeError);
+    JSLocation* location = static_cast<JSLocation*>(thisObj);
+    Frame* frame = location->frame();
+    if (!frame)
+        return jsUndefined();
+
+    const KURL& url = frame->loader()->url();
+    if (!url.hasPath())
+        return jsString(url.prettyURL() + "/");
+    return jsString(url.prettyURL());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSLocation.h b/WebCore/bindings/js/JSLocation.h
new file mode 100644 (file)
index 0000000..e10f2dd
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (C) 2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef JSLocation_h
+#define JSLocation_h
+
+#include "kjs_binding.h"
+
+namespace KJS {
+    class Window;
+}
+
+namespace WebCore {
+
+    class Frame;
+
+    class JSLocation : public KJS::DOMObject {
+        friend class KJS::Window;
+    public:
+        virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&);
+        KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const;
+        virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int attr = KJS::None);
+
+        enum {
+            Hash, Href, Hostname, Host,
+            Pathname, Port, Protocol, Search,
+            Replace, Reload, ToString, Assign
+        };
+
+        Frame* frame() const { return m_frame; }
+
+        virtual const KJS::ClassInfo* classInfo() const { return &info; }
+        static const KJS::ClassInfo info;
+
+    private:
+        JSLocation(Frame*);
+
+        Frame* m_frame;
+    };
+
+#define FOR_EACH_CLASS(macro) \
+    macro(JSLocationProtoFuncAssign) \
+    macro(JSLocationProtoFuncToString) \
+    macro(JSLocationProtoFuncReplace) \
+    macro(JSLocationProtoFuncReload) \
+
+FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
+#undef FOR_EACH_CLASS
+
+} // namespace WebCore
+
+#endif // JSLocation_h
index f01b08c68a883229491124ac990b25aea2fed38d..79412433e8fe5b8ccc277042cacf4abf6e460ee0 100644 (file)
@@ -46,6 +46,7 @@
 #include "JSHTMLCollection.h"
 #include "JSHTMLOptionElementConstructor.h"
 #include "JSXMLHttpRequest.h"
+#include "JSLocation.h"
 #include "Logging.h"
 #include "Page.h"
 #include "PausedTimeouts.h"
@@ -90,7 +91,7 @@ struct WindowPrivate {
     Window::ListenersMap jsHTMLEventListeners;
     Window::UnprotectedListenersMap jsUnprotectedEventListeners;
     Window::UnprotectedListenersMap jsUnprotectedHTMLEventListeners;
-    mutable Location* loc;
+    mutable WebCore::JSLocation* loc;
     WebCore::Event* m_evt;
     JSValue** m_returnValueSlot;
 
@@ -262,10 +263,10 @@ JSValue* Window::retrieve(Frame* frame)
     return jsUndefined(); // This can happen with JS disabled on the domain of that window
 }
 
-Location* Window::location() const
+WebCore::JSLocation* Window::location() const
 {
     if (!d->loc)
-        d->loc = new Location(impl()->frame());
+        d->loc = new JSLocation(impl()->frame());
     return d->loc;
 }
 
@@ -1351,244 +1352,6 @@ Window::UnprotectedListenersMap& Window::jsUnprotectedHTMLEventListeners()
     return d->jsUnprotectedHTMLEventListeners;
 }
 
-////////////////////// Location Object ////////////////////////
-
-const ClassInfo Location::info = { "Location", 0, &LocationTable };
-/*
-@begin LocationTable 12
-  assign        &LocationProtoFuncAssign::create        DontDelete|Function 1
-  hash          Location::Hash                          DontDelete
-  host          Location::Host                          DontDelete
-  hostname      Location::Hostname                      DontDelete
-  href          Location::Href                          DontDelete
-  pathname      Location::Pathname                      DontDelete
-  port          Location::Port                          DontDelete
-  protocol      Location::Protocol                      DontDelete
-  search        Location::Search                        DontDelete
-  toString      &LocationProtoFuncToString::create      DontEnum|DontDelete|Function 0
-  replace       &LocationProtoFuncReplace::create       DontDelete|Function 1
-  reload        &LocationProtoFuncReload::create        DontDelete|Function 0
-@end
-*/
-
-Location::Location(Frame* frame)
-    : m_frame(frame)
-{
-}
-
-JSValue *Location::getValueProperty(ExecState* exec, int token) const
-{
-  KURL url = m_frame->loader()->url();
-  switch (token) {
-  case Hash:
-    return jsString(url.ref().isNull() ? "" : "#" + url.ref());
-  case Host: {
-    // Note: this is the IE spec. The NS spec swaps the two, it says
-    // "The hostname property is the concatenation of the host and port properties, separated by a colon."
-    // Bleh.
-    UString str = url.host();
-    if (url.port())
-        str += ":" + String::number((int)url.port());
-    return jsString(str);
-  }
-  case Hostname:
-    return jsString(url.host());
-  case Href:
-    if (!url.hasPath())
-      return jsString(url.prettyURL() + "/");
-    return jsString(url.prettyURL());
-  case Pathname:
-    return jsString(url.path().isEmpty() ? "/" : url.path());
-  case Port:
-    return jsString(url.port() ? String::number((int)url.port()) : "");
-  case Protocol:
-    return jsString(url.protocol() + ":");
-  case Search:
-    return jsString(url.query());
-  default:
-    ASSERT_NOT_REACHED();
-    return jsUndefined();
-  }
-}
-
-bool Location::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-  if (!m_frame)
-    return false;
-
-  const Window* window = Window::retrieveWindow(m_frame);
-
-  const HashEntry* entry = Lookup::findEntry(&LocationTable, propertyName);
-  if (!entry || !(entry->attr & KJS::Function) || (entry->value.functionValue != &LocationProtoFuncReplace::create
-                                                   && entry->value.functionValue != &LocationProtoFuncReload::create
-                                                   && entry->value.functionValue != &LocationProtoFuncAssign::create))  {
-    if (!window || !window->allowsAccessFrom(exec)) {
-      slot.setUndefined(this);
-      return true;
-    }
-  }
-
-  return getStaticPropertySlot<Location, JSObject>(exec, &LocationTable, this, propertyName, slot);
-}
-
-void Location::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
-{
-  if (!m_frame)
-    return;
-
-  DeprecatedString str = value->toString(exec);
-  KURL url = m_frame->loader()->url();
-  const Window* window = Window::retrieveWindow(m_frame);
-  bool sameDomainAccess = window && window->allowsAccessFrom(exec);
-
-  const HashEntry* entry = Lookup::findEntry(&LocationTable, propertyName);
-
-  if (entry) {
-      // cross-domain access to the location is allowed when assigning the whole location,
-      // but not when assigning the individual pieces, since that might inadvertently
-      // disclose other parts of the original location.
-      if (entry->value.intValue != Href && !sameDomainAccess)
-          return;
-
-      switch (entry->value.intValue) {
-      case Href: {
-          Frame* frame = Window::retrieveActive(exec)->impl()->frame();
-          if (!frame)
-              return;
-          if (!frame->loader()->shouldAllowNavigation(m_frame))
-              return;
-          url = frame->loader()->completeURL(str);
-          break;
-      }
-      case Hash: {
-          if (str.startsWith("#"))
-              str = str.mid(1);
-          if (url.ref() == str)
-              return;
-          url.setRef(str);
-          break;
-      }
-      case Host: {
-          url.setHostAndPort(str);
-          break;
-      }
-      case Hostname:
-          url.setHost(str);
-          break;
-      case Pathname:
-          url.setPath(str);
-          break;
-      case Port:
-          url.setPort(str.toUInt());
-          break;
-      case Protocol:
-          url.setProtocol(str);
-          break;
-      case Search:
-          url.setQuery(str);
-          break;
-      default:
-          // Disallow changing other properties in LocationTable. e.g., "window.location.toString = ...".
-          // <http://bugs.webkit.org/show_bug.cgi?id=12720>
-          return;
-      }
-  } else {
-      if (sameDomainAccess)
-          JSObject::put(exec, propertyName, value, attr);
-      return;
-  }
-
-  Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
-  if (!url.deprecatedString().startsWith("javascript:", false) || sameDomainAccess) {
-    bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
-    m_frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture);
-  }
-}
-
-JSValue* LocationProtoFuncReplace::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
-{
-    if (!thisObj->inherits(&Location::info))
-        return throwError(exec, TypeError);
-    Location* location = static_cast<Location*>(thisObj);
-    Frame* frame = location->frame();
-    if (!frame)
-        return jsUndefined();
-
-    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
-    if (activeFrame) {
-        if (!activeFrame->loader()->shouldAllowNavigation(frame))
-            return jsUndefined();
-        DeprecatedString str = args[0]->toString(exec);
-        const Window* window = Window::retrieveWindow(frame);
-        if (!str.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
-            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
-            frame->loader()->scheduleLocationChange(activeFrame->loader()->completeURL(str).string(), activeFrame->loader()->outgoingReferrer(), true, userGesture);
-        }
-    }
-
-    return jsUndefined();
-}
-
-JSValue* LocationProtoFuncReload::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
-{
-    if (!thisObj->inherits(&Location::info))
-        return throwError(exec, TypeError);
-    Location* location = static_cast<Location*>(thisObj);
-    Frame* frame = location->frame();
-    if (!frame)
-        return jsUndefined();
-
-    Window* window = Window::retrieveWindow(frame);
-    if (!window->allowsAccessFrom(exec))
-        return jsUndefined();
-
-    if (!frame->loader()->url().deprecatedString().startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
-        bool userGesture = Window::retrieveActive(exec)->impl()->frame()->scriptProxy()->processingUserGesture();
-        frame->loader()->scheduleRefresh(userGesture);
-    }
-    return jsUndefined();
-}
-
-JSValue* LocationProtoFuncAssign::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
-{
-    if (!thisObj->inherits(&Location::info))
-        return throwError(exec, TypeError);
-    Location* location = static_cast<Location*>(thisObj);
-    Frame* frame = location->frame();
-    if (!frame)
-        return jsUndefined();
-
-    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
-    if (activeFrame) {
-        if (!activeFrame->loader()->shouldAllowNavigation(frame))
-            return jsUndefined();
-        const Window* window = Window::retrieveWindow(frame);
-        String dstUrl = activeFrame->loader()->completeURL(args[0]->toString(exec)).string();
-        if (!dstUrl.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
-            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
-            // We want a new history item if this JS was called via a user gesture
-            frame->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), false, userGesture);
-        }
-    }
-
-    return jsUndefined();
-}
-
-JSValue* LocationProtoFuncToString::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
-{
-    if (!thisObj->inherits(&Location::info))
-        return throwError(exec, TypeError);
-    Location* location = static_cast<Location*>(thisObj);
-    Frame* frame = location->frame();
-    if (!frame)
-        return jsUndefined();
-
-    const KURL& url = frame->loader()->url();
-    if (!url.hasPath())
-        return jsString(url.prettyURL() + "/");
-    return jsString(url.prettyURL());
-}
-
 /////////////////////////////////////////////////////////////////////////////
 
 void DOMWindowTimer::fired()
index d1f92505e7b3133bb4e79e4dbc3a0c4df485d4c1..fc901e8fdd373fa225dae6c043ce632f1547b971 100644 (file)
@@ -32,7 +32,9 @@ namespace WebCore {
     class DOMWindow;
     class Frame;
     class JSEventListener;
+    class JSLocation;
     class JSUnprotectedEventListener;
+    class Location;
     class PausedTimeouts;
     class ScheduledAction;
 }
@@ -40,14 +42,13 @@ namespace WebCore {
 namespace KJS {
 
     class DOMWindowTimer;
-    class Location;
     class Window;
     class WindowFunc;
     class WindowPrivate;
 
   // This is the only WebCore JS binding which does not inherit from DOMObject
   class Window : public JSGlobalObject {
-    friend class Location;
+    friend class WebCore::JSLocation;
     friend class WebCore::ScheduledAction;
   protected:
     Window(WebCore::DOMWindow*);
@@ -85,7 +86,7 @@ namespace KJS {
 
     void timerFired(DOMWindowTimer*);
 
-    Location* location() const;
+    WebCore::JSLocation* location() const;
 
     // Finds a wrapper of a JS EventListener, returns 0 if no existing one.
     WebCore::JSEventListener* findJSEventListener(JSValue*, bool html = false);
@@ -173,37 +174,6 @@ namespace KJS {
     macro(WindowProtoFuncShowModalDialog) \
     macro(WindowProtoFuncNotImplemented) \
 
-FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
-#undef FOR_EACH_CLASS
-
-
-  class Location : public DOMObject {
-    friend class Window;
-  public:
-    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-    JSValue* getValueProperty(ExecState*, int token) const;
-    virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attr = None);
-
-    enum { Hash, Href, Hostname, Host, Pathname, Port, Protocol, Search, 
-           Replace, Reload, ToString, Assign };
-
-    WebCore::Frame* frame() const { return m_frame; }
-
-    virtual const ClassInfo* classInfo() const { return &info; }
-    static const ClassInfo info;
-
-  private:
-    Location(WebCore::Frame*);
-
-    WebCore::Frame* m_frame;
-  };
-
-#define FOR_EACH_CLASS(macro) \
-    macro(LocationProtoFuncAssign) \
-    macro(LocationProtoFuncToString) \
-    macro(LocationProtoFuncReplace) \
-    macro(LocationProtoFuncReload) \
-
 FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
 #undef FOR_EACH_CLASS
 
index f477dff9097979eef99ffe858341fb93a7aa4d5e..80c47d342800b514f06efdb9d089e91315dd43be 100644 (file)
@@ -36,6 +36,7 @@
 #include "FrameLoader.h"
 #include "FrameView.h"
 #include "GCController.h"
+#include "JSLocation.h"
 #include "Logging.h"
 #include "Page.h"
 #include "PausedTimeouts.h"