void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle) { if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(element)) { loadFullDefaultStyle(); changedDefaultStyle = true; } // FIXME: We should assert that the sheet only styles SVG elements. if (element->isSVGElement() && !svgStyleSheet) { svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)); defaultStyle->addRulesFromSheet(svgStyleSheet, screenEval()); defaultPrintStyle->addRulesFromSheet(svgStyleSheet, printEval()); changedDefaultStyle = true; } // FIXME: We should assert that this sheet only contains rules for <video> and <audio>. if (!mediaControlsStyleSheet && (isHTMLVideoElement(element) || element->hasTagName(audioTag))) { String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(element->document()->page())->extraMediaControlsStyleSheet(); mediaControlsStyleSheet = parseUASheet(mediaRules); defaultStyle->addRulesFromSheet(mediaControlsStyleSheet, screenEval()); defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet, printEval()); changedDefaultStyle = true; } if (!fullscreenStyleSheet && FullscreenElementStack::isFullScreen(element->document())) { String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraFullScreenStyleSheet(); fullscreenStyleSheet = parseUASheet(fullscreenRules); defaultStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval()); defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval()); changedDefaultStyle = true; } ASSERT(defaultStyle->features().idsInRules.isEmpty()); ASSERT(mathMLStyleSheet || defaultStyle->features().siblingRules.isEmpty()); }
void FullscreenController::didExitFullScreen() { if (!m_fullScreenFrame) return; if (Document* document = m_fullScreenFrame->document()) { if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) { Element* element = fullscreen->webkitCurrentFullScreenElement(); if (element) { // When the client exits from full screen we have to call fullyExitFullscreen to notify // the document. While doing that, suppress notifications back to the client. m_isCancelingFullScreen = true; Fullscreen::fullyExitFullscreen(*document); m_isCancelingFullScreen = false; // If the video used overlay fullscreen mode, the background was made transparent. Restore the transparency. if (isHTMLVideoElement(element) && m_webViewImpl->layerTreeView()) m_webViewImpl->layerTreeView()->setHasTransparentBackground(m_webViewImpl->isTransparent()); if (m_exitFullscreenPageScaleFactor) { updatePageScaleConstraints(true); m_webViewImpl->setPageScaleFactor(m_exitFullscreenPageScaleFactor); m_webViewImpl->mainFrame()->setScrollOffset(WebSize(m_exitFullscreenScrollOffset)); m_webViewImpl->setVisualViewportOffset(m_exitFullscreenVisualViewportOffset); m_exitFullscreenPageScaleFactor = 0; m_exitFullscreenScrollOffset = IntSize(); } fullscreen->didExitFullScreenForElement(0); } } } m_fullScreenFrame.clear(); }
static bool shouldAppendLayer(const PaintLayer& layer) { Node* node = layer.layoutObject()->node(); if (node && isHTMLVideoElement(*node)) { HTMLVideoElement* element = toHTMLVideoElement(node); if (element->isFullscreen() && element->usesOverlayFullscreenVideo()) return false; } return true; }
void HTMLImageLoader::dispatchLoadEvent() { // HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure. if (isHTMLVideoElement(element())) return; bool errorOccurred = image()->errorOccurred(); if (!errorOccurred && image()->response().httpStatusCode() >= 400) errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror. element()->dispatchEvent(Event::create(errorOccurred ? EventTypeNames::error : EventTypeNames::load)); }
void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle) { // FIXME: We should assert that the sheet only styles SVG elements. if (element->isSVGElement() && !m_svgStyleSheet) { m_svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)); m_defaultStyle->addRulesFromSheet(svgStyleSheet(), screenEval()); m_defaultPrintStyle->addRulesFromSheet(svgStyleSheet(), printEval()); changedDefaultStyle = true; } // FIXME: We should assert that the sheet only styles MathML elements. if (element->namespaceURI() == MathMLNames::mathmlNamespaceURI && !m_mathmlStyleSheet) { m_mathmlStyleSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet)); m_defaultStyle->addRulesFromSheet(mathmlStyleSheet(), screenEval()); m_defaultPrintStyle->addRulesFromSheet(mathmlStyleSheet(), printEval()); changedDefaultStyle = true; } // FIXME: We should assert that this sheet only contains rules for <video> and <audio>. if (!m_mediaControlsStyleSheet && (isHTMLVideoElement(*element) || isHTMLAudioElement(*element))) { String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::theme().extraMediaControlsStyleSheet(); m_mediaControlsStyleSheet = parseUASheet(mediaRules); m_defaultStyle->addRulesFromSheet(mediaControlsStyleSheet(), screenEval()); m_defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet(), printEval()); changedDefaultStyle = true; } // FIXME: This only works because we Force recalc the entire document so the new sheet // is loaded for <html> and the correct styles apply to everyone. if (!m_fullscreenStyleSheet && FullscreenElementStack::isFullScreen(element->document())) { String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::theme().extraFullScreenStyleSheet(); m_fullscreenStyleSheet = parseUASheet(fullscreenRules); m_defaultStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval()); m_defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval()); changedDefaultStyle = true; } ASSERT(!m_defaultStyle->features().hasIdsInSelectors()); ASSERT(m_defaultStyle->features().siblingRules.isEmpty()); }
static LayoutVideo* findFullscreenVideoLayoutObject(Document& document) { // Recursively find the document that is in fullscreen. Element* fullscreenElement = Fullscreen::fullscreenElementFrom(document); Document* contentDocument = &document; while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) { contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument(); if (!contentDocument) return nullptr; fullscreenElement = Fullscreen::fullscreenElementFrom(*contentDocument); } // Get the current fullscreen element from the document. fullscreenElement = Fullscreen::currentFullScreenElementFrom(*contentDocument); if (!isHTMLVideoElement(fullscreenElement)) return nullptr; LayoutObject* layoutObject = fullscreenElement->layoutObject(); if (!layoutObject) return nullptr; return toLayoutVideo(layoutObject); }
void FullscreenController::didEnterFullScreen() { if (!m_provisionalFullScreenElement) return; RefPtrWillBeRawPtr<Element> element = m_provisionalFullScreenElement.release(); Document& document = element->document(); m_fullScreenFrame = document.frame(); if (!m_fullScreenFrame) return; if (!m_exitFullscreenPageScaleFactor) { m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor(); m_exitFullscreenScrollOffset = m_webViewImpl->mainFrame()->scrollOffset(); m_exitFullscreenPinchViewportOffset = m_webViewImpl->pinchViewportOffset(); updatePageScaleConstraints(false); m_webViewImpl->setPageScaleFactor(1.0f); m_webViewImpl->setMainFrameScrollOffset(IntPoint()); m_webViewImpl->setPinchViewportOffset(FloatPoint()); } Fullscreen::from(document).didEnterFullScreenForElement(element.get()); ASSERT(Fullscreen::currentFullScreenElementFrom(document) == element); if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) { if (isHTMLVideoElement(element)) { HTMLVideoElement* videoElement = toHTMLVideoElement(element); if (HTMLMediaElement::isMediaStreamURL(videoElement->sourceURL().string())) return; if (videoElement->webMediaPlayer() // FIXME: There is no embedder-side handling in layout test mode. && !LayoutTestSupport::isRunningLayoutTest()) { videoElement->webMediaPlayer()->enterFullscreen(); } if (m_webViewImpl->layerTreeView()) m_webViewImpl->layerTreeView()->setHasTransparentBackground(true); } } }
void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle) { // FIXME: We should assert that the sheet only styles SVG elements. if (element->isSVGElement() && !svgStyleSheet) { svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)); defaultStyle->addRulesFromSheet(svgStyleSheet, screenEval()); defaultPrintStyle->addRulesFromSheet(svgStyleSheet, printEval()); changedDefaultStyle = true; } #if ENABLE(WML) // FIXME: We should assert that the sheet only styles WML elements. if (element->isWMLElement() && !wmlStyleSheet) { wmlStyleSheet = parseUASheet(wmlUserAgentStyleSheet, sizeof(wmlUserAgentStyleSheet)); defaultStyle->addRulesFromSheet(wmlStyleSheet, screenEval()); defaultPrintStyle->addRulesFromSheet(wmlStyleSheet, printEval()); changedDefaultStyle = true; } #endif // FIXME: We should assert that this sheet only contains rules for <video> and <audio>. if (!mediaControlsStyleSheet && (isHTMLVideoElement(element) || element->hasTagName(audioTag))) { String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::theme().extraMediaControlsStyleSheet(); mediaControlsStyleSheet = parseUASheet(mediaRules); defaultStyle->addRulesFromSheet(mediaControlsStyleSheet, screenEval()); defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet, printEval()); changedDefaultStyle = true; } // FIXME: This only works because we Force recalc the entire document so the new sheet // is loaded for <html> and the correct styles apply to everyone. if (!fullscreenStyleSheet && FullscreenElementStack::isFullScreen(&element->document())) { String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::theme().extraFullScreenStyleSheet(); fullscreenStyleSheet = parseUASheet(fullscreenRules); defaultStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval()); defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval()); changedDefaultStyle = true; } ASSERT(defaultStyle->features().idsInRules.isEmpty()); ASSERT(defaultStyle->features().siblingRules.isEmpty()); }
void FullscreenController::didEnterFullScreen() { if (!m_provisionalFullScreenElement) return; RefPtrWillBeRawPtr<Element> element = m_provisionalFullScreenElement.release(); Document& document = element->document(); m_fullScreenFrame = document.frame(); if (!m_fullScreenFrame) return; if (!m_haveEnteredFullscreen) { updatePageScaleConstraints(false); m_webViewImpl->setPageScaleFactor(1.0f); m_webViewImpl->mainFrame()->setScrollOffset(WebSize()); m_webViewImpl->setVisualViewportOffset(FloatPoint()); m_haveEnteredFullscreen = true; } Fullscreen::from(document).didEnterFullScreenForElement(element.get()); ASSERT(Fullscreen::currentFullScreenElementFrom(document) == element); if (isHTMLVideoElement(element)) { HTMLVideoElement* videoElement = toHTMLVideoElement(element); if (videoElement->usesOverlayFullscreenVideo()) { if (videoElement->webMediaPlayer() // FIXME: There is no embedder-side handling in layout test mode. && !LayoutTestSupport::isRunningLayoutTest()) { videoElement->webMediaPlayer()->enterFullscreen(); } if (m_webViewImpl->layerTreeView()) m_webViewImpl->layerTreeView()->setHasTransparentBackground(true); } } }
bool WebVideoFullscreenManager::supportsFullscreen(const Node* node) const { if (!Settings::avKitEnabled()) return false; return isHTMLVideoElement(node); }
bool ChromeClientBlackBerry::supportsFullscreenForNode(const Node* node) { return isHTMLVideoElement(node); }
void ContextMenuClientImpl::showContextMenu(const WebCore::ContextMenu* defaultMenu) { // Displaying the context menu in this function is a big hack as we don't // have context, i.e. whether this is being invoked via a script or in // response to user input (Mouse event WM_RBUTTONDOWN, // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked // in response to the above input events before popping up the context menu. if (!m_webView->contextMenuAllowed()) return; HitTestResult r = m_webView->page()->contextMenuController().hitTestResult(); LocalFrame* selectedFrame = r.innerNodeFrame(); WebContextMenuData data; IntPoint mousePoint = selectedFrame->view()->contentsToWindow(r.roundedPointInInnerNodeFrame()); // FIXME(bokan): crbug.com/371902 - We shouldn't be making these scale // related coordinate transformatios in an ad hoc way. PinchViewport& pinchViewport = selectedFrame->host()->pinchViewport(); mousePoint -= flooredIntSize(pinchViewport.visibleRect().location()); mousePoint.scale(m_webView->pageScaleFactor(), m_webView->pageScaleFactor()); data.mousePosition = mousePoint; // Compute edit flags. data.editFlags = WebContextMenuData::CanDoNone; if (toLocalFrame(m_webView->focusedWebCoreFrame())->editor().canUndo()) data.editFlags |= WebContextMenuData::CanUndo; if (toLocalFrame(m_webView->focusedWebCoreFrame())->editor().canRedo()) data.editFlags |= WebContextMenuData::CanRedo; if (toLocalFrame(m_webView->focusedWebCoreFrame())->editor().canCut()) data.editFlags |= WebContextMenuData::CanCut; if (toLocalFrame(m_webView->focusedWebCoreFrame())->editor().canCopy()) data.editFlags |= WebContextMenuData::CanCopy; if (toLocalFrame(m_webView->focusedWebCoreFrame())->editor().canPaste()) data.editFlags |= WebContextMenuData::CanPaste; if (toLocalFrame(m_webView->focusedWebCoreFrame())->editor().canDelete()) data.editFlags |= WebContextMenuData::CanDelete; // We can always select all... data.editFlags |= WebContextMenuData::CanSelectAll; data.editFlags |= WebContextMenuData::CanTranslate; // Links, Images, Media tags, and Image/Media-Links take preference over // all else. data.linkURL = r.absoluteLinkURL(); if (isHTMLCanvasElement(r.innerNonSharedNode())) { data.mediaType = WebContextMenuData::MediaTypeCanvas; } else if (!r.absoluteImageURL().isEmpty()) { data.srcURL = r.absoluteImageURL(); data.mediaType = WebContextMenuData::MediaTypeImage; data.mediaFlags |= WebContextMenuData::MediaCanPrint; } else if (!r.absoluteMediaURL().isEmpty()) { data.srcURL = r.absoluteMediaURL(); // We know that if absoluteMediaURL() is not empty, then this // is a media element. HTMLMediaElement* mediaElement = toHTMLMediaElement(r.innerNonSharedNode()); if (isHTMLVideoElement(*mediaElement)) data.mediaType = WebContextMenuData::MediaTypeVideo; else if (isHTMLAudioElement(*mediaElement)) data.mediaType = WebContextMenuData::MediaTypeAudio; if (mediaElement->error()) data.mediaFlags |= WebContextMenuData::MediaInError; if (mediaElement->paused()) data.mediaFlags |= WebContextMenuData::MediaPaused; if (mediaElement->muted()) data.mediaFlags |= WebContextMenuData::MediaMuted; if (mediaElement->loop()) data.mediaFlags |= WebContextMenuData::MediaLoop; if (mediaElement->supportsSave()) data.mediaFlags |= WebContextMenuData::MediaCanSave; if (mediaElement->hasAudio()) data.mediaFlags |= WebContextMenuData::MediaHasAudio; // Media controls can be toggled only for video player. If we toggle // controls for audio then the player disappears, and there is no way to // return it back. Don't set this bit for fullscreen video, since // toggling is ignored in that case. if (mediaElement->hasVideo() && !mediaElement->isFullscreen()) data.mediaFlags |= WebContextMenuData::MediaCanToggleControls; if (mediaElement->controls()) data.mediaFlags |= WebContextMenuData::MediaControls; } else if (isHTMLObjectElement(*r.innerNonSharedNode()) || isHTMLEmbedElement(*r.innerNonSharedNode())) { RenderObject* object = r.innerNonSharedNode()->renderer(); if (object && object->isWidget()) { Widget* widget = toRenderWidget(object)->widget(); if (widget && widget->isPluginContainer()) { data.mediaType = WebContextMenuData::MediaTypePlugin; WebPluginContainerImpl* plugin = toWebPluginContainerImpl(widget); WebString text = plugin->plugin()->selectionAsText(); if (!text.isEmpty()) { data.selectedText = text; data.editFlags |= WebContextMenuData::CanCopy; } data.editFlags &= ~WebContextMenuData::CanTranslate; data.linkURL = plugin->plugin()->linkAtPosition(data.mousePosition); if (plugin->plugin()->supportsPaginatedPrint()) data.mediaFlags |= WebContextMenuData::MediaCanPrint; HTMLPlugInElement* pluginElement = toHTMLPlugInElement(r.innerNonSharedNode()); data.srcURL = pluginElement->document().completeURL(pluginElement->url()); data.mediaFlags |= WebContextMenuData::MediaCanSave; // Add context menu commands that are supported by the plugin. if (plugin->plugin()->canRotateView()) data.mediaFlags |= WebContextMenuData::MediaCanRotate; } } } // An image can to be null for many reasons, like being blocked, no image // data received from server yet. data.hasImageContents = (data.mediaType == WebContextMenuData::MediaTypeImage) && r.image() && !(r.image()->isNull()); // If it's not a link, an image, a media element, or an image/media link, // show a selection menu or a more generic page menu. if (selectedFrame->document()->loader()) data.frameEncoding = selectedFrame->document()->encodingName(); // Send the frame and page URLs in any case. data.pageURL = urlFromFrame(m_webView->mainFrameImpl()->frame()); if (selectedFrame != m_webView->mainFrameImpl()->frame()) { data.frameURL = urlFromFrame(selectedFrame); RefPtr<HistoryItem> historyItem = selectedFrame->loader().currentItem(); if (historyItem) data.frameHistoryItem = WebHistoryItem(historyItem); } if (r.isSelected()) { if (!isHTMLInputElement(*r.innerNonSharedNode()) || !toHTMLInputElement(r.innerNonSharedNode())->isPasswordField()) data.selectedText = selectedFrame->selectedText().stripWhiteSpace(); } if (r.isContentEditable()) { data.isEditable = true; // When Chrome enables asynchronous spellchecking, its spellchecker adds spelling markers to misspelled // words and attaches suggestions to these markers in the background. Therefore, when a user right-clicks // a mouse on a word, Chrome just needs to find a spelling marker on the word instead of spellchecking it. if (selectedFrame->settings() && selectedFrame->settings()->asynchronousSpellCheckingEnabled()) { DocumentMarker marker; data.misspelledWord = selectMisspellingAsync(selectedFrame, marker); data.misspellingHash = marker.hash(); if (marker.description().length()) { Vector<String> suggestions; marker.description().split('\n', suggestions); data.dictionarySuggestions = suggestions; } else if (m_webView->spellCheckClient()) { int misspelledOffset, misspelledLength; m_webView->spellCheckClient()->spellCheck(data.misspelledWord, misspelledOffset, misspelledLength, &data.dictionarySuggestions); } } else { data.isSpellCheckingEnabled = toLocalFrame(m_webView->focusedWebCoreFrame())->spellChecker().isContinuousSpellCheckingEnabled(); // Spellchecking might be enabled for the field, but could be disabled on the node. if (toLocalFrame(m_webView->focusedWebCoreFrame())->spellChecker().isSpellCheckingEnabledInFocusedNode()) { data.misspelledWord = selectMisspelledWord(selectedFrame); if (m_webView->spellCheckClient()) { int misspelledOffset, misspelledLength; m_webView->spellCheckClient()->spellCheck( data.misspelledWord, misspelledOffset, misspelledLength, &data.dictionarySuggestions); if (!misspelledLength) data.misspelledWord.reset(); } } } HTMLFormElement* form = selectedFrame->selection().currentForm(); if (form && isHTMLInputElement(*r.innerNonSharedNode())) { HTMLInputElement& selectedElement = toHTMLInputElement(*r.innerNonSharedNode()); WebSearchableFormData ws = WebSearchableFormData(WebFormElement(form), WebInputElement(&selectedElement)); if (ws.url().isValid()) data.keywordURL = ws.url(); } } if (selectedFrame->editor().selectionHasStyle(CSSPropertyDirection, "ltr") != FalseTriState) data.writingDirectionLeftToRight |= WebContextMenuData::CheckableMenuItemChecked; if (selectedFrame->editor().selectionHasStyle(CSSPropertyDirection, "rtl") != FalseTriState) data.writingDirectionRightToLeft |= WebContextMenuData::CheckableMenuItemChecked; // Now retrieve the security info. DocumentLoader* dl = selectedFrame->loader().documentLoader(); WebDataSource* ds = WebDataSourceImpl::fromDocumentLoader(dl); if (ds) data.securityInfo = ds->response().securityInfo(); data.referrerPolicy = static_cast<WebReferrerPolicy>(selectedFrame->document()->referrerPolicy()); // Filter out custom menu elements and add them into the data. populateCustomMenuItems(defaultMenu, &data); // Extract suggested filename for saving file. if (isHTMLAnchorElement(r.URLElement())) { HTMLAnchorElement* anchor = toHTMLAnchorElement(r.URLElement()); data.suggestedFilename = anchor->fastGetAttribute(HTMLNames::downloadAttr); } data.node = r.innerNonSharedNode(); WebLocalFrameImpl* selectedWebFrame = WebLocalFrameImpl::fromFrame(selectedFrame); if (selectedWebFrame->client()) selectedWebFrame->client()->showContextMenu(data); }