Backed out changeset e64e659c077d: servo PR #18809 and revendor for reftest failures, e.g. in layout/reftests/bugs/392435-1.html. r=backout on a CLOSED TREE

Backs out https://github.com/servo/servo/pull/18809
This commit is contained in:
Gecko Backout 2017-10-19 21:26:51 +00:00 committed by moz-servo-sync
parent fe16c1d5c3
commit 11c64178d8
142 changed files with 1635 additions and 1685 deletions

22
Cargo.lock generated
View file

@ -210,7 +210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "bluetooth" name = "bluetooth"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1", "bluetooth_traits 0.0.1",
"device 0.0.1 (git+https://github.com/servo/devices)", "device 0.0.1 (git+https://github.com/servo/devices)",
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -717,7 +717,7 @@ dependencies = [
name = "devtools_traits" name = "devtools_traits"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1091,7 +1091,7 @@ name = "gfx"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1190,7 +1190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "glutin_app" name = "glutin_app"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1", "compositing 0.0.1",
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1520,7 +1520,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1929,7 +1929,7 @@ dependencies = [
name = "msg" name = "msg"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1", "malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1", "malloc_size_of_derive 0.0.1",
"nonzero 0.0.1", "nonzero 0.0.1",
@ -2083,7 +2083,7 @@ dependencies = [
name = "nsstring_vendor" name = "nsstring_vendor"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -2603,7 +2603,7 @@ dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"audio-video-metadata 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "audio-video-metadata 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1", "bluetooth_traits 0.0.1",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
@ -2758,7 +2758,7 @@ dependencies = [
name = "selectors" name = "selectors"
version = "0.19.0" version = "0.19.0"
dependencies = [ dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3157,7 +3157,7 @@ dependencies = [
"arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "bindgen 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3240,7 +3240,7 @@ name = "style_traits"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1", "malloc_size_of 0.0.1",

View file

@ -10,7 +10,7 @@ name = "bluetooth"
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "0.7"
bluetooth_traits = {path = "../bluetooth_traits"} bluetooth_traits = {path = "../bluetooth_traits"}
device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]} device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
ipc-channel = "0.9" ipc-channel = "0.9"

View file

@ -47,16 +47,16 @@ const DIALOG_COLUMN_ID: &'static str = "Id";
const DIALOG_COLUMN_NAME: &'static str = "Name"; const DIALOG_COLUMN_NAME: &'static str = "Name";
bitflags! { bitflags! {
struct Flags: u32 { flags Flags: u32 {
const BROADCAST = 0b000000001; const BROADCAST = 0b000000001,
const READ = 0b000000010; const READ = 0b000000010,
const WRITE_WITHOUT_RESPONSE = 0b000000100; const WRITE_WITHOUT_RESPONSE = 0b000000100,
const WRITE = 0b000001000; const WRITE = 0b000001000,
const NOTIFY = 0b000010000; const NOTIFY = 0b000010000,
const INDICATE = 0b000100000; const INDICATE = 0b000100000,
const AUTHENTICATED_SIGNED_WRITES = 0b001000000; const AUTHENTICATED_SIGNED_WRITES = 0b001000000,
const RELIABLE_WRITE = 0b010000000; const RELIABLE_WRITE = 0b010000000,
const WRITABLE_AUXILIARIES = 0b100000000; const WRITABLE_AUXILIARIES = 0b100000000,
} }
} }
@ -522,15 +522,15 @@ impl BluetoothManager {
let flags = characteristic.get_flags().unwrap_or(vec!()); let flags = characteristic.get_flags().unwrap_or(vec!());
for flag in flags { for flag in flags {
match flag.as_ref() { match flag.as_ref() {
"broadcast" => props.insert(Flags::BROADCAST), "broadcast" => props.insert(BROADCAST),
"read" => props.insert(Flags::READ), "read" => props.insert(READ),
"write-without-response" => props.insert(Flags::WRITE_WITHOUT_RESPONSE), "write-without-response" => props.insert(WRITE_WITHOUT_RESPONSE),
"write" => props.insert(Flags::WRITE), "write" => props.insert(WRITE),
"notify" => props.insert(Flags::NOTIFY), "notify" => props.insert(NOTIFY),
"indicate" => props.insert(Flags::INDICATE), "indicate" => props.insert(INDICATE),
"authenticated-signed-writes" => props.insert(Flags::AUTHENTICATED_SIGNED_WRITES), "authenticated-signed-writes" => props.insert(AUTHENTICATED_SIGNED_WRITES),
"reliable-write" => props.insert(Flags::RELIABLE_WRITE), "reliable-write" => props.insert(RELIABLE_WRITE),
"writable-auxiliaries" => props.insert(Flags::WRITABLE_AUXILIARIES), "writable-auxiliaries" => props.insert(WRITABLE_AUXILIARIES),
_ => (), _ => (),
} }
} }
@ -747,15 +747,15 @@ impl BluetoothManager {
BluetoothCharacteristicMsg { BluetoothCharacteristicMsg {
uuid: uuid, uuid: uuid,
instance_id: characteristic.get_id(), instance_id: characteristic.get_id(),
broadcast: properties.contains(Flags::BROADCAST), broadcast: properties.contains(BROADCAST),
read: properties.contains(Flags::READ), read: properties.contains(READ),
write_without_response: properties.contains(Flags::WRITE_WITHOUT_RESPONSE), write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE),
write: properties.contains(Flags::WRITE), write: properties.contains(WRITE),
notify: properties.contains(Flags::NOTIFY), notify: properties.contains(NOTIFY),
indicate: properties.contains(Flags::INDICATE), indicate: properties.contains(INDICATE),
authenticated_signed_writes: properties.contains(Flags::AUTHENTICATED_SIGNED_WRITES), authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(Flags::RELIABLE_WRITE), reliable_write: properties.contains(RELIABLE_WRITE),
writable_auxiliaries: properties.contains(Flags::WRITABLE_AUXILIARIES), writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES),
} }
); );
} }

View file

@ -9,7 +9,7 @@
use actor::{Actor, ActorMessageStatus, ActorRegistry}; use actor::{Actor, ActorMessageStatus, ActorRegistry};
use actors::object::ObjectActor; use actors::object::ObjectActor;
use devtools_traits::{CachedConsoleMessageTypes, DevtoolScriptControlMsg}; use devtools_traits::{CONSOLE_API, CachedConsoleMessageTypes, DevtoolScriptControlMsg, PAGE_ERROR};
use devtools_traits::CachedConsoleMessage; use devtools_traits::CachedConsoleMessage;
use devtools_traits::EvaluateJSReply::{ActorValue, BooleanValue, StringValue}; use devtools_traits::EvaluateJSReply::{ActorValue, BooleanValue, StringValue};
use devtools_traits::EvaluateJSReply::{NullValue, NumberValue, VoidValue}; use devtools_traits::EvaluateJSReply::{NullValue, NumberValue, VoidValue};
@ -107,8 +107,8 @@ impl Actor for ConsoleActor {
let mut message_types = CachedConsoleMessageTypes::empty(); let mut message_types = CachedConsoleMessageTypes::empty();
for str_type in str_types { for str_type in str_types {
match str_type { match str_type {
"PageError" => message_types.insert(CachedConsoleMessageTypes::PAGE_ERROR), "PageError" => message_types.insert(PAGE_ERROR),
"ConsoleAPI" => message_types.insert(CachedConsoleMessageTypes::CONSOLE_API), "ConsoleAPI" => message_types.insert(CONSOLE_API),
s => debug!("unrecognized message type requested: \"{}\"", s), s => debug!("unrecognized message type requested: \"{}\"", s),
}; };
}; };

View file

@ -10,7 +10,7 @@ name = "devtools_traits"
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "0.7"
hyper = "0.10" hyper = "0.10"
hyper_serde = "0.7" hyper_serde = "0.7"
ipc-channel = "0.9" ipc-channel = "0.9"

View file

@ -243,9 +243,9 @@ pub struct ConsoleMessage {
bitflags! { bitflags! {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct CachedConsoleMessageTypes: u8 { pub flags CachedConsoleMessageTypes: u8 {
const PAGE_ERROR = 1 << 0; const PAGE_ERROR = 1 << 0,
const CONSOLE_API = 1 << 1; const CONSOLE_API = 1 << 1,
} }
} }

View file

@ -15,7 +15,7 @@ unstable = ["simd"]
[dependencies] [dependencies]
app_units = "0.5" app_units = "0.5"
bitflags = "1.0" bitflags = "0.7"
euclid = "0.15" euclid = "0.15"
fnv = "1.0" fnv = "1.0"
fontsan = {git = "https://github.com/servo/fontsan"} fontsan = {git = "https://github.com/servo/fontsan"}

View file

@ -139,17 +139,17 @@ impl Font {
} }
bitflags! { bitflags! {
pub struct ShapingFlags: u8 { pub flags ShapingFlags: u8 {
#[doc = "Set if the text is entirely whitespace."] #[doc = "Set if the text is entirely whitespace."]
const IS_WHITESPACE_SHAPING_FLAG = 0x01; const IS_WHITESPACE_SHAPING_FLAG = 0x01,
#[doc = "Set if we are to ignore ligatures."] #[doc = "Set if we are to ignore ligatures."]
const IGNORE_LIGATURES_SHAPING_FLAG = 0x02; const IGNORE_LIGATURES_SHAPING_FLAG = 0x02,
#[doc = "Set if we are to disable kerning."] #[doc = "Set if we are to disable kerning."]
const DISABLE_KERNING_SHAPING_FLAG = 0x04; const DISABLE_KERNING_SHAPING_FLAG = 0x04,
#[doc = "Text direction is right-to-left."] #[doc = "Text direction is right-to-left."]
const RTL_FLAG = 0x08; const RTL_FLAG = 0x08,
#[doc = "Set if word-break is set to keep-all."] #[doc = "Set if word-break is set to keep-all."]
const KEEP_ALL_FLAG = 0x10; const KEEP_ALL_FLAG = 0x10,
} }
} }
@ -186,8 +186,8 @@ impl Font {
let result = self.shape_cache.borrow_mut().entry(lookup_key).or_insert_with(|| { let result = self.shape_cache.borrow_mut().entry(lookup_key).or_insert_with(|| {
let start_time = time::precise_time_ns(); let start_time = time::precise_time_ns();
let mut glyphs = GlyphStore::new(text.len(), let mut glyphs = GlyphStore::new(text.len(),
options.flags.contains(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG), options.flags.contains(IS_WHITESPACE_SHAPING_FLAG),
options.flags.contains(ShapingFlags::RTL_FLAG)); options.flags.contains(RTL_FLAG));
if self.can_do_fast_shaping(text, options) { if self.can_do_fast_shaping(text, options) {
debug!("shape_text: Using ASCII fast path."); debug!("shape_text: Using ASCII fast path.");
@ -211,7 +211,7 @@ impl Font {
fn can_do_fast_shaping(&self, text: &str, options: &ShapingOptions) -> bool { fn can_do_fast_shaping(&self, text: &str, options: &ShapingOptions) -> bool {
options.script == Script::Latin && options.script == Script::Latin &&
!options.flags.contains(ShapingFlags::RTL_FLAG) && !options.flags.contains(RTL_FLAG) &&
self.handle.can_do_fast_shaping() && self.handle.can_do_fast_shaping() &&
text.is_ascii() text.is_ascii()
} }

View file

@ -6,7 +6,8 @@
use app_units::Au; use app_units::Au;
use euclid::Point2D; use euclid::Point2D;
use font::{ShapingFlags, Font, FontTableMethods, FontTableTag, ShapingOptions, KERN}; use font::{DISABLE_KERNING_SHAPING_FLAG, Font, FontTableMethods, FontTableTag};
use font::{IGNORE_LIGATURES_SHAPING_FLAG, KERN, RTL_FLAG, ShapingOptions};
use harfbuzz::{HB_DIRECTION_LTR, HB_DIRECTION_RTL, HB_MEMORY_MODE_READONLY}; use harfbuzz::{HB_DIRECTION_LTR, HB_DIRECTION_RTL, HB_MEMORY_MODE_READONLY};
use harfbuzz::{hb_blob_create, hb_face_create_for_tables}; use harfbuzz::{hb_blob_create, hb_face_create_for_tables};
use harfbuzz::{hb_buffer_create, hb_font_destroy}; use harfbuzz::{hb_buffer_create, hb_font_destroy};
@ -188,7 +189,7 @@ impl ShaperMethods for Shaper {
fn shape_text(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) { fn shape_text(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) {
unsafe { unsafe {
let hb_buffer: *mut hb_buffer_t = hb_buffer_create(); let hb_buffer: *mut hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, if options.flags.contains(ShapingFlags::RTL_FLAG) { hb_buffer_set_direction(hb_buffer, if options.flags.contains(RTL_FLAG) {
HB_DIRECTION_RTL HB_DIRECTION_RTL
} else { } else {
HB_DIRECTION_LTR HB_DIRECTION_LTR
@ -203,7 +204,7 @@ impl ShaperMethods for Shaper {
text.len() as c_int); text.len() as c_int);
let mut features = Vec::new(); let mut features = Vec::new();
if options.flags.contains(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG) { if options.flags.contains(IGNORE_LIGATURES_SHAPING_FLAG) {
features.push(hb_feature_t { features.push(hb_feature_t {
tag: LIGA, tag: LIGA,
value: 0, value: 0,
@ -211,7 +212,7 @@ impl ShaperMethods for Shaper {
end: hb_buffer_get_length(hb_buffer), end: hb_buffer_get_length(hb_buffer),
}) })
} }
if options.flags.contains(ShapingFlags::DISABLE_KERNING_SHAPING_FLAG) { if options.flags.contains(DISABLE_KERNING_SHAPING_FLAG) {
features.push(hb_feature_t { features.push(hb_feature_t {
tag: KERN, tag: KERN,
value: 0, value: 0,

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au; use app_units::Au;
use font::{Font, FontHandleMethods, FontMetrics, ShapingFlags}; use font::{Font, FontHandleMethods, FontMetrics, IS_WHITESPACE_SHAPING_FLAG, KEEP_ALL_FLAG};
use font::{RunMetrics, ShapingOptions}; use font::{RunMetrics, ShapingOptions};
use platform::font_template::FontTemplateData; use platform::font_template::FontTemplateData;
use range::Range; use range::Range;
@ -210,7 +210,7 @@ impl<'a> TextRun {
.take_while(|&(_, c)| char_is_whitespace(c)).last() { .take_while(|&(_, c)| char_is_whitespace(c)).last() {
whitespace.start = slice.start + i; whitespace.start = slice.start + i;
slice.end = whitespace.start; slice.end = whitespace.start;
} else if idx != text.len() && options.flags.contains(ShapingFlags::KEEP_ALL_FLAG) { } else if idx != text.len() && options.flags.contains(KEEP_ALL_FLAG) {
// If there's no whitespace and word-break is set to // If there's no whitespace and word-break is set to
// keep-all, try increasing the slice. // keep-all, try increasing the slice.
continue; continue;
@ -224,7 +224,7 @@ impl<'a> TextRun {
} }
if whitespace.len() > 0 { if whitespace.len() > 0 {
let mut options = options.clone(); let mut options = options.clone();
options.flags.insert(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG); options.flags.insert(IS_WHITESPACE_SHAPING_FLAG);
glyphs.push(GlyphRun { glyphs.push(GlyphRun {
glyph_store: font.shape_text(&text[whitespace.clone()], &options), glyph_store: font.shape_text(&text[whitespace.clone()], &options),
range: Range::new(ByteIndex(whitespace.start as isize), range: Range::new(ByteIndex(whitespace.start as isize),

View file

@ -12,7 +12,7 @@ path = "lib.rs"
[dependencies] [dependencies]
app_units = "0.5" app_units = "0.5"
atomic_refcell = "0.1" atomic_refcell = "0.1"
bitflags = "1.0" bitflags = "0.8"
canvas_traits = {path = "../canvas_traits"} canvas_traits = {path = "../canvas_traits"}
euclid = "0.15" euclid = "0.15"
fnv = "1.0" fnv = "1.0"

View file

@ -35,9 +35,13 @@ use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag}; use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags}; use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, INLINE_POSITION_IS_STATIC};
use flow::{IS_ABSOLUTELY_POSITIONED, FragmentationContext, MARGINS_CANNOT_COLLAPSE};
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow};
use flow_list::FlowList; use flow_list::FlowList;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM};
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use incremental::RelayoutMode; use incremental::RelayoutMode;
use layout_debug; use layout_debug;
@ -53,7 +57,7 @@ use style::computed_values::{position, text_align};
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage}; use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage};
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use traversal::PreorderFlowTraversal; use traversal::PreorderFlowTraversal;
@ -451,11 +455,11 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> {
// This flow might not be an absolutely positioned flow if it is the root of the tree. // This flow might not be an absolutely positioned flow if it is the root of the tree.
let block = flow.as_mut_block(); let block = flow.as_mut_block();
if !block.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if !block.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
return; return;
} }
if !block.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { if !block.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
return return
} }
@ -509,11 +513,11 @@ pub struct BlockFlow {
} }
bitflags! { bitflags! {
struct BlockFlowFlags: u8 { flags BlockFlowFlags: u8 {
#[doc = "If this is set, then this block flow is the root flow."] #[doc = "If this is set, then this block flow is the root flow."]
const IS_ROOT = 0b0000_0001; const IS_ROOT = 0b0000_0001,
#[doc = "If this is set, then this block flow has overflow and it will scroll."] #[doc = "If this is set, then this block flow has overflow and it will scroll."]
const HAS_SCROLLING_OVERFLOW = 0b0000_0010; const HAS_SCROLLING_OVERFLOW = 0b0000_0010,
} }
} }
@ -547,7 +551,7 @@ impl BlockFlow {
/// This determines the algorithm used to calculate inline-size, block-size, and the /// This determines the algorithm used to calculate inline-size, block-size, and the
/// relevant margins for this Block. /// relevant margins for this Block.
pub fn block_type(&self) -> BlockType { pub fn block_type(&self) -> BlockType {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.fragment.is_replaced() { if self.fragment.is_replaced() {
BlockType::AbsoluteReplaced BlockType::AbsoluteReplaced
} else { } else {
@ -660,7 +664,7 @@ impl BlockFlow {
#[inline] #[inline]
pub fn containing_block_size(&self, viewport_size: &Size2D<Au>, descendant: OpaqueFlow) pub fn containing_block_size(&self, viewport_size: &Size2D<Au>, descendant: OpaqueFlow)
-> LogicalSize<Au> { -> LogicalSize<Au> {
debug_assert!(self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)); debug_assert!(self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
if self.is_fixed() || self.is_root() { if self.is_fixed() || self.is_root() {
// Initial containing block is the CB for the root // Initial containing block is the CB for the root
LogicalSize::from_physical(self.base.writing_mode, *viewport_size) LogicalSize::from_physical(self.base.writing_mode, *viewport_size)
@ -779,13 +783,13 @@ impl BlockFlow {
let mut break_at = None; let mut break_at = None;
let content_box = self.fragment.content_box(); let content_box = self.fragment.content_box();
if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { if self.base.restyle_damage.contains(REFLOW) {
// Our current border-box position. // Our current border-box position.
let mut cur_b = Au(0); let mut cur_b = Au(0);
// Absolute positioning establishes a block formatting context. Don't propagate floats // Absolute positioning establishes a block formatting context. Don't propagate floats
// in or out. (But do propagate them between kids.) // in or out. (But do propagate them between kids.)
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse { margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse {
self.base.floats = Floats::new(self.fragment.style.writing_mode); self.base.floats = Floats::new(self.fragment.style.writing_mode);
} }
@ -801,7 +805,7 @@ impl BlockFlow {
let can_collapse_block_start_margin_with_kids = let can_collapse_block_start_margin_with_kids =
margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse && margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
!self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.border_padding.block_start == Au(0); self.fragment.border_padding.block_start == Au(0);
margin_collapse_info.initialize_block_start_margin( margin_collapse_info.initialize_block_start_margin(
&self.fragment, &self.fragment,
@ -812,10 +816,10 @@ impl BlockFlow {
let thread_id = self.base.thread_id; let thread_id = self.base.thread_id;
let (mut had_floated_children, mut had_children_with_clearance) = (false, false); let (mut had_floated_children, mut had_children_with_clearance) = (false, false);
for (child_index, kid) in self.base.child_iter_mut().enumerate() { for (child_index, kid) in self.base.child_iter_mut().enumerate() {
if flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
// Assume that the *hypothetical box* for an absolute flow starts immediately // Assume that the *hypothetical box* for an absolute flow starts immediately
// after the margin-end border edge of the previous flow. // after the margin-end border edge of the previous flow.
if flow::base(kid).flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { if flow::base(kid).flags.contains(BLOCK_POSITION_IS_STATIC) {
let previous_bottom_margin = margin_collapse_info.current_float_ceiling(); let previous_bottom_margin = margin_collapse_info.current_float_ceiling();
flow::mut_base(kid).position.start.b = cur_b + flow::mut_base(kid).position.start.b = cur_b +
@ -883,8 +887,8 @@ impl BlockFlow {
if !had_children_with_clearance && if !had_children_with_clearance &&
floats.is_present() && floats.is_present() &&
(flow::base(kid).flags.contains(FlowFlags::CLEARS_LEFT) || (flow::base(kid).flags.contains(CLEARS_LEFT) ||
flow::base(kid).flags.contains(FlowFlags::CLEARS_RIGHT)) { flow::base(kid).flags.contains(CLEARS_RIGHT)) {
had_children_with_clearance = true had_children_with_clearance = true
} }
@ -901,8 +905,8 @@ impl BlockFlow {
} }
// Clear past the floats that came in, if necessary. // Clear past the floats that came in, if necessary.
let clearance = match (flow::base(kid).flags.contains(FlowFlags::CLEARS_LEFT), let clearance = match (flow::base(kid).flags.contains(CLEARS_LEFT),
flow::base(kid).flags.contains(FlowFlags::CLEARS_RIGHT)) { flow::base(kid).flags.contains(CLEARS_RIGHT)) {
(false, false) => Au(0), (false, false) => Au(0),
(true, false) => floats.clearance(ClearType::Left), (true, false) => floats.clearance(ClearType::Left),
(false, true) => floats.clearance(ClearType::Right), (false, true) => floats.clearance(ClearType::Right),
@ -963,7 +967,7 @@ impl BlockFlow {
// Add in our block-end margin and compute our collapsible margins. // Add in our block-end margin and compute our collapsible margins.
let can_collapse_block_end_margin_with_kids = let can_collapse_block_end_margin_with_kids =
margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse && margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
!self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.border_padding.block_end == Au(0); self.fragment.border_padding.block_end == Au(0);
let (collapsible_margins, delta) = let (collapsible_margins, delta) =
margin_collapse_info.finish_and_compute_collapsible_margins( margin_collapse_info.finish_and_compute_collapsible_margins(
@ -978,13 +982,13 @@ impl BlockFlow {
let is_root = self.is_root(); let is_root = self.is_root();
if is_root || self.formatting_context_type() != FormattingContextType::None || if is_root || self.formatting_context_type() != FormattingContextType::None ||
self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
// The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest // The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest
// way to handle this is to just treat it as clearance. // way to handle this is to just treat it as clearance.
block_size = block_size + floats.clearance(ClearType::Both); block_size = block_size + floats.clearance(ClearType::Both);
} }
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
// FIXME(#2003, pcwalton): The max is taken here so that you can scroll the page, // FIXME(#2003, pcwalton): The max is taken here so that you can scroll the page,
// but this is not correct behavior according to CSS 2.1 § 10.5. Instead I think we // but this is not correct behavior according to CSS 2.1 § 10.5. Instead I think we
// should treat the root element as having `overflow: scroll` and use the layers- // should treat the root element as having `overflow: scroll` and use the layers-
@ -1004,7 +1008,7 @@ impl BlockFlow {
} }
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.propagate_early_absolute_position_info_to_children(); self.propagate_early_absolute_position_info_to_children();
return None return None
} }
@ -1072,9 +1076,9 @@ impl BlockFlow {
// size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.) // size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
if (self.base.flags.is_float() || if (self.base.flags.is_float() ||
self.formatting_context_type() == FormattingContextType::None) && self.formatting_context_type() == FormattingContextType::None) &&
!self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
} }
break_at.and_then(|(i, child_remaining)| { break_at.and_then(|(i, child_remaining)| {
@ -1158,7 +1162,7 @@ impl BlockFlow {
let viewport_size = LogicalSize::from_physical(self.fragment.style.writing_mode, let viewport_size = LogicalSize::from_physical(self.fragment.style.writing_mode,
shared_context.viewport_size()); shared_context.viewport_size());
Some(viewport_size.block) Some(viewport_size.block)
} else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && } else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.base.block_container_explicit_block_size.is_none() { self.base.block_container_explicit_block_size.is_none() {
self.base.absolute_cb.explicit_block_containing_size(shared_context) self.base.absolute_cb.explicit_block_containing_size(shared_context)
} else { } else {
@ -1296,7 +1300,7 @@ impl BlockFlow {
self.fragment.margin.block_end = solution.margin_block_end; self.fragment.margin.block_end = solution.margin_block_end;
self.fragment.border_box.start.b = Au(0); self.fragment.border_box.start.b = Au(0);
if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { if !self.base.flags.contains(BLOCK_POSITION_IS_STATIC) {
self.base.position.start.b = solution.block_start + self.fragment.margin.block_start self.base.position.start.b = solution.block_start + self.fragment.margin.block_start
} }
@ -1304,8 +1308,8 @@ impl BlockFlow {
self.fragment.border_box.size.block = block_size; self.fragment.border_box.size.block = block_size;
self.base.position.size.block = block_size; self.base.position.size.block = block_size;
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
} }
/// Compute inline size based using the `block_container_inline_size` set by the parent flow. /// Compute inline size based using the `block_container_inline_size` set by the parent flow.
@ -1354,7 +1358,7 @@ impl BlockFlow {
.map(|x| if x < box_border { Au(0) } else { x - box_border }); .map(|x| if x < box_border { Au(0) } else { x - box_border });
if self.is_root() { explicit_content_size = max(parent_container_size, explicit_content_size); } if self.is_root() { explicit_content_size = max(parent_container_size, explicit_content_size); }
// Calculate containing block inline size. // Calculate containing block inline size.
let containing_block_size = if flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { let containing_block_size = if flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.containing_block_size(&shared_context.viewport_size(), opaque_self).inline self.containing_block_size(&shared_context.viewport_size(), opaque_self).inline
} else { } else {
content_inline_size content_inline_size
@ -1382,12 +1386,12 @@ impl BlockFlow {
// float child does not have `REFLOW` set, we must be careful to avoid touching its // float child does not have `REFLOW` set, we must be careful to avoid touching its
// inline position, as no logic will run afterward to set its true value. // inline position, as no logic will run afterward to set its true value.
let kid_base = flow::mut_base(kid); let kid_base = flow::mut_base(kid);
let reflow_damage = if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { let reflow_damage = if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
ServoRestyleDamage::REFLOW_OUT_OF_FLOW REFLOW_OUT_OF_FLOW
} else { } else {
ServoRestyleDamage::REFLOW REFLOW
}; };
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) && if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) &&
kid_base.restyle_damage.contains(reflow_damage) { kid_base.restyle_damage.contains(reflow_damage) {
kid_base.position.start.i = kid_base.position.start.i =
if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() { if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() {
@ -1471,13 +1475,13 @@ impl BlockFlow {
content_box: LogicalRect<Au>) { content_box: LogicalRect<Au>) {
debug_assert!(self.formatting_context_type() != FormattingContextType::None); debug_assert!(self.formatting_context_type() != FormattingContextType::None);
if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { if !self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
return return
} }
// We do this first to avoid recomputing our inline size when we propagate it. // We do this first to avoid recomputing our inline size when we propagate it.
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
// The code below would completely wreck the layout if run on a flex item, however: // The code below would completely wreck the layout if run on a flex item, however:
// * Flex items are always the children of flex containers. // * Flex items are always the children of flex containers.
@ -1587,14 +1591,14 @@ impl BlockFlow {
// This is kind of a hack for Acid2. But it's a harmless one, because (a) this behavior // This is kind of a hack for Acid2. But it's a harmless one, because (a) this behavior
// is unspecified; (b) it matches the behavior one would intuitively expect, since // is unspecified; (b) it matches the behavior one would intuitively expect, since
// floats don't flow around blocks that take up no space in the block direction. // floats don't flow around blocks that take up no space in the block direction.
flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); flags.remove(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
} else if self.fragment.is_text_or_replaced() { } else if self.fragment.is_text_or_replaced() {
flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); flags.insert(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
} else { } else {
flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); flags.remove(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
for kid in self.base.children.iter() { for kid in self.base.children.iter() {
if flow::base(kid).flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) { if flow::base(kid).flags.contains(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) {
flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); flags.insert(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
break break
} }
} }
@ -1611,7 +1615,7 @@ impl BlockFlow {
let (mut left_float_width_accumulator, mut right_float_width_accumulator) = (Au(0), Au(0)); let (mut left_float_width_accumulator, mut right_float_width_accumulator) = (Au(0), Au(0));
let mut preferred_inline_size_of_children_without_text_or_replaced_fragments = Au(0); let mut preferred_inline_size_of_children_without_text_or_replaced_fragments = Au(0);
for kid in self.base.child_iter_mut() { for kid in self.base.child_iter_mut() {
if flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || !consult_children { if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) || !consult_children {
continue continue
} }
@ -1621,16 +1625,16 @@ impl BlockFlow {
max(computation.content_intrinsic_sizes.minimum_inline_size, max(computation.content_intrinsic_sizes.minimum_inline_size,
child_base.intrinsic_inline_sizes.minimum_inline_size); child_base.intrinsic_inline_sizes.minimum_inline_size);
if child_base.flags.contains(FlowFlags::CLEARS_LEFT) { if child_base.flags.contains(CLEARS_LEFT) {
left_float_width = max(left_float_width, left_float_width_accumulator); left_float_width = max(left_float_width, left_float_width_accumulator);
left_float_width_accumulator = Au(0) left_float_width_accumulator = Au(0)
} }
if child_base.flags.contains(FlowFlags::CLEARS_RIGHT) { if child_base.flags.contains(CLEARS_RIGHT) {
right_float_width = max(right_float_width, right_float_width_accumulator); right_float_width = max(right_float_width, right_float_width_accumulator);
right_float_width_accumulator = Au(0) right_float_width_accumulator = Au(0)
} }
match (float_kind, child_base.flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS)) { match (float_kind, child_base.flags.contains(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS)) {
(float::T::none, true) => { (float::T::none, true) => {
computation.content_intrinsic_sizes.preferred_inline_size = computation.content_intrinsic_sizes.preferred_inline_size =
max(computation.content_intrinsic_sizes.preferred_inline_size, max(computation.content_intrinsic_sizes.preferred_inline_size,
@ -1677,7 +1681,7 @@ impl BlockFlow {
} }
pub fn compute_inline_sizes(&mut self, shared_context: &SharedStyleContext) { pub fn compute_inline_sizes(&mut self, shared_context: &SharedStyleContext) {
if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { if !self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
return return
} }
@ -1758,23 +1762,23 @@ impl BlockFlow {
} }
pub fn is_inline_flex_item(&self) -> bool { pub fn is_inline_flex_item(&self) -> bool {
self.fragment.flags.contains(FragmentFlags::IS_INLINE_FLEX_ITEM) self.fragment.flags.contains(IS_INLINE_FLEX_ITEM)
} }
pub fn is_block_flex_item(&self) -> bool { pub fn is_block_flex_item(&self) -> bool {
self.fragment.flags.contains(FragmentFlags::IS_BLOCK_FLEX_ITEM) self.fragment.flags.contains(IS_BLOCK_FLEX_ITEM)
} }
pub fn mark_scrolling_overflow(&mut self, has_scrolling_overflow: bool) { pub fn mark_scrolling_overflow(&mut self, has_scrolling_overflow: bool) {
if has_scrolling_overflow { if has_scrolling_overflow {
self.flags.insert(BlockFlowFlags::HAS_SCROLLING_OVERFLOW); self.flags.insert(HAS_SCROLLING_OVERFLOW);
} else { } else {
self.flags.remove(BlockFlowFlags::HAS_SCROLLING_OVERFLOW); self.flags.remove(HAS_SCROLLING_OVERFLOW);
} }
} }
pub fn has_scrolling_overflow(&mut self) -> bool { pub fn has_scrolling_overflow(&mut self) -> bool {
self.flags.contains(BlockFlowFlags::HAS_SCROLLING_OVERFLOW) self.flags.contains(HAS_SCROLLING_OVERFLOW)
} }
// Return offset from original position because of `position: sticky`. // Return offset from original position because of `position: sticky`.
@ -1820,7 +1824,7 @@ impl Flow for BlockFlow {
_ => true, _ => true,
}; };
self.bubble_inline_sizes_for_block(consult_children); self.bubble_inline_sizes_for_block(consult_children);
self.fragment.restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES); self.fragment.restyle_damage.remove(BUBBLE_ISIZES);
} }
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments. /// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
@ -1870,14 +1874,13 @@ impl Flow for BlockFlow {
} }
let is_formatting_context = self.formatting_context_type() != FormattingContextType::None; let is_formatting_context = self.formatting_context_type() != FormattingContextType::None;
if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && is_formatting_context { if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && is_formatting_context {
self.assign_inline_position_for_formatting_context(layout_context, content_box); self.assign_inline_position_for_formatting_context(layout_context, content_box);
} }
if (self as &Flow).floats_might_flow_through() { if (self as &Flow).floats_might_flow_through() {
self.base.thread_id = parent_thread_id; self.base.thread_id = parent_thread_id;
if self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
ServoRestyleDamage::REFLOW) {
self.assign_block_size(layout_context); self.assign_block_size(layout_context);
// Don't remove the restyle damage; `assign_block_size` decides whether that is // Don't remove the restyle damage; `assign_block_size` decides whether that is
// appropriate (which in the case of e.g. absolutely-positioned flows, it is not). // appropriate (which in the case of e.g. absolutely-positioned flows, it is not).
@ -1911,7 +1914,7 @@ impl Flow for BlockFlow {
// Assign block-size for fragment if it is an image fragment. // Assign block-size for fragment if it is an image fragment.
self.fragment.assign_replaced_block_size_if_necessary(); self.fragment.assign_replaced_block_size_if_necessary();
if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.position.size.block = self.fragment.border_box.size.block; self.base.position.size.block = self.fragment.border_box.size.block;
let mut block_start = AdjoiningMargins::from_margin(self.fragment.margin.block_start); let mut block_start = AdjoiningMargins::from_margin(self.fragment.margin.block_start);
let block_end = AdjoiningMargins::from_margin(self.fragment.margin.block_end); let block_end = AdjoiningMargins::from_margin(self.fragment.margin.block_end);
@ -1921,14 +1924,13 @@ impl Flow for BlockFlow {
} else { } else {
self.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end); self.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end);
} }
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
ServoRestyleDamage::REFLOW);
} }
None None
} else if self.is_root() || } else if self.is_root() ||
self.formatting_context_type() != FormattingContextType::None || self.formatting_context_type() != FormattingContextType::None ||
self.base.flags.contains(FlowFlags::MARGINS_CANNOT_COLLAPSE) { self.base.flags.contains(MARGINS_CANNOT_COLLAPSE) {
// Root element margins should never be collapsed according to CSS § 8.3.1. // Root element margins should never be collapsed according to CSS § 8.3.1.
debug!("assign_block_size: assigning block_size for root flow {:?}", debug!("assign_block_size: assigning block_size for root flow {:?}",
flow::base(self).debug_id()); flow::base(self).debug_id());
@ -1955,7 +1957,7 @@ impl Flow for BlockFlow {
self.base.clip = max_rect(); self.base.clip = max_rect();
} }
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
let position_start = self.base.position.start.to_physical(self.base.writing_mode, let position_start = self.base.position.start.to_physical(self.base.writing_mode,
container_size); container_size);
@ -1973,17 +1975,17 @@ impl Flow for BlockFlow {
}; };
if !self.base.writing_mode.is_vertical() { if !self.base.writing_mode.is_vertical() {
if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if !self.base.flags.contains(INLINE_POSITION_IS_STATIC) {
self.base.stacking_relative_position.x = absolute_stacking_relative_position.x self.base.stacking_relative_position.x = absolute_stacking_relative_position.x
} }
if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { if !self.base.flags.contains(BLOCK_POSITION_IS_STATIC) {
self.base.stacking_relative_position.y = absolute_stacking_relative_position.y self.base.stacking_relative_position.y = absolute_stacking_relative_position.y
} }
} else { } else {
if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if !self.base.flags.contains(INLINE_POSITION_IS_STATIC) {
self.base.stacking_relative_position.y = absolute_stacking_relative_position.y self.base.stacking_relative_position.y = absolute_stacking_relative_position.y
} }
if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { if !self.base.flags.contains(BLOCK_POSITION_IS_STATIC) {
self.base.stacking_relative_position.x = absolute_stacking_relative_position.x self.base.stacking_relative_position.x = absolute_stacking_relative_position.x
} }
} }
@ -2056,28 +2058,28 @@ impl Flow for BlockFlow {
// Process children. // Process children.
for kid in self.base.child_iter_mut() { for kid in self.base.child_iter_mut() {
if flow::base(kid).flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) || if flow::base(kid).flags.contains(INLINE_POSITION_IS_STATIC) ||
flow::base(kid).flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { flow::base(kid).flags.contains(BLOCK_POSITION_IS_STATIC) {
let kid_base = flow::mut_base(kid); let kid_base = flow::mut_base(kid);
let physical_position = kid_base.position.to_physical(kid_base.writing_mode, let physical_position = kid_base.position.to_physical(kid_base.writing_mode,
container_size_for_children); container_size_for_children);
// Set the inline and block positions as necessary. // Set the inline and block positions as necessary.
if !kid_base.writing_mode.is_vertical() { if !kid_base.writing_mode.is_vertical() {
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.x = origin_for_children.x + kid_base.stacking_relative_position.x = origin_for_children.x +
physical_position.origin.x physical_position.origin.x
} }
if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { if kid_base.flags.contains(BLOCK_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.y = origin_for_children.y + kid_base.stacking_relative_position.y = origin_for_children.y +
physical_position.origin.y physical_position.origin.y
} }
} else { } else {
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.y = origin_for_children.y + kid_base.stacking_relative_position.y = origin_for_children.y +
physical_position.origin.y physical_position.origin.y
} }
if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { if kid_base.flags.contains(BLOCK_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.x = origin_for_children.x + kid_base.stacking_relative_position.x = origin_for_children.x +
physical_position.origin.x physical_position.origin.x
} }
@ -2090,11 +2092,11 @@ impl Flow for BlockFlow {
} }
fn mark_as_root(&mut self) { fn mark_as_root(&mut self) {
self.flags.insert(BlockFlowFlags::IS_ROOT) self.flags.insert(IS_ROOT)
} }
fn is_root(&self) -> bool { fn is_root(&self) -> bool {
self.flags.contains(BlockFlowFlags::IS_ROOT) self.flags.contains(IS_ROOT)
} }
/// The 'position' property of this flow. /// The 'position' property of this flow.
@ -2120,7 +2122,7 @@ impl Flow for BlockFlow {
} }
fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.style().logical_position().inline_start == self.fragment.style().logical_position().inline_start ==
LengthOrPercentageOrAuto::Auto && LengthOrPercentageOrAuto::Auto &&
self.fragment.style().logical_position().inline_end == self.fragment.style().logical_position().inline_end ==
@ -2130,7 +2132,7 @@ impl Flow for BlockFlow {
} }
fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) { fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.style().logical_position().block_start == self.fragment.style().logical_position().block_start ==
LengthOrPercentageOrAuto::Auto && LengthOrPercentageOrAuto::Auto &&
self.fragment.style().logical_position().block_end == self.fragment.style().logical_position().block_end ==
@ -2746,7 +2748,7 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
block: &mut BlockFlow, block: &mut BlockFlow,
solution: ISizeConstraintSolution) { solution: ISizeConstraintSolution) {
// Set the inline position of the absolute flow wrt to its containing block. // Set the inline position of the absolute flow wrt to its containing block.
if !block.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if !block.base.flags.contains(INLINE_POSITION_IS_STATIC) {
block.base.position.start.i = solution.inline_start; block.base.position.start.i = solution.inline_start;
} }
} }

View file

@ -16,19 +16,22 @@
use ServoArc; use ServoArc;
use block::BlockFlow; use block::BlockFlow;
use context::{LayoutContext, with_thread_local_font_context}; use context::{LayoutContext, with_thread_local_font_context};
use data::{LayoutDataFlags, LayoutData}; use data::{HAS_NEWLY_CONSTRUCTED_FLOW, LayoutData};
use flex::FlexFlow; use flex::FlexFlow;
use floats::FloatKind; use floats::FloatKind;
use flow::{self, AbsoluteDescendants, Flow, FlowClass, ImmutableFlowUtils}; use flow::{self, AbsoluteDescendants, Flow, FlowClass, ImmutableFlowUtils};
use flow::{FlowFlags, MutableFlowUtils, MutableOwnedFlowUtils}; use flow::{CAN_BE_FRAGMENTED, IS_ABSOLUTELY_POSITIONED, MARGINS_CANNOT_COLLAPSE};
use flow::{MutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::FlowRef; use flow_ref::FlowRef;
use fragment::{CanvasFragmentInfo, ImageFragmentInfo, InlineAbsoluteFragmentInfo, SvgFragmentInfo}; use fragment::{CanvasFragmentInfo, ImageFragmentInfo, InlineAbsoluteFragmentInfo, SvgFragmentInfo};
use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo, FragmentFlags}; use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo};
use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM};
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo}; use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use fragment::WhitespaceStrippingResult; use fragment::WhitespaceStrippingResult;
use gfx::display_list::OpaqueNode; use gfx::display_list::OpaqueNode;
use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow};
use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT};
use linked_list::prepend_from; use linked_list::prepend_from;
use list_item::{ListItemFlow, ListStyleTypeContent}; use list_item::{ListItemFlow, ListStyleTypeContent};
use multicol::{MulticolColumnFlow, MulticolFlow}; use multicol::{MulticolColumnFlow, MulticolFlow};
@ -51,7 +54,7 @@ use style::logical_geometry::Direction;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::properties::longhands::list_style_image; use style::properties::longhands::list_style_image;
use style::selector_parser::{PseudoElement, RestyleDamage}; use style::selector_parser::{PseudoElement, RestyleDamage};
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW};
use style::values::Either; use style::values::Either;
use table::TableFlow; use table::TableFlow;
use table_caption::TableCaptionFlow; use table_caption::TableCaptionFlow;
@ -170,7 +173,7 @@ impl InlineBlockSplit {
-> InlineBlockSplit { -> InlineBlockSplit {
fragment_accumulator.enclosing_node.as_mut().expect( fragment_accumulator.enclosing_node.as_mut().expect(
"enclosing_node is None; Are {ib} splits being generated outside of an inline node?" "enclosing_node is None; Are {ib} splits being generated outside of an inline node?"
).flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT); ).flags.remove(LAST_FRAGMENT_OF_ELEMENT);
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessors: mem::replace( predecessors: mem::replace(
@ -180,8 +183,7 @@ impl InlineBlockSplit {
flow: flow, flow: flow,
}; };
fragment_accumulator.enclosing_node.as_mut().unwrap().flags.remove( fragment_accumulator.enclosing_node.as_mut().unwrap().flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT);
split split
} }
@ -256,8 +258,7 @@ impl InlineFragmentsAccumulator {
pseudo: node.get_pseudo_element_type().strip(), pseudo: node.get_pseudo_element_type().strip(),
style: node.style(style_context), style: node.style(style_context),
selected_style: node.selected_style(), selected_style: node.selected_style(),
flags: InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT | flags: FIRST_FRAGMENT_OF_ELEMENT | LAST_FRAGMENT_OF_ELEMENT,
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT,
}), }),
bidi_control_chars: None, bidi_control_chars: None,
restyle_damage: node.restyle_damage(), restyle_damage: node.restyle_damage(),
@ -286,18 +287,17 @@ impl InlineFragmentsAccumulator {
for (index, fragment) in fragments.fragments.iter_mut().enumerate() { for (index, fragment) in fragments.fragments.iter_mut().enumerate() {
let mut enclosing_node = enclosing_node.clone(); let mut enclosing_node = enclosing_node.clone();
if index != 0 { if index != 0 {
enclosing_node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) enclosing_node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT)
} }
if index != fragment_count - 1 { if index != fragment_count - 1 {
enclosing_node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) enclosing_node.flags.remove(LAST_FRAGMENT_OF_ELEMENT)
} }
fragment.add_inline_context_style(enclosing_node); fragment.add_inline_context_style(enclosing_node);
} }
// Control characters are later discarded in transform_text, so they don't affect the // Control characters are later discarded in transform_text, so they don't affect the
// is_first/is_last styles above. // is_first/is_last styles above.
enclosing_node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT | enclosing_node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT | LAST_FRAGMENT_OF_ELEMENT);
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
if let Some((start, end)) = bidi_control_chars { if let Some((start, end)) = bidi_control_chars {
fragments.fragments.push_front( fragments.fragments.push_front(
@ -493,7 +493,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
ConstructionResult::Flow(kid_flow, AbsoluteDescendants::new()); ConstructionResult::Flow(kid_flow, AbsoluteDescendants::new());
self.set_flow_construction_result(&kid, construction_result) self.set_flow_construction_result(&kid, construction_result)
} else { } else {
if !flow::base(&*kid_flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if !flow::base(&*kid_flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
// Flush any inline fragments that we were gathering up. This allows us to // Flush any inline fragments that we were gathering up. This allows us to
// handle {ib} splits. // handle {ib} splits.
let old_inline_fragment_accumulator = let old_inline_fragment_accumulator =
@ -621,7 +621,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
flow.set_absolute_descendants(abs_descendants); flow.set_absolute_descendants(abs_descendants);
abs_descendants = AbsoluteDescendants::new(); abs_descendants = AbsoluteDescendants::new();
if flow::base(&*flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
// This is now the only absolute flow in the subtree which hasn't yet // This is now the only absolute flow in the subtree which hasn't yet
// reached its CB. // reached its CB.
abs_descendants.push(flow.clone()); abs_descendants.push(flow.clone());
@ -776,7 +776,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
match kid.get_construction_result() { match kid.get_construction_result() {
ConstructionResult::None => {} ConstructionResult::None => {}
ConstructionResult::Flow(flow, kid_abs_descendants) => { ConstructionResult::Flow(flow, kid_abs_descendants) => {
if !flow::base(&*flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if !flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
opt_inline_block_splits.push_back(InlineBlockSplit::new( opt_inline_block_splits.push_back(InlineBlockSplit::new(
&mut fragment_accumulator, node, self.style_context(), flow)); &mut fragment_accumulator, node, self.style_context(), flow));
abs_descendants.push_descendants(kid_abs_descendants); abs_descendants.push_descendants(kid_abs_descendants);
@ -1066,7 +1066,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
abs_descendants = AbsoluteDescendants::new(); abs_descendants = AbsoluteDescendants::new();
if flow::base(&*flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
// This is now the only absolute flow in the subtree which hasn't yet // This is now the only absolute flow in the subtree which hasn't yet
// reached its containing block. // reached its containing block.
abs_descendants.push(flow.clone()); abs_descendants.push(flow.clone());
@ -1137,7 +1137,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
abs_descendants = AbsoluteDescendants::new(); abs_descendants = AbsoluteDescendants::new();
if flow::base(&*wrapper_flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
// This is now the only absolute flow in the subtree which hasn't yet // This is now the only absolute flow in the subtree which hasn't yet
// reached its containing block. // reached its containing block.
abs_descendants.push(wrapper_flow.clone()); abs_descendants.push(wrapper_flow.clone());
@ -1332,8 +1332,8 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
} }
for kid in node.children() { for kid in node.children() {
if kid.flags().contains(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW) { if kid.flags().contains(HAS_NEWLY_CONSTRUCTED_FLOW) {
kid.remove_flags(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW); kid.remove_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
need_to_reconstruct = true need_to_reconstruct = true
} }
} }
@ -1342,7 +1342,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
return false return false
} }
if node.restyle_damage().contains(ServoRestyleDamage::RECONSTRUCT_FLOW) { if node.restyle_damage().contains(RECONSTRUCT_FLOW) {
return false return false
} }
@ -1436,7 +1436,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
} }
}; };
if set_has_newly_constructed_flow_flag { if set_has_newly_constructed_flow_flag {
node.insert_flags(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW); node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
} }
return result; return result;
} }
@ -1452,7 +1452,7 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal<ConcreteThreadS
// TODO: This should actually consult the table in that section to get the // TODO: This should actually consult the table in that section to get the
// final computed value for 'display'. // final computed value for 'display'.
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode) { fn process(&mut self, node: &ConcreteThreadSafeLayoutNode) {
node.insert_flags(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW); node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
// Bail out if this node has an ancestor with display: none. // Bail out if this node has an ancestor with display: none.
if node.style(self.style_context()).is_in_display_none_subtree() { if node.style(self.style_context()).is_in_display_none_subtree() {
@ -1654,7 +1654,7 @@ impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode
fn set_flow_construction_result(self, mut result: ConstructionResult) { fn set_flow_construction_result(self, mut result: ConstructionResult) {
if self.can_be_fragmented() { if self.can_be_fragmented() {
if let ConstructionResult::Flow(ref mut flow, _) = result { if let ConstructionResult::Flow(ref mut flow, _) = result {
flow::mut_base(FlowRef::deref_mut(flow)).flags.insert(FlowFlags::CAN_BE_FRAGMENTED); flow::mut_base(FlowRef::deref_mut(flow)).flags.insert(CAN_BE_FRAGMENTED);
} }
} }
@ -1744,7 +1744,7 @@ impl FlowConstructionUtils for FlowRef {
fn finish(&mut self) { fn finish(&mut self) {
if !opts::get().bubble_inline_sizes_separately { if !opts::get().bubble_inline_sizes_separately {
FlowRef::deref_mut(self).bubble_inline_sizes(); FlowRef::deref_mut(self).bubble_inline_sizes();
flow::mut_base(FlowRef::deref_mut(self)).restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES); flow::mut_base(FlowRef::deref_mut(self)).restyle_damage.remove(BUBBLE_ISIZES);
} }
} }
} }
@ -1945,7 +1945,7 @@ impl Legalizer {
} }
(FlowClass::Flex, FlowClass::Inline) => { (FlowClass::Flex, FlowClass::Inline) => {
flow::mut_base(FlowRef::deref_mut(child)).flags.insert(FlowFlags::MARGINS_CANNOT_COLLAPSE); flow::mut_base(FlowRef::deref_mut(child)).flags.insert(MARGINS_CANNOT_COLLAPSE);
let mut block_wrapper = let mut block_wrapper =
Legalizer::create_anonymous_flow(context, Legalizer::create_anonymous_flow(context,
parent, parent,
@ -1954,12 +1954,12 @@ impl Legalizer {
BlockFlow::from_fragment); BlockFlow::from_fragment);
{ {
let flag = if parent.as_flex().main_mode() == Direction::Inline { let flag = if parent.as_flex().main_mode() == Direction::Inline {
FragmentFlags::IS_INLINE_FLEX_ITEM IS_INLINE_FLEX_ITEM
} else { } else {
FragmentFlags::IS_BLOCK_FLEX_ITEM IS_BLOCK_FLEX_ITEM
}; };
let block = FlowRef::deref_mut(&mut block_wrapper).as_mut_block(); let block = FlowRef::deref_mut(&mut block_wrapper).as_mut_block();
block.base.flags.insert(FlowFlags::MARGINS_CANNOT_COLLAPSE); block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
block.fragment.flags.insert(flag); block.fragment.flags.insert(flag);
} }
block_wrapper.add_new_child((*child).clone()); block_wrapper.add_new_child((*child).clone());
@ -1971,12 +1971,12 @@ impl Legalizer {
(FlowClass::Flex, _) => { (FlowClass::Flex, _) => {
{ {
let flag = if parent.as_flex().main_mode() == Direction::Inline { let flag = if parent.as_flex().main_mode() == Direction::Inline {
FragmentFlags::IS_INLINE_FLEX_ITEM IS_INLINE_FLEX_ITEM
} else { } else {
FragmentFlags::IS_BLOCK_FLEX_ITEM IS_BLOCK_FLEX_ITEM
}; };
let block = FlowRef::deref_mut(child).as_mut_block(); let block = FlowRef::deref_mut(child).as_mut_block();
block.base.flags.insert(FlowFlags::MARGINS_CANNOT_COLLAPSE); block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
block.fragment.flags.insert(flag); block.fragment.flags.insert(flag);
} }
parent.add_new_child((*child).clone()); parent.add_new_child((*child).clone());

View file

@ -60,10 +60,10 @@ impl LayoutData {
} }
bitflags! { bitflags! {
pub struct LayoutDataFlags: u8 { pub flags LayoutDataFlags: u8 {
#[doc = "Whether a flow has been newly constructed."] #[doc = "Whether a flow has been newly constructed."]
const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01; const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01,
#[doc = "Whether this node has been traversed by layout."] #[doc = "Whether this node has been traversed by layout."]
const HAS_BEEN_TRAVERSED = 0x02; const HAS_BEEN_TRAVERSED = 0x02,
} }
} }

View file

@ -17,7 +17,7 @@ use context::LayoutContext;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedSize2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedSize2D};
use euclid::Vector2D; use euclid::Vector2D;
use flex::FlexFlow; use flex::FlexFlow;
use flow::{BaseFlow, Flow, FlowFlags}; use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
use flow_ref::FlowRef; use flow_ref::FlowRef;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo}; use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
@ -32,7 +32,7 @@ use gfx::display_list::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem}
use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, StackingContext}; use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, StackingContext};
use gfx::display_list::{StackingContextType, TextDisplayItem, TextOrientation, WebRenderImageInfo}; use gfx::display_list::{StackingContextType, TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId}; use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
use inline::{InlineFragmentNodeFlags, InlineFlow}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc; use ipc_channel::ipc;
use list_item::ListItemFlow; use list_item::ListItemFlow;
use model::{self, MaybeAuto}; use model::{self, MaybeAuto};
@ -54,7 +54,7 @@ use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalS
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::properties::longhands::border_image_repeat::computed_value::RepeatKeyword; use style::properties::longhands::border_image_repeat::computed_value::RepeatKeyword;
use style::properties::style_structs; use style::properties::style_structs;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::REPAINT;
use style::values::{Either, RGBA}; use style::values::{Either, RGBA};
use style::values::computed::{Angle, Gradient, GradientItem, LengthOrPercentage, Percentage}; use style::values::computed::{Angle, Gradient, GradientItem, LengthOrPercentage, Percentage};
use style::values::computed::{LengthOrPercentageOrAuto, NumberOrPercentage, Position}; use style::values::computed::{LengthOrPercentageOrAuto, NumberOrPercentage, Position};
@ -105,8 +105,7 @@ fn convert_repeat_mode(from: RepeatKeyword) -> RepeatMode {
fn establishes_containing_block_for_absolute(flags: StackingContextCollectionFlags, fn establishes_containing_block_for_absolute(flags: StackingContextCollectionFlags,
positioning: position::T) positioning: position::T)
-> bool { -> bool {
!flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) && !flags.contains(NEVER_CREATES_CONTAINING_BLOCK) && position::T::static_ != positioning
position::T::static_ != positioning
} }
trait RgbColor { trait RgbColor {
@ -1869,7 +1868,7 @@ impl FragmentDisplayListBuilding for Fragment {
border_painting_mode: BorderPaintingMode, border_painting_mode: BorderPaintingMode,
display_list_section: DisplayListSection, display_list_section: DisplayListSection,
clip: &Rect<Au>) { clip: &Rect<Au>) {
self.restyle_damage.remove(ServoRestyleDamage::REPAINT); self.restyle_damage.remove(REPAINT);
if self.style().get_inheritedbox().visibility != visibility::T::visible { if self.style().get_inheritedbox().visibility != visibility::T::visible {
return return
} }
@ -1915,10 +1914,8 @@ impl FragmentDisplayListBuilding for Fragment {
state, state,
&*node.style, &*node.style,
Some(InlineNodeBorderInfo { Some(InlineNodeBorderInfo {
is_first_fragment_of_element: is_first_fragment_of_element: node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT),
node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT), is_last_fragment_of_element: node.flags.contains(LAST_FRAGMENT_OF_ELEMENT),
is_last_fragment_of_element:
node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT),
}), }),
border_painting_mode, border_painting_mode,
&stacking_relative_border_box, &stacking_relative_border_box,
@ -2396,13 +2393,13 @@ impl FragmentDisplayListBuilding for Fragment {
} }
bitflags! { bitflags! {
pub struct StackingContextCollectionFlags: u8 { pub flags StackingContextCollectionFlags: u8 {
/// This flow never establishes a containing block. /// This flow never establishes a containing block.
const NEVER_CREATES_CONTAINING_BLOCK = 0b001; const NEVER_CREATES_CONTAINING_BLOCK = 0b001,
/// This flow never creates a ClipScrollNode. /// This flow never creates a ClipScrollNode.
const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010; const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010,
/// This flow never creates a stacking context. /// This flow never creates a stacking context.
const NEVER_CREATES_STACKING_CONTEXT = 0b100; const NEVER_CREATES_STACKING_CONTEXT = 0b100,
} }
} }
@ -2660,7 +2657,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.transform_clip_to_coordinate_space(state, preserved_state); self.transform_clip_to_coordinate_space(state, preserved_state);
} }
if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE) { if !flags.contains(NEVER_CREATES_CLIP_SCROLL_NODE) {
self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box); self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box); self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_css_clip(state, preserved_state, self.setup_clip_scroll_node_for_css_clip(state, preserved_state,
@ -2670,7 +2667,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
// We keep track of our position so that any stickily positioned elements can // We keep track of our position so that any stickily positioned elements can
// properly determine the extent of their movement relative to scrolling containers. // properly determine the extent of their movement relative to scrolling containers.
if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) { if !flags.contains(NEVER_CREATES_CONTAINING_BLOCK) {
let border_box = if self.fragment.establishes_stacking_context() { let border_box = if self.fragment.establishes_stacking_context() {
stacking_relative_border_box stacking_relative_border_box
} else { } else {
@ -2887,7 +2884,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
parent_stacking_context_id: StackingContextId, parent_stacking_context_id: StackingContextId,
parent_clip_and_scroll_info: ClipAndScrollInfo, parent_clip_and_scroll_info: ClipAndScrollInfo,
state: &mut StackingContextCollectionState) { state: &mut StackingContextCollectionState) {
let creation_mode = if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
self.fragment.style.get_box().position != position::T::static_ { self.fragment.style.get_box().position != position::T::static_ {
StackingContextType::PseudoPositioned StackingContextType::PseudoPositioned
} else { } else {
@ -2943,7 +2940,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
border_painting_mode: BorderPaintingMode) { border_painting_mode: BorderPaintingMode) {
let background_border_section = if self.base.flags.is_float() { let background_border_section = if self.base.flags.is_float() {
DisplayListSection::BackgroundAndBorders DisplayListSection::BackgroundAndBorders
} else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { } else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.fragment.establishes_stacking_context() { if self.fragment.establishes_stacking_context() {
DisplayListSection::BackgroundAndBorders DisplayListSection::BackgroundAndBorders
} else { } else {
@ -2979,7 +2976,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&self, &self,
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
) -> BlockStackingContextType { ) -> BlockStackingContextType {
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) { if flags.contains(NEVER_CREATES_STACKING_CONTEXT) {
return BlockStackingContextType::NonstackingContext; return BlockStackingContextType::NonstackingContext;
} }
@ -2987,7 +2984,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
return BlockStackingContextType::StackingContext return BlockStackingContextType::StackingContext
} }
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
return BlockStackingContextType::PseudoStackingContext return BlockStackingContextType::PseudoStackingContext
} }

View file

@ -14,7 +14,8 @@ use display_list_builder::StackingContextCollectionState;
use euclid::Point2D; use euclid::Point2D;
use floats::FloatKind; use floats::FloatKind;
use flow; use flow;
use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow, FlowFlags}; use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use layout_debug; use layout_debug;
use model::{AdjoiningMargins, CollapsibleMargins}; use model::{AdjoiningMargins, CollapsibleMargins};
@ -24,7 +25,7 @@ use std::ops::Range;
use style::computed_values::{align_content, align_self, flex_direction, flex_wrap, justify_content}; use style::computed_values::{align_content, align_self, flex_direction, flex_wrap, justify_content};
use style::logical_geometry::{Direction, LogicalSize}; use style::logical_geometry::{Direction, LogicalSize};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use style::values::computed::flex::FlexBasis; use style::values::computed::flex::FlexBasis;
use style::values::generics::flex::FlexBasis as GenericFlexBasis; use style::values::generics::flex::FlexBasis as GenericFlexBasis;
@ -448,7 +449,7 @@ impl FlexFlow {
if !fixed_width { if !fixed_width {
for kid in self.block_flow.base.children.iter_mut() { for kid in self.block_flow.base.children.iter_mut() {
let base = flow::mut_base(kid); let base = flow::mut_base(kid);
let is_absolutely_positioned = base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); let is_absolutely_positioned = base.flags.contains(IS_ABSOLUTELY_POSITIONED);
if !is_absolutely_positioned { if !is_absolutely_positioned {
let flex_item_inline_sizes = IntrinsicISizes { let flex_item_inline_sizes = IntrinsicISizes {
minimum_inline_size: base.intrinsic_inline_sizes.minimum_inline_size, minimum_inline_size: base.intrinsic_inline_sizes.minimum_inline_size,
@ -474,7 +475,7 @@ impl FlexFlow {
if !fixed_width { if !fixed_width {
for kid in self.block_flow.base.children.iter_mut() { for kid in self.block_flow.base.children.iter_mut() {
let base = flow::mut_base(kid); let base = flow::mut_base(kid);
let is_absolutely_positioned = base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); let is_absolutely_positioned = base.flags.contains(IS_ABSOLUTELY_POSITIONED);
if !is_absolutely_positioned { if !is_absolutely_positioned {
computation.content_intrinsic_sizes.minimum_inline_size = computation.content_intrinsic_sizes.minimum_inline_size =
max(computation.content_intrinsic_sizes.minimum_inline_size, max(computation.content_intrinsic_sizes.minimum_inline_size,
@ -517,7 +518,7 @@ impl FlexFlow {
for kid in &mut self.items { for kid in &mut self.items {
let kid_base = flow::mut_base(children.get(kid.index)); let kid_base = flow::mut_base(children.get(kid.index));
kid_base.block_container_explicit_block_size = container_block_size; kid_base.block_container_explicit_block_size = container_block_size;
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
// The inline-start margin edge of the child flow is at our inline-start content // The inline-start margin edge of the child flow is at our inline-start content
// edge, and its inline-size is our content inline-size. // edge, and its inline-size is our content inline-size.
kid_base.position.start.i = kid_base.position.start.i =
@ -854,7 +855,7 @@ impl Flow for FlexFlow {
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, flow)| { .filter(|&(_, flow)| {
!flow.as_block().base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) !flow.as_block().base.flags.contains(IS_ABSOLUTELY_POSITIONED)
}) })
.map(|(index, flow)| FlexItem::new(index, flow)) .map(|(index, flow)| FlexItem::new(index, flow))
.collect(); .collect();
@ -872,8 +873,7 @@ impl Flow for FlexFlow {
let _scope = layout_debug_scope!("flex::assign_inline_sizes {:x}", self.block_flow.base.debug_id()); let _scope = layout_debug_scope!("flex::assign_inline_sizes {:x}", self.block_flow.base.debug_id());
debug!("assign_inline_sizes"); debug!("assign_inline_sizes");
if !self.block_flow.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | if !self.block_flow.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
ServoRestyleDamage::REFLOW) {
return return
} }

View file

@ -4,7 +4,7 @@
use app_units::{Au, MAX_AU}; use app_units::{Au, MAX_AU};
use block::FormattingContextType; use block::FormattingContextType;
use flow::{self, Flow, FlowFlags, ImmutableFlowUtils}; use flow::{self, CLEARS_LEFT, CLEARS_RIGHT, Flow, ImmutableFlowUtils};
use persistent_list::PersistentList; use persistent_list::PersistentList;
use std::cmp::{max, min}; use std::cmp::{max, min};
use std::fmt; use std::fmt;
@ -459,10 +459,10 @@ impl SpeculatedFloatPlacement {
/// flow, computes the speculated inline size of the floats flowing in. /// flow, computes the speculated inline size of the floats flowing in.
pub fn compute_floats_in(&mut self, flow: &mut Flow) { pub fn compute_floats_in(&mut self, flow: &mut Flow) {
let base_flow = flow::base(flow); let base_flow = flow::base(flow);
if base_flow.flags.contains(FlowFlags::CLEARS_LEFT) { if base_flow.flags.contains(CLEARS_LEFT) {
self.left = Au(0) self.left = Au(0)
} }
if base_flow.flags.contains(FlowFlags::CLEARS_RIGHT) { if base_flow.flags.contains(CLEARS_RIGHT) {
self.right = Au(0) self.right = Au(0)
} }
} }

View file

@ -54,7 +54,7 @@ use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage; use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT};
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use table::TableFlow; use table::TableFlow;
use table_caption::TableCaptionFlow; use table_caption::TableCaptionFlow;
@ -253,7 +253,7 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static {
if might_have_floats_in_or_out { if might_have_floats_in_or_out {
mut_base(self).thread_id = parent_thread_id; mut_base(self).thread_id = parent_thread_id;
self.assign_block_size(layout_context); self.assign_block_size(layout_context);
mut_base(self).restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
} }
might_have_floats_in_or_out might_have_floats_in_or_out
} }
@ -403,7 +403,7 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static {
fn contains_positioned_fragments(&self) -> bool { fn contains_positioned_fragments(&self) -> bool {
self.contains_relatively_positioned_fragments() || self.contains_relatively_positioned_fragments() ||
base(self).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) base(self).flags.contains(IS_ABSOLUTELY_POSITIONED)
} }
fn contains_relatively_positioned_fragments(&self) -> bool { fn contains_relatively_positioned_fragments(&self) -> bool {
@ -595,52 +595,52 @@ impl FlowClass {
bitflags! { bitflags! {
#[doc = "Flags used in flows."] #[doc = "Flags used in flows."]
pub struct FlowFlags: u32 { pub flags FlowFlags: u32 {
// text align flags // text align flags
#[doc = "Whether this flow is absolutely positioned. This is checked all over layout, so a"] #[doc = "Whether this flow is absolutely positioned. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."] #[doc = "virtual call is too expensive."]
const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0000_0100_0000; const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0000_0100_0000,
#[doc = "Whether this flow clears to the left. This is checked all over layout, so a"] #[doc = "Whether this flow clears to the left. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."] #[doc = "virtual call is too expensive."]
const CLEARS_LEFT = 0b0000_0000_0000_0000_1000_0000; const CLEARS_LEFT = 0b0000_0000_0000_0000_1000_0000,
#[doc = "Whether this flow clears to the right. This is checked all over layout, so a"] #[doc = "Whether this flow clears to the right. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."] #[doc = "virtual call is too expensive."]
const CLEARS_RIGHT = 0b0000_0000_0000_0001_0000_0000; const CLEARS_RIGHT = 0b0000_0000_0000_0001_0000_0000,
#[doc = "Whether this flow is left-floated. This is checked all over layout, so a"] #[doc = "Whether this flow is left-floated. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."] #[doc = "virtual call is too expensive."]
const FLOATS_LEFT = 0b0000_0000_0000_0010_0000_0000; const FLOATS_LEFT = 0b0000_0000_0000_0010_0000_0000,
#[doc = "Whether this flow is right-floated. This is checked all over layout, so a"] #[doc = "Whether this flow is right-floated. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."] #[doc = "virtual call is too expensive."]
const FLOATS_RIGHT = 0b0000_0000_0000_0100_0000_0000; const FLOATS_RIGHT = 0b0000_0000_0000_0100_0000_0000,
#[doc = "Text alignment. \ #[doc = "Text alignment. \
NB: If you update this, update `TEXT_ALIGN_SHIFT` below."] NB: If you update this, update `TEXT_ALIGN_SHIFT` below."]
const TEXT_ALIGN = 0b0000_0000_0111_1000_0000_0000; const TEXT_ALIGN = 0b0000_0000_0111_1000_0000_0000,
#[doc = "Whether this flow has a fragment with `counter-reset` or `counter-increment` \ #[doc = "Whether this flow has a fragment with `counter-reset` or `counter-increment` \
styles."] styles."]
const AFFECTS_COUNTERS = 0b0000_0000_1000_0000_0000_0000; const AFFECTS_COUNTERS = 0b0000_0000_1000_0000_0000_0000,
#[doc = "Whether this flow's descendants have fragments that affect `counter-reset` or \ #[doc = "Whether this flow's descendants have fragments that affect `counter-reset` or \
`counter-increment` styles."] `counter-increment` styles."]
const HAS_COUNTER_AFFECTING_CHILDREN = 0b0000_0001_0000_0000_0000_0000; const HAS_COUNTER_AFFECTING_CHILDREN = 0b0000_0001_0000_0000_0000_0000,
#[doc = "Whether this flow behaves as though it had `position: static` for the purposes \ #[doc = "Whether this flow behaves as though it had `position: static` for the purposes \
of positioning in the inline direction. This is set for flows with `position: \ of positioning in the inline direction. This is set for flows with `position: \
static` and `position: relative` as well as absolutely-positioned flows with \ static` and `position: relative` as well as absolutely-positioned flows with \
unconstrained positions in the inline direction."] unconstrained positions in the inline direction."]
const INLINE_POSITION_IS_STATIC = 0b0000_0010_0000_0000_0000_0000; const INLINE_POSITION_IS_STATIC = 0b0000_0010_0000_0000_0000_0000,
#[doc = "Whether this flow behaves as though it had `position: static` for the purposes \ #[doc = "Whether this flow behaves as though it had `position: static` for the purposes \
of positioning in the block direction. This is set for flows with `position: \ of positioning in the block direction. This is set for flows with `position: \
static` and `position: relative` as well as absolutely-positioned flows with \ static` and `position: relative` as well as absolutely-positioned flows with \
unconstrained positions in the block direction."] unconstrained positions in the block direction."]
const BLOCK_POSITION_IS_STATIC = 0b0000_0100_0000_0000_0000_0000; const BLOCK_POSITION_IS_STATIC = 0b0000_0100_0000_0000_0000_0000,
/// Whether any ancestor is a fragmentation container /// Whether any ancestor is a fragmentation container
const CAN_BE_FRAGMENTED = 0b0000_1000_0000_0000_0000_0000; const CAN_BE_FRAGMENTED = 0b0000_1000_0000_0000_0000_0000,
/// Whether this flow contains any text and/or replaced fragments. /// Whether this flow contains any text and/or replaced fragments.
const CONTAINS_TEXT_OR_REPLACED_FRAGMENTS = 0b0001_0000_0000_0000_0000_0000; const CONTAINS_TEXT_OR_REPLACED_FRAGMENTS = 0b0001_0000_0000_0000_0000_0000,
/// Whether margins are prohibited from collapsing with this flow. /// Whether margins are prohibited from collapsing with this flow.
const MARGINS_CANNOT_COLLAPSE = 0b0010_0000_0000_0000_0000_0000; const MARGINS_CANNOT_COLLAPSE = 0b0010_0000_0000_0000_0000_0000,
} }
} }
@ -652,20 +652,20 @@ static TEXT_ALIGN_SHIFT: usize = 11;
impl FlowFlags { impl FlowFlags {
#[inline] #[inline]
pub fn text_align(self) -> text_align::T { pub fn text_align(self) -> text_align::T {
text_align::T::from_u32((self & FlowFlags::TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap() text_align::T::from_u32((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
} }
#[inline] #[inline]
pub fn set_text_align(&mut self, value: text_align::T) { pub fn set_text_align(&mut self, value: text_align::T) {
*self = (*self & !FlowFlags::TEXT_ALIGN) | *self = (*self & !TEXT_ALIGN) |
FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap(); FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap();
} }
#[inline] #[inline]
pub fn float_kind(&self) -> float::T { pub fn float_kind(&self) -> float::T {
if self.contains(FlowFlags::FLOATS_LEFT) { if self.contains(FLOATS_LEFT) {
float::T::left float::T::left
} else if self.contains(FlowFlags::FLOATS_RIGHT) { } else if self.contains(FLOATS_RIGHT) {
float::T::right float::T::right
} else { } else {
float::T::none float::T::none
@ -674,12 +674,12 @@ impl FlowFlags {
#[inline] #[inline]
pub fn is_float(&self) -> bool { pub fn is_float(&self) -> bool {
self.contains(FlowFlags::FLOATS_LEFT) || self.contains(FlowFlags::FLOATS_RIGHT) self.contains(FLOATS_LEFT) || self.contains(FLOATS_RIGHT)
} }
#[inline] #[inline]
pub fn clears_floats(&self) -> bool { pub fn clears_floats(&self) -> bool {
self.contains(FlowFlags::CLEARS_LEFT) || self.contains(FlowFlags::CLEARS_RIGHT) self.contains(CLEARS_LEFT) || self.contains(CLEARS_RIGHT)
} }
} }
@ -949,8 +949,8 @@ impl fmt::Debug for BaseFlow {
overflow={:?}{}{}{}", overflow={:?}{}{}{}",
self.stacking_context_id, self.stacking_context_id,
self.position, self.position,
if self.flags.contains(FlowFlags::FLOATS_LEFT) { "FL" } else { "" }, if self.flags.contains(FLOATS_LEFT) { "FL" } else { "" },
if self.flags.contains(FlowFlags::FLOATS_RIGHT) { "FR" } else { "" }, if self.flags.contains(FLOATS_RIGHT) { "FR" } else { "" },
self.speculated_float_placement_in, self.speculated_float_placement_in,
self.speculated_float_placement_out, self.speculated_float_placement_out,
self.overflow, self.overflow,
@ -993,50 +993,50 @@ impl BaseFlow {
Some(style) => { Some(style) => {
match style.get_box().position { match style.get_box().position {
position::T::absolute | position::T::fixed => { position::T::absolute | position::T::fixed => {
flags.insert(FlowFlags::IS_ABSOLUTELY_POSITIONED); flags.insert(IS_ABSOLUTELY_POSITIONED);
let logical_position = style.logical_position(); let logical_position = style.logical_position();
if logical_position.inline_start == LengthOrPercentageOrAuto::Auto && if logical_position.inline_start == LengthOrPercentageOrAuto::Auto &&
logical_position.inline_end == LengthOrPercentageOrAuto::Auto { logical_position.inline_end == LengthOrPercentageOrAuto::Auto {
flags.insert(FlowFlags::INLINE_POSITION_IS_STATIC); flags.insert(INLINE_POSITION_IS_STATIC);
} }
if logical_position.block_start == LengthOrPercentageOrAuto::Auto && if logical_position.block_start == LengthOrPercentageOrAuto::Auto &&
logical_position.block_end == LengthOrPercentageOrAuto::Auto { logical_position.block_end == LengthOrPercentageOrAuto::Auto {
flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC); flags.insert(BLOCK_POSITION_IS_STATIC);
} }
} }
_ => flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC | FlowFlags::INLINE_POSITION_IS_STATIC), _ => flags.insert(BLOCK_POSITION_IS_STATIC | INLINE_POSITION_IS_STATIC),
} }
if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary { if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
match style.get_box().float { match style.get_box().float {
float::T::none => {} float::T::none => {}
float::T::left => flags.insert(FlowFlags::FLOATS_LEFT), float::T::left => flags.insert(FLOATS_LEFT),
float::T::right => flags.insert(FlowFlags::FLOATS_RIGHT), float::T::right => flags.insert(FLOATS_RIGHT),
} }
} }
match style.get_box().clear { match style.get_box().clear {
clear::T::none => {} clear::T::none => {}
clear::T::left => flags.insert(FlowFlags::CLEARS_LEFT), clear::T::left => flags.insert(CLEARS_LEFT),
clear::T::right => flags.insert(FlowFlags::CLEARS_RIGHT), clear::T::right => flags.insert(CLEARS_RIGHT),
clear::T::both => { clear::T::both => {
flags.insert(FlowFlags::CLEARS_LEFT); flags.insert(CLEARS_LEFT);
flags.insert(FlowFlags::CLEARS_RIGHT); flags.insert(CLEARS_RIGHT);
} }
} }
if !style.get_counters().counter_reset.0.is_empty() || if !style.get_counters().counter_reset.0.is_empty() ||
!style.get_counters().counter_increment.0.is_empty() { !style.get_counters().counter_increment.0.is_empty() {
flags.insert(FlowFlags::AFFECTS_COUNTERS) flags.insert(AFFECTS_COUNTERS)
} }
} }
None => flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC | FlowFlags::INLINE_POSITION_IS_STATIC), None => flags.insert(BLOCK_POSITION_IS_STATIC | INLINE_POSITION_IS_STATIC),
} }
// New flows start out as fully damaged. // New flows start out as fully damaged.
let mut damage = RestyleDamage::rebuild_and_reflow(); let mut damage = RestyleDamage::rebuild_and_reflow();
damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW); damage.remove(RECONSTRUCT_FLOW);
BaseFlow { BaseFlow {
restyle_damage: damage, restyle_damage: damage,
@ -1073,15 +1073,15 @@ impl BaseFlow {
pub fn update_flags_if_needed(&mut self, style: &ComputedValues) { pub fn update_flags_if_needed(&mut self, style: &ComputedValues) {
// For absolutely-positioned flows, changes to top/bottom/left/right can cause these flags // For absolutely-positioned flows, changes to top/bottom/left/right can cause these flags
// to get out of date: // to get out of date:
if self.restyle_damage.contains(ServoRestyleDamage::REFLOW_OUT_OF_FLOW) { if self.restyle_damage.contains(REFLOW_OUT_OF_FLOW) {
// Note: We don't need to check whether IS_ABSOLUTELY_POSITIONED has changed, because // Note: We don't need to check whether IS_ABSOLUTELY_POSITIONED has changed, because
// changes to the 'position' property trigger flow reconstruction. // changes to the 'position' property trigger flow reconstruction.
if self.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.flags.contains(IS_ABSOLUTELY_POSITIONED) {
let logical_position = style.logical_position(); let logical_position = style.logical_position();
self.flags.set(FlowFlags::INLINE_POSITION_IS_STATIC, self.flags.set(INLINE_POSITION_IS_STATIC,
logical_position.inline_start == LengthOrPercentageOrAuto::Auto && logical_position.inline_start == LengthOrPercentageOrAuto::Auto &&
logical_position.inline_end == LengthOrPercentageOrAuto::Auto); logical_position.inline_end == LengthOrPercentageOrAuto::Auto);
self.flags.set(FlowFlags::BLOCK_POSITION_IS_STATIC, self.flags.set(BLOCK_POSITION_IS_STATIC,
logical_position.block_start == LengthOrPercentageOrAuto::Auto && logical_position.block_start == LengthOrPercentageOrAuto::Auto &&
logical_position.block_end == LengthOrPercentageOrAuto::Auto); logical_position.block_end == LengthOrPercentageOrAuto::Auto);
} }
@ -1092,8 +1092,7 @@ impl BaseFlow {
pub fn clone_with_children(&self, children: FlowList) -> BaseFlow { pub fn clone_with_children(&self, children: FlowList) -> BaseFlow {
BaseFlow { BaseFlow {
children: children, children: children,
restyle_damage: self.restyle_damage | ServoRestyleDamage::REPAINT | restyle_damage: self.restyle_damage | REPAINT | REFLOW_OUT_OF_FLOW | REFLOW,
ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW,
parallel: FlowParallelInfo::new(), parallel: FlowParallelInfo::new(),
floats: self.floats.clone(), floats: self.floats.clone(),
abs_descendants: self.abs_descendants.clone(), abs_descendants: self.abs_descendants.clone(),
@ -1291,7 +1290,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
return Some(base(kid).position.start.b + baseline_offset) return Some(base(kid).position.start.b + baseline_offset)
} }
} }
if kid.is_block_like() && !base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if kid.is_block_like() && !base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if let Some(baseline_offset) = kid.baseline_offset_of_last_line_box_in_flow() { if let Some(baseline_offset) = kid.baseline_offset_of_last_line_box_in_flow() {
return Some(base(kid).position.start.b + baseline_offset) return Some(base(kid).position.start.b + baseline_offset)
} }

View file

@ -19,8 +19,8 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::ByteIndex; use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice}; use gfx::text::text_run::{TextRun, TextRunSlice};
use gfx_traits::StackingContextId; use gfx_traits::StackingContextId;
use inline::{InlineFragmentNodeFlags, InlineFragmentContext, InlineFragmentNodeInfo}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
use inline::{InlineMetrics, LineMetrics}; use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT, LineMetrics};
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use layout_debug; use layout_debug;
@ -48,7 +48,7 @@ use style::logical_geometry::{Direction, LogicalMargin, LogicalRect, LogicalSize
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::properties::longhands::transform::computed_value::T as TransformList; use style::properties::longhands::transform::computed_value::T as TransformList;
use style::selector_parser::RestyleDamage; use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::RECONSTRUCT_FLOW;
use style::str::char_is_whitespace; use style::str::char_is_whitespace;
use style::values::{self, Either, Auto}; use style::values::{self, Either, Auto};
use style::values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
@ -533,13 +533,13 @@ pub struct ScannedTextFragmentInfo {
} }
bitflags! { bitflags! {
pub struct ScannedTextFlags: u8 { pub flags ScannedTextFlags: u8 {
/// Whether a line break is required after this fragment if wrapping on newlines (e.g. if /// Whether a line break is required after this fragment if wrapping on newlines (e.g. if
/// `white-space: pre` is in effect). /// `white-space: pre` is in effect).
const REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES = 0x01; const REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES = 0x01,
/// Is this fragment selected? /// Is this fragment selected?
const SELECTED = 0x02; const SELECTED = 0x02,
} }
} }
@ -566,11 +566,11 @@ impl ScannedTextFragmentInfo {
} }
pub fn requires_line_break_afterward_if_wrapping_on_newlines(&self) -> bool { pub fn requires_line_break_afterward_if_wrapping_on_newlines(&self) -> bool {
self.flags.contains(ScannedTextFlags::REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES) self.flags.contains(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES)
} }
pub fn selected(&self) -> bool { pub fn selected(&self) -> bool {
self.flags.contains(ScannedTextFlags::SELECTED) self.flags.contains(SELECTED)
} }
} }
@ -671,7 +671,7 @@ impl Fragment {
let writing_mode = style.writing_mode; let writing_mode = style.writing_mode;
let mut restyle_damage = node.restyle_damage(); let mut restyle_damage = node.restyle_damage();
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW); restyle_damage.remove(RECONSTRUCT_FLOW);
Fragment { Fragment {
node: node.opaque(), node: node.opaque(),
@ -700,7 +700,7 @@ impl Fragment {
-> Fragment { -> Fragment {
let writing_mode = style.writing_mode; let writing_mode = style.writing_mode;
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW); restyle_damage.remove(RECONSTRUCT_FLOW);
Fragment { Fragment {
node: node, node: node,
@ -753,7 +753,7 @@ impl Fragment {
size); size);
let mut restyle_damage = RestyleDamage::rebuild_and_reflow(); let mut restyle_damage = RestyleDamage::rebuild_and_reflow();
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW); restyle_damage.remove(RECONSTRUCT_FLOW);
Fragment { Fragment {
node: self.node, node: self.node,
@ -818,7 +818,7 @@ impl Fragment {
}); });
debug_assert!(ellipsis_fragments.len() == 1); debug_assert!(ellipsis_fragments.len() == 1);
ellipsis_fragment = ellipsis_fragments.fragments.into_iter().next().unwrap(); ellipsis_fragment = ellipsis_fragments.fragments.into_iter().next().unwrap();
ellipsis_fragment.flags |= FragmentFlags::IS_ELLIPSIS; ellipsis_fragment.flags |= IS_ELLIPSIS;
ellipsis_fragment ellipsis_fragment
} }
@ -858,36 +858,35 @@ impl Fragment {
QuantitiesIncludedInIntrinsicInlineSizes::all() QuantitiesIncludedInIntrinsicInlineSizes::all()
} }
SpecificFragmentInfo::Table => { SpecificFragmentInfo::Table => {
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED | INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING | INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} }
SpecificFragmentInfo::TableCell => { SpecificFragmentInfo::TableCell => {
let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING | let base_quantities = INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED; INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse == if self.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate { border_collapse::T::separate {
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER base_quantities | INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else { } else {
base_quantities base_quantities
} }
} }
SpecificFragmentInfo::TableWrapper => { SpecificFragmentInfo::TableWrapper => {
let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS | let base_quantities = INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED; INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse == if self.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate { border_collapse::T::separate {
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER base_quantities | INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else { } else {
base_quantities base_quantities
} }
} }
SpecificFragmentInfo::TableRow => { SpecificFragmentInfo::TableRow => {
let base_quantities = let base_quantities = INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse == if self.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate { border_collapse::T::separate {
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER base_quantities | INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else { } else {
base_quantities base_quantities
} }
@ -915,8 +914,7 @@ impl Fragment {
// FIXME(pcwalton): Percentages should be relative to any definite size per CSS-SIZING. // FIXME(pcwalton): Percentages should be relative to any definite size per CSS-SIZING.
// This will likely need to be done by pushing down definite sizes during selector // This will likely need to be done by pushing down definite sizes during selector
// cascading. // cascading.
let margin = if flags.contains( let margin = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS) {
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS) {
let margin = style.logical_margin(); let margin = style.logical_margin();
(MaybeAuto::from_style(margin.inline_start, Au(0)).specified_or_zero() + (MaybeAuto::from_style(margin.inline_start, Au(0)).specified_or_zero() +
MaybeAuto::from_style(margin.inline_end, Au(0)).specified_or_zero()) MaybeAuto::from_style(margin.inline_end, Au(0)).specified_or_zero())
@ -927,8 +925,7 @@ impl Fragment {
// FIXME(pcwalton): Percentages should be relative to any definite size per CSS-SIZING. // FIXME(pcwalton): Percentages should be relative to any definite size per CSS-SIZING.
// This will likely need to be done by pushing down definite sizes during selector // This will likely need to be done by pushing down definite sizes during selector
// cascading. // cascading.
let padding = if flags.contains( let padding = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_PADDING) {
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING) {
let padding = style.logical_padding(); let padding = style.logical_padding();
(padding.inline_start.to_used_value(Au(0)) + (padding.inline_start.to_used_value(Au(0)) +
padding.inline_end.to_used_value(Au(0))) padding.inline_end.to_used_value(Au(0)))
@ -936,8 +933,7 @@ impl Fragment {
Au(0) Au(0)
}; };
let border = if flags.contains( let border = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_BORDER) {
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER) {
self.border_width().inline_start_end() self.border_width().inline_start_end()
} else { } else {
Au(0) Au(0)
@ -956,7 +952,7 @@ impl Fragment {
let (border_padding, margin) = self.surrounding_intrinsic_inline_size(); let (border_padding, margin) = self.surrounding_intrinsic_inline_size();
let mut specified = Au(0); let mut specified = Au(0);
if flags.contains(QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) { if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
specified = MaybeAuto::from_style(style.content_inline_size(), specified = MaybeAuto::from_style(style.content_inline_size(),
Au(0)).specified_or_zero(); Au(0)).specified_or_zero();
specified = max(style.min_inline_size().to_used_value(Au(0)), specified); specified = max(style.min_inline_size().to_used_value(Au(0)), specified);
@ -1207,10 +1203,10 @@ impl Fragment {
inline_fragment_context.nodes.iter().fold(style_border_width, |accumulator, node| { inline_fragment_context.nodes.iter().fold(style_border_width, |accumulator, node| {
let mut this_border_width = let mut this_border_width =
node.style.border_width_for_writing_mode(writing_mode); node.style.border_width_for_writing_mode(writing_mode);
if !node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
this_border_width.inline_start = Au(0) this_border_width.inline_start = Au(0)
} }
if !node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
this_border_width.inline_end = Au(0) this_border_width.inline_end = Au(0)
} }
accumulator + this_border_width accumulator + this_border_width
@ -1264,15 +1260,13 @@ impl Fragment {
if let Some(ref inline_context) = self.inline_context { if let Some(ref inline_context) = self.inline_context {
for node in &inline_context.nodes { for node in &inline_context.nodes {
let margin = node.style.logical_margin(); let margin = node.style.logical_margin();
let this_inline_start_margin = if !node.flags.contains( let this_inline_start_margin = if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
Au(0) Au(0)
} else { } else {
MaybeAuto::from_style(margin.inline_start, MaybeAuto::from_style(margin.inline_start,
containing_block_inline_size).specified_or_zero() containing_block_inline_size).specified_or_zero()
}; };
let this_inline_end_margin = if!node.flags.contains( let this_inline_end_margin = if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
Au(0) Au(0)
} else { } else {
MaybeAuto::from_style(margin.inline_end, MaybeAuto::from_style(margin.inline_end,
@ -1345,10 +1339,10 @@ impl Fragment {
let zero_padding = LogicalMargin::zero(writing_mode); let zero_padding = LogicalMargin::zero(writing_mode);
inline_fragment_context.nodes.iter().fold(zero_padding, |accumulator, node| { inline_fragment_context.nodes.iter().fold(zero_padding, |accumulator, node| {
let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode); let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode);
if !node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
padding.inline_start = Au(0) padding.inline_start = Au(0)
} }
if !node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
padding.inline_end = Au(0) padding.inline_end = Au(0)
} }
accumulator + padding accumulator + padding
@ -1590,12 +1584,12 @@ impl Fragment {
let mut border_width = node.style.logical_border_width(); let mut border_width = node.style.logical_border_width();
let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode); let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode);
let mut margin = model::specified_margin_from_style(&*node.style, writing_mode); let mut margin = model::specified_margin_from_style(&*node.style, writing_mode);
if !node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
border_width.inline_start = Au(0); border_width.inline_start = Au(0);
padding.inline_start = Au(0); padding.inline_start = Au(0);
margin.inline_start = Au(0); margin.inline_start = Au(0);
} }
if !node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) { if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
border_width.inline_end = Au(0); border_width.inline_end = Au(0);
padding.inline_end = Au(0); padding.inline_end = Au(0);
margin.inline_end = Au(0); margin.inline_end = Au(0);
@ -1653,9 +1647,9 @@ impl Fragment {
let mut flags = SplitOptions::empty(); let mut flags = SplitOptions::empty();
if starts_line { if starts_line {
flags.insert(SplitOptions::STARTS_LINE); flags.insert(STARTS_LINE);
if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::T::break_word { if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::T::break_word {
flags.insert(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES) flags.insert(RETRY_AT_CHARACTER_BOUNDARIES)
} }
} }
@ -1673,7 +1667,7 @@ impl Fragment {
// Break at character boundaries. // Break at character boundaries.
let character_breaking_strategy = let character_breaking_strategy =
text_fragment_info.run.character_slices_in_range(&text_fragment_info.range); text_fragment_info.run.character_slices_in_range(&text_fragment_info.range);
flags.remove(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES); flags.remove(RETRY_AT_CHARACTER_BOUNDARIES);
self.calculate_split_position_using_breaking_strategy( self.calculate_split_position_using_breaking_strategy(
character_breaking_strategy, character_breaking_strategy,
max_inline_size, max_inline_size,
@ -1836,12 +1830,12 @@ impl Fragment {
if split_is_empty || overflowing { if split_is_empty || overflowing {
// If we've been instructed to retry at character boundaries (probably via // If we've been instructed to retry at character boundaries (probably via
// `overflow-wrap: break-word`), do so. // `overflow-wrap: break-word`), do so.
if flags.contains(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES) { if flags.contains(RETRY_AT_CHARACTER_BOUNDARIES) {
let character_breaking_strategy = let character_breaking_strategy =
text_fragment_info.run text_fragment_info.run
.character_slices_in_range(&text_fragment_info.range); .character_slices_in_range(&text_fragment_info.range);
let mut flags = flags; let mut flags = flags;
flags.remove(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES); flags.remove(RETRY_AT_CHARACTER_BOUNDARIES);
return self.calculate_split_position_using_breaking_strategy( return self.calculate_split_position_using_breaking_strategy(
character_breaking_strategy, character_breaking_strategy,
max_inline_size, max_inline_size,
@ -1850,7 +1844,7 @@ impl Fragment {
// We aren't at the start of the line, so don't overflow. Let inline layout wrap to // We aren't at the start of the line, so don't overflow. Let inline layout wrap to
// the next line instead. // the next line instead.
if !flags.contains(SplitOptions::STARTS_LINE) { if !flags.contains(STARTS_LINE) {
return None return None
} }
} }
@ -1886,7 +1880,7 @@ impl Fragment {
this_info.range_end_including_stripped_whitespace = this_info.range_end_including_stripped_whitespace =
other_info.range_end_including_stripped_whitespace; other_info.range_end_including_stripped_whitespace;
if other_info.requires_line_break_afterward_if_wrapping_on_newlines() { if other_info.requires_line_break_afterward_if_wrapping_on_newlines() {
this_info.flags.insert(ScannedTextFlags::REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES); this_info.flags.insert(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
} }
if other_info.insertion_point.is_some() { if other_info.insertion_point.is_some() {
this_info.insertion_point = other_info.insertion_point; this_info.insertion_point = other_info.insertion_point;
@ -2346,7 +2340,7 @@ impl Fragment {
// side, then we can't merge with the next fragment. // side, then we can't merge with the next fragment.
if let Some(ref inline_context) = self.inline_context { if let Some(ref inline_context) = self.inline_context {
for inline_context_node in inline_context.nodes.iter() { for inline_context_node in inline_context.nodes.iter() {
if !inline_context_node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) { if !inline_context_node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
continue continue
} }
if inline_context_node.style.logical_margin().inline_end != if inline_context_node.style.logical_margin().inline_end !=
@ -2367,7 +2361,7 @@ impl Fragment {
// preceding side, then it can't merge with us. // preceding side, then it can't merge with us.
if let Some(ref inline_context) = other.inline_context { if let Some(ref inline_context) = other.inline_context {
for inline_context_node in inline_context.nodes.iter() { for inline_context_node in inline_context.nodes.iter() {
if !inline_context_node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) { if !inline_context_node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
continue continue
} }
if inline_context_node.style.logical_margin().inline_start != if inline_context_node.style.logical_margin().inline_start !=
@ -2813,15 +2807,14 @@ impl Fragment {
.zip(inline_context_of_next_fragment.nodes.iter().rev()) .zip(inline_context_of_next_fragment.nodes.iter().rev())
{ {
if !inline_context_node_from_next_fragment.flags.contains( if !inline_context_node_from_next_fragment.flags.contains(
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) { LAST_FRAGMENT_OF_ELEMENT) {
continue continue
} }
if inline_context_node_from_next_fragment.address != if inline_context_node_from_next_fragment.address !=
inline_context_node_from_this_fragment.address { inline_context_node_from_this_fragment.address {
continue continue
} }
inline_context_node_from_this_fragment.flags.insert( inline_context_node_from_this_fragment.flags.insert(LAST_FRAGMENT_OF_ELEMENT);
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
} }
} }
} }
@ -2836,7 +2829,7 @@ impl Fragment {
inline_context_of_this_fragment.nodes.iter_mut().rev()) inline_context_of_this_fragment.nodes.iter_mut().rev())
{ {
if !inline_context_node_from_prev_fragment.flags.contains( if !inline_context_node_from_prev_fragment.flags.contains(
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) { FIRST_FRAGMENT_OF_ELEMENT) {
continue continue
} }
if inline_context_node_from_prev_fragment.address != if inline_context_node_from_prev_fragment.address !=
@ -2844,7 +2837,7 @@ impl Fragment {
continue continue
} }
inline_context_node_from_this_fragment.flags.insert( inline_context_node_from_this_fragment.flags.insert(
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT); FIRST_FRAGMENT_OF_ELEMENT);
} }
} }
} }
@ -2985,23 +2978,23 @@ impl fmt::Debug for Fragment {
} }
bitflags! { bitflags! {
struct QuantitiesIncludedInIntrinsicInlineSizes: u8 { flags QuantitiesIncludedInIntrinsicInlineSizes: u8 {
const INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS = 0x01; const INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS = 0x01,
const INTRINSIC_INLINE_SIZE_INCLUDES_PADDING = 0x02; const INTRINSIC_INLINE_SIZE_INCLUDES_PADDING = 0x02,
const INTRINSIC_INLINE_SIZE_INCLUDES_BORDER = 0x04; const INTRINSIC_INLINE_SIZE_INCLUDES_BORDER = 0x04,
const INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED = 0x08; const INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED = 0x08,
} }
} }
bitflags! { bitflags! {
// Various flags we can use when splitting fragments. See // Various flags we can use when splitting fragments. See
// `calculate_split_position_using_breaking_strategy()`. // `calculate_split_position_using_breaking_strategy()`.
struct SplitOptions: u8 { flags SplitOptions: u8 {
#[doc = "True if this is the first fragment on the line."] #[doc = "True if this is the first fragment on the line."]
const STARTS_LINE = 0x01; const STARTS_LINE = 0x01,
#[doc = "True if we should attempt to split at character boundaries if this split fails. \ #[doc = "True if we should attempt to split at character boundaries if this split fails. \
This is used to implement `overflow-wrap: break-word`."] This is used to implement `overflow-wrap: break-word`."]
const RETRY_AT_CHARACTER_BOUNDARIES = 0x02; const RETRY_AT_CHARACTER_BOUNDARIES = 0x02,
} }
} }
@ -3117,14 +3110,14 @@ impl Overflow {
} }
bitflags! { bitflags! {
pub struct FragmentFlags: u8 { pub flags FragmentFlags: u8 {
// TODO(stshine): find a better name since these flags can also be used for grid item. // TODO(stshine): find a better name since these flags can also be used for grid item.
/// Whether this fragment represents a child in a row flex container. /// Whether this fragment represents a child in a row flex container.
const IS_INLINE_FLEX_ITEM = 0b0000_0001; const IS_INLINE_FLEX_ITEM = 0b0000_0001,
/// Whether this fragment represents a child in a column flex container. /// Whether this fragment represents a child in a column flex container.
const IS_BLOCK_FLEX_ITEM = 0b0000_0010; const IS_BLOCK_FLEX_ITEM = 0b0000_0010,
/// Whether this fragment represents the generated text from a text-overflow clip. /// Whether this fragment represents the generated text from a text-overflow clip.
const IS_ELLIPSIS = 0b0000_0100; const IS_ELLIPSIS = 0b0000_0100,
} }
} }

View file

@ -9,7 +9,7 @@
//! as possible. //! as possible.
use context::{LayoutContext, with_thread_local_font_context}; use context::{LayoutContext, with_thread_local_font_context};
use flow::{self, Flow, FlowFlags, ImmutableFlowUtils}; use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils};
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::display_list::OpaqueNode; use gfx::display_list::OpaqueNode;
use script_layout_interface::wrapper_traits::PseudoElementType; use script_layout_interface::wrapper_traits::PseudoElementType;
@ -19,7 +19,7 @@ use style::computed_values::{display, list_style_type};
use style::computed_values::content::ContentItem; use style::computed_values::content::ContentItem;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage; use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
use text::TextRunScanner; use text::TextRunScanner;
use traversal::InorderFlowTraversal; use traversal::InorderFlowTraversal;
@ -131,8 +131,8 @@ impl<'a> InorderFlowTraversal for ResolveGeneratedContent<'a> {
#[inline] #[inline]
fn should_process_subtree(&mut self, flow: &mut Flow) -> bool { fn should_process_subtree(&mut self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.intersects(ServoRestyleDamage::RESOLVE_GENERATED_CONTENT) || flow::base(flow).restyle_damage.intersects(RESOLVE_GENERATED_CONTENT) ||
flow::base(flow).flags.intersects(FlowFlags::AFFECTS_COUNTERS | FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN) flow::base(flow).flags.intersects(AFFECTS_COUNTERS | HAS_COUNTER_AFFECTING_CHILDREN)
} }
} }

View file

@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use flow::{self, FlowFlags, Flow}; use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, IS_ABSOLUTELY_POSITIONED};
use style::computed_values::float; use style::computed_values::float;
use style::selector_parser::RestyleDamage; use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{REFLOW, RECONSTRUCT_FLOW};
/// Used in a flow traversal to indicate whether this re-layout should be incremental or not. /// Used in a flow traversal to indicate whether this re-layout should be incremental or not.
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
@ -15,10 +15,10 @@ pub enum RelayoutMode {
} }
bitflags! { bitflags! {
pub struct SpecialRestyleDamage: u8 { pub flags SpecialRestyleDamage: u8 {
#[doc = "If this flag is set, we need to reflow the entire document. This is more or less a \ #[doc = "If this flag is set, we need to reflow the entire document. This is more or less a \
temporary hack to deal with cases that we don't handle incrementally yet."] temporary hack to deal with cases that we don't handle incrementally yet."]
const REFLOW_ENTIRE_DOCUMENT = 0x01; const REFLOW_ENTIRE_DOCUMENT = 0x01,
} }
} }
@ -30,7 +30,7 @@ pub trait LayoutDamageComputation {
impl<'a> LayoutDamageComputation for &'a mut Flow { impl<'a> LayoutDamageComputation for &'a mut Flow {
fn compute_layout_damage(self) -> SpecialRestyleDamage { fn compute_layout_damage(self) -> SpecialRestyleDamage {
let mut special_damage = SpecialRestyleDamage::empty(); let mut special_damage = SpecialRestyleDamage::empty();
let is_absolutely_positioned = flow::base(self).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); let is_absolutely_positioned = flow::base(self).flags.contains(IS_ABSOLUTELY_POSITIONED);
// In addition to damage, we use this phase to compute whether nodes affect CSS counters. // In addition to damage, we use this phase to compute whether nodes affect CSS counters.
let mut has_counter_affecting_children = false; let mut has_counter_affecting_children = false;
@ -42,7 +42,7 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
for kid in self_base.children.iter_mut() { for kid in self_base.children.iter_mut() {
let child_is_absolutely_positioned = let child_is_absolutely_positioned =
flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED); flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED);
flow::mut_base(kid).restyle_damage.insert( flow::mut_base(kid).restyle_damage.insert(
parent_damage.damage_for_child(is_absolutely_positioned, parent_damage.damage_for_child(is_absolutely_positioned,
child_is_absolutely_positioned)); child_is_absolutely_positioned));
@ -55,21 +55,21 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
child_is_absolutely_positioned)); child_is_absolutely_positioned));
has_counter_affecting_children = has_counter_affecting_children || has_counter_affecting_children = has_counter_affecting_children ||
flow::base(kid).flags.intersects(FlowFlags::AFFECTS_COUNTERS | flow::base(kid).flags.intersects(AFFECTS_COUNTERS |
FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN); HAS_COUNTER_AFFECTING_CHILDREN);
} }
} }
let self_base = flow::mut_base(self); let self_base = flow::mut_base(self);
if self_base.flags.float_kind() != float::T::none && if self_base.flags.float_kind() != float::T::none &&
self_base.restyle_damage.intersects(ServoRestyleDamage::REFLOW) { self_base.restyle_damage.intersects(REFLOW) {
special_damage.insert(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT); special_damage.insert(REFLOW_ENTIRE_DOCUMENT);
} }
if has_counter_affecting_children { if has_counter_affecting_children {
self_base.flags.insert(FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN) self_base.flags.insert(HAS_COUNTER_AFFECTING_CHILDREN)
} else { } else {
self_base.flags.remove(FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN) self_base.flags.remove(HAS_COUNTER_AFFECTING_CHILDREN)
} }
special_damage special_damage
@ -78,7 +78,7 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
fn reflow_entire_document(self) { fn reflow_entire_document(self) {
let self_base = flow::mut_base(self); let self_base = flow::mut_base(self);
self_base.restyle_damage.insert(RestyleDamage::rebuild_and_reflow()); self_base.restyle_damage.insert(RestyleDamage::rebuild_and_reflow());
self_base.restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW); self_base.restyle_damage.remove(RECONSTRUCT_FLOW);
for kid in self_base.children.iter_mut() { for kid in self_base.children.iter_mut() {
kid.reflow_entire_document(); kid.reflow_entire_document();
} }

View file

@ -13,10 +13,10 @@ use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Size2D}; use euclid::{Point2D, Size2D};
use floats::{FloatKind, Floats, PlacementInfo}; use floats::{FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag}; use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{FlowFlags, EarlyAbsolutePositionInfo, OpaqueFlow}; use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, EarlyAbsolutePositionInfo, OpaqueFlow};
use flow_ref::FlowRef; use flow_ref::FlowRef;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::FragmentFlags; use fragment::IS_ELLIPSIS;
use fragment::SpecificFragmentInfo; use fragment::SpecificFragmentInfo;
use gfx::display_list::OpaqueNode; use gfx::display_list::OpaqueNode;
use gfx::font::FontMetrics; use gfx::font::FontMetrics;
@ -34,7 +34,7 @@ use style::computed_values::{display, overflow_x, position, text_align, text_jus
use style::computed_values::{vertical_align, white_space}; use style::computed_values::{vertical_align, white_space};
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::{longhands, ComputedValues}; use style::properties::{longhands, ComputedValues};
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
use style::values::generics::box_::VerticalAlign; use style::values::generics::box_::VerticalAlign;
use text; use text;
use traversal::PreorderFlowTraversal; use traversal::PreorderFlowTraversal;
@ -344,7 +344,7 @@ impl LineBreaker {
}; };
// Do not reflow truncated fragments. Reflow the original fragment only. // Do not reflow truncated fragments. Reflow the original fragment only.
let fragment = if fragment.flags.contains(FragmentFlags::IS_ELLIPSIS) { let fragment = if fragment.flags.contains(IS_ELLIPSIS) {
continue continue
} else if let SpecificFragmentInfo::TruncatedFragment(info) = fragment.specific { } else if let SpecificFragmentInfo::TruncatedFragment(info) = fragment.specific {
info.full info.full
@ -667,7 +667,7 @@ impl LineBreaker {
inline_start_fragment.border_padding.inline_end = Au(0); inline_start_fragment.border_padding.inline_end = Au(0);
if let Some(ref mut inline_context) = inline_start_fragment.inline_context { if let Some(ref mut inline_context) = inline_start_fragment.inline_context {
for node in &mut inline_context.nodes { for node in &mut inline_context.nodes {
node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT); node.flags.remove(LAST_FRAGMENT_OF_ELEMENT);
} }
} }
inline_start_fragment.border_box.size.inline += inline_start_fragment.border_padding.inline_start; inline_start_fragment.border_box.size.inline += inline_start_fragment.border_padding.inline_start;
@ -675,7 +675,7 @@ impl LineBreaker {
inline_end_fragment.border_padding.inline_start = Au(0); inline_end_fragment.border_padding.inline_start = Au(0);
if let Some(ref mut inline_context) = inline_end_fragment.inline_context { if let Some(ref mut inline_context) = inline_end_fragment.inline_context {
for node in &mut inline_context.nodes { for node in &mut inline_context.nodes {
node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT); node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
} }
} }
inline_end_fragment.border_box.size.inline += inline_end_fragment.border_padding.inline_end; inline_end_fragment.border_box.size.inline += inline_end_fragment.border_padding.inline_end;
@ -899,7 +899,7 @@ impl InlineFlow {
}; };
if flow.fragments.fragments.iter().any(Fragment::is_unscanned_generated_content) { if flow.fragments.fragments.iter().any(Fragment::is_unscanned_generated_content) {
flow.base.restyle_damage.insert(ServoRestyleDamage::RESOLVE_GENERATED_CONTENT); flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT);
} }
flow flow
@ -1315,7 +1315,7 @@ impl Flow for InlineFlow {
flow::mut_base(kid).floats = Floats::new(writing_mode); flow::mut_base(kid).floats = Floats::new(writing_mode);
} }
self.base.flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); self.base.flags.remove(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
let mut intrinsic_sizes_for_flow = IntrinsicISizesContribution::new(); let mut intrinsic_sizes_for_flow = IntrinsicISizesContribution::new();
let mut intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new(); let mut intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new();
@ -1374,10 +1374,10 @@ impl Flow for InlineFlow {
} }
} }
fragment.restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES); fragment.restyle_damage.remove(BUBBLE_ISIZES);
if fragment.is_text_or_replaced() { if fragment.is_text_or_replaced() {
self.base.flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); self.base.flags.insert(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
} }
} }
@ -1537,9 +1537,9 @@ impl Flow for InlineFlow {
} }
}); });
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
for fragment in &mut self.fragments.fragments { for fragment in &mut self.fragments.fragments {
fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
} }
} }
@ -1768,9 +1768,9 @@ pub struct InlineFragmentNodeInfo {
} }
bitflags! { bitflags! {
pub struct InlineFragmentNodeFlags: u8 { pub flags InlineFragmentNodeFlags: u8 {
const FIRST_FRAGMENT_OF_ELEMENT = 0x01; const FIRST_FRAGMENT_OF_ELEMENT = 0x01,
const LAST_FRAGMENT_OF_ELEMENT = 0x02; const LAST_FRAGMENT_OF_ELEMENT = 0x02,
} }
} }

View file

@ -22,7 +22,7 @@ use inline::InlineFlow;
use style::computed_values::{list_style_type, position}; use style::computed_values::{list_style_type, position};
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for ListItemFlow {} unsafe impl ::flow::HasBaseFlow for ListItemFlow {}
@ -56,7 +56,7 @@ impl ListItemFlow {
list_style_type::T::square | list_style_type::T::square |
list_style_type::T::disclosure_open | list_style_type::T::disclosure_open |
list_style_type::T::disclosure_closed => {} list_style_type::T::disclosure_closed => {}
_ => this.block_flow.base.restyle_damage.insert(ServoRestyleDamage::RESOLVE_GENERATED_CONTENT), _ => this.block_flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT),
} }
} }

View file

@ -11,7 +11,7 @@ use euclid::{Point2D, Vector2D, Rect, Size2D};
use flow::{self, Flow}; use flow::{self, Flow};
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo}; use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use gfx::display_list::{DisplayList, OpaqueNode, ScrollOffsetMap}; use gfx::display_list::{DisplayList, OpaqueNode, ScrollOffsetMap};
use inline::InlineFragmentNodeFlags; use inline::LAST_FRAGMENT_OF_ELEMENT;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use opaque_node::OpaqueNodeMethods; use opaque_node::OpaqueNodeMethods;
@ -562,7 +562,7 @@ impl FragmentBorderBoxIterator for ParentOffsetBorderBoxIterator {
}, },
} }
if node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) { if node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
self.has_processed_node = true; self.has_processed_node = true;
} }
} else if self.node_offset_box.is_none() { } else if self.node_offset_box.is_none() {

View file

@ -9,12 +9,12 @@ use context::LayoutContext;
use display_list_builder::{DisplayListBuildState, StackingContextCollectionState}; use display_list_builder::{DisplayListBuildState, StackingContextCollectionState};
use euclid::{Point2D, Vector2D}; use euclid::{Point2D, Vector2D};
use floats::SpeculatedFloatPlacement; use floats::SpeculatedFloatPlacement;
use flow::{self, Flow, ImmutableFlowUtils, FlowFlags}; use flow::{self, Flow, ImmutableFlowUtils, IS_ABSOLUTELY_POSITIONED};
use fragment::{FragmentBorderBoxIterator, CoordinateSystem}; use fragment::{FragmentBorderBoxIterator, CoordinateSystem};
use generated_content::ResolveGeneratedContent; use generated_content::ResolveGeneratedContent;
use incremental::RelayoutMode; use incremental::RelayoutMode;
use servo_config::opts; use servo_config::opts;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, STORE_OVERFLOW};
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList}; use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal}; use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal};
@ -33,7 +33,7 @@ pub fn reflow(root: &mut Flow, layout_context: &LayoutContext, relayout_mode: Re
if relayout_mode == RelayoutMode::Force { if relayout_mode == RelayoutMode::Force {
flow::mut_base(flow) flow::mut_base(flow)
.restyle_damage .restyle_damage
.insert(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); .insert(REFLOW_OUT_OF_FLOW | REFLOW);
} }
if assign_inline_sizes.should_process(flow) { if assign_inline_sizes.should_process(flow) {
@ -112,7 +112,7 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow, iterator
} }
pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) { pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
if !flow::base(flow).restyle_damage.contains(ServoRestyleDamage::STORE_OVERFLOW) { if !flow::base(flow).restyle_damage.contains(STORE_OVERFLOW) {
return; return;
} }
@ -124,20 +124,20 @@ pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
flow::mut_base(flow) flow::mut_base(flow)
.restyle_damage .restyle_damage
.remove(ServoRestyleDamage::STORE_OVERFLOW); .remove(STORE_OVERFLOW);
} }
/// Guesses how much inline size will be taken up by floats on the left and right sides of the /// Guesses how much inline size will be taken up by floats on the left and right sides of the
/// given flow. This is needed to speculatively calculate the inline sizes of block formatting /// given flow. This is needed to speculatively calculate the inline sizes of block formatting
/// contexts. The speculation typically succeeds, but if it doesn't we have to lay it out again. /// contexts. The speculation typically succeeds, but if it doesn't we have to lay it out again.
pub fn guess_float_placement(flow: &mut Flow) { pub fn guess_float_placement(flow: &mut Flow) {
if !flow::base(flow).restyle_damage.intersects(ServoRestyleDamage::REFLOW) { if !flow::base(flow).restyle_damage.intersects(REFLOW) {
return; return;
} }
let mut floats_in = SpeculatedFloatPlacement::compute_floats_in_for_first_child(flow); let mut floats_in = SpeculatedFloatPlacement::compute_floats_in_for_first_child(flow);
for kid in flow::mut_base(flow).child_iter_mut() { for kid in flow::mut_base(flow).child_iter_mut() {
if flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
// Do not propagate floats in or out, but do propogate between kids. // Do not propagate floats in or out, but do propogate between kids.
guess_float_placement(kid); guess_float_placement(kid);
} else { } else {

View file

@ -11,7 +11,8 @@ use block::{BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer};
use block::{ISizeConstraintInput, ISizeConstraintSolution}; use block::{ISizeConstraintInput, ISizeConstraintSolution};
use context::LayoutContext; use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags, StackingContextCollectionState}; use display_list_builder::{DisplayListBuildState, NEVER_CREATES_STACKING_CONTEXT};
use display_list_builder::StackingContextCollectionState;
use euclid::Point2D; use euclid::Point2D;
use flow; use flow;
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
@ -26,7 +27,7 @@ use style::computed_values::{border_collapse, border_spacing, table_layout};
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::CSSFloat; use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use table_row::{self, CellIntrinsicInlineSize, CollapsedBorder, CollapsedBorderProvenance}; use table_row::{self, CellIntrinsicInlineSize, CollapsedBorder, CollapsedBorderProvenance};
@ -504,8 +505,7 @@ impl Flow for TableFlow {
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
// Stacking contexts are collected by the table wrapper. // Stacking contexts are collected by the table wrapper.
self.block_flow.collect_stacking_contexts_for_block(state, self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_STACKING_CONTEXT);
StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT);
} }
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
@ -735,7 +735,7 @@ impl TableLikeFlow for BlockFlow {
debug_assert!(self.fragment.style.get_inheritedtable().border_collapse == debug_assert!(self.fragment.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate || block_direction_spacing == Au(0)); border_collapse::T::separate || block_direction_spacing == Au(0));
if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { if self.base.restyle_damage.contains(REFLOW) {
// Our current border-box position. // Our current border-box position.
let block_start_border_padding = self.fragment.border_padding.block_start; let block_start_border_padding = self.fragment.border_padding.block_start;
let mut current_block_offset = block_start_border_padding; let mut current_block_offset = block_start_border_padding;
@ -809,7 +809,7 @@ impl TableLikeFlow for BlockFlow {
} }
} }
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
} }
} }

View file

@ -13,7 +13,7 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags}; use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState; use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, FlowFlags, OpaqueFlow}; use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use layout_debug; use layout_debug;
@ -102,7 +102,7 @@ impl TableCellFlow {
let mut extents = None; let mut extents = None;
for kid in flow::base(self).children.iter() { for kid in flow::base(self).children.iter() {
let kid_base = flow::base(kid); let kid_base = flow::base(kid);
if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
continue continue
} }
let start = kid_base.position.start.b - let start = kid_base.position.start.b -
@ -144,7 +144,7 @@ impl TableCellFlow {
for kid in flow::mut_base(self).children.iter_mut() { for kid in flow::mut_base(self).children.iter_mut() {
let kid_base = flow::mut_base(kid); let kid_base = flow::mut_base(kid);
if !kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
kid_base.position.start.b += offset kid_base.position.start.b += offset
} }
} }

View file

@ -26,7 +26,7 @@ use std::iter::{Enumerate, IntoIterator, Peekable};
use style::computed_values::{border_collapse, border_spacing, border_top_style}; use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode}; use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::computed::{Color, LengthOrPercentageOrAuto}; use style::values::computed::{Color, LengthOrPercentageOrAuto};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow}; use table_cell::{CollapsedBordersForCell, TableCellFlow};
@ -114,7 +114,7 @@ impl TableRowFlow {
/// methods /// methods
#[inline(always)] #[inline(always)]
fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) { fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) {
if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { if self.block_flow.base.restyle_damage.contains(REFLOW) {
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of
// all cells). // all cells).
let mut max_block_size = Au(0); let mut max_block_size = Au(0);
@ -195,7 +195,7 @@ impl TableRowFlow {
} }
} }
self.block_flow.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); self.block_flow.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
} }
pub fn populate_collapsed_border_spacing<'a, I>( pub fn populate_collapsed_border_spacing<'a, I>(

View file

@ -10,7 +10,7 @@ use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer}; use block::{BlockFlow, ISizeAndMarginsComputer};
use context::LayoutContext; use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
use display_list_builder::{StackingContextCollectionFlags, StackingContextCollectionState}; use display_list_builder::{NEVER_CREATES_CONTAINING_BLOCK, StackingContextCollectionState};
use euclid::Point2D; use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow}; use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
@ -184,8 +184,7 @@ impl Flow for TableRowGroupFlow {
} }
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
self.block_flow.collect_stacking_contexts_for_block(state, self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_CONTAINING_BLOCK);
StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK);
} }
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {

View file

@ -17,11 +17,12 @@ use app_units::Au;
use block::{AbsoluteNonReplaced, BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput}; use block::{AbsoluteNonReplaced, BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
use block::{ISizeConstraintSolution, MarginsMayCollapseFlag}; use block::{ISizeConstraintSolution, MarginsMayCollapseFlag};
use context::LayoutContext; use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState, StackingContextCollectionFlags}; use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
use display_list_builder::{NEVER_CREATES_CLIP_SCROLL_NODE, NEVER_CREATES_CONTAINING_BLOCK};
use display_list_builder::StackingContextCollectionState; use display_list_builder::StackingContextCollectionState;
use euclid::Point2D; use euclid::Point2D;
use floats::FloatKind; use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils, FlowFlags, OpaqueFlow}; use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use model::MaybeAuto; use model::MaybeAuto;
@ -255,7 +256,7 @@ impl TableWrapperFlow {
return return
} }
if !self.block_flow.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { if !self.block_flow.base.flags.contains(INLINE_POSITION_IS_STATIC) {
let inline_size_computer = AbsoluteTable { let inline_size_computer = AbsoluteTable {
minimum_width_of_all_columns: minimum_width_of_all_columns, minimum_width_of_all_columns: minimum_width_of_all_columns,
preferred_width_of_all_columns: preferred_width_of_all_columns, preferred_width_of_all_columns: preferred_width_of_all_columns,
@ -463,9 +464,7 @@ impl Flow for TableWrapperFlow {
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
self.block_flow.collect_stacking_contexts_for_block( self.block_flow.collect_stacking_contexts_for_block(
state, state, NEVER_CREATES_CONTAINING_BLOCK | NEVER_CREATES_CLIP_SCROLL_NODE);
StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK |
StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE);
} }
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {

View file

@ -7,14 +7,15 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
use app_units::Au; use app_units::Au;
use fragment::{Fragment, ScannedTextFlags}; use fragment::{Fragment, REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES, ScannedTextFlags};
use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use fragment::{SELECTED, ScannedTextFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::font::{FontMetrics, RunMetrics, ShapingFlags, ShapingOptions}; use gfx::font::{DISABLE_KERNING_SHAPING_FLAG, FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG};
use gfx::font::{KEEP_ALL_FLAG, RTL_FLAG, RunMetrics, ShapingFlags, ShapingOptions};
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use gfx::text::glyph::ByteIndex; use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::TextRun; use gfx::text::text_run::TextRun;
use gfx::text::util::{self, CompressionMode}; use gfx::text::util::{self, CompressionMode};
use inline::{InlineFragmentNodeFlags, InlineFragments}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragments, LAST_FRAGMENT_OF_ELEMENT};
use linked_list::split_off_head; use linked_list::split_off_head;
use ordered_float::NotNaN; use ordered_float::NotNaN;
use range::Range; use range::Range;
@ -290,15 +291,15 @@ impl TextRunScanner {
let mut flags = ShapingFlags::empty(); let mut flags = ShapingFlags::empty();
if let Some(v) = letter_spacing.value() { if let Some(v) = letter_spacing.value() {
if v.px() != 0. { if v.px() != 0. {
flags.insert(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG); flags.insert(IGNORE_LIGATURES_SHAPING_FLAG);
} }
} }
if text_rendering == text_rendering::T::optimizespeed { if text_rendering == text_rendering::T::optimizespeed {
flags.insert(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG); flags.insert(IGNORE_LIGATURES_SHAPING_FLAG);
flags.insert(ShapingFlags::DISABLE_KERNING_SHAPING_FLAG) flags.insert(DISABLE_KERNING_SHAPING_FLAG)
} }
if word_break == word_break::T::keep_all { if word_break == word_break::T::keep_all {
flags.insert(ShapingFlags::KEEP_ALL_FLAG); flags.insert(KEEP_ALL_FLAG);
} }
let options = ShapingOptions { let options = ShapingOptions {
letter_spacing: letter_spacing.value().cloned().map(Au::from), letter_spacing: letter_spacing.value().cloned().map(Au::from),
@ -312,7 +313,7 @@ impl TextRunScanner {
let mut options = options; let mut options = options;
options.script = run_info.script; options.script = run_info.script;
if run_info.bidi_level.is_rtl() { if run_info.bidi_level.is_rtl() {
options.flags.insert(ShapingFlags::RTL_FLAG); options.flags.insert(RTL_FLAG);
} }
let mut font = fontgroup.fonts.get(run_info.font_index).unwrap().borrow_mut(); let mut font = fontgroup.fonts.get(run_info.font_index).unwrap().borrow_mut();
ScannedTextRun { ScannedTextRun {
@ -363,11 +364,11 @@ impl TextRunScanner {
if requires_line_break_afterward_if_wrapping_on_newlines { if requires_line_break_afterward_if_wrapping_on_newlines {
byte_range.extend_by(ByteIndex(-1)); // Trim the '\n' byte_range.extend_by(ByteIndex(-1)); // Trim the '\n'
flags.insert(ScannedTextFlags::REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES); flags.insert(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
} }
if mapping.selected { if mapping.selected {
flags.insert(ScannedTextFlags::SELECTED); flags.insert(SELECTED);
} }
let insertion_point = if mapping.contains_insertion_point(scanned_run.insertion_point) { let insertion_point = if mapping.contains_insertion_point(scanned_run.insertion_point) {
@ -401,10 +402,10 @@ impl TextRunScanner {
if let Some(ref mut context) = new_fragment.inline_context { if let Some(ref mut context) = new_fragment.inline_context {
for node in &mut context.nodes { for node in &mut context.nodes {
if !is_last_mapping_of_this_old_fragment { if !is_last_mapping_of_this_old_fragment {
node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT); node.flags.remove(LAST_FRAGMENT_OF_ELEMENT);
} }
if !is_first_mapping_of_this_old_fragment { if !is_first_mapping_of_this_old_fragment {
node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT); node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
} }
} }
} }

View file

@ -7,14 +7,14 @@
use construct::FlowConstructor; use construct::FlowConstructor;
use context::LayoutContext; use context::LayoutContext;
use display_list_builder::DisplayListBuildState; use display_list_builder::DisplayListBuildState;
use flow::{self, FlowFlags, Flow, ImmutableFlowUtils}; use flow::{self, CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use servo_config::opts; use servo_config::opts;
use style::context::{SharedStyleContext, StyleContext}; use style::context::{SharedStyleContext, StyleContext};
use style::data::ElementData; use style::data::ElementData;
use style::dom::{NodeInfo, TElement, TNode}; use style::dom::{NodeInfo, TElement, TNode};
use style::selector_parser::RestyleDamage; use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION};
use style::traversal::{DomTraversal, recalc_style_at}; use style::traversal::{DomTraversal, recalc_style_at};
use style::traversal::PerLevelTraversalData; use style::traversal::PerLevelTraversalData;
use wrapper::{GetRawData, LayoutNodeLayoutData}; use wrapper::{GetRawData, LayoutNodeLayoutData};
@ -209,7 +209,7 @@ fn construct_flows_at<N>(context: &LayoutContext, node: N)
} }
} }
tnode.mutate_layout_data().unwrap().flags.insert(::data::LayoutDataFlags::HAS_BEEN_TRAVERSED); tnode.mutate_layout_data().unwrap().flags.insert(::data::HAS_BEEN_TRAVERSED);
} }
if let Some(el) = node.as_element() { if let Some(el) = node.as_element() {
@ -227,12 +227,12 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> {
#[inline] #[inline]
fn process(&self, flow: &mut Flow) { fn process(&self, flow: &mut Flow) {
flow.bubble_inline_sizes(); flow.bubble_inline_sizes();
flow::mut_base(flow).restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES); flow::mut_base(flow).restyle_damage.remove(BUBBLE_ISIZES);
} }
#[inline] #[inline]
fn should_process(&self, flow: &mut Flow) -> bool { fn should_process(&self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.contains(ServoRestyleDamage::BUBBLE_ISIZES) flow::base(flow).restyle_damage.contains(BUBBLE_ISIZES)
} }
} }
@ -250,7 +250,7 @@ impl<'a> PreorderFlowTraversal for AssignISizes<'a> {
#[inline] #[inline]
fn should_process(&self, flow: &mut Flow) -> bool { fn should_process(&self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) flow::base(flow).restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW)
} }
} }
@ -280,9 +280,9 @@ impl<'a> PostorderFlowTraversal for AssignBSizes<'a> {
#[inline] #[inline]
fn should_process(&self, flow: &mut Flow) -> bool { fn should_process(&self, flow: &mut Flow) -> bool {
let base = flow::base(flow); let base = flow::base(flow);
base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) && base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) &&
// The fragmentation countainer is responsible for calling Flow::fragment recursively // The fragmentation countainer is responsible for calling Flow::fragment recursively
!base.flags.contains(FlowFlags::CAN_BE_FRAGMENTED) !base.flags.contains(CAN_BE_FRAGMENTED)
} }
} }
@ -293,13 +293,13 @@ pub struct ComputeStackingRelativePositions<'a> {
impl<'a> PreorderFlowTraversal for ComputeStackingRelativePositions<'a> { impl<'a> PreorderFlowTraversal for ComputeStackingRelativePositions<'a> {
#[inline] #[inline]
fn should_process_subtree(&self, flow: &mut Flow) -> bool { fn should_process_subtree(&self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.contains(ServoRestyleDamage::REPOSITION) flow::base(flow).restyle_damage.contains(REPOSITION)
} }
#[inline] #[inline]
fn process(&self, flow: &mut Flow) { fn process(&self, flow: &mut Flow) {
flow.compute_stacking_relative_position(self.layout_context); flow.compute_stacking_relative_position(self.layout_context);
flow::mut_base(flow).restyle_damage.remove(ServoRestyleDamage::REPOSITION) flow::mut_base(flow).restyle_damage.remove(REPOSITION)
} }
} }
@ -318,7 +318,7 @@ impl<'a> BuildDisplayList<'a> {
flow.clip_and_scroll_info(self.state.layout_context.id); flow.clip_and_scroll_info(self.state.layout_context.id);
flow.build_display_list(&mut self.state); flow.build_display_list(&mut self.state);
flow::mut_base(flow).restyle_damage.remove(ServoRestyleDamage::REPAINT); flow::mut_base(flow).restyle_damage.remove(REPAINT);
for kid in flow::child_iter_mut(flow) { for kid in flow::child_iter_mut(flow) {
self.traverse(kid); self.traverse(kid);

View file

@ -140,7 +140,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
let damage = { let damage = {
let data = node.get_raw_data().unwrap(); let data = node.get_raw_data().unwrap();
if !data.layout_data.borrow().flags.contains(::data::LayoutDataFlags::HAS_BEEN_TRAVERSED) { if !data.layout_data.borrow().flags.contains(::data::HAS_BEEN_TRAVERSED) {
// We're reflowing a node that was styled for the first time and // We're reflowing a node that was styled for the first time and
// has never been visited by layout. Return rebuild_and_reflow, // has never been visited by layout. Return rebuild_and_reflow,
// because that's what the code expects. // because that's what the code expects.

View file

@ -38,11 +38,13 @@ use layout::wrapper::GetRawData;
use msg::constellation_msg::{BrowsingContextId, PipelineId}; use msg::constellation_msg::{BrowsingContextId, PipelineId};
use nonzero::NonZero; use nonzero::NonZero;
use range::Range; use range::Range;
use script::layout_exports::{CAN_BE_FRAGMENTED, HAS_DIRTY_DESCENDANTS, IS_IN_DOC};
use script::layout_exports::{CharacterDataTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId}; use script::layout_exports::{CharacterDataTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use script::layout_exports::{Document, Element, Node, Text}; use script::layout_exports::{Document, Element, Node, Text};
use script::layout_exports::{HANDLED_SNAPSHOT, HAS_SNAPSHOT};
use script::layout_exports::{LayoutCharacterDataHelpers, LayoutDocumentHelpers}; use script::layout_exports::{LayoutCharacterDataHelpers, LayoutDocumentHelpers};
use script::layout_exports::{LayoutElementHelpers, LayoutNodeHelpers, LayoutDom, RawLayoutElementHelpers}; use script::layout_exports::{LayoutElementHelpers, LayoutNodeHelpers, RawLayoutElementHelpers};
use script::layout_exports::NodeFlags; use script::layout_exports::LayoutDom;
use script::layout_exports::PendingRestyle; use script::layout_exports::PendingRestyle;
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress}; use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
use script_layout_interface::{OpaqueStyleAndLayoutData, StyleData}; use script_layout_interface::{OpaqueStyleAndLayoutData, StyleData};
@ -205,11 +207,11 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
} }
fn can_be_fragmented(&self) -> bool { fn can_be_fragmented(&self) -> bool {
unsafe { self.node.get_flag(NodeFlags::CAN_BE_FRAGMENTED) } unsafe { self.node.get_flag(CAN_BE_FRAGMENTED) }
} }
unsafe fn set_can_be_fragmented(&self, value: bool) { unsafe fn set_can_be_fragmented(&self, value: bool) {
self.node.set_flag(NodeFlags::CAN_BE_FRAGMENTED, value) self.node.set_flag(CAN_BE_FRAGMENTED, value)
} }
} }
@ -396,28 +398,28 @@ impl<'le> TElement for ServoLayoutElement<'le> {
} }
fn has_dirty_descendants(&self) -> bool { fn has_dirty_descendants(&self) -> bool {
unsafe { self.as_node().node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) } unsafe { self.as_node().node.get_flag(HAS_DIRTY_DESCENDANTS) }
} }
fn has_snapshot(&self) -> bool { fn has_snapshot(&self) -> bool {
unsafe { self.as_node().node.get_flag(NodeFlags::HAS_SNAPSHOT) } unsafe { self.as_node().node.get_flag(HAS_SNAPSHOT) }
} }
fn handled_snapshot(&self) -> bool { fn handled_snapshot(&self) -> bool {
unsafe { self.as_node().node.get_flag(NodeFlags::HANDLED_SNAPSHOT) } unsafe { self.as_node().node.get_flag(HANDLED_SNAPSHOT) }
} }
unsafe fn set_handled_snapshot(&self) { unsafe fn set_handled_snapshot(&self) {
self.as_node().node.set_flag(NodeFlags::HANDLED_SNAPSHOT, true); self.as_node().node.set_flag(HANDLED_SNAPSHOT, true);
} }
unsafe fn set_dirty_descendants(&self) { unsafe fn set_dirty_descendants(&self) {
debug_assert!(self.as_node().node.get_flag(NodeFlags::IS_IN_DOC)); debug_assert!(self.as_node().node.get_flag(IS_IN_DOC));
self.as_node().node.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, true) self.as_node().node.set_flag(HAS_DIRTY_DESCENDANTS, true)
} }
unsafe fn unset_dirty_descendants(&self) { unsafe fn unset_dirty_descendants(&self) {
self.as_node().node.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, false) self.as_node().node.set_flag(HAS_DIRTY_DESCENDANTS, false)
} }
fn store_children_to_process(&self, n: isize) { fn store_children_to_process(&self, n: isize) {
@ -563,11 +565,11 @@ impl<'le> ServoLayoutElement<'le> {
} }
pub unsafe fn unset_snapshot_flags(&self) { pub unsafe fn unset_snapshot_flags(&self) {
self.as_node().node.set_flag(NodeFlags::HAS_SNAPSHOT | NodeFlags::HANDLED_SNAPSHOT, false); self.as_node().node.set_flag(HAS_SNAPSHOT | HANDLED_SNAPSHOT, false);
} }
pub unsafe fn set_has_snapshot(&self) { pub unsafe fn set_has_snapshot(&self) {
self.as_node().node.set_flag(NodeFlags::HAS_SNAPSHOT, true); self.as_node().node.set_flag(HAS_SNAPSHOT, true);
} }
pub unsafe fn note_dirty_descendant(&self) { pub unsafe fn note_dirty_descendant(&self) {

View file

@ -72,7 +72,7 @@ use layout::context::malloc_size_of_persistent_local_context;
use layout::display_list_builder::ToGfxColor; use layout::display_list_builder::ToGfxColor;
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow_ref::FlowRef; use layout::flow_ref::FlowRef;
use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage}; use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT, RelayoutMode};
use layout::layout_debug; use layout::layout_debug;
use layout::parallel; use layout::parallel;
use layout::query::{LayoutRPCImpl, LayoutThreadData, process_content_box_request, process_content_boxes_request}; use layout::query::{LayoutRPCImpl, LayoutThreadData, process_content_box_request, process_content_boxes_request};
@ -132,11 +132,11 @@ use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaList, MediaType}; use style::media_queries::{Device, MediaList, MediaType};
use style::properties::PropertyId; use style::properties::PropertyId;
use style::selector_parser::SnapshotMap; use style::selector_parser::SnapshotMap;
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards}; use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
use style::stylesheets::{Origin, Stylesheet, DocumentStyleSheet, StylesheetInDocument, UserAgentStylesheets}; use style::stylesheets::{Origin, Stylesheet, DocumentStyleSheet, StylesheetInDocument, UserAgentStylesheets};
use style::stylist::Stylist; use style::stylist::Stylist;
use style::thread_state::{self, ThreadState}; use style::thread_state;
use style::timer::Timer; use style::timer::Timer;
use style::traversal::DomTraversal; use style::traversal::DomTraversal;
use style::traversal_flags::TraversalFlags; use style::traversal_flags::TraversalFlags;
@ -285,7 +285,7 @@ impl LayoutThreadFactory for LayoutThread {
layout_threads: usize, layout_threads: usize,
paint_time_metrics: PaintTimeMetrics) { paint_time_metrics: PaintTimeMetrics) {
thread::Builder::new().name(format!("LayoutThread {:?}", id)).spawn(move || { thread::Builder::new().name(format!("LayoutThread {:?}", id)).spawn(move || {
thread_state::initialize(ThreadState::LAYOUT); thread_state::initialize(thread_state::LAYOUT);
// In order to get accurate crash reports, we install the top-level bc id. // In order to get accurate crash reports, we install the top-level bc id.
TopLevelBrowsingContextId::install(top_level_browsing_context_id); TopLevelBrowsingContextId::install(top_level_browsing_context_id);
@ -975,7 +975,7 @@ impl LayoutThread {
let traversal = ComputeStackingRelativePositions { layout_context: layout_context }; let traversal = ComputeStackingRelativePositions { layout_context: layout_context };
traversal.traverse(layout_root); traversal.traverse(layout_root);
if flow::base(layout_root).restyle_damage.contains(ServoRestyleDamage::REPAINT) || if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
rw_data.display_list.is_none() { rw_data.display_list.is_none() {
if reflow_goal.needs_display_list() { if reflow_goal.needs_display_list() {
let mut build_state = let mut build_state =
@ -1545,7 +1545,7 @@ impl LayoutThread {
// that are needed in both incremental and non-incremental traversals. // that are needed in both incremental and non-incremental traversals.
let damage = FlowRef::deref_mut(root_flow).compute_layout_damage(); let damage = FlowRef::deref_mut(root_flow).compute_layout_damage();
if opts::get().nonincremental_layout || damage.contains(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT) { if opts::get().nonincremental_layout || damage.contains(REFLOW_ENTIRE_DOCUMENT) {
FlowRef::deref_mut(root_flow).reflow_entire_document() FlowRef::deref_mut(root_flow).reflow_entire_document()
} }
}); });
@ -1568,8 +1568,7 @@ impl LayoutThread {
// Perform the primary layout passes over the flow tree to compute the locations of all // Perform the primary layout passes over the flow tree to compute the locations of all
// the boxes. // the boxes.
if flow::base(&**root_flow).restyle_damage.intersects(ServoRestyleDamage::REFLOW | if flow::base(&**root_flow).restyle_damage.intersects(REFLOW | REFLOW_OUT_OF_FLOW) {
ServoRestyleDamage::REFLOW_OUT_OF_FLOW) {
profile(time::ProfilerCategory::LayoutMain, profile(time::ProfilerCategory::LayoutMain,
self.profiler_metadata(), self.profiler_metadata(),
self.time_profiler_chan.clone(), self.time_profiler_chan.clone(),
@ -1636,8 +1635,7 @@ impl LayoutThread {
debug!("reflowing all nodes!"); debug!("reflowing all nodes!");
flow::mut_base(flow) flow::mut_base(flow)
.restyle_damage .restyle_damage
.insert(ServoRestyleDamage::REPAINT | ServoRestyleDamage::STORE_OVERFLOW | .insert(REPAINT | STORE_OVERFLOW | REFLOW | REPOSITION);
ServoRestyleDamage::REFLOW | ServoRestyleDamage::REPOSITION);
for child in flow::child_iter_mut(flow) { for child in flow::child_iter_mut(flow) {
LayoutThread::reflow_all_nodes(child); LayoutThread::reflow_all_nodes(child);

View file

@ -13,7 +13,7 @@ path = "lib.rs"
unstable = ["nonzero/unstable"] unstable = ["nonzero/unstable"]
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "0.7"
malloc_size_of = { path = "../malloc_size_of" } malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" } malloc_size_of_derive = { path = "../malloc_size_of_derive" }
nonzero = {path = "../nonzero"} nonzero = {path = "../nonzero"}

View file

@ -148,12 +148,12 @@ pub enum Key {
bitflags! { bitflags! {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct KeyModifiers: u8 { pub flags KeyModifiers: u8 {
const NONE = 0x00; const NONE = 0x00,
const SHIFT = 0x01; const SHIFT = 0x01,
const CONTROL = 0x02; const CONTROL = 0x02,
const ALT = 0x04; const ALT = 0x04,
const SUPER = 0x08; const SUPER = 0x08,
} }
} }

View file

@ -28,7 +28,7 @@ tinyfiledialogs = "2.5.9"
app_units = "0.5" app_units = "0.5"
audio-video-metadata = "0.1.4" audio-video-metadata = "0.1.4"
base64 = "0.6" base64 = "0.6"
bitflags = "1.0" bitflags = "0.7"
bluetooth_traits = {path = "../bluetooth_traits"} bluetooth_traits = {path = "../bluetooth_traits"}
byteorder = "1.0" byteorder = "1.0"
canvas_traits = {path = "../canvas_traits"} canvas_traits = {path = "../canvas_traits"}

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use devtools_traits::{AutoMargins, CachedConsoleMessage, CachedConsoleMessageTypes}; use devtools_traits::{AutoMargins, CONSOLE_API, CachedConsoleMessage, CachedConsoleMessageTypes};
use devtools_traits::{ComputedNodeLayout, ConsoleAPI, PageError}; use devtools_traits::{ComputedNodeLayout, ConsoleAPI, PageError};
use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, TimelineMarker}; use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, PAGE_ERROR, TimelineMarker};
use devtools_traits::TimelineMarkerType; use devtools_traits::TimelineMarkerType;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods; use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
@ -168,7 +168,7 @@ pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
reply: IpcSender<Vec<CachedConsoleMessage>>) { reply: IpcSender<Vec<CachedConsoleMessage>>) {
// TODO: check the messageTypes against a global Cache for console messages and page exceptions // TODO: check the messageTypes against a global Cache for console messages and page exceptions
let mut messages = Vec::new(); let mut messages = Vec::new();
if message_types.contains(CachedConsoleMessageTypes::PAGE_ERROR) { if message_types.contains(PAGE_ERROR) {
// TODO: make script error reporter pass all reported errors // TODO: make script error reporter pass all reported errors
// to devtools and cache them for returning here. // to devtools and cache them for returning here.
let msg = PageError { let msg = PageError {
@ -188,7 +188,7 @@ pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
}; };
messages.push(CachedConsoleMessage::PageError(msg)); messages.push(CachedConsoleMessage::PageError(msg));
} }
if message_types.contains(CachedConsoleMessageTypes::CONSOLE_API) { if message_types.contains(CONSOLE_API) {
// TODO: do for real // TODO: do for real
let msg = ConsoleAPI { let msg = ConsoleAPI {
type_: "ConsoleAPI".to_owned(), type_: "ConsoleAPI".to_owned(),

View file

@ -5,7 +5,7 @@
//! A shareable mutable container for the DOM. //! A shareable mutable container for the DOM.
use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut}; use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
use style::thread_state::{self, ThreadState}; use style::thread_state;
/// A mutable field in the DOM. /// A mutable field in the DOM.
/// ///
@ -45,7 +45,7 @@ impl<T> DomRefCell<T> {
/// ///
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T { pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T {
debug_assert!(thread_state::get().contains(ThreadState::SCRIPT)); debug_assert!(thread_state::get().contains(thread_state::SCRIPT));
&mut *self.value.as_ptr() &mut *self.value.as_ptr()
} }

View file

@ -2039,7 +2039,7 @@ DOMClass {
interface_chain: [ %s ], interface_chain: [ %s ],
type_id: %s, type_id: %s,
malloc_size_of: %s as unsafe fn(&mut _, _) -> _, malloc_size_of: %s as unsafe fn(&mut _, _) -> _,
global: InterfaceObjectMap::Globals::%s, global: InterfaceObjectMap::%s,
}""" % (prototypeChainString, DOMClassTypeId(descriptor), mallocSizeOf, globals_) }""" % (prototypeChainString, DOMClassTypeId(descriptor), mallocSizeOf, globals_)
@ -2445,7 +2445,7 @@ class CGConstructorEnabled(CGAbstractMethod):
iface = self.descriptor.interface iface = self.descriptor.interface
bits = " | ".join(sorted( bits = " | ".join(sorted(
"InterfaceObjectMap::Globals::" + camel_to_upper_snake(i) for i in iface.exposureSet "InterfaceObjectMap::" + camel_to_upper_snake(i) for i in iface.exposureSet
)) ))
conditions.append("is_exposed_in(aObj, %s)" % bits) conditions.append("is_exposed_in(aObj, %s)" % bits)
@ -7092,9 +7092,9 @@ class GlobalGenRoots():
for (idx, d) in enumerate(global_descriptors) for (idx, d) in enumerate(global_descriptors)
) )
global_flags = CGWrapper(CGIndenter(CGList([ global_flags = CGWrapper(CGIndenter(CGList([
CGGeneric("const %s = %#x;" % args) CGGeneric("const %s = %#x," % args)
for args in flags for args in flags
], "\n")), pre="pub struct Globals: u8 {\n", post="\n}") ], "\n")), pre="pub flags Globals: u8 {\n", post="\n}")
globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}") globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}")
phf = CGGeneric("include!(concat!(env!(\"OUT_DIR\"), \"/InterfaceObjectMapPhf.rs\"));") phf = CGGeneric("include!(concat!(env!(\"OUT_DIR\"), \"/InterfaceObjectMapPhf.rs\"));")

View file

@ -13,7 +13,7 @@ use style::context::QuirksMode;
use style::parser::ParserContext; use style::parser::ParserContext;
use style::stylesheets::CssRuleType; use style::stylesheets::CssRuleType;
use style::stylesheets::supports_rule::{Declaration, parse_condition_or_declaration}; use style::stylesheets::supports_rule::{Declaration, parse_condition_or_declaration};
use style_traits::ParsingMode; use style_traits::PARSING_MODE_DEFAULT;
#[dom_struct] #[dom_struct]
pub struct CSS { pub struct CSS {
@ -39,7 +39,7 @@ impl CSS {
let context = ParserContext::new_for_cssom( let context = ParserContext::new_for_cssom(
&url, &url,
Some(CssRuleType::Style), Some(CssRuleType::Style),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
QuirksMode::NoQuirks QuirksMode::NoQuirks
); );
decl.eval(&context) decl.eval(&context)
@ -55,7 +55,7 @@ impl CSS {
let context = ParserContext::new_for_cssom( let context = ParserContext::new_for_cssom(
&url, &url,
Some(CssRuleType::Style), Some(CssRuleType::Style),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
QuirksMode::NoQuirks QuirksMode::NoQuirks
); );
cond.eval(&context) cond.eval(&context)

View file

@ -20,7 +20,7 @@ use style::media_queries::parse_media_query_list;
use style::parser::ParserContext; use style::parser::ParserContext;
use style::shared_lock::{Locked, ToCssWithGuard}; use style::shared_lock::{Locked, ToCssWithGuard};
use style::stylesheets::{CssRuleType, MediaRule}; use style::stylesheets::{CssRuleType, MediaRule};
use style_traits::{ParsingMode, ToCss}; use style_traits::{PARSING_MODE_DEFAULT, ToCss};
#[dom_struct] #[dom_struct]
pub struct CSSMediaRule { pub struct CSSMediaRule {
@ -76,7 +76,7 @@ impl CSSMediaRule {
let url = window.get_url(); let url = window.get_url();
let quirks_mode = window.Document().quirks_mode(); let quirks_mode = window.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
let new_medialist = parse_media_query_list(&context, &mut input, let new_medialist = parse_media_query_list(&context, &mut input,

View file

@ -22,7 +22,7 @@ use style::properties::{DeclarationSource, Importance, PropertyDeclarationBlock,
use style::properties::{parse_one_declaration_into, parse_style_attribute, SourcePropertyDeclaration}; use style::properties::{parse_one_declaration_into, parse_style_attribute, SourcePropertyDeclaration};
use style::selector_parser::PseudoElement; use style::selector_parser::PseudoElement;
use style::shared_lock::Locked; use style::shared_lock::Locked;
use style_traits::{ParsingMode, ToCss}; use style_traits::{PARSING_MODE_DEFAULT, ToCss};
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface // http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
#[dom_struct] #[dom_struct]
@ -261,7 +261,7 @@ impl CSSStyleDeclaration {
let mut declarations = SourcePropertyDeclaration::new(); let mut declarations = SourcePropertyDeclaration::new();
let result = parse_one_declaration_into( let result = parse_one_declaration_into(
&mut declarations, id, &value, &self.owner.base_url(), &mut declarations, id, &value, &self.owner.base_url(),
window.css_error_reporter(), ParsingMode::DEFAULT, quirks_mode); window.css_error_reporter(), PARSING_MODE_DEFAULT, quirks_mode);
// Step 6 // Step 6
match result { match result {

View file

@ -18,7 +18,7 @@ use style::parser::ParserContext;
use style::shared_lock::{Locked, ToCssWithGuard}; use style::shared_lock::{Locked, ToCssWithGuard};
use style::stylesheets::{CssRuleType, SupportsRule}; use style::stylesheets::{CssRuleType, SupportsRule};
use style::stylesheets::supports_rule::SupportsCondition; use style::stylesheets::supports_rule::SupportsCondition;
use style_traits::{ParsingMode, ToCss}; use style_traits::{PARSING_MODE_DEFAULT, ToCss};
#[dom_struct] #[dom_struct]
pub struct CSSSupportsRule { pub struct CSSSupportsRule {
@ -64,7 +64,7 @@ impl CSSSupportsRule {
let url = win.Document().url(); let url = win.Document().url();
let quirks_mode = win.Document().quirks_mode(); let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Supports), let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Supports),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
let enabled = cond.eval(&context); let enabled = cond.eval(&context);
let mut guard = self.cssconditionrule.shared_lock().write(); let mut guard = self.cssconditionrule.shared_lock().write();

View file

@ -42,7 +42,7 @@ use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
use std::thread; use std::thread;
use style::thread_state::{self, ThreadState}; use style::thread_state;
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular /// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
/// value for the duration of this object's lifetime. This ensures that the related Worker /// value for the duration of this object's lifetime. This ensures that the related Worker
@ -167,7 +167,7 @@ impl DedicatedWorkerGlobalScope {
let origin = GlobalScope::current().expect("No current global object").origin().immutable().clone(); let origin = GlobalScope::current().expect("No current global object").origin().immutable().clone();
thread::Builder::new().name(name).spawn(move || { thread::Builder::new().name(name).spawn(move || {
thread_state::initialize(ThreadState::SCRIPT | ThreadState::IN_WORKER); thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER);
if let Some(top_level_browsing_context_id) = top_level_browsing_context_id { if let Some(top_level_browsing_context_id) = top_level_browsing_context_id {
TopLevelBrowsingContextId::install(top_level_browsing_context_id); TopLevelBrowsingContextId::install(top_level_browsing_context_id);

View file

@ -66,7 +66,7 @@ use dom::keyboardevent::KeyboardEvent;
use dom::location::Location; use dom::location::Location;
use dom::messageevent::MessageEvent; use dom::messageevent::MessageEvent;
use dom::mouseevent::MouseEvent; use dom::mouseevent::MouseEvent;
use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node, NodeFlags, LayoutNodeHelpers}; use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node, IS_IN_DOC, LayoutNodeHelpers};
use dom::node::VecPreOrderInsertionHelper; use dom::node::VecPreOrderInsertionHelper;
use dom::nodeiterator::NodeIterator; use dom::nodeiterator::NodeIterator;
use dom::nodelist::NodeList; use dom::nodelist::NodeList;
@ -99,6 +99,7 @@ use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSRuntime}; use js::jsapi::{JSContext, JSRuntime};
use js::jsapi::JS_GetRuntime; use js::jsapi::JS_GetRuntime;
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{BrowsingContextId, Key, KeyModifiers, KeyState, TopLevelBrowsingContextId}; use msg::constellation_msg::{BrowsingContextId, Key, KeyModifiers, KeyState, TopLevelBrowsingContextId};
use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy}; use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy};
use net_traits::CookieSource::NonHTTP; use net_traits::CookieSource::NonHTTP;
@ -129,7 +130,7 @@ use std::rc::Rc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use style::attr::AttrValue; use style::attr::AttrValue;
use style::context::QuirksMode; use style::context::QuirksMode;
use style::invalidation::element::restyle_hints::RestyleHint; use style::invalidation::element::restyle_hints::{RestyleHint, RESTYLE_SELF, RESTYLE_STYLE_ATTRIBUTE};
use style::media_queries::{Device, MediaList, MediaType}; use style::media_queries::{Device, MediaList, MediaType};
use style::selector_parser::{RestyleDamage, Snapshot}; use style::selector_parser::{RestyleDamage, Snapshot};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard}; use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard};
@ -1275,10 +1276,10 @@ impl Document {
(&None, &None) => self.window.upcast(), (&None, &None) => self.window.upcast(),
}; };
let ctrl = modifiers.contains(KeyModifiers::CONTROL); let ctrl = modifiers.contains(CONTROL);
let alt = modifiers.contains(KeyModifiers::ALT); let alt = modifiers.contains(ALT);
let shift = modifiers.contains(KeyModifiers::SHIFT); let shift = modifiers.contains(SHIFT);
let meta = modifiers.contains(KeyModifiers::SUPER); let meta = modifiers.contains(SUPER);
let is_composing = false; let is_composing = false;
let is_repeating = state == KeyState::Repeated; let is_repeating = state == KeyState::Repeated;
@ -2018,7 +2019,7 @@ impl LayoutDocumentHelpers for LayoutDom<Document> {
// may no longer be true when the next layout occurs. // may no longer be true when the next layout occurs.
let result = elements.drain() let result = elements.drain()
.map(|(k, v)| (k.to_layout(), v)) .map(|(k, v)| (k.to_layout(), v))
.filter(|&(ref k, _)| k.upcast::<Node>().get_flag(NodeFlags::IS_IN_DOC)) .filter(|&(ref k, _)| k.upcast::<Node>().get_flag(IS_IN_DOC))
.collect(); .collect();
result result
} }
@ -2465,11 +2466,11 @@ impl Document {
entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document())); entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document()));
} }
if attr.local_name() == &local_name!("style") { if attr.local_name() == &local_name!("style") {
entry.hint.insert(RestyleHint::RESTYLE_STYLE_ATTRIBUTE); entry.hint.insert(RESTYLE_STYLE_ATTRIBUTE);
} }
if vtable_for(el.upcast()).attribute_affects_presentational_hints(attr) { if vtable_for(el.upcast()).attribute_affects_presentational_hints(attr) {
entry.hint.insert(RestyleHint::RESTYLE_SELF); entry.hint.insert(RESTYLE_SELF);
} }
let snapshot = entry.snapshot.as_mut().unwrap(); let snapshot = entry.snapshot.as_mut().unwrap();

View file

@ -65,8 +65,8 @@ use dom::htmltemplateelement::HTMLTemplateElement;
use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers}; use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers};
use dom::mutationobserver::{Mutation, MutationObserver}; use dom::mutationobserver::{Mutation, MutationObserver};
use dom::namednodemap::NamedNodeMap; use dom::namednodemap::NamedNodeMap;
use dom::node::{ChildrenMutation, LayoutNodeHelpers, Node}; use dom::node::{CLICK_IN_PROGRESS, ChildrenMutation, LayoutNodeHelpers, Node};
use dom::node::{NodeDamage, NodeFlags, UnbindContext}; use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE, UnbindContext};
use dom::node::{document_from_node, window_from_node}; use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList; use dom::nodelist::NodeList;
use dom::promise::Promise; use dom::promise::Promise;
@ -90,6 +90,7 @@ use script_thread::ScriptThread;
use selectors::Element as SelectorsElement; use selectors::Element as SelectorsElement;
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
use selectors::matching::{ElementSelectorFlags, MatchingContext, RelevantLinkStatus}; use selectors::matching::{ElementSelectorFlags, MatchingContext, RelevantLinkStatus};
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
use selectors::sink::Push; use selectors::sink::Push;
use servo_arc::Arc; use servo_arc::Arc;
use servo_atoms::Atom; use servo_atoms::Atom;
@ -106,8 +107,8 @@ use style::applicable_declarations::ApplicableDeclarationBlock;
use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::attr::{AttrValue, LengthOrPercentageOrAuto};
use style::context::QuirksMode; use style::context::QuirksMode;
use style::dom_apis; use style::dom_apis;
use style::element_state::ElementState; use style::element_state::*;
use style::invalidation::element::restyle_hints::RestyleHint; use style::invalidation::element::restyle_hints::RESTYLE_SELF;
use style::properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x}; use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x};
use style::rule_tree::CascadeLevel; use style::rule_tree::CascadeLevel;
@ -291,7 +292,7 @@ impl Element {
// FIXME(bholley): I think we should probably only do this for // FIXME(bholley): I think we should probably only do this for
// NodeStyleDamaged, but I'm preserving existing behavior. // NodeStyleDamaged, but I'm preserving existing behavior.
restyle.hint.insert(RestyleHint::RESTYLE_SELF); restyle.hint.insert(RESTYLE_SELF);
if damage == NodeDamage::OtherNodeDamage { if damage == NodeDamage::OtherNodeDamage {
restyle.damage = RestyleDamage::rebuild_and_reflow(); restyle.damage = RestyleDamage::rebuild_and_reflow();
@ -1068,7 +1069,7 @@ impl Element {
} }
// TODO: Check whether the element is being rendered (i.e. not hidden). // TODO: Check whether the element is being rendered (i.e. not hidden).
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
if node.get_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE) { if node.get_flag(SEQUENTIALLY_FOCUSABLE) {
return true; return true;
} }
// https://html.spec.whatwg.org/multipage/#specially-focusable // https://html.spec.whatwg.org/multipage/#specially-focusable
@ -2486,11 +2487,11 @@ impl VirtualMethods for Element {
} }
let flags = self.selector_flags.get(); let flags = self.selector_flags.get();
if flags.intersects(ElementSelectorFlags::HAS_SLOW_SELECTOR) { if flags.intersects(HAS_SLOW_SELECTOR) {
// All children of this node need to be restyled when any child changes. // All children of this node need to be restyled when any child changes.
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
} else { } else {
if flags.intersects(ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS) { if flags.intersects(HAS_SLOW_SELECTOR_LATER_SIBLINGS) {
if let Some(next_child) = mutation.next_child() { if let Some(next_child) = mutation.next_child() {
for child in next_child.inclusively_following_siblings() { for child in next_child.inclusively_following_siblings() {
if child.is::<Element>() { if child.is::<Element>() {
@ -2499,7 +2500,7 @@ impl VirtualMethods for Element {
} }
} }
} }
if flags.intersects(ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR) { if flags.intersects(HAS_EDGE_CHILD_SELECTOR) {
if let Some(child) = mutation.modified_edge_element() { if let Some(child) = mutation.modified_edge_element() {
child.dirty(NodeDamage::OtherNodeDamage); child.dirty(NodeDamage::OtherNodeDamage);
} }
@ -2753,11 +2754,11 @@ impl Element {
} }
pub fn click_in_progress(&self) -> bool { pub fn click_in_progress(&self) -> bool {
self.upcast::<Node>().get_flag(NodeFlags::CLICK_IN_PROGRESS) self.upcast::<Node>().get_flag(CLICK_IN_PROGRESS)
} }
pub fn set_click_in_progress(&self, click: bool) { pub fn set_click_in_progress(&self, click: bool) {
self.upcast::<Node>().set_flag(NodeFlags::CLICK_IN_PROGRESS, click) self.upcast::<Node>().set_flag(CLICK_IN_PROGRESS, click)
} }
// https://html.spec.whatwg.org/multipage/#nearest-activatable-element // https://html.spec.whatwg.org/multipage/#nearest-activatable-element
@ -2857,12 +2858,12 @@ impl Element {
} }
pub fn active_state(&self) -> bool { pub fn active_state(&self) -> bool {
self.state.get().contains(ElementState::IN_ACTIVE_STATE) self.state.get().contains(IN_ACTIVE_STATE)
} }
/// <https://html.spec.whatwg.org/multipage/#concept-selector-active> /// <https://html.spec.whatwg.org/multipage/#concept-selector-active>
pub fn set_active_state(&self, value: bool) { pub fn set_active_state(&self, value: bool) {
self.set_state(ElementState::IN_ACTIVE_STATE, value); self.set_state(IN_ACTIVE_STATE, value);
if let Some(parent) = self.upcast::<Node>().GetParentElement() { if let Some(parent) = self.upcast::<Node>().GetParentElement() {
parent.set_active_state(value); parent.set_active_state(value);
@ -2870,71 +2871,71 @@ impl Element {
} }
pub fn focus_state(&self) -> bool { pub fn focus_state(&self) -> bool {
self.state.get().contains(ElementState::IN_FOCUS_STATE) self.state.get().contains(IN_FOCUS_STATE)
} }
pub fn set_focus_state(&self, value: bool) { pub fn set_focus_state(&self, value: bool) {
self.set_state(ElementState::IN_FOCUS_STATE, value); self.set_state(IN_FOCUS_STATE, value);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
} }
pub fn hover_state(&self) -> bool { pub fn hover_state(&self) -> bool {
self.state.get().contains(ElementState::IN_HOVER_STATE) self.state.get().contains(IN_HOVER_STATE)
} }
pub fn set_hover_state(&self, value: bool) { pub fn set_hover_state(&self, value: bool) {
self.set_state(ElementState::IN_HOVER_STATE, value) self.set_state(IN_HOVER_STATE, value)
} }
pub fn enabled_state(&self) -> bool { pub fn enabled_state(&self) -> bool {
self.state.get().contains(ElementState::IN_ENABLED_STATE) self.state.get().contains(IN_ENABLED_STATE)
} }
pub fn set_enabled_state(&self, value: bool) { pub fn set_enabled_state(&self, value: bool) {
self.set_state(ElementState::IN_ENABLED_STATE, value) self.set_state(IN_ENABLED_STATE, value)
} }
pub fn disabled_state(&self) -> bool { pub fn disabled_state(&self) -> bool {
self.state.get().contains(ElementState::IN_DISABLED_STATE) self.state.get().contains(IN_DISABLED_STATE)
} }
pub fn set_disabled_state(&self, value: bool) { pub fn set_disabled_state(&self, value: bool) {
self.set_state(ElementState::IN_DISABLED_STATE, value) self.set_state(IN_DISABLED_STATE, value)
} }
pub fn read_write_state(&self) -> bool { pub fn read_write_state(&self) -> bool {
self.state.get().contains(ElementState::IN_READ_WRITE_STATE) self.state.get().contains(IN_READ_WRITE_STATE)
} }
pub fn set_read_write_state(&self, value: bool) { pub fn set_read_write_state(&self, value: bool) {
self.set_state(ElementState::IN_READ_WRITE_STATE, value) self.set_state(IN_READ_WRITE_STATE, value)
} }
pub fn placeholder_shown_state(&self) -> bool { pub fn placeholder_shown_state(&self) -> bool {
self.state.get().contains(ElementState::IN_PLACEHOLDER_SHOWN_STATE) self.state.get().contains(IN_PLACEHOLDER_SHOWN_STATE)
} }
pub fn set_placeholder_shown_state(&self, value: bool) { pub fn set_placeholder_shown_state(&self, value: bool) {
if self.placeholder_shown_state() != value { if self.placeholder_shown_state() != value {
self.set_state(ElementState::IN_PLACEHOLDER_SHOWN_STATE, value); self.set_state(IN_PLACEHOLDER_SHOWN_STATE, value);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
} }
} }
pub fn target_state(&self) -> bool { pub fn target_state(&self) -> bool {
self.state.get().contains(ElementState::IN_TARGET_STATE) self.state.get().contains(IN_TARGET_STATE)
} }
pub fn set_target_state(&self, value: bool) { pub fn set_target_state(&self, value: bool) {
self.set_state(ElementState::IN_TARGET_STATE, value) self.set_state(IN_TARGET_STATE, value)
} }
pub fn fullscreen_state(&self) -> bool { pub fn fullscreen_state(&self) -> bool {
self.state.get().contains(ElementState::IN_FULLSCREEN_STATE) self.state.get().contains(IN_FULLSCREEN_STATE)
} }
pub fn set_fullscreen_state(&self, value: bool) { pub fn set_fullscreen_state(&self, value: bool) {
self.set_state(ElementState::IN_FULLSCREEN_STATE, value) self.set_state(IN_FULLSCREEN_STATE, value)
} }
/// <https://dom.spec.whatwg.org/#connected> /// <https://dom.spec.whatwg.org/#connected>

View file

@ -27,7 +27,7 @@ use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix}; use html5ever::{LocalName, Prefix};
use std::cell::Cell; use std::cell::Cell;
use std::default::Default; use std::default::Default;
use style::element_state::ElementState; use style::element_state::*;
#[derive(Clone, Copy, JSTraceable, PartialEq)] #[derive(Clone, Copy, JSTraceable, PartialEq)]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -51,7 +51,7 @@ impl HTMLButtonElement {
document: &Document) -> HTMLButtonElement { document: &Document) -> HTMLButtonElement {
HTMLButtonElement { HTMLButtonElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
local_name, prefix, document), local_name, prefix, document),
button_type: Cell::new(ButtonType::Submit), button_type: Cell::new(ButtonType::Submit),
form_owner: Default::default(), form_owner: Default::default(),

View file

@ -24,7 +24,7 @@ use dom::htmlframesetelement::HTMLFrameSetElement;
use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmlinputelement::HTMLInputElement; use dom::htmlinputelement::HTMLInputElement;
use dom::htmllabelelement::HTMLLabelElement; use dom::htmllabelelement::HTMLLabelElement;
use dom::node::{Node, NodeFlags}; use dom::node::{Node, SEQUENTIALLY_FOCUSABLE};
use dom::node::{document_from_node, window_from_node}; use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList; use dom::nodelist::NodeList;
use dom::virtualmethods::VirtualMethods; use dom::virtualmethods::VirtualMethods;
@ -76,18 +76,18 @@ impl HTMLElement {
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
if element.has_attribute(&local_name!("tabindex")) { if element.has_attribute(&local_name!("tabindex")) {
node.set_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE, true); node.set_flag(SEQUENTIALLY_FOCUSABLE, true);
} else { } else {
match node.type_id() { match node.type_id() {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement))
=> node.set_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE, true), => node.set_flag(SEQUENTIALLY_FOCUSABLE, true),
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => {
if element.has_attribute(&local_name!("href")) { if element.has_attribute(&local_name!("href")) {
node.set_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE, true); node.set_flag(SEQUENTIALLY_FOCUSABLE, true);
} }
}, },
_ => { _ => {
@ -97,9 +97,9 @@ impl HTMLElement {
AttrValue::String(ref string) => string == "true", AttrValue::String(ref string) => string == "true",
_ => false, _ => false,
}; };
node.set_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE, is_true); node.set_flag(SEQUENTIALLY_FOCUSABLE, is_true);
} else { } else {
node.set_flag(NodeFlags::SEQUENTIALLY_FOCUSABLE, false); node.set_flag(SEQUENTIALLY_FOCUSABLE, false);
} }
//TODO set SEQUENTIALLY_FOCUSABLE flag if editing host //TODO set SEQUENTIALLY_FOCUSABLE flag if editing host
//TODO set SEQUENTIALLY_FOCUSABLE flag if "sorting interface th elements" //TODO set SEQUENTIALLY_FOCUSABLE flag if "sorting interface th elements"

View file

@ -19,7 +19,7 @@ use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix}; use html5ever::{LocalName, Prefix};
use std::default::Default; use std::default::Default;
use style::element_state::ElementState; use style::element_state::*;
#[dom_struct] #[dom_struct]
pub struct HTMLFieldSetElement { pub struct HTMLFieldSetElement {
@ -33,7 +33,7 @@ impl HTMLFieldSetElement {
document: &Document) -> HTMLFieldSetElement { document: &Document) -> HTMLFieldSetElement {
HTMLFieldSetElement { HTMLFieldSetElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
local_name, prefix, document), local_name, prefix, document),
form_owner: Default::default(), form_owner: Default::default(),
} }

View file

@ -37,7 +37,7 @@ use dom::htmlobjectelement::HTMLObjectElement;
use dom::htmloutputelement::HTMLOutputElement; use dom::htmloutputelement::HTMLOutputElement;
use dom::htmlselectelement::HTMLSelectElement; use dom::htmlselectelement::HTMLSelectElement;
use dom::htmltextareaelement::HTMLTextAreaElement; use dom::htmltextareaelement::HTMLTextAreaElement;
use dom::node::{Node, NodeFlags, UnbindContext, VecPreOrderInsertionHelper}; use dom::node::{Node, PARSER_ASSOCIATED_FORM_OWNER, UnbindContext, VecPreOrderInsertionHelper};
use dom::node::{document_from_node, window_from_node}; use dom::node::{document_from_node, window_from_node};
use dom::validitystate::ValidationFlags; use dom::validitystate::ValidationFlags;
use dom::virtualmethods::VirtualMethods; use dom::virtualmethods::VirtualMethods;
@ -879,7 +879,7 @@ pub trait FormControl: DomObject {
fn set_form_owner_from_parser(&self, form: &HTMLFormElement) { fn set_form_owner_from_parser(&self, form: &HTMLFormElement) {
let elem = self.to_element(); let elem = self.to_element();
let node = elem.upcast::<Node>(); let node = elem.upcast::<Node>();
node.set_flag(NodeFlags::PARSER_ASSOCIATED_FORM_OWNER, true); node.set_flag(PARSER_ASSOCIATED_FORM_OWNER, true);
form.add_control(self); form.add_control(self);
self.set_form_owner(Some(form)); self.set_form_owner(Some(form));
} }
@ -968,8 +968,8 @@ pub trait FormControl: DomObject {
// Part of step 12. // Part of step 12.
// '..suppress the running of the reset the form owner algorithm // '..suppress the running of the reset the form owner algorithm
// when the parser subsequently attempts to insert the element..' // when the parser subsequently attempts to insert the element..'
let must_skip_reset = node.get_flag(NodeFlags::PARSER_ASSOCIATED_FORM_OWNER); let must_skip_reset = node.get_flag(PARSER_ASSOCIATED_FORM_OWNER);
node.set_flag(NodeFlags::PARSER_ASSOCIATED_FORM_OWNER, false); node.set_flag(PARSER_ASSOCIATED_FORM_OWNER, false);
if !must_skip_reset { if !must_skip_reset {
self.form_attribute_mutated(AttributeMutation::Set(None)); self.form_attribute_mutated(AttributeMutation::Set(None));

View file

@ -57,14 +57,14 @@ use task_source::TaskSource;
bitflags! { bitflags! {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct SandboxAllowance: u8 { flags SandboxAllowance: u8 {
const ALLOW_NOTHING = 0x00; const ALLOW_NOTHING = 0x00,
const ALLOW_SAME_ORIGIN = 0x01; const ALLOW_SAME_ORIGIN = 0x01,
const ALLOW_TOP_NAVIGATION = 0x02; const ALLOW_TOP_NAVIGATION = 0x02,
const ALLOW_FORMS = 0x04; const ALLOW_FORMS = 0x04,
const ALLOW_SCRIPTS = 0x08; const ALLOW_SCRIPTS = 0x08,
const ALLOW_POINTER_LOCK = 0x10; const ALLOW_POINTER_LOCK = 0x10,
const ALLOW_POPUPS = 0x20; const ALLOW_POPUPS = 0x20
} }
} }
@ -726,16 +726,16 @@ impl VirtualMethods for HTMLIFrameElement {
match attr.local_name() { match attr.local_name() {
&local_name!("sandbox") => { &local_name!("sandbox") => {
self.sandbox_allowance.set(mutation.new_value(attr).map(|value| { self.sandbox_allowance.set(mutation.new_value(attr).map(|value| {
let mut modes = SandboxAllowance::ALLOW_NOTHING; let mut modes = ALLOW_NOTHING;
for token in value.as_tokens() { for token in value.as_tokens() {
modes |= match &*token.to_ascii_lowercase() { modes |= match &*token.to_ascii_lowercase() {
"allow-same-origin" => SandboxAllowance::ALLOW_SAME_ORIGIN, "allow-same-origin" => ALLOW_SAME_ORIGIN,
"allow-forms" => SandboxAllowance::ALLOW_FORMS, "allow-forms" => ALLOW_FORMS,
"allow-pointer-lock" => SandboxAllowance::ALLOW_POINTER_LOCK, "allow-pointer-lock" => ALLOW_POINTER_LOCK,
"allow-popups" => SandboxAllowance::ALLOW_POPUPS, "allow-popups" => ALLOW_POPUPS,
"allow-scripts" => SandboxAllowance::ALLOW_SCRIPTS, "allow-scripts" => ALLOW_SCRIPTS,
"allow-top-navigation" => SandboxAllowance::ALLOW_TOP_NAVIGATION, "allow-top-navigation" => ALLOW_TOP_NAVIGATION,
_ => SandboxAllowance::ALLOW_NOTHING _ => ALLOW_NOTHING
}; };
} }
modes modes

View file

@ -48,7 +48,7 @@ use std::borrow::ToOwned;
use std::cell::Cell; use std::cell::Cell;
use std::ops::Range; use std::ops::Range;
use style::attr::AttrValue; use style::attr::AttrValue;
use style::element_state::ElementState; use style::element_state::*;
use style::str::split_commas; use style::str::split_commas;
use textinput::{SelectionDirection, TextInput}; use textinput::{SelectionDirection, TextInput};
use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction}; use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction};
@ -137,8 +137,7 @@ impl HTMLInputElement {
let chan = document.window().upcast::<GlobalScope>().script_to_constellation_chan().clone(); let chan = document.window().upcast::<GlobalScope>().script_to_constellation_chan().clone();
HTMLInputElement { HTMLInputElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE | HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE,
ElementState::IN_READ_WRITE_STATE,
local_name, prefix, document), local_name, prefix, document),
input_type: Cell::new(InputType::InputText), input_type: Cell::new(InputType::InputText),
placeholder: DomRefCell::new(DOMString::new()), placeholder: DomRefCell::new(DOMString::new()),
@ -281,13 +280,13 @@ impl LayoutHTMLInputElementHelpers for LayoutDom<HTMLInputElement> {
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe fn checked_state_for_layout(self) -> bool { unsafe fn checked_state_for_layout(self) -> bool {
self.upcast::<Element>().get_state_for_layout().contains(ElementState::IN_CHECKED_STATE) self.upcast::<Element>().get_state_for_layout().contains(IN_CHECKED_STATE)
} }
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe fn indeterminate_state_for_layout(self) -> bool { unsafe fn indeterminate_state_for_layout(self) -> bool {
self.upcast::<Element>().get_state_for_layout().contains(ElementState::IN_INDETERMINATE_STATE) self.upcast::<Element>().get_state_for_layout().contains(IN_INDETERMINATE_STATE)
} }
} }
@ -337,7 +336,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-checked // https://html.spec.whatwg.org/multipage/#dom-input-checked
fn Checked(&self) -> bool { fn Checked(&self) -> bool {
self.upcast::<Element>().state().contains(ElementState::IN_CHECKED_STATE) self.upcast::<Element>().state().contains(IN_CHECKED_STATE)
} }
// https://html.spec.whatwg.org/multipage/#dom-input-checked // https://html.spec.whatwg.org/multipage/#dom-input-checked
@ -539,12 +538,12 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-indeterminate // https://html.spec.whatwg.org/multipage/#dom-input-indeterminate
fn Indeterminate(&self) -> bool { fn Indeterminate(&self) -> bool {
self.upcast::<Element>().state().contains(ElementState::IN_INDETERMINATE_STATE) self.upcast::<Element>().state().contains(IN_INDETERMINATE_STATE)
} }
// https://html.spec.whatwg.org/multipage/#dom-input-indeterminate // https://html.spec.whatwg.org/multipage/#dom-input-indeterminate
fn SetIndeterminate(&self, val: bool) { fn SetIndeterminate(&self, val: bool) {
self.upcast::<Element>().set_state(ElementState::IN_INDETERMINATE_STATE, val) self.upcast::<Element>().set_state(IN_INDETERMINATE_STATE, val)
} }
// https://html.spec.whatwg.org/multipage/#dom-lfe-labels // https://html.spec.whatwg.org/multipage/#dom-lfe-labels
@ -746,7 +745,7 @@ impl HTMLInputElement {
} }
fn update_checked_state(&self, checked: bool, dirty: bool) { fn update_checked_state(&self, checked: bool, dirty: bool) {
self.upcast::<Element>().set_state(ElementState::IN_CHECKED_STATE, checked); self.upcast::<Element>().set_state(IN_CHECKED_STATE, checked);
if dirty { if dirty {
self.checked_changed.set(true); self.checked_changed.set(true);

View file

@ -35,7 +35,7 @@ use style::media_queries::parse_media_query_list;
use style::parser::ParserContext as CssParserContext; use style::parser::ParserContext as CssParserContext;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::{CssRuleType, Stylesheet}; use style::stylesheets::{CssRuleType, Stylesheet};
use style_traits::ParsingMode; use style_traits::PARSING_MODE_DEFAULT;
use stylesheet_loader::{StylesheetLoader, StylesheetContextSource, StylesheetOwner}; use stylesheet_loader::{StylesheetLoader, StylesheetContextSource, StylesheetOwner};
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
@ -287,7 +287,7 @@ impl HTMLLinkElement {
let mut css_parser = CssParser::new(&mut input); let mut css_parser = CssParser::new(&mut input);
let doc_url = document.url(); let doc_url = document.url();
let context = CssParserContext::new_for_cssom(&doc_url, Some(CssRuleType::Media), let context = CssParserContext::new_for_cssom(&doc_url, Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
document.quirks_mode()); document.quirks_mode());
let window = document.window(); let window = document.window();
let media = parse_media_query_list(&context, &mut css_parser, let media = parse_media_query_list(&context, &mut css_parser,

View file

@ -15,7 +15,7 @@ use dom::node::Node;
use dom::virtualmethods::VirtualMethods; use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix}; use html5ever::{LocalName, Prefix};
use style::element_state::ElementState; use style::element_state::*;
#[dom_struct] #[dom_struct]
pub struct HTMLOptGroupElement { pub struct HTMLOptGroupElement {
@ -28,7 +28,7 @@ impl HTMLOptGroupElement {
document: &Document) -> HTMLOptGroupElement { document: &Document) -> HTMLOptGroupElement {
HTMLOptGroupElement { HTMLOptGroupElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
local_name, prefix, document) local_name, prefix, document)
} }
} }

View file

@ -25,7 +25,7 @@ use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix}; use html5ever::{LocalName, Prefix};
use std::cell::Cell; use std::cell::Cell;
use style::element_state::ElementState; use style::element_state::*;
use style::str::{split_html_space_chars, str_join}; use style::str::{split_html_space_chars, str_join};
#[dom_struct] #[dom_struct]
@ -45,7 +45,7 @@ impl HTMLOptionElement {
document: &Document) -> HTMLOptionElement { document: &Document) -> HTMLOptionElement {
HTMLOptionElement { HTMLOptionElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
local_name, prefix, document), local_name, prefix, document),
selectedness: Cell::new(false), selectedness: Cell::new(false),
dirtiness: Cell::new(false), dirtiness: Cell::new(false),

View file

@ -35,7 +35,7 @@ use html5ever::{LocalName, Prefix};
use std::default::Default; use std::default::Default;
use std::iter; use std::iter;
use style::attr::AttrValue; use style::attr::AttrValue;
use style::element_state::ElementState; use style::element_state::*;
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct OptionsFilter; struct OptionsFilter;
@ -73,7 +73,7 @@ impl HTMLSelectElement {
document: &Document) -> HTMLSelectElement { document: &Document) -> HTMLSelectElement {
HTMLSelectElement { HTMLSelectElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
local_name, prefix, document), local_name, prefix, document),
options: Default::default(), options: Default::default(),
form_owner: Default::default(), form_owner: Default::default(),

View file

@ -25,7 +25,7 @@ use std::cell::Cell;
use style::media_queries::parse_media_query_list; use style::media_queries::parse_media_query_list;
use style::parser::ParserContext as CssParserContext; use style::parser::ParserContext as CssParserContext;
use style::stylesheets::{CssRuleType, Stylesheet, Origin}; use style::stylesheets::{CssRuleType, Stylesheet, Origin};
use style_traits::ParsingMode; use style_traits::PARSING_MODE_DEFAULT;
use stylesheet_loader::{StylesheetLoader, StylesheetOwner}; use stylesheet_loader::{StylesheetLoader, StylesheetOwner};
#[dom_struct] #[dom_struct]
@ -87,7 +87,7 @@ impl HTMLStyleElement {
let url = window.get_url(); let url = window.get_url();
let context = CssParserContext::new_for_cssom(&url, let context = CssParserContext::new_for_cssom(&url,
Some(CssRuleType::Media), Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
doc.quirks_mode()); doc.quirks_mode());
let shared_lock = node.owner_doc().style_shared_lock().clone(); let shared_lock = node.owner_doc().style_shared_lock().clone();
let mut input = ParserInput::new(&mq_str); let mut input = ParserInput::new(&mq_str);

View file

@ -32,7 +32,7 @@ use std::cell::Cell;
use std::default::Default; use std::default::Default;
use std::ops::Range; use std::ops::Range;
use style::attr::AttrValue; use style::attr::AttrValue;
use style::element_state::ElementState; use style::element_state::*;
use textinput::{KeyReaction, Lines, SelectionDirection, TextInput}; use textinput::{KeyReaction, Lines, SelectionDirection, TextInput};
#[dom_struct] #[dom_struct]
@ -111,8 +111,7 @@ impl HTMLTextAreaElement {
let chan = document.window().upcast::<GlobalScope>().script_to_constellation_chan().clone(); let chan = document.window().upcast::<GlobalScope>().script_to_constellation_chan().clone();
HTMLTextAreaElement { HTMLTextAreaElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE | HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE,
ElementState::IN_READ_WRITE_STATE,
local_name, prefix, document), local_name, prefix, document),
placeholder: DomRefCell::new(DOMString::new()), placeholder: DomRefCell::new(DOMString::new()),
textinput: DomRefCell::new(TextInput::new( textinput: DomRefCell::new(TextInput::new(

View file

@ -15,6 +15,7 @@ use dom::event::Event;
use dom::uievent::UIEvent; use dom::uievent::UIEvent;
use dom::window::Window; use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use msg::constellation_msg;
use msg::constellation_msg::{Key, KeyModifiers}; use msg::constellation_msg::{Key, KeyModifiers};
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
@ -143,16 +144,16 @@ impl KeyboardEvent {
pub fn get_key_modifiers(&self) -> KeyModifiers { pub fn get_key_modifiers(&self) -> KeyModifiers {
let mut result = KeyModifiers::empty(); let mut result = KeyModifiers::empty();
if self.shift.get() { if self.shift.get() {
result = result | KeyModifiers::SHIFT; result = result | constellation_msg::SHIFT;
} }
if self.ctrl.get() { if self.ctrl.get() {
result = result | KeyModifiers::CONTROL; result = result | constellation_msg::CONTROL;
} }
if self.alt.get() { if self.alt.get() {
result = result | KeyModifiers::ALT; result = result | constellation_msg::ALT;
} }
if self.meta.get() { if self.meta.get() {
result = result | KeyModifiers::SUPER; result = result | constellation_msg::SUPER;
} }
result result
} }
@ -164,7 +165,7 @@ pub fn key_value(ch: Option<char>, key: Key, mods: KeyModifiers) -> Cow<'static,
return Cow::from(format!("{}", ch)); return Cow::from(format!("{}", ch));
} }
let shift = mods.contains(KeyModifiers::SHIFT); let shift = mods.contains(constellation_msg::SHIFT);
Cow::from(match key { Cow::from(match key {
Key::Space => " ", Key::Space => " ",
Key::Apostrophe if shift => "\"", Key::Apostrophe if shift => "\"",

View file

@ -18,7 +18,7 @@ use style::media_queries::MediaList as StyleMediaList;
use style::parser::ParserContext; use style::parser::ParserContext;
use style::shared_lock::{SharedRwLock, Locked}; use style::shared_lock::{SharedRwLock, Locked};
use style::stylesheets::CssRuleType; use style::stylesheets::CssRuleType;
use style_traits::{ParsingMode, ToCss}; use style_traits::{PARSING_MODE_DEFAULT, ToCss};
#[dom_struct] #[dom_struct]
pub struct MediaList { pub struct MediaList {
@ -78,7 +78,7 @@ impl MediaListMethods for MediaList {
let url = window.get_url(); let url = window.get_url();
let quirks_mode = window.Document().quirks_mode(); let quirks_mode = window.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
*media_queries = parse_media_query_list(&context, &mut parser, *media_queries = parse_media_query_list(&context, &mut parser,
window.css_error_reporter()); window.css_error_reporter());
@ -116,7 +116,7 @@ impl MediaListMethods for MediaList {
let url = win.get_url(); let url = win.get_url();
let quirks_mode = win.Document().quirks_mode(); let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
let m = MediaQuery::parse(&context, &mut parser); let m = MediaQuery::parse(&context, &mut parser);
// Step 2 // Step 2
@ -145,7 +145,7 @@ impl MediaListMethods for MediaList {
let url = win.get_url(); let url = win.get_url();
let quirks_mode = win.Document().quirks_mode(); let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
let m = MediaQuery::parse(&context, &mut parser); let m = MediaQuery::parse(&context, &mut parser);
// Step 2 // Step 2

View file

@ -148,39 +148,39 @@ pub struct Node {
bitflags! { bitflags! {
#[doc = "Flags for node items."] #[doc = "Flags for node items."]
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
pub struct NodeFlags: u16 { pub flags NodeFlags: u16 {
#[doc = "Specifies whether this node is in a document."] #[doc = "Specifies whether this node is in a document."]
const IS_IN_DOC = 1 << 0; const IS_IN_DOC = 1 << 0,
#[doc = "Specifies whether this node needs style recalc on next reflow."] #[doc = "Specifies whether this node needs style recalc on next reflow."]
const HAS_DIRTY_DESCENDANTS = 1 << 1; const HAS_DIRTY_DESCENDANTS = 1 << 1,
// TODO: find a better place to keep this (#4105) // TODO: find a better place to keep this (#4105)
// https://critic.hoppipolla.co.uk/showcomment?chain=8873 // https://critic.hoppipolla.co.uk/showcomment?chain=8873
// Perhaps using a Set in Document? // Perhaps using a Set in Document?
#[doc = "Specifies whether or not there is an authentic click in progress on \ #[doc = "Specifies whether or not there is an authentic click in progress on \
this element."] this element."]
const CLICK_IN_PROGRESS = 1 << 2; const CLICK_IN_PROGRESS = 1 << 2,
#[doc = "Specifies whether this node is focusable and whether it is supposed \ #[doc = "Specifies whether this node is focusable and whether it is supposed \
to be reachable with using sequential focus navigation."] to be reachable with using sequential focus navigation."]
const SEQUENTIALLY_FOCUSABLE = 1 << 3; const SEQUENTIALLY_FOCUSABLE = 1 << 3,
/// Whether any ancestor is a fragmentation container /// Whether any ancestor is a fragmentation container
const CAN_BE_FRAGMENTED = 1 << 4; const CAN_BE_FRAGMENTED = 1 << 4,
// There's a free bit here. // There's a free bit here.
#[doc = "Specifies whether the parser has set an associated form owner for \ #[doc = "Specifies whether the parser has set an associated form owner for \
this element. Only applicable for form-associatable elements."] this element. Only applicable for form-associatable elements."]
const PARSER_ASSOCIATED_FORM_OWNER = 1 << 6; const PARSER_ASSOCIATED_FORM_OWNER = 1 << 6,
/// Whether this element has a snapshot stored due to a style or /// Whether this element has a snapshot stored due to a style or
/// attribute change. /// attribute change.
/// ///
/// See the `style::restyle_hints` module. /// See the `style::restyle_hints` module.
const HAS_SNAPSHOT = 1 << 7; const HAS_SNAPSHOT = 1 << 7,
/// Whether this element has already handled the stored snapshot. /// Whether this element has already handled the stored snapshot.
const HANDLED_SNAPSHOT = 1 << 8; const HANDLED_SNAPSHOT = 1 << 8,
} }
} }
@ -261,9 +261,9 @@ impl Node {
let parent_in_doc = self.is_in_doc(); let parent_in_doc = self.is_in_doc();
for node in new_child.traverse_preorder() { for node in new_child.traverse_preorder() {
node.set_flag(NodeFlags::IS_IN_DOC, parent_in_doc); node.set_flag(IS_IN_DOC, parent_in_doc);
// Out-of-document elements never have the descendants flag set. // Out-of-document elements never have the descendants flag set.
debug_assert!(!node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS)); debug_assert!(!node.get_flag(HAS_DIRTY_DESCENDANTS));
vtable_for(&&*node).bind_to_tree(parent_in_doc); vtable_for(&&*node).bind_to_tree(parent_in_doc);
} }
let document = new_child.owner_doc(); let document = new_child.owner_doc();
@ -303,8 +303,8 @@ impl Node {
for node in child.traverse_preorder() { for node in child.traverse_preorder() {
// Out-of-document elements never have the descendants flag set. // Out-of-document elements never have the descendants flag set.
node.set_flag(NodeFlags::IS_IN_DOC | NodeFlags::HAS_DIRTY_DESCENDANTS | node.set_flag(IS_IN_DOC | HAS_DIRTY_DESCENDANTS |
NodeFlags::HAS_SNAPSHOT | NodeFlags::HANDLED_SNAPSHOT, HAS_SNAPSHOT | HANDLED_SNAPSHOT,
false); false);
} }
for node in child.traverse_preorder() { for node in child.traverse_preorder() {
@ -427,7 +427,7 @@ impl Node {
} }
pub fn is_in_doc(&self) -> bool { pub fn is_in_doc(&self) -> bool {
self.flags.get().contains(NodeFlags::IS_IN_DOC) self.flags.get().contains(IS_IN_DOC)
} }
/// Returns the type ID of this node. /// Returns the type ID of this node.
@ -489,7 +489,7 @@ impl Node {
} }
pub fn has_dirty_descendants(&self) -> bool { pub fn has_dirty_descendants(&self) -> bool {
self.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) self.get_flag(HAS_DIRTY_DESCENDANTS)
} }
pub fn rev_version(&self) { pub fn rev_version(&self) {
@ -1394,7 +1394,7 @@ impl Node {
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
pub fn new_document_node() -> Node { pub fn new_document_node() -> Node {
Node::new_(NodeFlags::new() | NodeFlags::IS_IN_DOC, None) Node::new_(NodeFlags::new() | IS_IN_DOC, None)
} }
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]

View file

@ -33,7 +33,7 @@ use servo_url::ServoUrl;
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use style::thread_state::{self, ThreadState}; use style::thread_state::{self, IN_WORKER, SCRIPT};
/// Messages used to control service worker event loop /// Messages used to control service worker event loop
pub enum ServiceWorkerScriptMsg { pub enum ServiceWorkerScriptMsg {
@ -154,7 +154,7 @@ impl ServiceWorkerGlobalScope {
let serialized_worker_url = script_url.to_string(); let serialized_worker_url = script_url.to_string();
let origin = GlobalScope::current().expect("No current global object").origin().immutable().clone(); let origin = GlobalScope::current().expect("No current global object").origin().immutable().clone();
thread::Builder::new().name(format!("ServiceWorker for {}", serialized_worker_url)).spawn(move || { thread::Builder::new().name(format!("ServiceWorker for {}", serialized_worker_url)).spawn(move || {
thread_state::initialize(ThreadState::SCRIPT | ThreadState::IN_WORKER); thread_state::initialize(SCRIPT | IN_WORKER);
let roots = RootCollection::new(); let roots = RootCollection::new();
let _stack_roots = ThreadLocalStackRoots::new(&roots); let _stack_roots = ThreadLocalStackRoots::new(&roots);

View file

@ -28,17 +28,17 @@ pub enum ValidityStatus {
} }
bitflags!{ bitflags!{
pub struct ValidationFlags: u32 { pub flags ValidationFlags: u32 {
const VALUE_MISSING = 0b0000000001; const VALUE_MISSING = 0b0000000001,
const TYPE_MISMATCH = 0b0000000010; const TYPE_MISMATCH = 0b0000000010,
const PATTERN_MISMATCH = 0b0000000100; const PATTERN_MISMATCH = 0b0000000100,
const TOO_LONG = 0b0000001000; const TOO_LONG = 0b0000001000,
const TOO_SHORT = 0b0000010000; const TOO_SHORT = 0b0000010000,
const RANGE_UNDERFLOW = 0b0000100000; const RANGE_UNDERFLOW = 0b0000100000,
const RANGE_OVERFLOW = 0b0001000000; const RANGE_OVERFLOW = 0b0001000000,
const STEP_MISMATCH = 0b0010000000; const STEP_MISMATCH = 0b0010000000,
const BAD_INPUT = 0b0100000000; const BAD_INPUT = 0b0100000000,
const CUSTOM_ERROR = 0b1000000000; const CUSTOM_ERROR = 0b1000000000,
} }
} }

View file

@ -136,10 +136,10 @@ fn has_invalid_blend_constants(arg1: u32, arg2: u32) -> bool {
/// Set of bitflags for texture unpacking (texImage2d, etc...) /// Set of bitflags for texture unpacking (texImage2d, etc...)
bitflags! { bitflags! {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct TextureUnpacking: u8 { flags TextureUnpacking: u8 {
const FLIP_Y_AXIS = 0x01; const FLIP_Y_AXIS = 0x01,
const PREMULTIPLY_ALPHA = 0x02; const PREMULTIPLY_ALPHA = 0x02,
const CONVERT_COLORSPACE = 0x04; const CONVERT_COLORSPACE = 0x04,
} }
} }
@ -235,7 +235,7 @@ impl WebGLRenderingContext {
limits: ctx_data.limits, limits: ctx_data.limits,
canvas: Dom::from_ref(canvas), canvas: Dom::from_ref(canvas),
last_error: Cell::new(None), last_error: Cell::new(None),
texture_unpacking_settings: Cell::new(TextureUnpacking::CONVERT_COLORSPACE), texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE),
texture_unpacking_alignment: Cell::new(4), texture_unpacking_alignment: Cell::new(4),
bound_framebuffer: MutNullableDom::new(None), bound_framebuffer: MutNullableDom::new(None),
bound_textures: DomRefCell::new(Default::default()), bound_textures: DomRefCell::new(Default::default()),
@ -878,7 +878,7 @@ impl WebGLRenderingContext {
width: usize, width: usize,
height: usize, height: usize,
unpacking_alignment: usize) -> Vec<u8> { unpacking_alignment: usize) -> Vec<u8> {
if !self.texture_unpacking_settings.get().contains(TextureUnpacking::FLIP_Y_AXIS) { if !self.texture_unpacking_settings.get().contains(FLIP_Y_AXIS) {
return pixels; return pixels;
} }
@ -906,7 +906,7 @@ impl WebGLRenderingContext {
format: TexFormat, format: TexFormat,
data_type: TexDataType, data_type: TexDataType,
pixels: Vec<u8>) -> Vec<u8> { pixels: Vec<u8>) -> Vec<u8> {
if !self.texture_unpacking_settings.get().contains(TextureUnpacking::PREMULTIPLY_ALPHA) { if !self.texture_unpacking_settings.get().contains(PREMULTIPLY_ALPHA) {
return pixels; return pixels;
} }
@ -990,7 +990,7 @@ impl WebGLRenderingContext {
source_premultiplied: bool, source_premultiplied: bool,
source_from_image_or_canvas: bool, source_from_image_or_canvas: bool,
mut pixels: Vec<u8>) -> Vec<u8> { mut pixels: Vec<u8>) -> Vec<u8> {
let dest_premultiply = self.texture_unpacking_settings.get().contains(TextureUnpacking::PREMULTIPLY_ALPHA); let dest_premultiply = self.texture_unpacking_settings.get().contains(PREMULTIPLY_ALPHA);
if !source_premultiplied && dest_premultiply { if !source_premultiplied && dest_premultiply {
if source_from_image_or_canvas { if source_from_image_or_canvas {
// When the pixels come from image or canvas or imagedata, use RGBA8 format // When the pixels come from image or canvas or imagedata, use RGBA8 format
@ -2450,9 +2450,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
match param_name { match param_name {
constants::UNPACK_FLIP_Y_WEBGL => { constants::UNPACK_FLIP_Y_WEBGL => {
if param_value != 0 { if param_value != 0 {
texture_settings.insert(TextureUnpacking::FLIP_Y_AXIS) texture_settings.insert(FLIP_Y_AXIS)
} else { } else {
texture_settings.remove(TextureUnpacking::FLIP_Y_AXIS) texture_settings.remove(FLIP_Y_AXIS)
} }
self.texture_unpacking_settings.set(texture_settings); self.texture_unpacking_settings.set(texture_settings);
@ -2460,9 +2460,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}, },
constants::UNPACK_PREMULTIPLY_ALPHA_WEBGL => { constants::UNPACK_PREMULTIPLY_ALPHA_WEBGL => {
if param_value != 0 { if param_value != 0 {
texture_settings.insert(TextureUnpacking::PREMULTIPLY_ALPHA) texture_settings.insert(PREMULTIPLY_ALPHA)
} else { } else {
texture_settings.remove(TextureUnpacking::PREMULTIPLY_ALPHA) texture_settings.remove(PREMULTIPLY_ALPHA)
} }
self.texture_unpacking_settings.set(texture_settings); self.texture_unpacking_settings.set(texture_settings);
@ -2471,9 +2471,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::UNPACK_COLORSPACE_CONVERSION_WEBGL => { constants::UNPACK_COLORSPACE_CONVERSION_WEBGL => {
match param_value as u32 { match param_value as u32 {
constants::BROWSER_DEFAULT_WEBGL constants::BROWSER_DEFAULT_WEBGL
=> texture_settings.insert(TextureUnpacking::CONVERT_COLORSPACE), => texture_settings.insert(CONVERT_COLORSPACE),
constants::NONE constants::NONE
=> texture_settings.remove(TextureUnpacking::CONVERT_COLORSPACE), => texture_settings.remove(CONVERT_COLORSPACE),
_ => return self.webgl_error(InvalidEnum), _ => return self.webgl_error(InvalidEnum),
} }

View file

@ -109,7 +109,7 @@ use style::properties::longhands::overflow_x;
use style::selector_parser::PseudoElement; use style::selector_parser::PseudoElement;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::CssRuleType; use style::stylesheets::CssRuleType;
use style_traits::ParsingMode; use style_traits::PARSING_MODE_DEFAULT;
use task::TaskCanceller; use task::TaskCanceller;
use task_source::dom_manipulation::DOMManipulationTaskSource; use task_source::dom_manipulation::DOMManipulationTaskSource;
use task_source::file_reading::FileReadingTaskSource; use task_source::file_reading::FileReadingTaskSource;
@ -1016,7 +1016,7 @@ impl WindowMethods for Window {
let url = self.get_url(); let url = self.get_url();
let quirks_mode = self.Document().quirks_mode(); let quirks_mode = self.Document().quirks_mode();
let context = CssParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = CssParserContext::new_for_cssom(&url, Some(CssRuleType::Media),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
let media_query_list = media_queries::parse_media_query_list(&context, &mut parser, let media_query_list = media_queries::parse_media_query_list(&context, &mut parser,
self.css_error_reporter()); self.css_error_reporter());

View file

@ -63,7 +63,7 @@ use std::sync::mpsc;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::thread; use std::thread;
use style::thread_state::{self, ThreadState}; use style::thread_state;
use swapper::Swapper; use swapper::Swapper;
use swapper::swapper; use swapper::swapper;
use task::TaskBox; use task::TaskBox;
@ -426,7 +426,7 @@ impl WorkletThread {
// TODO: set interrupt handler? // TODO: set interrupt handler?
// TODO: configure the JS runtime (e.g. discourage GC, encourage agressive JIT) // TODO: configure the JS runtime (e.g. discourage GC, encourage agressive JIT)
debug!("Initializing worklet thread."); debug!("Initializing worklet thread.");
thread_state::initialize(ThreadState::SCRIPT | ThreadState::IN_WORKER); thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER);
let roots = RootCollection::new(); let roots = RootCollection::new();
let _stack_roots = ThreadLocalStackRoots::new(&roots); let _stack_roots = ThreadLocalStackRoots::new(&roots);
let mut thread = RootedTraceableBox::new(WorkletThread { let mut thread = RootedTraceableBox::new(WorkletThread {

View file

@ -140,7 +140,8 @@ pub mod layout_exports {
pub use dom::characterdata::LayoutCharacterDataHelpers; pub use dom::characterdata::LayoutCharacterDataHelpers;
pub use dom::document::{Document, LayoutDocumentHelpers, PendingRestyle}; pub use dom::document::{Document, LayoutDocumentHelpers, PendingRestyle};
pub use dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers}; pub use dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers};
pub use dom::node::NodeFlags; pub use dom::node::{CAN_BE_FRAGMENTED, HAS_DIRTY_DESCENDANTS, IS_IN_DOC};
pub use dom::node::{HANDLED_SNAPSHOT, HAS_SNAPSHOT};
pub use dom::node::{LayoutNodeHelpers, Node}; pub use dom::node::{LayoutNodeHelpers, Node};
pub use dom::text::Text; pub use dom::text::Text;
} }

View file

@ -33,7 +33,7 @@ use std::os;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::panic::AssertUnwindSafe; use std::panic::AssertUnwindSafe;
use std::ptr; use std::ptr;
use style::thread_state::{self, ThreadState}; use style::thread_state;
use task::TaskBox; use task::TaskBox;
use time::{Tm, now}; use time::{Tm, now};
@ -394,8 +394,8 @@ unsafe extern "C" fn gc_slice_callback(_rt: *mut JSRuntime, progress: GCProgress
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus, _data: *mut os::raw::c_void) { unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus, _data: *mut os::raw::c_void) {
match status { match status {
JSGCStatus::JSGC_BEGIN => thread_state::enter(ThreadState::IN_GC), JSGCStatus::JSGC_BEGIN => thread_state::enter(thread_state::IN_GC),
JSGCStatus::JSGC_END => thread_state::exit(ThreadState::IN_GC), JSGCStatus::JSGC_END => thread_state::exit(thread_state::IN_GC),
} }
} }

View file

@ -114,7 +114,7 @@ use std::result::Result;
use std::sync::Arc; use std::sync::Arc;
use std::sync::mpsc::{Receiver, Select, Sender, channel}; use std::sync::mpsc::{Receiver, Select, Sender, channel};
use std::thread; use std::thread;
use style::thread_state::{self, ThreadState}; use style::thread_state;
use task_source::dom_manipulation::DOMManipulationTaskSource; use task_source::dom_manipulation::DOMManipulationTaskSource;
use task_source::file_reading::FileReadingTaskSource; use task_source::file_reading::FileReadingTaskSource;
use task_source::history_traversal::HistoryTraversalTaskSource; use task_source::history_traversal::HistoryTraversalTaskSource;
@ -544,7 +544,7 @@ impl ScriptThreadFactory for ScriptThread {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let layout_chan = sender.clone(); let layout_chan = sender.clone();
thread::Builder::new().name(format!("ScriptThread {:?}", state.id)).spawn(move || { thread::Builder::new().name(format!("ScriptThread {:?}", state.id)).spawn(move || {
thread_state::initialize(ThreadState::SCRIPT); thread_state::initialize(thread_state::SCRIPT);
PipelineNamespace::install(state.pipeline_namespace_id); PipelineNamespace::install(state.pipeline_namespace_id);
TopLevelBrowsingContextId::install(state.top_level_browsing_context_id); TopLevelBrowsingContextId::install(state.top_level_browsing_context_id);
let roots = RootCollection::new(); let roots = RootCollection::new();

View file

@ -7,6 +7,7 @@
use clipboard_provider::ClipboardProvider; use clipboard_provider::ClipboardProvider;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
use dom::keyboardevent::KeyboardEvent; use dom::keyboardevent::KeyboardEvent;
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{Key, KeyModifiers}; use msg::constellation_msg::{Key, KeyModifiers};
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cmp::{max, min}; use std::cmp::{max, min};
@ -113,12 +114,12 @@ pub enum Direction {
/// i.e. cmd on Mac OS or ctrl on other platforms. /// i.e. cmd on Mac OS or ctrl on other platforms.
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
fn is_control_key(mods: KeyModifiers) -> bool { fn is_control_key(mods: KeyModifiers) -> bool {
mods.contains(KeyModifiers::SUPER) && !mods.contains(KeyModifiers::CONTROL | KeyModifiers::ALT) mods.contains(SUPER) && !mods.contains(CONTROL | ALT)
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
fn is_control_key(mods: KeyModifiers) -> bool { fn is_control_key(mods: KeyModifiers) -> bool {
mods.contains(KeyModifiers::CONTROL) && !mods.contains(KeyModifiers::SUPER | KeyModifiers::ALT) mods.contains(CONTROL) && !mods.contains(SUPER | ALT)
} }
/// The length in bytes of the first n characters in a UTF-8 string. /// The length in bytes of the first n characters in a UTF-8 string.
@ -584,36 +585,31 @@ impl<T: ClipboardProvider> TextInput<T> {
printable: Option<char>, printable: Option<char>,
key: Key, key: Key,
mods: KeyModifiers) -> KeyReaction { mods: KeyModifiers) -> KeyReaction {
let maybe_select = if mods.contains(KeyModifiers::SHIFT) { let maybe_select = if mods.contains(SHIFT) { Selection::Selected } else { Selection::NotSelected };
Selection::Selected
} else {
Selection::NotSelected
};
match (printable, key) { match (printable, key) {
(_, Key::B) if mods.contains(KeyModifiers::CONTROL | KeyModifiers::ALT) => { (_, Key::B) if mods.contains(CONTROL | ALT) => {
self.adjust_horizontal_by_word(Direction::Backward, maybe_select); self.adjust_horizontal_by_word(Direction::Backward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
(_, Key::F) if mods.contains(KeyModifiers::CONTROL | KeyModifiers::ALT) => { (_, Key::F) if mods.contains(CONTROL | ALT) => {
self.adjust_horizontal_by_word(Direction::Forward, maybe_select); self.adjust_horizontal_by_word(Direction::Forward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
(_, Key::A) if mods.contains(KeyModifiers::CONTROL | KeyModifiers::ALT) => { (_, Key::A) if mods.contains(CONTROL | ALT) => {
self.adjust_horizontal_to_line_end(Direction::Backward, maybe_select); self.adjust_horizontal_to_line_end(Direction::Backward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
(_, Key::E) if mods.contains(KeyModifiers::CONTROL | KeyModifiers::ALT) => { (_, Key::E) if mods.contains(CONTROL | ALT) => {
self.adjust_horizontal_to_line_end(Direction::Forward, maybe_select); self.adjust_horizontal_to_line_end(Direction::Forward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
(None, Key::A) if mods == KeyModifiers::CONTROL => { (None, Key::A) if mods == CONTROL => {
self.adjust_horizontal_to_line_end(Direction::Backward, maybe_select); self.adjust_horizontal_to_line_end(Direction::Backward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
(None, Key::E) if mods == KeyModifiers::CONTROL => { (None, Key::E) if mods == CONTROL => {
self.adjust_horizontal_to_line_end(Direction::Forward, maybe_select); self.adjust_horizontal_to_line_end(Direction::Forward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
@ -645,30 +641,30 @@ impl<T: ClipboardProvider> TextInput<T> {
KeyReaction::DispatchInput KeyReaction::DispatchInput
}, },
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
(None, Key::Left) if mods.contains(KeyModifiers::SUPER) => { (None, Key::Left) if mods.contains(SUPER) => {
self.adjust_horizontal_to_line_end(Direction::Backward, maybe_select); self.adjust_horizontal_to_line_end(Direction::Backward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
(None, Key::Right) if mods.contains(KeyModifiers::SUPER) => { (None, Key::Right) if mods.contains(SUPER) => {
self.adjust_horizontal_to_line_end(Direction::Forward, maybe_select); self.adjust_horizontal_to_line_end(Direction::Forward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
(None, Key::Up) if mods.contains(KeyModifiers::SUPER) => { (None, Key::Up) if mods.contains(SUPER) => {
self.adjust_horizontal_to_limit(Direction::Backward, maybe_select); self.adjust_horizontal_to_limit(Direction::Backward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
(None, Key::Down) if mods.contains(KeyModifiers::SUPER) => { (None, Key::Down) if mods.contains(SUPER) => {
self.adjust_horizontal_to_limit(Direction::Forward, maybe_select); self.adjust_horizontal_to_limit(Direction::Forward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
(None, Key::Left) if mods.contains(KeyModifiers::ALT) => { (None, Key::Left) if mods.contains(ALT) => {
self.adjust_horizontal_by_word(Direction::Backward, maybe_select); self.adjust_horizontal_by_word(Direction::Backward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },
(None, Key::Right) if mods.contains(KeyModifiers::ALT) => { (None, Key::Right) if mods.contains(ALT) => {
self.adjust_horizontal_by_word(Direction::Forward, maybe_select); self.adjust_horizontal_by_word(Direction::Forward, maybe_select);
KeyReaction::RedrawSelection KeyReaction::RedrawSelection
}, },

View file

@ -23,7 +23,7 @@ gecko_like_types = []
bench = [] bench = []
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "0.7"
matches = "0.1" matches = "0.1"
cssparser = "0.22.0" cssparser = "0.22.0"
log = "0.3" log = "0.3"

View file

@ -20,39 +20,37 @@ pub static RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE: usize = 4096;
bitflags! { bitflags! {
/// Set of flags that are set on either the element or its parent (depending /// Set of flags that are set on either the element or its parent (depending
/// on the flag) if the element could potentially match a selector. /// on the flag) if the element could potentially match a selector.
pub struct ElementSelectorFlags: usize { pub flags ElementSelectorFlags: usize {
/// When a child is added or removed from the parent, all the children /// When a child is added or removed from the parent, all the children
/// must be restyled, because they may match :nth-last-child, /// must be restyled, because they may match :nth-last-child,
/// :last-of-type, :nth-last-of-type, or :only-of-type. /// :last-of-type, :nth-last-of-type, or :only-of-type.
const HAS_SLOW_SELECTOR = 1 << 0; const HAS_SLOW_SELECTOR = 1 << 0,
/// When a child is added or removed from the parent, any later /// When a child is added or removed from the parent, any later
/// children must be restyled, because they may match :nth-child, /// children must be restyled, because they may match :nth-child,
/// :first-of-type, or :nth-of-type. /// :first-of-type, or :nth-of-type.
const HAS_SLOW_SELECTOR_LATER_SIBLINGS = 1 << 1; const HAS_SLOW_SELECTOR_LATER_SIBLINGS = 1 << 1,
/// When a child is added or removed from the parent, the first and /// When a child is added or removed from the parent, the first and
/// last children must be restyled, because they may match :first-child, /// last children must be restyled, because they may match :first-child,
/// :last-child, or :only-child. /// :last-child, or :only-child.
const HAS_EDGE_CHILD_SELECTOR = 1 << 2; const HAS_EDGE_CHILD_SELECTOR = 1 << 2,
/// The element has an empty selector, so when a child is appended we /// The element has an empty selector, so when a child is appended we
/// might need to restyle the parent completely. /// might need to restyle the parent completely.
const HAS_EMPTY_SELECTOR = 1 << 3; const HAS_EMPTY_SELECTOR = 1 << 3,
} }
} }
impl ElementSelectorFlags { impl ElementSelectorFlags {
/// Returns the subset of flags that apply to the element. /// Returns the subset of flags that apply to the element.
pub fn for_self(self) -> ElementSelectorFlags { pub fn for_self(self) -> ElementSelectorFlags {
self & (ElementSelectorFlags::HAS_EMPTY_SELECTOR) self & (HAS_EMPTY_SELECTOR)
} }
/// Returns the subset of flags that apply to the parent. /// Returns the subset of flags that apply to the parent.
pub fn for_parent(self) -> ElementSelectorFlags { pub fn for_parent(self) -> ElementSelectorFlags {
self & (ElementSelectorFlags::HAS_SLOW_SELECTOR | self & (HAS_SLOW_SELECTOR | HAS_SLOW_SELECTOR_LATER_SIBLINGS | HAS_EDGE_CHILD_SELECTOR)
ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS |
ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR)
} }
} }
@ -518,7 +516,7 @@ where
let combinator = selector_iter.next_sequence(); let combinator = selector_iter.next_sequence();
let siblings = combinator.map_or(false, |c| c.is_sibling()); let siblings = combinator.map_or(false, |c| c.is_sibling());
if siblings { if siblings {
flags_setter(element, ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS); flags_setter(element, HAS_SLOW_SELECTOR_LATER_SIBLINGS);
} }
if !matches_all_simple_selectors { if !matches_all_simple_selectors {
@ -718,7 +716,7 @@ where
element.is_root() element.is_root()
} }
Component::Empty => { Component::Empty => {
flags_setter(element, ElementSelectorFlags::HAS_EMPTY_SELECTOR); flags_setter(element, HAS_EMPTY_SELECTOR);
element.is_empty() element.is_empty()
} }
Component::Scope => { Component::Scope => {
@ -793,9 +791,9 @@ where
} }
flags_setter(element, if is_from_end { flags_setter(element, if is_from_end {
ElementSelectorFlags::HAS_SLOW_SELECTOR HAS_SLOW_SELECTOR
} else { } else {
ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS HAS_SLOW_SELECTOR_LATER_SIBLINGS
}); });
// Grab a reference to the appropriate cache. // Grab a reference to the appropriate cache.
@ -888,7 +886,7 @@ where
E: Element, E: Element,
F: FnMut(&E, ElementSelectorFlags), F: FnMut(&E, ElementSelectorFlags),
{ {
flags_setter(element, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); flags_setter(element, HAS_EDGE_CHILD_SELECTOR);
element.prev_sibling_element().is_none() element.prev_sibling_element().is_none()
} }
@ -898,6 +896,6 @@ where
E: Element, E: Element,
F: FnMut(&E, ElementSelectorFlags), F: FnMut(&E, ElementSelectorFlags),
{ {
flags_setter(element, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); flags_setter(element, HAS_EDGE_CHILD_SELECTOR);
element.next_sibling_element().is_none() element.next_sibling_element().is_none()
} }

View file

@ -32,7 +32,7 @@ gecko_debug = ["nsstring_vendor/gecko_debug"]
app_units = "0.5.5" app_units = "0.5.5"
arrayvec = "0.3.20" arrayvec = "0.3.20"
atomic_refcell = "0.1" atomic_refcell = "0.1"
bitflags = "1.0" bitflags = "0.7"
byteorder = "1.0" byteorder = "1.0"
cfg-if = "0.1.0" cfg-if = "0.1.0"
cssparser = "0.22.0" cssparser = "0.22.0"

View file

@ -37,7 +37,7 @@ use style_traits::CSSPixel;
use style_traits::DevicePixel; use style_traits::DevicePixel;
#[cfg(feature = "servo")] use style_traits::SpeculativePainter; #[cfg(feature = "servo")] use style_traits::SpeculativePainter;
use stylist::Stylist; use stylist::Stylist;
use thread_state::{self, ThreadState}; use thread_state;
use time; use time;
use timer::Timer; use timer::Timer;
use traversal::DomTraversal; use traversal::DomTraversal;
@ -415,15 +415,15 @@ impl TraversalStatistics {
bitflags! { bitflags! {
/// Represents which tasks are performed in a SequentialTask of /// Represents which tasks are performed in a SequentialTask of
/// UpdateAnimations which is a result of normal restyle. /// UpdateAnimations which is a result of normal restyle.
pub struct UpdateAnimationsTasks: u8 { pub flags UpdateAnimationsTasks: u8 {
/// Update CSS Animations. /// Update CSS Animations.
const CSS_ANIMATIONS = structs::UpdateAnimationsTasks_CSSAnimations; const CSS_ANIMATIONS = structs::UpdateAnimationsTasks_CSSAnimations,
/// Update CSS Transitions. /// Update CSS Transitions.
const CSS_TRANSITIONS = structs::UpdateAnimationsTasks_CSSTransitions; const CSS_TRANSITIONS = structs::UpdateAnimationsTasks_CSSTransitions,
/// Update effect properties. /// Update effect properties.
const EFFECT_PROPERTIES = structs::UpdateAnimationsTasks_EffectProperties; const EFFECT_PROPERTIES = structs::UpdateAnimationsTasks_EffectProperties,
/// Update animation cacade results for animations running on the compositor. /// Update animation cacade results for animations running on the compositor.
const CASCADE_RESULTS = structs::UpdateAnimationsTasks_CascadeResults; const CASCADE_RESULTS = structs::UpdateAnimationsTasks_CascadeResults,
} }
} }
@ -431,11 +431,11 @@ bitflags! {
bitflags! { bitflags! {
/// Represents which tasks are performed in a SequentialTask as a result of /// Represents which tasks are performed in a SequentialTask as a result of
/// animation-only restyle. /// animation-only restyle.
pub struct PostAnimationTasks: u8 { pub flags PostAnimationTasks: u8 {
/// Display property was changed from none in animation-only restyle so /// Display property was changed from none in animation-only restyle so
/// that we need to resolve styles for descendants in a subsequent /// that we need to resolve styles for descendants in a subsequent
/// normal restyle. /// normal restyle.
const DISPLAY_CHANGED_FROM_NONE_FOR_SMIL = 0x01; const DISPLAY_CHANGED_FROM_NONE_FOR_SMIL = 0x01,
} }
} }
@ -477,7 +477,7 @@ impl<E: TElement> SequentialTask<E> {
/// Executes this task. /// Executes this task.
pub fn execute(self) { pub fn execute(self) {
use self::SequentialTask::*; use self::SequentialTask::*;
debug_assert!(thread_state::get() == ThreadState::LAYOUT); debug_assert!(thread_state::get() == thread_state::LAYOUT);
match self { match self {
Unused(_) => unreachable!(), Unused(_) => unreachable!(),
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
@ -565,7 +565,7 @@ impl<E: TElement> SelectorFlagsMap<E> {
/// Applies the flags. Must be called on the main thread. /// Applies the flags. Must be called on the main thread.
pub fn apply_flags(&mut self) { pub fn apply_flags(&mut self) {
debug_assert!(thread_state::get() == ThreadState::LAYOUT); debug_assert!(thread_state::get() == thread_state::LAYOUT);
for (el, flags) in self.map.drain() { for (el, flags) in self.map.drain() {
unsafe { el.set_selector_flags(flags); } unsafe { el.set_selector_flags(flags); }
} }
@ -602,7 +602,7 @@ where
E: TElement, E: TElement,
{ {
fn drop(&mut self) { fn drop(&mut self) {
debug_assert!(thread_state::get() == ThreadState::LAYOUT); debug_assert!(thread_state::get() == thread_state::LAYOUT);
for task in self.0.drain(..) { for task in self.0.drain(..) {
task.execute() task.execute()
} }
@ -797,7 +797,7 @@ impl<E: TElement> ThreadLocalStyleContext<E> {
impl<E: TElement> Drop for ThreadLocalStyleContext<E> { impl<E: TElement> Drop for ThreadLocalStyleContext<E> {
fn drop(&mut self) { fn drop(&mut self) {
debug_assert!(self.current_element_info.is_none()); debug_assert!(self.current_element_info.is_none());
debug_assert!(thread_state::get() == ThreadState::LAYOUT); debug_assert!(thread_state::get() == thread_state::LAYOUT);
// Apply any slow selector flags that need to be set on parents. // Apply any slow selector flags that need to be set on parents.
self.selector_flags.apply_flags(); self.selector_flags.apply_flags();

View file

@ -25,9 +25,9 @@ use style_resolver::{PrimaryStyle, ResolvedElementStyles, ResolvedStyle};
bitflags! { bitflags! {
/// Various flags stored on ElementData. /// Various flags stored on ElementData.
#[derive(Default)] #[derive(Default)]
pub struct ElementDataFlags: u8 { pub flags ElementDataFlags: u8 {
/// Whether the styles changed for this restyle. /// Whether the styles changed for this restyle.
const WAS_RESTYLED = 1 << 0; const WAS_RESTYLED = 1 << 0,
/// Whether the last traversal of this element did not do /// Whether the last traversal of this element did not do
/// any style computation. This is not true during the initial /// any style computation. This is not true during the initial
/// styling pass, nor is it true when we restyle (in which case /// styling pass, nor is it true when we restyle (in which case
@ -36,16 +36,16 @@ bitflags! {
/// This bit always corresponds to the last time the element was /// This bit always corresponds to the last time the element was
/// traversed, so each traversal simply updates it with the appropriate /// traversed, so each traversal simply updates it with the appropriate
/// value. /// value.
const TRAVERSED_WITHOUT_STYLING = 1 << 1; const TRAVERSED_WITHOUT_STYLING = 1 << 1,
/// Whether we reframed/reconstructed any ancestor or self. /// Whether we reframed/reconstructed any ancestor or self.
const ANCESTOR_WAS_RECONSTRUCTED = 1 << 2; const ANCESTOR_WAS_RECONSTRUCTED = 1 << 2,
/// Whether the primary style of this element data was reused from another /// Whether the primary style of this element data was reused from another
/// element via a rule node comparison. This allows us to differentiate /// element via a rule node comparison. This allows us to differentiate
/// between elements that shared styles because they met all the criteria /// between elements that shared styles because they met all the criteria
/// of the style sharing cache, compared to elements that reused style /// of the style sharing cache, compared to elements that reused style
/// structs via rule node identity. The former gives us stronger transitive /// structs via rule node identity. The former gives us stronger transitive
/// guarantees that allows us to apply the style sharing cache to cousins. /// guarantees that allows us to apply the style sharing cache to cousins.
const PRIMARY_STYLE_REUSED_VIA_RULE_NODE = 1 << 3; const PRIMARY_STYLE_REUSED_VIA_RULE_NODE = 1 << 3,
} }
} }
@ -298,7 +298,7 @@ impl ElementData {
/// Returns this element's primary style as a resolved style to use for sharing. /// Returns this element's primary style as a resolved style to use for sharing.
pub fn share_primary_style(&self) -> PrimaryStyle { pub fn share_primary_style(&self) -> PrimaryStyle {
let reused_via_rule_node = let reused_via_rule_node =
self.flags.contains(ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE); self.flags.contains(PRIMARY_STYLE_REUSED_VIA_RULE_NODE);
PrimaryStyle { PrimaryStyle {
style: ResolvedStyle(self.styles.primary().clone()), style: ResolvedStyle(self.styles.primary().clone()),
@ -309,9 +309,9 @@ impl ElementData {
/// Sets a new set of styles, returning the old ones. /// Sets a new set of styles, returning the old ones.
pub fn set_styles(&mut self, new_styles: ResolvedElementStyles) -> ElementStyles { pub fn set_styles(&mut self, new_styles: ResolvedElementStyles) -> ElementStyles {
if new_styles.primary.reused_via_rule_node { if new_styles.primary.reused_via_rule_node {
self.flags.insert(ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE); self.flags.insert(PRIMARY_STYLE_REUSED_VIA_RULE_NODE);
} else { } else {
self.flags.remove(ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE); self.flags.remove(PRIMARY_STYLE_REUSED_VIA_RULE_NODE);
} }
mem::replace(&mut self.styles, new_styles.into()) mem::replace(&mut self.styles, new_styles.into())
} }
@ -399,7 +399,7 @@ impl ElementData {
#[inline] #[inline]
pub fn clear_restyle_flags_and_damage(&mut self) { pub fn clear_restyle_flags_and_damage(&mut self) {
self.damage = RestyleDamage::empty(); self.damage = RestyleDamage::empty();
self.flags.remove(ElementDataFlags::WAS_RESTYLED | ElementDataFlags::ANCESTOR_WAS_RECONSTRUCTED) self.flags.remove(WAS_RESTYLED | ANCESTOR_WAS_RECONSTRUCTED)
} }
/// Returns whether this element or any ancestor is going to be /// Returns whether this element or any ancestor is going to be
@ -416,7 +416,7 @@ impl ElementData {
/// Returns whether any ancestor of this element is going to be /// Returns whether any ancestor of this element is going to be
/// reconstructed. /// reconstructed.
fn reconstructed_ancestor(&self) -> bool { fn reconstructed_ancestor(&self) -> bool {
self.flags.contains(ElementDataFlags::ANCESTOR_WAS_RECONSTRUCTED) self.flags.contains(ANCESTOR_WAS_RECONSTRUCTED)
} }
/// Sets the flag that tells us whether we've reconstructed an ancestor. /// Sets the flag that tells us whether we've reconstructed an ancestor.
@ -424,34 +424,34 @@ impl ElementData {
if reconstructed { if reconstructed {
// If it weren't for animation-only traversals, we could assert // If it weren't for animation-only traversals, we could assert
// `!self.reconstructed_ancestor()` here. // `!self.reconstructed_ancestor()` here.
self.flags.insert(ElementDataFlags::ANCESTOR_WAS_RECONSTRUCTED); self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED);
} else { } else {
self.flags.remove(ElementDataFlags::ANCESTOR_WAS_RECONSTRUCTED); self.flags.remove(ANCESTOR_WAS_RECONSTRUCTED);
} }
} }
/// Mark this element as restyled, which is useful to know whether we need /// Mark this element as restyled, which is useful to know whether we need
/// to do a post-traversal. /// to do a post-traversal.
pub fn set_restyled(&mut self) { pub fn set_restyled(&mut self) {
self.flags.insert(ElementDataFlags::WAS_RESTYLED); self.flags.insert(WAS_RESTYLED);
self.flags.remove(ElementDataFlags::TRAVERSED_WITHOUT_STYLING); self.flags.remove(TRAVERSED_WITHOUT_STYLING);
} }
/// Returns true if this element was restyled. /// Returns true if this element was restyled.
#[inline] #[inline]
pub fn is_restyle(&self) -> bool { pub fn is_restyle(&self) -> bool {
self.flags.contains(ElementDataFlags::WAS_RESTYLED) self.flags.contains(WAS_RESTYLED)
} }
/// Mark that we traversed this element without computing any style for it. /// Mark that we traversed this element without computing any style for it.
pub fn set_traversed_without_styling(&mut self) { pub fn set_traversed_without_styling(&mut self) {
self.flags.insert(ElementDataFlags::TRAVERSED_WITHOUT_STYLING); self.flags.insert(TRAVERSED_WITHOUT_STYLING);
} }
/// Returns whether the element was traversed without computing any style for /// Returns whether the element was traversed without computing any style for
/// it. /// it.
pub fn traversed_without_styling(&self) -> bool { pub fn traversed_without_styling(&self) -> bool {
self.flags.contains(ElementDataFlags::TRAVERSED_WITHOUT_STYLING) self.flags.contains(TRAVERSED_WITHOUT_STYLING)
} }
/// Returns whether this element has been part of a restyle. /// Returns whether this element has been part of a restyle.
@ -493,8 +493,7 @@ impl ElementData {
/// happens later in the styling pipeline. The former gives us the stronger guarantees /// happens later in the styling pipeline. The former gives us the stronger guarantees
/// we need for style sharing, the latter does not. /// we need for style sharing, the latter does not.
pub fn safe_for_cousin_sharing(&self) -> bool { pub fn safe_for_cousin_sharing(&self) -> bool {
!self.flags.intersects(ElementDataFlags::TRAVERSED_WITHOUT_STYLING | !self.flags.intersects(TRAVERSED_WITHOUT_STYLING | PRIMARY_STYLE_REUSED_VIA_RULE_NODE)
ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE)
} }
/// Measures memory usage. /// Measures memory usage.

View file

@ -32,7 +32,7 @@ use std::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use std::ops::Deref; use std::ops::Deref;
use stylist::Stylist; use stylist::Stylist;
use traversal_flags::TraversalFlags; use traversal_flags::{TraversalFlags, self};
/// An opaque handle to a node, which, unlike UnsafeNode, cannot be transformed /// An opaque handle to a node, which, unlike UnsafeNode, cannot be transformed
/// back into a non-opaque representation. The only safe operation that can be /// back into a non-opaque representation. The only safe operation that can be
@ -476,7 +476,7 @@ pub trait TElement
!data.hint.has_animation_hint_or_recascade(); !data.hint.has_animation_hint_or_recascade();
} }
if traversal_flags.contains(TraversalFlags::UnstyledOnly) { if traversal_flags.contains(traversal_flags::UnstyledOnly) {
// We don't process invalidations in UnstyledOnly mode. // We don't process invalidations in UnstyledOnly mode.
return data.has_styles(); return data.has_styles();
} }

View file

@ -15,128 +15,127 @@ bitflags! {
/// TODO(emilio): We really really want to use the NS_EVENT_STATE bindings /// TODO(emilio): We really really want to use the NS_EVENT_STATE bindings
/// for this. /// for this.
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
pub struct ElementState: u64 { pub flags ElementState: u64 {
/// The mouse is down on this element. /// The mouse is down on this element.
/// <https://html.spec.whatwg.org/multipage/#selector-active> /// <https://html.spec.whatwg.org/multipage/#selector-active>
/// FIXME(#7333): set/unset this when appropriate /// FIXME(#7333): set/unset this when appropriate
const IN_ACTIVE_STATE = 1 << 0; const IN_ACTIVE_STATE = 1 << 0,
/// This element has focus. /// This element has focus.
/// <https://html.spec.whatwg.org/multipage/#selector-focus> /// <https://html.spec.whatwg.org/multipage/#selector-focus>
const IN_FOCUS_STATE = 1 << 1; const IN_FOCUS_STATE = 1 << 1,
/// The mouse is hovering over this element. /// The mouse is hovering over this element.
/// <https://html.spec.whatwg.org/multipage/#selector-hover> /// <https://html.spec.whatwg.org/multipage/#selector-hover>
const IN_HOVER_STATE = 1 << 2; const IN_HOVER_STATE = 1 << 2,
/// Content is enabled (and can be disabled). /// Content is enabled (and can be disabled).
/// <http://www.whatwg.org/html/#selector-enabled> /// <http://www.whatwg.org/html/#selector-enabled>
const IN_ENABLED_STATE = 1 << 3; const IN_ENABLED_STATE = 1 << 3,
/// Content is disabled. /// Content is disabled.
/// <http://www.whatwg.org/html/#selector-disabled> /// <http://www.whatwg.org/html/#selector-disabled>
const IN_DISABLED_STATE = 1 << 4; const IN_DISABLED_STATE = 1 << 4,
/// Content is checked. /// Content is checked.
/// <https://html.spec.whatwg.org/multipage/#selector-checked> /// <https://html.spec.whatwg.org/multipage/#selector-checked>
const IN_CHECKED_STATE = 1 << 5; const IN_CHECKED_STATE = 1 << 5,
/// <https://html.spec.whatwg.org/multipage/#selector-indeterminate> /// <https://html.spec.whatwg.org/multipage/#selector-indeterminate>
const IN_INDETERMINATE_STATE = 1 << 6; const IN_INDETERMINATE_STATE = 1 << 6,
/// <https://html.spec.whatwg.org/multipage/#selector-placeholder-shown> /// <https://html.spec.whatwg.org/multipage/#selector-placeholder-shown>
const IN_PLACEHOLDER_SHOWN_STATE = 1 << 7; const IN_PLACEHOLDER_SHOWN_STATE = 1 << 7,
/// <https://html.spec.whatwg.org/multipage/#selector-target> /// <https://html.spec.whatwg.org/multipage/#selector-target>
const IN_TARGET_STATE = 1 << 8; const IN_TARGET_STATE = 1 << 8,
/// <https://fullscreen.spec.whatwg.org/#%3Afullscreen-pseudo-class> /// <https://fullscreen.spec.whatwg.org/#%3Afullscreen-pseudo-class>
const IN_FULLSCREEN_STATE = 1 << 9; const IN_FULLSCREEN_STATE = 1 << 9,
/// <https://html.spec.whatwg.org/multipage/#selector-valid> /// <https://html.spec.whatwg.org/multipage/#selector-valid>
const IN_VALID_STATE = 1 << 10; const IN_VALID_STATE = 1 << 10,
/// <https://html.spec.whatwg.org/multipage/#selector-invalid> /// <https://html.spec.whatwg.org/multipage/#selector-invalid>
const IN_INVALID_STATE = 1 << 11; const IN_INVALID_STATE = 1 << 11,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-valid /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-valid
const IN_MOZ_UI_VALID_STATE = 1 << 12; const IN_MOZ_UI_VALID_STATE = 1 << 12,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-invalid /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-invalid
const IN_MOZ_UI_INVALID_STATE = 1 << 13; const IN_MOZ_UI_INVALID_STATE = 1 << 13,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-broken /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-broken
const IN_BROKEN_STATE = 1 << 14; const IN_BROKEN_STATE = 1 << 14,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-user-disabled /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-user-disabled
const IN_USER_DISABLED_STATE = 1 << 15; const IN_USER_DISABLED_STATE = 1 << 15,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-suppressed /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-suppressed
const IN_SUPPRESSED_STATE = 1 << 16; const IN_SUPPRESSED_STATE = 1 << 16,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-loading /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-loading
const IN_LOADING_STATE = 1 << 17; const IN_LOADING_STATE = 1 << 17,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-blocked /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-blocked
const IN_HANDLER_BLOCKED_STATE = 1 << 18; const IN_HANDLER_BLOCKED_STATE = 1 << 18,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-disabled /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-disabled
const IN_HANDLER_DISABLED_STATE = 1 << 19; const IN_HANDLER_DISABLED_STATE = 1 << 19,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-crashed /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-handler-crashed
const IN_HANDLER_CRASHED_STATE = 1 << 20; const IN_HANDLER_CRASHED_STATE = 1 << 20,
/// <https://html.spec.whatwg.org/multipage/#selector-required> /// <https://html.spec.whatwg.org/multipage/#selector-required>
const IN_REQUIRED_STATE = 1 << 21; const IN_REQUIRED_STATE = 1 << 21,
/// <https://html.spec.whatwg.org/multipage/#selector-optional> /// <https://html.spec.whatwg.org/multipage/#selector-optional>
const IN_OPTIONAL_STATE = 1 << 22; const IN_OPTIONAL_STATE = 1 << 22,
/// <https://html.spec.whatwg.org/multipage/#selector-read-write> /// <https://html.spec.whatwg.org/multipage/#selector-read-write>
const IN_READ_WRITE_STATE = 1 << 22; const IN_READ_WRITE_STATE = 1 << 22,
/// Non-standard: Older custom-elements spec. /// Non-standard: Older custom-elements spec.
const IN_UNRESOLVED_STATE = 1 << 23; const IN_UNRESOLVED_STATE = 1 << 23,
/// <https://html.spec.whatwg.org/multipage/#selector-visited> /// <https://html.spec.whatwg.org/multipage/#selector-visited>
const IN_VISITED_STATE = 1 << 24; const IN_VISITED_STATE = 1 << 24,
/// <https://html.spec.whatwg.org/multipage/#selector-link> /// <https://html.spec.whatwg.org/multipage/#selector-link>
const IN_UNVISITED_STATE = 1 << 25; const IN_UNVISITED_STATE = 1 << 25,
/// <https://drafts.csswg.org/selectors-4/#the-any-link-pseudo> /// <https://drafts.csswg.org/selectors-4/#the-any-link-pseudo>
const IN_VISITED_OR_UNVISITED_STATE = ElementState::IN_VISITED_STATE.bits | const IN_VISITED_OR_UNVISITED_STATE = IN_VISITED_STATE.bits | IN_UNVISITED_STATE.bits,
ElementState::IN_UNVISITED_STATE.bits;
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-drag-over /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-drag-over
const IN_DRAGOVER_STATE = 1 << 26; const IN_DRAGOVER_STATE = 1 << 26,
/// <https://html.spec.whatwg.org/multipage/#selector-in-range> /// <https://html.spec.whatwg.org/multipage/#selector-in-range>
const IN_INRANGE_STATE = 1 << 27; const IN_INRANGE_STATE = 1 << 27,
/// <https://html.spec.whatwg.org/multipage/#selector-out-of-range> /// <https://html.spec.whatwg.org/multipage/#selector-out-of-range>
const IN_OUTOFRANGE_STATE = 1 << 28; const IN_OUTOFRANGE_STATE = 1 << 28,
/// <https://html.spec.whatwg.org/multipage/#selector-read-only> /// <https://html.spec.whatwg.org/multipage/#selector-read-only>
const IN_MOZ_READONLY_STATE = 1 << 29; const IN_MOZ_READONLY_STATE = 1 << 29,
/// <https://html.spec.whatwg.org/multipage/#selector-read-write> /// <https://html.spec.whatwg.org/multipage/#selector-read-write>
const IN_MOZ_READWRITE_STATE = 1 << 30; const IN_MOZ_READWRITE_STATE = 1 << 30,
/// <https://html.spec.whatwg.org/multipage/#selector-default> /// <https://html.spec.whatwg.org/multipage/#selector-default>
const IN_DEFAULT_STATE = 1 << 31; const IN_DEFAULT_STATE = 1 << 31,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-submit-invalid /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-submit-invalid
const IN_MOZ_SUBMITINVALID_STATE = 1 << 32; const IN_MOZ_SUBMITINVALID_STATE = 1 << 32,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_OPTIMUM_STATE = 1 << 33; const IN_OPTIMUM_STATE = 1 << 33,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_SUB_OPTIMUM_STATE = 1 << 34; const IN_SUB_OPTIMUM_STATE = 1 << 34,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_SUB_SUB_OPTIMUM_STATE = 1 << 35; const IN_SUB_SUB_OPTIMUM_STATE = 1 << 35,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_DEVTOOLS_HIGHLIGHTED_STATE = 1 << 36; const IN_DEVTOOLS_HIGHLIGHTED_STATE = 1 << 36,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_STYLEEDITOR_TRANSITIONING_STATE = 1 << 37; const IN_STYLEEDITOR_TRANSITIONING_STATE = 1 << 37,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_INCREMENT_SCRIPT_LEVEL_STATE = 1 << 38; const IN_INCREMENT_SCRIPT_LEVEL_STATE = 1 << 38,
/// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-focusring /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-focusring
const IN_FOCUSRING_STATE = 1 << 39; const IN_FOCUSRING_STATE = 1 << 39,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_HANDLER_CLICK_TO_PLAY_STATE = 1 << 40; const IN_HANDLER_CLICK_TO_PLAY_STATE = 1 << 40,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_HANDLER_VULNERABLE_UPDATABLE_STATE = 1 << 41; const IN_HANDLER_VULNERABLE_UPDATABLE_STATE = 1 << 41,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_HANDLER_VULNERABLE_NO_UPDATE_STATE = 1 << 42; const IN_HANDLER_VULNERABLE_NO_UPDATE_STATE = 1 << 42,
/// <https://drafts.csswg.org/selectors-4/#the-focus-within-pseudo> /// <https://drafts.csswg.org/selectors-4/#the-focus-within-pseudo>
const IN_FOCUS_WITHIN_STATE = 1 << 43; const IN_FOCUS_WITHIN_STATE = 1 << 43,
/// :dir matching; the states are used for dynamic change detection. /// :dir matching; the states are used for dynamic change detection.
/// State that elements that match :dir(ltr) are in. /// State that elements that match :dir(ltr) are in.
const IN_LTR_STATE = 1 << 44; const IN_LTR_STATE = 1 << 44,
/// State that elements that match :dir(rtl) are in. /// State that elements that match :dir(rtl) are in.
const IN_RTL_STATE = 1 << 45; const IN_RTL_STATE = 1 << 45,
/// State that HTML elements that have a "dir" attr are in. /// State that HTML elements that have a "dir" attr are in.
const IN_HAS_DIR_ATTR_STATE = 1 << 46; const IN_HAS_DIR_ATTR_STATE = 1 << 46,
/// State that HTML elements with dir="ltr" (or something /// State that HTML elements with dir="ltr" (or something
/// case-insensitively equal to "ltr") are in. /// case-insensitively equal to "ltr") are in.
const IN_HAS_DIR_ATTR_LTR_STATE = 1 << 47; const IN_HAS_DIR_ATTR_LTR_STATE = 1 << 47,
/// State that HTML elements with dir="rtl" (or something /// State that HTML elements with dir="rtl" (or something
/// case-insensitively equal to "rtl") are in. /// case-insensitively equal to "rtl") are in.
const IN_HAS_DIR_ATTR_RTL_STATE = 1 << 48; const IN_HAS_DIR_ATTR_RTL_STATE = 1 << 48,
/// State that HTML <bdi> elements without a valid-valued "dir" attr or /// State that HTML <bdi> elements without a valid-valued "dir" attr or
/// any HTML elements (including <bdi>) with dir="auto" (or something /// any HTML elements (including <bdi>) with dir="auto" (or something
/// case-insensitively equal to "auto") are in. /// case-insensitively equal to "auto") are in.
const IN_HAS_DIR_ATTR_LIKE_AUTO_STATE = 1 << 49; const IN_HAS_DIR_ATTR_LIKE_AUTO_STATE = 1 << 49,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_AUTOFILL_STATE = 1 << 50; const IN_AUTOFILL_STATE = 1 << 50,
/// Non-standard & undocumented. /// Non-standard & undocumented.
const IN_AUTOFILL_PREVIEW_STATE = 1 << 51; const IN_AUTOFILL_PREVIEW_STATE = 1 << 51,
} }
} }
@ -145,10 +144,10 @@ bitflags! {
/// ///
/// NB: Is important for this to remain in sync with Gecko's /// NB: Is important for this to remain in sync with Gecko's
/// dom/base/nsIDocument.h. /// dom/base/nsIDocument.h.
pub struct DocumentState: u64 { pub flags DocumentState: u64 {
/// RTL locale: specific to the XUL localedir attribute /// RTL locale: specific to the XUL localedir attribute
const NS_DOCUMENT_STATE_RTL_LOCALE = 1 << 0; const NS_DOCUMENT_STATE_RTL_LOCALE = 1 << 0,
/// Window activation status /// Window activation status
const NS_DOCUMENT_STATE_WINDOW_INACTIVE = 1 << 1; const NS_DOCUMENT_STATE_WINDOW_INACTIVE = 1 << 1,
} }
} }

View file

@ -10,7 +10,9 @@
use cssparser::{ToCss, serialize_identifier}; use cssparser::{ToCss, serialize_identifier};
use gecko_bindings::structs::{self, CSSPseudoElementType}; use gecko_bindings::structs::{self, CSSPseudoElementType};
use properties::{ComputedValues, PropertyFlags}; use properties::{PropertyFlags, APPLIES_TO_FIRST_LETTER, APPLIES_TO_FIRST_LINE};
use properties::APPLIES_TO_PLACEHOLDER;
use properties::ComputedValues;
use properties::longhands::display::computed_value as display; use properties::longhands::display::computed_value as display;
use selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl}; use selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl};
use std::fmt; use std::fmt;
@ -151,9 +153,9 @@ impl PseudoElement {
#[inline] #[inline]
pub fn property_restriction(&self) -> Option<PropertyFlags> { pub fn property_restriction(&self) -> Option<PropertyFlags> {
match *self { match *self {
PseudoElement::FirstLetter => Some(PropertyFlags::APPLIES_TO_FIRST_LETTER), PseudoElement::FirstLetter => Some(APPLIES_TO_FIRST_LETTER),
PseudoElement::FirstLine => Some(PropertyFlags::APPLIES_TO_FIRST_LINE), PseudoElement::FirstLine => Some(APPLIES_TO_FIRST_LINE),
PseudoElement::Placeholder => Some(PropertyFlags::APPLIES_TO_PLACEHOLDER), PseudoElement::Placeholder => Some(APPLIES_TO_PLACEHOLDER),
_ => None, _ => None,
} }
} }

View file

@ -22,12 +22,11 @@ pub use gecko::snapshot::SnapshotMap;
bitflags! { bitflags! {
// See NonTSPseudoClass::is_enabled_in() // See NonTSPseudoClass::is_enabled_in()
struct NonTSPseudoClassFlag: u8 { flags NonTSPseudoClassFlag: u8 {
const PSEUDO_CLASS_ENABLED_IN_UA_SHEETS = 1 << 0; const PSEUDO_CLASS_ENABLED_IN_UA_SHEETS = 1 << 0,
const PSEUDO_CLASS_ENABLED_IN_CHROME = 1 << 1; const PSEUDO_CLASS_ENABLED_IN_CHROME = 1 << 1,
const PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME = const PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME =
NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS.bits | PSEUDO_CLASS_ENABLED_IN_UA_SHEETS.bits | PSEUDO_CLASS_ENABLED_IN_CHROME.bits,
NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_CHROME.bits;
} }
} }
@ -135,7 +134,7 @@ impl NonTSPseudoClass {
fn has_any_flag(&self, flags: NonTSPseudoClassFlag) -> bool { fn has_any_flag(&self, flags: NonTSPseudoClassFlag) -> bool {
macro_rules! check_flag { macro_rules! check_flag {
(_) => (false); (_) => (false);
($flags:ident) => (NonTSPseudoClassFlag::$flags.intersects(flags)); ($flags:expr) => ($flags.intersects(flags));
} }
macro_rules! pseudo_class_check_is_enabled_in { macro_rules! pseudo_class_check_is_enabled_in {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
@ -162,7 +161,7 @@ impl NonTSPseudoClass {
unsafe { mozilla::StylePrefs_sUnprefixedFullscreenApiEnabled }, unsafe { mozilla::StylePrefs_sUnprefixedFullscreenApiEnabled },
// Otherwise, a pseudo-class is enabled in content when it // Otherwise, a pseudo-class is enabled in content when it
// doesn't have any enabled flag. // doesn't have any enabled flag.
_ => !self.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME), _ => !self.has_any_flag(PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
} }
} }
@ -179,7 +178,7 @@ impl NonTSPseudoClass {
pub fn state_flag(&self) -> ElementState { pub fn state_flag(&self) -> ElementState {
macro_rules! flag { macro_rules! flag {
(_) => (ElementState::empty()); (_) => (ElementState::empty());
($state:ident) => (ElementState::$state); ($state:ident) => (::element_state::$state);
} }
macro_rules! pseudo_class_state { macro_rules! pseudo_class_state {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
@ -291,9 +290,9 @@ impl<'a> SelectorParser<'a> {
-> bool { -> bool {
pseudo_class.is_enabled_in_content() || pseudo_class.is_enabled_in_content() ||
(self.in_user_agent_stylesheet() && (self.in_user_agent_stylesheet() &&
pseudo_class.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS)) || pseudo_class.has_any_flag(PSEUDO_CLASS_ENABLED_IN_UA_SHEETS)) ||
(self.in_chrome_stylesheet() && (self.in_chrome_stylesheet() &&
pseudo_class.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_CHROME)) pseudo_class.has_any_flag(PSEUDO_CLASS_ENABLED_IN_CHROME))
} }
} }

View file

@ -22,7 +22,7 @@ use context::{QuirksMode, SharedStyleContext, PostAnimationTasks, UpdateAnimatio
use data::ElementData; use data::ElementData;
use dom::{LayoutIterator, NodeInfo, TElement, TNode}; use dom::{LayoutIterator, NodeInfo, TElement, TNode};
use dom::{OpaqueNode, PresentationalHintsSynthesizer}; use dom::{OpaqueNode, PresentationalHintsSynthesizer};
use element_state::{ElementState, DocumentState}; use element_state::{ElementState, DocumentState, NS_DOCUMENT_STATE_WINDOW_INACTIVE};
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult}; use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
use gecko::data::PerDocumentStyleData; use gecko::data::PerDocumentStyleData;
@ -729,17 +729,18 @@ impl<'le> GeckoElement<'le> {
/// it's probably not worth the trouble. /// it's probably not worth the trouble.
fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 { fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 {
use gecko_bindings::structs::*; use gecko_bindings::structs::*;
use selectors::matching::*;
let mut gecko_flags = 0u32; let mut gecko_flags = 0u32;
if flags.contains(ElementSelectorFlags::HAS_SLOW_SELECTOR) { if flags.contains(HAS_SLOW_SELECTOR) {
gecko_flags |= NODE_HAS_SLOW_SELECTOR as u32; gecko_flags |= NODE_HAS_SLOW_SELECTOR as u32;
} }
if flags.contains(ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS) { if flags.contains(HAS_SLOW_SELECTOR_LATER_SIBLINGS) {
gecko_flags |= NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS as u32; gecko_flags |= NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS as u32;
} }
if flags.contains(ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR) { if flags.contains(HAS_EDGE_CHILD_SELECTOR) {
gecko_flags |= NODE_HAS_EDGE_CHILD_SELECTOR as u32; gecko_flags |= NODE_HAS_EDGE_CHILD_SELECTOR as u32;
} }
if flags.contains(ElementSelectorFlags::HAS_EMPTY_SELECTOR) { if flags.contains(HAS_EMPTY_SELECTOR) {
gecko_flags |= NODE_HAS_EMPTY_SELECTOR as u32; gecko_flags |= NODE_HAS_EMPTY_SELECTOR as u32;
} }
@ -1079,7 +1080,8 @@ impl<'le> TElement for GeckoElement<'le> {
} }
fn is_visited_link(&self) -> bool { fn is_visited_link(&self) -> bool {
self.get_state().intersects(ElementState::IN_VISITED_STATE) use element_state::IN_VISITED_STATE;
self.get_state().intersects(IN_VISITED_STATE)
} }
#[inline] #[inline]
@ -1190,6 +1192,7 @@ impl<'le> TElement for GeckoElement<'le> {
/// Process various tasks that are a result of animation-only restyle. /// Process various tasks that are a result of animation-only restyle.
fn process_post_animation(&self, fn process_post_animation(&self,
tasks: PostAnimationTasks) { tasks: PostAnimationTasks) {
use context::DISPLAY_CHANGED_FROM_NONE_FOR_SMIL;
use gecko_bindings::structs::nsChangeHint_nsChangeHint_Empty; use gecko_bindings::structs::nsChangeHint_nsChangeHint_Empty;
use gecko_bindings::structs::nsRestyleHint_eRestyle_Subtree; use gecko_bindings::structs::nsRestyleHint_eRestyle_Subtree;
@ -1199,7 +1202,7 @@ impl<'le> TElement for GeckoElement<'le> {
// the descendants in the display:none subtree. Instead of resolving // the descendants in the display:none subtree. Instead of resolving
// those styles in animation-only restyle, we defer it to a subsequent // those styles in animation-only restyle, we defer it to a subsequent
// normal restyle. // normal restyle.
if tasks.intersects(PostAnimationTasks::DISPLAY_CHANGED_FROM_NONE_FOR_SMIL) { if tasks.intersects(DISPLAY_CHANGED_FROM_NONE_FOR_SMIL) {
debug_assert!(self.implemented_pseudo_element() debug_assert!(self.implemented_pseudo_element()
.map_or(true, |p| !p.is_before_or_after()), .map_or(true, |p| !p.is_before_or_after()),
"display property animation shouldn't run on pseudo elements \ "display property animation shouldn't run on pseudo elements \
@ -1895,7 +1898,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::Link => relevant_link.is_unvisited(self, context), NonTSPseudoClass::Link => relevant_link.is_unvisited(self, context),
NonTSPseudoClass::Visited => relevant_link.is_visited(self, context), NonTSPseudoClass::Visited => relevant_link.is_visited(self, context),
NonTSPseudoClass::MozFirstNode => { NonTSPseudoClass::MozFirstNode => {
flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); flags_setter(self, HAS_EDGE_CHILD_SELECTOR);
let mut elem = self.as_node(); let mut elem = self.as_node();
while let Some(prev) = elem.prev_sibling() { while let Some(prev) = elem.prev_sibling() {
if prev.contains_non_whitespace_content() { if prev.contains_non_whitespace_content() {
@ -1906,7 +1909,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
true true
} }
NonTSPseudoClass::MozLastNode => { NonTSPseudoClass::MozLastNode => {
flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); flags_setter(self, HAS_EDGE_CHILD_SELECTOR);
let mut elem = self.as_node(); let mut elem = self.as_node();
while let Some(next) = elem.next_sibling() { while let Some(next) = elem.next_sibling() {
if next.contains_non_whitespace_content() { if next.contains_non_whitespace_content() {
@ -1917,7 +1920,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
true true
} }
NonTSPseudoClass::MozOnlyWhitespace => { NonTSPseudoClass::MozOnlyWhitespace => {
flags_setter(self, ElementSelectorFlags::HAS_EMPTY_SELECTOR); flags_setter(self, HAS_EMPTY_SELECTOR);
if self.as_node().dom_children().any(|c| c.contains_non_whitespace_content()) { if self.as_node().dom_children().any(|c| c.contains_non_whitespace_content()) {
return false return false
} }
@ -1942,7 +1945,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
self.get_document_theme() == DocumentTheme::Doc_Theme_Dark self.get_document_theme() == DocumentTheme::Doc_Theme_Dark
} }
NonTSPseudoClass::MozWindowInactive => { NonTSPseudoClass::MozWindowInactive => {
self.document_state().contains(DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE) self.document_state().contains(NS_DOCUMENT_STATE_WINDOW_INACTIVE)
} }
NonTSPseudoClass::MozPlaceholder => false, NonTSPseudoClass::MozPlaceholder => false,
NonTSPseudoClass::MozAny(ref sels) => { NonTSPseudoClass::MozAny(ref sels) => {

View file

@ -9,7 +9,7 @@ description = "Rust bindings to xpcom string types"
# Revendoring nsstring from m-c into Servo # Revendoring nsstring from m-c into Servo
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "0.8"
[features] [features]
gecko_debug = [] gecko_debug = []

View file

@ -138,13 +138,13 @@ mod data_flags {
// While this has the same layout as u16, it cannot be passed // While this has the same layout as u16, it cannot be passed
// over FFI safely as a u16. // over FFI safely as a u16.
#[repr(C)] #[repr(C)]
pub struct DataFlags : u16 { pub flags DataFlags : u16 {
const TERMINATED = 1 << 0; // IsTerminated returns true const TERMINATED = 1 << 0, // IsTerminated returns true
const VOIDED = 1 << 1; // IsVoid returns true const VOIDED = 1 << 1, // IsVoid returns true
const SHARED = 1 << 2; // mData points to a heap-allocated, shared buffer const SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
const OWNED = 1 << 3; // mData points to a heap-allocated, raw buffer const OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
const INLINE = 1 << 4; // mData points to a writable, inline buffer const INLINE = 1 << 4, // mData points to a writable, inline buffer
const LITERAL = 1 << 5; // mData points to a string literal; TERMINATED will also be set const LITERAL = 1 << 5, // mData points to a string literal; TERMINATED will also be set
} }
} }
} }
@ -154,9 +154,9 @@ mod class_flags {
// While this has the same layout as u16, it cannot be passed // While this has the same layout as u16, it cannot be passed
// over FFI safely as a u16. // over FFI safely as a u16.
#[repr(C)] #[repr(C)]
pub struct ClassFlags : u16 { pub flags ClassFlags : u16 {
const INLINE = 1 << 0; // |this|'s buffer is inline const INLINE = 1 << 0, // |this|'s buffer is inline
const NULL_TERMINATED = 1 << 1; // |this| requires its buffer is null-terminated const NULL_TERMINATED = 1 << 1, // |this| requires its buffer is null-terminated
} }
} }
} }
@ -212,7 +212,7 @@ macro_rules! define_string_types {
$StringRepr { $StringRepr {
data: &NUL, data: &NUL,
length: 0, length: 0,
dataflags: DataFlags::TERMINATED | DataFlags::LITERAL, dataflags: data_flags::TERMINATED | data_flags::LITERAL,
classflags: classflags, classflags: classflags,
} }
} }
@ -536,7 +536,7 @@ macro_rules! define_string_types {
impl $String { impl $String {
pub fn new() -> $String { pub fn new() -> $String {
$String { $String {
hdr: $StringRepr::new(ClassFlags::NULL_TERMINATED), hdr: $StringRepr::new(class_flags::NULL_TERMINATED),
} }
} }
} }
@ -618,8 +618,8 @@ macro_rules! define_string_types {
hdr: $StringRepr { hdr: $StringRepr {
data: ptr, data: ptr,
length: length, length: length,
dataflags: DataFlags::OWNED | DataFlags::TERMINATED, dataflags: data_flags::OWNED | data_flags::TERMINATED,
classflags: ClassFlags::NULL_TERMINATED, classflags: class_flags::NULL_TERMINATED,
} }
} }
} }

View file

@ -13,9 +13,9 @@ use stylesheets::OriginSet;
/// Checks that the values for OriginFlags are the ones we expect. /// Checks that the values for OriginFlags are the ones we expect.
pub fn assert_flags_match() { pub fn assert_flags_match() {
use stylesheets::origin::*; use stylesheets::origin::*;
debug_assert_eq!(OriginFlags_UserAgent.0, OriginSet::ORIGIN_USER_AGENT.bits()); debug_assert_eq!(OriginFlags_UserAgent.0, ORIGIN_USER_AGENT.bits());
debug_assert_eq!(OriginFlags_Author.0, OriginSet::ORIGIN_AUTHOR.bits()); debug_assert_eq!(OriginFlags_Author.0, ORIGIN_AUTHOR.bits());
debug_assert_eq!(OriginFlags_User.0, OriginSet::ORIGIN_USER.bits()); debug_assert_eq!(OriginFlags_User.0, ORIGIN_USER.bits());
} }
impl From<OriginFlags> for OriginSet { impl From<OriginFlags> for OriginSet {

View file

@ -9,11 +9,11 @@ use Atom;
use context::{QuirksMode, SharedStyleContext}; use context::{QuirksMode, SharedStyleContext};
use data::ElementData; use data::ElementData;
use dom::TElement; use dom::TElement;
use element_state::ElementState; use element_state::{ElementState, IN_VISITED_OR_UNVISITED_STATE};
use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper}; use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
use invalidation::element::invalidation_map::*; use invalidation::element::invalidation_map::*;
use invalidation::element::invalidator::{InvalidationVector, Invalidation, InvalidationProcessor}; use invalidation::element::invalidator::{InvalidationVector, Invalidation, InvalidationProcessor};
use invalidation::element::restyle_hints::RestyleHint; use invalidation::element::restyle_hints::*;
use selector_map::SelectorMap; use selector_map::SelectorMap;
use selector_parser::Snapshot; use selector_parser::Snapshot;
use selectors::NthIndexCache; use selectors::NthIndexCache;
@ -102,7 +102,7 @@ where
// force a restyle here. Matching doesn't depend on the actual visited // force a restyle here. Matching doesn't depend on the actual visited
// state at all, so we can't look at matching results to decide what to // state at all, so we can't look at matching results to decide what to
// do for this case. // do for this case.
if state_changes.intersects(ElementState::IN_VISITED_OR_UNVISITED_STATE) { if state_changes.intersects(IN_VISITED_OR_UNVISITED_STATE) {
trace!(" > visitedness change, force subtree restyle"); trace!(" > visitedness change, force subtree restyle");
// We can't just return here because there may also be attribute // We can't just return here because there may also be attribute
// changes as well that imply additional hints. // changes as well that imply additional hints.
@ -186,7 +186,7 @@ where
}; };
if invalidated_self { if invalidated_self {
self.data.hint.insert(RestyleHint::RESTYLE_SELF); self.data.hint.insert(RESTYLE_SELF);
} }
invalidated_self invalidated_self
@ -195,7 +195,7 @@ where
fn should_process_descendants(&mut self, element: E) -> bool { fn should_process_descendants(&mut self, element: E) -> bool {
if element == self.element { if element == self.element {
return !self.data.styles.is_display_none() && return !self.data.styles.is_display_none() &&
!self.data.hint.contains(RestyleHint::RESTYLE_DESCENDANTS) !self.data.hint.contains(RESTYLE_DESCENDANTS)
} }
let data = match element.borrow_data() { let data = match element.borrow_data() {
@ -204,17 +204,17 @@ where
}; };
!data.styles.is_display_none() && !data.styles.is_display_none() &&
!data.hint.contains(RestyleHint::RESTYLE_DESCENDANTS) !data.hint.contains(RESTYLE_DESCENDANTS)
} }
fn recursion_limit_exceeded(&mut self, element: E) { fn recursion_limit_exceeded(&mut self, element: E) {
if element == self.element { if element == self.element {
self.data.hint.insert(RestyleHint::RESTYLE_DESCENDANTS); self.data.hint.insert(RESTYLE_DESCENDANTS);
return; return;
} }
if let Some(mut data) = element.mutate_data() { if let Some(mut data) = element.mutate_data() {
data.hint.insert(RestyleHint::RESTYLE_DESCENDANTS); data.hint.insert(RESTYLE_DESCENDANTS);
} }
} }
@ -242,7 +242,7 @@ where
fn invalidated_self(&mut self, element: E) { fn invalidated_self(&mut self, element: E) {
debug_assert_ne!(element, self.element); debug_assert_ne!(element, self.element);
if let Some(mut data) = element.mutate_data() { if let Some(mut data) = element.mutate_data() {
data.hint.insert(RestyleHint::RESTYLE_SELF); data.hint.insert(RESTYLE_SELF);
} }
} }
} }
@ -333,7 +333,7 @@ where
return true; return true;
} }
let visited_dependent = let visited_dependent =
if dependency.state.intersects(ElementState::IN_VISITED_OR_UNVISITED_STATE) { if dependency.state.intersects(IN_VISITED_OR_UNVISITED_STATE) {
VisitedDependent::Yes VisitedDependent::Yes
} else { } else {
VisitedDependent::No VisitedDependent::No

View file

@ -20,16 +20,16 @@ use smallvec::SmallVec;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
/// Gets the element state relevant to the given `:dir` pseudo-class selector. /// Gets the element state relevant to the given `:dir` pseudo-class selector.
pub fn dir_selector_to_state(s: &[u16]) -> ElementState { pub fn dir_selector_to_state(s: &[u16]) -> ElementState {
use element_state::ElementState; use element_state::{IN_LTR_STATE, IN_RTL_STATE};
// Jump through some hoops to deal with our Box<[u16]> thing. // Jump through some hoops to deal with our Box<[u16]> thing.
const LTR: [u16; 4] = [b'l' as u16, b't' as u16, b'r' as u16, 0]; const LTR: [u16; 4] = [b'l' as u16, b't' as u16, b'r' as u16, 0];
const RTL: [u16; 4] = [b'r' as u16, b't' as u16, b'l' as u16, 0]; const RTL: [u16; 4] = [b'r' as u16, b't' as u16, b'l' as u16, 0];
if LTR == *s { if LTR == *s {
ElementState::IN_LTR_STATE IN_LTR_STATE
} else if RTL == *s { } else if RTL == *s {
ElementState::IN_RTL_STATE IN_RTL_STATE
} else { } else {
// :dir(something-random) is a valid selector, but shouldn't // :dir(something-random) is a valid selector, but shouldn't
// match anything. // match anything.

View file

@ -10,38 +10,38 @@ use traversal_flags::TraversalFlags;
bitflags! { bitflags! {
/// The kind of restyle we need to do for a given element. /// The kind of restyle we need to do for a given element.
pub struct RestyleHint: u8 { pub flags RestyleHint: u8 {
/// Do a selector match of the element. /// Do a selector match of the element.
const RESTYLE_SELF = 1 << 0; const RESTYLE_SELF = 1 << 0,
/// Do a selector match of the element's descendants. /// Do a selector match of the element's descendants.
const RESTYLE_DESCENDANTS = 1 << 1; const RESTYLE_DESCENDANTS = 1 << 1,
/// Recascade the current element. /// Recascade the current element.
const RECASCADE_SELF = 1 << 2; const RECASCADE_SELF = 1 << 2,
/// Recascade all descendant elements. /// Recascade all descendant elements.
const RECASCADE_DESCENDANTS = 1 << 3; const RECASCADE_DESCENDANTS = 1 << 3,
/// Replace the style data coming from CSS transitions without updating /// Replace the style data coming from CSS transitions without updating
/// any other style data. This hint is only processed in animation-only /// any other style data. This hint is only processed in animation-only
/// traversal which is prior to normal traversal. /// traversal which is prior to normal traversal.
const RESTYLE_CSS_TRANSITIONS = 1 << 4; const RESTYLE_CSS_TRANSITIONS = 1 << 4,
/// Replace the style data coming from CSS animations without updating /// Replace the style data coming from CSS animations without updating
/// any other style data. This hint is only processed in animation-only /// any other style data. This hint is only processed in animation-only
/// traversal which is prior to normal traversal. /// traversal which is prior to normal traversal.
const RESTYLE_CSS_ANIMATIONS = 1 << 5; const RESTYLE_CSS_ANIMATIONS = 1 << 5,
/// Don't re-run selector-matching on the element, only the style /// Don't re-run selector-matching on the element, only the style
/// attribute has changed, and this change didn't have any other /// attribute has changed, and this change didn't have any other
/// dependencies. /// dependencies.
const RESTYLE_STYLE_ATTRIBUTE = 1 << 6; const RESTYLE_STYLE_ATTRIBUTE = 1 << 6,
/// Replace the style data coming from SMIL animations without updating /// Replace the style data coming from SMIL animations without updating
/// any other style data. This hint is only processed in animation-only /// any other style data. This hint is only processed in animation-only
/// traversal which is prior to normal traversal. /// traversal which is prior to normal traversal.
const RESTYLE_SMIL = 1 << 7; const RESTYLE_SMIL = 1 << 7,
} }
} }
@ -49,26 +49,26 @@ impl RestyleHint {
/// Creates a new `RestyleHint` indicating that the current element and all /// Creates a new `RestyleHint` indicating that the current element and all
/// its descendants must be fully restyled. /// its descendants must be fully restyled.
pub fn restyle_subtree() -> Self { pub fn restyle_subtree() -> Self {
RestyleHint::RESTYLE_SELF | RestyleHint::RESTYLE_DESCENDANTS RESTYLE_SELF | RESTYLE_DESCENDANTS
} }
/// Creates a new `RestyleHint` indicating that the current element and all /// Creates a new `RestyleHint` indicating that the current element and all
/// its descendants must be recascaded. /// its descendants must be recascaded.
pub fn recascade_subtree() -> Self { pub fn recascade_subtree() -> Self {
RestyleHint::RECASCADE_SELF | RestyleHint::RECASCADE_DESCENDANTS RECASCADE_SELF | RECASCADE_DESCENDANTS
} }
/// Returns whether this hint invalidates the element and all its /// Returns whether this hint invalidates the element and all its
/// descendants. /// descendants.
pub fn contains_subtree(&self) -> bool { pub fn contains_subtree(&self) -> bool {
self.contains(RestyleHint::RESTYLE_SELF | RestyleHint::RESTYLE_DESCENDANTS) self.contains(RESTYLE_SELF | RESTYLE_DESCENDANTS)
} }
/// Returns whether we need to restyle this element. /// Returns whether we need to restyle this element.
pub fn has_non_animation_invalidations(&self) -> bool { pub fn has_non_animation_invalidations(&self) -> bool {
self.intersects( self.intersects(
RestyleHint::RESTYLE_SELF | RESTYLE_SELF |
RestyleHint::RECASCADE_SELF | RECASCADE_SELF |
(Self::replacements() & !Self::for_animations()) (Self::replacements() & !Self::for_animations())
) )
} }
@ -96,10 +96,10 @@ impl RestyleHint {
/// Returns a new `CascadeHint` appropriate for children of the current /// Returns a new `CascadeHint` appropriate for children of the current
/// element. /// element.
fn propagate_for_non_animation_restyle(&self) -> Self { fn propagate_for_non_animation_restyle(&self) -> Self {
if self.contains(RestyleHint::RESTYLE_DESCENDANTS) { if self.contains(RESTYLE_DESCENDANTS) {
return Self::restyle_subtree() return Self::restyle_subtree()
} }
if self.contains(RestyleHint::RECASCADE_DESCENDANTS) { if self.contains(RECASCADE_DESCENDANTS) {
return Self::recascade_subtree() return Self::recascade_subtree()
} }
Self::empty() Self::empty()
@ -108,24 +108,24 @@ impl RestyleHint {
/// Creates a new `RestyleHint` that indicates the element must be /// Creates a new `RestyleHint` that indicates the element must be
/// recascaded. /// recascaded.
pub fn recascade_self() -> Self { pub fn recascade_self() -> Self {
RestyleHint::RECASCADE_SELF RECASCADE_SELF
} }
/// Returns a hint that contains all the replacement hints. /// Returns a hint that contains all the replacement hints.
pub fn replacements() -> Self { pub fn replacements() -> Self {
RestyleHint::RESTYLE_STYLE_ATTRIBUTE | Self::for_animations() RESTYLE_STYLE_ATTRIBUTE | Self::for_animations()
} }
/// The replacements for the animation cascade levels. /// The replacements for the animation cascade levels.
#[inline] #[inline]
pub fn for_animations() -> Self { pub fn for_animations() -> Self {
RestyleHint::RESTYLE_SMIL | RestyleHint::RESTYLE_CSS_ANIMATIONS | RestyleHint::RESTYLE_CSS_TRANSITIONS RESTYLE_SMIL | RESTYLE_CSS_ANIMATIONS | RESTYLE_CSS_TRANSITIONS
} }
/// Returns whether the hint specifies that the currently element must be /// Returns whether the hint specifies that the currently element must be
/// recascaded. /// recascaded.
pub fn has_recascade_self(&self) -> bool { pub fn has_recascade_self(&self) -> bool {
self.contains(RestyleHint::RECASCADE_SELF) self.contains(RECASCADE_SELF)
} }
/// Returns whether the hint specifies that an animation cascade level must /// Returns whether the hint specifies that an animation cascade level must
@ -139,7 +139,7 @@ impl RestyleHint {
/// be replaced. /// be replaced.
#[inline] #[inline]
pub fn has_animation_hint_or_recascade(&self) -> bool { pub fn has_animation_hint_or_recascade(&self) -> bool {
self.intersects(Self::for_animations() | RestyleHint::RECASCADE_SELF) self.intersects(Self::for_animations() | RECASCADE_SELF)
} }
/// Returns whether the hint specifies some restyle work other than an /// Returns whether the hint specifies some restyle work other than an
@ -153,7 +153,7 @@ impl RestyleHint {
/// for the element. /// for the element.
#[inline] #[inline]
pub fn match_self(&self) -> bool { pub fn match_self(&self) -> bool {
self.intersects(RestyleHint::RESTYLE_SELF) self.intersects(RESTYLE_SELF)
} }
/// Returns whether the hint specifies that some cascade levels must be /// Returns whether the hint specifies that some cascade levels must be
@ -177,7 +177,7 @@ impl RestyleHint {
// normal restyle. (We could have separate RECASCADE_SELF_NORMAL and // normal restyle. (We could have separate RECASCADE_SELF_NORMAL and
// RECASCADE_SELF_ANIMATIONS flags to make it clear, but this isn't // RECASCADE_SELF_ANIMATIONS flags to make it clear, but this isn't
// currently necessary.) // currently necessary.)
self.remove(RestyleHint::RECASCADE_SELF); self.remove(RECASCADE_SELF);
} }
} }
@ -204,23 +204,23 @@ impl From<nsRestyleHint> for RestyleHint {
if (raw.0 & (eRestyle_Self.0 | eRestyle_Subtree.0)) != 0 { if (raw.0 & (eRestyle_Self.0 | eRestyle_Subtree.0)) != 0 {
raw.0 &= !eRestyle_Self.0; raw.0 &= !eRestyle_Self.0;
hint.insert(RestyleHint::RESTYLE_SELF); hint.insert(RESTYLE_SELF);
} }
if (raw.0 & (eRestyle_Subtree.0 | eRestyle_SomeDescendants.0)) != 0 { if (raw.0 & (eRestyle_Subtree.0 | eRestyle_SomeDescendants.0)) != 0 {
raw.0 &= !eRestyle_Subtree.0; raw.0 &= !eRestyle_Subtree.0;
raw.0 &= !eRestyle_SomeDescendants.0; raw.0 &= !eRestyle_SomeDescendants.0;
hint.insert(RestyleHint::RESTYLE_DESCENDANTS); hint.insert(RESTYLE_DESCENDANTS);
} }
if (raw.0 & (eRestyle_ForceDescendants.0 | eRestyle_Force.0)) != 0 { if (raw.0 & (eRestyle_ForceDescendants.0 | eRestyle_Force.0)) != 0 {
raw.0 &= !eRestyle_Force.0; raw.0 &= !eRestyle_Force.0;
hint.insert(RestyleHint::RECASCADE_SELF); hint.insert(RECASCADE_SELF);
} }
if (raw.0 & eRestyle_ForceDescendants.0) != 0 { if (raw.0 & eRestyle_ForceDescendants.0) != 0 {
raw.0 &= !eRestyle_ForceDescendants.0; raw.0 &= !eRestyle_ForceDescendants.0;
hint.insert(RestyleHint::RECASCADE_DESCENDANTS); hint.insert(RECASCADE_DESCENDANTS);
} }
hint.insert(RestyleHint::from_bits_truncate(raw.0 as u8)); hint.insert(RestyleHint::from_bits_truncate(raw.0 as u8));
@ -239,7 +239,7 @@ pub fn assert_restyle_hints_match() {
use gecko_bindings::structs; use gecko_bindings::structs;
macro_rules! check_restyle_hints { macro_rules! check_restyle_hints {
( $( $a:ident => $b:path),*, ) => { ( $( $a:ident => $b:ident ),*, ) => {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
let mut replacements = RestyleHint::replacements(); let mut replacements = RestyleHint::replacements();
$( $(
@ -254,9 +254,9 @@ pub fn assert_restyle_hints_match() {
} }
check_restyle_hints! { check_restyle_hints! {
nsRestyleHint_eRestyle_CSSTransitions => RestyleHint::RESTYLE_CSS_TRANSITIONS, nsRestyleHint_eRestyle_CSSTransitions => RESTYLE_CSS_TRANSITIONS,
nsRestyleHint_eRestyle_CSSAnimations => RestyleHint::RESTYLE_CSS_ANIMATIONS, nsRestyleHint_eRestyle_CSSAnimations => RESTYLE_CSS_ANIMATIONS,
nsRestyleHint_eRestyle_StyleAttribute => RestyleHint::RESTYLE_STYLE_ATTRIBUTE, nsRestyleHint_eRestyle_StyleAttribute => RESTYLE_STYLE_ATTRIBUTE,
nsRestyleHint_eRestyle_StyleAttribute_Animations => RestyleHint::RESTYLE_SMIL, nsRestyleHint_eRestyle_StyleAttribute_Animations => RESTYLE_SMIL,
} }
} }

View file

@ -11,7 +11,7 @@ use Atom;
use LocalName as SelectorLocalName; use LocalName as SelectorLocalName;
use dom::{TElement, TNode}; use dom::{TElement, TNode};
use fnv::FnvHashSet; use fnv::FnvHashSet;
use invalidation::element::restyle_hints::RestyleHint; use invalidation::element::restyle_hints::{RESTYLE_SELF, RestyleHint};
use media_queries::Device; use media_queries::Device;
use selector_parser::SelectorImpl; use selector_parser::SelectorImpl;
use selectors::attr::CaseSensitivity; use selectors::attr::CaseSensitivity;
@ -223,12 +223,12 @@ impl StylesheetInvalidationSet {
let mut self_invalid = false; let mut self_invalid = false;
if !data.hint.contains(RestyleHint::RESTYLE_SELF) { if !data.hint.contains(RESTYLE_SELF) {
for invalidation in &self.invalid_elements { for invalidation in &self.invalid_elements {
if invalidation.matches(element) { if invalidation.matches(element) {
debug!("process_invalidations_in_subtree: {:?} matched self {:?}", debug!("process_invalidations_in_subtree: {:?} matched self {:?}",
element, invalidation); element, invalidation);
data.hint.insert(RestyleHint::RESTYLE_SELF); data.hint.insert(RESTYLE_SELF);
self_invalid = true; self_invalid = true;
break; break;
} }

View file

@ -25,51 +25,51 @@ pub enum InlineBaseDirection {
// TODO: improve the readability of the WritingMode serialization, refer to the Debug:fmt() // TODO: improve the readability of the WritingMode serialization, refer to the Debug:fmt()
bitflags!( bitflags!(
#[cfg_attr(feature = "servo", derive(MallocSizeOf, Serialize))] #[cfg_attr(feature = "servo", derive(MallocSizeOf, Serialize))]
pub struct WritingMode: u8 { pub flags WritingMode: u8 {
const RTL = 1 << 0; const FLAG_RTL = 1 << 0,
const VERTICAL = 1 << 1; const FLAG_VERTICAL = 1 << 1,
const VERTICAL_LR = 1 << 2; const FLAG_VERTICAL_LR = 1 << 2,
/// For vertical writing modes only. When set, line-over/line-under /// For vertical writing modes only. When set, line-over/line-under
/// sides are inverted from block-start/block-end. This flag is /// sides are inverted from block-start/block-end. This flag is
/// set when sideways-lr is used. /// set when sideways-lr is used.
const LINE_INVERTED = 1 << 3; const FLAG_LINE_INVERTED = 1 << 3,
const SIDEWAYS = 1 << 4; const FLAG_SIDEWAYS = 1 << 4,
const UPRIGHT = 1 << 5; const FLAG_UPRIGHT = 1 << 5,
} }
); );
impl WritingMode { impl WritingMode {
#[inline] #[inline]
pub fn is_vertical(&self) -> bool { pub fn is_vertical(&self) -> bool {
self.intersects(WritingMode::VERTICAL) self.intersects(FLAG_VERTICAL)
} }
/// Assuming .is_vertical(), does the block direction go left to right? /// Assuming .is_vertical(), does the block direction go left to right?
#[inline] #[inline]
pub fn is_vertical_lr(&self) -> bool { pub fn is_vertical_lr(&self) -> bool {
self.intersects(WritingMode::VERTICAL_LR) self.intersects(FLAG_VERTICAL_LR)
} }
/// Assuming .is_vertical(), does the inline direction go top to bottom? /// Assuming .is_vertical(), does the inline direction go top to bottom?
#[inline] #[inline]
pub fn is_inline_tb(&self) -> bool { pub fn is_inline_tb(&self) -> bool {
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical // https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
self.intersects(WritingMode::RTL) == self.intersects(WritingMode::LINE_INVERTED) self.intersects(FLAG_RTL) == self.intersects(FLAG_LINE_INVERTED)
} }
#[inline] #[inline]
pub fn is_bidi_ltr(&self) -> bool { pub fn is_bidi_ltr(&self) -> bool {
!self.intersects(WritingMode::RTL) !self.intersects(FLAG_RTL)
} }
#[inline] #[inline]
pub fn is_sideways(&self) -> bool { pub fn is_sideways(&self) -> bool {
self.intersects(WritingMode::SIDEWAYS) self.intersects(FLAG_SIDEWAYS)
} }
#[inline] #[inline]
pub fn is_upright(&self) -> bool { pub fn is_upright(&self) -> bool {
self.intersects(WritingMode::UPRIGHT) self.intersects(FLAG_UPRIGHT)
} }
#[inline] #[inline]
@ -121,7 +121,7 @@ impl WritingMode {
#[inline] #[inline]
pub fn inline_base_direction(&self) -> InlineBaseDirection { pub fn inline_base_direction(&self) -> InlineBaseDirection {
if self.intersects(WritingMode::RTL) { if self.intersects(FLAG_RTL) {
InlineBaseDirection::RightToLeft InlineBaseDirection::RightToLeft
} else { } else {
InlineBaseDirection::LeftToRight InlineBaseDirection::LeftToRight
@ -150,10 +150,10 @@ impl fmt::Display for WritingMode {
} else { } else {
write!(formatter, " RL")?; write!(formatter, " RL")?;
} }
if self.intersects(WritingMode::SIDEWAYS) { if self.intersects(FLAG_SIDEWAYS) {
write!(formatter, " Sideways")?; write!(formatter, " Sideways")?;
} }
if self.intersects(WritingMode::LINE_INVERTED) { if self.intersects(FLAG_LINE_INVERTED) {
write!(formatter, " Inverted")?; write!(formatter, " Inverted")?;
} }
} else { } else {

View file

@ -11,6 +11,8 @@ use context::{ElementCascadeInputs, QuirksMode, SelectorFlagsMap};
use context::{SharedStyleContext, StyleContext}; use context::{SharedStyleContext, StyleContext};
use data::ElementData; use data::ElementData;
use dom::TElement; use dom::TElement;
use invalidation::element::restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_TRANSITIONS};
use invalidation::element::restyle_hints::{RESTYLE_SMIL, RESTYLE_STYLE_ATTRIBUTE};
use invalidation::element::restyle_hints::RestyleHint; use invalidation::element::restyle_hints::RestyleHint;
use properties::ComputedValues; use properties::ComputedValues;
use rule_tree::{CascadeLevel, StrongRuleNode}; use rule_tree::{CascadeLevel, StrongRuleNode};
@ -18,7 +20,7 @@ use selector_parser::{PseudoElement, RestyleDamage};
use selectors::matching::ElementSelectorFlags; use selectors::matching::ElementSelectorFlags;
use servo_arc::{Arc, ArcBorrow}; use servo_arc::{Arc, ArcBorrow};
use style_resolver::ResolvedElementStyles; use style_resolver::ResolvedElementStyles;
use traversal_flags::TraversalFlags; use traversal_flags;
/// Represents the result of comparing an element's old and new style. /// Represents the result of comparing an element's old and new style.
#[derive(Debug)] #[derive(Debug)]
@ -159,7 +161,7 @@ trait PrivateMatchMethods: TElement {
// animation is running or not. // animation is running or not.
// TODO: We should check which @keyframes changed/added/deleted // TODO: We should check which @keyframes changed/added/deleted
// and update only animations corresponding to those @keyframes. // and update only animations corresponding to those @keyframes.
(context.shared.traversal_flags.contains(TraversalFlags::ForCSSRuleChanges) && (context.shared.traversal_flags.contains(traversal_flags::ForCSSRuleChanges) &&
(has_new_animation_style || has_animations)) || (has_new_animation_style || has_animations)) ||
!old_box_style.animations_equals(new_box_style) || !old_box_style.animations_equals(new_box_style) ||
(old_display_style == display::T::none && (old_display_style == display::T::none &&
@ -181,10 +183,10 @@ trait PrivateMatchMethods: TElement {
new_values: &ComputedValues, new_values: &ComputedValues,
restyle_hints: RestyleHint restyle_hints: RestyleHint
) { ) {
use context::PostAnimationTasks; use context::DISPLAY_CHANGED_FROM_NONE_FOR_SMIL;
use properties::longhands::display::computed_value as display; use properties::longhands::display::computed_value as display;
if !restyle_hints.intersects(RestyleHint::RESTYLE_SMIL) { if !restyle_hints.intersects(RESTYLE_SMIL) {
return; return;
} }
@ -204,7 +206,7 @@ trait PrivateMatchMethods: TElement {
// restyle). // restyle).
let task = ::context::SequentialTask::process_post_animation( let task = ::context::SequentialTask::process_post_animation(
*self, *self,
PostAnimationTasks::DISPLAY_CHANGED_FROM_NONE_FOR_SMIL, DISPLAY_CHANGED_FROM_NONE_FOR_SMIL,
); );
context.thread_local.tasks.push(task); context.thread_local.tasks.push(task);
} }
@ -217,6 +219,7 @@ trait PrivateMatchMethods: TElement {
new_values: &mut Arc<ComputedValues>, new_values: &mut Arc<ComputedValues>,
restyle_hint: RestyleHint, restyle_hint: RestyleHint,
important_rules_changed: bool) { important_rules_changed: bool) {
use context::{CASCADE_RESULTS, CSS_ANIMATIONS, CSS_TRANSITIONS, EFFECT_PROPERTIES};
use context::UpdateAnimationsTasks; use context::UpdateAnimationsTasks;
if context.shared.traversal_flags.for_animation_only() { if context.shared.traversal_flags.for_animation_only() {
@ -234,7 +237,7 @@ trait PrivateMatchMethods: TElement {
let mut tasks = UpdateAnimationsTasks::empty(); let mut tasks = UpdateAnimationsTasks::empty();
if self.needs_animations_update(context, old_values.as_ref(), new_values) { if self.needs_animations_update(context, old_values.as_ref(), new_values) {
tasks.insert(UpdateAnimationsTasks::CSS_ANIMATIONS); tasks.insert(CSS_ANIMATIONS);
} }
let before_change_style = if self.might_need_transitions_update(old_values.as_ref().map(|s| &**s), let before_change_style = if self.might_need_transitions_update(old_values.as_ref().map(|s| &**s),
@ -262,7 +265,7 @@ trait PrivateMatchMethods: TElement {
if let Some(values_without_transitions) = after_change_style { if let Some(values_without_transitions) = after_change_style {
*new_values = values_without_transitions; *new_values = values_without_transitions;
} }
tasks.insert(UpdateAnimationsTasks::CSS_TRANSITIONS); tasks.insert(CSS_TRANSITIONS);
// We need to clone old_values into SequentialTask, so we can use it later. // We need to clone old_values into SequentialTask, so we can use it later.
old_values.clone() old_values.clone()
@ -274,9 +277,9 @@ trait PrivateMatchMethods: TElement {
}; };
if self.has_animations() { if self.has_animations() {
tasks.insert(UpdateAnimationsTasks::EFFECT_PROPERTIES); tasks.insert(EFFECT_PROPERTIES);
if important_rules_changed { if important_rules_changed {
tasks.insert(UpdateAnimationsTasks::CASCADE_RESULTS); tasks.insert(CASCADE_RESULTS);
} }
} }
@ -342,7 +345,7 @@ trait PrivateMatchMethods: TElement {
debug!("accumulate_damage_for: {:?}", self); debug!("accumulate_damage_for: {:?}", self);
// Don't accumulate damage if we're in a forgetful traversal. // Don't accumulate damage if we're in a forgetful traversal.
if shared_context.traversal_flags.contains(TraversalFlags::Forgetful) { if shared_context.traversal_flags.contains(traversal_flags::Forgetful) {
debug!(" > forgetful traversal"); debug!(" > forgetful traversal");
return ChildCascadeRequirement::MustCascadeChildren; return ChildCascadeRequirement::MustCascadeChildren;
} }
@ -398,7 +401,7 @@ trait PrivateMatchMethods: TElement {
// seems not common enough to care about. // seems not common enough to care about.
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
{ {
use values::specified::align::AlignFlags; use values::specified::align;
let old_justify_items = let old_justify_items =
old_values.get_position().clone_justify_items(); old_values.get_position().clone_justify_items();
@ -406,10 +409,10 @@ trait PrivateMatchMethods: TElement {
new_values.get_position().clone_justify_items(); new_values.get_position().clone_justify_items();
let was_legacy_justify_items = let was_legacy_justify_items =
old_justify_items.computed.0.contains(AlignFlags::LEGACY); old_justify_items.computed.0.contains(align::ALIGN_LEGACY);
let is_legacy_justify_items = let is_legacy_justify_items =
new_justify_items.computed.0.contains(AlignFlags::LEGACY); new_justify_items.computed.0.contains(align::ALIGN_LEGACY);
if is_legacy_justify_items != was_legacy_justify_items { if is_legacy_justify_items != was_legacy_justify_items {
return ChildCascadeRequirement::MustCascadeChildren; return ChildCascadeRequirement::MustCascadeChildren;
@ -581,7 +584,7 @@ pub trait MatchMethods : TElement {
} }
// Don't accumulate damage if we're in a forgetful traversal. // Don't accumulate damage if we're in a forgetful traversal.
if context.shared.traversal_flags.contains(TraversalFlags::Forgetful) { if context.shared.traversal_flags.contains(traversal_flags::Forgetful) {
return ChildCascadeRequirement::MustCascadeChildren; return ChildCascadeRequirement::MustCascadeChildren;
} }
@ -765,7 +768,7 @@ pub trait MatchMethods : TElement {
if !context.shared.traversal_flags.for_animation_only() { if !context.shared.traversal_flags.for_animation_only() {
let mut result = false; let mut result = false;
if replacements.contains(RestyleHint::RESTYLE_STYLE_ATTRIBUTE) { if replacements.contains(RESTYLE_STYLE_ATTRIBUTE) {
let style_attribute = self.style_attribute(); let style_attribute = self.style_attribute();
result |= replace_rule_node(CascadeLevel::StyleAttributeNormal, result |= replace_rule_node(CascadeLevel::StyleAttributeNormal,
style_attribute, style_attribute,
@ -787,7 +790,7 @@ pub trait MatchMethods : TElement {
if replacements.intersects(RestyleHint::for_animations()) { if replacements.intersects(RestyleHint::for_animations()) {
debug_assert!(context.shared.traversal_flags.for_animation_only()); debug_assert!(context.shared.traversal_flags.for_animation_only());
if replacements.contains(RestyleHint::RESTYLE_SMIL) { if replacements.contains(RESTYLE_SMIL) {
replace_rule_node(CascadeLevel::SMILOverride, replace_rule_node(CascadeLevel::SMILOverride,
self.get_smil_override(), self.get_smil_override(),
primary_rules); primary_rules);
@ -803,12 +806,12 @@ pub trait MatchMethods : TElement {
// Apply Transition rules and Animation rules if the corresponding restyle hint // Apply Transition rules and Animation rules if the corresponding restyle hint
// is contained. // is contained.
if replacements.contains(RestyleHint::RESTYLE_CSS_TRANSITIONS) { if replacements.contains(RESTYLE_CSS_TRANSITIONS) {
replace_rule_node_for_animation(CascadeLevel::Transitions, replace_rule_node_for_animation(CascadeLevel::Transitions,
primary_rules); primary_rules);
} }
if replacements.contains(RestyleHint::RESTYLE_CSS_ANIMATIONS) { if replacements.contains(RESTYLE_CSS_ANIMATIONS) {
replace_rule_node_for_animation(CascadeLevel::Animations, replace_rule_node_for_animation(CascadeLevel::Animations,
primary_rules); primary_rules);
} }

View file

@ -8,6 +8,8 @@ use context::QuirksMode;
use cssparser::{Parser, SourceLocation, UnicodeRange}; use cssparser::{Parser, SourceLocation, UnicodeRange};
use error_reporting::{ParseErrorReporter, ContextualParseError}; use error_reporting::{ParseErrorReporter, ContextualParseError};
use style_traits::{OneOrMoreSeparated, ParseError, ParsingMode, Separator}; use style_traits::{OneOrMoreSeparated, ParseError, ParsingMode, Separator};
#[cfg(feature = "gecko")]
use style_traits::{PARSING_MODE_DEFAULT, PARSING_MODE_ALLOW_UNITLESS_LENGTH, PARSING_MODE_ALLOW_ALL_NUMERIC_VALUES};
use stylesheets::{CssRuleType, Origin, UrlExtraData, Namespaces}; use stylesheets::{CssRuleType, Origin, UrlExtraData, Namespaces};
/// Asserts that all ParsingMode flags have a matching ParsingMode value in gecko. /// Asserts that all ParsingMode flags have a matching ParsingMode value in gecko.
@ -17,7 +19,7 @@ pub fn assert_parsing_mode_match() {
use gecko_bindings::structs; use gecko_bindings::structs;
macro_rules! check_parsing_modes { macro_rules! check_parsing_modes {
( $( $a:ident => $b:path ),*, ) => { ( $( $a:ident => $b:ident ),*, ) => {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
let mut modes = ParsingMode::all(); let mut modes = ParsingMode::all();
$( $(
@ -30,9 +32,9 @@ pub fn assert_parsing_mode_match() {
} }
check_parsing_modes! { check_parsing_modes! {
ParsingMode_Default => ParsingMode::DEFAULT, ParsingMode_Default => PARSING_MODE_DEFAULT,
ParsingMode_AllowUnitlessLength => ParsingMode::ALLOW_UNITLESS_LENGTH, ParsingMode_AllowUnitlessLength => PARSING_MODE_ALLOW_UNITLESS_LENGTH,
ParsingMode_AllowAllNumericValues => ParsingMode::ALLOW_ALL_NUMERIC_VALUES, ParsingMode_AllowAllNumericValues => PARSING_MODE_ALLOW_ALL_NUMERIC_VALUES,
} }
} }

View file

@ -11,13 +11,13 @@ bitflags! {
/// anonymous boxes, see StyleBuilder::for_inheritance and its callsites. /// anonymous boxes, see StyleBuilder::for_inheritance and its callsites.
/// If we ever want to add some flags that shouldn't inherit for them, /// If we ever want to add some flags that shouldn't inherit for them,
/// we might want to add a function to handle this. /// we might want to add a function to handle this.
pub struct ComputedValueFlags: u16 { pub flags ComputedValueFlags: u16 {
/// Whether the style or any of the ancestors has a text-decoration-line /// Whether the style or any of the ancestors has a text-decoration-line
/// property that should get propagated to descendants. /// property that should get propagated to descendants.
/// ///
/// text-decoration-line is a reset property, but gets propagated in the /// text-decoration-line is a reset property, but gets propagated in the
/// frame/box tree. /// frame/box tree.
const HAS_TEXT_DECORATION_LINES = 1 << 0; const HAS_TEXT_DECORATION_LINES = 1 << 0,
/// Whether line break inside should be suppressed. /// Whether line break inside should be suppressed.
/// ///
@ -27,41 +27,41 @@ bitflags! {
/// ///
/// This bit is propagated to all children of line participants. /// This bit is propagated to all children of line participants.
/// It is currently used by ruby to make its content unbreakable. /// It is currently used by ruby to make its content unbreakable.
const SHOULD_SUPPRESS_LINEBREAK = 1 << 1; const SHOULD_SUPPRESS_LINEBREAK = 1 << 1,
/// A flag used to mark text that that has text-combine-upright. /// A flag used to mark text that that has text-combine-upright.
/// ///
/// This is used from Gecko's layout engine. /// This is used from Gecko's layout engine.
const IS_TEXT_COMBINED = 1 << 2; const IS_TEXT_COMBINED = 1 << 2,
/// A flag used to mark styles under a relevant link that is also /// A flag used to mark styles under a relevant link that is also
/// visited. /// visited.
const IS_RELEVANT_LINK_VISITED = 1 << 3; const IS_RELEVANT_LINK_VISITED = 1 << 3,
/// A flag used to mark styles which are a pseudo-element or under one. /// A flag used to mark styles which are a pseudo-element or under one.
const IS_IN_PSEUDO_ELEMENT_SUBTREE = 1 << 4; const IS_IN_PSEUDO_ELEMENT_SUBTREE = 1 << 4,
/// A flag used to mark styles which are in a display: none subtree, or /// A flag used to mark styles which are in a display: none subtree, or
/// under one. /// under one.
const IS_IN_DISPLAY_NONE_SUBTREE = 1 << 5; const IS_IN_DISPLAY_NONE_SUBTREE = 1 << 5,
/// Whether this style inherits the `display` property. /// Whether this style inherits the `display` property.
/// ///
/// This is important because it may affect our optimizations to avoid /// This is important because it may affect our optimizations to avoid
/// computing the style of pseudo-elements, given whether the /// computing the style of pseudo-elements, given whether the
/// pseudo-element is generated depends on the `display` value. /// pseudo-element is generated depends on the `display` value.
const INHERITS_DISPLAY = 1 << 6; const INHERITS_DISPLAY = 1 << 6,
/// Whether this style inherits the `content` property. /// Whether this style inherits the `content` property.
/// ///
/// Important because of the same reason. /// Important because of the same reason.
const INHERITS_CONTENT = 1 << 7; const INHERITS_CONTENT = 1 << 7,
/// Whether the child explicitly inherits any reset property. /// Whether the child explicitly inherits any reset property.
const INHERITS_RESET_STYLE = 1 << 8; const INHERITS_RESET_STYLE = 1 << 8,
/// A flag to mark a style which is a visited style. /// A flag to mark a style which is a visited style.
const IS_STYLE_IF_VISITED = 1 << 9; const IS_STYLE_IF_VISITED = 1 << 9,
} }
} }
@ -69,8 +69,6 @@ impl ComputedValueFlags {
/// Returns the flags that are inherited. /// Returns the flags that are inherited.
#[inline] #[inline]
pub fn inherited(self) -> Self { pub fn inherited(self) -> Self {
self & !(ComputedValueFlags::INHERITS_DISPLAY | self & !(INHERITS_DISPLAY | INHERITS_CONTENT | INHERITS_RESET_STYLE)
ComputedValueFlags::INHERITS_CONTENT |
ComputedValueFlags::INHERITS_RESET_STYLE)
} }
} }

View file

@ -19,7 +19,7 @@ use smallvec::SmallVec;
use std::fmt; use std::fmt;
use std::iter::{DoubleEndedIterator, Zip}; use std::iter::{DoubleEndedIterator, Zip};
use std::slice::Iter; use std::slice::Iter;
use style_traits::{ToCss, ParseError, ParsingMode, StyleParseErrorKind}; use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseErrorKind};
use stylesheets::{CssRuleType, Origin, UrlExtraData}; use stylesheets::{CssRuleType, Origin, UrlExtraData};
use super::*; use super::*;
use values::computed::Context; use values::computed::Context;
@ -853,7 +853,7 @@ impl ToCss for PropertyDeclarationBlock {
// Substeps 7 and 8 // Substeps 7 and 8
// We need to check the shorthand whether it's an alias property or not. // We need to check the shorthand whether it's an alias property or not.
// If it's an alias property, it should be serialized like its longhand. // If it's an alias property, it should be serialized like its longhand.
if shorthand.flags().contains(PropertyFlags::SHORTHAND_ALIAS_PROPERTY) { if shorthand.flags().contains(SHORTHAND_ALIAS_PROPERTY) {
append_serialization::<_, Cloned<slice::Iter< _>>, _>( append_serialization::<_, Cloned<slice::Iter< _>>, _>(
dest, dest,
&property, &property,
@ -1023,7 +1023,7 @@ pub fn parse_style_attribute<R>(input: &str,
let context = ParserContext::new(Origin::Author, let context = ParserContext::new(Origin::Author,
url_data, url_data,
Some(CssRuleType::Style), Some(CssRuleType::Style),
ParsingMode::DEFAULT, PARSING_MODE_DEFAULT,
quirks_mode); quirks_mode);
let error_context = ParserErrorContext { error_reporter: error_reporter }; let error_context = ParserErrorContext { error_reporter: error_reporter };
let mut input = ParserInput::new(input); let mut input = ParserInput::new(input);

View file

@ -1538,7 +1538,7 @@ fn static_assert() {
} }
pub fn set_computed_justify_items(&mut self, v: values::specified::JustifyItems) { pub fn set_computed_justify_items(&mut self, v: values::specified::JustifyItems) {
debug_assert!(v.0 != ::values::specified::align::AlignFlags::AUTO); debug_assert!(v.0 != ::values::specified::align::ALIGN_AUTO);
self.gecko.mJustifyItems = v.into(); self.gecko.mJustifyItems = v.into();
} }
@ -3364,20 +3364,20 @@ fn static_assert() {
use properties::longhands::will_change::computed_value::T; use properties::longhands::will_change::computed_value::T;
fn will_change_bitfield_from_prop_flags(prop: &LonghandId) -> u8 { fn will_change_bitfield_from_prop_flags(prop: &LonghandId) -> u8 {
use properties::PropertyFlags; use properties::{ABSPOS_CB, CREATES_STACKING_CONTEXT, FIXPOS_CB};
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_ABSPOS_CB; use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_ABSPOS_CB;
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_FIXPOS_CB; use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_FIXPOS_CB;
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_STACKING_CONTEXT; use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_STACKING_CONTEXT;
let servo_flags = prop.flags(); let servo_flags = prop.flags();
let mut bitfield = 0; let mut bitfield = 0;
if servo_flags.contains(PropertyFlags::CREATES_STACKING_CONTEXT) { if servo_flags.contains(CREATES_STACKING_CONTEXT) {
bitfield |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT; bitfield |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT;
} }
if servo_flags.contains(PropertyFlags::FIXPOS_CB) { if servo_flags.contains(FIXPOS_CB) {
bitfield |= NS_STYLE_WILL_CHANGE_FIXPOS_CB; bitfield |= NS_STYLE_WILL_CHANGE_FIXPOS_CB;
} }
if servo_flags.contains(PropertyFlags::ABSPOS_CB) { if servo_flags.contains(ABSPOS_CB) {
bitfield |= NS_STYLE_WILL_CHANGE_ABSPOS_CB; bitfield |= NS_STYLE_WILL_CHANGE_ABSPOS_CB;
} }
@ -3470,26 +3470,26 @@ fn static_assert() {
use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE; use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE;
use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT; use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT;
use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS; use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS;
use properties::longhands::contain::SpecifiedValue; use properties::longhands::contain;
if v.is_empty() { if v.is_empty() {
self.gecko.mContain = NS_STYLE_CONTAIN_NONE as u8; self.gecko.mContain = NS_STYLE_CONTAIN_NONE as u8;
return; return;
} }
if v.contains(SpecifiedValue::STRICT) { if v.contains(contain::STRICT) {
self.gecko.mContain = (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS) as u8; self.gecko.mContain = (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS) as u8;
return; return;
} }
let mut bitfield = 0; let mut bitfield = 0;
if v.contains(SpecifiedValue::LAYOUT) { if v.contains(contain::LAYOUT) {
bitfield |= NS_STYLE_CONTAIN_LAYOUT; bitfield |= NS_STYLE_CONTAIN_LAYOUT;
} }
if v.contains(SpecifiedValue::STYLE) { if v.contains(contain::STYLE) {
bitfield |= NS_STYLE_CONTAIN_STYLE; bitfield |= NS_STYLE_CONTAIN_STYLE;
} }
if v.contains(SpecifiedValue::PAINT) { if v.contains(contain::PAINT) {
bitfield |= NS_STYLE_CONTAIN_PAINT; bitfield |= NS_STYLE_CONTAIN_PAINT;
} }
@ -3502,25 +3502,25 @@ fn static_assert() {
use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE; use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE;
use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT; use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT;
use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS; use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS;
use properties::longhands::contain::{self, SpecifiedValue}; use properties::longhands::contain;
let mut servo_flags = contain::computed_value::T::empty(); let mut servo_flags = contain::computed_value::T::empty();
let gecko_flags = self.gecko.mContain; let gecko_flags = self.gecko.mContain;
if gecko_flags & (NS_STYLE_CONTAIN_STRICT as u8) != 0 && if gecko_flags & (NS_STYLE_CONTAIN_STRICT as u8) != 0 &&
gecko_flags & (NS_STYLE_CONTAIN_ALL_BITS as u8) != 0 { gecko_flags & (NS_STYLE_CONTAIN_ALL_BITS as u8) != 0 {
servo_flags.insert(SpecifiedValue::STRICT | SpecifiedValue::STRICT_BITS); servo_flags.insert(contain::STRICT | contain::STRICT_BITS);
return servo_flags; return servo_flags;
} }
if gecko_flags & (NS_STYLE_CONTAIN_LAYOUT as u8) != 0 { if gecko_flags & (NS_STYLE_CONTAIN_LAYOUT as u8) != 0 {
servo_flags.insert(SpecifiedValue::LAYOUT); servo_flags.insert(contain::LAYOUT);
} }
if gecko_flags & (NS_STYLE_CONTAIN_STYLE as u8) != 0{ if gecko_flags & (NS_STYLE_CONTAIN_STYLE as u8) != 0{
servo_flags.insert(SpecifiedValue::STYLE); servo_flags.insert(contain::STYLE);
} }
if gecko_flags & (NS_STYLE_CONTAIN_PAINT as u8) != 0 { if gecko_flags & (NS_STYLE_CONTAIN_PAINT as u8) != 0 {
servo_flags.insert(SpecifiedValue::PAINT); servo_flags.insert(contain::PAINT);
} }
return servo_flags; return servo_flags;

View file

@ -15,8 +15,7 @@ ${helpers.predefined_type(
animation_value_type="AnimatedColor", animation_value_type="AnimatedColor",
ignored_when_colors_disabled=True, ignored_when_colors_disabled=True,
allow_quirks=True, allow_quirks=True,
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
PropertyFlags::APPLIES_TO_PLACEHOLDER""",
)} )}
${helpers.predefined_type("background-image", "ImageLayer", ${helpers.predefined_type("background-image", "ImageLayer",
@ -26,8 +25,7 @@ ${helpers.predefined_type("background-image", "ImageLayer",
vector="True", vector="True",
animation_value_type="discrete", animation_value_type="discrete",
ignored_when_colors_disabled="True", ignored_when_colors_disabled="True",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
PropertyFlags::APPLIES_TO_PLACEHOLDER""")}
% for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]: % for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]:
${helpers.predefined_type( ${helpers.predefined_type(
@ -38,15 +36,13 @@ ${helpers.predefined_type("background-image", "ImageLayer",
spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-" + axis, spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-" + axis,
animation_value_type="ComputedValue", animation_value_type="ComputedValue",
vector=True, vector=True,
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
PropertyFlags::APPLIES_TO_PLACEHOLDER""",
)} )}
% endfor % endfor
<%helpers:vector_longhand name="background-repeat" animation_value_type="discrete" <%helpers:vector_longhand name="background-repeat" animation_value_type="discrete"
spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat" spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat"
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER">
PropertyFlags::APPLIES_TO_PLACEHOLDER""">
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
@ -146,8 +142,7 @@ ${helpers.single_keyword("background-attachment",
gecko_constant_prefix="NS_STYLE_IMAGELAYER_ATTACHMENT", gecko_constant_prefix="NS_STYLE_IMAGELAYER_ATTACHMENT",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment", spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
animation_value_type="discrete", animation_value_type="discrete",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
PropertyFlags::APPLIES_TO_PLACEHOLDER""")}
${helpers.single_keyword("background-clip", ${helpers.single_keyword("background-clip",
"border-box padding-box content-box", "border-box padding-box content-box",
@ -156,8 +151,7 @@ ${helpers.single_keyword("background-clip",
gecko_enum_prefix="StyleGeometryBox", gecko_enum_prefix="StyleGeometryBox",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-clip", spec="https://drafts.csswg.org/css-backgrounds/#the-background-clip",
animation_value_type="discrete", animation_value_type="discrete",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
PropertyFlags::APPLIES_TO_PLACEHOLDER""")}
${helpers.single_keyword("background-origin", ${helpers.single_keyword("background-origin",
"padding-box border-box content-box", "padding-box border-box content-box",
@ -165,8 +159,7 @@ ${helpers.single_keyword("background-origin",
gecko_enum_prefix="StyleGeometryBox", gecko_enum_prefix="StyleGeometryBox",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-origin", spec="https://drafts.csswg.org/css-backgrounds/#the-background-origin",
animation_value_type="discrete", animation_value_type="discrete",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
PropertyFlags::APPLIES_TO_PLACEHOLDER""")}
${helpers.predefined_type("background-size", "BackgroundSize", ${helpers.predefined_type("background-size", "BackgroundSize",
initial_value="computed::BackgroundSize::auto()", initial_value="computed::BackgroundSize::auto()",
@ -175,8 +168,7 @@ ${helpers.predefined_type("background-size", "BackgroundSize",
vector=True, vector=True,
animation_value_type="BackgroundSizeList", animation_value_type="BackgroundSizeList",
need_animatable=True, need_animatable=True,
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
PropertyFlags::APPLIES_TO_PLACEHOLDER""",
extra_prefixes="webkit")} extra_prefixes="webkit")}
// https://drafts.fxtf.org/compositing/#background-blend-mode // https://drafts.fxtf.org/compositing/#background-blend-mode
@ -187,5 +179,4 @@ ${helpers.single_keyword("background-blend-mode",
gecko_constant_prefix="NS_STYLE_BLEND", gecko_constant_prefix="NS_STYLE_BLEND",
vector=True, products="gecko", animation_value_type="discrete", vector=True, products="gecko", animation_value_type="discrete",
spec="https://drafts.fxtf.org/compositing/#background-blend-mode", spec="https://drafts.fxtf.org/compositing/#background-blend-mode",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
PropertyFlags::APPLIES_TO_PLACEHOLDER""")}

View file

@ -28,7 +28,7 @@
animation_value_type="AnimatedColor", animation_value_type="AnimatedColor",
logical=is_logical, logical=is_logical,
allow_quirks=not is_logical, allow_quirks=not is_logical,
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
ignored_when_colors_disabled=True, ignored_when_colors_disabled=True,
)} )}
@ -36,7 +36,7 @@
"specified::BorderStyle::none", "specified::BorderStyle::none",
alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-style"), alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-style"),
spec=maybe_logical_spec(side, "style"), spec=maybe_logical_spec(side, "style"),
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
animation_value_type="discrete" if not is_logical else "none", animation_value_type="discrete" if not is_logical else "none",
logical=is_logical)} logical=is_logical)}
@ -48,7 +48,7 @@
spec=maybe_logical_spec(side, "width"), spec=maybe_logical_spec(side, "width"),
animation_value_type="NonNegativeLength", animation_value_type="NonNegativeLength",
logical=is_logical, logical=is_logical,
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
allow_quirks=not is_logical)} allow_quirks=not is_logical)}
% endfor % endfor
@ -63,7 +63,7 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style',
"parse", extra_prefixes="webkit", "parse", extra_prefixes="webkit",
spec="https://drafts.csswg.org/css-backgrounds/#border-%s-radius" % corner, spec="https://drafts.csswg.org/css-backgrounds/#border-%s-radius" % corner,
boxed=True, boxed=True,
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
animation_value_type="BorderCornerRadius")} animation_value_type="BorderCornerRadius")}
% endfor % endfor
@ -73,7 +73,7 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style',
<%helpers:longhand name="-moz-border-${side}-colors" animation_value_type="discrete" <%helpers:longhand name="-moz-border-${side}-colors" animation_value_type="discrete"
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-border-*-colors)" spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-border-*-colors)"
products="gecko" products="gecko"
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER" flags="APPLIES_TO_FIRST_LETTER"
ignored_when_colors_disabled="True"> ignored_when_colors_disabled="True">
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
@ -207,7 +207,7 @@ ${helpers.predefined_type("border-image-source", "ImageLayer",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-image", spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
vector=False, vector=False,
animation_value_type="discrete", animation_value_type="discrete",
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
boxed="True")} boxed="True")}
${helpers.predefined_type("border-image-outset", "LengthOrNumberRect", ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect",
@ -216,11 +216,11 @@ ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect",
initial_specified_value="specified::LengthOrNumberRect::all(specified::LengthOrNumber::zero())", initial_specified_value="specified::LengthOrNumberRect::all(specified::LengthOrNumber::zero())",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset", spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
animation_value_type="discrete", animation_value_type="discrete",
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
boxed=True)} boxed=True)}
<%helpers:longhand name="border-image-repeat" animation_value_type="discrete" <%helpers:longhand name="border-image-repeat" animation_value_type="discrete"
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER" flags="APPLIES_TO_FIRST_LETTER"
spec="https://drafts.csswg.org/css-backgrounds/#border-image-repeat"> spec="https://drafts.csswg.org/css-backgrounds/#border-image-repeat">
use style_traits::ToCss; use style_traits::ToCss;
@ -279,7 +279,7 @@ ${helpers.predefined_type("border-image-width", "BorderImageWidth",
initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())", initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-width", spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
animation_value_type="discrete", animation_value_type="discrete",
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
boxed=True)} boxed=True)}
${helpers.predefined_type("border-image-slice", "BorderImageSlice", ${helpers.predefined_type("border-image-slice", "BorderImageSlice",
@ -287,7 +287,7 @@ ${helpers.predefined_type("border-image-slice", "BorderImageSlice",
initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()", initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice", spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
animation_value_type="discrete", animation_value_type="discrete",
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
boxed=True)} boxed=True)}
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]

View file

@ -16,7 +16,7 @@
<%helpers:longhand name="display" <%helpers:longhand name="display"
animation_value_type="discrete" animation_value_type="discrete"
custom_cascade="${product == 'servo'}" custom_cascade="${product == 'servo'}"
flags="PropertyFlags::APPLIES_TO_PLACEHOLDER" flags="APPLIES_TO_PLACEHOLDER"
spec="https://drafts.csswg.org/css-display/#propdef-display"> spec="https://drafts.csswg.org/css-display/#propdef-display">
<% <%
values = """inline block inline-block values = """inline block inline-block
@ -227,7 +227,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
${helpers.single_keyword("position", "static absolute relative fixed sticky", ${helpers.single_keyword("position", "static absolute relative fixed sticky",
animation_value_type="discrete", animation_value_type="discrete",
flags="PropertyFlags::CREATES_STACKING_CONTEXT PropertyFlags::ABSPOS_CB", flags="CREATES_STACKING_CONTEXT ABSPOS_CB",
spec="https://drafts.csswg.org/css-position/#position-property")} spec="https://drafts.csswg.org/css-position/#position-property")}
<%helpers:single_keyword_computed name="float" <%helpers:single_keyword_computed name="float"
@ -240,7 +240,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed sticky",
gecko_inexhaustive="True" gecko_inexhaustive="True"
gecko_ffi_name="mFloat" gecko_ffi_name="mFloat"
gecko_pref_ident="float_" gecko_pref_ident="float_"
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER" flags="APPLIES_TO_FIRST_LETTER"
spec="https://drafts.csswg.org/css-box/#propdef-float"> spec="https://drafts.csswg.org/css-box/#propdef-float">
impl ToComputedValue for SpecifiedValue { impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
@ -362,8 +362,7 @@ ${helpers.predefined_type(
"VerticalAlign", "VerticalAlign",
"computed::VerticalAlign::baseline()", "computed::VerticalAlign::baseline()",
animation_value_type="ComputedValue", animation_value_type="ComputedValue",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
PropertyFlags::APPLIES_TO_PLACEHOLDER""",
spec="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align", spec="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align",
)} )}
@ -376,7 +375,7 @@ ${helpers.single_keyword("-servo-overflow-clip-box", "padding-box content-box",
${helpers.single_keyword("overflow-clip-box", "padding-box content-box", ${helpers.single_keyword("overflow-clip-box", "padding-box content-box",
products="gecko", animation_value_type="discrete", internal=True, products="gecko", animation_value_type="discrete", internal=True,
flags="PropertyFlags::APPLIES_TO_PLACEHOLDER", flags="APPLIES_TO_PLACEHOLDER",
spec="Internal, not web-exposed, \ spec="Internal, not web-exposed, \
may be standardized in the future (https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box)")} may be standardized in the future (https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box)")}
@ -390,12 +389,12 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
extra_gecko_values="-moz-hidden-unscrollable", extra_gecko_values="-moz-hidden-unscrollable",
custom_consts=overflow_custom_consts, custom_consts=overflow_custom_consts,
gecko_constant_prefix="NS_STYLE_OVERFLOW", gecko_constant_prefix="NS_STYLE_OVERFLOW",
flags="PropertyFlags::APPLIES_TO_PLACEHOLDER", flags="APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-x")} spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-x")}
// FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`. // FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
<%helpers:longhand name="overflow-y" animation_value_type="discrete" <%helpers:longhand name="overflow-y" animation_value_type="discrete"
flags="PropertyFlags::APPLIES_TO_PLACEHOLDER", flags="APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-y"> spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-y">
pub use super::overflow_x::{SpecifiedValue, parse, get_initial_value, computed_value}; pub use super::overflow_x::{SpecifiedValue, parse, get_initial_value, computed_value};
</%helpers:longhand> </%helpers:longhand>
@ -669,7 +668,7 @@ ${helpers.predefined_type(
<%helpers:longhand name="transform" extra_prefixes="webkit" <%helpers:longhand name="transform" extra_prefixes="webkit"
animation_value_type="ComputedValue" animation_value_type="ComputedValue"
flags="PropertyFlags::CREATES_STACKING_CONTEXT PropertyFlags::FIXPOS_CB" flags="CREATES_STACKING_CONTEXT FIXPOS_CB"
spec="https://drafts.csswg.org/css-transforms/#propdef-transform"> spec="https://drafts.csswg.org/css-transforms/#propdef-transform">
use values::computed::{LengthOrPercentageOrNumber as ComputedLoPoNumber, LengthOrNumber as ComputedLoN}; use values::computed::{LengthOrPercentageOrNumber as ComputedLoPoNumber, LengthOrNumber as ComputedLoN};
use values::computed::{LengthOrPercentage as ComputedLoP, Length as ComputedLength}; use values::computed::{LengthOrPercentage as ComputedLoP, Length as ComputedLength};
@ -1572,7 +1571,7 @@ ${helpers.single_keyword("isolation",
"auto isolate", "auto isolate",
products="gecko", products="gecko",
spec="https://drafts.fxtf.org/compositing/#isolation", spec="https://drafts.fxtf.org/compositing/#isolation",
flags="PropertyFlags::CREATES_STACKING_CONTEXT", flags="CREATES_STACKING_CONTEXT",
animation_value_type="discrete")} animation_value_type="discrete")}
// TODO add support for logical values recto and verso // TODO add support for logical values recto and verso
@ -1605,7 +1604,7 @@ ${helpers.single_keyword("resize",
"none both horizontal vertical", "none both horizontal vertical",
products="gecko", products="gecko",
spec="https://drafts.csswg.org/css-ui/#propdef-resize", spec="https://drafts.csswg.org/css-ui/#propdef-resize",
flags="PropertyFlags::APPLIES_TO_PLACEHOLDER", flags="APPLIES_TO_PLACEHOLDER",
animation_value_type="discrete")} animation_value_type="discrete")}
@ -1616,7 +1615,7 @@ ${helpers.predefined_type("perspective",
gecko_ffi_name="mChildPerspective", gecko_ffi_name="mChildPerspective",
spec="https://drafts.csswg.org/css-transforms/#perspective", spec="https://drafts.csswg.org/css-transforms/#perspective",
extra_prefixes="moz webkit", extra_prefixes="moz webkit",
flags="PropertyFlags::CREATES_STACKING_CONTEXT PropertyFlags::FIXPOS_CB", flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
animation_value_type="ComputedValue")} animation_value_type="ComputedValue")}
${helpers.predefined_type("perspective-origin", ${helpers.predefined_type("perspective-origin",
@ -1647,7 +1646,7 @@ ${helpers.single_keyword("transform-style",
"flat preserve-3d", "flat preserve-3d",
spec="https://drafts.csswg.org/css-transforms/#transform-style-property", spec="https://drafts.csswg.org/css-transforms/#transform-style-property",
extra_prefixes="moz webkit", extra_prefixes="moz webkit",
flags="PropertyFlags::CREATES_STACKING_CONTEXT PropertyFlags::FIXPOS_CB", flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
animation_value_type="discrete")} animation_value_type="discrete")}
${helpers.predefined_type("transform-origin", ${helpers.predefined_type("transform-origin",
@ -1662,7 +1661,7 @@ ${helpers.predefined_type("transform-origin",
// like `content`(layout style paint) in gecko. We should implement `size` and `content`, // like `content`(layout style paint) in gecko. We should implement `size` and `content`,
// also update the glue once they are implemented in gecko. // also update the glue once they are implemented in gecko.
<%helpers:longhand name="contain" animation_value_type="discrete" products="gecko" <%helpers:longhand name="contain" animation_value_type="discrete" products="gecko"
flags="PropertyFlags::FIXPOS_CB" flags="FIXPOS_CB"
spec="https://drafts.csswg.org/css-contain/#contain-property"> spec="https://drafts.csswg.org/css-contain/#contain-property">
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
@ -1673,12 +1672,12 @@ ${helpers.predefined_type("transform-origin",
bitflags! { bitflags! {
#[derive(MallocSizeOf, ToComputedValue)] #[derive(MallocSizeOf, ToComputedValue)]
pub struct SpecifiedValue: u8 { pub flags SpecifiedValue: u8 {
const LAYOUT = 0x01; const LAYOUT = 0x01,
const STYLE = 0x02; const STYLE = 0x02,
const PAINT = 0x04; const PAINT = 0x04,
const STRICT = 0x8; const STRICT = 0x8,
const STRICT_BITS = SpecifiedValue::LAYOUT.bits | SpecifiedValue::STYLE.bits | SpecifiedValue::PAINT.bits; const STRICT_BITS = LAYOUT.bits | STYLE.bits | PAINT.bits,
} }
} }
@ -1687,13 +1686,13 @@ ${helpers.predefined_type("transform-origin",
if self.is_empty() { if self.is_empty() {
return dest.write_str("none") return dest.write_str("none")
} }
if self.contains(SpecifiedValue::STRICT) { if self.contains(STRICT) {
return dest.write_str("strict") return dest.write_str("strict")
} }
let mut has_any = false; let mut has_any = false;
macro_rules! maybe_write_value { macro_rules! maybe_write_value {
($ident:path => $str:expr) => { ($ident:ident => $str:expr) => {
if self.contains($ident) { if self.contains($ident) {
if has_any { if has_any {
dest.write_str(" ")?; dest.write_str(" ")?;
@ -1703,9 +1702,9 @@ ${helpers.predefined_type("transform-origin",
} }
} }
} }
maybe_write_value!(SpecifiedValue::LAYOUT => "layout"); maybe_write_value!(LAYOUT => "layout");
maybe_write_value!(SpecifiedValue::STYLE => "style"); maybe_write_value!(STYLE => "style");
maybe_write_value!(SpecifiedValue::PAINT => "paint"); maybe_write_value!(PAINT => "paint");
debug_assert!(has_any); debug_assert!(has_any);
Ok(()) Ok(())
@ -1726,15 +1725,15 @@ ${helpers.predefined_type("transform-origin",
return Ok(result) return Ok(result)
} }
if input.try(|input| input.expect_ident_matching("strict")).is_ok() { if input.try(|input| input.expect_ident_matching("strict")).is_ok() {
result.insert(SpecifiedValue::STRICT | SpecifiedValue::STRICT_BITS); result.insert(STRICT | STRICT_BITS);
return Ok(result) return Ok(result)
} }
while let Ok(name) = input.try(|i| i.expect_ident_cloned()) { while let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
let flag = match_ignore_ascii_case! { &name, let flag = match_ignore_ascii_case! { &name,
"layout" => Some(SpecifiedValue::LAYOUT), "layout" => Some(LAYOUT),
"style" => Some(SpecifiedValue::STYLE), "style" => Some(STYLE),
"paint" => Some(SpecifiedValue::PAINT), "paint" => Some(PAINT),
_ => None _ => None
}; };
let flag = match flag { let flag = match flag {
@ -1865,7 +1864,7 @@ ${helpers.predefined_type(
products="gecko", products="gecko",
boxed=True, boxed=True,
animation_value_type="ComputedValue", animation_value_type="ComputedValue",
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
spec="https://drafts.csswg.org/css-shapes/#shape-outside-property", spec="https://drafts.csswg.org/css-shapes/#shape-outside-property",
)} )}
@ -1885,28 +1884,28 @@ ${helpers.predefined_type(
/// These constants match Gecko's `NS_STYLE_TOUCH_ACTION_*` constants. /// These constants match Gecko's `NS_STYLE_TOUCH_ACTION_*` constants.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))] #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(ToComputedValue)] #[derive(ToComputedValue)]
pub struct SpecifiedValue: u8 { pub flags SpecifiedValue: u8 {
const TOUCH_ACTION_NONE = structs::NS_STYLE_TOUCH_ACTION_NONE as u8; const TOUCH_ACTION_NONE = structs::NS_STYLE_TOUCH_ACTION_NONE as u8,
const TOUCH_ACTION_AUTO = structs::NS_STYLE_TOUCH_ACTION_AUTO as u8; const TOUCH_ACTION_AUTO = structs::NS_STYLE_TOUCH_ACTION_AUTO as u8,
const TOUCH_ACTION_PAN_X = structs::NS_STYLE_TOUCH_ACTION_PAN_X as u8; const TOUCH_ACTION_PAN_X = structs::NS_STYLE_TOUCH_ACTION_PAN_X as u8,
const TOUCH_ACTION_PAN_Y = structs::NS_STYLE_TOUCH_ACTION_PAN_Y as u8; const TOUCH_ACTION_PAN_Y = structs::NS_STYLE_TOUCH_ACTION_PAN_Y as u8,
const TOUCH_ACTION_MANIPULATION = structs::NS_STYLE_TOUCH_ACTION_MANIPULATION as u8; const TOUCH_ACTION_MANIPULATION = structs::NS_STYLE_TOUCH_ACTION_MANIPULATION as u8,
} }
} }
impl ToCss for SpecifiedValue { impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
SpecifiedValue::TOUCH_ACTION_NONE => dest.write_str("none"), TOUCH_ACTION_NONE => dest.write_str("none"),
SpecifiedValue::TOUCH_ACTION_AUTO => dest.write_str("auto"), TOUCH_ACTION_AUTO => dest.write_str("auto"),
SpecifiedValue::TOUCH_ACTION_MANIPULATION => dest.write_str("manipulation"), TOUCH_ACTION_MANIPULATION => dest.write_str("manipulation"),
_ if self.contains(SpecifiedValue::TOUCH_ACTION_PAN_X | SpecifiedValue::TOUCH_ACTION_PAN_Y) => { _ if self.contains(TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y) => {
dest.write_str("pan-x pan-y") dest.write_str("pan-x pan-y")
}, },
_ if self.contains(SpecifiedValue::TOUCH_ACTION_PAN_X) => { _ if self.contains(TOUCH_ACTION_PAN_X) => {
dest.write_str("pan-x") dest.write_str("pan-x")
}, },
_ if self.contains(SpecifiedValue::TOUCH_ACTION_PAN_Y) => { _ if self.contains(TOUCH_ACTION_PAN_Y) => {
dest.write_str("pan-y") dest.write_str("pan-y")
}, },
_ => panic!("invalid touch-action value"), _ => panic!("invalid touch-action value"),
@ -1916,28 +1915,28 @@ ${helpers.predefined_type(
#[inline] #[inline]
pub fn get_initial_value() -> computed_value::T { pub fn get_initial_value() -> computed_value::T {
SpecifiedValue::TOUCH_ACTION_AUTO TOUCH_ACTION_AUTO
} }
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> { -> Result<SpecifiedValue, ParseError<'i>> {
// FIXME: remove clone() when lifetimes are non-lexical // FIXME: remove clone() when lifetimes are non-lexical
try_match_ident_ignore_ascii_case! { input, try_match_ident_ignore_ascii_case! { input,
"auto" => Ok(SpecifiedValue::TOUCH_ACTION_AUTO), "auto" => Ok(TOUCH_ACTION_AUTO),
"none" => Ok(SpecifiedValue::TOUCH_ACTION_NONE), "none" => Ok(TOUCH_ACTION_NONE),
"manipulation" => Ok(SpecifiedValue::TOUCH_ACTION_MANIPULATION), "manipulation" => Ok(TOUCH_ACTION_MANIPULATION),
"pan-x" => { "pan-x" => {
if input.try(|i| i.expect_ident_matching("pan-y")).is_ok() { if input.try(|i| i.expect_ident_matching("pan-y")).is_ok() {
Ok(SpecifiedValue::TOUCH_ACTION_PAN_X | SpecifiedValue::TOUCH_ACTION_PAN_Y) Ok(TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y)
} else { } else {
Ok(SpecifiedValue::TOUCH_ACTION_PAN_X) Ok(TOUCH_ACTION_PAN_X)
} }
}, },
"pan-y" => { "pan-y" => {
if input.try(|i| i.expect_ident_matching("pan-x")).is_ok() { if input.try(|i| i.expect_ident_matching("pan-x")).is_ok() {
Ok(SpecifiedValue::TOUCH_ACTION_PAN_X | SpecifiedValue::TOUCH_ACTION_PAN_Y) Ok(TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y)
} else { } else {
Ok(SpecifiedValue::TOUCH_ACTION_PAN_Y) Ok(TOUCH_ACTION_PAN_Y)
} }
}, },
} }

View file

@ -13,8 +13,7 @@ ${helpers.predefined_type(
"ColorPropertyValue", "ColorPropertyValue",
"::cssparser::RGBA::new(0, 0, 0, 255)", "::cssparser::RGBA::new(0, 0, 0, 255)",
animation_value_type="AnimatedRGBA", animation_value_type="AnimatedRGBA",
flags="""PropertyFlags::APPLIES_TO_FIRST_LETTER PropertyFlags::APPLIES_TO_FIRST_LINE flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
PropertyFlags::APPLIES_TO_PLACEHOLDER""",
ignored_when_colors_disabled="True", ignored_when_colors_disabled="True",
spec="https://drafts.csswg.org/css-color/#color" spec="https://drafts.csswg.org/css-color/#color"
)} )}

View file

@ -11,7 +11,7 @@ ${helpers.predefined_type("opacity",
"Opacity", "Opacity",
"1.0", "1.0",
animation_value_type="ComputedValue", animation_value_type="ComputedValue",
flags="PropertyFlags::CREATES_STACKING_CONTEXT PropertyFlags::APPLIES_TO_PLACEHOLDER", flags="CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-color/#opacity")} spec="https://drafts.csswg.org/css-color/#opacity")}
${helpers.predefined_type( ${helpers.predefined_type(
@ -22,7 +22,7 @@ ${helpers.predefined_type(
animation_value_type="AnimatedBoxShadowList", animation_value_type="AnimatedBoxShadowList",
extra_prefixes="webkit", extra_prefixes="webkit",
ignored_when_colors_disabled=True, ignored_when_colors_disabled=True,
flags="PropertyFlags::APPLIES_TO_FIRST_LETTER", flags="APPLIES_TO_FIRST_LETTER",
spec="https://drafts.csswg.org/css-backgrounds/#box-shadow", spec="https://drafts.csswg.org/css-backgrounds/#box-shadow",
)} )}
@ -42,7 +42,7 @@ ${helpers.predefined_type(
separator="Space", separator="Space",
animation_value_type="AnimatedFilterList", animation_value_type="AnimatedFilterList",
extra_prefixes="webkit", extra_prefixes="webkit",
flags="PropertyFlags::CREATES_STACKING_CONTEXT PropertyFlags::FIXPOS_CB", flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
spec="https://drafts.fxtf.org/filters/#propdef-filter", spec="https://drafts.fxtf.org/filters/#propdef-filter",
)} )}
@ -51,5 +51,5 @@ ${helpers.single_keyword("mix-blend-mode",
color-burn hard-light soft-light difference exclusion hue color-burn hard-light soft-light difference exclusion hue
saturation color luminosity""", gecko_constant_prefix="NS_STYLE_BLEND", saturation color luminosity""", gecko_constant_prefix="NS_STYLE_BLEND",
animation_value_type="discrete", animation_value_type="discrete",
flags="PropertyFlags::CREATES_STACKING_CONTEXT", flags="CREATES_STACKING_CONTEXT",
spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode")} spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode")}

Some files were not shown because too many files have changed in this diff Show more