Esempio n. 1
0
void ScriptRunner::executeScripts()
{
    RefPtrWillBeRawPtr<Document> protect(m_document.get());

    WillBeHeapDeque<RawPtrWillBeMember<ScriptLoader>> scriptLoaders;
    scriptLoaders.swap(m_scriptsToExecuteSoon);

    WillBeHeapHashSet<RawPtrWillBeMember<ScriptLoader>> inorderSet;
    while (!m_scriptsToExecuteInOrder.isEmpty() && m_scriptsToExecuteInOrder.first()->isReady()) {
        ScriptLoader* script = m_scriptsToExecuteInOrder.takeFirst();
        inorderSet.add(script);
        scriptLoaders.append(script);
    }

    while (!scriptLoaders.isEmpty()) {
        scriptLoaders.takeFirst()->execute();
        m_document->decrementLoadEventDelayCount();

        if (yieldForHighPriorityWork())
            break;
    }

    // If we have to yield, we must re-enqueue any scriptLoaders back onto the front of
    // m_scriptsToExecuteInOrder or m_scriptsToExecuteSoon depending on where the script
    // came from.
    // NOTE a yield followed by a notifyScriptReady(... ASYNC_EXECUTION) will result in that script executing
    // before any pre-existing ScriptsToExecuteInOrder.
    while (!scriptLoaders.isEmpty()) {
        ScriptLoader* script = scriptLoaders.takeLast();
        if (inorderSet.contains(script))
            m_scriptsToExecuteInOrder.prepend(script);
        else
            m_scriptsToExecuteSoon.prepend(script);
    }
}
Esempio n. 2
0
void Fullscreen::eventQueueTimerFired(Timer<Fullscreen>*)
{
    // Since we dispatch events in this function, it's possible that the
    // document will be detached and GC'd. We protect it here to make sure we
    // can finish the function successfully.
    RefPtrWillBeRawPtr<Document> protectDocument(document());
    WillBeHeapDeque<RefPtrWillBeMember<Event> > eventQueue;
    m_eventQueue.swap(eventQueue);

    while (!eventQueue.isEmpty()) {
        RefPtrWillBeRawPtr<Event> event = eventQueue.takeFirst();
        Node* target = event->target()->toNode();

        // If the element was removed from our tree, also message the documentElement.
        if (!target->inDocument() && document()->documentElement()) {
            ASSERT(isPrefixed(event->type()));
            eventQueue.append(createEvent(event->type(), *document()->documentElement()));
        }

        target->dispatchEvent(event);
    }
}
void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenElementStack>*)
{
    // Since we dispatch events in this function, it's possible that the
    // document will be detached and GC'd. We protect it here to make sure we
    // can finish the function successfully.
    RefPtrWillBeRawPtr<Document> protectDocument(document());
    WillBeHeapDeque<RefPtrWillBeMember<Node> > changeQueue;
    m_fullScreenChangeEventTargetQueue.swap(changeQueue);
    WillBeHeapDeque<RefPtrWillBeMember<Node> > errorQueue;
    m_fullScreenErrorEventTargetQueue.swap(errorQueue);

    while (!changeQueue.isEmpty()) {
        RefPtrWillBeRawPtr<Node> node = changeQueue.takeFirst();
        if (!node)
            node = document()->documentElement();
        // The dispatchEvent below may have blown away our documentElement.
        if (!node)
            continue;

        // If the element was removed from our tree, also message the documentElement. Since we may
        // have a document hierarchy, check that node isn't in another document.
        if (!document()->contains(node.get()) && !node->inDocument())
            changeQueue.append(document()->documentElement());

        node->dispatchEvent(Event::createBubble(EventTypeNames::webkitfullscreenchange));
    }

    while (!errorQueue.isEmpty()) {
        RefPtrWillBeRawPtr<Node> node = errorQueue.takeFirst();
        if (!node)
            node = document()->documentElement();
        // The dispatchEvent below may have blown away our documentElement.
        if (!node)
            continue;

        // If the element was removed from our tree, also message the documentElement. Since we may
        // have a document hierarchy, check that node isn't in another document.
        if (!document()->contains(node.get()) && !node->inDocument())
            errorQueue.append(document()->documentElement());

        node->dispatchEvent(Event::createBubble(EventTypeNames::webkitfullscreenerror));
    }
}
Esempio n. 4
0
void WebSocket::EventQueue::dispatchQueuedEvents()
{
    if (m_state != Active)
        return;

    RefPtrWillBeRawPtr<EventQueue> protect(this);

    WillBeHeapDeque<RefPtrWillBeMember<Event> > events;
    events.swap(m_events);
    while (!events.isEmpty()) {
        if (m_state == Stopped || m_state == Suspended)
            break;
        ASSERT(m_state == Active);
        ASSERT(m_target->executionContext());
        m_target->dispatchEvent(events.takeFirst());
        // |this| can be stopped here.
    }
    if (m_state == Suspended) {
        while (!m_events.isEmpty())
            events.append(m_events.takeFirst());
        events.swap(m_events);
    }
}
Esempio n. 5
0
void Fullscreen::exitFullscreen()
{
    // The exitFullscreen() method must run these steps:

    // 1. Let doc be the context object. (i.e. "this")
    Document* currentDoc = document();
    if (!currentDoc->isActive())
        return;

    // 2. If doc's fullscreen element stack is empty, terminate these steps.
    if (m_fullScreenElementStack.isEmpty())
        return;

    // 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
    // element stack (if any), ordered so that the child of the doc is last and the document furthest
    // away from the doc is first.
    WillBeHeapDeque<RefPtrWillBeMember<Document> > descendants;
    for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
        if (!descendant->isLocalFrame())
            continue;
        ASSERT(toLocalFrame(descendant)->document());
        if (fullscreenElementFrom(*toLocalFrame(descendant)->document()))
            descendants.prepend(toLocalFrame(descendant)->document());
    }

    // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
    // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
    for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
        ASSERT(*i);
        RequestType requestType = from(**i).m_fullScreenElementStack.last().second;
        from(**i).clearFullscreenElementStack();
        enqueueChangeEvent(**i, requestType);
    }

    // 5. While doc is not null, run these substeps:
    Element* newTop = 0;
    while (currentDoc) {
        RequestType requestType = from(*currentDoc).m_fullScreenElementStack.last().second;

        // 1. Pop the top element of doc's fullscreen element stack.
        from(*currentDoc).popFullscreenElementStack();

        //    If doc's fullscreen element stack is non-empty and the element now at the top is either
        //    not in a document or its node document is not doc, repeat this substep.
        newTop = fullscreenElementFrom(*currentDoc);
        if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
            continue;

        // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
        // on doc.
        enqueueChangeEvent(*currentDoc, requestType);

        // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
        // container, set doc to that browsing context container's node document.
        if (!newTop && currentDoc->ownerElement()) {
            currentDoc = &currentDoc->ownerElement()->document();
            continue;
        }

        // 4. Otherwise, set doc to null.
        currentDoc = 0;
    }

    // 6. Return, and run the remaining steps asynchronously.
    // 7. Optionally, perform some animation.

    FrameHost* host = document()->frameHost();

    // Speculative fix for engaget.com/videos per crbug.com/336239.
    // FIXME: This check is wrong. We ASSERT(document->isActive()) above
    // so this should be redundant and should be removed!
    if (!host)
        return;

    // Only exit out of full screen window mode if there are no remaining elements in the
    // full screen stack.
    if (!newTop) {
        // FIXME: if the frame exiting fullscreen is not the frame that entered
        // fullscreen (but a parent frame for example), m_fullScreenElement
        // might be null. We want to pass an element that is part of the
        // document so we will pass the documentElement in that case.
        // This should be fix by exiting fullscreen for a frame instead of an
        // element, see https://crbug.com/441259
        host->chrome().client().exitFullScreenForElement(
            m_fullScreenElement ? m_fullScreenElement.get() : document()->documentElement());
        return;
    }

    // Otherwise, notify the chrome of the new full screen element.
    host->chrome().client().enterFullScreenForElement(newTop);
}