summaryrefslogtreecommitdiffstats
path: root/servo/ports
diff options
context:
space:
mode:
Diffstat (limited to 'servo/ports')
-rw-r--r--servo/ports/geckolib/Cargo.toml2
-rw-r--r--servo/ports/geckolib/cbindgen.toml2
-rw-r--r--servo/ports/geckolib/glue.rs490
3 files changed, 338 insertions, 156 deletions
diff --git a/servo/ports/geckolib/Cargo.toml b/servo/ports/geckolib/Cargo.toml
index 1bdaaa80b7..37a44c2e61 100644
--- a/servo/ports/geckolib/Cargo.toml
+++ b/servo/ports/geckolib/Cargo.toml
@@ -15,7 +15,7 @@ gecko_refcount_logging = ["style/gecko_refcount_logging", "servo_arc/gecko_refco
[dependencies]
atomic_refcell = "0.1"
bincode = "1.0"
-cssparser = "0.33"
+cssparser = "0.34"
cstr = "0.2"
dom = { path = "../../../dom/base/rust" }
gecko-profiler = { path = "../../../tools/profiler/rust-api" }
diff --git a/servo/ports/geckolib/cbindgen.toml b/servo/ports/geckolib/cbindgen.toml
index 3edab4dfbb..d608840cae 100644
--- a/servo/ports/geckolib/cbindgen.toml
+++ b/servo/ports/geckolib/cbindgen.toml
@@ -350,7 +350,7 @@ renaming_overrides_prefixing = true
"BeforeFlag" = "StyleEasingBeforeFlag"
"FontPaletteValueSet" = "gfx::FontPaletteValueSet"
"PaletteValues" = "gfx::FontPaletteValueSet::PaletteValues"
-"ThinVec" = "nsTArray"
+"ThinVec" = "CopyableTArray"
"RawPthread" = "pthread_t"
"RawHandle" = "void*"
diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs
index 14614704b7..6efa274b46 100644
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -6,7 +6,10 @@ use super::error_reporter::ErrorReporter;
use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader};
use bincode::{deserialize, serialize};
use cssparser::ToCss as ParserToCss;
-use cssparser::{BasicParseError, ParseError as CssParseError, Parser, ParserInput, SourceLocation, UnicodeRange, Token};
+use cssparser::{
+ BasicParseError, ParseError as CssParseError, Parser, ParserInput, ParserState, SourceLocation,
+ Token, UnicodeRange,
+};
use dom::{DocumentState, ElementState};
use malloc_size_of::MallocSizeOfOps;
use nsstring::{nsCString, nsString};
@@ -51,12 +54,8 @@ use style::gecko_bindings::bindings;
use style::gecko_bindings::bindings::nsACString;
use style::gecko_bindings::bindings::nsAString;
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
-use style::gecko_bindings::bindings::Gecko_AppendPropertyValuePair;
use style::gecko_bindings::bindings::Gecko_ConstructFontFeatureValueSet;
use style::gecko_bindings::bindings::Gecko_ConstructFontPaletteValueSet;
-use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
-use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
-use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
use style::gecko_bindings::bindings::Gecko_HaveSeenPtr;
use style::gecko_bindings::structs;
use style::gecko_bindings::structs::gfx::FontPaletteValueSet;
@@ -69,7 +68,6 @@ use style::gecko_bindings::structs::nsCSSPropertyID;
use style::gecko_bindings::structs::nsChangeHint;
use style::gecko_bindings::structs::nsCompatibility;
use style::gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator;
-use style::gecko_bindings::structs::nsTArray;
use style::gecko_bindings::structs::nsresult;
use style::gecko_bindings::structs::CallerType;
use style::gecko_bindings::structs::CompositeOperation;
@@ -137,9 +135,9 @@ use style::stylesheets::{
AllowImportRules, ContainerRule, CounterStyleRule, CssRule, CssRuleType, CssRuleTypes,
CssRules, CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule,
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
- MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule, PropertyRule,
- SanitizationData, SanitizationKind, StartingStyleRule, StyleRule, StylesheetContents,
- StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData, ScopeRule,
+ MarginRule, MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule,
+ PropertyRule, SanitizationData, SanitizationKind, ScopeRule, StartingStyleRule, StyleRule,
+ StylesheetContents, StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData,
};
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
use style::thread_state;
@@ -162,7 +160,7 @@ use style::values::specified::source_size_list::SourceSizeList;
use style::values::specified::{AbsoluteLength, NoCalcLength};
use style::values::{specified, AtomIdent, CustomIdent, KeyframesName};
use style_traits::{CssWriter, ParseError, ParsingMode, ToCss};
-use thin_vec::ThinVec;
+use thin_vec::ThinVec as nsTArray;
use to_shmem::SharedMemoryBuilder;
trait ClosureHelper {
@@ -1263,9 +1261,9 @@ pub extern "C" fn Servo_ComputedValues_ShouldTransition(
let Some(old_value) = AnimationValue::from_computed_values(prop, old) else {
return Default::default();
};
- if old_value == new_value
- || (matches!(behavior, computed::TransitionBehavior::Normal)
- && !old_value.interpolable_with(&new_value))
+ if old_value == new_value ||
+ (matches!(behavior, computed::TransitionBehavior::Normal) &&
+ !old_value.interpolable_with(&new_value))
{
return Default::default();
}
@@ -1414,7 +1412,6 @@ pub unsafe extern "C" fn Servo_Property_SupportsType(
prop_id.supports_type(ty)
}
-// TODO(emilio): We could use ThinVec instead of nsTArray.
#[no_mangle]
pub unsafe extern "C" fn Servo_Property_GetCSSValuesForProperty(
prop_name: &nsACString,
@@ -1426,18 +1423,14 @@ pub unsafe extern "C" fn Servo_Property_GetCSSValuesForProperty(
let mut values = BTreeSet::<&'static str>::new();
prop_id.collect_property_completion_keywords(&mut |list| values.extend(list.iter()));
- let mut extras = vec![];
if values.contains("transparent") {
// This is a special value devtools use to avoid inserting the
// long list of color keywords. We need to prepend it to values.
- extras.push("COLOR");
+ result.push("COLOR".into());
}
- let len = extras.len() + values.len();
- bindings::Gecko_ResizeTArrayForStrings(result, len as u32);
-
- for (src, dest) in extras.iter().chain(values.iter()).zip(result.iter_mut()) {
- dest.write_str(src).unwrap();
+ for value in values {
+ result.push(value.into());
}
}
@@ -1691,7 +1684,7 @@ pub unsafe extern "C" fn Servo_ShutdownThreadPool() {
#[no_mangle]
pub unsafe extern "C" fn Servo_ThreadPool_GetThreadHandles(
- handles: &mut ThinVec<PlatformThreadHandle>,
+ handles: &mut nsTArray<PlatformThreadHandle>,
) {
StyleThreadPool::get_thread_handles(handles);
}
@@ -2156,7 +2149,7 @@ where
#[no_mangle]
pub extern "C" fn Servo_CssRules_ListTypes(rules: &LockedCssRules, result: &mut nsTArray<usize>) {
read_locked_arc(rules, |rules: &CssRules| {
- result.assign_from_iter_pod(rules.0.iter().map(|rule| rule.rule_type() as usize));
+ result.extend(rules.0.iter().map(|rule| rule.rule_type() as usize));
})
}
@@ -2402,6 +2395,13 @@ impl_group_rule_funcs! { (Media, MediaRule, MediaRule),
changed: Servo_StyleSet_MediaRuleChanged,
}
+impl_basic_rule_funcs! { (Margin, MarginRule, MarginRule),
+ getter: Servo_CssRules_GetMarginRuleAt,
+ debug: Servo_MarginRule_Debug,
+ to_css: Servo_MarginRule_GetCssText,
+ changed: Servo_StyleSet_MarginRuleChanged,
+}
+
impl_basic_rule_funcs! { (Namespace, NamespaceRule, NamespaceRule),
getter: Servo_CssRules_GetNamespaceRuleAt,
debug: Servo_NamespaceRule_Debug,
@@ -2529,7 +2529,7 @@ pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: &LockedStyleRule, result
read_locked_arc(rule, |rule| rule.selectors.to_css(result).unwrap());
}
-fn desugared_selector_list(rules: &ThinVec<&LockedStyleRule>) -> SelectorList {
+fn desugared_selector_list(rules: &nsTArray<&LockedStyleRule>) -> SelectorList {
let mut selectors: Option<SelectorList> = None;
for rule in rules.iter().rev() {
selectors = Some(read_locked_arc(rule, |rule| match selectors {
@@ -2541,8 +2541,15 @@ fn desugared_selector_list(rules: &ThinVec<&LockedStyleRule>) -> SelectorList {
}
#[no_mangle]
+pub extern "C" fn Servo_StyleRule_GetSelectorList(
+ rules: &nsTArray<&LockedStyleRule>,
+) -> *mut SelectorList {
+ Box::into_raw(Box::new(desugared_selector_list(rules)))
+}
+
+#[no_mangle]
pub extern "C" fn Servo_StyleRule_GetSelectorDataAtIndex(
- rules: &ThinVec<&LockedStyleRule>,
+ rules: &nsTArray<&LockedStyleRule>,
index: u32,
text: Option<&mut nsACString>,
specificity: Option<&mut u64>,
@@ -2566,7 +2573,7 @@ pub extern "C" fn Servo_StyleRule_GetSelectorCount(rule: &LockedStyleRule) -> u3
#[no_mangle]
pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
- rules: &ThinVec<&LockedStyleRule>,
+ rules: &nsTArray<&LockedStyleRule>,
element: &RawGeckoElement,
index: u32,
host: Option<&RawGeckoElement>,
@@ -2574,7 +2581,8 @@ pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
relevant_link_visited: bool,
) -> bool {
use selectors::matching::{
- matches_selector, MatchingContext, MatchingMode, NeedsSelectorFlags, VisitedHandlingMode,
+ matches_selector, IncludeStartingStyle, MatchingContext, MatchingMode, NeedsSelectorFlags,
+ VisitedHandlingMode,
};
let selectors = desugared_selector_list(rules);
let Some(selector) = selectors.slice().get(index as usize) else {
@@ -2615,6 +2623,7 @@ pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
/* bloom_filter = */ None,
&mut selector_caches,
visited_mode,
+ IncludeStartingStyle::No,
quirks_mode,
NeedsSelectorFlags::No,
MatchingForInvalidation::No,
@@ -2939,6 +2948,16 @@ pub extern "C" fn Servo_NamespaceRule_GetURI(rule: &NamespaceRule) -> *mut nsAto
}
#[no_mangle]
+pub extern "C" fn Servo_MarginRule_GetStyle(rule: &MarginRule) -> Strong<LockedDeclarationBlock> {
+ rule.block.clone().into()
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_MarginRule_GetName(rule: &MarginRule, out: &mut nsACString) {
+ out.assign(rule.name());
+}
+
+#[no_mangle]
pub extern "C" fn Servo_PageRule_GetStyle(rule: &LockedPageRule) -> Strong<LockedDeclarationBlock> {
read_locked_arc(rule, |rule: &PageRule| rule.block.clone().into())
}
@@ -3383,69 +3402,47 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetUnicodeRanges(
#[no_mangle]
pub unsafe extern "C" fn Servo_FontFaceRule_GetSources(
rule: &LockedFontFaceRule,
- out: *mut nsTArray<FontFaceSourceListComponent>,
+ out: &mut nsTArray<FontFaceSourceListComponent>,
) {
- let out = &mut *out;
read_locked_arc_worker(rule, |rule: &FontFaceRule| {
let sources = match rule.sources {
Some(ref s) => s,
None => return,
};
- let len = sources.0.iter().fold(0, |acc, src| {
- acc + match *src {
- Source::Url(ref url) => {
- (if url.format_hint.is_some() { 2 } else { 1 }) +
- (if url.tech_flags.is_empty() { 0 } else { 1 })
- },
- Source::Local(_) => 1,
- }
- });
-
- out.set_len(len as u32);
-
- let mut iter = out.iter_mut();
- {
- let mut set_next = |component: FontFaceSourceListComponent| {
- *iter.next().expect("miscalculated length") = component;
- };
-
- for source in sources.0.iter() {
- match *source {
- Source::Url(ref url) => {
- set_next(FontFaceSourceListComponent::Url(&url.url));
- if let Some(hint) = &url.format_hint {
- match hint {
- FontFaceSourceFormat::Keyword(kw) => {
- set_next(FontFaceSourceListComponent::FormatHintKeyword(*kw))
- },
- FontFaceSourceFormat::String(s) => {
- set_next(FontFaceSourceListComponent::FormatHintString {
- length: s.len(),
- utf8_bytes: s.as_ptr(),
- })
- },
- }
- }
- if !url.tech_flags.is_empty() {
- set_next(FontFaceSourceListComponent::TechFlags(url.tech_flags));
+ for source in sources.0.iter() {
+ match *source {
+ Source::Url(ref url) => {
+ out.push(FontFaceSourceListComponent::Url(&url.url));
+ if let Some(hint) = &url.format_hint {
+ match hint {
+ FontFaceSourceFormat::Keyword(kw) => {
+ out.push(FontFaceSourceListComponent::FormatHintKeyword(*kw))
+ },
+ FontFaceSourceFormat::String(s) => {
+ out.push(FontFaceSourceListComponent::FormatHintString {
+ length: s.len(),
+ utf8_bytes: s.as_ptr(),
+ })
+ },
}
- },
- Source::Local(ref name) => {
- set_next(FontFaceSourceListComponent::Local(name.name.as_ptr()));
- },
- }
+ }
+ if !url.tech_flags.is_empty() {
+ out.push(FontFaceSourceListComponent::TechFlags(url.tech_flags));
+ }
+ },
+ Source::Local(ref name) => {
+ out.push(FontFaceSourceListComponent::Local(name.name.as_ptr()));
+ },
}
}
-
- assert!(iter.next().is_none(), "miscalculated");
})
}
#[no_mangle]
pub unsafe extern "C" fn Servo_FontFaceRule_GetVariationSettings(
rule: &LockedFontFaceRule,
- variations: *mut nsTArray<structs::gfxFontVariation>,
+ variations: &mut nsTArray<structs::gfxFontVariation>,
) {
read_locked_arc_worker(rule, |rule: &FontFaceRule| {
let source_variations = match rule.variation_settings {
@@ -3453,20 +3450,22 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetVariationSettings(
None => return,
};
- (*variations).set_len(source_variations.0.len() as u32);
- for (target, source) in (*variations).iter_mut().zip(source_variations.0.iter()) {
- *target = structs::gfxFontVariation {
- mTag: source.tag.0,
- mValue: source.value.get(),
- };
- }
+ variations.extend(
+ source_variations
+ .0
+ .iter()
+ .map(|source| structs::gfxFontVariation {
+ mTag: source.tag.0,
+ mValue: source.value.get(),
+ }),
+ );
});
}
#[no_mangle]
pub unsafe extern "C" fn Servo_FontFaceRule_GetFeatureSettings(
rule: &LockedFontFaceRule,
- features: *mut nsTArray<structs::gfxFontFeature>,
+ features: &mut nsTArray<structs::gfxFontFeature>,
) {
read_locked_arc_worker(rule, |rule: &FontFaceRule| {
let source_features = match rule.feature_settings {
@@ -3474,13 +3473,15 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetFeatureSettings(
None => return,
};
- (*features).set_len(source_features.0.len() as u32);
- for (target, source) in (*features).iter_mut().zip(source_features.0.iter()) {
- *target = structs::gfxFontFeature {
- mTag: source.tag.0,
- mValue: source.value.value() as u32,
- };
- }
+ features.extend(
+ source_features
+ .0
+ .iter()
+ .map(|source| structs::gfxFontFeature {
+ mTag: source.tag.0,
+ mValue: source.value.value() as u32,
+ }),
+ );
});
}
@@ -4343,7 +4344,7 @@ pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(
values: &ComputedValues,
- rules: &mut ThinVec<*const LockedStyleRule>,
+ rules: &mut nsTArray<*const LockedStyleRule>,
) {
let rule_node = match values.rules {
Some(ref r) => r,
@@ -5540,6 +5541,12 @@ pub extern "C" fn Servo_DeclarationBlock_SetLengthValue(
structs::nsCSSUnit::eCSSUnit_CapHeight => {
NoCalcLength::FontRelative(FontRelativeLength::Cap(value))
},
+ structs::nsCSSUnit::eCSSUnit_LineHeight => {
+ NoCalcLength::FontRelative(FontRelativeLength::Lh(value))
+ },
+ structs::nsCSSUnit::eCSSUnit_RootLineHeight => {
+ NoCalcLength::FontRelative(FontRelativeLength::Rlh(value))
+ },
structs::nsCSSUnit::eCSSUnit_Pixel => NoCalcLength::Absolute(AbsoluteLength::Px(value)),
structs::nsCSSUnit::eCSSUnit_Inch => NoCalcLength::Absolute(AbsoluteLength::In(value)),
structs::nsCSSUnit::eCSSUnit_Centimeter => {
@@ -6307,22 +6314,14 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(
}
seen.insert(property);
- // This is safe since we immediately write to the uninitialized values.
- unsafe {
- animation_values.set_len((property_index + 1) as u32);
- ptr::write(
- &mut animation_values[property_index],
- structs::PropertyStyleAnimationValuePair {
- mProperty: property
- .to_gecko_animated_property_id(/* owned = */ true),
- mValue: structs::AnimationValue {
- mServo: value.map_or(structs::RefPtr::null(), |v| {
- structs::RefPtr::from_arc(Arc::new(v))
- }),
- },
- },
- );
- }
+ animation_values.push(structs::PropertyStyleAnimationValuePair {
+ mProperty: property.to_gecko_animated_property_id(),
+ mValue: structs::AnimationValue {
+ mServo: value.map_or(structs::RefPtr::null(), |v| {
+ structs::RefPtr::from_arc(Arc::new(v))
+ }),
+ },
+ });
property_index += 1;
};
@@ -6352,7 +6351,7 @@ pub extern "C" fn Servo_GetAnimationValues(
element: &RawGeckoElement,
style: &ComputedValues,
raw_data: &PerDocumentStyleData,
- animation_values: &mut ThinVec<structs::RefPtr<AnimationValue>>,
+ animation_values: &mut nsTArray<structs::RefPtr<AnimationValue>>,
) {
let data = raw_data.borrow();
let element = GeckoElement(element);
@@ -6389,7 +6388,7 @@ pub extern "C" fn Servo_AnimationValue_GetPropertyId(
value: &AnimationValue,
property_id: &mut structs::AnimatedPropertyID,
) {
- *property_id = value.id().to_gecko_animated_property_id(/* owned = */ true);
+ *property_id = value.id().to_gecko_animated_property_id();
}
#[no_mangle]
@@ -6476,6 +6475,15 @@ enum Offset {
One,
}
+fn property_value_pair_for(id: &PropertyDeclarationId) -> structs::PropertyValuePair {
+ structs::PropertyValuePair {
+ mProperty: id.to_gecko_animated_property_id(),
+ mServoDeclarationBlock: structs::RefPtr::null(),
+ #[cfg(feature = "gecko_debug")]
+ mSimulateComputeValuesFailure: false,
+ }
+}
+
fn fill_in_missing_keyframe_values(
all_properties: &PropertyDeclarationIdSet,
timing_function: &ComputedTimingFunction,
@@ -6496,22 +6504,25 @@ fn fill_in_missing_keyframe_values(
let composition = structs::CompositeOperationOrAuto::Auto;
let keyframe = match offset {
Offset::Zero => unsafe {
- Gecko_GetOrCreateInitialKeyframe(keyframes, timing_function, composition)
+ &mut *bindings::Gecko_GetOrCreateInitialKeyframe(
+ keyframes,
+ timing_function,
+ composition,
+ )
},
Offset::One => unsafe {
- Gecko_GetOrCreateFinalKeyframe(keyframes, timing_function, composition)
+ &mut *bindings::Gecko_GetOrCreateFinalKeyframe(
+ keyframes,
+ timing_function,
+ composition,
+ )
},
};
// Append properties that have not been set at this offset.
for property in all_properties.iter() {
if !properties_at_offset.contains(property) {
- unsafe {
- Gecko_AppendPropertyValuePair(
- &mut *(*keyframe).mPropertyValues,
- &property.to_gecko_animated_property_id(/* owned = */ false),
- );
- }
+ keyframe.mPropertyValues.push(property_value_pair_for(&property));
}
}
}
@@ -6577,7 +6588,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
// Look for an existing keyframe with the same offset, timing function, and compsition, or
// else add a new keyframe at the beginning of the keyframe array.
- let keyframe = Gecko_GetOrCreateKeyframeAtStart(
+ let keyframe = &mut *bindings::Gecko_GetOrCreateKeyframeAtStart(
keyframes,
step.start_percentage.0 as f32,
&timing_function,
@@ -6598,11 +6609,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
continue;
}
seen.insert(property);
-
- Gecko_AppendPropertyValuePair(
- &mut *(*keyframe).mPropertyValues,
- &property.to_gecko_animated_property_id(/* owned = */ false),
- );
+ keyframe.mPropertyValues.push(property_value_pair_for(&property));
}
if current_offset == 0.0 {
has_complete_initial_keyframe = true;
@@ -6634,12 +6641,8 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
continue;
}
- let pair = Gecko_AppendPropertyValuePair(
- &mut *(*keyframe).mPropertyValues,
- &id.to_gecko_animated_property_id(/* owned = */ false),
- );
-
- (*pair).mServoDeclarationBlock.set_arc(Arc::new(
+ let mut pair = property_value_pair_for(&id);
+ pair.mServoDeclarationBlock.set_arc(Arc::new(
global_style_data
.shared_lock
.wrap(PropertyDeclarationBlock::with_one(
@@ -6647,6 +6650,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
Importance::Normal,
)),
));
+ keyframe.mPropertyValues.push(pair);
if current_offset == 0.0 {
properties_set_at_start.insert(id);
@@ -6689,7 +6693,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
#[no_mangle]
pub extern "C" fn Servo_StyleSet_GetFontFaceRules(
raw_data: &PerDocumentStyleData,
- rules: &mut ThinVec<structs::nsFontFaceRuleContainer>,
+ rules: &mut nsTArray<structs::nsFontFaceRuleContainer>,
) {
let data = raw_data.borrow();
debug_assert_eq!(rules.len(), 0);
@@ -7563,7 +7567,6 @@ pub extern "C" fn Servo_StyleSet_HasNthOfCustomStateDependency(
})
}
-
#[no_mangle]
pub extern "C" fn Servo_StyleSet_HasNthOfStateDependency(
raw_data: &PerDocumentStyleData,
@@ -8125,7 +8128,7 @@ pub unsafe extern "C" fn Servo_ColorTo(
.unwrap();
result_color.assign(&s);
- result_components.assign_from_iter_pod(color.raw_components().iter().copied());
+ result_components.extend(color.raw_components().iter().copied());
// For now we don't do gamut mapping, so always false.
*result_adjusted = false;
@@ -9069,7 +9072,7 @@ impl PropDef {
#[no_mangle]
pub extern "C" fn Servo_GetRegisteredCustomProperties(
per_doc_data: &PerDocumentStyleData,
- custom_properties: &mut ThinVec<PropDef>,
+ custom_properties: &mut nsTArray<PropDef>,
) {
let stylist = &per_doc_data.borrow().stylist;
@@ -9109,7 +9112,7 @@ pub struct SelectorWarningData {
#[no_mangle]
pub extern "C" fn Servo_GetSelectorWarnings(
rule: &LockedStyleRule,
- warnings: &mut ThinVec<SelectorWarningData>,
+ warnings: &mut nsTArray<SelectorWarningData>,
) {
read_locked_arc(rule, |r| {
for (i, selector) in r.selectors.slice().iter().enumerate() {
@@ -9121,10 +9124,7 @@ pub extern "C" fn Servo_GetSelectorWarnings(
}
#[no_mangle]
-pub extern "C" fn Servo_GetRuleBodyText(
- initial_text: &nsACString,
- ret_val: &mut nsACString,
-) {
+pub extern "C" fn Servo_GetRuleBodyText(initial_text: &nsACString, ret_val: &mut nsACString) {
let css_text = unsafe { initial_text.as_str_unchecked() };
let mut input = ParserInput::new(&css_text);
let mut input = Parser::new(&mut input);
@@ -9138,7 +9138,7 @@ pub extern "C" fn Servo_GetRuleBodyText(
found_start = true;
break;
},
- _ => {}
+ _ => {},
}
if token.is_parse_error() {
@@ -9146,7 +9146,6 @@ pub extern "C" fn Servo_GetRuleBodyText(
}
}
-
if !found_start {
ret_val.set_is_void(true);
return;
@@ -9154,11 +9153,8 @@ pub extern "C" fn Servo_GetRuleBodyText(
let token_start = input.position();
// Parse the nested block to move the parser to the end of the block
- let _ = input.parse_nested_block(
- |_i| -> Result<(), CssParseError<'_, BasicParseError>> {
- Ok(())
- }
- );
+ let _ =
+ input.parse_nested_block(|_i| -> Result<(), CssParseError<'_, BasicParseError>> { Ok(()) });
// We're not guaranteed to have a closing bracket, but when we do, we need to move
// the end offset before it.
@@ -9208,11 +9204,8 @@ pub extern "C" fn Servo_ReplaceBlockRuleBodyTextInStylesheetText(
let token_start = input.position();
let rule_body_start = rule_start_index + token_start.byte_index();
// Parse the nested block to move the parser to the end of the block
- let _ = input.parse_nested_block(
- |_i| -> Result<(), CssParseError<'_, BasicParseError>> {
- Ok(())
- }
- );
+ let _ =
+ input.parse_nested_block(|_i| -> Result<(), CssParseError<'_, BasicParseError>> { Ok(()) });
let mut rule_body_end = rule_start_index + input.position().byte_index();
// We're not guaranteed to have a closing bracket, but when we do, we need to move
@@ -9228,11 +9221,7 @@ pub extern "C" fn Servo_ReplaceBlockRuleBodyTextInStylesheetText(
}
/// Find css_text byte position corresponding to the passed line and column
-fn get_byte_index_from_line_and_column(
- css_text: &str,
- line: u32,
- column: u32,
-) -> Option<usize> {
+fn get_byte_index_from_line_and_column(css_text: &str, line: u32, column: u32) -> Option<usize> {
// Find the byte index of the start of the passed line within css_text
let mut line_byte_index = Some(0);
if line != 1 {
@@ -9277,3 +9266,196 @@ fn get_byte_index_from_line_and_column(
None
}
+
+#[repr(C)]
+pub struct CSSToken {
+ pub text: nsCString,
+ pub token_type: nsCString,
+ pub has_unit: bool,
+ pub unit: nsCString,
+ pub has_number: bool,
+ pub number: f32,
+ pub has_value: bool,
+ pub value: nsCString,
+ // line and column at which the token starts
+ pub line: u32,
+ pub column: u32,
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_CSSParser_create(text: &nsACString) -> *mut ParserState {
+ let css_text = unsafe { text.as_str_unchecked() };
+ let mut parser_input = ParserInput::new(&css_text);
+ let input = Parser::new(&mut parser_input);
+ Box::into_raw(Box::new(input.state()))
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_CSSParser_destroy(state: *mut ParserState) {
+ drop(Box::from_raw(state));
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_CSSParser_GetCurrentLine(state: &ParserState) -> u32 {
+ return state.source_location().line;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_CSSParser_GetCurrentColumn(state: &ParserState) -> u32 {
+ return state.source_location().column;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_CSSParser_NextToken(
+ text: &nsACString,
+ state: &mut ParserState,
+ css_token: &mut CSSToken,
+) -> bool {
+ let css_text = unsafe { text.as_str_unchecked() };
+ let mut parser_input = ParserInput::new(&css_text);
+ let mut input = Parser::new(&mut parser_input);
+ input.reset(state);
+
+ let token_start = input.position();
+ let location_start = state.source_location();
+ let Ok(token) = &input.next_including_whitespace_and_comments() else {
+ return false;
+ };
+
+ let token_type = match *token {
+ Token::Ident(_) => "Ident",
+ Token::AtKeyword(_) => "AtKeyword",
+ Token::Hash(_) => "Hash",
+ Token::IDHash(_) => "IDHash",
+ Token::QuotedString(_) => "QuotedString",
+ Token::UnquotedUrl(_) => "UnquotedUrl",
+ Token::Delim(_) => "Delim",
+ Token::Number { .. } => "Number",
+ Token::Percentage { .. } => "Percentage",
+ Token::Dimension { .. } => "Dimension",
+ Token::WhiteSpace(_) => "WhiteSpace",
+ Token::Comment(_) => "Comment",
+ Token::Colon => "Colon",
+ Token::Semicolon => "Semicolon",
+ Token::Comma => "Comma",
+ Token::IncludeMatch => "IncludeMatch",
+ Token::DashMatch => "DashMatch",
+ Token::PrefixMatch => "PrefixMatch",
+ Token::SuffixMatch => "SuffixMatch",
+ Token::SubstringMatch => "SubstringMatch",
+ Token::CDO => "CDO",
+ Token::CDC => "CDC",
+ Token::Function(_) => "Function",
+ Token::ParenthesisBlock => "ParenthesisBlock",
+ Token::SquareBracketBlock => "SquareBracketBlock",
+ Token::CurlyBracketBlock => "CurlyBracketBlock",
+ Token::BadUrl(_) => "BadUrl",
+ Token::BadString(_) => "BadString",
+ Token::CloseParenthesis => "CloseParenthesis",
+ Token::CloseSquareBracket => "CloseSquareBracket",
+ Token::CloseCurlyBracket => "CloseCurlyBracket",
+ };
+
+ let token_value = match *token {
+ Token::Ident(value) |
+ Token::AtKeyword(value) |
+ Token::Hash(value) |
+ Token::IDHash(value) |
+ Token::QuotedString(value) |
+ Token::UnquotedUrl(value) |
+ Token::Function(value) |
+ Token::BadUrl(value) |
+ Token::BadString(value) => {
+ let mut text = nsCString::new();
+ text.assign(value.as_bytes());
+ Some(text)
+ },
+ // value is a str here, we need a different branch to handle it
+ Token::Comment(value) => {
+ let mut text = nsCString::new();
+ text.assign(value.as_bytes());
+ Some(text)
+ },
+ // Delim and WhiteSpace also have value, but they will be similar to text, so don't
+ // include them
+ Token::Delim(_) |
+ Token::WhiteSpace(_) |
+ // Number, Percentage and Dimension expose numeric values that will be exposed in `number`
+ Token::Number{..} |
+ Token::Percentage{..} |
+ Token::Dimension{..} |
+ // The rest of the tokens don't expose a string value
+ Token::Colon |
+ Token::Semicolon |
+ Token::Comma |
+ Token::IncludeMatch |
+ Token::DashMatch |
+ Token::PrefixMatch |
+ Token::SuffixMatch |
+ Token::SubstringMatch |
+ Token::CDO |
+ Token::CDC |
+ Token::ParenthesisBlock |
+ Token::SquareBracketBlock |
+ Token::CurlyBracketBlock |
+ Token::CloseParenthesis |
+ Token::CloseSquareBracket |
+ Token::CloseCurlyBracket => None
+ };
+
+ let token_unit = match *token {
+ Token::Dimension { ref unit, .. } => {
+ let mut unit_text = nsCString::new();
+ unit_text.assign(unit.as_bytes());
+ Some(unit_text)
+ },
+ _ => None,
+ };
+
+ let token_number = match *token {
+ Token::Dimension { ref value, .. } => Some(value),
+ Token::Number { ref value, .. } => Some(value),
+ Token::Percentage { ref unit_value, .. } => Some(unit_value),
+ _ => None,
+ };
+ css_token.has_number = token_number.is_some();
+ if css_token.has_number {
+ css_token.number = *token_number.unwrap();
+ }
+
+ let need_to_parse_nested_block = match *token {
+ Token::Function(_) |
+ Token::ParenthesisBlock |
+ Token::CurlyBracketBlock |
+ Token::SquareBracketBlock => true,
+ _ => false,
+ };
+
+ let mut text = nsCString::new();
+ text.assign(&input.slice_from(token_start));
+
+ css_token.text = text;
+ css_token.token_type = token_type.into();
+ css_token.has_value = token_value.is_some();
+ if css_token.has_value {
+ css_token.value = token_value.unwrap();
+ }
+ css_token.has_unit = token_unit.is_some();
+ if css_token.has_unit {
+ css_token.unit = token_unit.unwrap();
+ }
+
+ css_token.line = location_start.line;
+ css_token.column = location_start.column;
+
+ if need_to_parse_nested_block {
+ let _ = input.parse_nested_block(|i| -> Result<(), CssParseError<'_, BasicParseError>> {
+ *state = i.state();
+ Ok(())
+ });
+ } else {
+ *state = input.state();
+ }
+
+ return true;
+}