@@ -8,7 +8,7 @@ use std::time::Duration;
8
8
9
9
use constellation_traits:: NavigationHistoryBehavior ;
10
10
use dom_struct:: dom_struct;
11
- use html5ever:: { LocalName , Prefix } ;
11
+ use html5ever:: { LocalName , Prefix , local_name , namespace_url , ns } ;
12
12
use js:: rust:: HandleObject ;
13
13
use regex:: bytes:: Regex ;
14
14
use servo_url:: ServoUrl ;
@@ -21,7 +21,7 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
21
21
use crate :: dom:: bindings:: inheritance:: Castable ;
22
22
use crate :: dom:: bindings:: root:: DomRoot ;
23
23
use crate :: dom:: bindings:: str:: DOMString ;
24
- use crate :: dom:: document:: { DeclarativeRefresh , Document } ;
24
+ use crate :: dom:: document:: { DeclarativeRefresh , Document , determine_policy_for_token } ;
25
25
use crate :: dom:: element:: { AttributeMutation , Element } ;
26
26
use crate :: dom:: htmlelement:: HTMLElement ;
27
27
use crate :: dom:: htmlheadelement:: HTMLHeadElement ;
@@ -115,9 +115,31 @@ impl HTMLMetaElement {
115
115
116
116
/// <https://html.spec.whatwg.org/multipage/#meta-referrer>
117
117
fn apply_referrer ( & self ) {
118
- if let Some ( parent) = self . upcast :: < Node > ( ) . GetParentElement ( ) {
119
- if let Some ( head) = parent. downcast :: < HTMLHeadElement > ( ) {
120
- head. set_document_referrer ( ) ;
118
+ let doc = self . owner_document ( ) ;
119
+ // From spec: For historical reasons, unlike other standard metadata names, the processing model for referrer
120
+ // is not responsive to element removals, and does not use tree order. Only the most-recently-inserted or
121
+ // most-recently-modified meta element in this state has an effect.
122
+ // 1. If element is not in a document tree, then return.
123
+ let meta_node = self . upcast :: < Node > ( ) ;
124
+ if !meta_node. is_in_a_document_tree ( ) {
125
+ return ;
126
+ }
127
+
128
+ // 2. If element does not have a name attribute whose value is an ASCII case-insensitive match for "referrer",
129
+ // then return.
130
+ if self . upcast :: < Element > ( ) . get_name ( ) != Some ( atom ! ( "referrer" ) ) {
131
+ return ;
132
+ }
133
+
134
+ // 3. If element does not have a content attribute, or that attribute's value is the empty string, then return.
135
+ let content = self
136
+ . upcast :: < Element > ( )
137
+ . get_attribute ( & ns ! ( ) , & local_name ! ( "content" ) ) ;
138
+ if let Some ( attr) = content {
139
+ let attr = attr. value ( ) ;
140
+ let attr_val = attr. trim ( ) ;
141
+ if !attr_val. is_empty ( ) {
142
+ doc. set_referrer_policy ( determine_policy_for_token ( attr_val) ) ;
121
143
}
122
144
}
123
145
}
0 commit comments