From e5952c724919d15b42e384f78c6c693dd1a1af19 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Tue, 6 Aug 2024 07:46:20 +0000 Subject: [PATCH] Bug 1831649 - Parse `interactive-widget`. r=botond,emilio It's defined in the CSS viewport spec. https://drafts.csswg.org/css-viewport/#interactive-widget-section Differential Revision: https://phabricator.services.mozilla.com/D204163 --- dom/base/Document.cpp | 38 +++++++++++++++++++++++++++++++++++ dom/base/Document.h | 10 ++++++++- dom/base/InteractiveWidget.h | 19 ++++++++++++++++++ dom/base/ViewportMetaData.cpp | 2 ++ dom/base/ViewportMetaData.h | 4 +++- dom/base/moz.build | 1 + xpcom/ds/StaticAtoms.py | 1 + 7 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 dom/base/InteractiveWidget.h diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 43c408da843b..a1d840227428 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -194,6 +194,7 @@ #include "mozilla/dom/HTMLTextAreaElement.h" #include "mozilla/dom/ImageTracker.h" #include "mozilla/dom/InspectorUtils.h" +#include "mozilla/dom/InteractiveWidget.h" #include "mozilla/dom/Link.h" #include "mozilla/dom/MediaQueryList.h" #include "mozilla/dom/MediaSource.h" @@ -1432,6 +1433,7 @@ Document::Document(const char* aContentType) mHttpsOnlyStatus(nsILoadInfo::HTTPS_ONLY_UNINITIALIZED), mViewportType(Unknown), mViewportFit(ViewportFitType::Auto), + mInteractiveWidgetMode(InteractiveWidget::ResizesContent), mHeaderData(nullptr), mServoRestyleRootDirtyBits(0), mThrowOnDynamicMarkupInsertionCounter(0), @@ -10953,11 +10955,47 @@ ViewportMetaData Document::GetViewportMetaData() const { : ViewportMetaData(); } +static InteractiveWidget ParseInteractiveWidget( + const ViewportMetaData& aViewportMetaData) { + if (aViewportMetaData.mInteractiveWidgetMode.IsEmpty()) { + // The spec defines "use `resizes-visual` if no value specified", but here + // we use `resizes-content` for the backward compatibility now. + // We will change it in bug 1884807. + return InteractiveWidget::ResizesContent; + } + + if (aViewportMetaData.mInteractiveWidgetMode.EqualsIgnoreCase( + "resizes-visual")) { + return InteractiveWidget::ResizesVisual; + } + if (aViewportMetaData.mInteractiveWidgetMode.EqualsIgnoreCase( + "resizes-content")) { + return InteractiveWidget::ResizesContent; + } + if (aViewportMetaData.mInteractiveWidgetMode.EqualsIgnoreCase( + "overlays-content")) { + return InteractiveWidget::OverlaysContent; + } + // For the same reason above empty case, we use `resizes-content` here. + return InteractiveWidget::ResizesContent; +} + void Document::SetMetaViewportData(UniquePtr aData) { mLastModifiedViewportMetaData = std::move(aData); // Trigger recomputation of the nsViewportInfo the next time it's queried. mViewportType = Unknown; + // Parse interactive-widget here anyway. Normally we parse any data in the + // meta viewport tag in GetViewportInfo(), but GetViewportInfo() depends on + // the document state (e.g. display size, fullscreen, desktop-mode etc.) + // whereas interactive-widget is independent from the document state, it's + // necessary whatever the document state is. + dom::InteractiveWidget interactiveWidget = + ParseInteractiveWidget(*mLastModifiedViewportMetaData); + if (mInteractiveWidgetMode != interactiveWidget) { + mInteractiveWidgetMode = interactiveWidget; + } + AsyncEventDispatcher::RunDOMEventWhenSafe( *this, u"DOMMetaViewportFitChanged"_ns, CanBubble::eYes, ChromeOnlyDispatch::eYes); diff --git a/dom/base/Document.h b/dom/base/Document.h index 7a8d8f2a716f..b3f10be43f71 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -246,7 +246,6 @@ class FeaturePolicy; class FontFaceSet; class FragmentDirective; class FrameRequestCallback; -class ImageTracker; class HighlightRegistry; class HTMLAllCollection; class HTMLBodyElement; @@ -256,6 +255,8 @@ class HTMLDialogElement; class HTMLSharedElement; class HTMLVideoElement; class HTMLImageElement; +class ImageTracker; +enum class InteractiveWidget : uint8_t; struct LifecycleCallbackArgs; class Link; class Location; @@ -3958,6 +3959,10 @@ class Document : public nsINode, public: const OriginTrials& Trials() const { return mTrials; } + dom::InteractiveWidget InteractiveWidget() const { + return mInteractiveWidgetMode; + } + private: void DoCacheAllKnownLangPrefs(); void RecomputeLanguageFromCharset(); @@ -5173,6 +5178,9 @@ class Document : public nsINode, // https://drafts.csswg.org/css-round-display/#viewport-fit-descriptor ViewportFitType mViewportFit; + // https://drafts.csswg.org/css-viewport/#interactive-widget-section + dom::InteractiveWidget mInteractiveWidgetMode; + // XXXdholbert This should really be modernized to a nsTHashMap or similar, // though note that the modernization will need to take care to also convert // the special hash_table_ops logic (e.g. how SubDocClearEntry clears the diff --git a/dom/base/InteractiveWidget.h b/dom/base/InteractiveWidget.h new file mode 100644 index 000000000000..27b17ed73e62 --- /dev/null +++ b/dom/base/InteractiveWidget.h @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DOM_INTERACTIVE_WIDGET_H_ +#define DOM_INTERACTIVE_WIDGET_H_ + +namespace mozilla::dom { +// https://drafts.csswg.org/css-viewport/#interactive-widget-section +enum class InteractiveWidget : uint8_t { + OverlaysContent, + ResizesContent, + ResizesVisual, +}; +} // namespace mozilla::dom + +#endif // DOM_INTERACTIVE_WIDGET_H_ diff --git a/dom/base/ViewportMetaData.cpp b/dom/base/ViewportMetaData.cpp index 2646621629ce..a0669e500d6c 100644 --- a/dom/base/ViewportMetaData.cpp +++ b/dom/base/ViewportMetaData.cpp @@ -59,6 +59,8 @@ static void ProcessViewportToken(ViewportMetaData& aData, aData.mUserScalable.Assign(value); } else if (key_atom == nsGkAtoms::viewport_fit) { aData.mViewportFit.Assign(value); + } else if (key_atom == nsGkAtoms::interactive_widget) { + aData.mInteractiveWidgetMode.Assign(value); } } diff --git a/dom/base/ViewportMetaData.h b/dom/base/ViewportMetaData.h index 7de6eda731b4..14a908fff143 100644 --- a/dom/base/ViewportMetaData.h +++ b/dom/base/ViewportMetaData.h @@ -20,6 +20,7 @@ struct ViewportMetaData { nsString mMaximumScale; nsString mUserScalable; nsString mViewportFit; + nsString mInteractiveWidgetMode; bool operator==(const ViewportMetaData& aOther) const { return mWidth == aOther.mWidth && mHeight == aOther.mHeight && @@ -27,7 +28,8 @@ struct ViewportMetaData { mMinimumScale == aOther.mMinimumScale && mMaximumScale == aOther.mMaximumScale && mUserScalable == aOther.mUserScalable && - mViewportFit == aOther.mViewportFit; + mViewportFit == aOther.mViewportFit && + mInteractiveWidgetMode == aOther.mInteractiveWidgetMode; } bool operator!=(const ViewportMetaData& aOther) const { return !(*this == aOther); diff --git a/dom/base/moz.build b/dom/base/moz.build index 1fa6009f3ac9..7ce0213605b8 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -210,6 +210,7 @@ EXPORTS.mozilla.dom += [ "IDTracker.h", "ImageEncoder.h", "ImageTracker.h", + "InteractiveWidget.h", "IntlUtils.h", "JSExecutionContext.h", "Link.h", diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index 6b019b999b9b..3dd62646a885 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -568,6 +568,7 @@ STATIC_ATOMS = [ Atom("insertion", "insertion"), Atom("integer", "integer"), Atom("integrity", "integrity"), + Atom("interactive_widget", "interactive-widget"), Atom("internal", "internal"), Atom("internals", "internals"), Atom("intersection", "intersection"),