MCPcopy Create free account
hub / github.com/Stranger6667/css-inline / inline_to_impl

Method inline_to_impl

css-inline/src/lib.rs:644–883  ·  view source on GitHub ↗
(
        &self,
        html: &str,
        css: Option<&str>,
        target: &mut W,
        mode: InliningMode,
    )

Source from the content-addressed store, hash-verified

642
643 #[allow(clippy::too_many_lines)]
644 fn inline_to_impl<W: Write>(
645 &self,
646 html: &str,
647 css: Option<&str>,
648 target: &mut W,
649 mode: InliningMode,
650 ) -> Result<()> {
651 let mut document = Document::parse_with_options(
652 html.as_bytes(),
653 self.options.preallocate_node_capacity,
654 mode,
655 );
656 // CSS rules may overlap, and the final set of rules applied to an element depend on
657 // selectors' specificity - selectors with higher specificity have more priority.
658 // Inlining happens in two major steps:
659 // 1. All available styles are mapped to respective elements together with their
660 // selector's specificity. When two rules overlap on the same declaration, then
661 // the one with higher specificity replaces another.
662 // 2. Resulting styles are merged into existing "style" tags.
663 let track_selector_cleanup = self.options.remove_inlined_selectors;
664 let mut size_estimate: usize = if self.options.inline_style_tags {
665 document
666 .styles()
667 .map(|(_, s)| {
668 // Add 1 to account for the extra `\n` char we add between styles
669 s.len().saturating_add(1)
670 })
671 .sum()
672 } else {
673 0
674 };
675 if let Some(extra_css) = &self.options.extra_css {
676 size_estimate = size_estimate.saturating_add(extra_css.len());
677 }
678 if let Some(css) = css {
679 size_estimate = size_estimate.saturating_add(css.len());
680 }
681 let mut css_buffer = CssBuffer::new(track_selector_cleanup);
682 css_buffer.raw.reserve(size_estimate);
683 if self.options.inline_style_tags || self.options.keep_at_rules {
684 for (node_id, style) in document.styles() {
685 let style_node = track_selector_cleanup.then_some(node_id);
686 css_buffer.push(style_node, style, true);
687 }
688 }
689 if self.options.load_remote_stylesheets {
690 let mut links = document.stylesheets().collect::<Vec<&str>>();
691 links.sort_unstable();
692 links.dedup();
693 for href in &links {
694 let url = self.get_full_url(href);
695 #[cfg(feature = "stylesheet-cache")]
696 if let Some(lock) = self.options.cache.as_ref() {
697 let mut cache = lock.lock().expect("Cache lock is poisoned");
698 if let Some(cached) = cache.get(url.as_ref()) {
699 css_buffer.push(None, cached, true);
700 continue;
701 }

Callers 2

inline_toMethod · 0.80
inline_fragment_toMethod · 0.80

Calls 15

parse_with_optionsFunction · 0.85
apply_selector_cleanupFunction · 0.85
as_bytesMethod · 0.80
stylesMethod · 0.80
pushMethod · 0.80
stylesheetsMethod · 0.80
get_full_urlMethod · 0.80
as_refMethod · 0.80
into_partsMethod · 0.80
is_emptyMethod · 0.80
iterMethod · 0.80

Tested by

no test coverage detected