bool ExternalPopupMenu::showInternal()
{
    // Blink core reuses the PopupMenu of an element.  For simplicity, we do
    // recreate the actual external popup everytime.
    if (m_webExternalPopupMenu) {
        m_webExternalPopupMenu->close();
        m_webExternalPopupMenu = 0;
    }

    WebPopupMenuInfo info;
    getPopupMenuInfo(info, *m_ownerElement);
    if (info.items.isEmpty())
        return false;
    WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(m_localFrame.get());
    m_webExternalPopupMenu = webframe->client()->createExternalPopupMenu(info, this);
    if (m_webExternalPopupMenu) {
        LayoutObject* layoutObject = m_ownerElement->layoutObject();
        if (!layoutObject || !layoutObject->isBox())
            return false;
        FloatQuad quad(toLayoutBox(layoutObject)->localToAbsoluteQuad(FloatQuad(toLayoutBox(layoutObject)->borderBoundingBox())));
        IntRect rect(quad.enclosingBoundingBox());
        IntRect rectInViewport = m_localFrame->view()->soonToBeRemovedContentsToUnscaledViewport(rect);
        // TODO(tkent): If the anchor rectangle is not visible, we should not
        // show a popup.
        m_webExternalPopupMenu->show(rectInViewport);
        m_shownDOMTreeVersion = m_ownerElement->document().domTreeVersion();
        return true;
    } else {
        // The client might refuse to create a popup (when there is already one pending to be shown for example).
        didCancel();
        return false;
    }
}
void ExternalPopupMenu::show(const IntRect& rect, FrameView* v, int index)
{
    // WebCore reuses the PopupMenu of a page.
    // For simplicity, we do recreate the actual external popup everytime.
    hide();

    WebPopupMenuInfo info;
    getPopupMenuInfo(&info);
    if (info.items.isEmpty())
        return;
    m_webExternalPopupMenu =
        m_webViewClient->createExternalPopupMenu(info, this);
    m_webExternalPopupMenu->show(v->contentsToWindow(rect));
}
Example #3
0
void ExternalPopupMenu::show(const FloatQuad& controlPosition, const IntSize&, int index)
{
    IntRect rect(controlPosition.enclosingBoundingBox());
    // WebCore reuses the PopupMenu of a page.
    // For simplicity, we do recreate the actual external popup everytime.
    hide();

    WebPopupMenuInfo info;
    getPopupMenuInfo(&info);
    if (info.items.isEmpty())
        return;
    m_webExternalPopupMenu =
        m_webViewClient->createExternalPopupMenu(info, this);
    if (m_webExternalPopupMenu)
        m_webExternalPopupMenu->show(m_frameView->contentsToWindow(rect));
    else {
        // The client might refuse to create a popup (when there is already one pending to be shown for example).
        didCancel();
    }
}
Example #4
0
void ExternalPopupMenu::show(const FloatQuad& controlPosition, const IntSize&, int index)
{
    IntRect rect(controlPosition.enclosingBoundingBox());
    // WebCore reuses the PopupMenu of an element.
    // For simplicity, we do recreate the actual external popup everytime.
    if (m_webExternalPopupMenu) {
        m_webExternalPopupMenu->close();
        m_webExternalPopupMenu = 0;
    }

    WebPopupMenuInfo info;
    getPopupMenuInfo(info, *m_popupMenuClient);
    if (info.items.isEmpty())
        return;
    WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(m_localFrame.get());
    m_webExternalPopupMenu = webframe->client()->createExternalPopupMenu(info, this);
    if (m_webExternalPopupMenu) {
        // FIXME: Standardize viewport coordinate conversions. crbug.com/371902.
        IntRect rectInViewport = m_localFrame->view()->contentsToWindow(rect);
        if (m_webView.pinchVirtualViewportEnabled())
            rectInViewport.moveBy(-flooredIntPoint(m_webView.page()->frameHost().pinchViewport().location()));
        m_webExternalPopupMenu->show(rectInViewport);
#if OS(MACOSX)
        const WebInputEvent* currentEvent = WebViewImpl::currentInputEvent();
        if (currentEvent && currentEvent->type == WebInputEvent::MouseDown) {
            m_syntheticEvent = adoptPtr(new WebMouseEvent);
            *m_syntheticEvent = *static_cast<const WebMouseEvent*>(currentEvent);
            m_syntheticEvent->type = WebInputEvent::MouseUp;
            m_dispatchEventTimer.startOneShot(0, FROM_HERE);
            // FIXME: show() is asynchronous. If preparing a popup is slow and
            // a user released the mouse button before showing the popup,
            // mouseup and click events are correctly dispatched. Dispatching
            // the synthetic mouseup event is redundant in this case.
        }
#endif
    } else {
        // The client might refuse to create a popup (when there is already one pending to be shown for example).
        didCancel();
    }
}
Example #5
0
void ChromeClientImpl::popupOpened(PopupContainer* popupContainer,
                                   const IntRect& bounds,
                                   bool handleExternally)
{
    if (!m_webView->client())
        return;

    WebWidget* webwidget;
    if (handleExternally) {
        WebPopupMenuInfo popupInfo;
        getPopupMenuInfo(popupContainer, &popupInfo);
        webwidget = m_webView->client()->createPopupMenu(popupInfo);
    } else {
        webwidget = m_webView->client()->createPopupMenu(
            convertPopupType(popupContainer->popupType()));
        // We only notify when the WebView has to handle the popup, as when
        // the popup is handled externally, the fact that a popup is showing is
        // transparent to the WebView.
        m_webView->popupOpened(popupContainer);
    }
    static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds);
}
Example #6
0
void ChromeClientImpl::popupOpened(PopupContainer* popupContainer,
                                   const IntRect& bounds,
                                   bool handleExternally)
{
    // For Autofill popups, if the popup will not be fully visible, we shouldn't
    // show it at all. Among other things, this prevents users from being able
    // to interact via the keyboard with an invisible popup.
    if (popupContainer->popupType() == PopupContainer::Suggestion) {
        FrameView* view = m_webView->page()->mainFrame()->view();
        IntRect visibleRect = view->visibleContentRect(true /* include scrollbars */);
        // |bounds| is in screen coordinates, so make sure to convert it to
        // content coordinates prior to comparing to |visibleRect|.
        IntRect screenRect = bounds;
        screenRect.setLocation(view->screenToContents(bounds.location()));
        if (!visibleRect.contains(screenRect)) {
            m_webView->hideAutofillPopup();
            return;
        }
    }

    if (!m_webView->client())
        return;

    WebWidget* webwidget;
    if (handleExternally) {
        WebPopupMenuInfo popupInfo;
        getPopupMenuInfo(popupContainer, &popupInfo);
        webwidget = m_webView->client()->createPopupMenu(popupInfo);
    } else {
        webwidget = m_webView->client()->createPopupMenu(
            convertPopupType(popupContainer->popupType()));
        // We only notify when the WebView has to handle the popup, as when
        // the popup is handled externally, the fact that a popup is showing is
        // transparent to the WebView.
        m_webView->popupOpened(popupContainer);
    }
    static_cast<WebPopupMenuImpl*>(webwidget)->init(popupContainer, bounds);
}