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
This commit is contained in:
Hiroyuki Ikezoe 2024-08-06 07:46:20 +00:00
parent b76d3a301d
commit a0e0c6ed8c
7 changed files with 73 additions and 2 deletions

View File

@ -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<ViewportMetaData> 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);

View File

@ -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

View File

@ -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_

View File

@ -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);
}
}

View File

@ -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);

View File

@ -210,6 +210,7 @@ EXPORTS.mozilla.dom += [
"IDTracker.h",
"ImageEncoder.h",
"ImageTracker.h",
"InteractiveWidget.h",
"IntlUtils.h",
"JSExecutionContext.h",
"Link.h",

View File

@ -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"),