Open Bug 1998508 Opened 11 months ago Updated 11 months ago

Descending `:visited` selector matches through @scope

Categories

(Core :: CSS Parsing and Computation, defect)

defect

Tracking

()

ASSIGNED

People

(Reporter: dshin, Assigned: dshin)

References

(Blocks 1 open bug)

Details

(Whiteboard: [at-scope-triage])

Attachments

(3 files)

Was hidden behind WPT scope-visited.html failing in general due to async nature.

Failure is specific to us not stopping matching when we see a link matching a :visited. Can't locate the spec at the moment, but this is mentioned in the testcase as well as Servo.

Cases not utilizing @scope e.g. :visited > :visited {} never matches, so this seems to be expected in general.

The test confirms this by constructing <a> into <a> through JS, which seems quite edge-casey.

Proper fix to this would require handling, say, @scope (:is(.with_class_outer, :visited)), by knowing what matching branch is taken, so it isn't exactly trivial.

At least, we should only have to handle :visited, since our matching machinery already handles e.g. :visited .with_class_inner.

Proper fix to this would require handling, say, @scope (:is(.with_class_outer, :visited)), by knowing what matching branch is taken, so it isn't exactly trivial.

Should it? Visited matching works by switching the VisitedHandlingMode while matching, seems we should be able to do that? It's not needed to branch on the specific selector.

That is, should this just be a matter of using VisitedHandlingMode::AllLinksUnvisited while matching the scope selectors?

Flags: needinfo?(dshin)

(In reply to Emilio Cobos Álvarez [:emilio] from comment #2)

That is, should this just be a matter of using VisitedHandlingMode::AllLinksUnvisited while matching the scope selectors?

@scope (:visited) { :scope {}} needs to match, though.

Flags: needinfo?(dshin)

Oh, I guess we should only do that if the targeted element is a link.

Ah, but

<a href="" class="with_class_outer">
  Visited1
  <a href="" class="with_class_inner">Visited2</a>
</a>

should match

@scope(.with_class_outer) {
  :scope > :visited { color: green; }
}

(Part of scope-visited.html)

That's fine tho, right? Visited handling only changes whether :visited matches. So the class selector should be unaffected

So what I was thinking is that we can't just find the scope root and apply VisitedHandlingMode::AllLinksUnvisited if the scope root candidate is_link().

The way scope root gathering works, it happens before the inner selector match, through separate matches_selector calls, and as far as I can tell (Could be missing something), with_visited_handling_mode used during matching is transient, once the matching concludes for scope root, we lose the information on if we matched :visited, which we'd need to set visited handling mode for the inner scoped selector matching.

No, I think we might be talking past each other. My point is that if the inner element (actually probably also if a previous scope root candidate, but importantly not the scope root candidate we're about to check!) is a link then the scope should use AllLinksUnvisited.

Is there something I'm missing? That seems pretty similar to how we deal with combinators during selector matching. As long as we've walked out of a "link" subtree, we stop finding visited links.

We might want to set in_link after calling check(), I forget the exact
@scope semantics.

Assignee: nobody → dshin
Status: NEW → ASSIGNED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: