Beispiel #1
0
LayoutUnit LayoutMedia::computePanelWidth(const LayoutRect& mediaRect) const {
  // TODO(mlamouri): we don't know if the main frame has an horizontal scrollbar
  // if it is out of process. See https://crbug.com/662480
  if (document().page()->mainFrame()->isRemoteFrame())
    return mediaRect.width();

  FrameHost* frameHost = document().frameHost();
  LocalFrame* mainFrame = document().page()->deprecatedLocalMainFrame();
  FrameView* pageView = mainFrame ? mainFrame->view() : nullptr;
  if (!frameHost || !mainFrame || !pageView)
    return mediaRect.width();

  if (pageView->horizontalScrollbarMode() != ScrollbarAlwaysOff)
    return mediaRect.width();

  // On desktop, this will include scrollbars when they stay visible.
  const LayoutUnit visibleWidth(frameHost->visualViewport().visibleWidth());
  const LayoutUnit absoluteXOffset(
      localToAbsolute(
          FloatPoint(mediaRect.location()),
          UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries)
          .x());
  DCHECK_GE(visibleWidth - absoluteXOffset, 0);

  return std::min(mediaRect.width(), visibleWidth - absoluteXOffset);
}
Beispiel #2
0
int Screen::availTop() const
{
    if (!m_frame)
        return 0;
    FrameHost* host = m_frame->host();
    if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
        return lroundf(screenAvailableRect(m_frame->view()).y() * host->deviceScaleFactor());
    return static_cast<int>(screenAvailableRect(m_frame->view()).y());
}
Beispiel #3
0
unsigned Screen::width() const
{
    if (!m_frame)
        return 0;
    FrameHost* host = m_frame->host();
    if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
        return lroundf(screenRect(m_frame->view()).width() * host->deviceScaleFactor());
    return static_cast<unsigned>(screenRect(m_frame->view()).width());
}
Beispiel #4
0
void UseCounter::count(const Document& document, Feature feature)
{
    FrameHost* host = document.frameHost();
    if (!host)
        return;

    ASSERT(host->useCounter().deprecationMessage(feature).isEmpty());
    host->useCounter().recordMeasurement(feature);
}
Beispiel #5
0
bool UseCounter::isCounted(Document& document, Feature feature)
{
    Frame* frame = document.frame();
    if (!frame)
        return false;
    FrameHost* host = frame->host();
    if (!host)
        return false;
    return host->useCounter().hasRecordedMeasurement(feature);
}
Beispiel #6
0
int Screen::width() const
{
    if (!m_frame)
        return 0;
    FrameHost* host = m_frame->host();
    if (!host)
        return 0;
    if (host->settings().reportScreenSizeInPhysicalPixelsQuirk())
        return lroundf(host->chromeClient().screenInfo().rect.width * host->deviceScaleFactor());
    return host->chromeClient().screenInfo().rect.width;
}
Beispiel #7
0
int Screen::availTop() const
{
    if (!m_frame)
        return 0;
    FrameHost* host = m_frame->host();
    if (!host)
        return 0;
    if (host->settings().reportScreenSizeInPhysicalPixelsQuirk())
        return lroundf(host->chromeClient().screenInfo().availableRect.y * host->deviceScaleFactor());
    return static_cast<int>(host->chromeClient().screenInfo().availableRect.y);
}
Beispiel #8
0
void UseCounter::count(const Frame* frame, Feature feature)
{
    if (!frame)
        return;
    FrameHost* host = frame->host();
    if (!host)
        return;

    ASSERT(host->useCounter().deprecationMessage(feature).isEmpty());
    host->useCounter().recordMeasurement(feature);
}
Beispiel #9
0
void UseCounter::countDeprecation(const Document& document, Feature feature)
{
    FrameHost* host = document.frameHost();
    if (!host)
        return;

    if (host->useCounter().recordMeasurement(feature)) {
        ASSERT(!host->useCounter().deprecationMessage(feature).isEmpty());
        host->console().addMessage(DeprecationMessageSource, WarningMessageLevel, host->useCounter().deprecationMessage(feature));
    }
}
Beispiel #10
0
void Deprecation::warnOnDeprecatedProperties(const LocalFrame* frame, CSSPropertyID unresolvedProperty)
{
    FrameHost* host = frame ? frame->host() : nullptr;
    if (!host || host->deprecation().isSuppressed(unresolvedProperty))
        return;

    String message = deprecationMessage(unresolvedProperty);
    if (!message.isEmpty()) {
        host->deprecation().suppress(unresolvedProperty);
        frame->console().addMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, message));
    }
}
Beispiel #11
0
void UseCounter::countDeprecation(const LocalFrame* frame, Feature feature)
{
    if (!frame)
        return;
    FrameHost* host = frame->host();
    if (!host)
        return;

    if (host->useCounter().recordMeasurement(feature)) {
        ASSERT(!host->useCounter().deprecationMessage(feature).isEmpty());
        frame->console().addMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, host->useCounter().deprecationMessage(feature)));
    }
}
bool UseCounter::isCounted(Document& document, const String& string)
{
    Frame* frame = document.frame();
    if (!frame)
        return false;
    FrameHost* host = frame->host();
    if (!host)
        return false;

    CSSPropertyID propertyID = cssPropertyID(string);
    if (propertyID == CSSPropertyInvalid)
        return false;
    return host->useCounter().isCounted(propertyID);
}
Beispiel #13
0
void HTMLAnchorElement::handleClick(Event* event)
{
    Frame* frame = document().frame();
    if (!frame)
        return;
    FrameHost* host = frame->host();
    if (!host)
        return;
    mojo::URLRequestPtr request = mojo::URLRequest::New();
    request->url = href().string().toUTF8();
    host->services().NavigatorHost()->RequestNavigate(
        mojo::TARGET_SOURCE_NODE, request.Pass());
    event->setDefaultHandled();
}
Beispiel #14
0
bool BarProp::visible() const {
  if (!frame())
    return false;
  FrameHost* host = frame()->host();
  if (!host)
    return false;

  switch (m_type) {
    case Locationbar:
    case Personalbar:
    case Toolbar:
      return host->chromeClient().toolbarsVisible();
    case Menubar:
      return host->chromeClient().menubarVisible();
    case Scrollbars:
      return host->chromeClient().scrollbarsVisible();
    case Statusbar:
      return host->chromeClient().statusbarVisible();
  }

  ASSERT_NOT_REACHED();
  return false;
}
Storage* DOMWindowStorage::localStorage(ExceptionState& exceptionState) const
{
    if (!m_window->isCurrentlyDisplayedInFrame())
        return nullptr;
    Document* document = m_window->document();
    if (!document)
        return nullptr;
    String accessDeniedMessage = "Access is denied for this document.";
    if (!document->securityOrigin()->canAccessLocalStorage()) {
        if (document->isSandboxed(SandboxOrigin))
            exceptionState.throwSecurityError("The document is sandboxed and lacks the 'allow-same-origin' flag.");
        else if (document->url().protocolIs("data"))
            exceptionState.throwSecurityError("Storage is disabled inside 'data:' URLs.");
        else
            exceptionState.throwSecurityError(accessDeniedMessage);
        return nullptr;
    }
    if (m_localStorage) {
        if (!m_localStorage->area()->canAccessStorage(m_window->frame())) {
            exceptionState.throwSecurityError(accessDeniedMessage);
            return nullptr;
        }
        return m_localStorage;
    }
    // FIXME: Seems this check should be much higher?
    FrameHost* host = document->frameHost();
    if (!host || !host->settings().localStorageEnabled())
        return nullptr;
    StorageArea* storageArea = StorageNamespace::localStorageArea(document->securityOrigin());
    if (!storageArea->canAccessStorage(m_window->frame())) {
        exceptionState.throwSecurityError(accessDeniedMessage);
        return nullptr;
    }
    m_localStorage = Storage::create(m_window->frame(), storageArea);
    return m_localStorage;
}
static Frame* createNewWindow(LocalFrame& openerFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, bool& created)
{
    FrameHost* oldHost = openerFrame.host();
    if (!oldHost)
        return nullptr;

    Page* page = oldHost->chromeClient().createWindow(&openerFrame, request, features, policy);
    if (!page)
        return nullptr;
    FrameHost* host = &page->frameHost();

    ASSERT(page->mainFrame());
    LocalFrame& frame = *toLocalFrame(page->mainFrame());

    if (request.frameName() != "_blank")
        frame.tree().setName(request.frameName());

    host->chromeClient().setWindowFeatures(features);

    // 'x' and 'y' specify the location of the window, while 'width' and 'height'
    // specify the size of the viewport. We can only resize the window, so adjust
    // for the difference between the window size and the viewport size.

    IntRect windowRect = host->chromeClient().windowRect();
    IntSize viewportSize = host->chromeClient().pageRect().size();

    if (features.xSet)
        windowRect.setX(features.x);
    if (features.ySet)
        windowRect.setY(features.y);
    if (features.widthSet)
        windowRect.setWidth(features.width + (windowRect.width() - viewportSize.width()));
    if (features.heightSet)
        windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height()));

    host->chromeClient().setWindowRectWithAdjustment(windowRect);
    host->chromeClient().show(policy);

    if (openerFrame.document()->isSandboxed(SandboxPropagatesToAuxiliaryBrowsingContexts))
        frame.loader().forceSandboxFlags(openerFrame.securityContext()->getSandboxFlags());

    // This call may suspend the execution by running nested message loop.
    InspectorInstrumentation::windowCreated(&openerFrame, &frame);
    created = true;
    return &frame;
}
void FullscreenElementStack::webkitExitFullscreen()
{
    // The exitFullscreen() method must run these steps:

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

    // 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.
    Deque<RefPtr<Document> > descendants;
    for (Frame* descendant = document()->frame() ?  document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
        if (fullscreenElementFrom(descendant->document()))
            descendants.prepend(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 (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
        from(i->get())->clearFullscreenElementStack();
        addDocumentToFullScreenChangeEventQueue(i->get());
    }

    // 5. While doc is not null, run these substeps:
    Element* newTop = 0;
    while (currentDoc) {
        // 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.
        addDocumentToFullScreenChangeEventQueue(currentDoc);

        // 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) {
        host->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
        return;
    }

    // Otherwise, notify the chrome of the new full screen element.
    host->chrome().client().enterFullScreenForElement(newTop);
}
Beispiel #18
0
static Frame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSetOpener shouldSetOpener, bool& created)
{
    created = false;

    ASSERT(!features.dialog || request.frameName().isEmpty());
    ASSERT(request.resourceRequest().requestorOrigin() || openerFrame.document()->url().isEmpty());
    ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeAuxiliary);

    if (!request.frameName().isEmpty() && request.frameName() != "_blank" && policy == NavigationPolicyIgnore) {
        if (Frame* frame = lookupFrame.findFrameForNavigation(request.frameName(), openerFrame)) {
            if (request.frameName() != "_self") {
                if (FrameHost* host = frame->host()) {
                    if (host == openerFrame.host())
                        frame->page()->focusController().setFocusedFrame(frame);
                    else
                        host->chromeClient().focus();
                }
            }
            return frame;
        }
    }

    // Sandboxed frames cannot open new auxiliary browsing contexts.
    if (openerFrame.document()->isSandboxed(SandboxPopups)) {
        // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
        openerFrame.document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set."));
        return nullptr;
    }

    if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindows())
        return openerFrame.tree().top();

    FrameHost* oldHost = openerFrame.host();
    if (!oldHost)
        return nullptr;

    Page* page = oldHost->chromeClient().createWindow(&openerFrame, request, features, policy, shouldSetOpener);
    if (!page)
        return nullptr;
    FrameHost* host = &page->frameHost();

    ASSERT(page->mainFrame());
    Frame& frame = *page->mainFrame();

    if (request.frameName() != "_blank")
        frame.tree().setName(request.frameName());

    host->chromeClient().setWindowFeatures(features);

    // 'x' and 'y' specify the location of the window, while 'width' and 'height'
    // specify the size of the viewport. We can only resize the window, so adjust
    // for the difference between the window size and the viewport size.

    IntRect windowRect = host->chromeClient().windowRect();
    IntSize viewportSize = host->chromeClient().pageRect().size();

    if (features.xSet)
        windowRect.setX(features.x);
    if (features.ySet)
        windowRect.setY(features.y);
    if (features.widthSet)
        windowRect.setWidth(features.width + (windowRect.width() - viewportSize.width()));
    if (features.heightSet)
        windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height()));

    host->chromeClient().setWindowRectWithAdjustment(windowRect);
    host->chromeClient().show(policy);

    // TODO(japhet): There's currently no way to set sandbox flags on a RemoteFrame and have it propagate
    // to the real frame in a different process. See crbug.com/483584.
    if (frame.isLocalFrame() && openerFrame.document()->isSandboxed(SandboxPropagatesToAuxiliaryBrowsingContexts))
        toLocalFrame(&frame)->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());

    created = true;
    return &frame;
}
Beispiel #19
0
// https://fullscreen.spec.whatwg.org/#exit-fullscreen
void Fullscreen::exitFullscreen(Document& document) {
  // The exitFullscreen() method must run these steps:

  // 1. Let doc be the context object. (i.e. "this")
  if (!document.isActive())
    return;

  // 2. If doc's fullscreen element stack is empty, terminate these steps.
  if (!fullscreenElementFrom(document))
    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.
  HeapDeque<Member<Document>> descendants;
  for (Frame* descendant =
           document.frame() ? document.frame()->tree().traverseNext() : nullptr;
       descendant; descendant = descendant->tree().traverseNext()) {
    if (!descendant->isLocalFrame())
      continue;
    DCHECK(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 (auto& descendant : descendants) {
    DCHECK(descendant);
    RequestType requestType =
        from(*descendant).m_fullscreenElementStack.last().second;
    from(*descendant).clearFullscreenElementStack();
    from(document).enqueueChangeEvent(*descendant, requestType);
  }

  // 5. While doc is not null, run these substeps:
  Element* newTop = nullptr;
  for (Document* currentDoc = &document; 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->isConnected() || newTop->document() != currentDoc))
      continue;

    // 2. Queue a task to fire an event named fullscreenchange with its bubbles
    // attribute set to true on doc.
    from(document).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.
    //
    // OOPIF: If browsing context container's document is in another
    // process, keep moving up the ancestor chain and looking for a
    // browsing context container with a local document.
    // TODO(alexmos): Deal with nested fullscreen cases, see
    // https://crbug.com/617369.
    if (!newTop) {
      Frame* frame = currentDoc->frame()->tree().parent();
      while (frame && frame->isRemoteFrame())
        frame = frame->tree().parent();
      if (frame) {
        currentDoc = toLocalFrame(frame)->document();
        continue;
      }
    }

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

  // 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 DCHECK(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_currentFullScreenElement 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
    Element* currentFullScreenElement = currentFullScreenElementFrom(document);
    host->chromeClient().exitFullscreenForElement(
        currentFullScreenElement ? currentFullScreenElement
                                 : document.documentElement());
    return;
  }

  // Otherwise, notify the chrome of the new full screen element.
  host->chromeClient().enterFullscreenForElement(newTop);
}
Beispiel #20
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);
}
Beispiel #21
0
static Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, bool& created)
{
    ASSERT(!features.dialog || request.frameName().isEmpty());

    if (!request.frameName().isEmpty() && request.frameName() != "_blank" && policy == NavigationPolicyIgnore) {
        if (Frame* frame = lookupFrame->loader().findFrameForNavigation(request.frameName(), openerFrame->document())) {
            if (request.frameName() != "_self")
                frame->page()->focusController().setFocusedFrame(frame);
            created = false;
            return frame;
        }
    }

    // Sandboxed frames cannot open new auxiliary browsing contexts.
    if (openerFrame->document()->isSandboxed(SandboxPopups)) {
        // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
        openerFrame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
        return 0;
    }

    if (openerFrame->settings() && !openerFrame->settings()->supportsMultipleWindows()) {
        created = false;
        return openerFrame->tree().top();
    }

    Page* oldPage = openerFrame->page();
    if (!oldPage)
        return 0;

    Page* page = oldPage->chrome().client().createWindow(openerFrame, request, features, policy, shouldSendReferrer);
    if (!page)
        return 0;
    FrameHost* host = &page->frameHost();

    Frame* frame = page->mainFrame();

    frame->loader().forceSandboxFlags(openerFrame->document()->sandboxFlags());

    if (request.frameName() != "_blank")
        frame->tree().setName(request.frameName());

    host->chrome().setWindowFeatures(features);

    // 'x' and 'y' specify the location of the window, while 'width' and 'height'
    // specify the size of the viewport. We can only resize the window, so adjust
    // for the difference between the window size and the viewport size.

    FloatRect windowRect = host->chrome().windowRect();
    FloatSize viewportSize = host->chrome().pageRect().size();

    if (features.xSet)
        windowRect.setX(features.x);
    if (features.ySet)
        windowRect.setY(features.y);
    if (features.widthSet)
        windowRect.setWidth(features.width + (windowRect.width() - viewportSize.width()));
    if (features.heightSet)
        windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height()));

    // Ensure non-NaN values, minimum size as well as being within valid screen area.
    FloatRect newWindowRect = DOMWindow::adjustWindowRect(frame, windowRect);

    host->chrome().setWindowRect(newWindowRect);
    host->chrome().show(policy);

    created = true;
    return frame;
}