307a0c17434a38fbcd98030792013e14082dada9
[WebKit-https.git] / WebCore / bindings / js / JSDOMWindowCustom.cpp
1 /*
2  * Copyright (C) 2007 Apple, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "JSDOMWindow.h"
22
23 #include "Document.h"
24 #include "DOMWindow.h"
25 #include "ExceptionCode.h"
26 #include "Frame.h"
27 #include "FrameLoader.h"
28 #include "kjs_window.h"
29 #include "kjs/object.h"
30 #include "kjs/value.h"
31
32 namespace WebCore {
33
34 bool JSDOMWindow::customGetOwnPropertySlot(KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::PropertySlot& slot)
35 {
36     // we don't want any properties other than "closed" on a closed window
37     if (!impl()->frame()) {
38         if (propertyName == "closed") {
39             const KJS::HashEntry* entry = KJS::Lookup::findEntry(classInfo()->propHashTable, propertyName);
40             ASSERT(entry);
41             if (entry) {
42                 slot.setStaticEntry(this, entry, KJS::staticValueGetter<JSDOMWindow>);
43                 return true;
44             }
45         }
46         if (propertyName == "close") {
47             KJS::JSValue* proto = prototype();
48             if (proto->isObject()) {
49                 const KJS::HashEntry* entry = KJS::Lookup::findEntry(static_cast<KJS::JSObject*>(proto)->classInfo()->propHashTable, propertyName);
50                 ASSERT(entry);
51                 if (entry) {
52                     slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
53                     return true;
54                 }
55             }
56         }
57
58         slot.setUndefined(this);
59         return true;
60     }
61
62     // Look for overrides first
63     if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
64         if (!allowsAccessFrom(exec))
65             slot.setUndefined(this);
66
67         return true;
68     }
69
70     // FIXME: We need this to work around the blanket same origin (allowsAccessFrom) check in KJS::Window.  Once we remove that, we
71     // can move this to JSDOMWindowPrototype.
72     KJS::JSValue* proto = prototype();
73     if (proto->isObject()) {
74         const KJS::HashEntry* entry = KJS::Lookup::findEntry(static_cast<KJS::JSObject*>(proto)->classInfo()->propHashTable, propertyName);
75         if (entry) {
76             if (entry->attr & KJS::Function) {
77                 if (entry->value.functionValue == jsDOMWindowPrototypeFunctionFocus
78                     || entry->value.functionValue == jsDOMWindowPrototypeFunctionBlur
79                     || entry->value.functionValue == jsDOMWindowPrototypeFunctionClose
80                     || entry->value.functionValue == jsDOMWindowPrototypeFunctionPostMessage)
81                         slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
82                 else {
83                     if (!allowsAccessFrom(exec))
84                         slot.setUndefined(this);
85                     else
86                         slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
87                 }
88                 return true;
89             }
90         }
91     }
92
93     return false;
94 }
95
96 bool JSDOMWindow::customPut(KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::JSValue* value, int attr)
97 {
98     if (!impl()->frame())
99         return true;
100
101     // Called by an internal KJS, save time and jump directly to JSGlobalObject.
102     if (attr != KJS::None && attr != KJS::DontDelete) {
103         KJS::JSGlobalObject::put(exec, propertyName, value, attr);
104         return true;
105     }
106
107     // We have a local override (e.g. "var location"), save time and jump directly to JSGlobalObject.
108     KJS::PropertySlot slot;
109     if (KJS::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
110         if (allowsAccessFrom(exec))
111             KJS::JSGlobalObject::put(exec, propertyName, value, attr);
112         return true;
113     }
114
115     return false;
116 }
117
118 KJS::JSValue* JSDOMWindow::postMessage(KJS::ExecState* exec, const KJS::List& args)
119 {
120     DOMWindow* window = impl();
121     
122     DOMWindow* source = static_cast<JSDOMWindow*>(exec->dynamicGlobalObject())->impl();
123     String domain = source->frame()->loader()->url().host();
124     String uri = source->frame()->loader()->url().string();
125     String message = args[0]->toString(exec);
126     
127     if (exec->hadException())
128         return KJS::jsUndefined();
129     
130     window->postMessage(message, domain, uri, source);
131     
132     return KJS::jsUndefined();
133 }
134
135 } // namespace WebCore