WebCore:
[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 "kjs_window.h"
27 #include "kjs/object.h"
28 #include "kjs/value.h"
29
30 namespace WebCore {
31
32 bool JSDOMWindow::customGetOwnPropertySlot(KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::PropertySlot& slot)
33 {
34     // we don't want any properties other than "closed" on a closed window
35     if (!impl()->frame()) {
36         if (propertyName == "closed") {
37             const KJS::HashEntry* entry = KJS::Lookup::findEntry(classInfo()->propHashTable, propertyName);
38             ASSERT(entry);
39             if (entry) {
40                 slot.setStaticEntry(this, entry, KJS::staticValueGetter<JSDOMWindow>);
41                 return true;
42             }
43         }
44         if (propertyName == "close") {
45             KJS::JSValue* proto = prototype();
46             if (proto->isObject()) {
47                 const KJS::HashEntry* entry = KJS::Lookup::findEntry(static_cast<KJS::JSObject*>(proto)->classInfo()->propHashTable, propertyName);
48                 ASSERT(entry);
49                 if (entry) {
50                     slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
51                     return true;
52                 }
53             }
54         }
55
56         slot.setUndefined(this);
57         return true;
58     }
59
60     // Look for overrides first
61     if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
62         if (!allowsAccessFrom(exec))
63             slot.setUndefined(this);
64
65         return true;
66     }
67
68     // FIXME: We need this to work around the blanket same origin (allowsAccessFrom) check in KJS::Window.  Once we remove that, we
69     // can move this to JSDOMWindowPrototype.
70     KJS::JSValue* proto = prototype();
71     if (proto->isObject()) {
72         const KJS::HashEntry* entry = KJS::Lookup::findEntry(static_cast<KJS::JSObject*>(proto)->classInfo()->propHashTable, propertyName);
73         if (entry) {
74             if (entry->attr & KJS::Function) {
75                 if (entry->value.functionValue == &JSDOMWindowPrototypeFunctionFocus::create
76                     || entry->value.functionValue == &JSDOMWindowPrototypeFunctionBlur::create
77                     || entry->value.functionValue == &JSDOMWindowPrototypeFunctionClose::create
78                     || entry->value.functionValue == &JSDOMWindowPrototypeFunctionPostMessage::create)
79                         slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
80                 else {
81                     if (!allowsAccessFrom(exec))
82                         slot.setUndefined(this);
83                     else
84                         slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
85                 }
86                 return true;
87             }
88         }
89     }
90
91     return false;
92 }
93
94 bool JSDOMWindow::customPut(KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::JSValue* value, int attr)
95 {
96     if (!impl()->frame())
97         return true;
98
99     // Called by an internal KJS, save time and jump directly to JSGlobalObject.
100     if (attr != KJS::None && attr != KJS::DontDelete) {
101         KJS::JSGlobalObject::put(exec, propertyName, value, attr);
102         return true;
103     }
104
105     // We have a local override (e.g. "var location"), save time and jump directly to JSGlobalObject.
106     KJS::PropertySlot slot;
107     if (KJS::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
108         if (allowsAccessFrom(exec))
109             KJS::JSGlobalObject::put(exec, propertyName, value, attr);
110         return true;
111     }
112
113     return false;
114 }
115
116 KJS::JSValue* JSDOMWindow::postMessage(KJS::ExecState* exec, const KJS::List& args)
117 {
118     DOMWindow* window = impl();
119     
120     DOMWindow* source = static_cast<JSDOMWindow*>(exec->dynamicGlobalObject())->impl();
121     String domain = source->document()->securityOrigin()->domain();
122     String uri = source->document()->documentURI();
123     String message = args[0]->toString(exec);
124     
125     if (exec->hadException())
126         return KJS::jsUndefined();
127     
128     window->postMessage(message, domain, uri, source);
129     
130     return KJS::jsUndefined();
131 }
132
133 } // namespace WebCore