| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2000 Harri Porten (porten@kde.org) | 2 * Copyright (C) 2000 Harri Porten (porten@kde.org) |
| 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) | 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
| 4 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. | 4 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. |
| 5 * Copyright (C) 2006 James G. Speth (speth@end.com) | 5 * Copyright (C) 2006 James G. Speth (speth@end.com) |
| 6 * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) | 6 * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) |
| 7 * Copyright (C) 2007, 2008 Google Inc. All Rights Reserved. | 7 * Copyright (C) 2007, 2008 Google Inc. All Rights Reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 #include "CanvasGradient.h" | 49 #include "CanvasGradient.h" |
| 50 #include "CanvasPattern.h" | 50 #include "CanvasPattern.h" |
| 51 #include "CanvasRenderingContext2D.h" | 51 #include "CanvasRenderingContext2D.h" |
| 52 #include "CanvasStyle.h" | 52 #include "CanvasStyle.h" |
| 53 #include "Clipboard.h" | 53 #include "Clipboard.h" |
| 54 #include "ClipboardEvent.h" | 54 #include "ClipboardEvent.h" |
| 55 #include "Console.h" | 55 #include "Console.h" |
| 56 #include "DOMParser.h" | 56 #include "DOMParser.h" |
| 57 #include "DOMStringList.h" | 57 #include "DOMStringList.h" |
| 58 #include "DOMTimer.h" | 58 #include "DOMTimer.h" |
| 59 #include "DOMWindow.h" | |
| 60 #include "Document.h" | 59 #include "Document.h" |
| 61 #include "DocumentFragment.h" | 60 #include "DocumentFragment.h" |
| 62 #include "Event.h" | 61 #include "Event.h" |
| 63 #include "EventTarget.h" | 62 #include "EventTarget.h" |
| 64 #include "FloatRect.h" | 63 #include "FloatRect.h" |
| 65 #include "Frame.h" | 64 #include "Frame.h" |
| 66 #include "FrameLoader.h" | 65 #include "FrameLoader.h" |
| 67 #include "FrameTree.h" | 66 #include "FrameTree.h" |
| 68 #include "HTMLBodyElement.h" | 67 #include "HTMLBodyElement.h" |
| 69 #include "HTMLCanvasElement.h" | 68 #include "HTMLCanvasElement.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 // Generate a wrapper. | 134 // Generate a wrapper. |
| 136 Document* doc = V8Proxy::DOMWrapperToNative<Document>(info.Holder()); | 135 Document* doc = V8Proxy::DOMWrapperToNative<Document>(info.Holder()); |
| 137 v8::Handle<v8::Value> wrapper = | 136 v8::Handle<v8::Value> wrapper = |
| 138 V8Proxy::DOMImplementationToV8Object(doc->implementation()); | 137 V8Proxy::DOMImplementationToV8Object(doc->implementation()); |
| 139 // Store the wrapper in the internal field. | 138 // Store the wrapper in the internal field. |
| 140 info.Holder()->SetInternalField(kDocumentImplementationIndex, wrapper); | 139 info.Holder()->SetInternalField(kDocumentImplementationIndex, wrapper); |
| 141 | 140 |
| 142 return wrapper; | 141 return wrapper; |
| 143 } | 142 } |
| 144 | 143 |
| 145 // TODO(mbelshe): This should move into V8DOMWindowCustom.cpp | |
| 146 // Can't move it right now because it depends on V8ScheduledAction, | |
| 147 // which is private to this file (v8_custom.cpp). | |
| 148 v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, | |
| 149 bool single_shot) { | |
| 150 int num_arguments = args.Length(); | |
| 151 | |
| 152 if (num_arguments < 1) return v8::Undefined(); | |
| 153 | |
| 154 DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( | |
| 155 V8ClassIndex::DOMWINDOW, args.Holder()); | |
| 156 | |
| 157 if (!imp->frame()) | |
| 158 return v8::Undefined(); | |
| 159 | |
| 160 if (!V8Proxy::CanAccessFrame(imp->frame(), true)) | |
| 161 return v8::Undefined(); | |
| 162 | |
| 163 ScriptExecutionContext* script_context = | |
| 164 static_cast<ScriptExecutionContext*>(imp->frame()->document()); | |
| 165 | |
| 166 v8::Handle<v8::Value> function = args[0]; | |
| 167 | |
| 168 int32_t timeout = 0; | |
| 169 if (num_arguments >= 2) timeout = args[1]->Int32Value(); | |
| 170 | |
| 171 int id; | |
| 172 if (function->IsString()) { | |
| 173 // Don't allow setting timeouts to run empty functions! | |
| 174 // (Bug 1009597) | |
| 175 WebCore::String string_function = ToWebCoreString(function); | |
| 176 if (string_function.length() == 0) | |
| 177 return v8::Undefined(); | |
| 178 | |
| 179 id = DOMTimer::install(script_context, | |
| 180 new ScheduledAction(string_function), timeout, | |
| 181 single_shot); | |
| 182 } else if (function->IsFunction()) { | |
| 183 int param_count = num_arguments >= 2 ? num_arguments - 2 : 0; | |
| 184 v8::Local<v8::Value>* params = 0; | |
| 185 if (param_count > 0) { | |
| 186 params = new v8::Local<v8::Value>[param_count]; | |
| 187 for (int i = 0; i < param_count; i++) | |
| 188 // parameters must be globalized | |
| 189 params[i] = args[i+2]; | |
| 190 } | |
| 191 | |
| 192 // params is passed to action, and released in action's destructor | |
| 193 ScheduledAction* action = new ScheduledAction( | |
| 194 v8::Handle<v8::Function>::Cast(function), param_count, params); | |
| 195 | |
| 196 delete[] params; | |
| 197 | |
| 198 id = DOMTimer::install(script_context, action, timeout, single_shot); | |
| 199 } else { | |
| 200 // TODO(fqian): what's the right return value if failed. | |
| 201 return v8::Undefined(); | |
| 202 } | |
| 203 return v8::Integer::New(id); | |
| 204 } | |
| 205 | |
| 206 | |
| 207 // DOMWindow ------------------------------------------------------------------- | |
| 208 | |
| 209 static bool IsAscii(const String& str) { | |
| 210 for (size_t i = 0; i < str.length(); i++) { | |
| 211 if (str[i] > 0xFF) | |
| 212 return false; | |
| 213 } | |
| 214 return true; | |
| 215 } | |
| 216 | |
| 217 static v8::Handle<v8::Value> Base64Convert(const String& str, bool encode) { | |
| 218 if (!IsAscii(str)) { | |
| 219 V8Proxy::SetDOMException(INVALID_CHARACTER_ERR); | |
| 220 return v8::Handle<v8::Value>(); | |
| 221 } | |
| 222 | |
| 223 Vector<char> in(str.length()); | |
| 224 for (size_t i = 0; i < str.length(); i++) { | |
| 225 in[i] = static_cast<char>(str[i]); | |
| 226 } | |
| 227 Vector<char> out; | |
| 228 | |
| 229 if (encode) { | |
| 230 base64Encode(in, out); | |
| 231 } else { | |
| 232 if (!base64Decode(in, out)) { | |
| 233 V8Proxy::ThrowError(V8Proxy::GENERAL_ERROR, "Cannot decode base64"); | |
| 234 return v8::Undefined(); | |
| 235 } | |
| 236 } | |
| 237 | |
| 238 return v8String(String(out.data(), out.size())); | |
| 239 } | |
| 240 | |
| 241 CALLBACK_FUNC_DECL(DOMWindowAtob) { | |
| 242 INC_STATS("DOM.DOMWindow.atob()"); | |
| 243 DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( | |
| 244 V8ClassIndex::DOMWINDOW, args.Holder()); | |
| 245 | |
| 246 if (!V8Proxy::CanAccessFrame(imp->frame(), true)) | |
| 247 return v8::Undefined(); | |
| 248 | |
| 249 if (args.Length() < 1) { | |
| 250 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments"); | |
| 251 return v8::Undefined(); | |
| 252 } | |
| 253 | |
| 254 if (args[0]->IsNull()) return v8String(""); | |
| 255 | |
| 256 String str = ToWebCoreString(args[0]); | |
| 257 return Base64Convert(str, false); | |
| 258 } | |
| 259 | |
| 260 CALLBACK_FUNC_DECL(DOMWindowBtoa) { | |
| 261 INC_STATS("DOM.DOMWindow.btoa()"); | |
| 262 DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( | |
| 263 V8ClassIndex::DOMWINDOW, args.Holder()); | |
| 264 | |
| 265 if (!V8Proxy::CanAccessFrame(imp->frame(), true)) | |
| 266 return v8::Undefined(); | |
| 267 | |
| 268 if (args.Length() < 1) { | |
| 269 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments"); | |
| 270 return v8::Undefined(); | |
| 271 } | |
| 272 | |
| 273 if (args[0]->IsNull()) return v8String(""); | |
| 274 | |
| 275 String str = ToWebCoreString(args[0]); | |
| 276 return Base64Convert(str, true); | |
| 277 } | |
| 278 | |
| 279 // TODO(fqian): returning string is cheating, and we should | |
| 280 // fix this by calling toString function on the receiver. | |
| 281 // However, V8 implements toString in JavaScript, which requires | |
| 282 // switching context of receiver. I consider it is dangerous. | |
| 283 CALLBACK_FUNC_DECL(DOMWindowToString) | |
| 284 { | |
| 285 INC_STATS("DOM.DOMWindow.toString()"); | |
| 286 return args.This()->ObjectProtoToString(); | |
| 287 } | |
| 288 | |
| 289 CALLBACK_FUNC_DECL(DOMWindowNOP) | |
| 290 { | |
| 291 INC_STATS("DOM.DOMWindow.nop()"); | |
| 292 return v8::Undefined(); | |
| 293 } | |
| 294 | |
| 295 | |
| 296 static String EventNameFromAttributeName(const String& name) { | |
| 297 ASSERT(name.startsWith("on")); | |
| 298 String event_type = name.substring(2); | |
| 299 | |
| 300 if (event_type.startsWith("w")) { | |
| 301 switch(event_type[event_type.length() - 1]) { | |
| 302 case 't': | |
| 303 event_type = "webkitAnimationStart"; | |
| 304 break; | |
| 305 case 'n': | |
| 306 event_type = "webkitAnimationIteration"; | |
| 307 break; | |
| 308 case 'd': | |
| 309 ASSERT(event_type.length() > 7); | |
| 310 if (event_type[7] == 'a') | |
| 311 event_type = "webkitAnimationEnd"; | |
| 312 else | |
| 313 event_type = "webkitTransitionEnd"; | |
| 314 break; | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 return event_type; | |
| 319 } | |
| 320 | |
| 321 | |
| 322 ACCESSOR_SETTER(DOMWindowEventHandler) { | |
| 323 v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper( | |
| 324 V8ClassIndex::DOMWINDOW, info.This()); | |
| 325 if (holder.IsEmpty()) | |
| 326 return; | |
| 327 | |
| 328 DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( | |
| 329 V8ClassIndex::DOMWINDOW, holder); | |
| 330 if (!imp->frame()) | |
| 331 return; | |
| 332 | |
| 333 Document* doc = imp->frame()->document(); | |
| 334 if (!doc) | |
| 335 return; | |
| 336 | |
| 337 String key = ToWebCoreString(name); | |
| 338 String event_type = EventNameFromAttributeName(key); | |
| 339 | |
| 340 if (value->IsNull()) { | |
| 341 // Clear the event listener | |
| 342 imp->clearAttributeEventListener(event_type); | |
| 343 } else { | |
| 344 V8Proxy* proxy = V8Proxy::retrieve(imp->frame()); | |
| 345 if (!proxy) | |
| 346 return; | |
| 347 | |
| 348 RefPtr<EventListener> listener = | |
| 349 proxy->FindOrCreateV8EventListener(value, true); | |
| 350 if (listener) { | |
| 351 imp->setAttributeEventListener(event_type, listener); | |
| 352 } | |
| 353 } | |
| 354 } | |
| 355 | |
| 356 | |
| 357 ACCESSOR_GETTER(DOMWindowEventHandler) { | |
| 358 v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper( | |
| 359 V8ClassIndex::DOMWINDOW, info.This()); | |
| 360 if (holder.IsEmpty()) | |
| 361 return v8::Undefined(); | |
| 362 | |
| 363 DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>( | |
| 364 V8ClassIndex::DOMWINDOW, holder); | |
| 365 if (!imp->frame()) | |
| 366 return v8::Undefined(); | |
| 367 | |
| 368 Document* doc = imp->frame()->document(); | |
| 369 if (!doc) | |
| 370 return v8::Undefined(); | |
| 371 | |
| 372 String key = ToWebCoreString(name); | |
| 373 String event_type = EventNameFromAttributeName(key); | |
| 374 | |
| 375 EventListener* listener = imp->getAttributeEventListener(event_type); | |
| 376 return V8Proxy::EventListenerToV8Object(listener); | |
| 377 } | |
| 378 | |
| 379 // --------------- Security Checks ------------------------- | 144 // --------------- Security Checks ------------------------- |
| 380 NAMED_ACCESS_CHECK(DOMWindow) { | |
| 381 ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW); | |
| 382 v8::Handle<v8::Value> window = | |
| 383 V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host); | |
| 384 if (window.IsEmpty()) | |
| 385 return false; // the frame is gone. | |
| 386 | |
| 387 DOMWindow* target_win = | |
| 388 V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window); | |
| 389 | |
| 390 ASSERT(target_win); | |
| 391 | |
| 392 Frame* target = target_win->frame(); | |
| 393 if (!target) | |
| 394 return false; | |
| 395 | |
| 396 if (key->IsString()) { | |
| 397 String name = ToWebCoreString(key); | |
| 398 | |
| 399 // Allow access of GET and HAS if index is a subframe. | |
| 400 if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) && | |
| 401 target->tree()->child(name)) { | |
| 402 return true; | |
| 403 } | |
| 404 } | |
| 405 | |
| 406 return V8Proxy::CanAccessFrame(target, false); | |
| 407 } | |
| 408 | |
| 409 | |
| 410 INDEXED_ACCESS_CHECK(DOMWindow) { | |
| 411 ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW); | |
| 412 v8::Handle<v8::Value> window = | |
| 413 V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host); | |
| 414 if (window.IsEmpty()) | |
| 415 return false; | |
| 416 | |
| 417 DOMWindow* target_win = | |
| 418 V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window); | |
| 419 | |
| 420 ASSERT(target_win); | |
| 421 | |
| 422 Frame* target = target_win->frame(); | |
| 423 if (!target) | |
| 424 return false; | |
| 425 | |
| 426 // Allow access of GET and HAS if index is a subframe. | |
| 427 if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) && | |
| 428 target->tree()->child(index)) { | |
| 429 return true; | |
| 430 } | |
| 431 | |
| 432 return V8Proxy::CanAccessFrame(target, false); | |
| 433 } | |
| 434 | |
| 435 | |
| 436 INDEXED_ACCESS_CHECK(History) { | 145 INDEXED_ACCESS_CHECK(History) { |
| 437 ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY); | 146 ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY); |
| 438 // Only allow same origin access | 147 // Only allow same origin access |
| 439 History* imp = | 148 History* imp = |
| 440 V8Proxy::ToNativeObject<History>(V8ClassIndex::HISTORY, host); | 149 V8Proxy::ToNativeObject<History>(V8ClassIndex::HISTORY, host); |
| 441 return V8Proxy::CanAccessFrame(imp->frame(), false); | 150 return V8Proxy::CanAccessFrame(imp->frame(), false); |
| 442 } | 151 } |
| 443 | 152 |
| 444 | 153 |
| 445 NAMED_ACCESS_CHECK(History) { | 154 NAMED_ACCESS_CHECK(History) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 #undef MAKE_CASE | 236 #undef MAKE_CASE |
| 528 | 237 |
| 529 default: | 238 default: |
| 530 return V8ClassIndex::INVALID_CLASS_INDEX; | 239 return V8ClassIndex::INVALID_CLASS_INDEX; |
| 531 } | 240 } |
| 532 } | 241 } |
| 533 | 242 |
| 534 #endif // ENABLE(SVG) | 243 #endif // ENABLE(SVG) |
| 535 | 244 |
| 536 } // namespace WebCore | 245 } // namespace WebCore |
| OLD | NEW |