mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Initial support for <link rel="prefetch">
(#33345)
* Properly store link relations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Send fetch request for prefetch links We don't actually *do* anything with the response yet (handle errors etc) but its a first step. Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Fire load/error events for prefetch loads Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Set prefetch destination/cors setting correctly Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update WPT expectations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Fix ./mach test-tidy errors Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Set correct "Accept" value for prefetch requests Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Add spec text to individual steps Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
2993577ac0
commit
10e5bb72d9
11 changed files with 531 additions and 182 deletions
131
components/script/link_relations.rs
Normal file
131
components/script/link_relations.rs
Normal file
|
@ -0,0 +1,131 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use html5ever::{local_name, namespace_url, ns};
|
||||
use malloc_size_of::malloc_size_of_is_0;
|
||||
use style::str::HTML_SPACE_CHARACTERS;
|
||||
|
||||
use crate::dom::types::Element;
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct LinkRelations: u32 {
|
||||
const ALTERNATE = 1;
|
||||
const AUTHOR = 1 << 1;
|
||||
const BOOKMARK = 1 << 2;
|
||||
const CANONICAL = 1 << 3;
|
||||
const DNS_PREFETCH = 1 << 4;
|
||||
const EXPECT = 1 << 5;
|
||||
const EXTERNAL = 1 << 6;
|
||||
const HELP = 1 << 7;
|
||||
const ICON = 1 << 8;
|
||||
const LICENSE = 1 << 9;
|
||||
const NEXT = 1 << 10;
|
||||
const MANIFEST = 1 << 11;
|
||||
const MODULE_PRELOAD = 1 << 12;
|
||||
const NO_FOLLOW = 1 << 13;
|
||||
const NO_OPENER = 1 << 14;
|
||||
const NO_REFERRER = 1 << 15;
|
||||
const OPENER = 1 << 16;
|
||||
const PING_BACK = 1 << 17;
|
||||
const PRECONNECT = 1 << 18;
|
||||
const PREFETCH = 1 << 19;
|
||||
const PRELOAD = 1 << 20;
|
||||
const PREV = 1 << 21;
|
||||
const PRIVACY_POLICY = 1 << 22;
|
||||
const SEARCH = 1 << 23;
|
||||
const STYLESHEET = 1 << 24;
|
||||
const TAG = 1 << 25;
|
||||
const TermsOfService = 1 << 26;
|
||||
}
|
||||
}
|
||||
|
||||
impl LinkRelations {
|
||||
pub fn for_element(element: &Element) -> Self {
|
||||
let rel = element.get_attribute(&ns!(), &local_name!("rel")).map(|e| {
|
||||
let value = e.value();
|
||||
(**value).to_owned()
|
||||
});
|
||||
|
||||
// FIXME: for a, area and form elements we need to allow a different
|
||||
// set of attributes
|
||||
let mut relations = rel
|
||||
.map(|attribute| {
|
||||
attribute
|
||||
.split(HTML_SPACE_CHARACTERS)
|
||||
.map(Self::from_single_keyword_for_link_element)
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or(Self::empty());
|
||||
|
||||
// For historical reasons, "rev=made" is treated as if the "author" relation was specified
|
||||
let has_legacy_author_relation = element
|
||||
.get_attribute(&ns!(), &local_name!("rev"))
|
||||
.is_some_and(|rev| &**rev.value() == "made");
|
||||
if has_legacy_author_relation {
|
||||
relations |= Self::AUTHOR;
|
||||
}
|
||||
|
||||
relations
|
||||
}
|
||||
|
||||
/// Parse one of the relations allowed for the `<link>` element
|
||||
///
|
||||
/// If the keyword is invalid then `Self::empty` is returned.
|
||||
fn from_single_keyword_for_link_element(keyword: &str) -> Self {
|
||||
if keyword.eq_ignore_ascii_case("alternate") {
|
||||
Self::ALTERNATE
|
||||
} else if keyword.eq_ignore_ascii_case("canonical") {
|
||||
Self::CANONICAL
|
||||
} else if keyword.eq_ignore_ascii_case("author") {
|
||||
Self::AUTHOR
|
||||
} else if keyword.eq_ignore_ascii_case("dns-prefetch") {
|
||||
Self::DNS_PREFETCH
|
||||
} else if keyword.eq_ignore_ascii_case("expect") {
|
||||
Self::EXPECT
|
||||
} else if keyword.eq_ignore_ascii_case("help") {
|
||||
Self::HELP
|
||||
} else if keyword.eq_ignore_ascii_case("icon") ||
|
||||
keyword.eq_ignore_ascii_case("shortcut icon") ||
|
||||
keyword.eq_ignore_ascii_case("apple-touch-icon")
|
||||
{
|
||||
// TODO: "apple-touch-icon" is not in the spec. Where did it come from? Do we need it?
|
||||
// There is also "apple-touch-icon-precomposed" listed in
|
||||
// https://github.com/servo/servo/blob/e43e4778421be8ea30db9d5c553780c042161522/components/script/dom/htmllinkelement.rs#L452-L467
|
||||
Self::ICON
|
||||
} else if keyword.eq_ignore_ascii_case("manifest") {
|
||||
Self::MANIFEST
|
||||
} else if keyword.eq_ignore_ascii_case("modulepreload") {
|
||||
Self::MODULE_PRELOAD
|
||||
} else if keyword.eq_ignore_ascii_case("license") ||
|
||||
keyword.eq_ignore_ascii_case("copyright")
|
||||
{
|
||||
Self::LICENSE
|
||||
} else if keyword.eq_ignore_ascii_case("next") {
|
||||
Self::NEXT
|
||||
} else if keyword.eq_ignore_ascii_case("pingback") {
|
||||
Self::PING_BACK
|
||||
} else if keyword.eq_ignore_ascii_case("preconnect") {
|
||||
Self::PRECONNECT
|
||||
} else if keyword.eq_ignore_ascii_case("prefetch") {
|
||||
Self::PREFETCH
|
||||
} else if keyword.eq_ignore_ascii_case("preload") {
|
||||
Self::PRELOAD
|
||||
} else if keyword.eq_ignore_ascii_case("prev") || keyword.eq_ignore_ascii_case("previous") {
|
||||
Self::PREV
|
||||
} else if keyword.eq_ignore_ascii_case("privacy-policy") {
|
||||
Self::PRIVACY_POLICY
|
||||
} else if keyword.eq_ignore_ascii_case("search") {
|
||||
Self::SEARCH
|
||||
} else if keyword.eq_ignore_ascii_case("stylesheet") {
|
||||
Self::STYLESHEET
|
||||
} else if keyword.eq_ignore_ascii_case("terms-of-service") {
|
||||
Self::TermsOfService
|
||||
} else {
|
||||
Self::empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
malloc_size_of_is_0!(LinkRelations);
|
Loading…
Add table
Add a link
Reference in a new issue