1 : /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Web Workers.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * The Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2011
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Ben Turner <bent.mozilla@gmail.com> (Original Author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "Location.h"
40 :
41 : #include "jsapi.h"
42 : #include "jsfriendapi.h"
43 :
44 : #include "nsTraceRefcnt.h"
45 :
46 : #define PROPERTY_FLAGS \
47 : (JSPROP_ENUMERATE | JSPROP_SHARED)
48 :
49 : USING_WORKERS_NAMESPACE
50 :
51 : namespace {
52 :
53 : class Location
54 : {
55 : static JSClass sClass;
56 : static JSPropertySpec sProperties[];
57 : static JSFunctionSpec sFunctions[];
58 :
59 : enum SLOT {
60 : SLOT_href = 0,
61 : SLOT_protocol,
62 : SLOT_host,
63 : SLOT_hostname,
64 : SLOT_port,
65 : SLOT_pathname,
66 : SLOT_search,
67 : SLOT_hash,
68 :
69 : SLOT_COUNT
70 : };
71 :
72 : public:
73 : static JSObject*
74 0 : InitClass(JSContext* aCx, JSObject* aObj)
75 : {
76 : return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
77 0 : sFunctions, NULL, NULL);
78 : }
79 :
80 : static JSObject*
81 0 : Create(JSContext* aCx, JSString* aHref, JSString* aProtocol, JSString* aHost,
82 : JSString* aHostname, JSString* aPort, JSString* aPathname,
83 : JSString* aSearch, JSString* aHash)
84 : {
85 0 : JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
86 0 : if (!obj) {
87 0 : return NULL;
88 : }
89 :
90 0 : jsval empty = JS_GetEmptyStringValue(aCx);
91 :
92 : JS_SetReservedSlot(obj, SLOT_href,
93 0 : aHref ? STRING_TO_JSVAL(aHref) : empty);
94 : JS_SetReservedSlot(obj, SLOT_protocol,
95 0 : aProtocol ? STRING_TO_JSVAL(aProtocol) : empty);
96 : JS_SetReservedSlot(obj, SLOT_host,
97 0 : aHost ? STRING_TO_JSVAL(aHost) : empty);
98 : JS_SetReservedSlot(obj, SLOT_hostname,
99 0 : aHostname ? STRING_TO_JSVAL(aHostname) : empty);
100 : JS_SetReservedSlot(obj, SLOT_port,
101 0 : aPort ? STRING_TO_JSVAL(aPort) : empty);
102 : JS_SetReservedSlot(obj, SLOT_pathname,
103 0 : aPathname ? STRING_TO_JSVAL(aPathname) : empty);
104 : JS_SetReservedSlot(obj, SLOT_search,
105 0 : aSearch ? STRING_TO_JSVAL(aSearch) : empty);
106 : JS_SetReservedSlot(obj, SLOT_hash,
107 0 : aHash ? STRING_TO_JSVAL(aHash) : empty);
108 :
109 0 : Location* priv = new Location();
110 0 : JS_SetPrivate(obj, priv);
111 :
112 0 : return obj;
113 : }
114 :
115 : private:
116 0 : Location()
117 : {
118 0 : MOZ_COUNT_CTOR(mozilla::dom::workers::Location);
119 0 : }
120 :
121 0 : ~Location()
122 : {
123 0 : MOZ_COUNT_DTOR(mozilla::dom::workers::Location);
124 0 : }
125 :
126 : static JSBool
127 0 : Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
128 : {
129 : JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
130 0 : sClass.name);
131 0 : return false;
132 : }
133 :
134 : static void
135 0 : Finalize(JSContext* aCx, JSObject* aObj)
136 : {
137 0 : JS_ASSERT(JS_GetClass(aObj) == &sClass);
138 0 : delete static_cast<Location*>(JS_GetPrivate(aObj));
139 0 : }
140 :
141 : static JSBool
142 0 : ToString(JSContext* aCx, unsigned aArgc, jsval* aVp)
143 : {
144 0 : JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
145 0 : if (!obj) {
146 0 : return false;
147 : }
148 :
149 0 : JSClass* classPtr = JS_GetClass(obj);
150 0 : if (classPtr != &sClass) {
151 : JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
152 : JSMSG_INCOMPATIBLE_PROTO, sClass.name, "toString",
153 0 : classPtr);
154 0 : return false;
155 : }
156 :
157 0 : jsval href = JS_GetReservedSlot(obj, SLOT_href);
158 :
159 0 : JS_SET_RVAL(aCx, aVp, href);
160 0 : return true;
161 : }
162 :
163 : static JSBool
164 0 : GetProperty(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
165 : {
166 0 : JSClass* classPtr = JS_GetClass(aObj);
167 0 : if (classPtr != &sClass) {
168 : JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
169 : JSMSG_INCOMPATIBLE_PROTO, sClass.name, "GetProperty",
170 0 : classPtr->name);
171 0 : return false;
172 : }
173 :
174 0 : JS_ASSERT(JSID_IS_INT(aIdval));
175 0 : JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < SLOT_COUNT);
176 :
177 0 : *aVp = JS_GetReservedSlot(aObj, JSID_TO_INT(aIdval));
178 0 : return true;
179 : }
180 : };
181 :
182 : JSClass Location::sClass = {
183 : "WorkerLocation",
184 : JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
185 : JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
186 : JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
187 : JSCLASS_NO_OPTIONAL_MEMBERS
188 : };
189 :
190 : JSPropertySpec Location::sProperties[] = {
191 : { "href", SLOT_href, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
192 : { "protocol", SLOT_protocol, PROPERTY_FLAGS, GetProperty,
193 : js_GetterOnlyPropertyStub },
194 : { "host", SLOT_host, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
195 : { "hostname", SLOT_hostname, PROPERTY_FLAGS, GetProperty,
196 : js_GetterOnlyPropertyStub },
197 : { "port", SLOT_port, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
198 : { "pathname", SLOT_pathname, PROPERTY_FLAGS, GetProperty,
199 : js_GetterOnlyPropertyStub },
200 : { "search", SLOT_search, PROPERTY_FLAGS, GetProperty,
201 : js_GetterOnlyPropertyStub },
202 : { "hash", SLOT_hash, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
203 : { 0, 0, 0, NULL, NULL }
204 : };
205 :
206 : JSFunctionSpec Location::sFunctions[] = {
207 : JS_FN("toString", ToString, 0, 0),
208 : JS_FS_END
209 : };
210 :
211 : } // anonymous namespace
212 :
213 : BEGIN_WORKERS_NAMESPACE
214 :
215 : namespace location {
216 :
217 : bool
218 0 : InitClass(JSContext* aCx, JSObject* aGlobal)
219 : {
220 0 : return !!Location::InitClass(aCx, aGlobal);
221 : }
222 :
223 : JSObject*
224 0 : Create(JSContext* aCx, JSString* aHref, JSString* aProtocol, JSString* aHost,
225 : JSString* aHostname, JSString* aPort, JSString* aPathname,
226 : JSString* aSearch, JSString* aHash)
227 : {
228 : return Location::Create(aCx, aHref, aProtocol, aHost, aHostname, aPort,
229 0 : aPathname, aSearch, aHash);
230 : }
231 :
232 : } // namespace location
233 :
234 : END_WORKERS_NAMESPACE
|