ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, HTMLImageElement* image, int sx, int sy, int sw, int sh, ExceptionState& exceptionState) { // This variant does not work in worker threads. ASSERT(eventTarget.toDOMWindow()); if (!image->cachedImage()) { exceptionState.throwDOMException(InvalidStateError, "No image can be retrieved from the provided element."); return ScriptPromise(); } if (image->cachedImage()->image()->isSVGImage()) { exceptionState.throwDOMException(InvalidStateError, "The image element contains an SVG image, which is unsupported."); return ScriptPromise(); } if (!sw || !sh) { exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width")); return ScriptPromise(); } if (!image->cachedImage()->image()->currentFrameHasSingleSecurityOrigin()) { exceptionState.throwSecurityError("The source image contains image data from multiple origins."); return ScriptPromise(); } Document* document = eventTarget.toDOMWindow()->document(); if (!image->cachedImage()->passesAccessControlCheck(document->securityOrigin()) && document->securityOrigin()->taintsCanvas(image->src())) { exceptionState.throwSecurityError("Cross-origin access to the source image is denied."); return ScriptPromise(); } // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 return fulfillImageBitmap(scriptState, ImageBitmap::create(image, IntRect(sx, sy, sw, sh))); }
ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, HTMLVideoElement* video, int sx, int sy, int sw, int sh, ExceptionState& exceptionState) { // This variant does not work in worker threads. ASSERT(eventTarget.toDOMWindow()); if (video->networkState() == HTMLMediaElement::NETWORK_EMPTY) { exceptionState.throwDOMException(InvalidStateError, "The provided element has not retrieved data."); return ScriptPromise(); } if (video->readyState() <= HTMLMediaElement::HAVE_METADATA) { exceptionState.throwDOMException(InvalidStateError, "The provided element's player has no current data."); return ScriptPromise(); } if (!sw || !sh) { exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width")); return ScriptPromise(); } if (!video->hasSingleSecurityOrigin()) { exceptionState.throwSecurityError("The source video contains image data from multiple origins."); return ScriptPromise(); } if (!video->webMediaPlayer()->didPassCORSAccessCheck() && eventTarget.toDOMWindow()->document()->securityOrigin()->taintsCanvas(video->currentSrc())) { exceptionState.throwSecurityError("Cross-origin access to the source video is denied."); return ScriptPromise(); } // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 return fulfillImageBitmap(scriptState, ImageBitmap::create(video, IntRect(sx, sy, sw, sh))); }
void EventQueue::dispatchEvent(PassRefPtr<Event> event) { EventTarget* eventTarget = event->target(); if (eventTarget->toDOMWindow()) eventTarget->toDOMWindow()->dispatchEvent(event, 0); else eventTarget->dispatchEvent(event); }
void DOMWindowEventQueue::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event) { EventTarget* eventTarget = event->target(); if (eventTarget->toDOMWindow()) eventTarget->toDOMWindow()->dispatchEvent(event, nullptr); else eventTarget->dispatchEvent(event); }
bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception* exception, CachedScript* cachedScript) { EventTarget* target = errorEventTarget(); if (!target) return false; #if PLATFORM(IOS) if (target->toDOMWindow() && is<Document>(*this)) { Settings* settings = downcast<Document>(*this).settings(); if (settings && !settings->shouldDispatchJavaScriptWindowOnErrorEvents()) return false; } #endif String message = errorMessage; int line = lineNumber; int column = columnNumber; String sourceName = sourceURL; Deprecated::ScriptValue error = exception && exception->value() ? Deprecated::ScriptValue(vm(), exception->value()) : Deprecated::ScriptValue(); sanitizeScriptError(message, line, column, sourceName, error, cachedScript); ASSERT(!m_inDispatchErrorEvent); m_inDispatchErrorEvent = true; Ref<ErrorEvent> errorEvent = ErrorEvent::create(message, sourceName, line, column, error); target->dispatchEvent(errorEvent); m_inDispatchErrorEvent = false; return errorEvent->defaultPrevented(); }
void ScriptedAnimationController::dispatchEvents(const AtomicString& eventInterfaceFilter) { WillBeHeapVector<RefPtrWillBeMember<Event> > events; if (eventInterfaceFilter.isEmpty()) { events.swap(m_eventQueue); m_perFrameEvents.clear(); } else { WillBeHeapVector<RefPtrWillBeMember<Event> > remaining; for (auto& event : m_eventQueue) { if (event && event->interfaceName() == eventInterfaceFilter) { m_perFrameEvents.remove(eventTargetKey(event.get())); events.append(event.release()); } else { remaining.append(event.release()); } } remaining.swap(m_eventQueue); } for (size_t i = 0; i < events.size(); ++i) { EventTarget* eventTarget = events[i]->target(); // FIXME: we should figure out how to make dispatchEvent properly virtual to avoid // special casting window. // FIXME: We should not fire events for nodes that are no longer in the tree. if (LocalDOMWindow* window = eventTarget->toDOMWindow()) window->dispatchEvent(events[i], nullptr); else eventTarget->dispatchEvent(events[i]); InspectorInstrumentation::didRemoveEvent(eventTarget, events[i].get()); } }
bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, CachedScript* cachedScript) { EventTarget* target = errorEventTarget(); if (!target) return false; #if PLATFORM(IOS) if (target == target->toDOMWindow() && isDocument()) { Settings* settings = static_cast<Document*>(this)->settings(); if (settings && !settings->shouldDispatchJavaScriptWindowOnErrorEvents()) return false; } #endif String message = errorMessage; int line = lineNumber; int column = columnNumber; String sourceName = sourceURL; sanitizeScriptError(message, line, column, sourceName, cachedScript); ASSERT(!m_inDispatchErrorEvent); m_inDispatchErrorEvent = true; RefPtr<ErrorEvent> errorEvent = ErrorEvent::create(message, sourceName, line, column); target->dispatchEvent(errorEvent); m_inDispatchErrorEvent = false; return errorEvent->defaultPrevented(); }
void ReplayController::willDispatchEvent(const Event& event, Frame* frame) { EventTarget* target = event.target(); if (!target && !frame) return; Document* document = frame ? frame->document() : nullptr; // Fetch the document from the event target, because the target could be detached. if (Node* node = target->toNode()) document = node->inDocument() ? &node->document() : node->ownerDocument(); else if (DOMWindow* window = target->toDOMWindow()) document = window->document(); ASSERT(document); InputCursor& cursor = document->inputCursor(); #if !LOG_DISABLED bool eventIsUnrelated = !cursor.isCapturing() && !cursor.isReplaying(); logDispatchedDOMEvent(event, eventIsUnrelated); #else UNUSED_PARAM(cursor); #endif #if ENABLE_AGGRESSIVE_DETERMINISM_CHECKS // To ensure deterministic JS execution, all DOM events must be dispatched deterministically. // If these assertions fail, then this DOM event is being dispatched by a nondeterministic EventLoop // cycle, and may cause program execution to diverge if any JS code runs because of the DOM event. if (cursor.isCapturing() || cursor.isReplaying()) ASSERT(cursor.withinEventLoopInputExtent()); else if (cursor.isReplaying()) ASSERT(dispatcher().isDispatching()); #endif }
void ScriptedAnimationController::dispatchEvents() { Vector<RefPtr<Event> > events; events.swap(m_eventQueue); m_perFrameEvents.clear(); for (size_t i = 0; i < events.size(); ++i) { EventTarget* eventTarget = events[i]->target(); // FIXME: we should figure out how to make dispatchEvent properly virtual to avoid // special casting window. // FIXME: We should not fire events for nodes that are no longer in the tree. if (LocalDOMWindow* window = eventTarget->toDOMWindow()) window->dispatchEvent(events[i], nullptr); else eventTarget->dispatchEvent(events[i]); } }
ScriptPromise HTMLVideoElement::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& options, ExceptionState& exceptionState) { ASSERT(eventTarget.toDOMWindow()); if (getNetworkState() == HTMLMediaElement::NETWORK_EMPTY) { exceptionState.throwDOMException(InvalidStateError, "The provided element has not retrieved data."); return ScriptPromise(); } if (getReadyState() <= HTMLMediaElement::HAVE_METADATA) { exceptionState.throwDOMException(InvalidStateError, "The provided element's player has no current data."); return ScriptPromise(); } if (!sw || !sh) { exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width")); return ScriptPromise(); } return ImageBitmapSource::fulfillImageBitmap(scriptState, ImageBitmap::create(this, IntRect(sx, sy, sw, sh), eventTarget.toDOMWindow()->document(), options)); }
ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, HTMLCanvasElement* canvas, int sx, int sy, int sw, int sh, ExceptionState& exceptionState) { // This variant does not work in worker threads. ASSERT(eventTarget.toDOMWindow()); if (!canvas->originClean()) { exceptionState.throwSecurityError("The canvas element provided is tainted with cross-origin data."); return ScriptPromise(); } if (!sw || !sh) { exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width")); return ScriptPromise(); } // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 return fulfillImageBitmap(scriptState, canvas->isPaintable() ? ImageBitmap::create(canvas, IntRect(sx, sy, sw, sh)) : nullptr); }
static void logDispatchedDOMEvent(const Event& event, bool eventIsUnrelated) { EventTarget* target = event.target(); if (!target) return; // A DOM event is unrelated if it is being dispatched to a document that is neither capturing nor replaying. if (Node* node = target->toNode()) { LOG(WebReplay, "%-20s --->%s DOM event: type=%s, target=%u/node[%p] %s\n", "ReplayEvents", (eventIsUnrelated) ? "Unrelated" : "Dispatching", event.type().string().utf8().data(), frameIndexFromDocument((node->inDocument()) ? &node->document() : node->ownerDocument()), node, node->nodeName().utf8().data()); } else if (DOMWindow* window = target->toDOMWindow()) { LOG(WebReplay, "%-20s --->%s DOM event: type=%s, target=%u/window[%p] %s\n", "ReplayEvents", (eventIsUnrelated) ? "Unrelated" : "Dispatching", event.type().string().utf8().data(), frameIndexFromDocument(window->document()), window, window->location()->href().utf8().data()); } }