aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs132
1 files changed, 86 insertions, 46 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index b4273233c37..211927bbf9c 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -87,6 +87,7 @@ use dom::window::{ReflowReason, Window};
use encoding::EncodingRef;
use encoding::all::UTF_8;
use euclid::point::Point2D;
+use gfx_traits::ScrollRootId;
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
use html5ever_atoms::{LocalName, QualName};
use ipc_channel::ipc::{self, IpcSender};
@@ -136,18 +137,12 @@ pub enum TouchEventResult {
Forwarded,
}
-#[derive(JSTraceable, PartialEq, HeapSizeOf)]
+#[derive(Clone, Copy, Debug, HeapSizeOf, JSTraceable, PartialEq)]
pub enum IsHTMLDocument {
HTMLDocument,
NonHTMLDocument,
}
-#[derive(PartialEq)]
-enum ParserBlockedByScript {
- Blocked,
- Unblocked,
-}
-
#[derive(JSTraceable, HeapSizeOf)]
#[must_root]
pub struct StylesheetInDocument {
@@ -287,6 +282,8 @@ pub struct Document {
/// https://w3c.github.io/uievents/#event-type-dblclick
#[ignore_heap_size_of = "Defined in std"]
last_click_info: DOMRefCell<Option<(Instant, Point2D<f32>)>>,
+ /// https://html.spec.whatwg.org/multipage/#ignore-destructive-writes-counter
+ ignore_destructive_writes_counter: Cell<u32>,
}
#[derive(JSTraceable, HeapSizeOf)]
@@ -378,15 +375,16 @@ impl Document {
self.trigger_mozbrowser_event(MozBrowserEvent::SecurityChange(https_state));
}
+ // https://html.spec.whatwg.org/multipage/#active-document
+ pub fn is_active(&self) -> bool {
+ self.browsing_context().map_or(false, |context| {
+ self == &*context.active_document()
+ })
+ }
+
// https://html.spec.whatwg.org/multipage/#fully-active
pub fn is_fully_active(&self) -> bool {
- let browsing_context = match self.browsing_context() {
- Some(browsing_context) => browsing_context,
- None => return false,
- };
- let active_document = browsing_context.active_document();
-
- if self != &*active_document {
+ if !self.is_active() {
return false;
}
// FIXME: It should also check whether the browser context is top-level or not
@@ -434,7 +432,6 @@ impl Document {
// that workable.
match self.GetDocumentElement() {
Some(root) => {
- root.upcast::<Node>().is_dirty() ||
root.upcast::<Node>().has_dirty_descendants() ||
!self.pending_restyles.borrow().is_empty() ||
self.needs_paint()
@@ -623,7 +620,10 @@ impl Document {
if let Some((x, y)) = point {
// Step 3
- self.window.perform_a_scroll(x, y, ScrollBehavior::Instant,
+ self.window.perform_a_scroll(x,
+ y,
+ ScrollRootId::root(),
+ ScrollBehavior::Instant,
target.r());
}
}
@@ -1546,15 +1546,13 @@ impl Document {
self.process_asap_scripts();
}
- if self.maybe_execute_parser_blocking_script() == ParserBlockedByScript::Blocked {
- return;
- }
-
- // A finished resource load can potentially unblock parsing. In that case, resume the
- // parser so its loop can find out.
if let Some(parser) = self.get_current_parser() {
- if parser.is_suspended() {
- parser.resume();
+ if let Some(script) = self.pending_parsing_blocking_script.get() {
+ if self.script_blocking_stylesheets_count.get() > 0 || !script.is_ready_to_be_executed() {
+ return;
+ }
+ self.pending_parsing_blocking_script.set(None);
+ parser.resume_with_pending_parsing_blocking_script(&script);
}
} else if self.reflow_timeout.get().is_none() {
// If we don't have a parser, and the reflow timer has been reset, explicitly
@@ -1577,23 +1575,6 @@ impl Document {
}
}
- /// If document parsing is blocked on a script, and that script is ready to run,
- /// execute it.
- /// https://html.spec.whatwg.org/multipage/#ready-to-be-parser-executed
- fn maybe_execute_parser_blocking_script(&self) -> ParserBlockedByScript {
- let script = match self.pending_parsing_blocking_script.get() {
- None => return ParserBlockedByScript::Unblocked,
- Some(script) => script,
- };
-
- if self.script_blocking_stylesheets_count.get() == 0 && script.is_ready_to_be_executed() {
- self.pending_parsing_blocking_script.set(None);
- script.execute();
- return ParserBlockedByScript::Unblocked;
- }
- ParserBlockedByScript::Blocked
- }
-
/// https://html.spec.whatwg.org/multipage/#the-end step 3
pub fn process_deferred_scripts(&self) {
if self.ready_state.get() != DocumentReadyState::Interactive {
@@ -1902,15 +1883,15 @@ impl Document {
referrer_policy: Cell::new(referrer_policy),
target_element: MutNullableHeap::new(None),
last_click_info: DOMRefCell::new(None),
+ ignore_destructive_writes_counter: Default::default(),
}
}
// https://dom.spec.whatwg.org/#dom-document
- pub fn Constructor(global: &GlobalScope) -> Fallible<Root<Document>> {
- let win = global.as_window();
- let doc = win.Document();
+ pub fn Constructor(window: &Window) -> Fallible<Root<Document>> {
+ let doc = window.Document();
let docloader = DocumentLoader::new(&*doc.loader());
- Ok(Document::new(win,
+ Ok(Document::new(window,
None,
None,
IsHTMLDocument::NonHTMLDocument,
@@ -2078,6 +2059,16 @@ impl Document {
ReflowQueryType::NoQuery,
ReflowReason::ElementStateChanged);
}
+
+ pub fn incr_ignore_destructive_writes_counter(&self) {
+ self.ignore_destructive_writes_counter.set(
+ self.ignore_destructive_writes_counter.get() + 1);
+ }
+
+ pub fn decr_ignore_destructive_writes_counter(&self) {
+ self.ignore_destructive_writes_counter.set(
+ self.ignore_destructive_writes_counter.get() - 1);
+ }
}
@@ -2438,7 +2429,7 @@ impl DocumentMethods for Document {
)
)),
"webglcontextevent" =>
- Ok(Root::upcast(WebGLContextEvent::new_uninitialized(self.window.upcast()))),
+ Ok(Root::upcast(WebGLContextEvent::new_uninitialized(&self.window))),
"storageevent" => {
let USVString(url) = self.URL();
Ok(Root::upcast(StorageEvent::new_uninitialized(&self.window, DOMString::from(url))))
@@ -3044,6 +3035,55 @@ impl DocumentMethods for Document {
elements
}
+ // https://html.spec.whatwg.org/multipage/#dom-document-write
+ fn Write(&self, text: Vec<DOMString>) -> ErrorResult {
+ if !self.is_html_document() {
+ // Step 1.
+ return Err(Error::InvalidState);
+ }
+
+ // Step 2.
+ // TODO: handle throw-on-dynamic-markup-insertion counter.
+
+ if !self.is_active() {
+ // Step 3.
+ return Ok(());
+ }
+
+ let parser = self.get_current_parser();
+ let parser = match parser.as_ref() {
+ Some(parser) if parser.script_nesting_level() > 0 => parser,
+ _ => {
+ // Either there is no parser, which means the parsing ended;
+ // or script nesting level is 0, which means the method was
+ // called from outside a parser-executed script.
+ if self.ignore_destructive_writes_counter.get() > 0 {
+ // Step 4.
+ // TODO: handle ignore-opens-during-unload counter.
+ return Ok(());
+ }
+ // Step 5.
+ // TODO: call document.open().
+ return Err(Error::InvalidState);
+ }
+ };
+
+ // Step 7.
+ // TODO: handle reload override buffer.
+
+ // Steps 6-8.
+ parser.write(text);
+
+ // Step 9.
+ Ok(())
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-document-writeln
+ fn Writeln(&self, mut text: Vec<DOMString>) -> ErrorResult {
+ text.push("\n".into());
+ self.Write(text)
+ }
+
// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
document_and_element_event_handlers!();
}