~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include "KURL.h"
32
32
#include "Location.h"
33
33
#include "ScriptController.h"
 
34
#include <runtime/JSFunction.h>
34
35
#include <runtime/PrototypeFunction.h>
35
36
 
36
37
using namespace JSC;
37
38
 
38
39
namespace WebCore {
39
40
 
40
 
JSValuePtr nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
41
 
{
42
 
    return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionReplace);
43
 
}
44
 
 
45
 
JSValuePtr nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
46
 
{
47
 
    return new (exec) PrototypeFunction(exec, 0, propertyName, jsLocationPrototypeFunctionReload);
48
 
}
49
 
 
50
 
JSValuePtr nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
51
 
{
52
 
    return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionAssign);
53
 
}
54
 
 
55
 
bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 
41
static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
 
42
{
 
43
    return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace);
 
44
}
 
45
 
 
46
static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
 
47
{
 
48
    return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload);
 
49
}
 
50
 
 
51
static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
 
52
{
 
53
    return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign);
 
54
}
 
55
 
 
56
bool JSLocation::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
56
57
{
57
58
    Frame* frame = impl()->frame();
58
59
    if (!frame) {
61
62
    }
62
63
 
63
64
    // When accessing Location cross-domain, functions are always the native built-in ones.
64
 
    // See JSDOMWindow::customGetOwnPropertySlot for additional details.
 
65
    // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
65
66
 
66
67
    // Our custom code is only needed to implement the Window cross-domain scheme, so if access is
67
68
    // allowed, return false so the normal lookup will take place.
76
77
            slot.setCustom(this, nonCachingStaticReplaceFunctionGetter);
77
78
            return true;
78
79
        } else if (entry->function() == jsLocationPrototypeFunctionReload) {
79
 
            slot.setCustom(this, nonCachingStaticReplaceFunctionGetter);
 
80
            slot.setCustom(this, nonCachingStaticReloadFunctionGetter);
80
81
            return true;
81
82
        } else if (entry->function() == jsLocationPrototypeFunctionAssign) {
82
83
            slot.setCustom(this, nonCachingStaticAssignFunctionGetter);
93
94
    return true;
94
95
}
95
96
 
96
 
bool JSLocation::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
 
97
bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 
98
{
 
99
    Frame* frame = impl()->frame();
 
100
    if (!frame) {
 
101
        descriptor.setUndefined();
 
102
        return true;
 
103
    }
 
104
    
 
105
    // When accessing Location cross-domain, functions are always the native built-in ones.
 
106
    // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
 
107
    
 
108
    // Our custom code is only needed to implement the Window cross-domain scheme, so if access is
 
109
    // allowed, return false so the normal lookup will take place.
 
110
    String message;
 
111
    if (allowsAccessFromFrame(exec, frame, message))
 
112
        return false;
 
113
    
 
114
    // Check for the few functions that we allow, even when called cross-domain.
 
115
    const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
 
116
    PropertySlot slot;
 
117
    if (entry && (entry->attributes() & Function)) {
 
118
        if (entry->function() == jsLocationPrototypeFunctionReplace) {
 
119
            slot.setCustom(this, nonCachingStaticReplaceFunctionGetter);
 
120
            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
 
121
            return true;
 
122
        } else if (entry->function() == jsLocationPrototypeFunctionReload) {
 
123
            slot.setCustom(this, nonCachingStaticReloadFunctionGetter);
 
124
            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
 
125
            return true;
 
126
        } else if (entry->function() == jsLocationPrototypeFunctionAssign) {
 
127
            slot.setCustom(this, nonCachingStaticAssignFunctionGetter);
 
128
            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
 
129
            return true;
 
130
        }
 
131
    }
 
132
    
 
133
    // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString,
 
134
    // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in
 
135
    // such cases when normally the string form of Location would be the URL.
 
136
    
 
137
    printErrorMessageForFrame(frame, message);
 
138
    descriptor.setUndefined();
 
139
    return true;
 
140
}
 
141
 
 
142
bool JSLocation::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
97
143
{
98
144
    Frame* frame = impl()->frame();
99
145
    if (!frame)
100
146
        return true;
101
147
 
 
148
    if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
 
149
        return true;
 
150
 
102
151
    bool sameDomainAccess = allowsAccessFromFrame(exec, frame);
103
152
 
104
153
    const HashEntry* entry = JSLocation::s_info.propHashTable(exec)->entry(exec, propertyName);
125
174
    return Base::deleteProperty(exec, propertyName);
126
175
}
127
176
 
