Exemple #1
0
void Page::refreshPlugins(bool reload)
{
    if (allPages().isEmpty())
        return;

    PluginData::refresh();

    Vector<RefPtr<LocalFrame> > framesNeedingReload;

    HashSet<Page*>::iterator end = allPages().end();
    for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
        Page* page = *it;

        // Clear out the page's plug-in data.
        if (page->m_pluginData)
            page->m_pluginData = nullptr;

        if (!reload)
            continue;

        for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
            if (frame->isLocalFrame() && toLocalFrame(frame)->document()->containsPlugins())
                framesNeedingReload.append(toLocalFrame(frame));
        }
    }

    for (size_t i = 0; i < framesNeedingReload.size(); ++i)
        framesNeedingReload[i]->loader().reload();
}
Exemple #2
0
void WebPagePopupImpl::closePopup() {
  {
    // This function can be called in EventDispatchForbiddenScope for the main
    // document, and the following operations dispatch some events.  It's safe
    // because web authors can't listen the events.
    EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents;

    if (m_page) {
      toLocalFrame(m_page->mainFrame())->loader().stopAllLoaders();
      PagePopupSupplement::uninstall(*toLocalFrame(m_page->mainFrame()));
    }
    bool closeAlreadyCalled = m_closing;
    m_closing = true;

    destroyPage();

    // m_widgetClient might be 0 because this widget might be already closed.
    if (m_widgetClient && !closeAlreadyCalled) {
      // closeWidgetSoon() will call this->close() later.
      m_widgetClient->closeWidgetSoon();
    }
  }
  m_popupClient->didClosePopup();
  m_webView->cleanupPagePopup();
}
Exemple #3
0
void Page::willBeDestroyed()
{
    RefPtr<Frame> mainFrame = m_mainFrame;

    if (mainFrame->isLocalFrame())
        toLocalFrame(mainFrame.get())->loader().frameDetached();

    // Disable all agents prior to resetting the frame view.
    m_inspectorController->willBeDestroyed();

    if (mainFrame->isLocalFrame()) {
        toLocalFrame(mainFrame.get())->setView(nullptr);
    } else {
        ASSERT(m_mainFrame->isRemoteFrame());
        toRemoteFrame(mainFrame.get())->setView(nullptr);
    }

    allPages().remove(this);
    if (ordinaryPages().contains(this))
        ordinaryPages().remove(this);

    if (m_scrollingCoordinator)
        m_scrollingCoordinator->willBeDestroyed();

#ifndef NDEBUG
    pageCounter.decrement();
#endif

    m_chrome->willBeDestroyed();
    m_mainFrame = 0;
    if (m_validationMessageClient)
        m_validationMessageClient->willBeDestroyed();
    WillBeHeapSupplementable<Page>::willBeDestroyed();
}
Exemple #4
0
WebInputEventResult WebPagePopupImpl::handleKeyEvent(
    const WebKeyboardEvent& event) {
  if (m_closing || !m_page->mainFrame() ||
      !toLocalFrame(m_page->mainFrame())->view())
    return WebInputEventResult::NotHandled;
  return toLocalFrame(m_page->mainFrame())->eventHandler().keyEvent(event);
}
void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy)
{
    ASSERT(request.resourceRequest().requestorOrigin() || (openerFrame.document() && openerFrame.document()->url().isEmpty()));

    if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
        return;

    if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPopups))
        return;

    if (!LocalDOMWindow::allowPopUp(openerFrame))
        return;

    if (policy == NavigationPolicyCurrentTab)
        policy = NavigationPolicyNewForegroundTab;

    WindowFeatures features;
    features.noopener = request.getShouldSetOpener() == NeverSetOpener;
    bool created;
    Frame* newFrame = createWindowHelper(openerFrame, openerFrame, openerFrame, request, features, policy, created);
    if (!newFrame)
        return;
    if (request.getShouldSendReferrer() == MaybeSendReferrer) {
        // TODO(japhet): Does ReferrerPolicy need to be proagated for RemoteFrames?
        if (newFrame->isLocalFrame())
            toLocalFrame(newFrame)->document()->setReferrerPolicy(openerFrame.document()->getReferrerPolicy());
    }

    // TODO(japhet): Form submissions on RemoteFrames don't work yet.
    FrameLoadRequest newRequest(0, request.resourceRequest());
    newRequest.setForm(request.form());
    if (newFrame->isLocalFrame())
        toLocalFrame(newFrame)->loader().load(newRequest);
}
void PaintLayerCompositor::updateIfNeededRecursive()
{
    FrameView* view = m_layoutView.frameView();
    if (view->shouldThrottleRendering())
        return;

    for (Frame* child = m_layoutView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
        if (!child->isLocalFrame())
            continue;
        LocalFrame* localFrame = toLocalFrame(child);
        // It's possible for trusted Pepper plugins to force hit testing in situations where
        // the frame tree is in an inconsistent state, such as in the middle of frame detach.
        // TODO(bbudge) Remove this check when trusted Pepper plugins are gone.
        if (localFrame->document()->isActive())
            localFrame->contentLayoutObject()->compositor()->updateIfNeededRecursive();
    }

    TRACE_EVENT0("blink", "PaintLayerCompositor::updateIfNeededRecursive");

    ASSERT(!m_layoutView.needsLayout());

    ScriptForbiddenScope forbidScript;

    // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree,
    // which asserts that it's not InCompositingUpdate.
    enableCompositingModeIfNeeded();

    if (m_needsUpdateDescendantDependentFlags) {
        updateDescendantDependentFlagsForEntireSubtree(*rootLayer());
        m_needsUpdateDescendantDependentFlags = false;
    }

    m_layoutView.commitPendingSelection();

    lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
    updateIfNeeded();
    lifecycle().advanceTo(DocumentLifecycle::CompositingClean);

    DocumentAnimations::updateCompositorAnimations(m_layoutView.document());

    m_layoutView.frameView()->scrollableArea()->updateCompositorScrollAnimations();
    if (const FrameView::ScrollableAreaSet* animatingScrollableAreas = m_layoutView.frameView()->animatingScrollableAreas()) {
        for (ScrollableArea* scrollableArea : *animatingScrollableAreas)
            scrollableArea->updateCompositorScrollAnimations();
    }

#if ENABLE(ASSERT)
    ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
    assertNoUnresolvedDirtyBits();
    for (Frame* child = m_layoutView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
        if (!child->isLocalFrame())
            continue;
        LocalFrame* localFrame = toLocalFrame(child);
        if (localFrame->shouldThrottleRendering())
            continue;
        localFrame->contentLayoutObject()->compositor()->assertNoUnresolvedDirtyBits();
    }
#endif
}
Exemple #7
0
void WindowProxy::updateActivityLogger() {
  m_scriptState->perContextData()->setActivityLogger(
      V8DOMActivityLogger::activityLogger(
          m_world->worldId(),
          m_frame->isLocalFrame() && toLocalFrame(m_frame)->document()
              ? toLocalFrame(m_frame)->document()->baseURI()
              : KURL()));
}
bool WebDevToolsAgentImpl::handleInputEvent(blink::Page* page, const WebInputEvent& inputEvent)
{
    if (!m_attached && !m_generatingEvent)
        return false;

    // FIXME: This workaround is required for touch emulation on Mac, where
    // compositor-side pinch handling is not enabled. See http://crbug.com/138003.
    bool isPinch = inputEvent.type == WebInputEvent::GesturePinchBegin || inputEvent.type == WebInputEvent::GesturePinchUpdate || inputEvent.type == WebInputEvent::GesturePinchEnd;
    if (isPinch && m_touchEventEmulationEnabled) {
        FrameView* frameView = page->deprecatedLocalMainFrame()->view();
        PlatformGestureEventBuilder gestureEvent(frameView, static_cast<const WebGestureEvent&>(inputEvent));
        float pageScaleFactor = page->pageScaleFactor();
        if (gestureEvent.type() == PlatformEvent::GesturePinchBegin) {
            m_lastPinchAnchorCss = adoptPtr(new blink::IntPoint(frameView->scrollPosition() + gestureEvent.position()));
            m_lastPinchAnchorDip = adoptPtr(new blink::IntPoint(gestureEvent.position()));
            m_lastPinchAnchorDip->scale(pageScaleFactor, pageScaleFactor);
        }
        if (gestureEvent.type() == PlatformEvent::GesturePinchUpdate && m_lastPinchAnchorCss) {
            float newPageScaleFactor = pageScaleFactor * gestureEvent.scale();
            blink::IntPoint anchorCss(*m_lastPinchAnchorDip.get());
            anchorCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor);
            m_webViewImpl->setPageScaleFactor(newPageScaleFactor);
            m_webViewImpl->setMainFrameScrollOffset(*m_lastPinchAnchorCss.get() - toIntSize(anchorCss));
        }
        if (gestureEvent.type() == PlatformEvent::GesturePinchEnd) {
            m_lastPinchAnchorCss.clear();
            m_lastPinchAnchorDip.clear();
        }
        return true;
    }

    InspectorController* ic = inspectorController();
    if (!ic)
        return false;

    if (WebInputEvent::isGestureEventType(inputEvent.type) && inputEvent.type == WebInputEvent::GestureTap) {
        // Only let GestureTab in (we only need it and we know PlatformGestureEventBuilder supports it).
        PlatformGestureEvent gestureEvent = PlatformGestureEventBuilder(page->deprecatedLocalMainFrame()->view(), static_cast<const WebGestureEvent&>(inputEvent));
        return ic->handleGestureEvent(toLocalFrame(page->mainFrame()), gestureEvent);
    }
    if (WebInputEvent::isMouseEventType(inputEvent.type) && inputEvent.type != WebInputEvent::MouseEnter) {
        // PlatformMouseEventBuilder does not work with MouseEnter type, so we filter it out manually.
        PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(page->deprecatedLocalMainFrame()->view(), static_cast<const WebMouseEvent&>(inputEvent));
        return ic->handleMouseEvent(toLocalFrame(page->mainFrame()), mouseEvent);
    }
    if (WebInputEvent::isTouchEventType(inputEvent.type)) {
        PlatformTouchEvent touchEvent = PlatformTouchEventBuilder(page->deprecatedLocalMainFrame()->view(), static_cast<const WebTouchEvent&>(inputEvent));
        return ic->handleTouchEvent(toLocalFrame(page->mainFrame()), touchEvent);
    }
    if (WebInputEvent::isKeyboardEventType(inputEvent.type)) {
        PlatformKeyboardEvent keyboardEvent = PlatformKeyboardEventBuilder(static_cast<const WebKeyboardEvent&>(inputEvent));
        return ic->handleKeyboardEvent(page->deprecatedLocalMainFrame(), keyboardEvent);
    }
    return false;
}
bool WebPagePopupImpl::handleGestureEvent(const WebGestureEvent& event)
{
    if (m_closing || !m_page || !m_page->mainFrame() || !toLocalFrame(m_page->mainFrame())->view())
        return false;
    if (event.type == WebInputEvent::GestureTap && !isGestureEventInWindow(event)) {
        cancel();
        return false;
    }
    LocalFrame& frame = *toLocalFrame(m_page->mainFrame());
    return frame.eventHandler().handleGestureEvent(PlatformGestureEventBuilder(frame.view(), event));
}
Exemple #10
0
void Page::setTimerAlignmentInterval(double interval)
{
    if (interval == m_timerAlignmentInterval)
        return;

    m_timerAlignmentInterval = interval;
    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
        if (frame->isLocalFrame() && toLocalFrame(frame)->document())
            toLocalFrame(frame)->document()->didChangeTimerAlignmentInterval();
    }
}
static LocalFrame* findFrameWithSecurityOrigin(LocalFrame* inspectedFrame, const String& originRawString)
{
    for (Frame* frame = inspectedFrame; frame; frame = frame->tree().traverseNext(inspectedFrame)) {
        if (!frame->isLocalFrame())
            continue;
        RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin();
        if (documentOrigin->toRawString() == originRawString)
            return toLocalFrame(frame);
    }
    return nullptr;
}
Exemple #12
0
Frame* FrameTree::find(const AtomicString& name) const
{
    if (name == "_self" || name == "_current" || name.isEmpty())
        return m_thisFrame;

    if (name == "_top") {
      for (LocalFrame* f = toLocalFrame(m_thisFrame); f; f = toLocalFrame(f->tree().parent())) {
            if (f->isNwFakeTop())
                return f;
        }
        return top();
    }

    if (name == "_parent") {
        if (m_thisFrame->isNwFakeTop())
            return m_thisFrame.get();
        return parent() ? parent() : m_thisFrame.get();
    }

    // Since "_blank" should never be any frame's name, the following just amounts to an optimization.
    if (name == "_blank")
        return nullptr;

    // Search subtree starting with this frame first.
    for (Frame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m_thisFrame))
        if (frame->tree().name() == name)
            return frame;

    // Search the entire tree for this page next.
    Page* page = m_thisFrame->page();

    // The frame could have been detached from the page, so check it.
    if (!page)
        return nullptr;

    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
        if (frame->tree().name() == name)
            return frame;

    // Search the entire tree of each of the other pages in this namespace.
    // FIXME: Is random order OK?
    const HashSet<Page*>& pages = Page::ordinaryPages();
    for (const Page* otherPage : pages) {
        if (otherPage != page) {
            for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
                if (frame->tree().name() == name)
                    return frame;
            }
        }
    }

    return nullptr;
}
Exemple #13
0
LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
{
    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
        // FIXME: RemoteFrame security origins are not yet available.
        if (!frame->isLocalFrame())
            continue;
        RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin();
        if (documentOrigin->toRawString() == originRawString)
            return toLocalFrame(frame);
    }
    return 0;
}
Exemple #14
0
void WindowProxy::createContext() {
  // FIXME: This should be a null check of m_frame->client(), but there are
  // still some edge cases
  // that this fails to catch during frame detach.
  if (m_frame->isLocalFrame() &&
      !toLocalFrame(m_frame)->loader().documentLoader())
    return;

  // Create a new v8::Context with the window object as the global object
  // (aka the inner global).  Reuse the global proxy object (aka the outer
  // global) if it already exists.  See the comments in
  // setupWindowPrototypeChain for the structure of the prototype chain of
  // the global object.
  v8::Local<v8::ObjectTemplate> globalTemplate =
      V8Window::domTemplate(m_isolate, *m_world)->InstanceTemplate();
  if (globalTemplate.IsEmpty())
    return;

  // FIXME: It's not clear what the right thing to do for remote frames is.
  // The extensions registered don't generally seem to make sense for remote
  // frames, so skip it for now.
  Vector<const char*> extensionNames;
  if (m_frame->isLocalFrame()) {
    LocalFrame* frame = toLocalFrame(m_frame);
    // Dynamically tell v8 about our extensions now.
    const V8Extensions& extensions = ScriptController::registeredExtensions();
    extensionNames.reserveInitialCapacity(extensions.size());
    int extensionGroup = m_world->extensionGroup();
    int worldId = m_world->worldId();
    for (const auto* extension : extensions) {
      if (!frame->loader().client()->allowScriptExtension(
              extension->name(), extensionGroup, worldId))
        continue;

      extensionNames.append(extension->name());
    }
  }
  v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(),
                                                    extensionNames.data());

  v8::Local<v8::Context> context;
  {
    V8PerIsolateData::UseCounterDisabledScope useCounterDisabled(
        V8PerIsolateData::from(m_isolate));
    context = v8::Context::New(m_isolate, &extensionConfiguration,
                               globalTemplate, m_global.newLocal(m_isolate));
  }
  if (context.IsEmpty())
    return;
  m_scriptState = ScriptState::create(context, m_world);
}
Frame* FrameTree::scopedChild(const AtomicString& name) const
{
    if (!m_thisFrame->isLocalFrame())
        return 0;

    TreeScope* scope = toLocalFrame(m_thisFrame)->document();
    if (!scope)
        return 0;

    for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
        if (child->tree().name() == name && child->isLocalFrame() && toLocalFrame(child)->inScope(scope))
            return child;
    return 0;
}
Exemple #16
0
WebInputEventResult WebPagePopupImpl::handleGestureEvent(
    const WebGestureEvent& event) {
  if (m_closing || !m_page || !m_page->mainFrame() ||
      !toLocalFrame(m_page->mainFrame())->view())
    return WebInputEventResult::NotHandled;
  if ((event.type == WebInputEvent::GestureTap ||
       event.type == WebInputEvent::GestureTapDown) &&
      !isViewportPointInWindow(event.x, event.y)) {
    cancel();
    return WebInputEventResult::NotHandled;
  }
  LocalFrame& frame = *toLocalFrame(m_page->mainFrame());
  return frame.eventHandler().handleGestureEvent(
      PlatformGestureEventBuilder(frame.view(), event));
}
Exemple #17
0
void Page::setNeedsRecalcStyleInAllFrames()
{
    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
        if (frame->isLocalFrame())
            toLocalFrame(frame)->document()->styleResolverChanged();
    }
}
Exemple #18
0
void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame)
{
    Frame* parentFrame = frame->tree().parent();
    if (!parentFrame->isLocalFrame())
        parentFrame = 0;
    m_frontend->frameAttached(frameId(frame), frameId(toLocalFrame(parentFrame)));
}
void ScreenOrientationController::notifyOrientationChanged()
{
    ASSERT(RuntimeEnabledFeatures::screenOrientationEnabled());

    if (!isActiveAndVisible())
        return;

    updateOrientation();

    // Keep track of the frames that need to be notified before notifying the
    // current frame as it will prevent side effects from the change event
    // handlers.
    WillBeHeapVector<RefPtrWillBeMember<LocalFrame> > childFrames;
    for (Frame* child = frame()->tree().firstChild(); child; child = child->tree().nextSibling()) {
        if (child->isLocalFrame())
            childFrames.append(toLocalFrame(child));
    }

    // Notify current orientation object.
    if (!m_dispatchEventTimer.isActive())
        m_dispatchEventTimer.startOneShot(0, FROM_HERE);

    // ... and child frames, if they have a ScreenOrientationController.
    for (size_t i = 0; i < childFrames.size(); ++i) {
        if (ScreenOrientationController* controller = ScreenOrientationController::from(*childFrames[i]))
            controller->notifyOrientationChanged();
    }
}
void WindowProxy::updateDocumentProperty()
{
    if (!m_world->isMainWorld())
        return;

    if (m_frame->isRemoteFrame()) {
        return;
    }

    ScriptState::Scope scope(m_scriptState.get());
    v8::Local<v8::Context> context = m_scriptState->context();
    LocalFrame* frame = toLocalFrame(m_frame);
    v8::Local<v8::Value> documentWrapper = toV8(frame->document(), context->Global(), context->GetIsolate());
    if (documentWrapper.IsEmpty())
        return;
    ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty());
    if (m_document.isEmpty())
        updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper));
    checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document());

    ASSERT(documentWrapper->IsObject());
    // TODO(bashi): Avoid using ForceSet(). When we use accessors to implement
    // attributes, we may be able to remove updateDocumentProperty().
    if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete))))
        return;

    // We also stash a reference to the document on the inner global object so that
    // LocalDOMWindow objects we obtain from JavaScript references are guaranteed to have
    // live Document objects.
    V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8HiddenValue::document(m_isolate), documentWrapper);
}
void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior)
{
    if (!isContextInitialized())
        return;

    v8::HandleScope handleScope(m_isolate);
    v8::Local<v8::Context> context = m_scriptState->context();
    if (m_frame->isLocalFrame()) {
        LocalFrame* frame = toLocalFrame(m_frame);
        // The embedder could run arbitrary code in response to the willReleaseScriptContext callback, so all disposing should happen after it returns.
        frame->loader().client()->willReleaseScriptContext(context, m_world->worldId());
        InspectorInstrumentation::willReleaseScriptContext(frame, m_scriptState.get());
    }

    m_document.clear();

    if (behavior == DetachGlobal)
        m_scriptState->detachGlobalObject();

    m_scriptState->disposePerContextData();

    // It's likely that disposing the context has created a lot of
    // garbage. Notify V8 about this so it'll have a chance of cleaning
    // it up when idle.
    V8GCForContextDispose::instance().notifyContextDisposed(m_frame->isMainFrame());
}
IntersectionObserver* IntersectionObserver::create(const IntersectionObserverInit& observerInit, IntersectionObserverCallback& callback, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<Node> root = observerInit.root();
    if (!root) {
        // TODO(szager): Use Document instead of document element for implicit root. (crbug.com/570538)
        ExecutionContext* context = callback.executionContext();
        ASSERT(context->isDocument());
        Frame* mainFrame = toDocument(context)->frame()->tree().top();
        if (mainFrame && mainFrame->isLocalFrame())
            root = toLocalFrame(mainFrame)->document();
    }
    if (!root) {
        exceptionState.throwDOMException(HierarchyRequestError, "Unable to get root node in main frame to track.");
        return nullptr;
    }

    Vector<Length> rootMargin;
    if (observerInit.hasRootMargin())
        parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState);
    if (exceptionState.hadException())
        return nullptr;

    Vector<float> thresholds;
    if (observerInit.hasThreshold())
        parseThresholds(observerInit.threshold(), thresholds, exceptionState);
    else
        thresholds.append(0);
    if (exceptionState.hadException())
        return nullptr;

    return new IntersectionObserver(callback, *root, rootMargin, thresholds);
}
void WindowProxy::updateDocumentProperty()
{
    if (!m_world->isMainWorld())
        return;

    if (m_frame->isRemoteFrame()) {
        return;
    }

    ScriptState::Scope scope(m_scriptState.get());
    v8::Local<v8::Context> context = m_scriptState->context();
    LocalFrame* frame = toLocalFrame(m_frame);
    v8::Local<v8::Value> documentWrapper = toV8(frame->document(), context->Global(), context->GetIsolate());
    if (documentWrapper.IsEmpty())
        return;
    ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty());
    if (m_document.isEmpty())
        updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper));
    checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document());

    ASSERT(documentWrapper->IsObject());
    // TODO(jochen): Don't replace the accessor with a data value. We need a way to tell v8 that the accessor's return value won't change after this point.
    if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete))))
        return;
}
void BeaconLoader::willSendRequest(WebURLLoader*, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse)
{
    passedNewRequest.setAllowStoredCredentials(true);
    ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest());
    const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse());

    ASSERT(!newRequest.isNull());
    ASSERT(!redirectResponse.isNull());

    String errorDescription;
    StoredCredentials withCredentials = AllowStoredCredentials;
    ResourceLoaderOptions options;
    if (!CrossOriginAccessControl::handleRedirect(m_beaconOrigin.get(), newRequest, redirectResponse, withCredentials, options, errorDescription)) {
        if (page() && page()->mainFrame()) {
            if (page()->mainFrame()->isLocalFrame()) {
                LocalFrame* localFrame = toLocalFrame(page()->mainFrame());
                if (localFrame->document())
                    localFrame->document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorDescription));
            }
        }
        // Cancel the load and self destruct.
        dispose();
        return;
    }
    // FIXME: http://crbug.com/427429 is needed to correctly propagate
    // updates of Origin: following this successful redirect.
}
Exemple #25
0
bool SpellCheckerClientImpl::shouldSpellcheckByDefault()
{
    // Spellcheck should be enabled for all editable areas (such as textareas,
    // contentEditable regions, designMode docs and inputs).
    if (!m_webView->focusedCoreFrame()->isLocalFrame())
        return false;
    const LocalFrame* frame = toLocalFrame(m_webView->focusedCoreFrame());
    if (!frame)
        return false;
    if (frame->spellChecker().isSpellCheckingEnabledInFocusedNode())
        return true;
    const Document* document = frame->document();
    if (!document)
        return false;
    const Element* element = document->focusedElement();
    // If |element| is null, we default to allowing spellchecking. This is done
    // in order to mitigate the issue when the user clicks outside the textbox,
    // as a result of which |element| becomes null, resulting in all the spell
    // check markers being deleted. Also, the LocalFrame will decide not to do
    // spellchecking if the user can't edit - so returning true here will not
    // cause any problems to the LocalFrame's behavior.
    if (!element)
        return true;
    const LayoutObject* layoutObject = element->layoutObject();
    if (!layoutObject)
        return false;

    return true;
}
void MixedContentChecker::handleCertificateError(LocalFrame* frame, const ResourceResponse& response, WebURLRequest::FrameType frameType, WebURLRequest::RequestContext requestContext)
{
    Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType);
    if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame)
        return;

    // TODO(estark): handle remote frames, perhaps by omitting security info when the effective frame is remote.
    if (!effectiveFrame->isLocalFrame())
        return;

    LocalFrame* localEffectiveFrame = toLocalFrame(effectiveFrame);

    // Use the current local frame's client; the embedder doesn't
    // distinguish mixed content signals from different frames on the
    // same page.
    FrameLoaderClient* client = frame->loader().client();
    ContextType contextType = MixedContentChecker::contextTypeFromContext(requestContext, effectiveFrame);
    if (contextType == ContextTypeBlockable) {
        client->didRunContentWithCertificateErrors(response.url(), response.getSecurityInfo(), mainResourceUrlForFrame(effectiveFrame), localEffectiveFrame->loader().documentLoader()->response().getSecurityInfo());
    } else {
        // contextTypeFromContext() never returns NotMixedContent (it
        // computes the type of mixed content, given that the content is
        // mixed).
        ASSERT(contextType != ContextTypeNotMixedContent);
        client->didDisplayContentWithCertificateErrors(response.url(), response.getSecurityInfo(), mainResourceUrlForFrame(effectiveFrame), localEffectiveFrame->loader().documentLoader()->response().getSecurityInfo());
    }
}
Exemple #27
0
void PageAnimator::serviceScriptedAnimations(double monotonicAnimationStartTime)
{
    m_animationFramePending = false;
    TemporaryChange<bool> servicing(m_servicingAnimations, true);

    WillBeHeapVector<RefPtrWillBeMember<Document> > documents;
    for (RefPtr<Frame> frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
        if (frame->isLocalFrame())
            documents.append(toLocalFrame(frame.get())->document());
    }

    for (size_t i = 0; i < documents.size(); ++i) {
        if (documents[i]->frame()) {
            documents[i]->view()->serviceScrollAnimations();

            if (const FrameView::ScrollableAreaSet* scrollableAreas = documents[i]->view()->scrollableAreas()) {
                for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
                    (*it)->serviceScrollAnimations();
            }
        }
    }

    for (size_t i = 0; i < documents.size(); ++i) {
        DocumentAnimations::updateAnimationTimingForAnimationFrame(*documents[i], monotonicAnimationStartTime);
        SVGDocumentExtensions::serviceOnAnimationFrame(*documents[i], monotonicAnimationStartTime);
    }

    for (size_t i = 0; i < documents.size(); ++i)
        documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
}
Exemple #28
0
bool SVGImage::currentFrameHasSingleSecurityOrigin() const
{
    if (!m_page)
        return true;

    LocalFrame* frame = toLocalFrame(m_page->mainFrame());

    RELEASE_ASSERT(frame->document()->loadEventFinished());

    SVGSVGElement* rootElement = frame->document()->accessSVGExtensions().rootElement();
    if (!rootElement)
        return true;

    // Don't allow foreignObject elements or images that are not known to be
    // single-origin since these can leak cross-origin information.
    for (Node* node = rootElement; node; node = ComposedTreeTraversal::next(*node)) {
        if (isSVGForeignObjectElement(*node))
            return false;
        if (isSVGImageElement(*node)) {
            if (!toSVGImageElement(*node).currentFrameHasSingleSecurityOrigin())
                return false;
        } else if (isSVGFEImageElement(*node)) {
            if (!toSVGFEImageElement(*node).currentFrameHasSingleSecurityOrigin())
                return false;
        }
    }

    // Because SVG image rendering disallows external resources and links, these
    // images effectively are restricted to a single security origin.
    return true;
}
inline void TextResourceDecoderBuilder::setupEncoding(TextResourceDecoder* decoder, Document* document)
{
    LocalFrame* frame = document->frame();
    LocalFrame* parentFrame = 0;
    if (frame && frame->tree().parent() && frame->tree().parent()->isLocalFrame())
        parentFrame = toLocalFrame(frame->tree().parent());

    if (!m_encoding.isEmpty())
        decoder->setEncoding(m_encoding.string(), m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader);

    // Set the hint encoding to the parent frame encoding only if
    // the parent and the current frames share the security origin.
    // We impose this condition because somebody can make a child frameg63
    // containing a carefully crafted html/javascript in one encoding
    // that can be mistaken for hintEncoding (or related encoding) by
    // an auto detector. When interpreted in the latter, it could be
    // an attack vector.
    // FIXME: This might be too cautious for non-7bit-encodings and
    // we may consider relaxing this later after testing.
    if (frame && canReferToParentFrameEncoding(frame, parentFrame)) {
        if (parentFrame->document()->encodingWasDetectedHeuristically())
            decoder->setHintEncoding(parentFrame->document()->encoding());

        if (m_encoding.isEmpty())
            decoder->setEncoding(parentFrame->document()->inputEncoding().string(), TextResourceDecoder::EncodingFromParentFrame);
    }
}
ScopedPageLoadDeferrer::ScopedPageLoadDeferrer(Page* exclusion)
{
    const HashSet<Page*>& pages = Page::ordinaryPages();

    HashSet<Page*>::const_iterator end = pages.end();
    for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
        Page* page = *it;
        if (page == exclusion || page->defersLoading())
            continue;

        if (page->mainFrame()->isLocalFrame()) {
            m_deferredFrames.append(page->deprecatedLocalMainFrame());

            // Ensure that we notify the client if the initial empty document is accessed before
            // showing anything modal, to prevent spoofs while the modal window or sheet is visible.
            page->deprecatedLocalMainFrame()->loader().notifyIfInitialDocumentAccessed();
        }

        // This code is not logically part of load deferring, but we do not want JS code executed
        // beneath modal windows or sheets, which is exactly when ScopedPageLoadDeferrer is used.
        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
            if (frame->isLocalFrame())
                toLocalFrame(frame)->document()->suspendScheduledTasks();
        }
    }

    size_t count = m_deferredFrames.size();
    for (size_t i = 0; i < count; ++i) {
        if (Page* page = m_deferredFrames[i]->page())
            page->setDefersLoading(true);
    }
}