Open Bug 1885596 Opened 8 months ago Updated 22 days ago

Implement better anchoring/positioning logic for in-content feature callouts

Categories

(Firefox :: Messaging System, task, P2)

task
Points:
13

Tracking

()

People

(Reporter: aminomancer, Unassigned)

References

(Depends on 1 open bug, Blocks 2 open bugs)

Details

This bug is about making sure the callout is properly anchored to its anchor node. Right now, we do that in the chrome by wrapping the callout in a <panel> element, which is a XULPopupElement. That automatically gives it a lower level behavior ensuring it follows its anchor around and disappears when its anchor disappears. But the existing in-content FeatureCallout code (inherited from the original use of FeatureCallout in Firefox View) will not be able to follow its anchor around. It has an absolute position relative to the page, and it only updates its position on scroll and resize events. This won't work for upcoming purposes in about:newtab and PDF.js.

I propose that we rethink the in-content approach from the ground up. Webpages with similar anchored popups, dropdowns, etc. often approach this a bit differently: they make the callout a child of the anchor node, and they set CSS rules on both with the callout's position relative to the anchor (parent) rather than relative to the page:

anchor {
  overflow: visible;
  position: relative;
}

callout {
  position: absolute;
  bottom: ...
}

That way, if the anchor moves on layout (say its left sibling was hidden so it got moved to the left), the callout will follow along with it automatically.

Iteration: --- → 126.1 - Mar 18 - Mar 29
Priority: -- → P1
Iteration: 126.1 - Mar 18 - Mar 29 → 126.2 - Apr 1 - Apr 12

I have some updates and some recommendations from Emilio. There are several ways we can approach this, and we might want to implement the simplest one for now, but update it later to a more permanent configuration.

  1. CSSWG is working on CSS Anchor Positioning, which is basically the holy grail for what we're trying to do.
    • They're looking for help with prototyping/testing, so we could help accelerate this.
  2. Watching the position of an element is kinda annoying but if you know which changes can affect its position you might be able to (ab)use an IntersectionObserver
  3. The Popover API can be used to avoid the overflow issue. Popovers don't respect their ancestors' overflow styling, but they do (for now, by the default static position) get positioned relative to their parent. So, popover could substitute for panel in content. We should try this first since it already exists.
    • There's some indication that this will change in the future, with popover position changing to resemble absolute position. But the justification for changing that is the introduction of anchor positioning, which will make this use case obsolete. So when this does change, we should be able to switch to an anchor positioned <div>.
  4. Another (less ideal) solution would be to allow rendering nsMenuPopupFrames in content. document.insertAnonymousContent() can be used to render something like a panel without exposing it to the web content, but we'd still need to free up the aforementioned restrictions on nsMenuPopupFrame (I'm not sure where those are, we'd need to research it if we go in this direction).

Bug 1838746 is the anchor positioning metabug. Helping to drive that forward will be really useful since it'll give us a permanent, non-janky system for callout positioning in content.

A note about selection menus: Ed has created a prototype to open a callout when text is selected. And the callout is positioned relative to the selection. Selected text is not an element, so you can't make a popover a child of selected text, nor can you give the selected text an anchor-name. Normally, these selection menus listen to selectionchange events and adjust the callout offset accordingly. I think this is fine, because although the selected text is not an element, the only way the selected text can move is if the element containing it moves. So if the popover is a child of the same element the text is, and the popover's position offset is relative to that parent element, then it will move with the selected text. Same goes for anchor positioning.

We also need to think about how we might isolate the callout from the web content. The callout's click event handlers should check event.isTrusted to make sure the webpage isn't responsible for the interaction. Maybe there are other security concerns. I mentioned document.insertAnonymousContent above, but I don't think that kind of anonymous content can have an ordinary HTML parent element. It seems like it's inserted as a child of the document instead. Though that might still work for anchor positioning, maybe out of the box or maybe with special handling.

See Also: → css-anchor-position-1
Iteration: 126.2 - Apr 1 - Apr 12 → 127.1 - Apr 15 - Apr 26
Iteration: 127.1 - Apr 15 - Apr 26 → 127.2 - Apr 29 - May 10
Iteration: 127.2 - Apr 29 - May 10 → 128.1 - May 13 - May 24
Iteration: 128.1 - May 13 - May 24 → 128.2 - May 27 - Jun 7
Points: 5 → 13
Priority: P1 → P2
Iteration: 128.2 - May 27 - Jun 7 → 129.1 - Jun 10 - Jun 21
Iteration: 129.1 - Jun 10 - Jun 21 → 129.2 - Jun 24 - Jul 5
Iteration: 129.2 - Jun 24 - Jul 5 → 130.1 - Jul 8 - Jul 19
Iteration: 130.1 - Jul 8 - Jul 19 → 130.2 - Jul 22 - Aug 2
Iteration: 130.2 - Jul 22 - Aug 2 → 131.1 - Aug 5 - Aug 16
Iteration: 131.1 - Aug 5 - Aug 16 → 131.2 - Aug 19 - Aug 30
Iteration: 131.2 - Aug 19 - Aug 30 → 132.1 - Sep 2 - Sep 13
Iteration: 132.1 - Sep 2 - Sep 13 → 132.2 - Sep 16 - Sep 27
Iteration: 132.2 - Sep 16 - Sep 27 → 133.1 - Sep 30 - Oct 11
Iteration: 133.1 - Sep 30 - Oct 11 → 133.2 - Oct 14 - Oct 25
Iteration: 133.2 - Oct 14 - Oct 25 → ---
You need to log in before you can comment on or make changes to this bug.