128
 
bool JSLocation::customGetPropertyNames(ExecState* exec, PropertyNameArray&)
 
177
void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
129
178
{
130
179
    // Only allow the location object to enumerated by frames in the same origin.
131
180
    if (!allowsAccessFromFrame(exec, impl()->frame()))
132
 
        return true;
133
 
    return false;
134
 
}
135
 
 
136
 
static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory)
137
 
{
138
 
    Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
139
 
    if (!url.protocolIs("javascript") || allowsAccessFromFrame(exec, frame)) {
140
 
        bool userGesture = activeFrame->script()->processingUserGesture();
141
 
        frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, userGesture);
142
 
    }
143
 
}
144
 
 
145
 
void JSLocation::setHref(ExecState* exec, JSValuePtr value)
146
 
{
147
 
    Frame* frame = impl()->frame();
148
 
    ASSERT(frame);
149
 
 
150
 
    Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
151
 
    if (!activeFrame)
152
 
        return;
153
 
    if (!activeFrame->loader()->shouldAllowNavigation(frame))
154
 
        return;
155
 
 
156
 
    KURL url = activeFrame->loader()->completeURL(value->toString(exec));
157
 
    navigateIfAllowed(exec, frame, url, false);
158
 
}
159
 
 
160
 
void JSLocation::setProtocol(ExecState* exec, JSValuePtr value)
161
 
{
162
 
    Frame* frame = impl()->frame();
163
 
    ASSERT(frame);
164
 
 
165
 
    KURL url = frame->loader()->url();
166
 
    url.setProtocol(value->toString(exec));
167
 
 
168
 
    navigateIfAllowed(exec, frame, url, false);
169
 
}
170
 
 
171
 
void JSLocation::setHost(ExecState* exec, JSValuePtr value)
172
 
{
173
 
    Frame* frame = impl()->frame();
174
 
    ASSERT(frame);
175
 
 
176
 
    KURL url = frame->loader()->url();
177
 
    url.setHostAndPort(value->toString(exec));
178
 
 
179
 
    navigateIfAllowed(exec, frame, url, false);
180
 
}
181
 
 
182
 
void JSLocation::setHostname(ExecState* exec, JSValuePtr value)
183
 
{
184
 
    Frame* frame = impl()->frame();
185
 
    ASSERT(frame);
186
 
 
187
 
    KURL url = frame->loader()->url();
188
 
    url.setHost(value->toString(exec));
189
 
 
190
 
    navigateIfAllowed(exec, frame, url, false);
191
 
}
192
 
 
193
 
void JSLocation::setPort(ExecState* exec, JSValuePtr value)
 
181
        return;
 
182
    Base::getOwnPropertyNames(exec, propertyNames);
 
183
}
 
184
 
 
185
void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
 
186
{
 
187
    if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
 
188
        return;
 
189
    Base::defineGetter(exec, propertyName, getterFunction, attributes);
 
190
}
 
191
 
 
192
static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
 
193
{
 
194
    Frame* lexicalFrame = toLexicalFrame(exec);
 
195
    if (!lexicalFrame)
 
196
        return;
 
197
 
 
198
    if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame))
 
199
        frame->loader()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture(exec));
 
200
}
 
201
 
 
202
void JSLocation::setHref(ExecState* exec, JSValue value)
 
203
{
 
204
    Frame* frame = impl()->frame();
 
205
    ASSERT(frame);
 
206
 
 
207
    KURL url = completeURL(exec, value.toString(exec));
 
208
    if (url.isNull())
 
209
        return;
 
210
 
 
211
    if (!shouldAllowNavigation(exec, frame))
 
212
        return;
 
213
 
 
214
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
215
}
 
216
 
 
217
void JSLocation::setProtocol(ExecState* exec, JSValue value)
 
218
{
 
219
    Frame* frame = impl()->frame();
 
220
    ASSERT(frame);
 
221
 
 
222
    KURL url = frame->loader()->url();
 
223
    url.setProtocol(value.toString(exec));
 
224
 
 
225
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
226
}
 
227
 
 
228
void JSLocation::setHost(ExecState* exec, JSValue value)
 
229
{
 
230
    Frame* frame = impl()->frame();
 
231
    ASSERT(frame);
 
232
 
 
233
    KURL url = frame->loader()->url();
 
234
    url.setHostAndPort(value.toString(exec));
 
235
 
 
236
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
237
}
 
