servo: Merge #15536 - Implement setter for document.domain (from asajeffrey:script-document-domain-setter); r=nox

<!-- Please describe your changes on the following line: -->

This PR implements the setter for `document.domain`.

It builds on #15438 and #15478, only the last commit is part of this PR.

It includes tests for similar-origin security checks.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #934.
- [X] There are tests for these changes.

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: e600e0495ce4ab0f1bb798689f8ebeab84258ec3

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : ec98c74739989d9ef39efc22b8b0b74cd26c6968
This commit is contained in:
Alan Jeffrey 2017-03-15 08:35:41 -07:00
Родитель 1d646c760e
Коммит 6ca8988eeb
14 изменённых файлов: 260 добавлений и 102 удалений

Просмотреть файл

@ -108,7 +108,7 @@ use servo_config::opts;
use servo_config::prefs::PREFS;
use servo_rand::{Rng, SeedableRng, ServoRng, random};
use servo_remutex::ReentrantMutex;
use servo_url::ServoUrl;
use servo_url::{Host, ServoUrl};
use std::borrow::ToOwned;
use std::collections::{HashMap, VecDeque};
use std::iter::once;
@ -229,13 +229,13 @@ pub struct Constellation<Message, LTF, STF> {
/// event loop for each registered domain name (aka eTLD+1) in
/// each top-level frame. We store the event loops in a map
/// indexed by top-level frame id (as a `FrameId`) and registered
/// domain name (as a `String`) to event loops. This double
/// domain name (as a `Host`) to event loops. This double
/// indirection ensures that separate tabs do not share event
/// loops, even if the same domain is loaded in each.
/// It is important that scripts with the same eTLD+1
/// share an event loop, since they can use `document.domain`
/// to become same-origin, at which point they can share DOM objects.
event_loops: HashMap<FrameId, HashMap<String, Weak<EventLoop>>>,
event_loops: HashMap<FrameId, HashMap<Host, Weak<EventLoop>>>,
/// The set of all the pipelines in the browser.
/// (See the `pipeline` module for more details.)
@ -604,16 +604,18 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
None => self.root_frame_id,
};
debug!("Creating new pipeline {} in top-level frame {}.", pipeline_id, top_level_frame_id);
let (event_loop, host) = match sandbox {
IFrameSandboxState::IFrameSandboxed => (None, None),
IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) {
None => (None, None),
Some(host) => {
let event_loop = self.event_loops.get(&top_level_frame_id)
.and_then(|map| map.get(host))
.and_then(|map| map.get(&host))
.and_then(|weak| weak.upgrade());
match event_loop {
None => (None, Some(String::from(host))),
None => (None, Some(host)),
Some(event_loop) => (Some(event_loop.clone()), None),
}
},
@ -677,6 +679,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
};
if let Some(host) = host {
debug!("Adding new host entry {} for top-level frame {}.", host, top_level_frame_id);
self.event_loops.entry(top_level_frame_id)
.or_insert_with(HashMap::new)
.insert(host, Rc::downgrade(&pipeline.event_loop));

Просмотреть файл

@ -15,7 +15,7 @@
//! those cases are not present.
use servo_config::resource_files::read_resource_file;
use servo_url::ServoUrl;
use servo_url::{Host, ImmutableOrigin, ServoUrl};
use std::collections::HashSet;
use std::iter::FromIterator;
use std::str::from_utf8;
@ -146,6 +146,10 @@ pub fn is_reg_domain(domain: &str) -> bool {
/// Returns None if the URL has no host name.
/// Returns the registered suffix for the host name if it is a domain.
/// Leaves the host name alone if it is an IP address.
pub fn reg_host<'a>(url: &'a ServoUrl) -> Option<&'a str> {
url.domain().map(reg_suffix).or(url.host_str())
pub fn reg_host(url: &ServoUrl) -> Option<Host> {
match url.origin() {
ImmutableOrigin::Tuple(_, Host::Domain(domain), _) => Some(Host::Domain(String::from(reg_suffix(&*domain)))),
ImmutableOrigin::Tuple(_, ip, _) => Some(ip),
ImmutableOrigin::Opaque(_) => None,
}
}

Просмотреть файл

@ -10,7 +10,6 @@ use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclar
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, jsstring_to_str};
use dom::bindings::inheritance::Castable;
@ -261,6 +260,6 @@ pub fn handle_request_animation_frame(documents: &Documents,
pub fn handle_reload(documents: &Documents,
id: PipelineId) {
if let Some(win) = documents.find_window(id) {
win.Location().Reload();
win.Location().reload_without_origin_check();
}
}

Просмотреть файл

@ -103,6 +103,7 @@ use msg::constellation_msg::{FrameId, Key, KeyModifiers, KeyState};
use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy};
use net_traits::CookieSource::NonHTTP;
use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl};
use net_traits::pub_domains::is_pub_domain;
use net_traits::request::RequestInit;
use net_traits::response::HttpsState;
use num_traits::ToPrimitive;
@ -1988,6 +1989,55 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
}
}
// https://html.spec.whatwg.org/multipage/#is-a-registrable-domain-suffix-of-or-is-equal-to
// The spec says to return a bool, we actually return an Option<Host> containing
// the parsed host in the successful case, to avoid having to re-parse the host.
fn get_registrable_domain_suffix_of_or_is_equal_to(host_suffix_string: &str, original_host: Host) -> Option<Host> {
// Step 1
if host_suffix_string.is_empty() {
return None;
}
// Step 2-3.
let host = match Host::parse(host_suffix_string) {
Ok(host) => host,
Err(_) => return None,
};
// Step 4.
if host != original_host {
// Step 4.1
let host = match host {
Host::Domain(ref host) => host,
_ => return None,
};
let original_host = match original_host {
Host::Domain(ref original_host) => original_host,
_ => return None,
};
// Step 4.2
let (prefix, suffix) = match original_host.len().checked_sub(host.len()) {
Some(index) => original_host.split_at(index),
None => return None,
};
if !prefix.ends_with(".") {
return None;
}
if suffix != host {
return None;
}
// Step 4.3
if is_pub_domain(host) {
return None;
}
}
// Step 5
Some(host)
}
/// https://url.spec.whatwg.org/#network-scheme
fn url_has_network_scheme(url: &ServoUrl) -> bool {
match url.scheme() {
@ -2472,7 +2522,7 @@ impl DocumentMethods for Document {
false
}
// https://html.spec.whatwg.org/multipage/#relaxing-the-same-origin-restriction
// https://html.spec.whatwg.org/multipage/#dom-document-domain
fn Domain(&self) -> DOMString {
// Step 1.
if !self.has_browsing_context {
@ -2489,6 +2539,35 @@ impl DocumentMethods for Document {
}
}
// https://html.spec.whatwg.org/multipage/#dom-document-domain
fn SetDomain(&self, value: DOMString) -> ErrorResult {
// Step 1.
if !self.has_browsing_context {
return Err(Error::Security);
}
// TODO: Step 2. "If this Document object's active sandboxing
// flag set has its sandboxed document.domain browsing context
// flag set, then throw a "SecurityError" DOMException."
// Steps 3-4.
let effective_domain = match self.origin.effective_domain() {
Some(effective_domain) => effective_domain,
None => return Err(Error::Security),
};
// Step 5
let host = match get_registrable_domain_suffix_of_or_is_equal_to(&*value, effective_domain) {
None => return Err(Error::Security),
Some(host) => host,
};
// Step 6
self.origin.set_domain(host);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-document-referrer
fn Referrer(&self) -> DOMString {
match self.referrer {
@ -3396,6 +3475,9 @@ impl DocumentMethods for Document {
let entry_responsible_document = GlobalScope::entry().as_window().Document();
// This check is same-origin not same-origin-domain.
// https://github.com/whatwg/html/issues/2282
// https://github.com/whatwg/html/pull/2288
if !self.origin.same_origin(&entry_responsible_document.origin) {
// Step 4.
return Err(Error::Security);

Просмотреть файл

@ -4,8 +4,9 @@
use dom::bindings::codegen::Bindings::HistoryBinding;
use dom::bindings::codegen::Bindings::HistoryBinding::HistoryMethods;
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
use dom::bindings::codegen::Bindings::LocationBinding::LocationBinding::LocationMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
@ -59,17 +60,17 @@ impl HistoryMethods for History {
}
// https://html.spec.whatwg.org/multipage/#dom-history-go
fn Go(&self, delta: i32) {
fn Go(&self, delta: i32) -> Fallible<()> {
let direction = if delta > 0 {
TraversalDirection::Forward(delta as usize)
} else if delta < 0 {
TraversalDirection::Back(-delta as usize)
} else {
self.window.Location().Reload();
return;
return self.window.Location().Reload();
};
self.traverse_history(direction);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-history-back

Просмотреть файл

@ -327,20 +327,6 @@ impl HTMLIFrameElement {
false
}
}
pub fn get_content_window(&self) -> Option<Root<Window>> {
self.pipeline_id.get()
.and_then(|pipeline_id| ScriptThread::find_document(pipeline_id))
.and_then(|document| {
let current_global = GlobalScope::current();
let current_document = current_global.as_window().Document();
if document.origin().same_origin(current_document.origin()) {
Some(Root::from_ref(document.window()))
} else {
None
}
})
}
}
pub trait HTMLIFrameElementLayoutMethods {
@ -512,15 +498,31 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentwindow
fn GetContentWindow(&self) -> Option<Root<BrowsingContext>> {
match self.get_content_window() {
Some(ref window) => Some(window.browsing_context()),
None => None
}
self.pipeline_id.get().and_then(|_| ScriptThread::find_browsing_context(self.frame_id))
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentdocument
// https://html.spec.whatwg.org/multipage/#concept-bcc-content-document
fn GetContentDocument(&self) -> Option<Root<Document>> {
self.get_content_window().map(|window| window.Document())
// Step 1.
let pipeline_id = match self.pipeline_id.get() {
None => return None,
Some(pipeline_id) => pipeline_id,
};
// Step 2-3.
// Note that this lookup will fail if the document is dissimilar-origin,
// so we should return None in that case.
let document = match ScriptThread::find_document(pipeline_id) {
None => return None,
Some(document) => document,
};
// Step 4.
let current = GlobalScope::current().as_window().Document();
if !current.origin().same_origin_domain(document.origin()) {
return None;
}
// Step 5.
Some(document)
}
// Experimental mozbrowser implementation is based on the webidl

Просмотреть файл

@ -4,10 +4,12 @@
use dom::bindings::codegen::Bindings::LocationBinding;
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
use dom::globalscope::GlobalScope;
use dom::urlhelper::UrlHelper;
use dom::window::Window;
use dom_struct::dom_struct;
@ -43,11 +45,27 @@ impl Location {
setter(&mut url, value);
self.window.load_url(url, false, false, None);
}
fn check_same_origin_domain(&self) -> ErrorResult {
let entry_document = GlobalScope::entry().as_window().Document();
let this_document = self.window.Document();
if entry_document.origin().same_origin_domain(this_document.origin()) {
Ok(())
} else {
Err(Error::Security)
}
}
// https://html.spec.whatwg.org/multipage/#dom-location-reload
pub fn reload_without_origin_check(&self) {
self.window.load_url(self.get_url(), true, true, None);
}
}
impl LocationMethods for Location {
// https://html.spec.whatwg.org/multipage/#dom-location-assign
fn Assign(&self, url: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
// TODO: per spec, we should use the _API base URL_ specified by the
// _entry settings object_.
let base_url = self.window.get_url();
@ -60,12 +78,15 @@ impl LocationMethods for Location {
}
// https://html.spec.whatwg.org/multipage/#dom-location-reload
fn Reload(&self) {
fn Reload(&self) -> ErrorResult {
try!(self.check_same_origin_domain());
self.window.load_url(self.get_url(), true, true, None);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-replace
fn Replace(&self, url: USVString) -> ErrorResult {
// Note: no call to self.check_same_origin_domain()
// TODO: per spec, we should use the _API base URL_ specified by the
// _entry settings object_.
let base_url = self.window.get_url();
@ -78,97 +99,124 @@ impl LocationMethods for Location {
}
// https://html.spec.whatwg.org/multipage/#dom-location-hash
fn Hash(&self) -> USVString {
UrlHelper::Hash(&self.get_url())
fn GetHash(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Hash(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-hash
fn SetHash(&self, mut value: USVString) {
fn SetHash(&self, mut value: USVString) -> ErrorResult {
if value.0.is_empty() {
value = USVString("#".to_owned());
}
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetHash);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-host
fn Host(&self) -> USVString {
UrlHelper::Host(&self.get_url())
fn GetHost(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Host(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-host
fn SetHost(&self, value: USVString) {
fn SetHost(&self, value: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetHost);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-origin
fn Origin(&self) -> USVString {
UrlHelper::Origin(&self.get_url())
fn GetOrigin(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Origin(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-hostname
fn Hostname(&self) -> USVString {
UrlHelper::Hostname(&self.get_url())
fn GetHostname(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Hostname(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-hostname
fn SetHostname(&self, value: USVString) {
fn SetHostname(&self, value: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetHostname);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-href
fn Href(&self) -> USVString {
UrlHelper::Href(&self.get_url())
fn GetHref(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Href(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-href
fn SetHref(&self, value: USVString) {
if let Ok(url) = self.window.get_url().join(&value.0) {
self.window.load_url(url, false, false, None);
}
fn SetHref(&self, value: USVString) -> ErrorResult {
// Note: no call to self.check_same_origin_domain()
let url = match self.window.get_url().join(&value.0) {
Ok(url) => url,
Err(e) => return Err(Error::Type(format!("Couldn't parse URL: {}", e))),
};
self.window.load_url(url, false, false, None);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-pathname
fn Pathname(&self) -> USVString {
UrlHelper::Pathname(&self.get_url())
fn GetPathname(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Pathname(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-pathname
fn SetPathname(&self, value: USVString) {
fn SetPathname(&self, value: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetPathname);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-port
fn Port(&self) -> USVString {
UrlHelper::Port(&self.get_url())
fn GetPort(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Port(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-port
fn SetPort(&self, value: USVString) {
fn SetPort(&self, value: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetPort);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-protocol
fn Protocol(&self) -> USVString {
UrlHelper::Protocol(&self.get_url())
fn GetProtocol(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Protocol(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-protocol
fn SetProtocol(&self, value: USVString) {
fn SetProtocol(&self, value: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetProtocol);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-location-href
fn Stringifier(&self) -> DOMString {
DOMString::from(self.Href().0)
fn Stringifier(&self) -> Fallible<DOMString> {
Ok(DOMString::from(try!(self.GetHref()).0))
}
// https://html.spec.whatwg.org/multipage/#dom-location-search
fn Search(&self) -> USVString {
UrlHelper::Search(&self.get_url())
fn GetSearch(&self) -> Fallible<USVString> {
try!(self.check_same_origin_domain());
Ok(UrlHelper::Search(&self.get_url()))
}
// https://html.spec.whatwg.org/multipage/#dom-location-search
fn SetSearch(&self, value: USVString) {
fn SetSearch(&self, value: USVString) -> ErrorResult {
try!(self.check_same_origin_domain());
self.set_url_component(value, UrlHelper::SetSearch);
Ok(())
}
}

Просмотреть файл

@ -81,7 +81,7 @@ partial /*sealed*/ interface Document {
// resource metadata management
[/*PutForwards=href, */Unforgeable]
readonly attribute Location? location;
readonly attribute DOMString domain;
[SetterThrows] attribute DOMString domain;
readonly attribute DOMString referrer;
[Throws]
attribute DOMString cookie;

Просмотреть файл

@ -10,7 +10,7 @@ interface History {
readonly attribute unsigned long length;
// attribute ScrollRestoration scrollRestoration;
// readonly attribute any state;
void go(optional long delta = 0);
[Throws] void go(optional long delta = 0);
void back();
void forward();
// void pushState(any data, DOMString title, optional USVString? url = null);

Просмотреть файл

@ -4,26 +4,24 @@
// https://html.spec.whatwg.org/multipage/#location
[Exposed=Window, Unforgeable] interface Location {
/*stringifier*/ attribute USVString href;
readonly attribute USVString origin;
attribute USVString protocol;
attribute USVString host;
attribute USVString hostname;
attribute USVString port;
attribute USVString pathname;
attribute USVString search;
attribute USVString hash;
/*stringifier*/ [Throws] attribute USVString href;
[Throws] readonly attribute USVString origin;
[Throws] attribute USVString protocol;
[Throws] attribute USVString host;
[Throws] attribute USVString hostname;
[Throws] attribute USVString port;
[Throws] attribute USVString pathname;
[Throws] attribute USVString search;
[Throws] attribute USVString hash;
[Throws]
void assign(USVString url);
[Throws]
void replace(USVString url);
void reload();
[Throws] void assign(USVString url);
[Throws] void replace(USVString url);
[Throws] void reload();
//[SameObject] readonly attribute USVString[] ancestorOrigins;
// This is only doing as well as gecko right now.
// https://github.com/servo/servo/issues/7590 is on file for
// adding attribute stringifier support.
stringifier;
[Throws] stringifier;
};

Просмотреть файл

@ -42,7 +42,7 @@ use dom::location::Location;
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
use dom::messageevent::MessageEvent;
use dom::navigator::Navigator;
use dom::node::{Node, from_untrusted_node_address, window_from_node, NodeDamage};
use dom::node::{Node, NodeDamage, document_from_node, from_untrusted_node_address, window_from_node};
use dom::performance::Performance;
use dom::promise::Promise;
use dom::screen::Screen;
@ -528,7 +528,24 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#dom-frameelement
fn GetFrameElement(&self) -> Option<Root<Element>> {
self.browsing_context().frame_element().map(Root::from_ref)
// Steps 1-3.
let context = match self.browsing_context.get() {
None => return None,
Some(context) => context,
};
// Step 4-5.
let container = match context.frame_element() {
None => return None,
Some(container) => container,
};
// Step 6.
let container_doc = document_from_node(container);
let current_doc = GlobalScope::current().as_window().Document();
if !current_doc.origin().same_origin_domain(container_doc.origin()) {
return None;
}
// Step 7.
Some(Root::from_ref(container))
}
// https://html.spec.whatwg.org/multipage/#dom-navigator

Просмотреть файл

@ -27,7 +27,6 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
use dom::bindings::codegen::Bindings::EventBinding::EventInit;
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
use dom::bindings::codegen::Bindings::TransitionEventBinding::TransitionEventInit;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
@ -644,6 +643,14 @@ impl ScriptThread {
}))
}
pub fn find_browsing_context(id: FrameId) -> Option<Root<BrowsingContext>> {
SCRIPT_THREAD_ROOT.with(|root| root.get().and_then(|script_thread| {
let script_thread = unsafe { &*script_thread };
script_thread.browsing_contexts.borrow().get(&id)
.map(|context| Root::from_ref(&**context))
}))
}
/// Creates a new script thread.
pub fn new(state: InitialScriptState,
port: Receiver<MainThreadScriptMsg>,
@ -1348,7 +1355,7 @@ impl ScriptThread {
/// Handles activity change message
fn handle_set_document_activity_msg(&self, id: PipelineId, activity: DocumentActivity) {
debug!("Setting activity of {} to be {:?}.", id, activity);
debug!("Setting activity of {} to be {:?} in {:?}.", id, activity, thread::current().name());
let document = self.documents.borrow().find_document(id);
if let Some(document) = document {
document.set_activity(activity);
@ -2101,7 +2108,7 @@ impl ScriptThread {
fn handle_reload(&self, pipeline_id: PipelineId) {
let window = self.documents.borrow().find_window(pipeline_id);
if let Some(window) = window {
window.Location().Reload();
window.Location().reload_without_origin_check();
}
}

Просмотреть файл

@ -113,29 +113,24 @@ pub fn handle_get_frame_id(documents: &Documents,
pipeline: PipelineId,
webdriver_frame_id: WebDriverFrameId,
reply: IpcSender<Result<Option<PipelineId>, ()>>) {
let window = match webdriver_frame_id {
let result = match webdriver_frame_id {
WebDriverFrameId::Short(_) => {
// This isn't supported yet
Ok(None)
},
WebDriverFrameId::Element(x) => {
match find_node_by_unique_id(documents, pipeline, x) {
Some(ref node) => {
match node.downcast::<HTMLIFrameElement>() {
Some(ref elem) => Ok(elem.get_content_window()),
None => Err(())
}
},
None => Err(())
}
find_node_by_unique_id(documents, pipeline, x)
.and_then(|node| node.downcast::<HTMLIFrameElement>().map(|elem| elem.pipeline_id()))
.ok_or(())
},
WebDriverFrameId::Parent => {
documents.find_window(pipeline).map(|window| window.parent()).ok_or(())
documents.find_window(pipeline)
.map(|window| window.parent_info().map(|(parent_id, _)| parent_id))
.ok_or(())
}
};
let frame_id = window.map(|x| x.map(|x| x.upcast::<GlobalScope>().pipeline_id()));
reply.send(frame_id).unwrap()
reply.send(result).unwrap()
}
pub fn handle_find_element_css(documents: &Documents, pipeline: PipelineId, selector: String,

Просмотреть файл

@ -28,6 +28,8 @@ use std::path::Path;
use std::sync::Arc;
use url::{Url, Position};
pub use url::Host;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ServoUrl(Arc<Url>);