summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/js/JSLocationCustom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/js/JSLocationCustom.cpp')
-rw-r--r--WebCore/bindings/js/JSLocationCustom.cpp80
1 files changed, 63 insertions, 17 deletions
diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp
index d7d32f4..c76a2b1 100644
--- a/WebCore/bindings/js/JSLocationCustom.cpp
+++ b/WebCore/bindings/js/JSLocationCustom.cpp
@@ -31,6 +31,7 @@
#include "KURL.h"
#include "Location.h"
#include "ScriptController.h"
+#include <runtime/JSFunction.h>
#include <runtime/PrototypeFunction.h>
using namespace JSC;
@@ -93,6 +94,51 @@ bool JSLocation::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& p
return true;
}
+bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+{
+ Frame* frame = impl()->frame();
+ if (!frame) {
+ descriptor.setUndefined();
+ return true;
+ }
+
+ // When accessing Location cross-domain, functions are always the native built-in ones.
+ // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
+
+ // Our custom code is only needed to implement the Window cross-domain scheme, so if access is
+ // allowed, return false so the normal lookup will take place.
+ String message;
+ if (allowsAccessFromFrame(exec, frame, message))
+ return false;
+
+ // Check for the few functions that we allow, even when called cross-domain.
+ const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
+ PropertySlot slot;
+ if (entry && (entry->attributes() & Function)) {
+ if (entry->function() == jsLocationPrototypeFunctionReplace) {
+ slot.setCustom(this, nonCachingStaticReplaceFunctionGetter);
+ descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
+ return true;
+ } else if (entry->function() == jsLocationPrototypeFunctionReload) {
+ slot.setCustom(this, nonCachingStaticReloadFunctionGetter);
+ descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
+ return true;
+ } else if (entry->function() == jsLocationPrototypeFunctionAssign) {
+ slot.setCustom(this, nonCachingStaticAssignFunctionGetter);
+ descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
+ return true;
+ }
+ }
+
+ // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString,
+ // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in
+ // such cases when normally the string form of Location would be the URL.
+
+ printErrorMessageForFrame(frame, message);
+ descriptor.setUndefined();
+ return true;
+}
+
bool JSLocation::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
Frame* frame = impl()->frame();
@@ -128,19 +174,19 @@ bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName)
return Base::deleteProperty(exec, propertyName);
}
-void JSLocation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
// Only allow the location object to enumerated by frames in the same origin.
if (!allowsAccessFromFrame(exec, impl()->frame()))
return;
- Base::getPropertyNames(exec, propertyNames);
+ Base::getOwnPropertyNames(exec, propertyNames);
}
-void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
+void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
{
if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
return;
- Base::defineGetter(exec, propertyName, getterFunction);
+ Base::defineGetter(exec, propertyName, getterFunction, attributes);
}
static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
@@ -150,7 +196,7 @@ static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bo
return;
if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame))
- frame->loader()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture(exec));
+ frame->redirectScheduler()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture(exec));
}
void JSLocation::setHref(ExecState* exec, JSValue value)
@@ -158,13 +204,13 @@ void JSLocation::setHref(ExecState* exec, JSValue value)
Frame* frame = impl()->frame();
ASSERT(frame);
- if (!shouldAllowNavigation(exec, frame))
- return;
-
KURL url = completeURL(exec, value.toString(exec));
if (url.isNull())
return;
+ if (!shouldAllowNavigation(exec, frame))
+ return;
+
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
@@ -262,13 +308,13 @@ JSValue JSLocation::replace(ExecState* exec, const ArgList& args)
if (!frame)
return jsUndefined();
- if (!shouldAllowNavigation(exec, frame))
- return jsUndefined();
-
KURL url = completeURL(exec, args.at(0).toString(exec));
if (url.isNull())
return jsUndefined();
+ if (!shouldAllowNavigation(exec, frame))
+ return jsUndefined();
+
navigateIfAllowed(exec, frame, url, true, true);
return jsUndefined();
}
@@ -280,7 +326,7 @@ JSValue JSLocation::reload(ExecState* exec, const ArgList&)
return jsUndefined();
if (!protocolIsJavaScript(frame->loader()->url()))
- frame->loader()->scheduleRefresh(processingUserGesture(exec));
+ frame->redirectScheduler()->scheduleRefresh(processingUserGesture(exec));
return jsUndefined();
}
@@ -290,13 +336,13 @@ JSValue JSLocation::assign(ExecState* exec, const ArgList& args)
if (!frame)
return jsUndefined();
- if (!shouldAllowNavigation(exec, frame))
- return jsUndefined();
-
KURL url = completeURL(exec, args.at(0).toString(exec));
if (url.isNull())
return jsUndefined();
+ if (!shouldAllowNavigation(exec, frame))
+ return jsUndefined();
+
// We want a new history item if this JS was called via a user gesture
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
return jsUndefined();
@@ -316,11 +362,11 @@ bool JSLocationPrototype::putDelegate(ExecState* exec, const Identifier& propert
return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf);
}
-void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
+void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
{
if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
return;
- Base::defineGetter(exec, propertyName, getterFunction);
+ Base::defineGetter(exec, propertyName, getterFunction, attributes);
}
} // namespace WebCore