gecko-dev/servo/ports/geckolib/glue.rs

439 строки
18 KiB
Rust
Исходник Обычный вид История

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![allow(unsafe_code)]
use app_units::Au;
use data::{NUM_THREADS, PerDocumentStyleData};
use env_logger;
use euclid::Size2D;
use gecko_bindings::bindings::RawGeckoDocumentBorrowed;
use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed};
use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut};
use gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned, ServoNodeDataOwned};
use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
use gecko_bindings::bindings::{ServoComputedValuesBorrowedOrNull, ServoDeclarationBlock};
use gecko_bindings::bindings::{ServoDeclarationBlockBorrowed, ServoDeclarationBlockStrong};
use gecko_bindings::bindings::{ThreadSafePrincipalHolder, ThreadSafeURIHolder, nsHTMLCSSStyleSheet};
use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
servo: Merge #12469 - style: Rewrite the restyle hints code to allow different kinds of element snapshots (from emilio:stylo); r=bholley <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> This is a rewrite for how style interfaces with its consumers in order to allow different representations for an element snapshot. This also changes the requirements of an element snapshot, requiring them to only implement MatchAttr, instead of MatchAttrGeneric. This is important for stylo since implementing MatchAttrGeneric is way more difficult for us given the atom limitations. This also allows for more performant implementations in the Gecko side of things. I don't want to get this merged just yet, mainly because the stylo part is not implemented, but I'd like early feedback from @bholley and/or @heycam: How do you see this approach? I don't think we'll have much problem to implement MatchAttr for our element snapshots, but... worth checking. r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 1e0321f7dde5f33f7d26bbd4f088622fa3660477
2016-07-22 00:54:34 +03:00
use gecko_bindings::structs::ServoElementSnapshot;
use gecko_bindings::structs::nsRestyleHint;
use gecko_bindings::structs::{SheetParsingMode, nsIAtom};
use gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI};
use gecko_bindings::sugar::ownership::{HasSimpleFFI, HasFFI, Strong};
servo: Merge #12815 - stylo: Use atoms as the pseudo-element back-end (from emilio:stylo-atoms); r=bholley <!-- Please describe your changes on the following line: --> A bit of work left, and we can uber-optimize this (left comments, will fill follow-ups), but this is a decent refactor so I thought I'd rather get some feedback on it. r? @bholley (not formally yet, maybe, but some feedback is appreciated). --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because geckolib only... <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: c386a3c8813a17d810f48d0b4ad18f2c984ecaa4 --HG-- rename : servo/ports/geckolib/gecko_bindings/tools/.gitignore => servo/ports/geckolib/binding_tools/.gitignore rename : servo/ports/geckolib/gecko_bindings/tools/README.md => servo/ports/geckolib/binding_tools/README.md rename : servo/ports/geckolib/gecko_bindings/tools/regen.py => servo/ports/geckolib/binding_tools/regen.py rename : servo/ports/geckolib/gecko_bindings/tools/regen.sh => servo/ports/geckolib/binding_tools/regen.sh rename : servo/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh => servo/ports/geckolib/binding_tools/setup_bindgen.sh
2016-08-16 20:50:29 +03:00
use gecko_string_cache::Atom;
servo: Merge #12469 - style: Rewrite the restyle hints code to allow different kinds of element snapshots (from emilio:stylo); r=bholley <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> This is a rewrite for how style interfaces with its consumers in order to allow different representations for an element snapshot. This also changes the requirements of an element snapshot, requiring them to only implement MatchAttr, instead of MatchAttrGeneric. This is important for stylo since implementing MatchAttrGeneric is way more difficult for us given the atom limitations. This also allows for more performant implementations in the Gecko side of things. I don't want to get this merged just yet, mainly because the stylo part is not implemented, but I'd like early feedback from @bholley and/or @heycam: How do you see this approach? I don't think we'll have much problem to implement MatchAttr for our element snapshots, but... worth checking. r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 1e0321f7dde5f33f7d26bbd4f088622fa3660477
2016-07-22 00:54:34 +03:00
use snapshot::GeckoElementSnapshot;
servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley Background: The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)). Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait. ---- The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much. The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …). Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.) r? @bholley --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab --HG-- rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
2016-07-20 10:58:34 +03:00
use std::mem::transmute;
use std::ptr;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use std::sync::{Arc, Mutex};
use style::arc_ptr_eq;
servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley Background: The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)). Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait. ---- The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much. The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …). Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.) r? @bholley --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab --HG-- rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
2016-07-20 10:58:34 +03:00
use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley Background: The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)). Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait. ---- The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much. The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …). Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.) r? @bholley --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab --HG-- rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
2016-07-20 10:58:34 +03:00
use style::gecko_selector_impl::{GeckoSelectorImpl, PseudoElement};
use style::parallel;
use style::parser::ParserContextExtraData;
use style::properties::{ComputedValues, PropertyDeclarationBlock, parse_one_declaration};
use style::selector_impl::PseudoElementCascadeType;
use style::sequential;
servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley Background: The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)). Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait. ---- The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much. The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …). Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.) r? @bholley --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab --HG-- rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
2016-07-20 10:58:34 +03:00
use style::stylesheets::{Stylesheet, Origin};
use style::timer::Timer;
use traversal::RecalcStyleOnly;
use url::Url;
use wrapper::{DUMMY_BASE_URL, GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData};
/*
* For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
* the C header in Gecko. In order to catch accidental mismatches, we run rust-bindgen against
* those signatures as well, giving us a second declaration of all the Servo_* functions in this
* crate. If there's a mismatch, LLVM will assert and abort, which is a rather awful thing to
* depend on but good enough for our purposes.
*/
#[no_mangle]
pub extern "C" fn Servo_Initialize() -> () {
// Enable standard Rust logging.
//
// See https://doc.rust-lang.org/log/env_logger/index.html for instructions.
env_logger::init().unwrap();
// Allocate our default computed values.
unsafe { ComputedValues::initialize(); }
}
#[no_mangle]
pub extern "C" fn Servo_Shutdown() -> () {
// Destroy our default computed values.
unsafe { ComputedValues::shutdown(); }
}
fn restyle_subtree(node: GeckoNode, raw_data: RawServoStyleSetBorrowedMut) {
debug_assert!(node.is_element() || node.is_text_node());
// Force the creation of our lazily-constructed initial computed values on
// the main thread, since it's not safe to call elsewhere.
//
// FIXME(bholley): this should move into Servo_Initialize as soon as we get
// rid of the HackilyFindSomeDeviceContext stuff that happens during
// initial_values computation, since that stuff needs to be called further
// along in startup than the sensible place to call Servo_Initialize.
servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley Background: The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)). Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait. ---- The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much. The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …). Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.) r? @bholley --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab --HG-- rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
2016-07-20 10:58:34 +03:00
ComputedValues::initial_values();
// The stylist consumes stylesheets lazily.
let per_doc_data = PerDocumentStyleData::from_ffi_mut(raw_data);
per_doc_data.flush_stylesheets();
let local_context_data =
LocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone());
let shared_style_context = SharedStyleContext {
viewport_size: Size2D::new(Au(0), Au(0)),
screen_size_changed: false,
generation: 0,
goal: ReflowGoal::ForScriptQuery,
stylist: per_doc_data.stylist.clone(),
running_animations: per_doc_data.running_animations.clone(),
expired_animations: per_doc_data.expired_animations.clone(),
error_reporter: Box::new(StdoutErrorReporter),
local_context_creation_data: Mutex::new(local_context_data),
timer: Timer::new(),
};
// We ensure this is true before calling Servo_RestyleSubtree()
debug_assert!(node.is_dirty() || node.has_dirty_descendants());
if per_doc_data.num_threads == 1 || per_doc_data.work_queue.is_none() {
sequential::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context);
} else {
parallel::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context,
per_doc_data.work_queue.as_mut().unwrap());
}
}
#[no_mangle]
pub extern "C" fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed,
raw_data: RawServoStyleSetBorrowedMut) -> () {
let node = GeckoNode(node);
restyle_subtree(node, raw_data);
}
#[no_mangle]
pub extern "C" fn Servo_RestyleDocument(doc: RawGeckoDocumentBorrowed, raw_data: RawServoStyleSetBorrowedMut) -> () {
let document = GeckoDocument(doc);
let node = match document.root_node() {
Some(x) => x,
None => return,
};
restyle_subtree(node, raw_data);
}
#[no_mangle]
pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 {
*NUM_THREADS as u32
}
#[no_mangle]
pub extern "C" fn Servo_NodeData_Drop(data: ServoNodeDataOwned) -> () {
let _ = data.into_box::<NonOpaqueStyleData>();
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8,
length: u32,
mode: SheetParsingMode,
base_bytes: *const u8,
base_length: u32,
base: *mut ThreadSafeURIHolder,
referrer: *mut ThreadSafeURIHolder,
principal: *mut ThreadSafePrincipalHolder)
-> RawServoStyleSheetStrong {
let input = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
let origin = match mode {
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
SheetParsingMode::eUserSheetFeatures => Origin::User,
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
};
let base_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(base_bytes, base_length as usize)) };
let url = Url::parse(base_str).unwrap();
let extra_data = ParserContextExtraData {
base: Some(GeckoArcURI::new(base)),
referrer: Some(GeckoArcURI::new(referrer)),
principal: Some(GeckoArcPrincipal::new(principal)),
};
let sheet = Arc::new(Stylesheet::from_str(input, url, origin, Box::new(StdoutErrorReporter),
extra_data));
unsafe {
transmute(sheet)
}
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed) {
let data = PerDocumentStyleData::from_ffi_mut(raw_data);
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.push(sheet.clone());
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed) {
let data = PerDocumentStyleData::from_ffi_mut(raw_data);
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.insert(0, sheet.clone());
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed,
raw_reference: RawServoStyleSheetBorrowed) {
let data = PerDocumentStyleData::from_ffi_mut(raw_data);
let sheet = HasArcFFI::as_arc(&raw_sheet);
let reference = HasArcFFI::as_arc(&raw_reference);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
let index = data.stylesheets.iter().position(|x| arc_ptr_eq(x, reference)).unwrap();
data.stylesheets.insert(index, sheet.clone());
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowedMut,
raw_sheet: RawServoStyleSheetBorrowed) {
let data = PerDocumentStyleData::from_ffi_mut(raw_data);
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets_changed = true;
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
!Stylesheet::as_arc(&raw_sheet).rules.is_empty()
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed) -> () {
unsafe { Stylesheet::addref(sheet) };
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> () {
unsafe { Stylesheet::release(sheet) };
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed)
-> ServoComputedValuesStrong {
let node = unsafe { GeckoNode(node) };
let arc_cv = match node.borrow_data().map_or(None, |data| data.style.clone()) {
Some(style) => style,
None => {
// FIXME(bholley): This case subverts the intended semantics of this
// function, and exists only to make stylo builds more robust corner-
// cases where Gecko wants the style for a node that Servo never
// traversed. We should remove this as soon as possible.
error!("stylo: encountered unstyled node, substituting default values.");
servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley Background: The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)). Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait. ---- The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much. The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …). Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.) r? @bholley --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactoring <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab --HG-- rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
2016-07-20 10:58:34 +03:00
Arc::new(ComputedValues::initial_values().clone())
},
};
arc_cv.into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
pseudo_tag: *mut nsIAtom,
raw_data: RawServoStyleSetBorrowedMut)
-> ServoComputedValuesStrong {
// The stylist consumes stylesheets lazily.
let data = PerDocumentStyleData::from_ffi_mut(raw_data);
data.flush_stylesheets();
servo: Merge #12815 - stylo: Use atoms as the pseudo-element back-end (from emilio:stylo-atoms); r=bholley <!-- Please describe your changes on the following line: --> A bit of work left, and we can uber-optimize this (left comments, will fill follow-ups), but this is a decent refactor so I thought I'd rather get some feedback on it. r? @bholley (not formally yet, maybe, but some feedback is appreciated). --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because geckolib only... <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: c386a3c8813a17d810f48d0b4ad18f2c984ecaa4 --HG-- rename : servo/ports/geckolib/gecko_bindings/tools/.gitignore => servo/ports/geckolib/binding_tools/.gitignore rename : servo/ports/geckolib/gecko_bindings/tools/README.md => servo/ports/geckolib/binding_tools/README.md rename : servo/ports/geckolib/gecko_bindings/tools/regen.py => servo/ports/geckolib/binding_tools/regen.py rename : servo/ports/geckolib/gecko_bindings/tools/regen.sh => servo/ports/geckolib/binding_tools/regen.sh rename : servo/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh => servo/ports/geckolib/binding_tools/setup_bindgen.sh
2016-08-16 20:50:29 +03:00
let atom = Atom::from(pseudo_tag);
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true);
let maybe_parent = parent_style_or_null.as_arc_opt();
let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent);
new_computed.map_or(Strong::null(), |c| c.into_strong())
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesBorrowed,
match_element: RawGeckoElementBorrowed,
pseudo_tag: *mut nsIAtom,
raw_data: RawServoStyleSetBorrowedMut,
is_probe: bool)
-> ServoComputedValuesStrong {
debug_assert!(!(match_element as *const _).is_null());
let parent_or_null = || {
if is_probe {
Strong::null()
} else {
ComputedValues::as_arc(&parent_style).clone().into_strong()
}
};
servo: Merge #12815 - stylo: Use atoms as the pseudo-element back-end (from emilio:stylo-atoms); r=bholley <!-- Please describe your changes on the following line: --> A bit of work left, and we can uber-optimize this (left comments, will fill follow-ups), but this is a decent refactor so I thought I'd rather get some feedback on it. r? @bholley (not formally yet, maybe, but some feedback is appreciated). --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because geckolib only... <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: c386a3c8813a17d810f48d0b4ad18f2c984ecaa4 --HG-- rename : servo/ports/geckolib/gecko_bindings/tools/.gitignore => servo/ports/geckolib/binding_tools/.gitignore rename : servo/ports/geckolib/gecko_bindings/tools/README.md => servo/ports/geckolib/binding_tools/README.md rename : servo/ports/geckolib/gecko_bindings/tools/regen.py => servo/ports/geckolib/binding_tools/regen.py rename : servo/ports/geckolib/gecko_bindings/tools/regen.sh => servo/ports/geckolib/binding_tools/regen.sh rename : servo/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh => servo/ports/geckolib/binding_tools/setup_bindgen.sh
2016-08-16 20:50:29 +03:00
let atom = Atom::from(pseudo_tag);
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false);
// The stylist consumes stylesheets lazily.
let data = PerDocumentStyleData::from_ffi_mut(raw_data);
data.flush_stylesheets();
let element = unsafe { GeckoElement(match_element) };
match GeckoSelectorImpl::pseudo_element_cascade_type(&pseudo) {
PseudoElementCascadeType::Eager => {
let node = element.as_node();
let maybe_computed = node.borrow_data()
.and_then(|data| {
data.per_pseudo.get(&pseudo).map(|c| c.clone())
});
maybe_computed.map_or_else(parent_or_null, FFIArcHelpers::into_strong)
}
PseudoElementCascadeType::Lazy => {
let parent = ComputedValues::as_arc(&parent_style);
data.stylist
.lazily_compute_pseudo_element_style(&element, &pseudo, parent)
.map_or_else(parent_or_null, FFIArcHelpers::into_strong)
}
PseudoElementCascadeType::Precomputed => {
unreachable!("Anonymous pseudo found in \
Servo_GetComputedValuesForPseudoElement");
}
}
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValuesBorrowedOrNull)
-> ServoComputedValuesStrong {
let style = if parent_style.is_null() {
Arc::new(ComputedValues::initial_values().clone())
} else {
ComputedValues::inherit_from(parent_style.as_arc())
};
style.into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) -> () {
unsafe { ComputedValues::addref(ptr) };
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) -> () {
unsafe { ComputedValues::release(ptr) };
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_Init() -> RawServoStyleSetOwned {
let data = Box::new(PerDocumentStyleData::new());
data.into_ffi()
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () {
let _ = data.into_box::<PerDocumentStyleData>();
}
pub struct GeckoDeclarationBlock {
pub declarations: Option<Arc<PropertyDeclarationBlock>>,
// XXX The following two fields are made atomic to work around the
// ownership system so that they can be changed inside a shared
// instance. It wouldn't provide safety as Rust usually promises,
// but it is fine as far as we only access them in a single thread.
// If we need to access them in different threads, we would need
// to redesign how it works with MiscContainer in Gecko side.
pub cache: AtomicPtr<nsHTMLCSSStyleSheet>,
pub immutable: AtomicBool,
}
unsafe impl HasFFI for GeckoDeclarationBlock {
type FFIType = ServoDeclarationBlock;
}
unsafe impl HasArcFFI for GeckoDeclarationBlock {}
#[no_mangle]
pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
cache: *mut nsHTMLCSSStyleSheet)
-> ServoDeclarationBlockStrong {
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
Arc::new(GeckoDeclarationBlock {
declarations: GeckoElement::parse_style_attribute(value).map(Arc::new),
cache: AtomicPtr::new(cache),
immutable: AtomicBool::new(false),
}).into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: ServoDeclarationBlockBorrowed) {
unsafe { GeckoDeclarationBlock::addref(declarations) };
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationBlockBorrowed) {
unsafe { GeckoDeclarationBlock::release(declarations) };
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockBorrowed)
-> *mut nsHTMLCSSStyleSheet {
GeckoDeclarationBlock::as_arc(&declarations).cache.load(Ordering::Relaxed)
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_SetImmutable(declarations: ServoDeclarationBlockBorrowed) {
GeckoDeclarationBlock::as_arc(&declarations).immutable.store(true, Ordering::Relaxed)
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDeclarationBlockBorrowed) {
GeckoDeclarationBlock::as_arc(&declarations).cache.store(ptr::null_mut(), Ordering::Relaxed)
}
#[no_mangle]
pub extern "C" fn Servo_CSSSupports(property: *const u8, property_length: u32,
value: *const u8, value_length: u32) -> bool {
let property = unsafe { from_utf8_unchecked(slice::from_raw_parts(property, property_length as usize)) };
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(value, value_length as usize)) };
let base_url = &*DUMMY_BASE_URL;
let extra_data = ParserContextExtraData::default();
match parse_one_declaration(&property, &value, &base_url, Box::new(StdoutErrorReporter), extra_data) {
Ok(decls) => !decls.is_empty(),
Err(()) => false,
}
}
servo: Merge #12469 - style: Rewrite the restyle hints code to allow different kinds of element snapshots (from emilio:stylo); r=bholley <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> This is a rewrite for how style interfaces with its consumers in order to allow different representations for an element snapshot. This also changes the requirements of an element snapshot, requiring them to only implement MatchAttr, instead of MatchAttrGeneric. This is important for stylo since implementing MatchAttrGeneric is way more difficult for us given the atom limitations. This also allows for more performant implementations in the Gecko side of things. I don't want to get this merged just yet, mainly because the stylo part is not implemented, but I'd like early feedback from @bholley and/or @heycam: How do you see this approach? I don't think we'll have much problem to implement MatchAttr for our element snapshots, but... worth checking. r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 1e0321f7dde5f33f7d26bbd4f088622fa3660477
2016-07-22 00:54:34 +03:00
#[no_mangle]
pub extern "C" fn Servo_ComputeRestyleHint(element: RawGeckoElementBorrowed,
servo: Merge #12469 - style: Rewrite the restyle hints code to allow different kinds of element snapshots (from emilio:stylo); r=bholley <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> This is a rewrite for how style interfaces with its consumers in order to allow different representations for an element snapshot. This also changes the requirements of an element snapshot, requiring them to only implement MatchAttr, instead of MatchAttrGeneric. This is important for stylo since implementing MatchAttrGeneric is way more difficult for us given the atom limitations. This also allows for more performant implementations in the Gecko side of things. I don't want to get this merged just yet, mainly because the stylo part is not implemented, but I'd like early feedback from @bholley and/or @heycam: How do you see this approach? I don't think we'll have much problem to implement MatchAttr for our element snapshots, but... worth checking. r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 1e0321f7dde5f33f7d26bbd4f088622fa3660477
2016-07-22 00:54:34 +03:00
snapshot: *mut ServoElementSnapshot,
raw_data: RawServoStyleSetBorrowed) -> nsRestyleHint {
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data);
servo: Merge #12469 - style: Rewrite the restyle hints code to allow different kinds of element snapshots (from emilio:stylo); r=bholley <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> This is a rewrite for how style interfaces with its consumers in order to allow different representations for an element snapshot. This also changes the requirements of an element snapshot, requiring them to only implement MatchAttr, instead of MatchAttrGeneric. This is important for stylo since implementing MatchAttrGeneric is way more difficult for us given the atom limitations. This also allows for more performant implementations in the Gecko side of things. I don't want to get this merged just yet, mainly because the stylo part is not implemented, but I'd like early feedback from @bholley and/or @heycam: How do you see this approach? I don't think we'll have much problem to implement MatchAttr for our element snapshots, but... worth checking. r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 1e0321f7dde5f33f7d26bbd4f088622fa3660477
2016-07-22 00:54:34 +03:00
let snapshot = unsafe { GeckoElementSnapshot::from_raw(snapshot) };
let element = unsafe { GeckoElement(element) };
servo: Merge #12469 - style: Rewrite the restyle hints code to allow different kinds of element snapshots (from emilio:stylo); r=bholley <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> This is a rewrite for how style interfaces with its consumers in order to allow different representations for an element snapshot. This also changes the requirements of an element snapshot, requiring them to only implement MatchAttr, instead of MatchAttrGeneric. This is important for stylo since implementing MatchAttrGeneric is way more difficult for us given the atom limitations. This also allows for more performant implementations in the Gecko side of things. I don't want to get this merged just yet, mainly because the stylo part is not implemented, but I'd like early feedback from @bholley and/or @heycam: How do you see this approach? I don't think we'll have much problem to implement MatchAttr for our element snapshots, but... worth checking. r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 1e0321f7dde5f33f7d26bbd4f088622fa3660477
2016-07-22 00:54:34 +03:00
// NB: This involves an FFI call, we can get rid of it easily if needed.
let current_state = element.get_state();
let hint = per_doc_data.stylist
.compute_restyle_hint(&element, &snapshot,
current_state);
// NB: Binary representations match.
unsafe { transmute(hint.bits() as u32) }
}