Bug 1867939, part 5: Integrate find-text-directive algorithm into Document load. r=peterv,farre,dom-core

This patch integrates the algorithm to find a text fragment range
into the document loading mechanism.
Unlike described in the spec, the fragment directive is not stripped
from the URL in the Session History Entry, instead it is stripped when
setting the URI into the Document using `Document::SetURI()`,
as well as when accessing the URL through `Location`.

The `PresShell` class is extended by a new method which sets the
ranges created from the text directives into the FrameSelection as
TargetText selection and scrolls it into view.

Security restrictions like force load at top and cross-origin iframes
are not yet considered in this patch.

Differential Revision: https://phabricator.services.mozilla.com/D195688
This commit is contained in:
Jan-Niklas Jaeschke
2024-04-04 14:39:33 +00:00
parent dbaf47b1f4
commit 6019fb9e6a
6 changed files with 130 additions and 14 deletions

View File

@@ -14,6 +14,7 @@
#include "mozilla/dom/AncestorIterator.h"
#include "mozilla/dom/FontFaceSet.h"
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/FragmentDirective.h"
#include "mozilla/dom/LargestContentfulPaint.h"
#include "mozilla/dom/MouseEventBinding.h"
#include "mozilla/dom/PerformanceMainThread.h"
@@ -3291,6 +3292,46 @@ nsresult PresShell::ScrollToAnchor() {
ScrollAxis(), ScrollFlags::AnchorScrollFlags);
}
bool PresShell::HighlightAndGoToTextFragment(bool aScrollToTextFragment) {
MOZ_ASSERT(mDocument);
if (!StaticPrefs::dom_text_fragments_enabled()) {
return false;
}
const RefPtr<FragmentDirective> fragmentDirective =
mDocument->FragmentDirective();
nsTArray<RefPtr<nsRange>> textDirectiveRanges =
fragmentDirective->FindTextFragmentsInDocument();
if (textDirectiveRanges.IsEmpty()) {
return false;
}
const RefPtr<Selection> targetTextSelection =
GetCurrentSelection(SelectionType::eTargetText);
if (!targetTextSelection) {
return false;
}
for (RefPtr<nsRange> range : textDirectiveRanges) {
targetTextSelection->AddRangeAndSelectFramesAndNotifyListeners(
*range, IgnoreErrors());
}
if (!aScrollToTextFragment) {
return false;
}
// Scroll the last text directive into view.
nsRange* lastRange = textDirectiveRanges.LastElement();
MOZ_ASSERT(lastRange);
if (RefPtr<nsIContent> lastRangeStartContent =
nsIContent::FromNode(lastRange->GetStartContainer())) {
return ScrollContentIntoView(
lastRangeStartContent,
ScrollAxis(WhereToScroll::Center, WhenToScroll::Always),
ScrollAxis(), ScrollFlags::AnchorScrollFlags) == NS_OK;
}
return false;
}
/*
* Helper (per-continuation) for ScrollContentIntoView.
*