Skip to content
Permalink
Browse files
Implement unprefixed :fullscreen pseudo-class
https://bugs.webkit.org/show_bug.cgi?id=246041
rdar://100783064

Reviewed by Antti Koivisto.

Defined in https://fullscreen.spec.whatwg.org/#:fullscreen-pseudo-class

This differs from :-webkit-full-screen, since :fullscreen applies to all fullscreen element in the top layer,
as opposed to :-webkit-full-screen, which applies on the top-most one.

Unfortunately, this still does not allow us to remove full style rebuilds for 2 reasons:
- We still need to support :-webkit-full-screen-ancestor/document
- There seems to be a bug where adding position: fixed; & adding to top layer in the same layout causes dirty renderers.

Tests are not necessary, as this is exercised by the user agent stylesheet (which is already well tested by the fullscreen/ directory).

* LayoutTests/imported/w3c/web-platform-tests/fullscreen/rendering/fullscreen-css-invalidation-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fullscreen/rendering/fullscreen-pseudo-class-support-expected.txt:
* Source/WebCore/css/CSSSelector.cpp:
(WebCore::CSSSelector::selectorText const):
* Source/WebCore/css/CSSSelector.h:
* Source/WebCore/css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne const):
* Source/WebCore/css/SelectorCheckerTestFunctions.h:
(WebCore::matchesFullscreenPseudoClass):
(WebCore::matchesWebkitFullScreenPseudoClass):
(WebCore::matchesFullScreenPseudoClass): Deleted.
* Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in:
* Source/WebCore/css/fullscreen.css:
(#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API):
(:root:-webkit-full-screen-document:not(:fullscreen)):
(:fullscreen video,):
(img:fullscreen):
(iframe:fullscreen):
(:not(:root):fullscreen::backdrop):
(:root:-webkit-full-screen-document:not(:-webkit-full-screen)): Deleted.
(:-webkit-full-screen video,): Deleted.
(img:-webkit-full-screen): Deleted.
(iframe:-webkit-full-screen): Deleted.
(:not(:root):-webkit-full-screen::backdrop): Deleted.
* Source/WebCore/cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::JSC_DEFINE_JIT_OPERATION):
(WebCore::SelectorCompiler::addPseudoClassType):
* Source/WebCore/dom/Element.cpp:
(WebCore::Element::setFullscreenFlag):
* Source/WebCore/dom/FullscreenManager.cpp:
(WebCore::FullscreenManager::willEnterFullscreen):

Canonical link: https://commits.webkit.org/257542@main
  • Loading branch information
nt1m committed Dec 8, 2022
1 parent cfc4f80 commit 47a29162018212a00fcd6a8861272bbfd7c0c57d
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 24 deletions.
@@ -1,4 +1,4 @@
Should be green

FAIL Invalidate :fullscreen based style assert_equals: Green when :root is fullscreened. expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS Invalidate :fullscreen based style

@@ -1,3 +1,3 @@

FAIL :fullscreen pseudo-class support The string did not match the expected pattern.
PASS :fullscreen pseudo-class support

@@ -463,7 +463,10 @@ String CSSSelector::selectorText(StringView separator, StringView rightSide) con
builder.append(":-webkit-full-page-media");
break;
#if ENABLE(FULLSCREEN_API)
case CSSSelector::PseudoClassFullScreen:
case CSSSelector::PseudoClassFullscreen:
builder.append(":fullscreen");
break;
case CSSSelector::PseudoClassWebkitFullScreen:
builder.append(":-webkit-full-screen");
break;
case CSSSelector::PseudoClassFullScreenAncestor:
@@ -155,7 +155,8 @@ struct PossiblyQuotedIdentifier {
PseudoClassSingleButton,
PseudoClassNoButton,
#if ENABLE(FULLSCREEN_API)
PseudoClassFullScreen,
PseudoClassFullscreen,
PseudoClassWebkitFullScreen,
PseudoClassFullScreenDocument,
PseudoClassFullScreenAncestor,
PseudoClassAnimatingFullScreenTransition,
@@ -1040,8 +1040,10 @@ bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
ASSERT(selector.argumentList() && !selector.argumentList()->isEmpty());
return matchesLangPseudoClass(element, *selector.argumentList());
#if ENABLE(FULLSCREEN_API)
case CSSSelector::PseudoClassFullScreen:
return matchesFullScreenPseudoClass(element);
case CSSSelector::PseudoClassFullscreen:
return matchesFullscreenPseudoClass(element);
case CSSSelector::PseudoClassWebkitFullScreen:
return matchesWebkitFullScreenPseudoClass(element);
case CSSSelector::PseudoClassAnimatingFullScreenTransition:
return matchesFullScreenAnimatingFullScreenTransitionPseudoClass(element);
case CSSSelector::PseudoClassFullScreenAncestor:
@@ -29,7 +29,6 @@
#include "FocusController.h"
#include "Frame.h"
#include "FrameSelection.h"
#include "FullscreenManager.h"
#include "HTMLDialogElement.h"
#include "HTMLFrameElement.h"
#include "HTMLIFrameElement.h"
@@ -47,6 +46,11 @@
#include "HTMLAttachmentElement.h"
#endif

#if ENABLE(FULLSCREEN_API)
#include "DocumentOrShadowRootFullscreen.h"
#include "FullscreenManager.h"
#endif

#if ENABLE(VIDEO)
#include "HTMLMediaElement.h"
#include "WebVTTElement.h"
@@ -402,7 +406,16 @@ ALWAYS_INLINE bool scrollbarMatchesCornerPresentPseudoClass(const SelectorChecke

#if ENABLE(FULLSCREEN_API)

ALWAYS_INLINE bool matchesFullScreenPseudoClass(const Element& element)
ALWAYS_INLINE bool matchesFullscreenPseudoClass(const Element& element)
{
if (element.hasFullscreenFlag())
return true;
if (element.shadowRoot())
return DocumentOrShadowRootFullscreen::fullscreenElement(element.document()) == &element;
return false;
}

ALWAYS_INLINE bool matchesWebkitFullScreenPseudoClass(const Element& element)
{
// While a Document is in the fullscreen state, and the document's current fullscreen
// element is an element in the document, the 'full-screen' pseudoclass applies to
@@ -74,8 +74,9 @@ where
window-inactive

#if ENABLE(FULLSCREEN_API)
fullscreen
-webkit-animating-full-screen-transition
-webkit-full-screen
-webkit-full-screen, PseudoClassWebkitFullScreen, PseudoElementUnknown
-webkit-full-screen-ancestor
-webkit-full-screen-document
-webkit-full-screen-controls-hidden
@@ -26,7 +26,7 @@

/* https://fullscreen.spec.whatwg.org/#user-agent-level-style-sheet-defaults */

:not(:root):-webkit-full-screen {
:not(:root):fullscreen {
position: fixed !important;
inset: 0 !important;
margin: 0 !important;
@@ -43,27 +43,27 @@
object-fit:contain;
}

:root:-webkit-full-screen-document:not(:-webkit-full-screen) {
:root:-webkit-full-screen-document:not(:fullscreen) {
overflow: hidden !important;
}

:-webkit-full-screen video,
video:-webkit-full-screen {
:fullscreen video,
video:fullscreen {
-webkit-cursor-visibility: auto-hide;
}

img:-webkit-full-screen {
img:fullscreen {
width: auto;
height: 100%;
max-width: 100%;
}

iframe:-webkit-full-screen {
iframe:fullscreen {
border: none !important;
padding: 0 !important;
}

:not(:root):-webkit-full-screen::backdrop {
:not(:root):fullscreen::backdrop {
background: black;
}

@@ -104,7 +104,8 @@ static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationIsWindowInactive,
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesDir, bool, (const Element&, uint32_t));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesLangPseudoClass, bool, (const Element&, const FixedVector<PossiblyQuotedIdentifier>&));
#if ENABLE(FULLSCREEN_API)
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFullScreenPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFullscreenPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesWebkitFullScreenPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFullScreenDocumentPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFullScreenAncestorPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFullScreenAnimatingFullScreenTransitionPseudoClass, bool, (const Element&));
@@ -716,9 +717,14 @@ JSC_DEFINE_JIT_OPERATION(operationIsWindowInactive, bool, (const Element& elemen
}

#if ENABLE(FULLSCREEN_API)
JSC_DEFINE_JIT_OPERATION(operationMatchesFullScreenPseudoClass, bool, (const Element& element))
JSC_DEFINE_JIT_OPERATION(operationMatchesFullscreenPseudoClass, bool, (const Element& element))
{
return matchesFullScreenPseudoClass(element);
return matchesFullscreenPseudoClass(element);
}

JSC_DEFINE_JIT_OPERATION(operationMatchesWebkitFullScreenPseudoClass, bool, (const Element& element))
{
return matchesWebkitFullScreenPseudoClass(element);
}

JSC_DEFINE_JIT_OPERATION(operationMatchesFullScreenDocumentPseudoClass, bool, (const Element& element))
@@ -896,8 +902,11 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec
return FunctionType::SimpleSelectorChecker;

#if ENABLE(FULLSCREEN_API)
case CSSSelector::PseudoClassFullScreen:
fragment.unoptimizedPseudoClasses.append(CodePtr<JSC::OperationPtrTag>(operationMatchesFullScreenPseudoClass));
case CSSSelector::PseudoClassFullscreen:
fragment.unoptimizedPseudoClasses.append(CodePtr<JSC::OperationPtrTag>(operationMatchesFullscreenPseudoClass));
return FunctionType::SimpleSelectorChecker;
case CSSSelector::PseudoClassWebkitFullScreen:
fragment.unoptimizedPseudoClasses.append(CodePtr<JSC::OperationPtrTag>(operationMatchesWebkitFullScreenPseudoClass));
return FunctionType::SimpleSelectorChecker;
case CSSSelector::PseudoClassFullScreenDocument:
fragment.unoptimizedPseudoClasses.append(CodePtr<JSC::OperationPtrTag>(operationMatchesFullScreenDocumentPseudoClass));
@@ -4169,6 +4169,7 @@ void Element::requestFullscreen(FullscreenOptions&&, RefPtr<DeferredPromise>&& p

void Element::setFullscreenFlag(bool flag)
{
Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFullscreen, flag);
if (flag)
setNodeFlag(NodeFlag::IsFullscreen);
else
@@ -443,12 +443,13 @@ bool FullscreenManager::willEnterFullscreen(Element& element)
m_pendingFullscreenElement = nullptr;
m_fullscreenElement = &element;

document().resolveStyle(Document::ResolveStyleType::Rebuild);

Element* ancestor = m_fullscreenElement.get();
Element* ancestor = &element;
do {
ancestor->setFullscreenFlag(true);

if (ancestor == &element)
document().resolveStyle(Document::ResolveStyleType::Rebuild);

if (!ancestor->isInTopLayer())
ancestor->addToTopLayer();
addDocumentToFullscreenChangeEventQueue(ancestor->document());

0 comments on commit 47a2916

Please sign in to comment.