+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.
JSHTMLVideoElement.h \
JSHistory.h \
JSKeyboardEvent.h \
+ JSLocation.lut.h \
JSMediaError.h \
JSMediaList.h \
JSMouseEvent.h \
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 \
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 \
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
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;
};
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
#include "HTMLDocument.h"
#include "JSDOMWindow.h"
#include "JSHTMLDocument.h"
+#include "JSLocation.h"
#include "kjs_binding.h"
#include "kjs_proxy.h"
--- /dev/null
+// -*- 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
--- /dev/null
+/*
+ * 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
#include "JSHTMLCollection.h"
#include "JSHTMLOptionElementConstructor.h"
#include "JSXMLHttpRequest.h"
+#include "JSLocation.h"
#include "Logging.h"
#include "Page.h"
#include "PausedTimeouts.h"
Window::ListenersMap jsHTMLEventListeners;
Window::UnprotectedListenersMap jsUnprotectedEventListeners;
Window::UnprotectedListenersMap jsUnprotectedHTMLEventListeners;
- mutable Location* loc;
+ mutable WebCore::JSLocation* loc;
WebCore::Event* m_evt;
JSValue** m_returnValueSlot;
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;
}
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()
class DOMWindow;
class Frame;
class JSEventListener;
+ class JSLocation;
class JSUnprotectedEventListener;
+ class Location;
class PausedTimeouts;
class ScheduledAction;
}
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*);
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);
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
#include "FrameLoader.h"
#include "FrameView.h"
#include "GCController.h"
+#include "JSLocation.h"
#include "Logging.h"
#include "Page.h"
#include "PausedTimeouts.h"