2016-01-19 11:49:10 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2017-01-04 06:20:59 +03:00
|
|
|
use atomic_refcell::AtomicRefMut;
|
2016-11-07 08:26:08 +03:00
|
|
|
use cssparser::Parser;
|
2016-11-24 02:47:18 +03:00
|
|
|
use cssparser::ToCss as ParserToCss;
|
2017-02-15 14:05:07 +03:00
|
|
|
use env_logger::LogBuilder;
|
2016-11-25 20:00:44 +03:00
|
|
|
use selectors::Element;
|
2016-12-18 05:22:10 +03:00
|
|
|
use std::borrow::Cow;
|
2017-02-15 14:05:07 +03:00
|
|
|
use std::env;
|
2016-11-04 07:42:06 +03:00
|
|
|
use std::fmt::Write;
|
2016-11-25 20:00:44 +03:00
|
|
|
use std::ptr;
|
2017-03-03 05:46:40 +03:00
|
|
|
use style::context::{QuirksMode, SharedStyleContext, StyleContext};
|
2017-05-12 16:56:47 +03:00
|
|
|
use style::context::ThreadLocalStyleContext;
|
2016-12-26 05:13:30 +03:00
|
|
|
use style::data::{ElementData, ElementStyles, RestyleData};
|
2017-03-29 14:52:07 +03:00
|
|
|
use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
|
2016-12-13 06:13:03 +03:00
|
|
|
use style::dom::{ShowSubtreeData, TElement, TNode};
|
2017-05-12 13:41:35 +03:00
|
|
|
use style::element_state::ElementState;
|
2017-04-24 13:05:51 +03:00
|
|
|
use style::error_reporting::RustLogReporter;
|
2017-04-09 14:15:51 +03:00
|
|
|
use style::font_metrics::get_metrics_provider_for_product;
|
2017-02-23 21:15:41 +03:00
|
|
|
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
|
2017-04-12 10:27:02 +03:00
|
|
|
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData};
|
2016-11-25 20:00:44 +03:00
|
|
|
use style::gecko::restyle_damage::GeckoRestyleDamage;
|
2017-04-27 15:39:42 +03:00
|
|
|
use style::gecko::selector_parser::PseudoElement;
|
2016-09-26 10:36:05 +03:00
|
|
|
use style::gecko::traversal::RecalcStyleOnly;
|
2016-11-25 20:00:44 +03:00
|
|
|
use style::gecko::wrapper::GeckoElement;
|
2017-02-10 06:27:33 +03:00
|
|
|
use style::gecko_bindings::bindings;
|
2017-02-24 15:09:33 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut};
|
2016-10-18 08:51:14 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
|
2017-05-11 14:27:42 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoDocumentRule, RawServoDocumentRuleBorrowed};
|
2017-05-19 07:49:30 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
|
|
|
|
use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed};
|
2017-04-12 18:00:26 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoMediaList, RawServoMediaListBorrowed, RawServoMediaListStrong};
|
2017-03-15 13:58:06 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
|
|
|
|
use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
|
2017-04-10 05:47:59 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
|
2016-09-26 10:36:05 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
|
|
|
|
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
|
|
|
|
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
|
2017-04-28 13:11:04 +03:00
|
|
|
use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
|
2016-11-24 02:47:18 +03:00
|
|
|
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
|
2017-05-20 15:24:21 +03:00
|
|
|
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
|
|
|
|
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
|
2017-05-13 22:05:40 +03:00
|
|
|
use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
|
|
|
|
use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
|
|
|
|
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
|
2017-05-20 15:24:21 +03:00
|
|
|
use style::gecko_bindings::bindings::Gecko_NewNoneTransform;
|
2017-04-06 06:53:30 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoAnimationPropertySegmentBorrowed;
|
2017-05-20 15:24:21 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoCSSPropertyIDListBorrowed;
|
2017-02-24 15:09:33 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
|
2017-04-06 06:53:30 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoComputedTimingBorrowed;
|
2016-11-25 20:00:44 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
|
2017-03-30 04:50:47 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut;
|
2017-04-10 12:04:54 +03:00
|
|
|
use style::gecko_bindings::bindings::RawGeckoServoStyleRuleListBorrowedMut;
|
2017-01-14 00:25:39 +03:00
|
|
|
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
|
2017-05-01 13:51:48 +03:00
|
|
|
use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut;
|
2017-01-26 10:36:33 +03:00
|
|
|
use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
|
2016-12-31 06:12:55 +03:00
|
|
|
use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
|
2017-04-10 12:04:54 +03:00
|
|
|
use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
|
2016-10-18 08:51:14 +03:00
|
|
|
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
|
2016-11-24 02:47:18 +03:00
|
|
|
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
|
2017-03-21 11:36:49 +03:00
|
|
|
use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
|
|
|
|
use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
|
2016-11-25 20:00:44 +03:00
|
|
|
use style::gecko_bindings::structs;
|
2017-05-16 04:46:42 +03:00
|
|
|
use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation};
|
2017-04-10 12:04:54 +03:00
|
|
|
use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
|
2016-12-18 05:22:10 +03:00
|
|
|
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
|
2017-05-16 09:17:07 +03:00
|
|
|
use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
|
|
|
|
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint};
|
2017-05-24 08:03:42 +03:00
|
|
|
use style::gecko_bindings::structs::IterationCompositeOperation;
|
2016-12-31 06:12:55 +03:00
|
|
|
use style::gecko_bindings::structs::Loader;
|
2017-01-18 16:39:57 +03:00
|
|
|
use style::gecko_bindings::structs::RawGeckoPresContextOwned;
|
2017-05-10 23:08:59 +03:00
|
|
|
use style::gecko_bindings::structs::ServoElementSnapshotTable;
|
2017-04-03 07:30:56 +03:00
|
|
|
use style::gecko_bindings::structs::URLExtraData;
|
2017-02-09 05:39:45 +03:00
|
|
|
use style::gecko_bindings::structs::nsCSSValueSharedList;
|
2017-05-14 04:50:10 +03:00
|
|
|
use style::gecko_bindings::structs::nsCompatibility;
|
2016-12-01 08:54:46 +03:00
|
|
|
use style::gecko_bindings::structs::nsresult;
|
2017-03-22 14:17:09 +03:00
|
|
|
use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI, HasBoxFFI};
|
2016-09-26 10:36:05 +03:00
|
|
|
use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
|
2017-04-03 15:05:42 +03:00
|
|
|
use style::gecko_bindings::sugar::refptr::RefPtr;
|
2017-02-20 08:12:57 +03:00
|
|
|
use style::gecko_properties::{self, style_structs};
|
2017-05-19 07:49:30 +03:00
|
|
|
use style::keyframes::{Keyframe, KeyframeSelector, KeyframesStepValue};
|
2017-03-13 09:55:46 +03:00
|
|
|
use style::media_queries::{MediaList, parse_media_query_list};
|
2016-02-04 20:55:09 +03:00
|
|
|
use style::parallel;
|
2017-05-14 02:53:07 +03:00
|
|
|
use style::parser::{PARSING_MODE_DEFAULT, ParserContext};
|
2017-05-20 02:37:14 +03:00
|
|
|
use style::properties::{CascadeFlags, ComputedValues, Importance, SourcePropertyDeclaration};
|
|
|
|
use style::properties::{LonghandIdSet, PropertyDeclarationBlock, PropertyId, StyleBuilder};
|
2017-03-13 20:47:05 +03:00
|
|
|
use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
2017-05-10 10:05:43 +03:00
|
|
|
use style::properties::animated_properties::{Animatable, AnimationValue, TransitionProperty};
|
2017-05-20 02:37:14 +03:00
|
|
|
use style::properties::parse_one_declaration_into;
|
2017-02-14 06:44:12 +03:00
|
|
|
use style::restyle_hints::{self, RestyleHint};
|
2017-05-16 04:46:42 +03:00
|
|
|
use style::rule_tree::StyleSource;
|
2016-11-20 18:21:52 +03:00
|
|
|
use style::selector_parser::PseudoElementCascadeType;
|
2016-07-06 04:55:36 +03:00
|
|
|
use style::sequential;
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
|
2016-09-26 10:36:05 +03:00
|
|
|
use style::string_cache::Atom;
|
2017-04-28 18:25:21 +03:00
|
|
|
use style::style_adjuster::StyleAdjuster;
|
2017-05-03 04:01:10 +03:00
|
|
|
use style::stylearc::Arc;
|
2017-04-12 18:00:26 +03:00
|
|
|
use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers};
|
2017-05-19 07:49:30 +03:00
|
|
|
use style::stylesheets::{ImportRule, KeyframesRule, MediaRule, NamespaceRule, Origin};
|
2017-05-11 14:27:42 +03:00
|
|
|
use style::stylesheets::{PageRule, Stylesheet, StyleRule, SupportsRule, DocumentRule};
|
2016-12-31 06:12:55 +03:00
|
|
|
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
|
2017-01-17 00:56:51 +03:00
|
|
|
use style::supports::parse_condition_or_declaration;
|
2016-11-21 17:16:36 +03:00
|
|
|
use style::thread_state;
|
2016-07-20 21:38:31 +03:00
|
|
|
use style::timer::Timer;
|
2017-05-21 11:07:47 +03:00
|
|
|
use style::traversal::{ANIMATION_ONLY, FOR_CSS_RULE_CHANGES, FOR_RECONSTRUCT, UNSTYLED_CHILDREN_ONLY};
|
2017-03-27 07:13:44 +03:00
|
|
|
use style::traversal::{resolve_style, DomTraversal, TraversalDriver, TraversalFlags};
|
2017-05-19 07:49:30 +03:00
|
|
|
use style::values::{CustomIdent, KeyframesName};
|
2016-11-07 08:26:08 +03:00
|
|
|
use style_traits::ToCss;
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
use super::stylesheet_loader::StylesheetLoader;
|
2016-09-26 10:36:05 +03:00
|
|
|
|
2016-01-19 11:49:10 +03:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2017-04-03 15:05:42 +03:00
|
|
|
// A dummy url data for where we don't pass url data in.
|
|
|
|
// We need to get rid of this sooner than later.
|
2017-04-07 03:33:35 +03:00
|
|
|
static mut DUMMY_URL_DATA: *mut URLExtraData = 0 as *mut URLExtraData;
|
2017-02-23 21:15:41 +03:00
|
|
|
|
2016-05-05 04:37:26 +03:00
|
|
|
#[no_mangle]
|
2017-04-07 03:33:35 +03:00
|
|
|
pub extern "C" fn Servo_Initialize(dummy_url_data: *mut URLExtraData) {
|
2017-05-14 02:53:07 +03:00
|
|
|
use style::parser::assert_parsing_mode_match;
|
|
|
|
|
2017-02-15 14:05:07 +03:00
|
|
|
// Initialize logging.
|
|
|
|
let mut builder = LogBuilder::new();
|
|
|
|
let default_level = if cfg!(debug_assertions) { "warn" } else { "error" };
|
|
|
|
match env::var("RUST_LOG") {
|
|
|
|
Ok(v) => builder.parse(&v).init().unwrap(),
|
|
|
|
_ => builder.parse(default_level).init().unwrap(),
|
|
|
|
};
|
2016-08-04 04:20:21 +03:00
|
|
|
|
2016-11-21 17:16:36 +03:00
|
|
|
// Pretend that we're a Servo Layout thread, to make some assertions happy.
|
|
|
|
thread_state::initialize(thread_state::LAYOUT);
|
2017-02-14 06:44:12 +03:00
|
|
|
|
|
|
|
// Perform some debug-only runtime assertions.
|
|
|
|
restyle_hints::assert_restyle_hints_match();
|
2017-05-14 02:53:07 +03:00
|
|
|
assert_parsing_mode_match();
|
2017-02-20 08:12:57 +03:00
|
|
|
|
|
|
|
// Initialize some static data.
|
|
|
|
gecko_properties::initialize();
|
2017-04-03 15:05:42 +03:00
|
|
|
|
|
|
|
// Initialize the dummy url data
|
2017-04-07 03:33:35 +03:00
|
|
|
unsafe { DUMMY_URL_DATA = dummy_url_data; }
|
2016-08-04 04:20:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2017-03-13 20:01:16 +03:00
|
|
|
pub extern "C" fn Servo_Shutdown() {
|
2017-02-20 08:12:57 +03:00
|
|
|
// Clear some static data to avoid shutdown leaks.
|
|
|
|
gecko_properties::shutdown();
|
2017-04-03 15:05:42 +03:00
|
|
|
|
2017-04-07 03:33:35 +03:00
|
|
|
// The dummy url will be released after shutdown, so clear the
|
|
|
|
// reference to avoid use-after-free.
|
|
|
|
unsafe { DUMMY_URL_DATA = ptr::null_mut(); }
|
2017-04-03 15:05:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn dummy_url_data() -> &'static RefPtr<URLExtraData> {
|
2017-04-07 03:33:35 +03:00
|
|
|
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
|
2016-11-25 20:00:44 +03:00
|
|
|
}
|
2016-04-04 17:41:29 +03:00
|
|
|
|
2017-05-12 16:56:47 +03:00
|
|
|
static DEFAULT_ERROR_REPORTER: RustLogReporter = RustLogReporter;
|
|
|
|
|
2017-04-12 10:27:02 +03:00
|
|
|
fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
|
|
|
|
guard: &'a SharedRwLockReadGuard,
|
2017-05-12 16:56:47 +03:00
|
|
|
per_doc_data: &'a PerDocumentStyleDataImpl,
|
2017-05-10 23:08:59 +03:00
|
|
|
traversal_flags: TraversalFlags,
|
|
|
|
snapshot_map: &'a ServoElementSnapshotTable)
|
|
|
|
-> SharedStyleContext<'a> {
|
2016-11-25 20:00:44 +03:00
|
|
|
SharedStyleContext {
|
2017-05-12 16:56:47 +03:00
|
|
|
stylist: &per_doc_data.stylist,
|
2017-04-12 10:27:02 +03:00
|
|
|
options: global_style_data.options.clone(),
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
guards: StylesheetGuards::same(guard),
|
2017-05-12 16:56:47 +03:00
|
|
|
error_reporter: &DEFAULT_ERROR_REPORTER,
|
2016-07-20 21:38:31 +03:00
|
|
|
timer: Timer::new(),
|
2017-05-14 04:50:10 +03:00
|
|
|
quirks_mode: per_doc_data.stylist.quirks_mode(),
|
2017-04-09 09:04:57 +03:00
|
|
|
traversal_flags: traversal_flags,
|
2017-05-10 23:08:59 +03:00
|
|
|
snapshot_map: snapshot_map,
|
2016-11-25 20:00:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-27 15:39:42 +03:00
|
|
|
fn traverse_subtree(element: GeckoElement,
|
|
|
|
raw_data: RawServoStyleSetBorrowed,
|
2017-05-10 23:08:59 +03:00
|
|
|
traversal_flags: TraversalFlags,
|
|
|
|
snapshots: &ServoElementSnapshotTable) {
|
2016-11-25 20:00:44 +03:00
|
|
|
// When new content is inserted in a display:none subtree, we will call into
|
|
|
|
// servo to try to style it. Detect that here and bail out.
|
|
|
|
if let Some(parent) = element.parent_element() {
|
2016-12-15 06:41:12 +03:00
|
|
|
if parent.borrow_data().map_or(true, |d| d.styles().is_display_none()) {
|
2017-03-30 12:34:25 +03:00
|
|
|
debug!("{:?} has unstyled parent {:?} - ignoring call to traverse_subtree", element, parent);
|
2016-11-25 20:00:44 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-23 21:15:41 +03:00
|
|
|
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
2017-04-27 14:45:49 +03:00
|
|
|
debug_assert!(!per_doc_data.stylesheets.has_changed());
|
2016-12-10 04:01:05 +03:00
|
|
|
|
2017-05-10 23:08:59 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let shared_style_context = create_shared_context(&global_style_data,
|
|
|
|
&guard,
|
|
|
|
&per_doc_data,
|
|
|
|
traversal_flags,
|
|
|
|
snapshots);
|
|
|
|
|
|
|
|
|
|
|
|
let token = RecalcStyleOnly::pre_traverse(element,
|
|
|
|
&shared_style_context,
|
|
|
|
traversal_flags);
|
2016-12-10 04:01:05 +03:00
|
|
|
if !token.should_traverse() {
|
2016-10-26 14:36:06 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-13 06:13:03 +03:00
|
|
|
debug!("Traversing subtree:");
|
|
|
|
debug!("{:?}", ShowSubtreeData(element.as_node()));
|
|
|
|
|
2017-05-18 21:38:41 +03:00
|
|
|
let traversal_driver = if global_style_data.style_thread_pool.is_none() || !element.is_root() {
|
2017-01-25 04:02:41 +03:00
|
|
|
TraversalDriver::Sequential
|
2016-07-28 01:56:26 +03:00
|
|
|
} else {
|
2017-01-25 04:02:41 +03:00
|
|
|
TraversalDriver::Parallel
|
|
|
|
};
|
|
|
|
|
|
|
|
let traversal = RecalcStyleOnly::new(shared_style_context, traversal_driver);
|
2017-05-18 21:38:41 +03:00
|
|
|
if traversal_driver.is_parallel() {
|
2017-04-09 09:55:09 +03:00
|
|
|
parallel::traverse_dom(&traversal, element, token,
|
2017-02-23 21:15:41 +03:00
|
|
|
global_style_data.style_thread_pool.as_ref().unwrap());
|
2017-01-25 04:02:41 +03:00
|
|
|
} else {
|
|
|
|
sequential::traverse_dom(&traversal, element, token);
|
2016-01-19 11:49:10 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-10 23:08:59 +03:00
|
|
|
/// Traverses the subtree rooted at `root` for restyling.
|
|
|
|
///
|
|
|
|
/// Returns whether a Gecko post-traversal (to perform lazy frame construction,
|
|
|
|
/// or consume any RestyleData, or drop any ElementData) is required.
|
2016-05-26 00:26:11 +03:00
|
|
|
#[no_mangle]
|
2016-11-25 20:00:44 +03:00
|
|
|
pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed,
|
|
|
|
raw_data: RawServoStyleSetBorrowed,
|
2017-05-10 23:08:59 +03:00
|
|
|
snapshots: *const ServoElementSnapshotTable,
|
2017-04-09 09:04:57 +03:00
|
|
|
root_behavior: structs::TraversalRootBehavior,
|
|
|
|
restyle_behavior: structs::TraversalRestyleBehavior)
|
|
|
|
-> bool {
|
|
|
|
use self::structs::TraversalRestyleBehavior as Restyle;
|
|
|
|
use self::structs::TraversalRootBehavior as Root;
|
2017-05-10 23:08:59 +03:00
|
|
|
debug_assert!(!snapshots.is_null());
|
2017-04-09 09:04:57 +03:00
|
|
|
|
2016-11-25 20:00:44 +03:00
|
|
|
let element = GeckoElement(root);
|
|
|
|
debug!("Servo_TraverseSubtree: {:?}", element);
|
2017-03-27 07:13:44 +03:00
|
|
|
|
2017-04-09 09:04:57 +03:00
|
|
|
let traversal_flags = match (root_behavior, restyle_behavior) {
|
2017-05-20 15:24:21 +03:00
|
|
|
(Root::Normal, Restyle::Normal) |
|
|
|
|
(Root::Normal, Restyle::ForAnimationOnly)
|
2017-05-21 11:07:47 +03:00
|
|
|
=> TraversalFlags::empty(),
|
2017-05-20 15:24:21 +03:00
|
|
|
(Root::UnstyledChildrenOnly, Restyle::Normal) |
|
|
|
|
(Root::UnstyledChildrenOnly, Restyle::ForAnimationOnly)
|
2017-05-21 11:07:47 +03:00
|
|
|
=> UNSTYLED_CHILDREN_ONLY,
|
|
|
|
(Root::Normal, Restyle::ForCSSRuleChanges) => FOR_CSS_RULE_CHANGES,
|
2017-04-09 09:04:57 +03:00
|
|
|
(Root::Normal, Restyle::ForReconstruct) => FOR_RECONSTRUCT,
|
|
|
|
_ => panic!("invalid combination of TraversalRootBehavior and TraversalRestyleBehavior"),
|
2017-03-27 07:13:44 +03:00
|
|
|
};
|
|
|
|
|
2017-05-20 15:24:21 +03:00
|
|
|
let needs_animation_only_restyle = element.has_animation_only_dirty_descendants() ||
|
|
|
|
element.has_animation_restyle_hints();
|
|
|
|
if needs_animation_only_restyle {
|
2017-05-10 23:08:59 +03:00
|
|
|
traverse_subtree(element,
|
|
|
|
raw_data,
|
|
|
|
traversal_flags | ANIMATION_ONLY,
|
|
|
|
unsafe { &*snapshots });
|
2017-03-27 07:13:44 +03:00
|
|
|
}
|
|
|
|
|
2017-05-20 15:24:21 +03:00
|
|
|
if restyle_behavior == Restyle::ForAnimationOnly {
|
|
|
|
return needs_animation_only_restyle;
|
|
|
|
}
|
|
|
|
|
2017-05-10 23:08:59 +03:00
|
|
|
traverse_subtree(element,
|
|
|
|
raw_data,
|
|
|
|
traversal_flags,
|
|
|
|
unsafe { &*snapshots });
|
2017-02-10 06:27:33 +03:00
|
|
|
|
2017-05-10 23:08:59 +03:00
|
|
|
element.has_dirty_descendants() || element.borrow_data().unwrap().has_restyle()
|
2016-05-26 00:26:11 +03:00
|
|
|
}
|
|
|
|
|
2017-01-26 10:36:33 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValues_Interpolate(from: RawServoAnimationValueBorrowed,
|
|
|
|
to: RawServoAnimationValueBorrowed,
|
|
|
|
progress: f64)
|
|
|
|
-> RawServoAnimationValueStrong
|
|
|
|
{
|
|
|
|
let from_value = AnimationValue::as_arc(&from);
|
|
|
|
let to_value = AnimationValue::as_arc(&to);
|
|
|
|
if let Ok(value) = from_value.interpolate(to_value, progress) {
|
|
|
|
Arc::new(value).into_strong()
|
|
|
|
} else {
|
|
|
|
RawServoAnimationValueStrong::null()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-12 15:00:20 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValues_IsInterpolable(from: RawServoAnimationValueBorrowed,
|
|
|
|
to: RawServoAnimationValueBorrowed)
|
|
|
|
-> bool {
|
|
|
|
let from_value = AnimationValue::as_arc(&from);
|
|
|
|
let to_value = AnimationValue::as_arc(&to);
|
|
|
|
from_value.interpolate(to_value, 0.5).is_ok()
|
|
|
|
}
|
|
|
|
|
2017-04-21 08:52:13 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValues_ComputeDistance(from: RawServoAnimationValueBorrowed,
|
|
|
|
to: RawServoAnimationValueBorrowed)
|
|
|
|
-> f64 {
|
|
|
|
let from_value = AnimationValue::as_arc(&from);
|
|
|
|
let to_value = AnimationValue::as_arc(&to);
|
|
|
|
from_value.compute_distance(to_value).unwrap_or(0.0)
|
|
|
|
}
|
|
|
|
|
2017-01-26 10:36:33 +03:00
|
|
|
#[no_mangle]
|
2017-05-01 13:51:48 +03:00
|
|
|
pub extern "C" fn Servo_AnimationValueMap_Push(value_map: RawServoAnimationValueMapBorrowedMut,
|
2017-03-17 13:09:31 +03:00
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: RawServoAnimationValueBorrowed)
|
2017-01-26 10:36:33 +03:00
|
|
|
{
|
2017-03-17 13:09:31 +03:00
|
|
|
use style::properties::animated_properties::AnimationValueMap;
|
|
|
|
|
2017-05-01 13:51:48 +03:00
|
|
|
let value_map = AnimationValueMap::from_ffi_mut(value_map);
|
2017-03-17 13:09:31 +03:00
|
|
|
let value = AnimationValue::as_arc(&value).as_ref();
|
2017-05-01 13:51:48 +03:00
|
|
|
value_map.insert(property.into(), value.clone());
|
2017-01-26 10:36:33 +03:00
|
|
|
}
|
|
|
|
|
2017-04-06 06:53:30 +03:00
|
|
|
#[no_mangle]
|
2017-05-01 13:51:48 +03:00
|
|
|
pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMapBorrowedMut,
|
2017-04-06 06:53:30 +03:00
|
|
|
base_values: *mut ::std::os::raw::c_void,
|
|
|
|
css_property: nsCSSPropertyID,
|
|
|
|
segment: RawGeckoAnimationPropertySegmentBorrowed,
|
2017-05-24 08:03:42 +03:00
|
|
|
last_segment: RawGeckoAnimationPropertySegmentBorrowed,
|
|
|
|
computed_timing: RawGeckoComputedTimingBorrowed,
|
|
|
|
iteration_composite: IterationCompositeOperation)
|
2017-04-06 06:53:30 +03:00
|
|
|
{
|
|
|
|
use style::gecko_bindings::bindings::Gecko_AnimationGetBaseStyle;
|
|
|
|
use style::gecko_bindings::bindings::Gecko_GetPositionInSegment;
|
|
|
|
use style::gecko_bindings::bindings::Gecko_GetProgressFromComputedTiming;
|
|
|
|
use style::properties::animated_properties::AnimationValueMap;
|
|
|
|
|
|
|
|
let property: TransitionProperty = css_property.into();
|
2017-05-01 13:51:48 +03:00
|
|
|
let value_map = AnimationValueMap::from_ffi_mut(raw_value_map);
|
2017-04-06 06:53:30 +03:00
|
|
|
|
2017-05-24 08:03:42 +03:00
|
|
|
// We will need an underlying value if either of the endpoints is null...
|
2017-05-15 07:24:48 +03:00
|
|
|
let need_underlying_value = segment.mFromValue.mServo.mRawPtr.is_null() ||
|
|
|
|
segment.mToValue.mServo.mRawPtr.is_null() ||
|
2017-05-24 08:03:42 +03:00
|
|
|
// ... or if they have a non-replace composite mode ...
|
2017-05-15 07:24:48 +03:00
|
|
|
segment.mFromComposite != CompositeOperation::Replace ||
|
2017-05-24 08:03:42 +03:00
|
|
|
segment.mToComposite != CompositeOperation::Replace ||
|
|
|
|
// ... or if we accumulate onto the last value and it is null.
|
|
|
|
(iteration_composite == IterationCompositeOperation::Accumulate &&
|
|
|
|
computed_timing.mCurrentIteration > 0 &&
|
|
|
|
last_segment.mToValue.mServo.mRawPtr.is_null());
|
2017-05-15 07:24:48 +03:00
|
|
|
|
2017-04-06 06:53:30 +03:00
|
|
|
// If either of the segment endpoints are null, get the underlying value to
|
|
|
|
// use from the current value in the values map (set by a lower-priority
|
|
|
|
// effect), or, if there is no current value, look up the cached base value
|
|
|
|
// for this property.
|
2017-05-15 07:24:48 +03:00
|
|
|
let underlying_value = if need_underlying_value {
|
2017-05-01 13:51:48 +03:00
|
|
|
let previous_composed_value = value_map.get(&property).cloned();
|
2017-04-06 06:53:30 +03:00
|
|
|
previous_composed_value.or_else(|| {
|
|
|
|
let raw_base_style = unsafe { Gecko_AnimationGetBaseStyle(base_values, css_property) };
|
|
|
|
AnimationValue::arc_from_borrowed(&raw_base_style).map(|v| v.as_ref()).cloned()
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
2017-05-15 07:24:48 +03:00
|
|
|
if need_underlying_value && underlying_value.is_none() {
|
|
|
|
warn!("Underlying value should be valid when we expect to use it");
|
2017-04-06 06:53:30 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-24 08:03:42 +03:00
|
|
|
// Extract keyframe values.
|
2017-04-06 06:53:30 +03:00
|
|
|
let raw_from_value;
|
2017-05-24 08:03:42 +03:00
|
|
|
let keyframe_from_value = if !segment.mFromValue.mServo.mRawPtr.is_null() {
|
2017-04-06 06:53:30 +03:00
|
|
|
raw_from_value = unsafe { &*segment.mFromValue.mServo.mRawPtr };
|
2017-05-24 08:03:42 +03:00
|
|
|
Some(AnimationValue::as_arc(&raw_from_value))
|
2017-04-06 06:53:30 +03:00
|
|
|
} else {
|
2017-05-24 08:03:42 +03:00
|
|
|
None
|
2017-04-06 06:53:30 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
let raw_to_value;
|
2017-05-24 08:03:42 +03:00
|
|
|
let keyframe_to_value = if !segment.mToValue.mServo.mRawPtr.is_null() {
|
2017-04-06 06:53:30 +03:00
|
|
|
raw_to_value = unsafe { &*segment.mToValue.mServo.mRawPtr };
|
2017-05-24 08:03:42 +03:00
|
|
|
Some(AnimationValue::as_arc(&raw_to_value))
|
2017-04-06 06:53:30 +03:00
|
|
|
} else {
|
2017-05-24 08:03:42 +03:00
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
// Composite with underlying value.
|
|
|
|
// A return value of None means, "Just use keyframe_value as-is."
|
|
|
|
let composite_endpoint = |keyframe_value: Option<&Arc<AnimationValue>>,
|
|
|
|
composite_op: CompositeOperation| -> Option<AnimationValue> {
|
|
|
|
match keyframe_value {
|
|
|
|
Some(keyframe_value) => {
|
|
|
|
match composite_op {
|
|
|
|
CompositeOperation::Add => {
|
|
|
|
debug_assert!(need_underlying_value,
|
|
|
|
"Should have detected we need an underlying value");
|
|
|
|
underlying_value.as_ref().unwrap().add(keyframe_value).ok()
|
|
|
|
},
|
|
|
|
CompositeOperation::Accumulate => {
|
|
|
|
debug_assert!(need_underlying_value,
|
|
|
|
"Should have detected we need an underlying value");
|
|
|
|
underlying_value.as_ref().unwrap().accumulate(keyframe_value, 1).ok()
|
|
|
|
},
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
debug_assert!(need_underlying_value,
|
|
|
|
"Should have detected we need an underlying value");
|
|
|
|
underlying_value.clone()
|
|
|
|
},
|
|
|
|
}
|
2017-04-06 06:53:30 +03:00
|
|
|
};
|
2017-05-24 08:03:42 +03:00
|
|
|
let mut composited_from_value = composite_endpoint(keyframe_from_value, segment.mFromComposite);
|
|
|
|
let mut composited_to_value = composite_endpoint(keyframe_to_value, segment.mToComposite);
|
|
|
|
|
|
|
|
debug_assert!(keyframe_from_value.is_some() || composited_from_value.is_some(),
|
|
|
|
"Should have a suitable from value to use");
|
|
|
|
debug_assert!(keyframe_to_value.is_some() || composited_to_value.is_some(),
|
|
|
|
"Should have a suitable to value to use");
|
|
|
|
|
|
|
|
// Apply iteration composite behavior.
|
|
|
|
if iteration_composite == IterationCompositeOperation::Accumulate &&
|
|
|
|
computed_timing.mCurrentIteration > 0 {
|
|
|
|
let raw_last_value;
|
|
|
|
let last_value = if !last_segment.mToValue.mServo.mRawPtr.is_null() {
|
|
|
|
raw_last_value = unsafe { &*last_segment.mToValue.mServo.mRawPtr };
|
|
|
|
AnimationValue::as_arc(&raw_last_value).as_ref()
|
|
|
|
} else {
|
|
|
|
debug_assert!(need_underlying_value,
|
|
|
|
"Should have detected we need an underlying value");
|
|
|
|
underlying_value.as_ref().unwrap()
|
|
|
|
};
|
|
|
|
|
|
|
|
// As with composite_endpoint, a return value of None means, "Use keyframe_value as-is."
|
|
|
|
let apply_iteration_composite = |keyframe_value: Option<&Arc<AnimationValue>>,
|
|
|
|
composited_value: Option<AnimationValue>|
|
|
|
|
-> Option<AnimationValue> {
|
|
|
|
let count = computed_timing.mCurrentIteration;
|
|
|
|
match composited_value {
|
|
|
|
Some(endpoint) => last_value.accumulate(&endpoint, count)
|
|
|
|
.ok()
|
|
|
|
.or(Some(endpoint)),
|
|
|
|
None => last_value.accumulate(keyframe_value.unwrap(), count)
|
|
|
|
.ok(),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
composited_from_value = apply_iteration_composite(keyframe_from_value,
|
|
|
|
composited_from_value);
|
|
|
|
composited_to_value = apply_iteration_composite(keyframe_to_value,
|
|
|
|
composited_to_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use the composited value if there is one, otherwise, use the original keyframe value.
|
|
|
|
let from_value = composited_from_value.as_ref().unwrap_or_else(|| keyframe_from_value.unwrap());
|
|
|
|
let to_value = composited_to_value.as_ref().unwrap_or_else(|| keyframe_to_value.unwrap());
|
2017-04-06 06:53:30 +03:00
|
|
|
|
|
|
|
let progress = unsafe { Gecko_GetProgressFromComputedTiming(computed_timing) };
|
|
|
|
if segment.mToKey == segment.mFromKey {
|
|
|
|
if progress < 0. {
|
2017-05-01 13:51:48 +03:00
|
|
|
value_map.insert(property, from_value.clone());
|
2017-04-06 06:53:30 +03:00
|
|
|
} else {
|
2017-05-01 13:51:48 +03:00
|
|
|
value_map.insert(property, to_value.clone());
|
2017-04-06 06:53:30 +03:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let position = unsafe {
|
|
|
|
Gecko_GetPositionInSegment(segment, progress, computed_timing.mBeforeFlag)
|
|
|
|
};
|
|
|
|
if let Ok(value) = from_value.interpolate(to_value, position) {
|
2017-05-01 13:51:48 +03:00
|
|
|
value_map.insert(property, value);
|
2017-04-06 06:53:30 +03:00
|
|
|
} else if progress < 0.5 {
|
2017-05-01 13:51:48 +03:00
|
|
|
value_map.insert(property, from_value.clone());
|
2017-04-06 06:53:30 +03:00
|
|
|
} else {
|
2017-05-01 13:51:48 +03:00
|
|
|
value_map.insert(property, to_value.clone());
|
2017-04-06 06:53:30 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-10 12:34:07 +03:00
|
|
|
macro_rules! get_property_id_from_nscsspropertyid {
|
|
|
|
($property_id: ident, $ret: expr) => {{
|
|
|
|
match PropertyId::from_nscsspropertyid($property_id) {
|
|
|
|
Ok(property_id) => property_id,
|
|
|
|
Err(()) => { return $ret; }
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
2017-02-09 05:39:45 +03:00
|
|
|
#[no_mangle]
|
2017-02-10 12:34:07 +03:00
|
|
|
pub extern "C" fn Servo_AnimationValue_Serialize(value: RawServoAnimationValueBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
buffer: *mut nsAString)
|
|
|
|
{
|
|
|
|
let uncomputed_value = AnimationValue::as_arc(&value).uncompute();
|
|
|
|
let mut string = String::new();
|
2017-03-08 14:07:04 +03:00
|
|
|
let rv = PropertyDeclarationBlock::with_one(uncomputed_value, Importance::Normal)
|
|
|
|
.single_value_to_css(&get_property_id_from_nscsspropertyid!(property, ()), &mut string);
|
2017-02-10 12:34:07 +03:00
|
|
|
debug_assert!(rv.is_ok());
|
|
|
|
|
|
|
|
write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValue_GetOpacity(value: RawServoAnimationValueBorrowed)
|
2017-02-09 05:39:45 +03:00
|
|
|
-> f32
|
|
|
|
{
|
|
|
|
let value = AnimationValue::as_arc(&value);
|
|
|
|
if let AnimationValue::Opacity(opacity) = **value {
|
|
|
|
opacity
|
|
|
|
} else {
|
|
|
|
panic!("The AnimationValue should be Opacity");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2017-02-10 12:34:07 +03:00
|
|
|
pub extern "C" fn Servo_AnimationValue_GetTransform(value: RawServoAnimationValueBorrowed,
|
2017-02-16 13:58:54 +03:00
|
|
|
list: *mut structs::RefPtr<nsCSSValueSharedList>)
|
2017-02-09 05:39:45 +03:00
|
|
|
{
|
|
|
|
let value = AnimationValue::as_arc(&value);
|
|
|
|
if let AnimationValue::Transform(ref servo_list) = **value {
|
2017-05-20 15:24:21 +03:00
|
|
|
let list = unsafe { &mut *list };
|
|
|
|
match servo_list.0 {
|
|
|
|
Some(ref servo_list) => {
|
|
|
|
style_structs::Box::convert_transform(servo_list, list);
|
|
|
|
},
|
|
|
|
None => unsafe {
|
|
|
|
list.set_move(RefPtr::from_addrefed(Gecko_NewNoneTransform()));
|
|
|
|
}
|
|
|
|
}
|
2017-02-09 05:39:45 +03:00
|
|
|
} else {
|
|
|
|
panic!("The AnimationValue should be transform");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-24 10:16:14 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBorrowed,
|
|
|
|
other: RawServoAnimationValueBorrowed)
|
|
|
|
-> bool
|
|
|
|
{
|
|
|
|
let this_value = AnimationValue::as_arc(&this);
|
|
|
|
let other_value = AnimationValue::as_arc(&other);
|
|
|
|
this_value == other_value
|
|
|
|
}
|
|
|
|
|
2017-04-12 15:00:20 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValue_Uncompute(value: RawServoAnimationValueBorrowed)
|
|
|
|
-> RawServoDeclarationBlockStrong {
|
|
|
|
let value = AnimationValue::as_arc(&value);
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
Arc::new(global_style_data.shared_lock.wrap(
|
|
|
|
PropertyDeclarationBlock::with_one(value.uncompute(), Importance::Normal))).into_strong()
|
|
|
|
}
|
|
|
|
|
2017-04-06 06:53:30 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
element: RawGeckoElementBorrowed,
|
2017-05-10 23:08:59 +03:00
|
|
|
snapshots: *const ServoElementSnapshotTable,
|
2017-05-16 04:46:42 +03:00
|
|
|
pseudo_type: CSSPseudoElementType)
|
2017-04-06 06:53:30 +03:00
|
|
|
-> ServoComputedValuesStrong
|
|
|
|
{
|
|
|
|
use style::matching::MatchMethods;
|
2017-05-10 23:08:59 +03:00
|
|
|
debug_assert!(!snapshots.is_null());
|
2017-04-06 06:53:30 +03:00
|
|
|
|
|
|
|
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
2017-05-10 23:08:59 +03:00
|
|
|
let shared_context = create_shared_context(&global_style_data,
|
|
|
|
&guard,
|
|
|
|
&doc_data,
|
|
|
|
TraversalFlags::empty(),
|
|
|
|
unsafe { &*snapshots });
|
2017-04-06 06:53:30 +03:00
|
|
|
let element = GeckoElement(element);
|
|
|
|
let element_data = element.borrow_data().unwrap();
|
|
|
|
let styles = element_data.styles();
|
|
|
|
|
2017-05-16 04:46:42 +03:00
|
|
|
let pseudo = PseudoElement::from_pseudo_type(pseudo_type);
|
2017-04-06 06:53:30 +03:00
|
|
|
let pseudos = &styles.pseudos;
|
2017-04-23 12:55:34 +03:00
|
|
|
let pseudo_style = match pseudo {
|
|
|
|
Some(ref p) => {
|
|
|
|
let style = pseudos.get(p);
|
|
|
|
debug_assert!(style.is_some());
|
|
|
|
style
|
|
|
|
}
|
|
|
|
None => None,
|
|
|
|
};
|
2017-04-06 06:53:30 +03:00
|
|
|
|
2017-04-09 14:15:51 +03:00
|
|
|
let provider = get_metrics_provider_for_product();
|
2017-05-10 23:08:59 +03:00
|
|
|
element.get_base_style(&shared_context,
|
|
|
|
&provider,
|
|
|
|
&styles.primary,
|
|
|
|
pseudo_style)
|
2017-04-06 06:53:30 +03:00
|
|
|
.into_strong()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_ComputedValues_ExtractAnimationValue(computed_values: ServoComputedValuesBorrowed,
|
|
|
|
property_id: nsCSSPropertyID)
|
|
|
|
-> RawServoAnimationValueStrong
|
|
|
|
{
|
|
|
|
let computed_values = ComputedValues::as_arc(&computed_values);
|
|
|
|
Arc::new(AnimationValue::from_computed_values(&property_id.into(), computed_values)).into_strong()
|
|
|
|
}
|
|
|
|
|
2017-04-12 15:00:20 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool {
|
|
|
|
use style::properties::animated_properties;
|
|
|
|
animated_properties::nscsspropertyid_is_animatable(property)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Property_IsDiscreteAnimatable(property: nsCSSPropertyID) -> bool {
|
|
|
|
let property: TransitionProperty = property.into();
|
|
|
|
property.is_discrete()
|
|
|
|
}
|
|
|
|
|
2016-07-06 04:55:36 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 {
|
2017-02-23 21:15:41 +03:00
|
|
|
GLOBAL_STYLE_DATA.num_threads as u32
|
2016-07-06 04:55:36 +03:00
|
|
|
}
|
|
|
|
|
2016-01-19 11:49:10 +03:00
|
|
|
#[no_mangle]
|
2017-03-13 20:01:16 +03:00
|
|
|
pub extern "C" fn Servo_Element_ClearData(element: RawGeckoElementBorrowed) {
|
2016-11-25 20:00:44 +03:00
|
|
|
GeckoElement(element).clear_data();
|
2016-01-19 11:49:10 +03:00
|
|
|
}
|
2016-02-04 20:55:09 +03:00
|
|
|
|
2016-11-10 21:56:48 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyleSheetStrong {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
2016-11-10 21:56:48 +03:00
|
|
|
let origin = match mode {
|
|
|
|
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
|
|
|
|
SheetParsingMode::eUserSheetFeatures => Origin::User,
|
|
|
|
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
|
2017-05-02 07:52:36 +03:00
|
|
|
SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent,
|
2016-11-10 21:56:48 +03:00
|
|
|
};
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let shared_lock = global_style_data.shared_lock.clone();
|
2017-02-23 22:02:24 +03:00
|
|
|
Arc::new(Stylesheet::from_str(
|
2017-04-03 15:05:42 +03:00
|
|
|
"", unsafe { dummy_url_data() }.clone(), origin,
|
2017-04-12 18:00:26 +03:00
|
|
|
Arc::new(shared_lock.wrap(MediaList::empty())),
|
2017-04-28 06:32:24 +03:00
|
|
|
shared_lock, None, &RustLogReporter, QuirksMode::NoQuirks, 0u64)
|
2017-02-23 22:02:24 +03:00
|
|
|
).into_strong()
|
2016-11-10 21:56:48 +03:00
|
|
|
}
|
|
|
|
|
2016-02-04 20:55:09 +03:00
|
|
|
#[no_mangle]
|
2016-12-31 06:12:55 +03:00
|
|
|
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
|
|
|
|
stylesheet: *mut ServoStyleSheet,
|
|
|
|
data: *const nsACString,
|
2016-10-25 12:09:19 +03:00
|
|
|
mode: SheetParsingMode,
|
2017-04-12 18:00:26 +03:00
|
|
|
media_list: *const RawServoMediaList,
|
2017-05-15 13:28:50 +03:00
|
|
|
extra_data: *mut URLExtraData,
|
2017-05-17 14:53:57 +03:00
|
|
|
line_number_offset: u32,
|
|
|
|
quirks_mode: nsCompatibility)
|
2016-10-25 12:09:19 +03:00
|
|
|
-> RawServoStyleSheetStrong {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
2016-10-25 12:09:19 +03:00
|
|
|
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
2016-02-04 20:55:09 +03:00
|
|
|
|
2016-04-30 00:27:16 +03:00
|
|
|
let origin = match mode {
|
|
|
|
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
|
|
|
|
SheetParsingMode::eUserSheetFeatures => Origin::User,
|
|
|
|
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
|
2017-05-02 07:52:36 +03:00
|
|
|
SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent,
|
2016-04-30 00:27:16 +03:00
|
|
|
};
|
|
|
|
|
2017-04-03 15:05:42 +03:00
|
|
|
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
|
2016-12-31 06:12:55 +03:00
|
|
|
let loader = if loader.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(StylesheetLoader::new(loader, stylesheet))
|
|
|
|
};
|
|
|
|
|
|
|
|
// FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
|
|
|
|
let loader: Option<&StyleStylesheetLoader> = match loader {
|
|
|
|
None => None,
|
|
|
|
Some(ref s) => Some(s),
|
|
|
|
};
|
|
|
|
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let shared_lock = global_style_data.shared_lock.clone();
|
2017-04-12 18:00:26 +03:00
|
|
|
let media = if media_list.is_null() {
|
|
|
|
Arc::new(shared_lock.wrap(MediaList::empty()))
|
|
|
|
} else {
|
|
|
|
Locked::<MediaList>::as_arc(unsafe { &&*media_list }).clone()
|
|
|
|
};
|
|
|
|
|
2017-02-23 22:02:24 +03:00
|
|
|
Arc::new(Stylesheet::from_str(
|
2017-04-12 18:00:26 +03:00
|
|
|
input, url_data.clone(), origin, media,
|
2017-05-15 13:28:50 +03:00
|
|
|
shared_lock, loader, &RustLogReporter,
|
2017-05-17 14:53:57 +03:00
|
|
|
quirks_mode.into(), line_number_offset as u64)
|
2017-02-23 22:02:24 +03:00
|
|
|
).into_strong()
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
|
|
|
|
2016-12-31 06:12:55 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheetBorrowed,
|
|
|
|
loader: *mut Loader,
|
|
|
|
gecko_stylesheet: *mut ServoStyleSheet,
|
|
|
|
data: *const nsACString,
|
2017-05-15 13:28:50 +03:00
|
|
|
extra_data: *mut URLExtraData,
|
|
|
|
line_number_offset: u32)
|
2016-12-31 06:12:55 +03:00
|
|
|
{
|
|
|
|
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
2017-04-03 15:05:42 +03:00
|
|
|
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
|
2016-12-31 06:12:55 +03:00
|
|
|
|
|
|
|
let loader = if loader.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(StylesheetLoader::new(loader, gecko_stylesheet))
|
|
|
|
};
|
|
|
|
|
|
|
|
// FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
|
|
|
|
let loader: Option<&StyleStylesheetLoader> = match loader {
|
|
|
|
None => None,
|
|
|
|
Some(ref s) => Some(s),
|
|
|
|
};
|
|
|
|
|
|
|
|
let sheet = Stylesheet::as_arc(&stylesheet);
|
2017-05-15 13:28:50 +03:00
|
|
|
Stylesheet::update_from_str(&sheet, input, url_data, loader,
|
|
|
|
&RustLogReporter, line_number_offset as u64);
|
2016-12-31 06:12:55 +03:00
|
|
|
}
|
|
|
|
|
2016-02-04 20:55:09 +03:00
|
|
|
#[no_mangle]
|
2016-10-11 20:03:29 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowed,
|
2016-12-26 05:13:30 +03:00
|
|
|
raw_sheet: RawServoStyleSheetBorrowed,
|
2017-05-14 00:13:13 +03:00
|
|
|
unique_id: u64) {
|
2016-10-11 20:03:29 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
2016-09-03 06:42:21 +03:00
|
|
|
let sheet = HasArcFFI::as_arc(&raw_sheet);
|
2017-05-03 02:15:05 +03:00
|
|
|
data.stylesheets.append_stylesheet(sheet, unique_id);
|
2017-05-11 00:22:06 +03:00
|
|
|
data.clear_stylist();
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2016-10-11 20:03:29 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowed,
|
2016-12-26 05:13:30 +03:00
|
|
|
raw_sheet: RawServoStyleSheetBorrowed,
|
2017-05-14 00:13:13 +03:00
|
|
|
unique_id: u64) {
|
2016-10-11 20:03:29 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
2016-09-03 06:42:21 +03:00
|
|
|
let sheet = HasArcFFI::as_arc(&raw_sheet);
|
2017-05-03 02:15:05 +03:00
|
|
|
data.stylesheets.prepend_stylesheet(sheet, unique_id);
|
2017-05-11 00:22:06 +03:00
|
|
|
data.clear_stylist();
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
|
|
|
|
2016-04-29 08:37:40 +03:00
|
|
|
#[no_mangle]
|
2016-10-11 20:03:29 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowed,
|
2016-08-24 16:16:05 +03:00
|
|
|
raw_sheet: RawServoStyleSheetBorrowed,
|
2017-05-14 00:13:13 +03:00
|
|
|
unique_id: u64,
|
|
|
|
before_unique_id: u64) {
|
2016-10-11 20:03:29 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
2016-09-03 06:42:21 +03:00
|
|
|
let sheet = HasArcFFI::as_arc(&raw_sheet);
|
2017-05-03 02:15:05 +03:00
|
|
|
data.stylesheets.insert_stylesheet_before(sheet, unique_id, before_unique_id);
|
2017-05-11 00:22:06 +03:00
|
|
|
data.clear_stylist();
|
2016-04-29 08:37:40 +03:00
|
|
|
}
|
|
|
|
|
2016-02-04 20:55:09 +03:00
|
|
|
#[no_mangle]
|
2016-10-11 20:03:29 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowed,
|
2017-05-14 00:13:13 +03:00
|
|
|
unique_id: u64) {
|
2016-10-11 20:03:29 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
2017-05-03 02:15:05 +03:00
|
|
|
data.stylesheets.remove_stylesheet(unique_id);
|
2017-05-11 00:22:06 +03:00
|
|
|
data.clear_stylist();
|
2016-12-26 05:13:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_FlushStyleSheets(raw_data: RawServoStyleSetBorrowed) {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
2016-12-26 05:13:30 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
data.flush_stylesheets(&guard);
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
|
|
|
|
2016-12-19 08:49:28 +03:00
|
|
|
#[no_mangle]
|
2017-04-14 05:23:07 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
author_style_disabled: bool) {
|
2016-12-19 08:49:28 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
2017-04-19 11:41:08 +03:00
|
|
|
data.stylesheets.force_dirty();
|
|
|
|
data.stylesheets.set_author_style_disabled(author_style_disabled);
|
2017-05-11 00:22:06 +03:00
|
|
|
data.clear_stylist();
|
2016-12-19 08:49:28 +03:00
|
|
|
}
|
|
|
|
|
2016-02-04 20:55:09 +03:00
|
|
|
#[no_mangle]
|
2016-08-24 16:16:05 +03:00
|
|
|
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
!Stylesheet::as_arc(&raw_sheet).rules.read_with(&guard).0.is_empty()
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 02:47:18 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong {
|
2016-11-29 14:26:46 +03:00
|
|
|
Stylesheet::as_arc(&sheet).rules.clone().into_strong()
|
2016-11-24 02:47:18 +03:00
|
|
|
}
|
|
|
|
|
2017-03-22 14:17:09 +03:00
|
|
|
fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
|
|
|
|
where Locked<T>: HasArcFFI, F: FnOnce(&T) -> R
|
|
|
|
{
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
func(Locked::<T>::as_arc(&raw).read_with(&guard))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
|
|
|
|
where Locked<T>: HasArcFFI, F: FnOnce(&mut T) -> R
|
|
|
|
{
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let mut guard = global_style_data.shared_lock.write();
|
|
|
|
func(Locked::<T>::as_arc(&raw).write_with(&mut guard))
|
|
|
|
}
|
|
|
|
|
2016-11-24 02:47:18 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
|
2017-03-13 20:01:16 +03:00
|
|
|
result: nsTArrayBorrowed_uintptr_t) {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(rules, |rules: &CssRules| {
|
|
|
|
let iter = rules.0.iter().map(|rule| rule.rule_type() as usize);
|
|
|
|
let (size, upper) = iter.size_hint();
|
|
|
|
debug_assert_eq!(size, upper.unwrap());
|
|
|
|
unsafe { result.set_len(size as u32) };
|
|
|
|
result.iter_mut().zip(iter).fold((), |_, (r, v)| *r = v);
|
|
|
|
})
|
2016-11-24 02:47:18 +03:00
|
|
|
}
|
|
|
|
|
2016-12-01 08:54:46 +03:00
|
|
|
#[no_mangle]
|
2017-04-03 15:05:42 +03:00
|
|
|
pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
|
|
|
|
sheet: RawServoStyleSheetBorrowed,
|
|
|
|
rule: *const nsACString,
|
|
|
|
index: u32,
|
|
|
|
nested: bool,
|
|
|
|
loader: *mut Loader,
|
|
|
|
gecko_stylesheet: *mut ServoStyleSheet,
|
2016-12-01 08:54:46 +03:00
|
|
|
rule_type: *mut u16) -> nsresult {
|
|
|
|
let sheet = Stylesheet::as_arc(&sheet);
|
2017-04-03 15:05:42 +03:00
|
|
|
let loader = if loader.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(StylesheetLoader::new(loader, gecko_stylesheet))
|
|
|
|
};
|
|
|
|
let loader = loader.as_ref().map(|loader| loader as &StyleStylesheetLoader);
|
2016-12-01 08:54:46 +03:00
|
|
|
let rule = unsafe { rule.as_ref().unwrap().as_str_unchecked() };
|
2017-04-12 18:00:26 +03:00
|
|
|
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
match Locked::<CssRules>::as_arc(&rules).insert_rule(&global_style_data.shared_lock,
|
|
|
|
rule,
|
|
|
|
sheet,
|
|
|
|
index as usize,
|
|
|
|
nested,
|
|
|
|
loader) {
|
|
|
|
Ok(new_rule) => {
|
|
|
|
*unsafe { rule_type.as_mut().unwrap() } = new_rule.rule_type() as u16;
|
|
|
|
nsresult::NS_OK
|
2016-12-01 08:54:46 +03:00
|
|
|
}
|
2017-04-12 18:00:26 +03:00
|
|
|
Err(err) => err.into(),
|
|
|
|
}
|
2016-12-01 08:54:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32) -> nsresult {
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(rules, |rules: &mut CssRules| {
|
|
|
|
match rules.remove_rule(index as usize) {
|
|
|
|
Ok(_) => nsresult::NS_OK,
|
|
|
|
Err(err) => err.into()
|
|
|
|
}
|
|
|
|
})
|
2016-12-01 08:54:46 +03:00
|
|
|
}
|
|
|
|
|
2017-05-19 07:49:30 +03:00
|
|
|
macro_rules! impl_basic_rule_funcs_without_getter {
|
|
|
|
{ ($rule_type:ty, $raw_type:ty),
|
|
|
|
debug: $debug:ident,
|
|
|
|
to_css: $to_css:ident,
|
|
|
|
} => {
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn $debug(rule: &$raw_type, result: *mut nsACString) {
|
|
|
|
read_locked_arc(rule, |rule: &$rule_type| {
|
|
|
|
write!(unsafe { result.as_mut().unwrap() }, "{:?}", *rule).unwrap();
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn $to_css(rule: &$raw_type, result: *mut nsAString) {
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let rule = Locked::<$rule_type>::as_arc(&rule);
|
|
|
|
rule.read_with(&guard).to_css(&guard, unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-15 13:58:06 +03:00
|
|
|
macro_rules! impl_basic_rule_funcs {
|
|
|
|
{ ($name:ident, $rule_type:ty, $raw_type:ty),
|
|
|
|
getter: $getter:ident,
|
|
|
|
debug: $debug:ident,
|
|
|
|
to_css: $to_css:ident,
|
|
|
|
} => {
|
|
|
|
#[no_mangle]
|
2017-05-15 13:28:50 +03:00
|
|
|
pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32,
|
|
|
|
line: *mut u32, column: *mut u32)
|
|
|
|
-> Strong<$raw_type> {
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
|
|
|
|
match rules.0[index as usize] {
|
|
|
|
CssRule::$name(ref rule) => {
|
|
|
|
let location = rule.read_with(&guard).source_location;
|
|
|
|
*unsafe { line.as_mut().unwrap() } = location.line as u32;
|
|
|
|
*unsafe { column.as_mut().unwrap() } = location.column as u32;
|
|
|
|
rule.clone().into_strong()
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
unreachable!(concat!(stringify!($getter), "should only be called ",
|
|
|
|
"on a ", stringify!($name), " rule"));
|
2017-03-15 13:58:06 +03:00
|
|
|
}
|
2017-05-15 13:28:50 +03:00
|
|
|
}
|
2017-03-15 13:58:06 +03:00
|
|
|
}
|
|
|
|
|
2017-05-19 07:49:30 +03:00
|
|
|
impl_basic_rule_funcs_without_getter! { ($rule_type, $raw_type),
|
|
|
|
debug: $debug,
|
|
|
|
to_css: $to_css,
|
2017-03-15 13:58:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-28 13:11:04 +03:00
|
|
|
macro_rules! impl_group_rule_funcs {
|
|
|
|
{ ($name:ident, $rule_type:ty, $raw_type:ty),
|
|
|
|
get_rules: $get_rules:ident,
|
|
|
|
$($basic:tt)+
|
|
|
|
} => {
|
|
|
|
impl_basic_rule_funcs! { ($name, $rule_type, $raw_type), $($basic)+ }
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn $get_rules(rule: &$raw_type) -> ServoCssRulesStrong {
|
|
|
|
read_locked_arc(rule, |rule: &$rule_type| {
|
|
|
|
rule.rules.clone().into_strong()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-15 13:58:06 +03:00
|
|
|
impl_basic_rule_funcs! { (Style, StyleRule, RawServoStyleRule),
|
|
|
|
getter: Servo_CssRules_GetStyleRuleAt,
|
|
|
|
debug: Servo_StyleRule_Debug,
|
|
|
|
to_css: Servo_StyleRule_GetCssText,
|
|
|
|
}
|
|
|
|
|
2017-05-19 07:49:30 +03:00
|
|
|
impl_basic_rule_funcs_without_getter! { (Keyframe, RawServoKeyframe),
|
|
|
|
debug: Servo_Keyframe_Debug,
|
|
|
|
to_css: Servo_Keyframe_GetCssText,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_basic_rule_funcs! { (Keyframes, KeyframesRule, RawServoKeyframesRule),
|
|
|
|
getter: Servo_CssRules_GetKeyframesRuleAt,
|
|
|
|
debug: Servo_KeyframesRule_Debug,
|
|
|
|
to_css: Servo_KeyframesRule_GetCssText,
|
|
|
|
}
|
|
|
|
|
2017-04-28 13:11:04 +03:00
|
|
|
impl_group_rule_funcs! { (Media, MediaRule, RawServoMediaRule),
|
|
|
|
get_rules: Servo_MediaRule_GetRules,
|
2017-03-15 13:58:06 +03:00
|
|
|
getter: Servo_CssRules_GetMediaRuleAt,
|
|
|
|
debug: Servo_MediaRule_Debug,
|
|
|
|
to_css: Servo_MediaRule_GetCssText,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_basic_rule_funcs! { (Namespace, NamespaceRule, RawServoNamespaceRule),
|
|
|
|
getter: Servo_CssRules_GetNamespaceRuleAt,
|
|
|
|
debug: Servo_NamespaceRule_Debug,
|
|
|
|
to_css: Servo_NamespaceRule_GetCssText,
|
2016-11-24 02:47:18 +03:00
|
|
|
}
|
|
|
|
|
2017-04-10 05:47:59 +03:00
|
|
|
impl_basic_rule_funcs! { (Page, PageRule, RawServoPageRule),
|
|
|
|
getter: Servo_CssRules_GetPageRuleAt,
|
|
|
|
debug: Servo_PageRule_Debug,
|
|
|
|
to_css: Servo_PageRule_GetCssText,
|
|
|
|
}
|
|
|
|
|
2017-04-28 13:11:04 +03:00
|
|
|
impl_group_rule_funcs! { (Supports, SupportsRule, RawServoSupportsRule),
|
|
|
|
get_rules: Servo_SupportsRule_GetRules,
|
|
|
|
getter: Servo_CssRules_GetSupportsRuleAt,
|
|
|
|
debug: Servo_SupportsRule_Debug,
|
|
|
|
to_css: Servo_SupportsRule_GetCssText,
|
|
|
|
}
|
|
|
|
|
2017-05-11 14:27:42 +03:00
|
|
|
impl_group_rule_funcs! { (Document, DocumentRule, RawServoDocumentRule),
|
|
|
|
get_rules: Servo_DocumentRule_GetRules,
|
|
|
|
getter: Servo_CssRules_GetDocumentRuleAt,
|
|
|
|
debug: Servo_DocumentRule_Debug,
|
|
|
|
to_css: Servo_DocumentRule_GetCssText,
|
|
|
|
}
|
|
|
|
|
2017-05-16 09:17:07 +03:00
|
|
|
macro_rules! impl_getter_for_embedded_rule {
|
|
|
|
($getter:ident: $name:ident -> $ty:ty) => {
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32) -> *mut $ty
|
|
|
|
{
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
|
|
|
|
match rules.0[index as usize] {
|
|
|
|
CssRule::$name(ref rule) => rule.read_with(&guard).get(),
|
|
|
|
_ => unreachable!(concat!(stringify!($getter), " should only be called on a ",
|
|
|
|
stringify!($name), " rule")),
|
|
|
|
}
|
|
|
|
}
|
2017-03-30 04:50:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-16 09:17:07 +03:00
|
|
|
impl_getter_for_embedded_rule!(Servo_CssRules_GetFontFaceRuleAt:
|
|
|
|
FontFace -> nsCSSFontFaceRule);
|
|
|
|
impl_getter_for_embedded_rule!(Servo_CssRules_GetCounterStyleRuleAt:
|
|
|
|
CounterStyle -> nsCSSCounterStyleRule);
|
|
|
|
|
2016-11-24 02:47:18 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) -> RawServoDeclarationBlockStrong {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(rule, |rule: &StyleRule| {
|
|
|
|
rule.block.clone().into_strong()
|
|
|
|
})
|
2016-11-24 02:47:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleRule_SetStyle(rule: RawServoStyleRuleBorrowed,
|
2017-03-13 20:01:16 +03:00
|
|
|
declarations: RawServoDeclarationBlockBorrowed) {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(rule, |rule: &mut StyleRule| {
|
|
|
|
rule.block = declarations.clone();
|
|
|
|
})
|
2016-11-24 02:47:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2017-03-13 20:01:16 +03:00
|
|
|
pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed, result: *mut nsAString) {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(rule, |rule: &StyleRule| {
|
|
|
|
rule.selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
})
|
2016-11-24 02:47:18 +03:00
|
|
|
}
|
|
|
|
|
2017-05-19 07:49:30 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed, result: *mut nsAString) {
|
|
|
|
read_locked_arc(keyframe, |keyframe: &Keyframe| {
|
|
|
|
keyframe.selector.to_css(unsafe { result.as_mut().unwrap() }).unwrap()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Keyframe_SetKeyText(keyframe: RawServoKeyframeBorrowed, text: *const nsACString) -> bool {
|
|
|
|
let text = unsafe { text.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
if let Ok(selector) = Parser::new(&text).parse_entirely(KeyframeSelector::parse) {
|
|
|
|
write_locked_arc(keyframe, |keyframe: &mut Keyframe| {
|
|
|
|
keyframe.selector = selector;
|
|
|
|
});
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Keyframe_GetStyle(keyframe: RawServoKeyframeBorrowed) -> RawServoDeclarationBlockStrong {
|
|
|
|
read_locked_arc(keyframe, |keyframe: &Keyframe| keyframe.block.clone().into_strong())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Keyframe_SetStyle(keyframe: RawServoKeyframeBorrowed,
|
|
|
|
declarations: RawServoDeclarationBlockBorrowed) {
|
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
|
|
|
write_locked_arc(keyframe, |keyframe: &mut Keyframe| {
|
|
|
|
keyframe.block = declarations.clone();
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_KeyframesRule_GetName(rule: RawServoKeyframesRuleBorrowed) -> *mut nsIAtom {
|
|
|
|
read_locked_arc(rule, |rule: &KeyframesRule| rule.name.as_atom().as_ptr())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2017-05-21 23:40:41 +03:00
|
|
|
pub extern "C" fn Servo_KeyframesRule_SetName(rule: RawServoKeyframesRuleBorrowed, name: *mut nsIAtom) {
|
2017-05-19 07:49:30 +03:00
|
|
|
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
2017-05-21 23:40:41 +03:00
|
|
|
rule.name = KeyframesName::Ident(CustomIdent(unsafe { Atom::from_addrefed(name) }));
|
2017-05-19 07:49:30 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_KeyframesRule_GetCount(rule: RawServoKeyframesRuleBorrowed) -> u32 {
|
|
|
|
read_locked_arc(rule, |rule: &KeyframesRule| rule.keyframes.len() as u32)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_KeyframesRule_GetKeyframe(rule: RawServoKeyframesRuleBorrowed, index: u32)
|
|
|
|
-> RawServoKeyframeStrong {
|
|
|
|
read_locked_arc(rule, |rule: &KeyframesRule| {
|
|
|
|
rule.keyframes[index as usize].clone().into_strong()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_KeyframesRule_FindRule(rule: RawServoKeyframesRuleBorrowed,
|
|
|
|
key: *const nsACString) -> u32 {
|
|
|
|
let key = unsafe { key.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
Locked::<KeyframesRule>::as_arc(&rule).read_with(&guard)
|
|
|
|
.find_rule(&guard, key).map(|index| index as u32)
|
|
|
|
.unwrap_or(u32::max_value())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_KeyframesRule_AppendRule(rule: RawServoKeyframesRuleBorrowed,
|
|
|
|
sheet: RawServoStyleSheetBorrowed,
|
|
|
|
css: *const nsACString) -> bool {
|
|
|
|
let css = unsafe { css.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
let sheet = Stylesheet::as_arc(&sheet);
|
|
|
|
if let Ok(keyframe) = Keyframe::parse(css, sheet) {
|
|
|
|
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
|
|
|
rule.keyframes.push(keyframe);
|
|
|
|
});
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_KeyframesRule_DeleteRule(rule: RawServoKeyframesRuleBorrowed, index: u32) {
|
|
|
|
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
|
|
|
rule.keyframes.remove(index as usize);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-03-13 09:55:46 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaRule_GetMedia(rule: RawServoMediaRuleBorrowed) -> RawServoMediaListStrong {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(rule, |rule: &MediaRule| {
|
|
|
|
rule.media_queries.clone().into_strong()
|
|
|
|
})
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2017-03-15 13:58:06 +03:00
|
|
|
pub extern "C" fn Servo_NamespaceRule_GetPrefix(rule: RawServoNamespaceRuleBorrowed) -> *mut nsIAtom {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(rule, |rule: &NamespaceRule| {
|
|
|
|
rule.prefix.as_ref().unwrap_or(&atom!("")).as_ptr()
|
|
|
|
})
|
2017-03-15 13:58:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_NamespaceRule_GetURI(rule: RawServoNamespaceRuleBorrowed) -> *mut nsIAtom {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(rule, |rule: &NamespaceRule| rule.url.0.as_ptr())
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
2017-04-10 05:47:59 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_PageRule_GetStyle(rule: RawServoPageRuleBorrowed) -> RawServoDeclarationBlockStrong {
|
|
|
|
read_locked_arc(rule, |rule: &PageRule| {
|
2017-05-15 13:28:50 +03:00
|
|
|
rule.block.clone().into_strong()
|
2017-04-10 05:47:59 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_PageRule_SetStyle(rule: RawServoPageRuleBorrowed,
|
|
|
|
declarations: RawServoDeclarationBlockBorrowed) {
|
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
|
|
|
write_locked_arc(rule, |rule: &mut PageRule| {
|
2017-05-15 13:28:50 +03:00
|
|
|
rule.block = declarations.clone();
|
2017-04-10 05:47:59 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-04-28 13:11:04 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_SupportsRule_GetConditionText(rule: RawServoSupportsRuleBorrowed,
|
|
|
|
result: *mut nsAString) {
|
|
|
|
read_locked_arc(rule, |rule: &SupportsRule| {
|
|
|
|
rule.condition.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-05-11 14:27:42 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DocumentRule_GetConditionText(rule: RawServoDocumentRuleBorrowed,
|
|
|
|
result: *mut nsAString) {
|
|
|
|
read_locked_arc(rule, |rule: &DocumentRule| {
|
|
|
|
rule.condition.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-03-25 00:57:33 +03:00
|
|
|
#[no_mangle]
|
2016-09-03 06:42:21 +03:00
|
|
|
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
2017-03-13 20:47:05 +03:00
|
|
|
pseudo_tag: *mut nsIAtom,
|
|
|
|
skip_display_fixup: bool,
|
|
|
|
raw_data: RawServoStyleSetBorrowed)
|
2016-08-17 15:35:43 +03:00
|
|
|
-> ServoComputedValuesStrong {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let guards = StylesheetGuards::same(&guard);
|
2016-12-26 05:13:30 +03:00
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
2016-08-16 20:50:29 +03:00
|
|
|
let atom = Atom::from(pseudo_tag);
|
2017-05-16 04:46:42 +03:00
|
|
|
let pseudo = PseudoElement::from_anon_box_atom(&atom)
|
|
|
|
.expect("Not an anon box pseudo?");
|
2016-04-30 00:27:16 +03:00
|
|
|
|
|
|
|
|
2016-10-05 08:59:56 +03:00
|
|
|
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
|
2017-03-13 20:47:05 +03:00
|
|
|
let mut cascade_flags = CascadeFlags::empty();
|
|
|
|
if skip_display_fixup {
|
|
|
|
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
|
|
|
|
}
|
2017-04-09 14:15:51 +03:00
|
|
|
let metrics = get_metrics_provider_for_product();
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
|
2017-04-09 14:15:51 +03:00
|
|
|
cascade_flags, &metrics)
|
2017-02-10 21:34:57 +03:00
|
|
|
.values.unwrap()
|
2017-01-09 13:46:09 +03:00
|
|
|
.into_strong()
|
2016-03-25 00:57:33 +03:00
|
|
|
}
|
|
|
|
|
2016-05-04 13:42:23 +03:00
|
|
|
#[no_mangle]
|
2016-12-26 05:13:30 +03:00
|
|
|
pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
|
2017-05-16 04:46:42 +03:00
|
|
|
pseudo_type: CSSPseudoElementType,
|
|
|
|
is_probe: bool,
|
2016-12-26 05:13:30 +03:00
|
|
|
raw_data: RawServoStyleSetBorrowed)
|
|
|
|
-> ServoComputedValuesStrong
|
|
|
|
{
|
|
|
|
let element = GeckoElement(element);
|
|
|
|
let data = unsafe { element.ensure_data() }.borrow_mut();
|
2017-01-05 08:01:38 +03:00
|
|
|
let doc_data = PerDocumentStyleData::from_ffi(raw_data);
|
2016-05-04 13:42:23 +03:00
|
|
|
|
2016-12-26 05:13:30 +03:00
|
|
|
// FIXME(bholley): Assert against this.
|
|
|
|
if data.get_styles().is_none() {
|
2017-02-15 14:05:07 +03:00
|
|
|
warn!("Calling Servo_ResolvePseudoStyle on unstyled element");
|
2016-12-26 05:13:30 +03:00
|
|
|
return if is_probe {
|
2016-09-03 06:42:21 +03:00
|
|
|
Strong::null()
|
2016-05-04 13:42:23 +03:00
|
|
|
} else {
|
2017-01-18 16:39:57 +03:00
|
|
|
doc_data.borrow().default_computed_values().clone().into_strong()
|
2016-12-26 05:13:30 +03:00
|
|
|
};
|
|
|
|
}
|
2016-05-04 13:42:23 +03:00
|
|
|
|
2017-05-16 04:46:42 +03:00
|
|
|
let pseudo = PseudoElement::from_pseudo_type(pseudo_type)
|
|
|
|
.expect("ResolvePseudoStyle with a non-pseudo?");
|
|
|
|
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
2017-05-16 04:46:42 +03:00
|
|
|
match get_pseudo_style(&guard, element, &pseudo, data.styles(), doc_data) {
|
2016-12-26 05:13:30 +03:00
|
|
|
Some(values) => values.into_strong(),
|
2017-05-16 04:46:42 +03:00
|
|
|
// FIXME(emilio): This looks pretty wrong! Shouldn't it be at least an
|
|
|
|
// empty style inheriting from the element?
|
2017-02-10 21:34:57 +03:00
|
|
|
None if !is_probe => data.styles().primary.values().clone().into_strong(),
|
2016-12-26 05:13:30 +03:00
|
|
|
None => Strong::null(),
|
|
|
|
}
|
|
|
|
}
|
2016-05-04 13:42:23 +03:00
|
|
|
|
2017-05-09 21:21:29 +03:00
|
|
|
#[no_mangle]
|
2017-05-16 04:46:42 +03:00
|
|
|
pub extern "C" fn Servo_HasAuthorSpecifiedRules(element: RawGeckoElementBorrowed,
|
2017-05-09 21:21:29 +03:00
|
|
|
rule_type_mask: u32,
|
|
|
|
author_colors_allowed: bool)
|
|
|
|
-> bool
|
|
|
|
{
|
|
|
|
let element = GeckoElement(element);
|
2017-05-16 04:46:42 +03:00
|
|
|
|
|
|
|
let data = element.borrow_data().unwrap();
|
|
|
|
let primary_style = &data.styles().primary;
|
|
|
|
|
2017-05-09 21:21:29 +03:00
|
|
|
let guard = (*GLOBAL_STYLE_DATA).shared_lock.read();
|
|
|
|
let guards = StylesheetGuards::same(&guard);
|
|
|
|
|
2017-05-16 04:46:42 +03:00
|
|
|
primary_style.rules.has_author_specified_rules(element,
|
|
|
|
&guards,
|
|
|
|
rule_type_mask,
|
|
|
|
author_colors_allowed)
|
2017-05-09 21:21:29 +03:00
|
|
|
}
|
|
|
|
|
2017-04-27 15:39:42 +03:00
|
|
|
fn get_pseudo_style(guard: &SharedRwLockReadGuard,
|
|
|
|
element: GeckoElement,
|
2017-05-16 04:46:42 +03:00
|
|
|
pseudo: &PseudoElement,
|
2017-04-27 15:39:42 +03:00
|
|
|
styles: &ElementStyles,
|
|
|
|
doc_data: &PerDocumentStyleData)
|
2016-12-26 05:13:30 +03:00
|
|
|
-> Option<Arc<ComputedValues>>
|
|
|
|
{
|
2017-04-27 15:39:42 +03:00
|
|
|
match pseudo.cascade_type() {
|
2017-02-10 21:34:57 +03:00
|
|
|
PseudoElementCascadeType::Eager => styles.pseudos.get(&pseudo).map(|s| s.values().clone()),
|
2016-12-26 05:13:30 +03:00
|
|
|
PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"),
|
2016-05-04 13:42:23 +03:00
|
|
|
PseudoElementCascadeType::Lazy => {
|
2016-12-26 05:13:30 +03:00
|
|
|
let d = doc_data.borrow_mut();
|
2017-05-23 10:25:07 +03:00
|
|
|
let base = if pseudo.inherits_from_default_values() {
|
|
|
|
d.default_computed_values()
|
|
|
|
} else {
|
|
|
|
styles.primary.values()
|
|
|
|
};
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let guards = StylesheetGuards::same(guard);
|
2017-04-09 14:15:51 +03:00
|
|
|
let metrics = get_metrics_provider_for_product();
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
d.stylist.lazily_compute_pseudo_element_style(&guards,
|
|
|
|
&element,
|
2017-02-25 22:00:07 +03:00
|
|
|
&pseudo,
|
2017-04-09 14:15:51 +03:00
|
|
|
base,
|
|
|
|
&metrics)
|
2017-02-10 21:34:57 +03:00
|
|
|
.map(|s| s.values().clone())
|
2016-12-26 05:13:30 +03:00
|
|
|
},
|
2016-05-04 13:42:23 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-06 14:30:47 +03:00
|
|
|
#[no_mangle]
|
2017-01-05 08:01:38 +03:00
|
|
|
pub extern "C" fn Servo_ComputedValues_Inherit(
|
|
|
|
raw_data: RawServoStyleSetBorrowed,
|
2017-04-28 18:25:21 +03:00
|
|
|
parent_style: ServoComputedValuesBorrowedOrNull,
|
|
|
|
target: structs::InheritTarget)
|
2016-08-17 15:35:43 +03:00
|
|
|
-> ServoComputedValuesStrong {
|
2017-01-05 08:01:38 +03:00
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
2016-10-05 08:59:56 +03:00
|
|
|
let maybe_arc = ComputedValues::arc_from_borrowed(&parent_style);
|
2017-04-28 18:25:21 +03:00
|
|
|
|
|
|
|
let for_text = target == structs::InheritTarget::Text;
|
2016-10-05 08:59:56 +03:00
|
|
|
let style = if let Some(reference) = maybe_arc.as_ref() {
|
2017-04-28 18:25:21 +03:00
|
|
|
let mut style =
|
2017-05-01 02:31:41 +03:00
|
|
|
StyleBuilder::for_inheritance(reference,
|
|
|
|
&data.default_computed_values());
|
2017-04-28 18:25:21 +03:00
|
|
|
if for_text {
|
|
|
|
StyleAdjuster::new(&mut style, /* is_root = */ false)
|
|
|
|
.adjust_for_text();
|
|
|
|
}
|
|
|
|
|
2017-05-01 02:31:41 +03:00
|
|
|
Arc::new(style.build())
|
2016-08-04 04:20:21 +03:00
|
|
|
} else {
|
2017-04-28 18:25:21 +03:00
|
|
|
debug_assert!(!for_text);
|
2017-01-18 16:39:57 +03:00
|
|
|
data.default_computed_values().clone()
|
2016-08-04 04:20:21 +03:00
|
|
|
};
|
2017-04-28 18:25:21 +03:00
|
|
|
|
2016-09-03 06:42:21 +03:00
|
|
|
style.into_strong()
|
2016-05-06 14:30:47 +03:00
|
|
|
}
|
|
|
|
|
2017-01-18 16:39:57 +03:00
|
|
|
/// See the comment in `Device` to see why it's ok to pass an owned reference to
|
|
|
|
/// the pres context (hint: the context outlives the StyleSet, that holds the
|
|
|
|
/// device alive).
|
2016-02-04 20:55:09 +03:00
|
|
|
#[no_mangle]
|
2017-01-18 16:39:57 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
|
2017-01-05 08:01:38 +03:00
|
|
|
-> RawServoStyleSetOwned {
|
|
|
|
let data = Box::new(PerDocumentStyleData::new(pres_context));
|
2016-09-03 06:42:21 +03:00
|
|
|
data.into_ffi()
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
|
|
|
|
2017-01-05 08:01:38 +03:00
|
|
|
#[no_mangle]
|
2017-01-18 16:39:57 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_RebuildData(raw_data: RawServoStyleSetBorrowed) {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
2017-01-05 08:01:38 +03:00
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
data.reset_device(&guard);
|
2017-01-05 08:01:38 +03:00
|
|
|
}
|
|
|
|
|
2017-05-17 17:21:53 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_Clear(raw_data: RawServoStyleSetBorrowed) {
|
|
|
|
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
|
|
|
data.clear_stylist();
|
|
|
|
}
|
|
|
|
|
2016-02-04 20:55:09 +03:00
|
|
|
#[no_mangle]
|
2017-03-13 20:01:16 +03:00
|
|
|
pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) {
|
2016-09-03 06:42:21 +03:00
|
|
|
let _ = data.into_box::<PerDocumentStyleData>();
|
2016-02-04 20:55:09 +03:00
|
|
|
}
|
2016-06-24 05:46:25 +03:00
|
|
|
|
2017-05-20 02:37:14 +03:00
|
|
|
fn parse_property_into(declarations: &mut SourcePropertyDeclaration,
|
|
|
|
property_id: PropertyId,
|
|
|
|
value: *const nsACString,
|
|
|
|
data: *mut URLExtraData,
|
|
|
|
parsing_mode: structs::ParsingMode,
|
|
|
|
quirks_mode: QuirksMode) -> Result<(), ()> {
|
2017-05-14 02:53:07 +03:00
|
|
|
use style::parser::ParsingMode;
|
2017-05-11 05:25:47 +03:00
|
|
|
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
|
2017-05-14 02:53:07 +03:00
|
|
|
let parsing_mode = ParsingMode::from_bits_truncate(parsing_mode);
|
2017-05-11 05:25:47 +03:00
|
|
|
|
2017-05-20 02:37:14 +03:00
|
|
|
parse_one_declaration_into(
|
|
|
|
declarations,
|
|
|
|
property_id,
|
|
|
|
value,
|
|
|
|
url_data,
|
|
|
|
&RustLogReporter,
|
|
|
|
parsing_mode,
|
|
|
|
quirks_mode)
|
2017-05-11 05:25:47 +03:00
|
|
|
}
|
|
|
|
|
2016-10-09 16:53:28 +03:00
|
|
|
#[no_mangle]
|
2017-04-15 14:20:52 +03:00
|
|
|
pub extern "C" fn Servo_ParseProperty(property: nsCSSPropertyID, value: *const nsACString,
|
2017-05-11 05:25:47 +03:00
|
|
|
data: *mut URLExtraData,
|
2017-05-17 14:53:57 +03:00
|
|
|
parsing_mode: structs::ParsingMode,
|
|
|
|
quirks_mode: nsCompatibility)
|
2016-10-18 08:51:14 +03:00
|
|
|
-> RawServoDeclarationBlockStrong {
|
2017-04-15 14:20:52 +03:00
|
|
|
let id = get_property_id_from_nscsspropertyid!(property,
|
|
|
|
RawServoDeclarationBlockStrong::null());
|
2017-05-20 02:37:14 +03:00
|
|
|
let mut declarations = SourcePropertyDeclaration::new();
|
|
|
|
match parse_property_into(&mut declarations, id, value, data,
|
|
|
|
parsing_mode, quirks_mode.into()) {
|
|
|
|
Ok(()) => {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
2017-03-08 14:07:04 +03:00
|
|
|
let mut block = PropertyDeclarationBlock::new();
|
2017-05-20 02:37:14 +03:00
|
|
|
block.extend(declarations.drain(), Importance::Normal);
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
Arc::new(global_style_data.shared_lock.wrap(block)).into_strong()
|
2017-03-08 14:07:04 +03:00
|
|
|
}
|
|
|
|
Err(_) => RawServoDeclarationBlockStrong::null()
|
2016-10-09 16:53:28 +03:00
|
|
|
}
|
|
|
|
}
|
2016-10-18 08:51:14 +03:00
|
|
|
|
2017-03-21 11:36:49 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_ParseEasing(easing: *const nsAString,
|
2017-04-03 07:30:56 +03:00
|
|
|
data: *mut URLExtraData,
|
2017-03-21 11:36:49 +03:00
|
|
|
output: nsTimingFunctionBorrowedMut)
|
|
|
|
-> bool {
|
|
|
|
use style::properties::longhands::transition_timing_function;
|
|
|
|
|
2017-04-03 15:05:42 +03:00
|
|
|
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
|
2017-04-24 13:05:51 +03:00
|
|
|
let reporter = RustLogReporter;
|
2017-04-28 18:25:21 +03:00
|
|
|
let context = ParserContext::new(Origin::Author,
|
|
|
|
url_data,
|
|
|
|
&reporter,
|
|
|
|
Some(CssRuleType::Style),
|
2017-05-14 02:53:07 +03:00
|
|
|
PARSING_MODE_DEFAULT,
|
2017-04-28 06:32:24 +03:00
|
|
|
QuirksMode::NoQuirks);
|
2017-03-21 11:36:49 +03:00
|
|
|
let easing = unsafe { (*easing).to_string() };
|
|
|
|
match transition_timing_function::single_value::parse(&context, &mut Parser::new(&easing)) {
|
|
|
|
Ok(parsed_easing) => {
|
|
|
|
*output = parsed_easing.into();
|
|
|
|
true
|
|
|
|
},
|
|
|
|
Err(_) => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-20 15:24:21 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_GetProperties_Overriding_Animation(element: RawGeckoElementBorrowed,
|
|
|
|
list: RawGeckoCSSPropertyIDListBorrowed,
|
|
|
|
set: nsCSSPropertyIDSetBorrowedMut) {
|
|
|
|
let element = GeckoElement(element);
|
|
|
|
let element_data = match element.borrow_data() {
|
|
|
|
Some(data) => data,
|
|
|
|
None => return
|
|
|
|
};
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let guards = StylesheetGuards::same(&guard);
|
|
|
|
let (overridden, custom) =
|
|
|
|
element_data.styles().primary.rules.get_properties_overriding_animations(&guards);
|
|
|
|
for p in list.iter() {
|
|
|
|
match PropertyId::from_nscsspropertyid(*p) {
|
|
|
|
Ok(property) => {
|
|
|
|
if let PropertyId::Longhand(id) = property {
|
|
|
|
if overridden.contains(id) {
|
|
|
|
unsafe { Gecko_AddPropertyToSet(set, *p) };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(_) => {
|
|
|
|
if *p == nsCSSPropertyID::eCSSPropertyExtra_variable && custom {
|
|
|
|
unsafe { Gecko_AddPropertyToSet(set, *p) };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-24 05:46:25 +03:00
|
|
|
#[no_mangle]
|
2017-03-11 23:08:49 +03:00
|
|
|
pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString,
|
2017-05-14 04:50:10 +03:00
|
|
|
raw_extra_data: *mut URLExtraData,
|
|
|
|
quirks_mode: nsCompatibility)
|
2017-03-11 23:08:49 +03:00
|
|
|
-> RawServoDeclarationBlockStrong {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
2016-10-25 12:09:19 +03:00
|
|
|
let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
2017-04-03 15:05:42 +03:00
|
|
|
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
Arc::new(global_style_data.shared_lock.wrap(
|
2017-05-14 04:50:10 +03:00
|
|
|
GeckoElement::parse_style_attribute(value, url_data, quirks_mode.into()))).into_strong()
|
2016-06-24 05:46:25 +03:00
|
|
|
}
|
|
|
|
|
2016-11-04 07:42:06 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_CreateEmpty() -> RawServoDeclarationBlockStrong {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
Arc::new(global_style_data.shared_lock.wrap(PropertyDeclarationBlock::new())).into_strong()
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclarationBlockBorrowed)
|
|
|
|
-> RawServoDeclarationBlockStrong {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
|
|
|
Arc::new(global_style_data.shared_lock.wrap(
|
|
|
|
declarations.read_with(&guard).clone()
|
|
|
|
)).into_strong()
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
2016-10-09 16:53:28 +03:00
|
|
|
#[no_mangle]
|
2016-10-18 08:51:14 +03:00
|
|
|
pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
|
|
|
|
b: RawServoDeclarationBlockBorrowed)
|
2016-10-09 16:53:28 +03:00
|
|
|
-> bool {
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
*Locked::<PropertyDeclarationBlock>::as_arc(&a).read_with(&guard).declarations() ==
|
|
|
|
*Locked::<PropertyDeclarationBlock>::as_arc(&b).read_with(&guard).declarations()
|
2016-06-24 05:46:25 +03:00
|
|
|
}
|
2016-07-19 07:25:31 +03:00
|
|
|
|
2016-11-04 07:42:06 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
result: *mut nsAString) {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
decls.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
})
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
2016-10-09 16:53:28 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
|
2016-10-18 08:51:14 +03:00
|
|
|
declarations: RawServoDeclarationBlockBorrowed,
|
2016-12-18 05:22:10 +03:00
|
|
|
property_id: nsCSSPropertyID, buffer: *mut nsAString)
|
2016-10-09 16:53:28 +03:00
|
|
|
{
|
2016-12-18 05:22:10 +03:00
|
|
|
let property_id = get_property_id_from_nscsspropertyid!(property_id, ());
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
let mut string = String::new();
|
|
|
|
let rv = decls.single_value_to_css(&property_id, &mut string);
|
|
|
|
debug_assert!(rv.is_ok());
|
2016-10-18 08:51:14 +03:00
|
|
|
|
2017-03-22 14:17:09 +03:00
|
|
|
write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string");
|
|
|
|
})
|
2016-10-09 16:53:28 +03:00
|
|
|
}
|
|
|
|
|
2017-05-22 07:22:35 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_SerializeFontValueForCanvas(
|
|
|
|
declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
buffer: *mut nsAString) {
|
|
|
|
use style::properties::shorthands::font;
|
|
|
|
|
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
let longhands = match font::LonghandsToSerialize::from_iter(decls.declarations_iter()) {
|
|
|
|
Ok(l) => l,
|
|
|
|
Err(()) => {
|
|
|
|
warn!("Unexpected property!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut string = String::new();
|
|
|
|
let rv = longhands.to_css_for_canvas(&mut string);
|
|
|
|
debug_assert!(rv.is_ok());
|
|
|
|
|
|
|
|
write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string");
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-11-04 07:42:06 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
decls.declarations().len() as u32
|
|
|
|
})
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
index: u32, result: *mut nsAString) -> bool {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
if let Some(&(ref decl, _)) = decls.declarations().get(index as usize) {
|
|
|
|
let result = unsafe { result.as_mut().unwrap() };
|
2017-05-02 12:19:59 +03:00
|
|
|
result.assign_utf8(&decl.id().name());
|
2017-03-22 14:17:09 +03:00
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
})
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
2016-12-18 05:22:10 +03:00
|
|
|
macro_rules! get_property_id_from_property {
|
|
|
|
($property: ident, $ret: expr) => {{
|
|
|
|
let property = unsafe { $property.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
match PropertyId::parse(Cow::Borrowed(property)) {
|
|
|
|
Ok(property_id) => property_id,
|
|
|
|
Err(()) => { return $ret; }
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_property_value(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
property_id: PropertyId, value: *mut nsAString) {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
decls.property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() }).unwrap();
|
|
|
|
})
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_GetPropertyValue(declarations: RawServoDeclarationBlockBorrowed,
|
2016-12-18 05:22:10 +03:00
|
|
|
property: *const nsACString, value: *mut nsAString) {
|
|
|
|
get_property_value(declarations, get_property_id_from_property!(property, ()), value)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_GetPropertyValueById(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID, value: *mut nsAString) {
|
|
|
|
get_property_value(declarations, get_property_id_from_nscsspropertyid!(property, ()), value)
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
|
2016-12-18 05:22:10 +03:00
|
|
|
property: *const nsACString) -> bool {
|
|
|
|
let property_id = get_property_id_from_property!(property, false);
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
decls.property_priority(&property_id).important()
|
|
|
|
})
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
2016-12-18 05:22:10 +03:00
|
|
|
fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId,
|
2017-04-14 12:49:29 +03:00
|
|
|
value: *const nsACString, is_important: bool, data: *mut URLExtraData,
|
2017-05-17 14:53:57 +03:00
|
|
|
parsing_mode: structs::ParsingMode,
|
|
|
|
quirks_mode: QuirksMode) -> bool {
|
2017-05-20 02:37:14 +03:00
|
|
|
let mut source_declarations = SourcePropertyDeclaration::new();
|
|
|
|
match parse_property_into(&mut source_declarations, property_id, value, data,
|
|
|
|
parsing_mode, quirks_mode) {
|
|
|
|
Ok(()) => {
|
2017-05-11 05:25:47 +03:00
|
|
|
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
2017-05-20 02:37:14 +03:00
|
|
|
decls.extend_reset(source_declarations.drain(), importance)
|
2017-05-11 05:25:47 +03:00
|
|
|
})
|
|
|
|
},
|
|
|
|
Err(_) => false,
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2016-12-18 05:22:10 +03:00
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed,
|
2017-03-10 02:02:06 +03:00
|
|
|
property: *const nsACString, value: *const nsACString,
|
2017-04-14 12:49:29 +03:00
|
|
|
is_important: bool, data: *mut URLExtraData,
|
2017-05-17 14:53:57 +03:00
|
|
|
parsing_mode: structs::ParsingMode,
|
|
|
|
quirks_mode: nsCompatibility) -> bool {
|
2017-03-10 02:02:06 +03:00
|
|
|
set_property(declarations, get_property_id_from_property!(property, false),
|
2017-05-17 14:53:57 +03:00
|
|
|
value, is_important, data, parsing_mode, quirks_mode.into())
|
2016-12-18 05:22:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoDeclarationBlockBorrowed,
|
2017-03-10 02:02:06 +03:00
|
|
|
property: nsCSSPropertyID, value: *const nsACString,
|
2017-04-14 12:49:29 +03:00
|
|
|
is_important: bool, data: *mut URLExtraData,
|
2017-05-17 14:53:57 +03:00
|
|
|
parsing_mode: structs::ParsingMode,
|
|
|
|
quirks_mode: nsCompatibility) -> bool {
|
2017-03-10 02:02:06 +03:00
|
|
|
set_property(declarations, get_property_id_from_nscsspropertyid!(property, false),
|
2017-05-17 14:53:57 +03:00
|
|
|
value, is_important, data, parsing_mode, quirks_mode.into())
|
2016-12-18 05:22:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.remove_property(&property_id);
|
|
|
|
});
|
2016-12-18 05:22:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
property: *const nsACString) {
|
|
|
|
remove_property(declarations, get_property_id_from_property!(property, ()))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID) {
|
|
|
|
remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ()))
|
2016-11-04 07:42:06 +03:00
|
|
|
}
|
|
|
|
|
2017-04-12 18:00:26 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_Create() -> RawServoMediaListStrong {
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
Arc::new(global_style_data.shared_lock.wrap(MediaList::empty())).into_strong()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_DeepClone(list: RawServoMediaListBorrowed) -> RawServoMediaListStrong {
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
read_locked_arc(list, |list: &MediaList| {
|
|
|
|
Arc::new(global_style_data.shared_lock.wrap(list.clone()))
|
|
|
|
.into_strong()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_Matches(list: RawServoMediaListBorrowed,
|
|
|
|
raw_data: RawServoStyleSetBorrowed)
|
|
|
|
-> bool {
|
|
|
|
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
read_locked_arc(list, |list: &MediaList| {
|
2017-05-23 04:12:46 +03:00
|
|
|
list.evaluate(per_doc_data.stylist.device(), per_doc_data.stylist.quirks_mode())
|
2017-04-12 18:00:26 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-04-15 14:20:52 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_HasCSSWideKeyword(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID) -> bool {
|
|
|
|
let property_id = get_property_id_from_nscsspropertyid!(property, false);
|
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
decls.has_css_wide_keyword(&property_id)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-03-13 09:55:46 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed, result: *mut nsAString) {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(list, |list: &MediaList| {
|
|
|
|
list.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
})
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed, text: *const nsACString) {
|
|
|
|
let text = unsafe { text.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
let mut parser = Parser::new(&text);
|
2017-04-12 13:38:50 +03:00
|
|
|
let url_data = unsafe { dummy_url_data() };
|
2017-04-24 13:05:51 +03:00
|
|
|
let reporter = RustLogReporter;
|
2017-04-14 12:49:29 +03:00
|
|
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
2017-05-14 02:53:07 +03:00
|
|
|
PARSING_MODE_DEFAULT,
|
2017-04-28 06:32:24 +03:00
|
|
|
QuirksMode::NoQuirks);
|
2017-04-12 13:38:50 +03:00
|
|
|
write_locked_arc(list, |list: &mut MediaList| {
|
|
|
|
*list = parse_media_query_list(&context, &mut parser);
|
2017-03-22 14:17:09 +03:00
|
|
|
})
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_GetLength(list: RawServoMediaListBorrowed) -> u32 {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(list, |list: &MediaList| list.media_queries.len() as u32)
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_GetMediumAt(list: RawServoMediaListBorrowed, index: u32,
|
|
|
|
result: *mut nsAString) -> bool {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(list, |list: &MediaList| {
|
|
|
|
if let Some(media_query) = list.media_queries.get(index as usize) {
|
|
|
|
media_query.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
})
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed,
|
|
|
|
new_medium: *const nsACString) {
|
|
|
|
let new_medium = unsafe { new_medium.as_ref().unwrap().as_str_unchecked() };
|
2017-04-12 13:38:50 +03:00
|
|
|
let url_data = unsafe { dummy_url_data() };
|
2017-04-24 13:05:51 +03:00
|
|
|
let reporter = RustLogReporter;
|
2017-04-14 12:49:29 +03:00
|
|
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
2017-05-14 02:53:07 +03:00
|
|
|
PARSING_MODE_DEFAULT,
|
2017-04-28 06:32:24 +03:00
|
|
|
QuirksMode::NoQuirks);
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(list, |list: &mut MediaList| {
|
2017-04-12 13:38:50 +03:00
|
|
|
list.append_medium(&context, new_medium);
|
2017-03-22 14:17:09 +03:00
|
|
|
})
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed,
|
|
|
|
old_medium: *const nsACString) -> bool {
|
|
|
|
let old_medium = unsafe { old_medium.as_ref().unwrap().as_str_unchecked() };
|
2017-04-12 13:38:50 +03:00
|
|
|
let url_data = unsafe { dummy_url_data() };
|
2017-04-24 13:05:51 +03:00
|
|
|
let reporter = RustLogReporter;
|
2017-04-14 12:49:29 +03:00
|
|
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
2017-05-14 02:53:07 +03:00
|
|
|
PARSING_MODE_DEFAULT,
|
2017-04-28 06:32:24 +03:00
|
|
|
QuirksMode::NoQuirks);
|
2017-04-12 13:38:50 +03:00
|
|
|
write_locked_arc(list, |list: &mut MediaList| list.delete_medium(&context, old_medium))
|
2017-03-13 09:55:46 +03:00
|
|
|
}
|
|
|
|
|
2017-02-19 07:43:33 +03:00
|
|
|
macro_rules! get_longhand_from_id {
|
2017-05-11 03:05:21 +03:00
|
|
|
($id:expr) => {
|
2017-02-19 07:43:33 +03:00
|
|
|
match PropertyId::from_nscsspropertyid($id) {
|
|
|
|
Ok(PropertyId::Longhand(long)) => long,
|
|
|
|
_ => {
|
2017-05-11 03:05:21 +03:00
|
|
|
panic!("stylo: unknown presentation property with id {:?}", $id);
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
2017-02-04 04:36:04 +03:00
|
|
|
}
|
|
|
|
};
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! match_wrap_declared {
|
|
|
|
($longhand:ident, $($property:ident => $inner:expr,)*) => (
|
|
|
|
match $longhand {
|
|
|
|
$(
|
2017-03-17 00:48:53 +03:00
|
|
|
LonghandId::$property => PropertyDeclaration::$property($inner),
|
2017-02-19 07:43:33 +03:00
|
|
|
)*
|
|
|
|
_ => {
|
2017-05-11 03:05:21 +03:00
|
|
|
panic!("stylo: Don't know how to handle presentation property {:?}", $longhand);
|
2017-02-04 04:36:04 +03:00
|
|
|
}
|
|
|
|
}
|
2017-02-19 07:43:33 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_PropertyIsSet(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID)
|
|
|
|
-> bool {
|
|
|
|
use style::properties::PropertyDeclarationId;
|
2017-05-11 03:05:21 +03:00
|
|
|
let long = get_longhand_from_id!(property);
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
|
|
|
decls.get(PropertyDeclarationId::Longhand(long)).is_some()
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetIdentStringValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property:
|
|
|
|
nsCSSPropertyID,
|
|
|
|
value:
|
|
|
|
*mut nsIAtom) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::properties::longhands::_x_lang::computed_value::T as Lang;
|
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let prop = match_wrap_declared! { long,
|
|
|
|
XLang => Lang(Atom::from(value)),
|
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
#[allow(unreachable_code)]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: i32) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::properties::longhands;
|
2017-03-20 10:28:46 +03:00
|
|
|
use style::values::specified::BorderStyle;
|
2017-02-19 07:43:33 +03:00
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let value = value as u32;
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
|
|
|
MozUserModify => longhands::_moz_user_modify::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
// TextEmphasisPosition => FIXME implement text-emphasis-position
|
2017-04-12 17:16:55 +03:00
|
|
|
Direction => longhands::direction::SpecifiedValue::from_gecko_keyword(value),
|
2017-02-19 07:43:33 +03:00
|
|
|
Display => longhands::display::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
Float => longhands::float::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
VerticalAlign => longhands::vertical_align::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
TextAlign => longhands::text_align::SpecifiedValue::from_gecko_keyword(value),
|
2017-03-31 14:01:06 +03:00
|
|
|
TextEmphasisPosition => longhands::text_emphasis_position::SpecifiedValue::from_gecko_keyword(value),
|
2017-02-19 07:43:33 +03:00
|
|
|
Clear => longhands::clear::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
FontSize => {
|
|
|
|
// We rely on Gecko passing in font-size values (0...7) here.
|
2017-03-20 10:28:46 +03:00
|
|
|
longhands::font_size::SpecifiedValue::from_html_size(value as u8)
|
2017-02-19 07:43:33 +03:00
|
|
|
},
|
2017-04-22 01:03:28 +03:00
|
|
|
FontStyle => longhands::font_style::computed_value::T::from_gecko_keyword(value).into(),
|
2017-04-12 17:16:55 +03:00
|
|
|
FontWeight => longhands::font_weight::SpecifiedValue::from_gecko_keyword(value),
|
2017-02-19 07:43:33 +03:00
|
|
|
ListStyleType => longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value),
|
2017-04-12 17:16:55 +03:00
|
|
|
MozMathVariant => longhands::_moz_math_variant::SpecifiedValue::from_gecko_keyword(value),
|
2017-02-19 07:43:33 +03:00
|
|
|
WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
CaptionSide => longhands::caption_side::SpecifiedValue::from_gecko_keyword(value),
|
|
|
|
BorderTopStyle => BorderStyle::from_gecko_keyword(value),
|
|
|
|
BorderRightStyle => BorderStyle::from_gecko_keyword(value),
|
|
|
|
BorderBottomStyle => BorderStyle::from_gecko_keyword(value),
|
|
|
|
BorderLeftStyle => BorderStyle::from_gecko_keyword(value),
|
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetIntValue(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: i32) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-04-12 17:16:55 +03:00
|
|
|
use style::properties::longhands::_moz_script_level::SpecifiedValue as MozScriptLevel;
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::properties::longhands::_x_span::computed_value::T as Span;
|
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let prop = match_wrap_declared! { long,
|
|
|
|
XSpan => Span(value),
|
2017-04-12 17:16:55 +03:00
|
|
|
// Gecko uses Integer values to signal that it is relative
|
|
|
|
MozScriptLevel => MozScriptLevel::Relative(value),
|
2017-02-19 07:43:33 +03:00
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: f32) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::properties::longhands::border_spacing::SpecifiedValue as BorderSpacing;
|
2017-05-22 09:46:01 +03:00
|
|
|
use style::properties::longhands::height::SpecifiedValue as Height;
|
|
|
|
use style::properties::longhands::width::SpecifiedValue as Width;
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::values::specified::BorderWidth;
|
2017-05-22 09:46:01 +03:00
|
|
|
use style::values::specified::MozLength;
|
2017-05-11 03:05:21 +03:00
|
|
|
use style::values::specified::length::{NoCalcLength, LengthOrPercentage};
|
2017-02-19 07:43:33 +03:00
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let nocalc = NoCalcLength::from_px(value);
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
2017-05-22 09:46:01 +03:00
|
|
|
Height => Height(MozLength::LengthOrPercentageOrAuto(nocalc.into())),
|
|
|
|
Width => Width(MozLength::LengthOrPercentageOrAuto(nocalc.into())),
|
2017-04-16 08:13:28 +03:00
|
|
|
BorderTopWidth => BorderWidth::Width(nocalc.into()),
|
|
|
|
BorderRightWidth => BorderWidth::Width(nocalc.into()),
|
|
|
|
BorderBottomWidth => BorderWidth::Width(nocalc.into()),
|
|
|
|
BorderLeftWidth => BorderWidth::Width(nocalc.into()),
|
2017-02-19 07:43:33 +03:00
|
|
|
MarginTop => nocalc.into(),
|
|
|
|
MarginRight => nocalc.into(),
|
|
|
|
MarginBottom => nocalc.into(),
|
|
|
|
MarginLeft => nocalc.into(),
|
|
|
|
PaddingTop => nocalc.into(),
|
|
|
|
PaddingRight => nocalc.into(),
|
|
|
|
PaddingBottom => nocalc.into(),
|
|
|
|
PaddingLeft => nocalc.into(),
|
|
|
|
BorderSpacing => Box::new(
|
|
|
|
BorderSpacing {
|
|
|
|
horizontal: nocalc.into(),
|
2017-03-27 16:13:39 +03:00
|
|
|
vertical: None,
|
2017-02-04 04:36:04 +03:00
|
|
|
}
|
2017-02-19 07:43:33 +03:00
|
|
|
),
|
2017-05-11 03:05:21 +03:00
|
|
|
BorderTopLeftRadius => Box::new(LengthOrPercentage::from(nocalc).into()),
|
|
|
|
BorderTopRightRadius => Box::new(LengthOrPercentage::from(nocalc).into()),
|
|
|
|
BorderBottomLeftRadius => Box::new(LengthOrPercentage::from(nocalc).into()),
|
|
|
|
BorderBottomRightRadius => Box::new(LengthOrPercentage::from(nocalc).into()),
|
2017-02-19 07:43:33 +03:00
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
2017-04-12 17:16:55 +03:00
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetLengthValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: f32,
|
|
|
|
unit: structs::nsCSSUnit) {
|
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-04-25 21:06:23 +03:00
|
|
|
use style::properties::longhands::_moz_script_min_size::SpecifiedValue as MozScriptMinSize;
|
2017-05-22 09:46:01 +03:00
|
|
|
use style::properties::longhands::width::SpecifiedValue as Width;
|
|
|
|
use style::values::specified::MozLength;
|
2017-05-02 10:27:39 +03:00
|
|
|
use style::values::specified::length::{AbsoluteLength, FontRelativeLength, PhysicalLength};
|
2017-04-12 17:16:55 +03:00
|
|
|
use style::values::specified::length::{LengthOrPercentage, NoCalcLength};
|
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let nocalc = match unit {
|
|
|
|
structs::nsCSSUnit::eCSSUnit_EM => NoCalcLength::FontRelative(FontRelativeLength::Em(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_XHeight => NoCalcLength::FontRelative(FontRelativeLength::Ex(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_Pixel => NoCalcLength::Absolute(AbsoluteLength::Px(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_Inch => NoCalcLength::Absolute(AbsoluteLength::In(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_Centimeter => NoCalcLength::Absolute(AbsoluteLength::Cm(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_Millimeter => NoCalcLength::Absolute(AbsoluteLength::Mm(value)),
|
2017-05-02 10:27:39 +03:00
|
|
|
structs::nsCSSUnit::eCSSUnit_PhysicalMillimeter => NoCalcLength::Physical(PhysicalLength(value)),
|
2017-04-12 17:16:55 +03:00
|
|
|
structs::nsCSSUnit::eCSSUnit_Point => NoCalcLength::Absolute(AbsoluteLength::Pt(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_Pica => NoCalcLength::Absolute(AbsoluteLength::Pc(value)),
|
|
|
|
structs::nsCSSUnit::eCSSUnit_Quarter => NoCalcLength::Absolute(AbsoluteLength::Q(value)),
|
|
|
|
_ => unreachable!("Unknown unit {:?} passed to SetLengthValue", unit)
|
|
|
|
};
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
2017-05-22 09:46:01 +03:00
|
|
|
Width => Width(MozLength::LengthOrPercentageOrAuto(nocalc.into())),
|
2017-04-12 17:16:55 +03:00
|
|
|
FontSize => LengthOrPercentage::from(nocalc).into(),
|
2017-04-25 21:06:23 +03:00
|
|
|
MozScriptMinSize => MozScriptMinSize(nocalc),
|
2017-04-12 17:16:55 +03:00
|
|
|
};
|
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetNumberValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: f32) {
|
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
|
|
|
use style::properties::longhands::_moz_script_level::SpecifiedValue as MozScriptLevel;
|
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
|
|
|
MozScriptSizeMultiplier => value,
|
|
|
|
// Gecko uses Number values to signal that it is absolute
|
|
|
|
MozScriptLevel => MozScriptLevel::Absolute(value as i32),
|
|
|
|
};
|
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-02-19 07:43:33 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: f32) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-05-22 09:46:01 +03:00
|
|
|
use style::properties::longhands::height::SpecifiedValue as Height;
|
|
|
|
use style::properties::longhands::width::SpecifiedValue as Width;
|
|
|
|
use style::values::specified::MozLength;
|
2017-04-12 17:16:55 +03:00
|
|
|
use style::values::specified::length::{LengthOrPercentage, Percentage};
|
2017-02-19 07:43:33 +03:00
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let pc = Percentage(value);
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
2017-05-22 09:46:01 +03:00
|
|
|
Height => Height(MozLength::LengthOrPercentageOrAuto(pc.into())),
|
|
|
|
Width => Width(MozLength::LengthOrPercentageOrAuto(pc.into())),
|
2017-02-19 07:43:33 +03:00
|
|
|
MarginTop => pc.into(),
|
|
|
|
MarginRight => pc.into(),
|
|
|
|
MarginBottom => pc.into(),
|
|
|
|
MarginLeft => pc.into(),
|
2017-04-12 17:16:55 +03:00
|
|
|
FontSize => LengthOrPercentage::from(pc).into(),
|
2017-02-19 07:43:33 +03:00
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-05-22 09:46:01 +03:00
|
|
|
use style::properties::longhands::height::SpecifiedValue as Height;
|
|
|
|
use style::properties::longhands::width::SpecifiedValue as Width;
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::values::specified::LengthOrPercentageOrAuto;
|
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let auto = LengthOrPercentageOrAuto::Auto;
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
2017-05-22 09:46:01 +03:00
|
|
|
Height => Height::auto(),
|
|
|
|
Width => Width::auto(),
|
2017-02-19 07:43:33 +03:00
|
|
|
MarginTop => auto,
|
|
|
|
MarginRight => auto,
|
|
|
|
MarginBottom => auto,
|
|
|
|
MarginLeft => auto,
|
2017-02-04 04:36:04 +03:00
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-03-14 02:50:26 +03:00
|
|
|
use style::values::specified::{Color, CSSColor};
|
2017-02-04 04:36:04 +03:00
|
|
|
|
2017-02-19 07:43:33 +03:00
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let cc = CSSColor { parsed: Color::CurrentColor, authored: None };
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
|
|
|
BorderTopColor => cc,
|
|
|
|
BorderRightColor => cc,
|
|
|
|
BorderBottomColor => cc,
|
|
|
|
BorderLeftColor => cc,
|
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
property: nsCSSPropertyID,
|
|
|
|
value: structs::nscolor) {
|
|
|
|
use style::gecko::values::convert_nscolor_to_rgba;
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::{PropertyDeclaration, LonghandId};
|
2017-02-28 10:08:33 +03:00
|
|
|
use style::properties::longhands;
|
2017-03-14 02:50:26 +03:00
|
|
|
use style::values::specified::{Color, CSSColor};
|
2017-02-19 07:43:33 +03:00
|
|
|
|
|
|
|
let long = get_longhand_from_id!(property);
|
|
|
|
let rgba = convert_nscolor_to_rgba(value);
|
|
|
|
let color = CSSColor { parsed: Color::RGBA(rgba), authored: None };
|
|
|
|
|
|
|
|
let prop = match_wrap_declared! { long,
|
|
|
|
BorderTopColor => color,
|
|
|
|
BorderRightColor => color,
|
|
|
|
BorderBottomColor => color,
|
|
|
|
BorderLeftColor => color,
|
2017-02-28 10:08:33 +03:00
|
|
|
Color => longhands::color::SpecifiedValue(color),
|
2017-02-19 07:43:33 +03:00
|
|
|
BackgroundColor => color,
|
|
|
|
};
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(prop, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetFontFamily(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
value: *const nsAString) {
|
|
|
|
use cssparser::Parser;
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::PropertyDeclaration;
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::properties::longhands::font_family::SpecifiedValue as FontFamily;
|
|
|
|
|
|
|
|
let string = unsafe { (*value).to_string() };
|
|
|
|
let mut parser = Parser::new(&string);
|
|
|
|
if let Ok(family) = FontFamily::parse(&mut parser) {
|
|
|
|
if parser.is_exhausted() {
|
2017-04-22 01:03:28 +03:00
|
|
|
let decl = PropertyDeclaration::FontFamily(Box::new(family));
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(decl, Importance::Normal);
|
|
|
|
})
|
2017-02-19 07:43:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-12 17:16:55 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed,
|
|
|
|
value: *const nsAString,
|
|
|
|
raw_extra_data: *mut URLExtraData) {
|
|
|
|
use style::properties::PropertyDeclaration;
|
|
|
|
use style::properties::longhands::background_image::SpecifiedValue as BackgroundImage;
|
2017-05-15 17:13:38 +03:00
|
|
|
use style::values::Either;
|
|
|
|
use style::values::generics::image::Image;
|
2017-04-12 17:16:55 +03:00
|
|
|
use style::values::specified::url::SpecifiedUrl;
|
|
|
|
|
|
|
|
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
|
|
|
|
let string = unsafe { (*value).to_string() };
|
2017-04-24 13:05:51 +03:00
|
|
|
let error_reporter = RustLogReporter;
|
2017-04-14 12:49:29 +03:00
|
|
|
let context = ParserContext::new(Origin::Author, url_data, &error_reporter,
|
2017-05-14 02:53:07 +03:00
|
|
|
Some(CssRuleType::Style), PARSING_MODE_DEFAULT,
|
2017-04-28 06:32:24 +03:00
|
|
|
QuirksMode::NoQuirks);
|
2017-05-16 02:04:59 +03:00
|
|
|
if let Ok(mut url) = SpecifiedUrl::parse_from_string(string.into(), &context) {
|
|
|
|
url.build_image_value();
|
2017-04-12 17:16:55 +03:00
|
|
|
let decl = PropertyDeclaration::BackgroundImage(BackgroundImage(
|
2017-05-15 17:13:38 +03:00
|
|
|
vec![Either::Second(Image::Url(url))]
|
2017-04-12 17:16:55 +03:00
|
|
|
));
|
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(decl, Importance::Normal);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-19 07:43:33 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarations:
|
|
|
|
RawServoDeclarationBlockBorrowed) {
|
2017-03-17 00:48:53 +03:00
|
|
|
use style::properties::PropertyDeclaration;
|
2017-02-19 07:43:33 +03:00
|
|
|
use style::properties::longhands::text_decoration_line;
|
|
|
|
|
|
|
|
let mut decoration = text_decoration_line::computed_value::none;
|
|
|
|
decoration |= text_decoration_line::COLOR_OVERRIDE;
|
2017-03-17 00:48:53 +03:00
|
|
|
let decl = PropertyDeclaration::TextDecorationLine(decoration);
|
2017-03-22 14:17:09 +03:00
|
|
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
|
|
|
decls.push(decl, Importance::Normal);
|
|
|
|
})
|
2017-02-04 04:36:04 +03:00
|
|
|
}
|
|
|
|
|
2016-07-19 07:25:31 +03:00
|
|
|
#[no_mangle]
|
2017-05-17 14:53:57 +03:00
|
|
|
pub extern "C" fn Servo_CSSSupports2(property: *const nsACString,
|
|
|
|
value: *const nsACString) -> bool {
|
2017-05-11 05:25:47 +03:00
|
|
|
let id = get_property_id_from_property!(property, false);
|
2016-07-19 07:25:31 +03:00
|
|
|
|
2017-05-20 02:37:14 +03:00
|
|
|
let mut declarations = SourcePropertyDeclaration::new();
|
|
|
|
parse_property_into(
|
|
|
|
&mut declarations,
|
|
|
|
id,
|
|
|
|
value,
|
|
|
|
unsafe { DUMMY_URL_DATA },
|
|
|
|
structs::ParsingMode_Default,
|
|
|
|
QuirksMode::NoQuirks
|
|
|
|
).is_ok()
|
2016-07-19 07:25:31 +03:00
|
|
|
}
|
2016-07-22 00:54:34 +03:00
|
|
|
|
2017-01-17 00:56:51 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool {
|
|
|
|
let condition = unsafe { cond.as_ref().unwrap().as_str_unchecked() };
|
|
|
|
let mut input = Parser::new(&condition);
|
|
|
|
let cond = parse_condition_or_declaration(&mut input);
|
|
|
|
if let Ok(cond) = cond {
|
2017-04-03 15:05:42 +03:00
|
|
|
let url_data = unsafe { dummy_url_data() };
|
2017-04-24 13:05:51 +03:00
|
|
|
let reporter = RustLogReporter;
|
2017-04-14 12:49:29 +03:00
|
|
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Style),
|
2017-05-14 02:53:07 +03:00
|
|
|
PARSING_MODE_DEFAULT,
|
2017-04-28 06:32:24 +03:00
|
|
|
QuirksMode::NoQuirks);
|
2017-01-17 00:56:51 +03:00
|
|
|
cond.eval(&context)
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-25 20:00:44 +03:00
|
|
|
/// Only safe to call on the main thread, with exclusive access to the element and
|
|
|
|
/// its ancestors.
|
2017-03-27 07:13:44 +03:00
|
|
|
unsafe fn maybe_restyle<'a>(data: &'a mut AtomicRefMut<ElementData>,
|
|
|
|
element: GeckoElement,
|
|
|
|
animation_only: bool)
|
2016-11-25 20:00:44 +03:00
|
|
|
-> Option<&'a mut RestyleData>
|
|
|
|
{
|
2017-01-10 04:26:50 +03:00
|
|
|
// Don't generate a useless RestyleData if the element hasn't been styled.
|
|
|
|
if !data.has_styles() {
|
|
|
|
return None;
|
2016-11-25 20:00:44 +03:00
|
|
|
}
|
2017-01-10 04:26:50 +03:00
|
|
|
|
|
|
|
// Propagate the bit up the chain.
|
2017-05-10 23:08:59 +03:00
|
|
|
if let Some(p) = element.parent_element() {
|
|
|
|
if animation_only {
|
|
|
|
p.note_descendants::<AnimationOnlyDirtyDescendants>();
|
|
|
|
} else {
|
|
|
|
p.note_descendants::<DirtyDescendants>();
|
|
|
|
}
|
2017-03-29 14:52:07 +03:00
|
|
|
};
|
|
|
|
|
2017-02-10 06:27:33 +03:00
|
|
|
bindings::Gecko_SetOwnerDocumentNeedsStyleFlush(element.0);
|
2017-01-10 04:26:50 +03:00
|
|
|
|
|
|
|
// Ensure and return the RestyleData.
|
|
|
|
Some(data.ensure_restyle())
|
2016-11-25 20:00:44 +03:00
|
|
|
}
|
|
|
|
|
2017-04-10 12:04:54 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_Element_GetStyleRuleList(element: RawGeckoElementBorrowed,
|
|
|
|
rules: RawGeckoServoStyleRuleListBorrowedMut) {
|
|
|
|
let element = GeckoElement(element);
|
|
|
|
let data = match element.borrow_data() {
|
|
|
|
Some(element_data) => element_data,
|
|
|
|
None => return,
|
|
|
|
};
|
|
|
|
let computed = match data.get_styles() {
|
|
|
|
Some(styles) => &styles.primary,
|
|
|
|
None => return,
|
|
|
|
};
|
|
|
|
let mut result = vec![];
|
|
|
|
for rule_node in computed.rules.self_and_ancestors() {
|
|
|
|
if let Some(&StyleSource::Style(ref rule)) = rule_node.style_source() {
|
|
|
|
result.push(Locked::<StyleRule>::arc_as_borrowed(&rule));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsafe { rules.set_len(result.len() as u32) };
|
|
|
|
for (&src, dest) in result.into_iter().zip(rules.iter_mut()) {
|
|
|
|
*dest = src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-25 20:00:44 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed,
|
|
|
|
restyle_hint: nsRestyleHint,
|
|
|
|
change_hint: nsChangeHint) {
|
|
|
|
let element = GeckoElement(element);
|
|
|
|
let damage = GeckoRestyleDamage::new(change_hint);
|
|
|
|
debug!("Servo_NoteExplicitHints: {:?}, restyle_hint={:?}, change_hint={:?}",
|
|
|
|
element, restyle_hint, change_hint);
|
2017-04-27 08:48:21 +03:00
|
|
|
|
|
|
|
let restyle_hint: RestyleHint = restyle_hint.into();
|
2017-05-20 21:44:31 +03:00
|
|
|
debug_assert!(!(restyle_hint.has_animation_hint() &&
|
|
|
|
restyle_hint.has_non_animation_hint()),
|
2017-04-27 08:48:21 +03:00
|
|
|
"Animation restyle hints should not appear with non-animation restyle hints");
|
2016-11-25 20:00:44 +03:00
|
|
|
|
2017-01-13 06:23:17 +03:00
|
|
|
let mut maybe_data = element.mutate_data();
|
2017-03-27 07:13:44 +03:00
|
|
|
let maybe_restyle_data = maybe_data.as_mut().and_then(|d| unsafe {
|
2017-05-20 21:44:31 +03:00
|
|
|
maybe_restyle(d, element, restyle_hint.has_animation_hint())
|
2017-03-27 07:13:44 +03:00
|
|
|
});
|
2017-01-13 06:23:17 +03:00
|
|
|
if let Some(restyle_data) = maybe_restyle_data {
|
2017-05-20 21:44:31 +03:00
|
|
|
restyle_data.hint.insert(restyle_hint.into());
|
2016-11-25 20:00:44 +03:00
|
|
|
restyle_data.damage |= damage;
|
|
|
|
} else {
|
|
|
|
debug!("(Element not styled, discarding hints)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-31 06:12:55 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_ImportRule_GetSheet(import_rule:
|
|
|
|
RawServoImportRuleBorrowed)
|
|
|
|
-> RawServoStyleSheetStrong {
|
2017-03-22 14:17:09 +03:00
|
|
|
read_locked_arc(import_rule, |rule: &ImportRule| {
|
|
|
|
rule.stylesheet.clone().into_strong()
|
|
|
|
})
|
2016-12-31 06:12:55 +03:00
|
|
|
}
|
|
|
|
|
2016-11-25 20:00:44 +03:00
|
|
|
#[no_mangle]
|
2017-01-10 04:26:50 +03:00
|
|
|
pub extern "C" fn Servo_TakeChangeHint(element: RawGeckoElementBorrowed) -> nsChangeHint
|
2016-11-25 20:00:44 +03:00
|
|
|
{
|
|
|
|
let element = GeckoElement(element);
|
2017-01-10 04:26:50 +03:00
|
|
|
let damage = if let Some(mut data) = element.mutate_data() {
|
|
|
|
let d = data.get_restyle().map_or(GeckoRestyleDamage::empty(), |r| r.damage);
|
|
|
|
data.clear_restyle();
|
|
|
|
d
|
|
|
|
} else {
|
2017-02-15 14:05:07 +03:00
|
|
|
warn!("Trying to get change hint from unstyled element");
|
2017-01-10 04:26:50 +03:00
|
|
|
GeckoRestyleDamage::empty()
|
|
|
|
};
|
2016-11-25 20:00:44 +03:00
|
|
|
|
2017-01-10 04:26:50 +03:00
|
|
|
debug!("Servo_TakeChangeHint: {:?}, damage={:?}", element, damage);
|
2016-11-25 20:00:44 +03:00
|
|
|
damage.as_change_hint()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
|
2017-03-29 07:39:06 +03:00
|
|
|
raw_data: RawServoStyleSetBorrowed,
|
|
|
|
allow_stale: bool)
|
2016-12-28 06:55:01 +03:00
|
|
|
-> ServoComputedValuesStrong
|
2016-11-25 20:00:44 +03:00
|
|
|
{
|
|
|
|
let element = GeckoElement(element);
|
2017-01-10 04:26:50 +03:00
|
|
|
debug!("Servo_ResolveStyle: {:?}", element);
|
2017-05-10 23:08:59 +03:00
|
|
|
let data = unsafe { element.ensure_data() }.borrow();
|
2016-12-10 04:01:05 +03:00
|
|
|
|
2017-03-29 07:39:06 +03:00
|
|
|
let valid_styles = if allow_stale {
|
2017-05-10 23:08:59 +03:00
|
|
|
data.has_styles()
|
2017-03-29 07:39:06 +03:00
|
|
|
} else {
|
2017-05-10 23:08:59 +03:00
|
|
|
element.has_current_styles(&*data)
|
2017-03-29 07:39:06 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
if !valid_styles {
|
2017-04-12 05:05:32 +03:00
|
|
|
debug_assert!(false, "Resolving style on element without current styles with lazy \
|
|
|
|
computation forbidden.");
|
2017-01-10 04:26:50 +03:00
|
|
|
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
2017-01-18 16:39:57 +03:00
|
|
|
return per_doc_data.default_computed_values().clone().into_strong();
|
2016-12-10 04:01:05 +03:00
|
|
|
}
|
|
|
|
|
2017-02-10 21:34:57 +03:00
|
|
|
data.styles().primary.values().clone().into_strong()
|
2016-11-25 20:00:44 +03:00
|
|
|
}
|
2016-07-22 00:54:34 +03:00
|
|
|
|
2016-12-28 06:55:01 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
|
2017-05-16 04:46:42 +03:00
|
|
|
pseudo_type: CSSPseudoElementType,
|
2017-05-10 23:08:59 +03:00
|
|
|
snapshots: *const ServoElementSnapshotTable,
|
2016-12-28 06:55:01 +03:00
|
|
|
raw_data: RawServoStyleSetBorrowed)
|
|
|
|
-> ServoComputedValuesStrong
|
|
|
|
{
|
2017-05-10 23:08:59 +03:00
|
|
|
debug_assert!(!snapshots.is_null());
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
2016-12-28 06:55:01 +03:00
|
|
|
let element = GeckoElement(element);
|
|
|
|
let doc_data = PerDocumentStyleData::from_ffi(raw_data);
|
|
|
|
let finish = |styles: &ElementStyles| -> Arc<ComputedValues> {
|
2017-05-16 04:46:42 +03:00
|
|
|
PseudoElement::from_pseudo_type(pseudo_type).and_then(|ref pseudo| {
|
|
|
|
get_pseudo_style(&guard, element, pseudo, styles, doc_data)
|
|
|
|
}).unwrap_or_else(|| styles.primary.values().clone())
|
2016-12-28 06:55:01 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
// In the common case we already have the style. Check that before setting
|
|
|
|
// up all the computation machinery.
|
|
|
|
let mut result = element.mutate_data()
|
|
|
|
.and_then(|d| d.get_styles().map(&finish));
|
|
|
|
if result.is_some() {
|
|
|
|
return result.unwrap().into_strong();
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't have the style ready. Go ahead and compute it as necessary.
|
2017-05-12 16:56:47 +03:00
|
|
|
let data = doc_data.borrow();
|
2017-04-12 10:27:02 +03:00
|
|
|
let shared = create_shared_context(&global_style_data,
|
|
|
|
&guard,
|
2017-05-12 16:56:47 +03:00
|
|
|
&data,
|
2017-05-10 23:08:59 +03:00
|
|
|
TraversalFlags::empty(),
|
|
|
|
unsafe { &*snapshots });
|
2016-12-28 06:55:01 +03:00
|
|
|
let mut tlc = ThreadLocalStyleContext::new(&shared);
|
|
|
|
let mut context = StyleContext {
|
|
|
|
shared: &shared,
|
|
|
|
thread_local: &mut tlc,
|
|
|
|
};
|
|
|
|
let ensure = |el: GeckoElement| { unsafe { el.ensure_data(); } };
|
|
|
|
let clear = |el: GeckoElement| el.clear_data();
|
|
|
|
resolve_style(&mut context, element, &ensure, &clear,
|
|
|
|
|styles| result = Some(finish(styles)));
|
|
|
|
|
|
|
|
result.unwrap().into_strong()
|
|
|
|
}
|
|
|
|
|
2017-02-24 15:09:33 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeListBorrowed,
|
|
|
|
style: ServoComputedValuesBorrowed,
|
|
|
|
parent_style: ServoComputedValuesBorrowedOrNull,
|
2017-03-11 15:40:31 +03:00
|
|
|
raw_data: RawServoStyleSetBorrowed,
|
2017-02-24 15:09:33 +03:00
|
|
|
computed_keyframes: RawGeckoComputedKeyframeValuesListBorrowedMut)
|
|
|
|
{
|
2017-03-31 13:20:26 +03:00
|
|
|
use std::mem;
|
2017-02-27 01:09:44 +03:00
|
|
|
use style::properties::LonghandIdSet;
|
2017-02-24 15:09:33 +03:00
|
|
|
use style::properties::declaration_block::Importance;
|
|
|
|
use style::values::computed::Context;
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
|
|
|
|
|
2017-03-11 15:40:31 +03:00
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
2017-02-24 15:09:33 +03:00
|
|
|
|
|
|
|
let style = ComputedValues::as_arc(&style);
|
|
|
|
let parent_style = parent_style.as_ref().map(|r| &**ComputedValues::as_arc(&r));
|
2017-03-11 15:40:31 +03:00
|
|
|
|
2017-03-14 02:50:26 +03:00
|
|
|
let default_values = data.default_computed_values();
|
2017-04-09 14:15:51 +03:00
|
|
|
let metrics = get_metrics_provider_for_product();
|
2017-02-24 15:09:33 +03:00
|
|
|
|
2017-04-22 01:03:28 +03:00
|
|
|
let mut context = Context {
|
2017-02-24 15:09:33 +03:00
|
|
|
is_root_element: false,
|
2017-05-23 04:12:46 +03:00
|
|
|
device: data.stylist.device(),
|
2017-03-11 15:40:31 +03:00
|
|
|
inherited_style: parent_style.unwrap_or(default_values),
|
|
|
|
layout_parent_style: parent_style.unwrap_or(default_values),
|
2017-05-01 02:31:41 +03:00
|
|
|
style: StyleBuilder::for_derived_style(&style),
|
2017-04-09 14:15:51 +03:00
|
|
|
font_metrics_provider: &metrics,
|
2017-05-01 02:31:41 +03:00
|
|
|
cached_system_font: None,
|
2017-04-10 09:35:18 +03:00
|
|
|
in_media_query: false,
|
2017-05-14 04:50:10 +03:00
|
|
|
quirks_mode: data.stylist.quirks_mode(),
|
2017-02-24 15:09:33 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
for (index, keyframe) in keyframes.iter().enumerate() {
|
|
|
|
let ref mut animation_values = computed_keyframes[index];
|
|
|
|
|
2017-02-27 01:09:44 +03:00
|
|
|
let mut seen = LonghandIdSet::new();
|
2017-02-24 15:09:33 +03:00
|
|
|
|
|
|
|
// mServoDeclarationBlock is null in the case where we have an invalid css property.
|
|
|
|
let iter = keyframe.mPropertyValues.iter()
|
|
|
|
.filter(|&property| !property.mServoDeclarationBlock.mRawPtr.is_null());
|
2017-05-02 14:03:40 +03:00
|
|
|
let mut property_index = 0;
|
2017-02-24 15:09:33 +03:00
|
|
|
for property in iter {
|
|
|
|
let declarations = unsafe { &*property.mServoDeclarationBlock.mRawPtr.clone() };
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
|
|
|
let guard = declarations.read_with(&guard);
|
2017-02-24 15:09:33 +03:00
|
|
|
|
2017-03-08 14:07:04 +03:00
|
|
|
let anim_iter = guard.declarations()
|
2017-02-24 15:09:33 +03:00
|
|
|
.iter()
|
|
|
|
.filter_map(|&(ref decl, imp)| {
|
|
|
|
if imp == Importance::Normal {
|
|
|
|
let property = TransitionProperty::from_declaration(decl);
|
2017-04-22 01:03:28 +03:00
|
|
|
let animation = AnimationValue::from_declaration(decl, &mut context,
|
|
|
|
default_values);
|
2017-02-24 15:09:33 +03:00
|
|
|
debug_assert!(property.is_none() == animation.is_none(),
|
|
|
|
"The failure condition of TransitionProperty::from_declaration \
|
|
|
|
and AnimationValue::from_declaration should be the same");
|
|
|
|
// Skip the property if either ::from_declaration fails.
|
|
|
|
if property.is_none() || animation.is_none() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some((property.unwrap(), animation.unwrap()))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-05-02 14:03:40 +03:00
|
|
|
for anim in anim_iter {
|
2017-02-24 15:09:33 +03:00
|
|
|
if !seen.has_transition_property_bit(&anim.0) {
|
|
|
|
// This is safe since we immediately write to the uninitialized values.
|
2017-05-02 14:03:40 +03:00
|
|
|
unsafe { animation_values.set_len((property_index + 1) as u32) };
|
2017-02-24 15:09:33 +03:00
|
|
|
seen.set_transition_property_bit(&anim.0);
|
2017-05-02 14:03:40 +03:00
|
|
|
animation_values[property_index].mProperty = (&anim.0).into();
|
2017-03-31 13:20:26 +03:00
|
|
|
// We only make sure we have enough space for this variable,
|
|
|
|
// but didn't construct a default value for StyleAnimationValue,
|
|
|
|
// so we should zero it to avoid getting undefined behaviors.
|
2017-05-02 14:03:40 +03:00
|
|
|
animation_values[property_index].mValue.mGecko = unsafe { mem::zeroed() };
|
|
|
|
animation_values[property_index].mValue.mServo.set_arc_leaky(Arc::new(anim.1));
|
|
|
|
property_index += 1;
|
2017-02-24 15:09:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-03 07:46:15 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AnimationValue_Compute(declarations: RawServoDeclarationBlockBorrowed,
|
|
|
|
style: ServoComputedValuesBorrowed,
|
|
|
|
parent_style: ServoComputedValuesBorrowedOrNull,
|
|
|
|
raw_data: RawServoStyleSetBorrowed)
|
|
|
|
-> RawServoAnimationValueStrong {
|
|
|
|
use style::values::computed::Context;
|
|
|
|
|
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
let style = ComputedValues::as_arc(&style);
|
|
|
|
let parent_style = parent_style.as_ref().map(|r| &**ComputedValues::as_arc(&r));
|
|
|
|
let default_values = data.default_computed_values();
|
|
|
|
let metrics = get_metrics_provider_for_product();
|
|
|
|
let mut context = Context {
|
|
|
|
is_root_element: false,
|
2017-05-23 04:12:46 +03:00
|
|
|
device: data.stylist.device(),
|
2017-05-03 07:46:15 +03:00
|
|
|
inherited_style: parent_style.unwrap_or(default_values),
|
|
|
|
layout_parent_style: parent_style.unwrap_or(default_values),
|
|
|
|
style: StyleBuilder::for_derived_style(&style),
|
|
|
|
font_metrics_provider: &metrics,
|
|
|
|
cached_system_font: None,
|
|
|
|
in_media_query: false,
|
2017-05-17 14:53:57 +03:00
|
|
|
quirks_mode: data.stylist.quirks_mode(),
|
2017-05-03 07:46:15 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
|
|
|
// We only compute the first element in declarations.
|
|
|
|
match declarations.read_with(&guard).declarations().first() {
|
|
|
|
Some(&(ref decl, imp)) if imp == Importance::Normal => {
|
|
|
|
let animation = AnimationValue::from_declaration(decl, &mut context, default_values);
|
|
|
|
animation.map_or(RawServoAnimationValueStrong::null(), |value| {
|
|
|
|
Arc::new(value).into_strong()
|
|
|
|
})
|
|
|
|
},
|
|
|
|
_ => RawServoAnimationValueStrong::null()
|
|
|
|
}
|
|
|
|
}
|
2016-12-28 06:55:01 +03:00
|
|
|
|
2016-11-25 20:00:44 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed) {
|
2017-04-23 02:40:47 +03:00
|
|
|
if !cfg!(feature = "gecko_debug") {
|
2016-11-25 20:00:44 +03:00
|
|
|
panic!("Calling Servo_AssertTreeIsClean in release build");
|
|
|
|
}
|
|
|
|
|
|
|
|
let root = GeckoElement(root);
|
|
|
|
fn assert_subtree_is_clean<'le>(el: GeckoElement<'le>) {
|
2017-03-27 07:13:44 +03:00
|
|
|
debug_assert!(!el.has_dirty_descendants() && !el.has_animation_only_dirty_descendants());
|
2016-11-25 20:00:44 +03:00
|
|
|
for child in el.as_node().children() {
|
|
|
|
if let Some(child) = child.as_element() {
|
|
|
|
assert_subtree_is_clean(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-22 00:54:34 +03:00
|
|
|
|
2016-11-25 20:00:44 +03:00
|
|
|
assert_subtree_is_clean(root);
|
2016-07-22 00:54:34 +03:00
|
|
|
}
|
2017-01-29 08:24:04 +03:00
|
|
|
|
2017-05-13 22:05:40 +03:00
|
|
|
fn append_computed_property_value(keyframe: *mut structs::Keyframe,
|
|
|
|
style: &ComputedValues,
|
|
|
|
property: &TransitionProperty,
|
|
|
|
shared_lock: &SharedRwLock) {
|
|
|
|
let block = style.to_declaration_block(property.clone().into());
|
|
|
|
unsafe {
|
|
|
|
let index = (*keyframe).mPropertyValues.len();
|
|
|
|
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
|
|
|
(*keyframe).mPropertyValues[index].mProperty = property.into();
|
|
|
|
// FIXME. Bug 1360398: Do not set computed values once we handles
|
|
|
|
// missing keyframes with additive composition.
|
|
|
|
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
|
|
|
Arc::new(shared_lock.wrap(block)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-24 12:26:19 +03:00
|
|
|
enum Offset {
|
|
|
|
Zero,
|
|
|
|
One
|
|
|
|
}
|
|
|
|
|
2017-05-13 22:05:40 +03:00
|
|
|
fn fill_in_missing_keyframe_values(all_properties: &[TransitionProperty],
|
|
|
|
timing_function: nsTimingFunctionBorrowed,
|
|
|
|
style: &ComputedValues,
|
|
|
|
properties_set_at_offset: &LonghandIdSet,
|
2017-05-24 12:26:19 +03:00
|
|
|
offset: Offset,
|
2017-05-13 22:05:40 +03:00
|
|
|
keyframes: RawGeckoKeyframeListBorrowedMut,
|
|
|
|
shared_lock: &SharedRwLock) {
|
|
|
|
let needs_filling = all_properties.iter().any(|ref property| {
|
|
|
|
!properties_set_at_offset.has_transition_property_bit(property)
|
|
|
|
});
|
|
|
|
|
|
|
|
// Return earli if all animated properties are already set.
|
|
|
|
if !needs_filling {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let keyframe = match offset {
|
2017-05-24 12:26:19 +03:00
|
|
|
Offset::Zero => unsafe {
|
2017-05-13 22:05:40 +03:00
|
|
|
Gecko_GetOrCreateInitialKeyframe(keyframes, timing_function)
|
|
|
|
},
|
2017-05-24 12:26:19 +03:00
|
|
|
Offset::One => unsafe {
|
2017-05-13 22:05:40 +03:00
|
|
|
Gecko_GetOrCreateFinalKeyframe(keyframes, timing_function)
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// Append properties that have not been set at this offset.
|
|
|
|
for ref property in all_properties.iter() {
|
|
|
|
if !properties_set_at_offset.has_transition_property_bit(property) {
|
|
|
|
append_computed_property_value(keyframe,
|
|
|
|
style,
|
|
|
|
property,
|
|
|
|
shared_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_GetKeyframesForName(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
name: *const nsACString,
|
|
|
|
inherited_timing_function: nsTimingFunctionBorrowed,
|
|
|
|
style: ServoComputedValuesBorrowed,
|
|
|
|
keyframes: RawGeckoKeyframeListBorrowedMut) -> bool {
|
|
|
|
debug_assert!(keyframes.len() == 0,
|
|
|
|
"keyframes should be initially empty");
|
servo: Merge #16014 - Per-process lock for CSSOM objects (from servo:style-ref); r=emilio
<!-- Please describe your changes on the following line: -->
Before this PR, every object reflected in CSSOM is in `Arc<RwLock<_>>` to enable safe (synchronized) mutable aliasing. Acquiring all these locks has significant cost during selector matching:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1311469
* https://bugzilla.mozilla.org/show_bug.cgi?id=1335941
* https://bugzilla.mozilla.org/show_bug.cgi?id=1339703
This PR introduce a mechanism to protect many objects with the same `RwLock` that only needs to be acquired once.
In Stylo, there is one such lock per process (in a `lazy_static`), used for everything.
I non-Stylo Servo, I originally intended to have one such lock per document (for author-origin stylesheets, and one per process for user-agent and user sytlesheets since they’re shared across documents, and never mutated anyway). However I failed to have the same document-specific (or pipeline-specific) `Arc` reachable from both `Document` nodes and `LayoutThread`. Recursively following callers lead me to include this `Arc` in `UnprivilegedPipelineContent`, but that needs to be serializable. So there is a second process-wide lock.
This was previously #15998, closed accidentally.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- 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: bb54f0a429de0e8b8861f8071b6cf82f73622664
--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 851230e57ac8775707df5f0f103be5feac81fc41
2017-03-20 00:31:19 +03:00
|
|
|
|
2017-03-10 07:23:21 +03:00
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
2017-01-29 08:24:04 +03:00
|
|
|
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
|
2017-05-13 22:05:40 +03:00
|
|
|
|
|
|
|
let animation = match data.stylist.animations().get(&name) {
|
|
|
|
Some(animation) => animation,
|
|
|
|
None => return false,
|
|
|
|
};
|
|
|
|
|
2017-01-29 08:24:04 +03:00
|
|
|
let style = ComputedValues::as_arc(&style);
|
2017-05-13 22:05:40 +03:00
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
2017-01-29 08:24:04 +03:00
|
|
|
|
2017-05-13 22:05:40 +03:00
|
|
|
let mut properties_set_at_current_offset = LonghandIdSet::new();
|
|
|
|
let mut properties_set_at_start = LonghandIdSet::new();
|
|
|
|
let mut properties_set_at_end = LonghandIdSet::new();
|
|
|
|
let mut has_complete_initial_keyframe = false;
|
|
|
|
let mut has_complete_final_keyframe = false;
|
|
|
|
let mut current_offset = -1.;
|
|
|
|
|
|
|
|
// Iterate over the keyframe rules backwards so we can drop overridden
|
|
|
|
// properties (since declarations in later rules override those in earlier
|
|
|
|
// ones).
|
|
|
|
for step in animation.steps.iter().rev() {
|
|
|
|
if step.start_percentage.0 != current_offset {
|
|
|
|
properties_set_at_current_offset.clear();
|
|
|
|
current_offset = step.start_percentage.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override timing_function if the keyframe has an animation-timing-function.
|
|
|
|
let timing_function = match step.get_animation_timing_function(&guard) {
|
|
|
|
Some(val) => val.into(),
|
|
|
|
None => *inherited_timing_function,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Look for an existing keyframe with the same offset and timing
|
|
|
|
// function or else add a new keyframe at the beginning of the keyframe
|
|
|
|
// array.
|
|
|
|
let keyframe = unsafe {
|
|
|
|
Gecko_GetOrCreateKeyframeAtStart(keyframes,
|
|
|
|
step.start_percentage.0 as f32,
|
|
|
|
&timing_function)
|
|
|
|
};
|
|
|
|
|
|
|
|
match step.value {
|
|
|
|
KeyframesStepValue::ComputedValues => {
|
|
|
|
// In KeyframesAnimation::from_keyframes if there is no 0% or
|
|
|
|
// 100% keyframe at all, we will create a 'ComputedValues' step
|
|
|
|
// to represent that all properties animated by the keyframes
|
|
|
|
// animation should be set to the underlying computed value for
|
|
|
|
// that keyframe.
|
|
|
|
for property in animation.properties_changed.iter() {
|
|
|
|
append_computed_property_value(keyframe,
|
|
|
|
style,
|
|
|
|
property,
|
|
|
|
&global_style_data.shared_lock);
|
2017-04-19 11:06:31 +03:00
|
|
|
}
|
2017-05-13 22:05:40 +03:00
|
|
|
if current_offset == 0.0 {
|
|
|
|
has_complete_initial_keyframe = true;
|
|
|
|
} else if current_offset == 1.0 {
|
|
|
|
has_complete_final_keyframe = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
KeyframesStepValue::Declarations { ref block } => {
|
|
|
|
let guard = block.read_with(&guard);
|
|
|
|
// Filter out non-animatable properties.
|
|
|
|
let animatable =
|
|
|
|
guard.declarations()
|
|
|
|
.iter()
|
|
|
|
.filter(|&&(ref declaration, _)| {
|
|
|
|
declaration.is_animatable()
|
|
|
|
});
|
|
|
|
|
|
|
|
let mut index = unsafe { (*keyframe).mPropertyValues.len() };
|
|
|
|
for &(ref declaration, _) in animatable {
|
|
|
|
let property = TransitionProperty::from_declaration(declaration).unwrap();
|
|
|
|
if !properties_set_at_current_offset.has_transition_property_bit(&property) {
|
|
|
|
properties_set_at_current_offset.set_transition_property_bit(&property);
|
|
|
|
if current_offset == 0.0 {
|
|
|
|
properties_set_at_start.set_transition_property_bit(&property);
|
|
|
|
} else if current_offset == 1.0 {
|
|
|
|
properties_set_at_end.set_transition_property_bit(&property);
|
|
|
|
}
|
2017-04-19 11:06:31 +03:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let property = TransitionProperty::from_declaration(declaration).unwrap();
|
|
|
|
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
2017-04-26 17:33:08 +03:00
|
|
|
(*keyframe).mPropertyValues[index].mProperty = (&property).into();
|
2017-04-19 11:06:31 +03:00
|
|
|
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
|
|
|
Arc::new(global_style_data.shared_lock.wrap(
|
|
|
|
PropertyDeclarationBlock::with_one(
|
|
|
|
declaration.clone(), Importance::Normal
|
|
|
|
))));
|
|
|
|
}
|
2017-05-13 22:05:40 +03:00
|
|
|
index += 1;
|
2017-04-19 11:06:31 +03:00
|
|
|
}
|
2017-05-13 22:05:40 +03:00
|
|
|
}
|
|
|
|
},
|
2017-04-19 11:06:31 +03:00
|
|
|
}
|
2017-01-29 08:24:04 +03:00
|
|
|
}
|
2017-05-13 22:05:40 +03:00
|
|
|
|
|
|
|
// Append property values that are missing in the initial or the final keyframes.
|
|
|
|
if !has_complete_initial_keyframe {
|
|
|
|
fill_in_missing_keyframe_values(&animation.properties_changed,
|
|
|
|
inherited_timing_function,
|
|
|
|
style,
|
|
|
|
&properties_set_at_start,
|
2017-05-24 12:26:19 +03:00
|
|
|
Offset::Zero,
|
2017-05-13 22:05:40 +03:00
|
|
|
keyframes,
|
|
|
|
&global_style_data.shared_lock);
|
|
|
|
}
|
|
|
|
if !has_complete_final_keyframe {
|
|
|
|
fill_in_missing_keyframe_values(&animation.properties_changed,
|
|
|
|
inherited_timing_function,
|
|
|
|
style,
|
|
|
|
&properties_set_at_end,
|
2017-05-24 12:26:19 +03:00
|
|
|
Offset::One,
|
2017-05-13 22:05:40 +03:00
|
|
|
keyframes,
|
|
|
|
&global_style_data.shared_lock);
|
|
|
|
}
|
|
|
|
true
|
2017-01-29 08:24:04 +03:00
|
|
|
}
|
|
|
|
|
2017-03-30 04:50:47 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_GetFontFaceRules(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
rules: RawGeckoFontFaceRuleListBorrowedMut) {
|
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
debug_assert!(rules.len() == 0);
|
|
|
|
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
|
|
|
|
unsafe { rules.set_len(data.font_faces.len() as u32) };
|
|
|
|
for (src, dest) in data.font_faces.iter().zip(rules.iter_mut()) {
|
|
|
|
dest.mRule = src.0.read_with(&guard).clone().forget();
|
|
|
|
dest.mSheetType = src.1.into();
|
|
|
|
}
|
|
|
|
}
|
2017-04-15 14:20:52 +03:00
|
|
|
|
2017-05-16 09:17:07 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_GetCounterStyleRule(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
name: *mut nsIAtom) -> *mut nsCSSCounterStyleRule {
|
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
unsafe {
|
|
|
|
Atom::with(name, |name| data.counter_styles.get(name))
|
|
|
|
}.map(|rule| {
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
rule.read_with(&guard).get()
|
|
|
|
}).unwrap_or(ptr::null_mut())
|
|
|
|
}
|
|
|
|
|
2017-04-15 14:20:52 +03:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
|
|
|
declarations: RawServoDeclarationBlockBorrowed)
|
|
|
|
-> ServoComputedValuesStrong
|
|
|
|
{
|
|
|
|
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
|
|
|
let guard = global_style_data.shared_lock.read();
|
|
|
|
let guards = StylesheetGuards::same(&guard);
|
|
|
|
|
|
|
|
let parent_style = match ComputedValues::arc_from_borrowed(&parent_style_or_null) {
|
|
|
|
Some(parent) => &parent,
|
|
|
|
None => doc_data.default_computed_values(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
|
|
|
|
|
|
|
doc_data.stylist.compute_for_declarations(&guards,
|
|
|
|
parent_style,
|
|
|
|
declarations.clone()).into_strong()
|
|
|
|
}
|
2017-05-12 13:41:35 +03:00
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_MightHaveAttributeDependency(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
local_name: *mut nsIAtom) -> bool {
|
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
2017-05-16 09:17:07 +03:00
|
|
|
unsafe { Atom::with(local_name, |atom| data.stylist.might_have_attribute_dependency(atom)) }
|
2017-05-12 13:41:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn Servo_StyleSet_HasStateDependency(raw_data: RawServoStyleSetBorrowed,
|
|
|
|
state: u64) -> bool {
|
|
|
|
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
|
|
|
data.stylist.has_state_dependency(ElementState::from_bits_truncate(state))
|
|
|
|
}
|