void PopupMenuImpl::update() { if (!m_popup || !m_client) return; ownerElement().document().updateLayoutTreeIfNeeded(); if (!m_client) return; m_needsUpdate = false; RefPtr<SharedBuffer> data = SharedBuffer::create(); PagePopupClient::addString("window.updateData = {\n", data.get()); PagePopupClient::addString("type: \"update\",\n", data.get()); ItemIterationContext context(*ownerElement().computedStyle(), data.get()); context.serializeBaseStyle(); PagePopupClient::addString("children: [", data.get()); for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())) { if (isHTMLOptionElement(child)) addOption(context, toHTMLOptionElement(child)); if (isHTMLOptGroupElement(child)) addOptGroup(context, toHTMLOptGroupElement(child)); if (isHTMLHRElement(child)) addSeparator(context, toHTMLHRElement(child)); } PagePopupClient::addString("],\n", data.get()); PagePopupClient::addString("}\n", data.get()); m_popup->postMessage(String::fromUTF8(data->data(), data->size())); }
void PopupMenuImpl::update() { if (!m_popup || !m_ownerElement) return; ownerElement().document().updateLayoutTreeIfNeeded(); // disconnectClient() might have been called. if (!m_ownerElement) return; m_needsUpdate = false; RefPtr<SharedBuffer> data = SharedBuffer::create(); PagePopupClient::addString("window.updateData = {\n", data.get()); PagePopupClient::addString("type: \"update\",\n", data.get()); ItemIterationContext context(*m_ownerElement->computedStyle(), data.get()); context.serializeBaseStyle(); PagePopupClient::addString("children: [", data.get()); const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = m_ownerElement->listItems(); for (; context.m_listIndex < items.size(); ++context.m_listIndex) { Element& child = *items[context.m_listIndex]; if (!isHTMLOptGroupElement(child.parentNode())) context.finishGroupIfNecessary(); if (isHTMLOptionElement(child)) addOption(context, toHTMLOptionElement(child)); else if (isHTMLOptGroupElement(child)) addOptGroup(context, toHTMLOptGroupElement(child)); else if (isHTMLHRElement(child)) addSeparator(context, toHTMLHRElement(child)); } context.finishGroupIfNecessary(); PagePopupClient::addString("],\n", data.get()); PagePopupClient::addString("}\n", data.get()); m_popup->postMessage(String::fromUTF8(data->data(), data->size())); }
void PopupMenuImpl::writeDocument(SharedBuffer* data) { IntRect anchorRectInScreen = m_chromeClient->viewportToScreen(m_client->elementRectRelativeToViewport()); PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data); data->append(Platform::current()->loadResource("pickerCommon.css")); data->append(Platform::current()->loadResource("listPicker.css")); PagePopupClient::addString("</style></head><body><div id=main>Loading...</div><script>\n" "window.dialogArguments = {\n", data); addProperty("selectedIndex", m_client->selectedIndex(), data); const ComputedStyle* ownerStyle = ownerElement().computedStyle(); ItemIterationContext context(*ownerStyle, data); context.serializeBaseStyle(); PagePopupClient::addString("children: [\n", data); for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())) { if (isHTMLOptionElement(child)) addOption(context, toHTMLOptionElement(child)); if (isHTMLOptGroupElement(child)) addOptGroup(context, toHTMLOptGroupElement(child)); if (isHTMLHRElement(child)) addSeparator(context, toHTMLHRElement(child)); } PagePopupClient::addString("],\n", data); addProperty("anchorRectInScreen", anchorRectInScreen, data); bool isRTL = !ownerStyle->isLeftToRightDirection(); addProperty("isRTL", isRTL, data); addProperty("paddingStart", isRTL ? m_client->clientPaddingRight().toDouble() : m_client->clientPaddingLeft().toDouble(), data); PagePopupClient::addString("};\n", data); data->append(Platform::current()->loadResource("pickerCommon.js")); data->append(Platform::current()->loadResource("listPicker.js")); PagePopupClient::addString("</script></body>\n", data); }
void PopupMenuImpl::update() { if (!m_popup || !m_client) return; ownerElement().document().updateLayoutTreeIfNeeded(); if (!m_client) return; m_needsUpdate = false; RefPtr<SharedBuffer> data = SharedBuffer::create(); PagePopupClient::addString("window.updateData = {\n", data.get()); PagePopupClient::addString("type: \"update\",\n", data.get()); PagePopupClient::addString("children: [", data.get()); bool enableExtraStyling = !hasTooManyItemsForStyling(); for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())) { if (isHTMLOptionElement(child)) addOption(toHTMLOptionElement(child), enableExtraStyling, data.get()); if (isHTMLOptGroupElement(child)) addOptGroup(toHTMLOptGroupElement(child), enableExtraStyling, data.get()); if (isHTMLHRElement(child)) addSeparator(toHTMLHRElement(child), enableExtraStyling, data.get()); } PagePopupClient::addString("],\n", data.get()); PagePopupClient::addString("}\n", data.get()); m_popup->postMessage(String::fromUTF8(data->data(), data->size())); }
void PopupMenuImpl::writeDocument(SharedBuffer* data) { HTMLSelectElement& ownerElement = *m_ownerElement; IntRect anchorRectInScreen = m_chromeClient->viewportToScreen( ownerElement.visibleBoundsInVisualViewport(), ownerElement.document().view()); PagePopupClient::addString( "<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data); data->append(Platform::current()->loadResource("pickerCommon.css")); data->append(Platform::current()->loadResource("listPicker.css")); PagePopupClient::addString( "</style></head><body><div id=main>Loading...</div><script>\n" "window.dialogArguments = {\n", data); addProperty("selectedIndex", ownerElement.selectedListIndex(), data); const ComputedStyle* ownerStyle = ownerElement.computedStyle(); ItemIterationContext context(*ownerStyle, data); context.serializeBaseStyle(); PagePopupClient::addString("children: [\n", data); const HeapVector<Member<HTMLElement>>& items = ownerElement.listItems(); for (; context.m_listIndex < items.size(); ++context.m_listIndex) { Element& child = *items[context.m_listIndex]; if (!isHTMLOptGroupElement(child.parentNode())) context.finishGroupIfNecessary(); if (isHTMLOptionElement(child)) addOption(context, toHTMLOptionElement(child)); else if (isHTMLOptGroupElement(child)) addOptGroup(context, toHTMLOptGroupElement(child)); else if (isHTMLHRElement(child)) addSeparator(context, toHTMLHRElement(child)); } context.finishGroupIfNecessary(); PagePopupClient::addString("],\n", data); addProperty("anchorRectInScreen", anchorRectInScreen, data); float zoom = zoomFactor(); float scaleFactor = m_chromeClient->windowToViewportScalar(1.f); addProperty("zoomFactor", zoom / scaleFactor, data); bool isRTL = !ownerStyle->isLeftToRightDirection(); addProperty("isRTL", isRTL, data); addProperty("paddingStart", isRTL ? ownerElement.clientPaddingRight().toDouble() / zoom : ownerElement.clientPaddingLeft().toDouble() / zoom, data); PagePopupClient::addString("};\n", data); data->append(Platform::current()->loadResource("pickerCommon.js")); data->append(Platform::current()->loadResource("listPicker.js")); PagePopupClient::addString("</script></body>\n", data); }
void PopupMenuImpl::update() { if (!m_popup || !m_ownerElement) return; ownerElement().document().updateStyleAndLayoutTree(); // disconnectClient() might have been called. if (!m_ownerElement) return; m_needsUpdate = false; if (!ownerElement() .document() .frame() ->view() ->visibleContentRect() .intersects(ownerElement().pixelSnappedBoundingBox())) { hide(); return; } RefPtr<SharedBuffer> data = SharedBuffer::create(); PagePopupClient::addString("window.updateData = {\n", data.get()); PagePopupClient::addString("type: \"update\",\n", data.get()); ItemIterationContext context(*m_ownerElement->computedStyle(), data.get()); context.serializeBaseStyle(); PagePopupClient::addString("children: [", data.get()); const HeapVector<Member<HTMLElement>>& items = m_ownerElement->listItems(); for (; context.m_listIndex < items.size(); ++context.m_listIndex) { Element& child = *items[context.m_listIndex]; if (!isHTMLOptGroupElement(child.parentNode())) context.finishGroupIfNecessary(); if (isHTMLOptionElement(child)) addOption(context, toHTMLOptionElement(child)); else if (isHTMLOptGroupElement(child)) addOptGroup(context, toHTMLOptGroupElement(child)); else if (isHTMLHRElement(child)) addSeparator(context, toHTMLHRElement(child)); } context.finishGroupIfNecessary(); PagePopupClient::addString("],\n", data.get()); IntRect anchorRectInScreen = m_chromeClient->viewportToScreen( m_ownerElement->visibleBoundsInVisualViewport(), ownerElement().document().view()); addProperty("anchorRectInScreen", anchorRectInScreen, data.get()); PagePopupClient::addString("}\n", data.get()); m_popup->postMessage(String::fromUTF8(data->data(), data->size())); }
void PopupMenuImpl::writeDocument(SharedBuffer* data) { IntRect anchorRectInScreen = m_chromeClient->viewportToScreen(m_client->elementRectRelativeToViewport()); PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data); data->append(Platform::current()->loadResource("pickerCommon.css")); data->append(Platform::current()->loadResource("listPicker.css")); PagePopupClient::addString("</style></head><body><div id=main>Loading...</div><script>\n" "window.dialogArguments = {\n", data); addProperty("selectedIndex", m_client->selectedIndex(), data); PagePopupClient::addString("children: [\n", data); bool enableExtraStyling = !hasTooManyItemsForStyling(); for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())) { if (isHTMLOptionElement(child)) addOption(toHTMLOptionElement(child), enableExtraStyling, data); if (isHTMLOptGroupElement(child)) addOptGroup(toHTMLOptGroupElement(child), enableExtraStyling, data); if (isHTMLHRElement(child)) addSeparator(toHTMLHRElement(child), enableExtraStyling, data); } PagePopupClient::addString("],\n", data); addProperty("anchorRectInScreen", anchorRectInScreen, data); const ComputedStyle* ownerStyle = ownerElement().computedStyle(); Color backgroundColor = ownerStyle->visitedDependentColor(CSSPropertyBackgroundColor); #if OS(LINUX) // On other platforms, the <option> background color is the same as the // <select> background color. On Linux, that makes the <option> // background color very dark, so by default, try to use a lighter // background color for <option>s. if (LayoutTheme::theme().systemColor(CSSValueButtonface) == backgroundColor) backgroundColor = LayoutTheme::theme().systemColor(CSSValueMenu); #endif addProperty("backgroundColor", backgroundColor.serialized(), data); bool isRTL = !ownerStyle->isLeftToRightDirection(); addProperty("isRTL", isRTL, data); addProperty("paddingStart", isRTL ? m_client->clientPaddingRight().toDouble() : m_client->clientPaddingLeft().toDouble(), data); PagePopupClient::addString("};\n", data); data->append(Platform::current()->loadResource("pickerCommon.js")); data->append(Platform::current()->loadResource("listPicker.js")); PagePopupClient::addString("</script></body>\n", data); }
void PopupMenuImpl::addOptGroup(HTMLOptGroupElement& element, bool enableExtraStyling, SharedBuffer* data) { PagePopupClient::addString("{\n", data); PagePopupClient::addString("type: \"optgroup\",\n", data); addProperty("label", element.groupLabelText(), data); addProperty("title", element.title(), data); addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr), data); addProperty("disabled", element.isDisabledFormControl(), data); addElementStyle(element, enableExtraStyling, data); PagePopupClient::addString("children: [", data); for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(element)) { if (isHTMLOptionElement(child)) addOption(toHTMLOptionElement(child), enableExtraStyling, data); if (isHTMLOptGroupElement(child)) addOptGroup(toHTMLOptGroupElement(child), enableExtraStyling, data); if (isHTMLHRElement(child)) addSeparator(toHTMLHRElement(child), enableExtraStyling, data); } PagePopupClient::addString("],\n", data); PagePopupClient::addString("},\n", data); }
void PopupMenuImpl::addOptGroup(ItemIterationContext& context, HTMLOptGroupElement& element) { SharedBuffer* data = context.m_buffer; ++context.m_listIndex; PagePopupClient::addString("{\n", data); PagePopupClient::addString("type: \"optgroup\",\n", data); addProperty("label", element.groupLabelText(), data); addProperty("title", element.title(), data); addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr), data); addProperty("disabled", element.isDisabledFormControl(), data); addElementStyle(context, element); PagePopupClient::addString("children: [", data); for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(element)) { if (isHTMLOptionElement(child)) addOption(context, toHTMLOptionElement(child)); // TODO(tkent): Ignore nested OPTGROUP. crbug.com/502101. if (isHTMLOptGroupElement(child)) addOptGroup(context, toHTMLOptGroupElement(child)); if (isHTMLHRElement(child)) addSeparator(context, toHTMLHRElement(child)); } PagePopupClient::addString("],\n", data); PagePopupClient::addString("},\n", data); }