238
 
 
239
void JSLocation::setHostname(ExecState* exec, JSValue value)
 
240
{
 
241
    Frame* frame = impl()->frame();
 
242
    ASSERT(frame);
 
243
 
 
244
    KURL url = frame->loader()->url();
 
245
    url.setHost(value.toString(exec));
 
246
 
 
247
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
248
}
 
249
 
 
250
void JSLocation::setPort(ExecState* exec, JSValue value)
194
251
{
195
252
    Frame* frame = impl()->frame();
196
253
    ASSERT(frame);
197
254
 
198
255
    KURL url = frame->loader()->url();
199
256
    // FIXME: Could make this a little less ugly if String provided a toUnsignedShort function.
200
 
    const UString& portString = value->toString(exec);
 
257
    const UString& portString = value.toString(exec);
201
258
    int port = charactersToInt(portString.data(), portString.size());
202
259
    if (port < 0 || port > 0xFFFF)
203
260
        port = 0;
204
261
    url.setPort(port);
205
262
 
206
 
    navigateIfAllowed(exec, frame, url, false);
207
 
}
208
 
 
209
 
void JSLocation::setPathname(ExecState* exec, JSValuePtr value)
210
 
{
211
 
    Frame* frame = impl()->frame();
212
 
    ASSERT(frame);
213
 
 
214
 
    KURL url = frame->loader()->url();
215
 
    url.setPath(value->toString(exec));
216
 
 
217
 
    navigateIfAllowed(exec, frame, url, false);
218
 
}
219
 
 
220
 
void JSLocation::setSearch(ExecState* exec, JSValuePtr value)
221
 
{
222
 
    Frame* frame = impl()->frame();
223
 
    ASSERT(frame);
224
 
 
225
 
    KURL url = frame->loader()->url();
226
 
    url.setQuery(value->toString(exec));
227
 
 
228
 
    navigateIfAllowed(exec, frame, url, false);
229
 
}
230
 
 
231
 
void JSLocation::setHash(ExecState* exec, JSValuePtr value)
232
 
{
233
 
    Frame* frame = impl()->frame();
234
 
    ASSERT(frame);
235
 
 
236
 
    KURL url = frame->loader()->url();
237
 
    String oldRef = url.ref();
238
 
    String str = value->toString(exec);
 
263
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
264
}
 
265
 
 
266
void JSLocation::setPathname(ExecState* exec, JSValue value)
 
267
{
 
268
    Frame* frame = impl()->frame();
 
269
    ASSERT(frame);
 
270
 
 
271
    KURL url = frame->loader()->url();
 
272
    url.setPath(value.toString(exec));
 
273
 
 
274
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
275
}
 
276
 
 
277
void JSLocation::setSearch(ExecState* exec, JSValue value)
 
278
{
 
279
    Frame* frame = impl()->frame();
 
280
    ASSERT(frame);
 
281
 
 
282
    KURL url = frame->loader()->url();
 
283
    url.setQuery(value.toString(exec));
 
284
 
 
285
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
286
}
 
287
 
 
288
void JSLocation::setHash(ExecState* exec, JSValue value)
 
289
{
 
290
    Frame* frame = impl()->frame();
 
291
    ASSERT(frame);
 
292
 
 
293
    KURL url = frame->loader()->url();
 
294
    String oldFragmentIdentifier = url.fragmentIdentifier();
 
295
    String str = value.toString(exec);
239
296
    if (str.startsWith("#"))
240
297
        str = str.substring(1);
241
 
    if (oldRef == str || (oldRef.isNull() && str.isEmpty()))
 
298
    if (equalIgnoringNullity(oldFragmentIdentifier, str))
242
299
        return;
243
 
    url.setRef(str);
244
 
 
245
 
    navigateIfAllowed(exec, frame, url, false);
246
 
}
247
 
 
248
 
JSValuePtr JSLocation::replace(ExecState* exec, const ArgList& args)
249
 
{
250
 
    Frame* frame = impl()->frame();
251
 
    if (!frame)
252
 
        return jsUndefined();
253
 
 
254
 
    Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
255
 
    if (!activeFrame) 
256
 
        return jsUndefined();
257
 
    if (!activeFrame->loader()->shouldAllowNavigation(frame))
258
 
        return jsUndefined();
259
 
 
260
 
    navigateIfAllowed(exec, frame, activeFrame->loader()->completeURL(args.at(exec, 0)->toString(exec)), true);
261
 
    return jsUndefined();
262
 
}
263
 
 
264
 
