Skip to content

Commit

Permalink
Add togglePopover() method for popovers
Browse files Browse the repository at this point in the history
Per the resolution [1] there's a desire to add a togglePopover()
convenience method. This CL adds that method plus tests.

[1] openui/open-ui#610 (comment)

Bug: 1307772
Change-Id: Icd39c766786e7d1f6475a86ca8a7a1e89b66182e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4000073
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1067805}
  • Loading branch information
Mason Freed authored and Chromium LUCI CQ committed Nov 5, 2022
1 parent 4864bf9 commit 9c386f1
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3464,6 +3464,8 @@ enum WebFeature {
kWindowProxyCrossOriginAccessFromOtherPageTop = 4143,
kWindowProxyCrossOriginAccessFromOtherPageWindow = 4144,
kPrivateNetworkAccessFetchedWorkerScript = 4145,
// The items above roughly this point are available in the M99 branch.

kFrameNameContainsBrace = 4146,
kFrameNameContainsNewline = 4147,
kAbortSignalThrowIfAborted = 4148,
Expand Down Expand Up @@ -3496,6 +3498,8 @@ enum WebFeature {
kMediaCapabilitiesEncodingInfoWebrtc = 4175,
kUsbDeviceForget = 4176,
kPartitionedCookies = 4177,
// The items above roughly this point are available in the M100 branch.

kSecureContextIncorrectForSharedWorker = 4178,
kV8FunctionPrototypeArguments = 4179,
kV8FunctionPrototypeCaller = 4180,
Expand All @@ -3507,6 +3511,8 @@ enum WebFeature {
kPressureObserver_TakeRecords = 4186,
kPrivacySandboxAdsAPIs = 4187,
kFledge = 4188,
// The items above roughly this point are available in the M101 branch.

kElementShowPopover = 4189,
kElementHidePopover = 4190,
kValidPopoverAttribute = 4191,
Expand All @@ -3530,6 +3536,8 @@ enum WebFeature {
kOBSOLETE_LegacyConstraintGoogCpuOveruseDetection = 4209,
kAudioContextOutputLatency = 4210,
kV8Window_QueryLocalFonts_Method = 4211,
// The items above roughly this point are available in the M102 branch.

kCSSAtRuleScope = 4212,
kOBSOLETE_DeferredShapingDisabledByPositioned = 4213,
kCapabilityDelegationOfFullscreenRequest = 4214,
Expand All @@ -3546,6 +3554,8 @@ enum WebFeature {
kFedCmLogout = 4225,
kFedCmLogoutRps = 4226,
kV8Navigator_DeprecatedReplaceInURN_Method = 4227,
// The items above roughly this point are available in the M103 branch.

kWebAppBorderless = 4228,
kPaymentInstruments = 4229,
kV8PaymentInstruments_Clear_Method = 4230,
Expand Down Expand Up @@ -3602,6 +3612,8 @@ enum WebFeature {
kV8PendingBeacon_Deactivate_Method = 4281,
kOBSOLETE_kV8PendingBeacon_SetData_Method = 4282,
kV8PendingBeacon_SendNow_Method = 4283,
// The items above roughly this point are available in the M104 branch.

kTabSharingBarSwitchToCapturer = 4284,
kTabSharingBarSwitchToCapturee = 4285,
kAutomaticLazyAds = 4286,
Expand Down Expand Up @@ -3648,12 +3660,16 @@ enum WebFeature {
kV8PendingPostBeacon_SetData_Method = 4327,
kContentVisibilityAutoStateChangedHandlerRegistered = 4328,
kReplacedElementPaintedWithLargeOverflow = 4329,
// The items above roughly this point are available in the M105 branch.

kFlexboxAbsPosJustifyContent = 4330,
kMultipleFetchHandlersInServiceWorker = 4331,
kStorageAccessAPI_requestStorageAccessForOrigin_Method = 4332,
kPrivateAggregationApiAll = 4333,
kPrivateAggregationApiFledge = 4334,
kPrivateAggregationApiSharedStorage = 4335,
// The items above roughly this point are available in the M106 branch.

kDeferredShaping2ReshapedByComputedStyle = 4336,
kDeferredShaping2ReshapedByDomContentLoaded = 4337,
kDeferredShaping2ReshapedByFcp = 4338,
Expand Down Expand Up @@ -3681,6 +3697,8 @@ enum WebFeature {
kDestructiveDocumentWriteAfterModuleScript = 4360,
kCSSAtSupportsDropInvalidWhileForgivingParsing = 4361,
kPermissionsPolicyUnload = 4362,
// The items above roughly this point are available in the M107 branch.

kServiceWorkerSkippedForSubresourceLoad = 4363,
kClientHintsPrefersReducedMotion = 4364,
kWakeLockAcquireScreenLockWithoutActivation = 4365,
Expand All @@ -3702,6 +3720,9 @@ enum WebFeature {
kViewportDependentLazyLoadedImageWithoutSizesAttribute = 4381,
kV8MediaStreamTrack_ApplyConstraints_Method = 4382,
kViewTransition = 4383,
// The items above roughly this point are available in the M108 branch.

kElementTogglePopover = 4384,

// Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots.
Expand Down
20 changes: 20 additions & 0 deletions third_party/blink/renderer/core/html/html_element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,26 @@ bool HTMLElement::popoverOpen() const {
return false;
}

void HTMLElement::togglePopover(ExceptionState& exception_state) {
DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
GetDocument().GetExecutionContext()));
if (!HasPopoverAttribute()) {
return exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
"Not supported on elements that do not have a valid value for the "
"'popover' attribute");
} else if (!isConnected()) {
return exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"Invalid disconnected popover elements");
}
if (popoverOpen()) {
hidePopover(exception_state);
} else {
showPopover(exception_state);
}
}

// Showing a popover happens in phases, to facilitate animations and
// transitions:
// 1. Move the popover to the top layer, stop matching `:closed`, and
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/html/html_element.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class CORE_EXPORT HTMLElement : public Element {
bool HasPopoverAttribute() const;
PopoverValueType PopoverType() const;
bool popoverOpen() const;
void togglePopover(ExceptionState& exception_state);
void showPopover(ExceptionState& exception_state);
void hidePopover(ExceptionState& exception_state);
void HidePopoverInternal(HidePopoverFocusBehavior focus_behavior,
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/html/html_element.idl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
[ImplementedAs=offsetHeightForBinding] readonly attribute long offsetHeight;

// The Popover API
[MeasureAs=ElementTogglePopover,RuntimeEnabled=HTMLPopoverAttribute,RaisesException] void togglePopover();
[MeasureAs=ElementShowPopover,RuntimeEnabled=HTMLPopoverAttribute,RaisesException] void showPopover();
[MeasureAs=ElementHidePopover,RuntimeEnabled=HTMLPopoverAttribute,RaisesException] void hidePopover();
[CEReactions,RuntimeEnabled=HTMLPopoverAttribute,MeasureAs=AnyPopoverAttribute,Reflect,ReflectOnly=("auto","manual"),ReflectEmpty="auto",ReflectInvalid="manual"] attribute DOMString? popover;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@
popover.hidePopover();
assertPopoverVisibility(popover, /*isPopover*/true, /*expectedVisibility*/false, 'After hidePopover(), a popover should be hidden');
assert_throws_dom("InvalidStateError",() => popover.hidePopover(),'Calling hidePopover on a hidden popover should throw InvalidStateError');
popover.togglePopover();
assertPopoverVisibility(popover, /*isPopover*/true, /*expectedVisibility*/true, 'After togglePopover() on hidden popover, it should be visible');
popover.togglePopover();
assertPopoverVisibility(popover, /*isPopover*/true, /*expectedVisibility*/false, 'After togglePopover() on visible popover, it should be hidden');
const parent = popover.parentElement;
popover.remove();
assert_throws_dom("InvalidStateError",() => popover.showPopover(),'Calling showPopover on a disconnected popover should throw InvalidStateError');
assert_throws_dom("InvalidStateError",() => popover.hidePopover(),'Calling hidePopover on a disconnected popover should throw InvalidStateError');
assert_throws_dom("InvalidStateError",() => popover.togglePopover(),'Calling hidePopover on a disconnected popover should throw InvalidStateError');
parent.appendChild(popover);
}
function assertNotAPopover(nonPopover) {
Expand All @@ -76,6 +82,8 @@
assertPopoverVisibility(nonPopover, /*isPopover*/false, expectVisible, 'Calling showPopover on a non-popover should leave it visible');
assert_throws_dom("NotSupportedError",() => nonPopover.hidePopover(),'Calling hidePopover on a non-popover should throw NotSupportedError');
assertPopoverVisibility(nonPopover, /*isPopover*/false, expectVisible, 'Calling hidePopover on a non-popover should leave it visible');
assert_throws_dom("NotSupportedError",() => nonPopover.togglePopover(),'Calling togglePopover on a non-popover should throw NotSupportedError');
assertPopoverVisibility(nonPopover, /*isPopover*/false, expectVisible, 'Calling togglePopover on a non-popover should leave it visible');
}

// Start with the provided examples:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ namespace http://www.w3.org/1999/xhtml
property title
property toString
property toggleAttribute
property togglePopover
property toggles
property translate
property virtualKeyboardPolicy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3368,6 +3368,7 @@ interface HTMLElement : Element
method focus
method hidePopover
method showPopover
method togglePopover
setter accessKey
setter autocapitalize
setter autofocus
Expand Down
1 change: 1 addition & 0 deletions tools/metrics/histograms/enums.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42320,6 +42320,7 @@ Called by update_use_counter_feature_enum.py.-->
label="ViewportDependentLazyLoadedImageWithoutSizesAttribute"/>
<int value="4382" label="V8MediaStreamTrack_ApplyConstraints_Method"/>
<int value="4383" label="ViewTransition"/>
<int value="4384" label="ElementTogglePopover"/>
</enum>

<enum name="FeaturePolicyAllowlistType">
Expand Down

0 comments on commit 9c386f1

Please sign in to comment.