18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2000 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  USA
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSLocationCustom.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DOMWindow.h"
27d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "ExceptionCode.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMBinding.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMWindowCustom.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "KURL.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Location.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScriptController.h"
35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <runtime/JSFunction.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <runtime/PrototypeFunction.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC;
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace);
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload);
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign);
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool JSLocation::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame) {
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        slot.setUndefined();
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // When accessing Location cross-domain, functions are always the native built-in ones.
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Our custom code is only needed to implement the Window cross-domain scheme, so if access is
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // allowed, return false so the normal lookup will take place.
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String message;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (allowsAccessFromFrame(exec, frame, message))
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check for the few functions that we allow, even when called cross-domain.
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (entry && (entry->attributes() & Function)) {
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (entry->function() == jsLocationPrototypeFunctionReplace) {
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            slot.setCustom(this, nonCachingStaticReplaceFunctionGetter);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (entry->function() == jsLocationPrototypeFunctionReload) {
81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            slot.setCustom(this, nonCachingStaticReloadFunctionGetter);
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (entry->function() == jsLocationPrototypeFunctionAssign) {
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            slot.setCustom(this, nonCachingStaticAssignFunctionGetter);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString,
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // such cases when normally the string form of Location would be the URL.
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printErrorMessageForFrame(frame, message);
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    slot.setUndefined();
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Frame* frame = impl()->frame();
101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!frame) {
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        descriptor.setUndefined();
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return true;
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // throw out all cross domain access
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!allowsAccessFromFrame(exec, frame))
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return true;
109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Check for the few functions that we allow, even when called cross-domain.
111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    PropertySlot slot;
113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (entry && (entry->attributes() & Function)) {
114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (entry->function() == jsLocationPrototypeFunctionReplace) {
115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            slot.setCustom(this, nonCachingStaticReplaceFunctionGetter);
116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (entry->function() == jsLocationPrototypeFunctionReload) {
119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            slot.setCustom(this, nonCachingStaticReloadFunctionGetter);
120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (entry->function() == jsLocationPrototypeFunctionAssign) {
123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            slot.setCustom(this, nonCachingStaticAssignFunctionGetter);
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString,
130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in
131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // such cases when normally the string form of Location would be the URL.
132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    descriptor.setUndefined();
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return true;
135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool JSLocation::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
1455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool sameDomainAccess = allowsAccessFromFrame(exec, frame);
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const HashEntry* entry = JSLocation::s_info.propHashTable(exec)->entry(exec, propertyName);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!entry) {
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (sameDomainAccess)
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSObject::put(exec, propertyName, value, slot);
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Cross-domain access to the location is allowed when assigning the whole location,
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // but not when assigning the individual pieces, since that might inadvertently
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // disclose other parts of the original location.
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (entry->propertyPutter() != setJSLocationHref && !sameDomainAccess)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName)
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Only allow deleting by frames in the same origin.
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!allowsAccessFromFrame(exec, impl()->frame()))
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::deleteProperty(exec, propertyName);
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
172d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Only allow the location object to enumerated by frames in the same origin.
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!allowsAccessFromFrame(exec, impl()->frame()))
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
177d0825bca7fe65beaee391d30da42e937db621564Steve Block    Base::getOwnPropertyNames(exec, propertyNames, mode);
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
1815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
1835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Base::defineGetter(exec, propertyName, getterFunction, attributes);
1855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Frame* lexicalFrame = toLexicalFrame(exec);
1905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!lexicalFrame)
1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame))
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        frame->redirectScheduler()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture(exec));
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setHref(ExecState* exec, JSValue value)
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    KURL url = completeURL(exec, value.toString(exec));
2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (url.isNull())
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!shouldAllowNavigation(exec, frame))
207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setProtocol(ExecState* exec, JSValue value)
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
218d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!url.setProtocol(value.toString(exec))) {
219d0825bca7fe65beaee391d30da42e937db621564Steve Block        setDOMException(exec, SYNTAX_ERR);
220d0825bca7fe65beaee391d30da42e937db621564Steve Block        return;
221d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setHost(ExecState* exec, JSValue value)
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    url.setHostAndPort(value.toString(exec));
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setHostname(ExecState* exec, JSValue value)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    url.setHost(value.toString(exec));
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setPort(ExecState* exec, JSValue value)
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Could make this a little less ugly if String provided a toUnsignedShort function.
255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    const UString& portString = value.toString(exec);
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int port = charactersToInt(portString.data(), portString.size());
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (port < 0 || port > 0xFFFF)
258643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        url.removePort();
259643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else
260643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        url.setPort(port);
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setPathname(ExecState* exec, JSValue value)
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    url.setPath(value.toString(exec));
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setSearch(ExecState* exec, JSValue value)
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    url.setQuery(value.toString(exec));
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSLocation::setHash(ExecState* exec, JSValue value)
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(frame);
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    KURL url = frame->loader()->url();
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    String oldFragmentIdentifier = url.fragmentIdentifier();
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    String str = value.toString(exec);
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (str.startsWith("#"))
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        str = str.substring(1);
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (equalIgnoringNullity(oldFragmentIdentifier, str))
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    url.setFragmentIdentifier(str);
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3045f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSLocation::replace(ExecState* exec, const ArgList& args)
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    KURL url = completeURL(exec, args.at(0).toString(exec));
3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (url.isNull())
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!shouldAllowNavigation(exec, frame))
315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return jsUndefined();
316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    navigateIfAllowed(exec, frame, url, true, true);
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsUndefined();
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3215f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSLocation::reload(ExecState* exec, const ArgList&)
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!frame || !allowsAccessFromFrame(exec, frame))
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!protocolIsJavaScript(frame->loader()->url()))
328231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        frame->redirectScheduler()->scheduleRefresh(processingUserGesture(exec));
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsUndefined();
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3325f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSLocation::assign(ExecState* exec, const ArgList& args)
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    KURL url = completeURL(exec, args.at(0).toString(exec));
3395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (url.isNull())
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!shouldAllowNavigation(exec, frame))
343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return jsUndefined();
344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We want a new history item if this JS was called via a user gesture
3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsUndefined();
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3505f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSLocation::toString(ExecState* exec, const ArgList&)
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = impl()->frame();
3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!frame || !allowsAccessFromFrame(exec, frame))
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsString(exec, impl()->toString());
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool JSLocationPrototype::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&)
3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf);
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
3665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
3675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
368231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Base::defineGetter(exec, propertyName, getterFunction, attributes);
3695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
3705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
372