JSValuePtr JSLocation::reload(ExecState* exec, const ArgList&)
265
 
{
266
 
    Frame* frame = impl()->frame();
267
 
    if (!frame)
268
 
        return jsUndefined();
269
 
 
270
 
    JSDOMWindow* window = toJSDOMWindow(frame);
271
 
    if (!window->allowsAccessFrom(exec))
272
 
        return jsUndefined();
273
 
 
274
 
    if (!frame->loader()->url().protocolIs("javascript") || (window && window->allowsAccessFrom(exec))) {
275
 
        bool userGesture = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame()->script()->processingUserGesture();
276
 
        frame->loader()->scheduleRefresh(userGesture);
277
 
    }
278
 
    return jsUndefined();
279
 
}
280
 
 
281
 
JSValuePtr JSLocation::assign(ExecState* exec, const ArgList& args)
282
 
{
283
 
    Frame* frame = impl()->frame();
284
 
    if (!frame)
285
 
        return jsUndefined();
286
 
 
287
 
    Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
288
 
    if (!activeFrame)
289
 
        return jsUndefined();
290
 
    if (!activeFrame->loader()->shouldAllowNavigation(frame))
 
300
    url.setFragmentIdentifier(str);
 
301
 
 
302
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
 
303
}
 
304
 
 
305
JSValue JSLocation::replace(ExecState* exec, const ArgList& args)
 
306
{
 
307
    Frame* frame = impl()->frame();
 
308
    if (!frame)
 
309
        return jsUndefined();
 
310
 
 
311
    KURL url = completeURL(exec, args.at(0).toString(exec));
 
312
    if (url.isNull())
 
313
        return jsUndefined();
 
314
 
 
315
    if (!shouldAllowNavigation(exec, frame))
 
316
        return jsUndefined();
 
317
 
 
318
    navigateIfAllowed(exec, frame, url, true, true);
 
319
    return jsUndefined();
 
320
}
 
321
 
 
322
JSValue JSLocation::reload(ExecState* exec, const ArgList&)
 
323
{
 
324
    Frame* frame = impl()->frame();
 
325
    if (!frame || !allowsAccessFromFrame(exec, frame))
 
326
        return jsUndefined();
 
327
 
 
328
    if (!protocolIsJavaScript(frame->loader()->url()))
 
329
        frame->loader()->scheduleRefresh(processingUserGesture(exec));
 
330
    return jsUndefined();
 
331
}
 
332
 
 
333
JSValue JSLocation::assign(ExecState* exec, const ArgList& args)
 
334
{
 
335
    Frame* frame = impl()->frame();
 
336
    if (!frame)
 
337
        return jsUndefined();
 
338
 
 
339
    KURL url = completeURL(exec, args.at(0).toString(exec));
 
340
    if (url.isNull())
 
341
        return jsUndefined();
 
342
 
 
343
    if (!shouldAllowNavigation(exec, frame))
291
344
        return jsUndefined();
292
345
 
293
346
    // We want a new history item if this JS was called via a user gesture
294
 
    navigateIfAllowed(exec, frame, activeFrame->loader()->completeURL(args.at(exec, 0)->toString(exec)), false);
 
347
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
295
348
    return jsUndefined();
296
349
}
297
350
 
298
 
JSValuePtr JSLocation::toString(ExecState* exec, const ArgList&)
 
351
JSValue JSLocation::toString(ExecState* exec, const ArgList&)
299
352
{
300
353
    Frame* frame = impl()->frame();
301
 
    if (!frame)
302
 
        return jsUndefined();
303
 
    if (!allowsAccessFromFrame(exec, frame))
 
354
    if (!frame || !allowsAccessFromFrame(exec, frame))
304
355
        return jsUndefined();
305
356
 
306
357
    return jsString(exec, impl()->toString());
307
358
}
308
359
 
 
360
bool JSLocationPrototype::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&)
 
361
{
 
362
    return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf);
 
363
}
 
364
 
 
365
void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
 
366
{
 
367
    if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)
 
368
        return;
 
369
    Base::defineGetter(exec, propertyName, getterFunction, attributes);
 
370
}
 
371
 
309
372
} // namespace WebCore