Fix references in onepass

This commit is contained in:
Wilson Lin 2021-08-08 19:00:51 +10:00
parent 3e3a4bbd9a
commit 4fc9496829
6 changed files with 26 additions and 14 deletions

View File

@ -46,6 +46,10 @@ const WHITESPACE_OR_SLASH_OR_EQUALS_OR_RIGHT_CHEVRON = [
const DOUBLE_QUOTE = [c('"')];
const SINGLE_QUOTE = [c("'")];
// Official characters allowed in an attribute name.
// NOTE: Unicode noncharacters not tested.
// See https://html.spec.whatwg.org/multipage/syntax.html#syntax-attribute-name for spec.
const WHATWG_ATTR_NAME_CHAR = invert([...CONTROL, c(' '), c('"'), c('\''), c('>'), c('/'), c('=')]);
// Valid attribute quote characters.
// See https://html.spec.whatwg.org/multipage/introduction.html#intro-early-example for spec.
// Backtick is not a valid quote character according to spec.
@ -88,6 +92,7 @@ impl std::ops::Index<u8> for Lookup {
WHITESPACE_OR_SLASH,
WHITESPACE_OR_SLASH_OR_EQUALS_OR_RIGHT_CHEVRON,
WHATWG_ATTR_NAME_CHAR,
DOUBLE_QUOTE,
SINGLE_QUOTE,
ATTR_QUOTE,

View File

@ -22,7 +22,7 @@ mod unit;
/// # Examples
///
/// ```
/// use minify_html::{Cfg, Error, in_place};
/// use minify_html_onepass::{Cfg, Error, in_place};
///
/// let mut code = b"<p> Hello, world! </p>".to_vec();
/// let cfg = &Cfg {
@ -62,7 +62,7 @@ pub fn in_place(code: &mut [u8], cfg: &Cfg) -> Result<usize, Error> {
/// # Examples
///
/// ```
/// use minify_html::{Cfg, Error, in_place_str};
/// use minify_html_onepass::{Cfg, Error, in_place_str};
///
/// let mut code = "<p> Hello, world! </p>".to_string();
/// let cfg = &Cfg {
@ -92,7 +92,7 @@ pub fn in_place_str<'s>(code: &'s mut str, cfg: &Cfg) -> Result<&'s str, Error>
/// # Examples
///
/// ```
/// use minify_html::{Cfg, Error, truncate};
/// use minify_html_onepass::{Cfg, Error, truncate};
///
/// let mut code = b"<p> Hello, world! </p>".to_vec();
/// let cfg = &Cfg {
@ -125,7 +125,7 @@ pub fn truncate(code: &mut Vec<u8>, cfg: &Cfg) -> Result<(), Error> {
/// # Examples
///
/// ```
/// use minify_html::{Cfg, Error, copy};
/// use minify_html_onepass::{Cfg, Error, copy};
///
/// let mut code: &[u8] = b"<p> Hello, world! </p>";
/// let cfg = &Cfg {
@ -164,7 +164,7 @@ pub fn copy(code: &[u8], cfg: &Cfg) -> Result<Vec<u8>, Error> {
/// # Examples
///
/// ```
/// use minify_html::{Cfg, FriendlyError, with_friendly_error};
/// use minify_html_onepass::{Cfg, FriendlyError, with_friendly_error};
///
/// let mut code = b"<p></div>".to_vec();
/// let cfg = &Cfg {

View File

@ -16,6 +16,7 @@ use crate::proc::range::ProcessorRange;
use crate::proc::MatchAction::*;
use crate::proc::MatchMode::*;
use minify_html_common::gen::codepoints::Lookup;
use minify_html_common::spec::tag::EMPTY_SLICE;
pub mod checkpoint;
pub mod entity;
@ -239,6 +240,12 @@ impl<'d> Processor<'d> {
!self._in_bounds(0)
}
#[inline(always)]
pub fn get_or_empty(&self, r: Option<ProcessorRange>) -> &[u8] {
r.and_then(|r| self.code.get(r.start..r.end))
.unwrap_or(EMPTY_SLICE)
}
#[inline(always)]
pub fn require_not_at_end(&self) -> ProcessingResult<()> {
if self.at_end() {

View File

@ -8,7 +8,7 @@ use crate::unit::attr::value::{
process_attr_value, skip_attr_value, DelimiterType, ProcessedAttrValue,
};
use minify_html_common::gen::attrs::ATTRS;
use minify_html_common::gen::codepoints::{ATTR_NAME_CHAR, WHITESPACE};
use minify_html_common::gen::codepoints::{WHATWG_ATTR_NAME_CHAR, WHITESPACE};
use minify_html_common::spec::tag::ns::Namespace;
mod value;
@ -34,7 +34,7 @@ pub fn process_attr(
// It's possible to expect attribute name but not be called at an attribute, e.g. due to whitespace between name and
// value, which causes name to be considered boolean attribute and `=` to be start of new (invalid) attribute name.
let name = proc
.m(WhileInLookup(ATTR_NAME_CHAR), Keep)
.m(WhileInLookup(WHATWG_ATTR_NAME_CHAR), Keep)
.require("attribute name")?;
proc.make_lowercase(name);
let attr_cfg = ATTRS.get(ns, &proc[element], &proc[name]);

View File

@ -64,7 +64,7 @@ pub fn process_content(
collapse,
destroy_whole,
trim,
} = get_whitespace_minification_for_tag(parent.map(|r| &proc[r]), descendant_of_pre);
} = get_whitespace_minification_for_tag(proc.get_or_empty(parent), descendant_of_pre);
let handle_ws = collapse || destroy_whole || trim;
@ -146,7 +146,7 @@ pub fn process_content(
.require("tag name")?;
proc.make_lowercase(tag_name);
if can_omit_as_before(proc, parent, tag_name) {
if can_omit_as_before(proc.get_or_empty(parent), &proc[tag_name]) {
// TODO Is this necessary? Can a previous closing tag even exist?
prev_sibling_closing_tag.write_if_exists(proc);
tag_checkpoint.restore(proc);
@ -169,9 +169,9 @@ pub fn process_content(
prev_sibling_closing_tag.replace(new_closing_tag);
}
ContentType::End => {
if prev_sibling_closing_tag
.exists_and(|prev_tag| !can_omit_as_last_node(proc, parent, prev_tag))
{
if prev_sibling_closing_tag.exists_and(|prev_tag| {
!can_omit_as_last_node(proc.get_or_empty(parent), &proc[prev_tag])
}) {
prev_sibling_closing_tag.write(proc);
};
break;

View File

@ -107,7 +107,7 @@ pub fn process_tag(
source_tag_name: ProcessorRange,
) -> ProcessingResult<MaybeClosingTag> {
if prev_sibling_closing_tag
.exists_and(|prev_tag| !can_omit_as_before(proc, Some(prev_tag), source_tag_name))
.exists_and(|prev_tag| !can_omit_as_before(&proc[prev_tag], &proc[source_tag_name]))
{
prev_sibling_closing_tag.write(proc);
};
@ -237,7 +237,7 @@ pub fn process_tag(
}
};
let can_omit_closing_tag = can_omit_as_last_node(proc, parent, tag_name);
let can_omit_closing_tag = can_omit_as_last_node(proc.get_or_empty(parent), &proc[tag_name]);
if closing_tag_omitted || proc.at_end() && can_omit_closing_tag {
return Ok(MaybeClosingTag(None));
};