[Git][java-team/libhtml5parser-java][master] 3 commits: New upstream version 1.4+r20260416
bastif (@bastif)
gitlab at salsa.debian.org
Fri May 1 13:49:12 BST 2026
bastif pushed to branch master at Debian Java Maintainers / libhtml5parser-java
Commits:
5c6cfbbf by Fab Stz at 2026-05-01T14:42:20+02:00
New upstream version 1.4+r20260416
- - - - -
0ebed37d by Fab Stz at 2026-05-01T14:42:21+02:00
Update upstream source from tag 'upstream/1.4+r20260416'
Update to upstream version '1.4+r20260416'
with Debian dir 5e8917984c28eeee6bf5550e9507b67bb09d4117
- - - - -
3f5082d3 by Fab Stz at 2026-05-01T14:48:28+02:00
Update changelog to 1.4+r20260416-1
- - - - -
18 changed files:
- − .github/dependabot.yml
- .github/workflows/build.yml
- + CONTRIBUTING.md
- debian/changelog
- gwt-src/nu/validator/htmlparser/gwt/BrowserTreeBuilder.java
- src/nu/validator/htmlparser/dom/DOMTreeBuilder.java
- src/nu/validator/htmlparser/impl/AttributeName.java
- src/nu/validator/htmlparser/impl/ElementName.java
- src/nu/validator/htmlparser/impl/Portability.java
- src/nu/validator/htmlparser/impl/Tokenizer.java
- src/nu/validator/htmlparser/impl/TreeBuilder.java
- src/nu/validator/htmlparser/sax/SAXTreeBuilder.java
- src/nu/validator/htmlparser/xom/XOMTreeBuilder.java
- src/nu/validator/saxtree/CharBufferNode.java
- src/nu/validator/saxtree/ParentNode.java
- translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java
- translator-src/nu/validator/htmlparser/cpptranslate/CppVisitor.java
- translator-src/nu/validator/htmlparser/cpptranslate/HVisitor.java
Changes:
=====================================
.github/dependabot.yml deleted
=====================================
@@ -1,10 +0,0 @@
-version: 2
-updates:
- - package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "weekly"
- - package-ecosystem: "maven"
- directory: "/"
- schedule:
- interval: "weekly"
=====================================
.github/workflows/build.yml
=====================================
@@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- java: [24, 21, 17, 11.0.23]
+ java: [25, 21, 17, 11.0.23]
os: [ubuntu-latest, macos-latest, windows-latest]
name: Java ${{ matrix.java }}
steps:
=====================================
CONTRIBUTING.md
=====================================
@@ -0,0 +1,96 @@
+# Contributing to htmlparser
+
+## Adding new elements
+
+When adding new elements to the parser, you must regenerate the element name hash tables in `src/nu/validator/htmlparser/impl/ElementName.java`.
+
+### Step 1: Add the new element constant
+
+Add a new `static final ElementName` constant for your element, following the existing pattern:
+
+```java
+public static final ElementName MYNEWELEMENT = new ElementName(
+ "mynewelement", "mynewelement",
+ // CPPONLY: NS_NewHTMLElement,
+ // CPPONLY: NS_NewSVGUnknownElement,
+ TreeBuilder.OTHER);
+```
+
+The flags (like `TreeBuilder.OTHER`, `SPECIAL`, `SCOPING`, etc.) depend on how the element should be handled by the tree builder.
+
+### Step 2: Uncomment the code generation sections
+
+Uncomment three sections in `ElementName.java`:
+
+1. **The imports** near the top (~lines 26-39):
+ - `java.io.*`
+ - `java.util.*`
+ - `java.util.regex.*`
+
+2. **`implements Comparable<ElementName>`** on the class declaration (~line 49)
+
+3. **The code generation block** marked with:
+ `"START CODE ONLY USED FOR GENERATING CODE uncomment and run to regenerate"`
+ That includes the `main()` method and helper functions (~lines 272-659)
+
+### Step 3: Add case to treeBuilderGroupToName() if needed
+
+If your element uses a new `TreeBuilder` group constant, add a case for it in the `treeBuilderGroupToName()` method within the code generation block.
+
+### Step 4: Compile and run
+
+Compile the project:
+
+```bash
+mvn compile
+```
+
+Run the `ElementName` class with paths to the Gecko tag-list files:
+
+```bash
+java -cp target/classes nu.validator.htmlparser.impl.ElementName \
+ /path/to/nsHTMLTagList.h \
+ /path/to/SVGTagList.h
+```
+
+**For Java-only builds** (not Gecko), you can use empty dummy files:
+
+```bash
+mkdir -p /tmp/tagfiles
+touch /tmp/tagfiles/nsHTMLTagList.h /tmp/tagfiles/SVGTagList.h
+java -cp target/classes nu.validator.htmlparser.impl.ElementName \
+ /tmp/tagfiles/nsHTMLTagList.h \
+ /tmp/tagfiles/SVGTagList.h
+```
+
+> [!NOTE]
+> Using empty files means the `CPPONLY` comments will all show `NS_NewHTMLUnknownElement`. For Gecko builds, use the actual files from moz-central:
+> - `parser/htmlparser/nsHTMLTagList.h`
+> - `dom/svg/SVGTagList.h`
+
+### Step 5: Update the generated arrays
+
+The program outputs:
+1. All element constant definitions (with updated `CPPONLY` comments if using real Gecko tag files)
+2. The `ELEMENT_NAMES` array in level-order binary search tree order
+3. The `ELEMENT_HASHES` array with corresponding hash values
+
+Replace the existing `ELEMENT_NAMES` and `ELEMENT_HASHES` arrays in the file with the generated output. The arrays must stay in sync—element at position N in `ELEMENT_NAMES` must have its hash at position N in `ELEMENT_HASHES`.
+
+### Step 6: Re-comment the code generation sections
+
+After regeneration, comment out the sections you uncommented in Step 2 to restore the file to its normal state.
+
+### Step 7: Run tests
+
+Verify your changes work correctly:
+
+```bash
+mvn test
+```
+
+### Technical Details
+
+The hash function (`bufToHash`) creates a unique integer for each element name using the element's length and specific character positions. The arrays are organized as a level-order binary search tree for O(log n) lookup performance.
+
+If you encounter a hash collision (two elements with the same hash), the regeneration will report an error. That would require modifying the hash function, which has not been necessary historically.
=====================================
debian/changelog
=====================================
@@ -1,3 +1,9 @@
+libhtml5parser-java (1.4+r20260416-1) UNRELEASED; urgency=medium
+
+ * New upstream version 1.4+r20260416-1
+
+ -- Fab Stz <fabstz-it at yahoo.fr> Fri, 01 May 2026 14:42:33 +0200
+
libhtml5parser-java (1.4+r20250916-1) unstable; urgency=medium
[ Fab Stz ]
=====================================
gwt-src/nu/validator/htmlparser/gwt/BrowserTreeBuilder.java
=====================================
@@ -474,4 +474,107 @@ class BrowserTreeBuilder extends CoalescingTreeBuilder<JavaScriptObject> {
fatal(e);
}
}
+
+ private static native JavaScriptObject getNextSibling(
+ JavaScriptObject node) /*-{
+ return node.nextSibling;
+ }-*/;
+
+ private static native String getLocalName(
+ JavaScriptObject node) /*-{
+ return node.localName;
+ }-*/;
+
+ private static native String getNamespaceURI(
+ JavaScriptObject node) /*-{
+ return node.namespaceURI;
+ }-*/;
+
+ private static native boolean hasAttribute(
+ JavaScriptObject node, String name) /*-{
+ return node.hasAttribute(name);
+ }-*/;
+
+ @Override
+ // https://html.spec.whatwg.org/multipage/form-elements.html#maybe-clone-an-option-into-selectedcontent
+ // Implements "maybe clone an option into selectedcontent"
+ protected void optionElementPopped(JavaScriptObject option)
+ throws SAXException {
+ try {
+ // Find the nearest ancestor <select> element
+ JavaScriptObject ancestor = getParentNode(option);
+ JavaScriptObject select = null;
+ while (ancestor != null && getNodeType(ancestor) == 1) {
+ if ("select".equals(getLocalName(ancestor))
+ && "http://www.w3.org/1999/xhtml".equals(
+ getNamespaceURI(ancestor))) {
+ select = ancestor;
+ break;
+ }
+ ancestor = getParentNode(ancestor);
+ }
+ if (select == null) {
+ return;
+ }
+ if (hasAttribute(select, "multiple")) {
+ return;
+ }
+
+ // Find the first <selectedcontent> descendant of <select>
+ JavaScriptObject selectedContent = findSelectedContent(
+ select);
+ if (selectedContent == null) {
+ return;
+ }
+
+ // Check option selectedness
+ boolean hasSelectedAttr = hasAttribute(option, "selected");
+ if (!hasSelectedAttr && hasChildNodes(selectedContent)) {
+ // Not the first option and no explicit selected attr
+ return;
+ }
+
+ // Clear selectedcontent children and deep-clone option children
+ while (hasChildNodes(selectedContent)) {
+ removeChild(selectedContent, getFirstChild(selectedContent));
+ }
+ for (JavaScriptObject child = getFirstChild(option);
+ child != null; child = getNextSibling(child)) {
+ appendChild(selectedContent, cloneNodeDeep(child));
+ }
+ } catch (JavaScriptException e) {
+ fatal(e);
+ }
+ }
+
+ private JavaScriptObject findSelectedContent(
+ JavaScriptObject root) {
+ JavaScriptObject current = getFirstChild(root);
+ if (current == null) {
+ return null;
+ }
+ JavaScriptObject next;
+ for (;;) {
+ if (getNodeType(current) == 1
+ && "selectedcontent".equals(getLocalName(current))
+ && "http://www.w3.org/1999/xhtml".equals(
+ getNamespaceURI(current))) {
+ return current;
+ }
+ if ((next = getFirstChild(current)) != null) {
+ current = next;
+ continue;
+ }
+ for (;;) {
+ if (current == root) {
+ return null;
+ }
+ if ((next = getNextSibling(current)) != null) {
+ current = next;
+ break;
+ }
+ current = getParentNode(current);
+ }
+ }
+ }
}
=====================================
src/nu/validator/htmlparser/dom/DOMTreeBuilder.java
=====================================
@@ -354,4 +354,89 @@ class DOMTreeBuilder extends CoalescingTreeBuilder<Element> {
fatal(e);
}
}
+
+ @Override
+ // https://html.spec.whatwg.org/multipage/form-elements.html#maybe-clone-an-option-into-selectedcontent
+ // Implements "maybe clone an option into selectedcontent"
+ protected void optionElementPopped(Element option) throws SAXException {
+ try {
+ // Find the nearest ancestor <select> element
+ Node ancestor = option.getParentNode();
+ Element select = null;
+ while (ancestor != null) {
+ if (ancestor.getNodeType() == Node.ELEMENT_NODE) {
+ Element elt = (Element) ancestor;
+ if ("select".equals(elt.getLocalName())
+ && "http://www.w3.org/1999/xhtml".equals(
+ elt.getNamespaceURI())) {
+ select = elt;
+ break;
+ }
+ }
+ ancestor = ancestor.getParentNode();
+ }
+ if (select == null) {
+ return;
+ }
+ if (select.hasAttribute("multiple")) {
+ return;
+ }
+
+ // Find the first <selectedcontent> descendant of <select>
+ Element selectedContent = findSelectedContent(select);
+ if (selectedContent == null) {
+ return;
+ }
+
+ // Check option selectedness
+ boolean hasSelected = option.hasAttribute("selected");
+ if (!hasSelected && selectedContent.hasChildNodes()) {
+ // Not the first option and no explicit selected attr
+ return;
+ }
+
+ // Clear selectedcontent children and deep-clone option children
+ while (selectedContent.hasChildNodes()) {
+ selectedContent.removeChild(selectedContent.getFirstChild());
+ }
+ for (Node child = option.getFirstChild(); child != null;
+ child = child.getNextSibling()) {
+ selectedContent.appendChild(child.cloneNode(true));
+ }
+ } catch (DOMException e) {
+ fatal(e);
+ }
+ }
+
+ private Element findSelectedContent(Element root) {
+ Node current = root.getFirstChild();
+ if (current == null) {
+ return null;
+ }
+ Node next;
+ for (;;) {
+ if (current.getNodeType() == Node.ELEMENT_NODE) {
+ Element elt = (Element) current;
+ if ("selectedcontent".equals(elt.getLocalName())
+ && "http://www.w3.org/1999/xhtml".equals(
+ elt.getNamespaceURI())) {
+ return elt;
+ }
+ }
+ if ((next = current.getFirstChild()) != null) {
+ current = next;
+ continue;
+ }
+ for (;;) {
+ if (current == root) {
+ return null;
+ }
+ if ((next = current.getNextSibling()) != null) {
+ current = next;
+ break;
+ }
+ current = current.getParentNode();
+ }
+ }
+ }
}
=====================================
src/nu/validator/htmlparser/impl/AttributeName.java
=====================================
@@ -806,7 +806,9 @@ public final class AttributeName
public static final AttributeName SRCDOC = new AttributeName(ALL_NO_NS, "srcdoc", "srcdoc", "srcdoc", "srcdoc", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName STDDEVIATION = new AttributeName(ALL_NO_NS, "stddeviation", "stddeviation", "stdDeviation", "stddeviation", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SANDBOX = new AttributeName(ALL_NO_NS, "sandbox", "sandbox", "sandbox", "sandbox", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SHADOWROOTCUSTOMELEMENTREGISTRY = new AttributeName(ALL_NO_NS, "shadowrootcustomelementregistry", "shadowrootcustomelementregistry", "shadowrootcustomelementregistry", "shadowrootcustomelementregistry", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SHADOWROOTDELEGATESFOCUS = new AttributeName(ALL_NO_NS, "shadowrootdelegatesfocus", "shadowrootdelegatesfocus", "shadowrootdelegatesfocus", "shadowrootdelegatesfocus", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SHADOWROOTSLOTASSIGNMENT = new AttributeName(ALL_NO_NS, "shadowrootslotassignment", "shadowrootslotassignment", "shadowrootslotassignment", "shadowrootslotassignment", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName WORD_SPACING = new AttributeName(ALL_NO_NS, "word-spacing", "word-spacing", "word-spacing", "word-spacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName ACCENTUNDER = new AttributeName(ALL_NO_NS, "accentunder", "accentunder", "accentunder", "accentunder", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName ACCEPT_CHARSET = new AttributeName(ALL_NO_NS, "accept-charset", "accept-charset", "accept-charset", "accept-charset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
@@ -1199,37 +1201,37 @@ public final class AttributeName
public static final AttributeName RY = new AttributeName(ALL_NO_NS, "ry", "ry", "ry", "ry", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName REFY = new AttributeName(ALL_NO_NS, "refy", "refy", "refY", "refy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
private final static @NoLength AttributeName[] ATTRIBUTE_NAMES = {
- MARKERUNITS,
- BASELINE,
- STOP_COLOR,
+ MARKERWIDTH,
+ BASELINE_SHIFT,
+ SHAPE,
CLEAR,
- XREF,
- AUTOPLAY,
- FONT_STYLE,
+ PROFILE,
+ XLINK_SHOW,
+ FONT_WEIGHT,
ARIA_DISABLED,
OPACITY,
- ONBEFOREPRINT,
- PATH,
- ALINK,
- ONMOUSEDOWN,
- COLS,
- COLUMNLINES,
+ ONMESSAGE,
+ ONCHANGE,
+ ZOOMANDPAN,
+ ONMOUSEOUT,
+ CLASSID,
+ ACCUMULATE,
Y,
ARIA_MULTISELECTABLE,
ROTATE,
SHADOWROOTCLONABLE,
- LINEBREAK,
- REPEATDUR,
- ORIGIN,
- RADIUS,
- TABLEVALUES,
- POINTSATZ,
- NUMOCTAVES,
- CLIPPATHUNITS,
- ONDRAGEND,
- ROWS,
- PATTERNTRANSFORM,
- VIEWTARGET,
+ INTERCEPT,
+ ROLE,
+ MARGINHEIGHT,
+ OPTIMUM,
+ SCALE,
+ POINTSATX,
+ FLOOD_OPACITY,
+ CLIP_RULE,
+ ONDRAGENTER,
+ ROWSPAN,
+ ONSTART,
+ VALUE,
MIN,
K3,
ARIA_CHANNEL,
@@ -1237,31 +1239,31 @@ public final class AttributeName
LOCAL,
ONABORT,
HIDDEN,
- ACCEPT_CHARSET,
- DIRECTION,
- OBJECT,
- ONBEFORECUT,
- SIZE,
- IMAGE_RENDERING,
- MATHBACKGROUND,
- DIVISOR,
- LINK,
- FILL_OPACITY,
- FORM,
- OPEN,
- XLINK_TITLE,
- COLOR_INTERPOLATION,
- ONZOOM,
- STROKE,
- LOOP,
- COORDS,
- STARTOFFSET,
- LOWSRC,
- CONTEXTMENU,
- KEYTIMES,
- TEXT_DECORATION,
- REQUIRED,
- CY,
+ WORD_SPACING,
+ DEFER,
+ ONBEFOREUNLOAD,
+ ONKEYPRESS,
+ SPREADMETHOD,
+ IMAGESIZES,
+ HIGH,
+ BEGIN,
+ VISIBILITY,
+ FILL_RULE,
+ FRAMESPACING,
+ KERNELUNITLENGTH,
+ WHEN,
+ COLOR_PROFILE,
+ ONFOCUSIN,
+ STROKE_LINEJOIN,
+ HTTP_EQUIV,
+ ATTRIBUTETYPE,
+ ONDRAGSTART,
+ KEYSYSTEM,
+ CONTROLS,
+ FONTSIZE,
+ SYSTEMLANGUAGE,
+ ONSUBMIT,
+ REFX,
END,
SRC,
Y1,
@@ -1276,183 +1278,183 @@ public final class AttributeName
FETCHPRIORITY,
BORDER,
RENDERING_INTENT,
- SANDBOX,
- BEVELLED,
- CODEBASE,
- FACE,
- NAME,
- ONRESET,
- ONSELECTSTART,
- REFERRERPOLICY,
- STRETCHY,
- HREFLANG,
- DRAGGABLE,
- LONGDESC,
- TARGETY,
- MATHSIZE,
- ACTIVE,
- MANIFEST,
- TABINDEX,
- MASK,
- CELLPADDING,
- REPLACE,
- FRAMEBORDER,
- SUMMARY,
- KERNELMATRIX,
- POINTER_EVENTS,
- TRANSFORM,
- XMLNS,
- AUTOCAPITALIZE,
- EXPONENT,
- ONMOUSEENTER,
- ONMOUSEUP,
- STROKE_DASHARRAY,
- COMPACT,
- GLYPH_ORIENTATION_HORIZONTAL,
- SHAPE_RENDERING,
- ABBR,
- NOHREF,
- OPERATOR,
- BIAS,
- CLASS,
- PRESERVEALPHA,
- ALTTEXT,
- FILTER,
- FONT_SIZE_ADJUST,
- RT,
- RESTART,
- WRITING_MODE,
- GROUPALIGN,
- VALUES,
- FX,
- RY,
- DIR,
- IN2,
- REL,
- R,
- K1,
- X2,
- XML_SPACE,
- ARIA_LABELLEDBY,
- ARIA_SELECTED,
- ARIA_PRESSED,
- ARIA_SECRET,
- ARIA_TEMPLATEID,
- ARIA_MULTILINE,
- ARIA_RELEVANT,
- ARIA_AUTOCOMPLETE,
- ARIA_HASPOPUP,
- DEFAULT,
- HSPACE,
- MOVABLELIMITS,
- RSPACE,
- SEPARATORS,
- ENABLE_BACKGROUND,
- CHECKED,
- ONSCROLL,
- SPECULAREXPONENT,
- GRADIENTTRANSFORM,
- LOADING,
- SEED,
- SRCDOC,
- WORD_SPACING,
+ STDDEVIATION,
ACCENT,
- BASELINE_SHIFT,
CODE,
- DEFER,
EDGE,
- INTERCEPT,
LINETHICKNESS,
- ONBEFOREUNLOAD,
ORDER,
- ONMESSAGE,
ORIENTATION,
- ONKEYPRESS,
ONRESIZE,
- ROLE,
SIZES,
- SPREADMETHOD,
DIFFUSECONSTANT,
- PROFILE,
ALIGNMENT_BASELINE,
- IMAGESIZES,
LANG,
- MARGINHEIGHT,
TARGET,
- HIGH,
MATHVARIANT,
- ONCHANGE,
ACTIONTYPE,
- BEGIN,
LIMITINGCONEANGLE,
- OPTIMUM,
SCRIPTSIZEMULTIPLIER,
- VISIBILITY,
MARKERHEIGHT,
- MARKERWIDTH,
AMPLITUDE,
- FILL_RULE,
ONCLICK,
- SCALE,
AZIMUTH,
- FRAMESPACING,
PRIMITIVEUNITS,
- ZOOMANDPAN,
EVENT,
- KERNELUNITLENGTH,
ONEND,
- POINTSATX,
STANDBY,
- WHEN,
XLINK_ARCROLE,
- XLINK_SHOW,
AUTOCOMPLETE,
- COLOR_PROFILE,
COLOR_INTERPOLATION_FILTERS,
- FLOOD_OPACITY,
ONLOAD,
- ONFOCUSIN,
ONMOUSELEAVE,
- ONMOUSEOUT,
RQUOTE,
- STROKE_LINEJOIN,
STROKE_WIDTH,
- CLIP_RULE,
DISPLAYSTYLE,
- HTTP_EQUIV,
SCOPED,
- SHAPE,
TEMPLATE,
- ATTRIBUTETYPE,
CHARSET,
- ONDRAGENTER,
ONDRAGDROP,
- ONDRAGSTART,
AS,
- CLASSID,
CLOSURE,
- KEYSYSTEM,
MINSIZE,
- ROWSPAN,
SUBSCRIPTSHIFT,
- CONTROLS,
ENCTYPE,
- FONT_WEIGHT,
FONT_FAMILY,
- FONTSIZE,
LIST,
- ONSTART,
PATTERNUNITS,
- SYSTEMLANGUAGE,
TEXTLENGTH,
- ACCUMULATE,
COLUMNSPACING,
- ONSUBMIT,
RESULT,
- VALUE,
CX,
- REFX,
FY,
+ DIR,
+ IN2,
+ REL,
+ R,
+ K1,
+ X2,
+ XML_SPACE,
+ ARIA_LABELLEDBY,
+ ARIA_SELECTED,
+ ARIA_PRESSED,
+ ARIA_SECRET,
+ ARIA_TEMPLATEID,
+ ARIA_MULTILINE,
+ ARIA_RELEVANT,
+ ARIA_AUTOCOMPLETE,
+ ARIA_HASPOPUP,
+ DEFAULT,
+ HSPACE,
+ MOVABLELIMITS,
+ RSPACE,
+ SEPARATORS,
+ ENABLE_BACKGROUND,
+ CHECKED,
+ ONSCROLL,
+ SPECULAREXPONENT,
+ GRADIENTTRANSFORM,
+ LOADING,
+ SEED,
+ SRCDOC,
+ SHADOWROOTCUSTOMELEMENTREGISTRY,
+ ACCEPT_CHARSET,
+ BEVELLED,
+ BASELINE,
+ CODEBASE,
+ DIRECTION,
+ FACE,
+ LINEBREAK,
+ NAME,
+ OBJECT,
+ ONRESET,
+ ONBEFOREPRINT,
+ ONSELECTSTART,
+ ONBEFORECUT,
+ REFERRERPOLICY,
+ REPEATDUR,
+ STRETCHY,
+ SIZE,
+ HREFLANG,
+ XREF,
+ DRAGGABLE,
+ IMAGE_RENDERING,
+ LONGDESC,
+ ORIGIN,
+ TARGETY,
+ MATHBACKGROUND,
+ MATHSIZE,
+ PATH,
+ ACTIVE,
+ DIVISOR,
+ MANIFEST,
+ RADIUS,
+ TABINDEX,
+ LINK,
+ MASK,
+ MARKERUNITS,
+ CELLPADDING,
+ FILL_OPACITY,
+ REPLACE,
+ TABLEVALUES,
+ FRAMEBORDER,
+ FORM,
+ SUMMARY,
+ ALINK,
+ KERNELMATRIX,
+ OPEN,
+ POINTER_EVENTS,
+ POINTSATZ,
+ TRANSFORM,
+ XLINK_TITLE,
+ XMLNS,
+ AUTOPLAY,
+ AUTOCAPITALIZE,
+ COLOR_INTERPOLATION,
+ EXPONENT,
+ NUMOCTAVES,
+ ONMOUSEENTER,
+ ONZOOM,
+ ONMOUSEUP,
+ ONMOUSEDOWN,
+ STROKE_DASHARRAY,
+ STROKE,
+ COMPACT,
+ CLIPPATHUNITS,
+ GLYPH_ORIENTATION_HORIZONTAL,
+ LOOP,
+ SHAPE_RENDERING,
+ STOP_COLOR,
+ ABBR,
+ COORDS,
+ NOHREF,
+ ONDRAGEND,
+ OPERATOR,
+ STARTOFFSET,
+ BIAS,
+ COLS,
+ CLASS,
+ LOWSRC,
+ PRESERVEALPHA,
+ ROWS,
+ ALTTEXT,
+ CONTEXTMENU,
+ FILTER,
+ FONT_STYLE,
+ FONT_SIZE_ADJUST,
+ KEYTIMES,
+ RT,
+ PATTERNTRANSFORM,
+ RESTART,
+ TEXT_DECORATION,
+ WRITING_MODE,
+ COLUMNLINES,
+ GROUPALIGN,
+ REQUIRED,
+ VALUES,
+ VIEWTARGET,
+ FX,
+ CY,
REFY,
ALT,
DUR,
@@ -1511,7 +1513,8 @@ public final class AttributeName
SHADOWROOTMODE,
SHADOWROOTREFERENCETARGET,
SHADOWROOTSERIALIZABLE,
- STDDEVIATION,
+ SHADOWROOTSLOTASSIGNMENT,
+ SANDBOX,
SHADOWROOTDELEGATESFOCUS,
ACCENTUNDER,
ACCESSKEY,
@@ -1707,262 +1710,263 @@ public final class AttributeName
RX,
BY,
DY,
- };
- private final static int[] ATTRIBUTE_HASHES = {
- 1854497003,
- 1747939528,
- 1941454586,
- 1681174213,
- 1776114564,
- 1915025672,
- 2001669450,
- 1680165421,
- 1721347639,
- 1754792749,
- 1805715716,
- 1898428101,
- 1922699851,
- 1983347764,
- 2016787611,
- 71827457,
- 1680282148,
- 1689324870,
- 1740045858,
- 1752985897,
- 1756471625,
- 1788254870,
- 1823580230,
- 1874698443,
- 1906423097,
- 1921894426,
- 1933145837,
- 1972863609,
- 1991392548,
- 2007019632,
- 2060302634,
- 57205395,
- 911736834,
- 1680181996,
- 1680368221,
- 1685882101,
- 1704526375,
- 1734182982,
- 1747299630,
- 1749027145,
- 1754606246,
- 1754907227,
- 1757053236,
- 1785174319,
- 1804036350,
- 1816144023,
- 1853862084,
- 1867620412,
- 1884343396,
- 1905628916,
- 1910441627,
- 1916278099,
- 1922567078,
- 1924585254,
- 1937777860,
- 1966439670,
- 1974849131,
- 1988132214,
- 2000162011,
- 2004199576,
- 2009071951,
- 2024616088,
- 2081947650,
- 53006051,
- 60345635,
- 885522434,
- 1680095865,
- 1680165533,
- 1680229115,
- 1680343801,
- 1680437801,
- 1682440540,
- 1687620127,
- 1692408896,
- 1716623661,
- 1731048742,
- 1739583824,
- 1740130375,
- 1747792072,
- 1748552744,
- 1749856356,
- 1754214628,
- 1754645079,
- 1754858317,
- 1756190926,
- 1756804936,
- 1767875272,
- 1782518297,
- 1786821704,
- 1791070327,
- 1804235064,
- 1814656326,
- 1820928104,
- 1824377064,
- 1854464212,
- 1865910347,
- 1873590471,
- 1884142379,
- 1891186903,
- 1903612236,
- 1906408542,
- 1908462185,
- 1910503637,
- 1915394254,
- 1917327080,
- 1922413292,
- 1922671417,
- 1924462384,
- 1932870919,
- 1934917372,
- 1941409583,
- 1965349396,
- 1972196486,
- 1972909592,
- 1982640164,
- 1983461061,
- 1990062797,
- 1999273799,
- 2001578182,
- 2001814704,
- 2005925890,
- 2008084807,
- 2010452700,
- 2018908874,
- 2026741958,
- 2066743298,
- 2089811970,
- 52488851,
- 55077603,
- 59825747,
- 68157441,
- 878182402,
- 901775362,
- 1037879561,
- 1680159327,
- 1680165437,
- 1680165692,
- 1680198203,
- 1680231247,
- 1680315086,
- 1680345965,
- 1680413393,
- 1680452349,
- 1681879063,
- 1683805446,
- 1686731997,
- 1689048326,
- 1689839946,
- 1699185409,
- 1714763319,
- 1721189160,
- 1723336432,
- 1733874289,
- 1736416327,
- 1739927860,
- 1740096054,
+ RY,
+ };
+ private final static int[] ATTRIBUTE_HASHES = {
+ 1854474395,
+ 1747839118,
+ 1941438085,
+ 1681174213,
+ 1772032615,
+ 1910527802,
+ 2001634459,
+ 1680165421,
+ 1721347639,
+ 1754647353,
+ 1804978712,
+ 1894552650,
+ 1922679386,
+ 1983266615,
+ 2015950026,
+ 71827457,
+ 1680282148,
+ 1689324870,
+ 1740045858,
+ 1751679545,
+ 1756302628,
+ 1787193500,
+ 1822002839,
+ 1874261045,
+ 1906419001,
+ 1917953597,
+ 1932986153,
+ 1972744939,
+ 1991021879,
+ 2006516551,
+ 2026975253,
+ 57205395,
+ 911736834,
+ 1680181996,
+ 1680368221,
+ 1685882101,
+ 1704526375,
+ 1734182982,
1742183484,
+ 1748869205,
+ 1754546894,
+ 1754872618,
+ 1756874572,
+ 1785051290,
+ 1801312388,
+ 1814986837,
+ 1825677514,
+ 1867448617,
+ 1884267068,
+ 1903759600,
+ 1909819252,
+ 1916210285,
+ 1922470745,
+ 1924570799,
+ 1935597338,
+ 1965561677,
+ 1972962123,
+ 1987410233,
+ 2000125224,
+ 2001898808,
+ 2008408414,
+ 2023146024,
+ 2075005220,
+ 53006051,
+ 60345635,
+ 885522434,
+ 1680095865,
+ 1680165533,
+ 1680229115,
+ 1680343801,
+ 1680437801,
+ 1682440540,
+ 1687620127,
+ 1692408896,
+ 1716623661,
+ 1731048742,
+ 1739583824,
+ 1740119884,
1747446838,
- 1747839118,
1748306996,
- 1748869205,
1749399124,
- 1751679545,
1753297133,
- 1754546894,
1754643237,
- 1754647353,
1754798923,
- 1754872618,
1754958648,
- 1756302628,
1756737685,
- 1756874572,
1765800271,
- 1772032615,
1780975314,
- 1785051290,
1786740932,
- 1787193500,
1790814502,
- 1801312388,
1804069019,
- 1804978712,
1814558026,
- 1814986837,
1820262641,
- 1822002839,
1823841492,
- 1825677514,
1854302364,
- 1854474395,
1864698185,
- 1867448617,
1872034503,
- 1874261045,
1881750231,
- 1884267068,
1889633006,
- 1894552650,
1900548965,
- 1903759600,
1905754853,
- 1906419001,
1907701479,
- 1909819252,
1910441773,
- 1910527802,
1915295948,
- 1916210285,
1916337499,
- 1917953597,
1922319046,
- 1922470745,
1922665052,
- 1922679386,
1924206934,
- 1924570799,
1924738716,
- 1932986153,
1933508940,
- 1935597338,
1941253366,
- 1941438085,
1942026440,
- 1965561677,
1966454567,
- 1972744939,
1972904522,
- 1972962123,
1980235778,
- 1983266615,
1983416119,
- 1987410233,
1988788535,
- 1991021879,
1991643278,
- 2000125224,
2001210183,
- 2001634459,
2001710299,
- 2001898808,
2004957380,
- 2006516551,
2007064812,
- 2008408414,
2009141482,
- 2015950026,
2016910397,
- 2023146024,
2024763702,
- 2026975253,
2065170434,
- 2075005220,
2083520514,
+ 52488851,
+ 55077603,
+ 59825747,
+ 68157441,
+ 878182402,
+ 901775362,
+ 1037879561,
+ 1680159327,
+ 1680165437,
+ 1680165692,
+ 1680198203,
+ 1680231247,
+ 1680315086,
+ 1680345965,
+ 1680413393,
+ 1680452349,
+ 1681879063,
+ 1683805446,
+ 1686731997,
+ 1689048326,
+ 1689839946,
+ 1699185409,
+ 1714763319,
+ 1721189160,
+ 1723336432,
+ 1733874289,
+ 1736416327,
+ 1739927860,
+ 1740096054,
+ 1740185423,
+ 1747299630,
+ 1747792072,
+ 1747939528,
+ 1748552744,
+ 1749027145,
+ 1749856356,
+ 1752985897,
+ 1754214628,
+ 1754606246,
+ 1754645079,
+ 1754792749,
+ 1754858317,
+ 1754907227,
+ 1756190926,
+ 1756471625,
+ 1756804936,
+ 1757053236,
+ 1767875272,
+ 1776114564,
+ 1782518297,
+ 1785174319,
+ 1786821704,
+ 1788254870,
+ 1791070327,
+ 1804036350,
+ 1804235064,
+ 1805715716,
+ 1814656326,
+ 1816144023,
+ 1820928104,
+ 1823580230,
+ 1824377064,
+ 1853862084,
+ 1854464212,
+ 1854497003,
+ 1865910347,
+ 1867620412,
+ 1873590471,
+ 1874698443,
+ 1884142379,
+ 1884343396,
+ 1891186903,
+ 1898428101,
+ 1903612236,
+ 1905628916,
+ 1906408542,
+ 1906423097,
+ 1908462185,
+ 1910441627,
+ 1910503637,
+ 1915025672,
+ 1915394254,
+ 1916278099,
+ 1917327080,
+ 1921894426,
+ 1922413292,
+ 1922567078,
+ 1922671417,
+ 1922699851,
+ 1924462384,
+ 1924585254,
+ 1932870919,
+ 1933145837,
+ 1934917372,
+ 1937777860,
+ 1941409583,
+ 1941454586,
+ 1965349396,
+ 1966439670,
+ 1972196486,
+ 1972863609,
+ 1972909592,
+ 1974849131,
+ 1982640164,
+ 1983347764,
+ 1983461061,
+ 1988132214,
+ 1990062797,
+ 1991392548,
+ 1999273799,
+ 2000162011,
+ 2001578182,
+ 2001669450,
+ 2001814704,
+ 2004199576,
+ 2005925890,
+ 2007019632,
+ 2008084807,
+ 2009071951,
+ 2010452700,
+ 2016787611,
+ 2018908874,
+ 2024616088,
+ 2026741958,
+ 2060302634,
+ 2066743298,
+ 2081947650,
2091784484,
50917059,
52489043,
@@ -2021,7 +2025,8 @@ public final class AttributeName
1739914974,
1739962169,
1740045862,
- 1740119884,
+ 1740109544,
+ 1740130375,
1740222216,
1747295467,
1747309881,
@@ -2217,5 +2222,6 @@ public final class AttributeName
2073034754,
2081423362,
2082471938,
+ 2089811970,
};
}
=====================================
src/nu/validator/htmlparser/impl/ElementName.java
=====================================
@@ -1424,7 +1424,11 @@ TreeBuilder.OTHER);
public static final ElementName SELECT = new ElementName("select", "select",
// CPPONLY: NS_NewHTMLSelectElement,
// CPPONLY: NS_NewSVGUnknownElement,
-TreeBuilder.SELECT | SPECIAL);
+TreeBuilder.SELECT | SPECIAL | SCOPING);
+public static final ElementName SELECTEDCONTENT = new ElementName("selectedcontent", "selectedcontent",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
public static final ElementName SLOT = new ElementName("slot", "slot",
// CPPONLY: NS_NewHTMLSlotElement,
// CPPONLY: NS_NewSVGUnknownElement,
@@ -1484,18 +1488,18 @@ TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_
private final static @NoLength ElementName[] ELEMENT_NAMES = {
FIGCAPTION,
CITE,
-FRAMESET,
+FEOFFSET,
H1,
CLIPPATH,
METER,
-RADIALGRADIENT,
+SELECT,
B,
BGSOUND,
SOURCE,
DL,
RP,
-NOFRAMES,
-MTEXT,
+PROGRESS,
+NOSCRIPT,
VIEW,
DIV,
G,
@@ -1507,10 +1511,10 @@ TEXTPATH,
ANIMATETRANSFORM,
SECTION,
HR,
-CANVAS,
-BASEFONT,
-FEDISTANTLIGHT,
-OUTPUT,
+DEFS,
+DATALIST,
+FONT,
+PLAINTEXT,
TFOOT,
FEMORPHOLOGY,
COL,
@@ -1533,14 +1537,14 @@ OPTION,
VIDEO,
BR,
FOOTER,
-TR,
-DETAILS,
-DT,
-FOREIGNOBJECT,
-FESPOTLIGHT,
-INPUT,
-RT,
-TT,
+ADDRESS,
+MS,
+APPLET,
+FIELDSET,
+FEPOINTLIGHT,
+LINEARGRADIENT,
+OBJECT,
+RECT,
SLOT,
MENU,
FECONVOLVEMATRIX,
@@ -1585,23 +1589,23 @@ SAMP,
ANIMATECOLOR,
FECOMPONENTTRANSFER,
HEADER,
-NOBR,
-ADDRESS,
-DEFS,
-MS,
-PROGRESS,
-APPLET,
-DATALIST,
-FIELDSET,
-FEOFFSET,
-FEPOINTLIGHT,
-FONT,
-LINEARGRADIENT,
-NOSCRIPT,
-OBJECT,
-PLAINTEXT,
-RECT,
-SELECT,
+TR,
+CANVAS,
+DETAILS,
+NOFRAMES,
+DT,
+BASEFONT,
+FOREIGNOBJECT,
+FRAMESET,
+FESPOTLIGHT,
+FEDISTANTLIGHT,
+INPUT,
+MTEXT,
+RT,
+OUTPUT,
+TT,
+RADIALGRADIENT,
+SELECTEDCONTENT,
SCRIPT,
TEXT,
FEDROPSHADOW,
@@ -1689,22 +1693,23 @@ FEFUNCR,
FILTER,
FEGAUSSIANBLUR,
MARKER,
+NOBR,
};
private final static int[] ELEMENT_HASHES = {
1900845386,
1748359220,
-2001349720,
+2001349736,
876609538,
1798686984,
1971465813,
-2007781534,
+2008125638,
59768833,
1730965751,
1756474198,
1864368130,
1938817026,
-1988763672,
-2005324101,
+1990037800,
+2005719336,
2060065124,
52490899,
62390273,
@@ -1716,10 +1721,10 @@ private final static int[] ELEMENT_HASHES = {
1881498736,
1907661127,
1967128578,
-1982935782,
-1999397992,
-2001392798,
-2006329158,
+1983533124,
+2000525512,
+2001495140,
+2006896969,
2008851557,
2085266636,
51961587,
@@ -1742,14 +1747,14 @@ private final static int[] ELEMENT_HASHES = {
1925844629,
1963982850,
1967795958,
-1973420034,
-1983633431,
-1998585858,
-2001309869,
-2001392795,
-2003183333,
-2005925890,
-2006974466,
+1982173479,
+1986527234,
+1998724870,
+2001349704,
+2001392796,
+2004635806,
+2006028454,
+2007601444,
2008325940,
2021937364,
2068523856,
@@ -1794,23 +1799,23 @@ private final static int[] ELEMENT_HASHES = {
1965334268,
1967788867,
1968836118,
-1971938532,
-1982173479,
-1983533124,
-1986527234,
-1990037800,
-1998724870,
-2000525512,
-2001349704,
-2001349736,
-2001392796,
-2001495140,
-2004635806,
-2005719336,
-2006028454,
-2006896969,
-2007601444,
-2008125638,
+1973420034,
+1982935782,
+1983633431,
+1988763672,
+1998585858,
+1999397992,
+2001309869,
+2001349720,
+2001392795,
+2001392798,
+2003183333,
+2005324101,
+2005925890,
+2006329158,
+2006974466,
+2007781534,
+2008305999,
2008340774,
2008994116,
2051837468,
@@ -1898,5 +1903,6 @@ private final static int[] ELEMENT_HASHES = {
1967795910,
1968053806,
1971461414,
+1971938532,
};
}
=====================================
src/nu/validator/htmlparser/impl/Portability.java
=====================================
@@ -31,6 +31,7 @@ import nu.validator.htmlparser.common.Interner;
public final class Portability {
+ // [NOCPP[
public static int checkedAdd(int a, int b) throws SAXException {
// This can't be translated code, because in C++ signed integer overflow is UB, so the below code would be wrong.
assert a >= 0;
@@ -41,6 +42,7 @@ public final class Portability {
}
return sum;
}
+ // ]NOCPP]
// Allocating methods
=====================================
src/nu/validator/htmlparser/impl/Tokenizer.java
=====================================
@@ -932,7 +932,7 @@ public class Tokenizer implements Locator, Locator2 {
// ]NOCPP]
- HtmlAttributes emptyAttributes() {
+ @Inline HtmlAttributes emptyAttributes() {
// [NOCPP[
if (newAttributesEachTime) {
return new HtmlAttributes(mappingLangToXmlLang);
@@ -944,7 +944,7 @@ public class Tokenizer implements Locator, Locator2 {
// ]NOCPP]
}
- @Inline private void appendCharRefBuf(char c) {
+ private void appendCharRefBuf(char c) {
// CPPONLY: assert charRefBufLen < charRefBuf.length:
// CPPONLY: "RELEASE: Attempted to overrun charRefBuf!";
charRefBuf[charRefBufLen++] = c;
@@ -983,11 +983,8 @@ public class Tokenizer implements Locator, Locator2 {
* the UTF-16 code unit to append
*/
@Inline private void appendStrBuf(char c) {
- // CPPONLY: assert strBufLen < strBuf.length: "Previous buffer length insufficient.";
// CPPONLY: if (strBufLen == strBuf.length) {
- // CPPONLY: if (!EnsureBufferSpace(1)) {
- // CPPONLY: assert false: "RELEASE: Unable to recover from buffer reallocation failure";
- // CPPONLY: } // TODO: Add telemetry when outer if fires but inner does not
+ // CPPONLY: EnsureBufferSpaceShouldNeverHappen(1);
// CPPONLY: }
strBuf[strBufLen++] = c;
}
@@ -1000,9 +997,22 @@ public class Tokenizer implements Locator, Locator2 {
*
* @return the buffer as a string
*/
- protected String strBufToString() {
+ @Inline protected String strBufToString() {
+ // CPPONLY: String digitAtom = TryAtomizeForSingleDigit();
+ // CPPONLY: if (digitAtom) {
+ // CPPONLY: return digitAtom;
+ // CPPONLY: }
+ // CPPONLY:
+ // CPPONLY: boolean maybeAtomize = false;
+ // CPPONLY: if (!newAttributesEachTime) {
+ // CPPONLY: if (attributeName == AttributeName.CLASS ||
+ // CPPONLY: attributeName == AttributeName.TYPE) {
+ // CPPONLY: maybeAtomize = true;
+ // CPPONLY: }
+ // CPPONLY: }
+ // CPPONLY:
String str = Portability.newStringFromBuffer(strBuf, 0, strBufLen
- // CPPONLY: , tokenHandler, !newAttributesEachTime && attributeName == AttributeName.CLASS
+ // CPPONLY: , tokenHandler, maybeAtomize
);
clearStrBufAfterUse();
return str;
@@ -1014,7 +1024,7 @@ public class Tokenizer implements Locator, Locator2 {
*
* @return the buffer as local name
*/
- private void strBufToDoctypeName() {
+ @Inline private void strBufToDoctypeName() {
doctypeName = Portability.newLocalNameFromBuffer(strBuf, strBufLen, interner);
clearStrBufAfterUse();
}
@@ -1025,7 +1035,7 @@ public class Tokenizer implements Locator, Locator2 {
* @throws SAXException
* if the token handler threw
*/
- private void emitStrBuf() throws SAXException {
+ @Inline private void emitStrBuf() throws SAXException {
if (strBufLen > 0) {
tokenHandler.characters(strBuf, 0, strBufLen);
clearStrBufAfterUse();
@@ -1094,13 +1104,12 @@ public class Tokenizer implements Locator, Locator2 {
// ]NOCPP]
}
- private void appendStrBuf(@NoLength char[] buffer, int offset, int length) throws SAXException {
- int newLen = Portability.checkedAdd(strBufLen, length);
- // CPPONLY: assert newLen <= strBuf.length: "Previous buffer length insufficient.";
+ @Inline private void appendStrBuf(@NoLength char[] buffer, int offset, int length) throws SAXException {
+ // Years of crash stats have shown that the this addition doesn't overflow, as it logically
+ // shouldn't.
+ int newLen = strBufLen + length;
// CPPONLY: if (strBuf.length < newLen) {
- // CPPONLY: if (!EnsureBufferSpace(length)) {
- // CPPONLY: assert false: "RELEASE: Unable to recover from buffer reallocation failure";
- // CPPONLY: } // TODO: Add telemetry when outer if fires but inner does not
+ // CPPONLY: EnsureBufferSpaceShouldNeverHappen(length);
// CPPONLY: }
System.arraycopy(buffer, offset, strBuf, strBufLen, length);
strBufLen = newLen;
@@ -1455,12 +1464,6 @@ public class Tokenizer implements Locator, Locator2 {
*/
int pos = start - 1;
- /**
- * The index of the first <code>char</code> in <code>buf</code> that is
- * part of a coalesced run of character tokens or
- * <code>Integer.MAX_VALUE</code> if there is not a current run being
- * coalesced.
- */
switch (state) {
case DATA:
case RCDATA:
@@ -1486,19 +1489,24 @@ public class Tokenizer implements Locator, Locator2 {
break;
}
- /**
- * The number of <code>char</code>s in <code>buf</code> that have
- * meaning. (The rest of the array is garbage and should not be
- * examined.)
- */
// CPPONLY: if (mViewSource) {
// CPPONLY: mViewSource.SetBuffer(buffer);
- // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: if (htmlaccelEnabled()) {
+ // CPPONLY: pos = StateLoopViewSourceSIMD(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: } else {
+ // CPPONLY: pos = StateLoopViewSourceALU(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: }
// CPPONLY: mViewSource.DropBuffer((pos == buffer.getEnd()) ? pos : pos + 1);
// CPPONLY: } else if (tokenHandler.WantsLineAndColumn()) {
- // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: if (htmlaccelEnabled()) {
+ // CPPONLY: pos = StateLoopLineColSIMD(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: } else {
+ // CPPONLY: pos = StateLoopLineColALU(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: }
+ // CPPONLY: } else if (htmlaccelEnabled()) {
+ // CPPONLY: pos = StateLoopFastestSIMD(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
// CPPONLY: } else {
- // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: pos = StateLoopFastestALU(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
// CPPONLY: }
// [NOCPP[
pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState,
@@ -1547,7 +1555,7 @@ public class Tokenizer implements Locator, Locator2 {
}
// ]NOCPP]
- @SuppressWarnings("unused") private int stateLoop(int state, char c,
+ @SuppressWarnings("unused") @Inline private int stateLoop(int state, char c,
int pos, @NoLength char[] buf, boolean reconsume, int returnState,
int endPos) throws SAXException {
boolean reportedConsecutiveHyphens = false;
@@ -1626,7 +1634,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementData(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -2201,7 +2213,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementAttributeValueDoubleQuoted(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -2698,7 +2714,11 @@ public class Tokenizer implements Locator, Locator2 {
// CPPONLY: MOZ_FALLTHROUGH;
case COMMENT:
commentloop: for (;;) {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementComment(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -3194,7 +3214,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementCdataSection(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -3281,7 +3305,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementAttributeValueSingleQuoted(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -3893,7 +3921,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementPlaintext(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -4005,7 +4037,12 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // RCDATA and DATA have the same set of characters that they are indifferent to, hence accelerateData.
+ // CPPONLY: pos += accelerateAdvancementData(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -4056,7 +4093,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementRawtext(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -4340,7 +4381,12 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // Using `accelerateAdvancementRawtext`, because this states has the same characters of interest as RAWTEXT.
+ // CPPONLY: pos += accelerateAdvancementRawtext(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -4536,7 +4582,11 @@ public class Tokenizer implements Locator, Locator2 {
if (reconsume) {
reconsume = false;
} else {
- if (++pos == endPos) {
+ ++pos;
+ // Perhaps at some point, it will be appropriate to do SIMD in Java, but not today.
+ // The line below advances pos by some number of code units that this state is indifferent to.
+ // CPPONLY: pos += accelerateAdvancementScriptDataEscaped(buf, pos, endPos);
+ if (pos == endPos) {
break stateloop;
}
c = checkChar(buf, pos);
@@ -6348,24 +6398,24 @@ public class Tokenizer implements Locator, Locator2 {
forceQuirks = false;
}
- private void adjustDoubleHyphenAndAppendToStrBufCarriageReturn()
+ @Inline private void adjustDoubleHyphenAndAppendToStrBufCarriageReturn()
throws SAXException {
silentCarriageReturn();
adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
}
- private void adjustDoubleHyphenAndAppendToStrBufLineFeed()
+ @Inline private void adjustDoubleHyphenAndAppendToStrBufLineFeed()
throws SAXException {
silentLineFeed();
adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
}
- private void appendStrBufLineFeed() {
+ @Inline private void appendStrBufLineFeed() {
silentLineFeed();
appendStrBuf('\n');
}
- private void appendStrBufCarriageReturn() {
+ @Inline private void appendStrBufCarriageReturn() {
silentCarriageReturn();
appendStrBuf('\n');
}
@@ -6383,7 +6433,7 @@ public class Tokenizer implements Locator, Locator2 {
// ]NOCPP]
- private void emitCarriageReturn(@NoLength char[] buf, int pos)
+ @Inline private void emitCarriageReturn(@NoLength char[] buf, int pos)
throws SAXException {
silentCarriageReturn();
flushChars(buf, pos);
@@ -6412,7 +6462,7 @@ public class Tokenizer implements Locator, Locator2 {
cstart = pos + 1;
}
- private void setAdditionalAndRememberAmpersandLocation(char add) {
+ @Inline private void setAdditionalAndRememberAmpersandLocation(char add) {
additional = add;
// [NOCPP[
ampersandLocation = new LocatorImpl(this);
@@ -7077,7 +7127,7 @@ public class Tokenizer implements Locator, Locator2 {
* happened in a non-text context, this method turns that deferred suspension
* request into an immediately-pending suspension request.
*/
- private void suspendIfRequestedAfterCurrentNonTextToken() {
+ @Inline private void suspendIfRequestedAfterCurrentNonTextToken() {
if (suspendAfterCurrentNonTextToken) {
suspendAfterCurrentNonTextToken = false;
shouldSuspend = true;
@@ -7221,7 +7271,7 @@ public class Tokenizer implements Locator, Locator2 {
* @param val
* @throws SAXException
*/
- private void emitOrAppendTwo(@Const @NoLength char[] val, int returnState)
+ @Inline private void emitOrAppendTwo(@Const @NoLength char[] val, int returnState)
throws SAXException {
if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
appendStrBuf(val[0]);
@@ -7231,7 +7281,7 @@ public class Tokenizer implements Locator, Locator2 {
}
}
- private void emitOrAppendOne(@Const @NoLength char[] val, int returnState)
+ @Inline private void emitOrAppendOne(@Const @NoLength char[] val, int returnState)
throws SAXException {
if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
appendStrBuf(val[0]);
@@ -7268,7 +7318,7 @@ public class Tokenizer implements Locator, Locator2 {
}
}
- public void requestSuspension() {
+ @Inline public void requestSuspension() {
shouldSuspend = true;
}
@@ -7311,7 +7361,7 @@ public class Tokenizer implements Locator, Locator2 {
// ]NOCPP]
- public boolean isInDataState() {
+ @Inline public boolean isInDataState() {
return (stateSave == DATA);
}
=====================================
src/nu/validator/htmlparser/impl/TreeBuilder.java
=====================================
@@ -226,12 +226,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// no fall-through
- private static final int IN_SELECT_IN_TABLE = 10;
-
- private static final int IN_SELECT = 11;
-
- // no fall-through
-
private static final int AFTER_BODY = 12;
// no fall-through
@@ -952,9 +946,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
* current node.
*/
break charactersloop;
- case IN_SELECT:
- case IN_SELECT_IN_TABLE:
- break charactersloop;
case IN_TABLE:
case IN_TABLE_BODY:
case IN_ROW:
@@ -1166,9 +1157,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
mode = IN_TABLE;
i--;
continue;
- case IN_SELECT:
- case IN_SELECT_IN_TABLE:
- break charactersloop;
case AFTER_BODY:
errNonSpaceAfterBody();
fatal();
@@ -1334,8 +1322,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case IN_TABLE_BODY:
case IN_ROW:
case IN_TABLE:
- case IN_SELECT_IN_TABLE:
- case IN_SELECT:
case IN_COLUMN_GROUP:
case FRAMESET_OK:
case IN_CAPTION:
@@ -1531,12 +1517,19 @@ public abstract class TreeBuilder<T> implements TokenHandler,
if (!(group == FONT && !(attributes.contains(AttributeName.COLOR)
|| attributes.contains(AttributeName.FACE) || attributes.contains(AttributeName.SIZE)))) {
errHtmlStartTagInForeignContext(name);
- if (!fragment) {
- while (!isSpecialParentInForeign(stack[currentPtr])) {
- popForeign(-1, -1);
- }
+ // Pop until we reach an HTML namespace element,
+ // HTML integration point, or MathML text integration point.
+ // In fragment case, stop before popping the context element.
+ while (currentPtr > 0 && !isSpecialParentInForeign(stack[currentPtr])) {
+ popForeign(-1, -1);
+ }
+ if (currentPtr > 0 || isSpecialParentInForeign(stack[currentPtr])) {
+ // Popped to an HTML element or integration point
continue starttagloop;
- } // else fall thru
+ }
+ // In fragment case with foreign context, fall through
+ // to let switch(mode) handle the token in HTML namespace
+ break;
}
// CPPONLY: MOZ_FALLTHROUGH;
default:
@@ -2163,6 +2156,25 @@ public abstract class TreeBuilder<T> implements TokenHandler,
break starttagloop;
case HR:
implicitlyCloseP();
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "A start tag whose tag name is "hr""
+ // "If the stack of open elements has a select element in scope:"
+ if (findLastInScope("select") != TreeBuilder.NOT_FOUND_ON_STACK) {
+ // "1. Generate implied end tags."
+ generateImpliedEndTags();
+ // "2. If the stack of open elements has an option element
+ // in scope or has an optgroup element in scope, then
+ // this is a parse error."
+ if (errorHandler != null
+ && (findLastInScope("option") != TreeBuilder.NOT_FOUND_ON_STACK
+ || findLastInScope("optgroup") != TreeBuilder.NOT_FOUND_ON_STACK)) {
+ errUnclosedElementsImplied(
+ findLastInScope("option") != TreeBuilder.NOT_FOUND_ON_STACK
+ ? findLastInScope("option")
+ : findLastInScope("optgroup"),
+ name);
+ }
+ }
appendVoidElementToCurrentMayFoster(
elementName,
attributes);
@@ -2177,7 +2189,31 @@ public abstract class TreeBuilder<T> implements TokenHandler,
elementName = ElementName.IMG;
continue starttagloop;
case IMG:
+ reconstructTheActiveFormattingElements();
+ appendVoidElementToCurrentMayFoster(
+ elementName, attributes,
+ formPointer);
+ selfClosing = false;
+ // [NOCPP[
+ voidElement = true;
+ // ]NOCPP]
+ attributes = null; // CPP
+ break starttagloop;
case INPUT:
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "A start tag whose tag name is "input""
+ // "If the stack of open elements has a select element
+ // in scope:"
+ eltPos = findLastInScope("select");
+ if (eltPos != TreeBuilder.NOT_FOUND_ON_STACK) {
+ // "Parse error."
+ errStartTagWithSelectOpen(name);
+ // "Pop elements until a select element has been popped."
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ continue starttagloop;
+ }
reconstructTheActiveFormattingElements();
appendVoidElementToCurrentMayFoster(
elementName, attributes,
@@ -2228,31 +2264,100 @@ public abstract class TreeBuilder<T> implements TokenHandler,
attributes = null; // CPP
break starttagloop;
case SELECT:
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "A start tag whose tag name is "select""
+ // "If the parser was created as part of the HTML fragment
+ // parsing algorithm and the context element is a select
+ // element:"
+ if (fragment && "select" == contextName) {
+ // "Parse error. Ignore the token."
+ errStartSelectWhereEndSelectExpected();
+ break starttagloop;
+ }
+ // "Otherwise, if the stack of open elements has a select
+ // element in scope:"
+ eltPos = findLastInScope(name);
+ if (eltPos != TreeBuilder.NOT_FOUND_ON_STACK) {
+ // "Parse error."
+ errStartSelectWhereEndSelectExpected();
+ // "Pop elements until a select element has been popped."
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break starttagloop;
+ }
+ // "Otherwise:"
+ // "Reconstruct the active formatting elements, if any."
reconstructTheActiveFormattingElements();
+ // "Insert an HTML element for the token."
appendToCurrentNodeAndPushElementMayFoster(
elementName,
attributes, formPointer);
- switch (mode) {
- case IN_TABLE:
- case IN_CAPTION:
- case IN_COLUMN_GROUP:
- case IN_TABLE_BODY:
- case IN_ROW:
- case IN_CELL:
- mode = IN_SELECT_IN_TABLE;
- break;
- default:
- mode = IN_SELECT;
- break;
+ // "Set the frameset-ok flag to "not ok"."
+ framesetOk = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case OPTION:
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "A start tag whose tag name is "option""
+ // "If the stack of open elements has a select element in scope:"
+ if (findLastInScope("select") != TreeBuilder.NOT_FOUND_ON_STACK) {
+ // "1. Generate implied end tags except for optgroup elements."
+ generateImpliedEndTagsExceptFor("optgroup");
+ // "2. If the stack of open elements has an option element
+ // in scope, then this is a parse error."
+ if (errorHandler != null) {
+ int optionPos = findLastInScope("option");
+ if (optionPos != TreeBuilder.NOT_FOUND_ON_STACK) {
+ errUnclosedElementsImplied(optionPos, name);
+ }
+ }
+ } else {
+ // "Otherwise, if the current node is an option element,
+ // then pop the current node from the stack of open elements."
+ if (isCurrent("option")) {
+ pop();
+ }
}
+ // "Reconstruct the active formatting elements, if any."
+ reconstructTheActiveFormattingElements();
+ // "Insert an HTML element for the token."
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
attributes = null; // CPP
break starttagloop;
case OPTGROUP:
- case OPTION:
- if (isCurrent("option")) {
- pop();
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "A start tag whose tag name is "optgroup""
+ // "If the stack of open elements has a select element in scope:"
+ if (findLastInScope("select") != TreeBuilder.NOT_FOUND_ON_STACK) {
+ // "1. Generate implied end tags."
+ generateImpliedEndTags();
+ // "2. If the stack of open elements has an option element
+ // in scope or has an optgroup element in scope, then
+ // this is a parse error."
+ if (errorHandler != null) {
+ int optionPos = findLastInScope("option");
+ if (optionPos != TreeBuilder.NOT_FOUND_ON_STACK) {
+ errUnclosedElementsImplied(optionPos, name);
+ } else {
+ int optgroupPos = findLastInScope("optgroup");
+ if (optgroupPos != TreeBuilder.NOT_FOUND_ON_STACK) {
+ errUnclosedElementsImplied(optgroupPos, name);
+ }
+ }
+ }
+ } else {
+ // "Otherwise, if the current node is an option element,
+ // then pop the current node from the stack of open elements."
+ if (isCurrent("option")) {
+ pop();
+ }
}
+ // "Reconstruct the active formatting elements, if any."
reconstructTheActiveFormattingElements();
+ // "Insert an HTML element for the token."
appendToCurrentNodeAndPushElementMayFoster(
elementName,
attributes);
@@ -2322,14 +2427,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
attributes = null; // CPP
break starttagloop;
case CAPTION:
- case COL:
- case COLGROUP:
case TBODY_OR_THEAD_OR_TFOOT:
case TR:
case TD_OR_TH:
+ case COL:
+ case COLGROUP:
case FRAME:
case FRAMESET:
case HEAD:
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "A start tag whose tag name is one of: "caption", "col",
+ // "colgroup", "frame", "frameset", "head", "tbody", "td",
+ // "tfoot", "th", "thead", "tr""
errStrayStartTag(name);
break starttagloop;
case OUTPUT:
@@ -2507,111 +2616,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
mode = IN_TABLE;
continue;
}
- case IN_SELECT_IN_TABLE:
- switch (group) {
- case CAPTION:
- case TBODY_OR_THEAD_OR_TFOOT:
- case TR:
- case TD_OR_TH:
- case TABLE:
- errStartTagWithSelectOpen(name);
- eltPos = findLastInTableScope("select");
- if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
- assert fragment;
- break starttagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
- }
- while (currentPtr >= eltPos) {
- pop();
- }
- resetTheInsertionMode();
- continue;
- default:
- // fall through to IN_SELECT
- }
- // CPPONLY: MOZ_FALLTHROUGH;
- case IN_SELECT:
- switch (group) {
- case HTML:
- errStrayStartTag(name);
- if (!fragment) {
- addAttributesToHtml(attributes);
- attributes = null; // CPP
- }
- break starttagloop;
- case OPTION:
- if (isCurrent("option")) {
- pop();
- }
- appendToCurrentNodeAndPushElement(
- elementName,
- attributes);
- attributes = null; // CPP
- break starttagloop;
- case OPTGROUP:
- if (isCurrent("option")) {
- pop();
- }
- if (isCurrent("optgroup")) {
- pop();
- }
- appendToCurrentNodeAndPushElement(
- elementName,
- attributes);
- attributes = null; // CPP
- break starttagloop;
- case SELECT:
- errStartSelectWhereEndSelectExpected();
- eltPos = findLastInTableScope(name);
- if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
- assert fragment;
- errNoSelectInTableScope();
- break starttagloop;
- } else {
- while (currentPtr >= eltPos) {
- pop();
- }
- resetTheInsertionMode();
- break starttagloop;
- }
- case INPUT:
- case TEXTAREA:
- errStartTagWithSelectOpen(name);
- eltPos = findLastInTableScope("select");
- if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
- assert fragment;
- break starttagloop;
- }
- while (currentPtr >= eltPos) {
- pop();
- }
- resetTheInsertionMode();
- continue;
- case SCRIPT:
- startTagScriptInHead(elementName, attributes);
- attributes = null; // CPP
- break starttagloop;
- case TEMPLATE:
- startTagTemplateInHead(elementName, attributes);
- attributes = null; // CPP
- break starttagloop;
- case HR:
- if (isCurrent("option")) {
- pop();
- }
- if (isCurrent("optgroup")) {
- pop();
- }
- appendVoidElementToCurrent(elementName, attributes);
- selfClosing = false;
- // [NOCPP[
- voidElement = true;
- // ]NOCPP]
- attributes = null; // CPP
- break starttagloop;
- default:
- errStrayStartTag(name);
- break starttagloop;
- }
case AFTER_BODY:
switch (group) {
case HTML:
@@ -2992,9 +2996,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
boolean shadowRootIsClonable = attributes.contains(AttributeName.SHADOWROOTCLONABLE);
boolean shadowRootIsSerializable = attributes.contains(AttributeName.SHADOWROOTSERIALIZABLE);
boolean shadowRootDelegatesFocus = attributes.contains(AttributeName.SHADOWROOTDELEGATESFOCUS);
+ boolean shadowRootCustomElementRegistry = attributes.contains(AttributeName.SHADOWROOTCUSTOMELEMENTREGISTRY);
String shadowRootReferenceTarget = attributes.getValue(AttributeName.SHADOWROOTREFERENCETARGET);
+ String shadowRootSlotAssignment = attributes.getValue(AttributeName.SHADOWROOTSLOTASSIGNMENT);
- return getShadowRootFromHost(currentNode, templateNode, shadowRootMode, shadowRootIsClonable, shadowRootIsSerializable, shadowRootDelegatesFocus, shadowRootReferenceTarget);
+ return getShadowRootFromHost(currentNode, templateNode, shadowRootMode, shadowRootIsClonable, shadowRootIsSerializable, shadowRootDelegatesFocus, shadowRootCustomElementRegistry, shadowRootSlotAssignment, shadowRootReferenceTarget);
}
/**
@@ -3220,6 +3226,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
for (;;) {
if (eltPos == 0) {
assert fragment: "We can get this close to the root of the stack in foreign content only in the fragment case.";
+ // For </p> and </br>, continue to mode handling
+ // which will create implied start tags
+ if (group == P || group == BR) {
+ break; // break from inner loop, continue to switch(mode)
+ }
break endtagloop;
}
if (stack[eltPos].name == name) {
@@ -3513,7 +3524,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case PRE_OR_LISTING:
case FIELDSET:
case BUTTON:
+ case SELECT:
case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY:
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
+ // "An end tag whose tag name is one of: "address", "article",
+ // ..., "select", ..., "ul""
eltPos = findLastInScope(name);
if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
errStrayEndTag(name);
@@ -3564,12 +3579,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
eltPos = findLastInButtonScope("p");
if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
errNoElementToCloseButEndTagSeen("p");
- // XXX Can the 'in foreign' case happen anymore?
if (isInForeign()) {
errHtmlStartTagInForeignContext(name);
- // Check for currentPtr for the fragment
- // case.
- while (currentPtr >= 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+ // Pop foreign elements, but keep context element in fragment case
+ while (currentPtr > 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
pop();
}
}
@@ -3650,11 +3663,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case BR:
errEndTagBr();
if (isInForeign()) {
- // XXX can this happen anymore?
errHtmlStartTagInForeignContext(name);
- // Check for currentPtr for the fragment
- // case.
- while (currentPtr >= 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+ // Pop foreign elements, but keep context element in fragment case
+ while (currentPtr > 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
pop();
}
}
@@ -3677,7 +3688,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case IFRAME:
case NOEMBED: // XXX???
case NOFRAMES: // XXX??
- case SELECT:
case TABLE:
case TEXTAREA: // XXX??
errStrayEndTag(name);
@@ -3787,72 +3797,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
mode = IN_TABLE;
continue;
}
- case IN_SELECT_IN_TABLE:
- switch (group) {
- case CAPTION:
- case TABLE:
- case TBODY_OR_THEAD_OR_TFOOT:
- case TR:
- case TD_OR_TH:
- errEndTagSeenWithSelectOpen(name);
- if (findLastInTableScope(name) != TreeBuilder.NOT_FOUND_ON_STACK) {
- eltPos = findLastInTableScope("select");
- if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
- assert fragment;
- break endtagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
- }
- while (currentPtr >= eltPos) {
- pop();
- }
- resetTheInsertionMode();
- continue;
- } else {
- break endtagloop;
- }
- default:
- // fall through to IN_SELECT
- }
- // CPPONLY: MOZ_FALLTHROUGH;
- case IN_SELECT:
- switch (group) {
- case OPTION:
- if (isCurrent("option")) {
- pop();
- break endtagloop;
- } else {
- errStrayEndTag(name);
- break endtagloop;
- }
- case OPTGROUP:
- if (isCurrent("option")
- && "optgroup" == stack[currentPtr - 1].name) {
- pop();
- }
- if (isCurrent("optgroup")) {
- pop();
- } else {
- errStrayEndTag(name);
- }
- break endtagloop;
- case SELECT:
- eltPos = findLastInTableScope("select");
- if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
- assert fragment;
- errStrayEndTag(name);
- break endtagloop;
- }
- while (currentPtr >= eltPos) {
- pop();
- }
- resetTheInsertionMode();
- break endtagloop;
- case TEMPLATE:
- endTagTemplateInHead();
- break endtagloop;
- default:
- errStrayEndTag(name);
- break endtagloop;
- }
case AFTER_BODY:
switch (group) {
case HTML:
@@ -4312,23 +4256,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
return;
}
}
- if ("select" == name) {
- int ancestorIndex = i;
- while (ancestorIndex > 0) {
- StackNode<T> ancestor = stack[ancestorIndex--];
- if ("http://www.w3.org/1999/xhtml" == ancestor.ns) {
- if ("template" == ancestor.name) {
- break;
- }
- if ("table" == ancestor.name) {
- mode = IN_SELECT_IN_TABLE;
- return;
- }
- }
- }
- mode = IN_SELECT;
- return;
- } else if ("td" == name || "th" == name) {
+ if ("td" == name || "th" == name) {
mode = IN_CELL;
return;
} else if ("tr" == name) {
@@ -5089,6 +5017,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private void pop() throws SAXException {
StackNode<T> node = stack[currentPtr];
assert debugOnlyClearLastStackSlot();
+ if (node.getGroup() == OPTION) {
+ optionElementPopped(node.node);
+ }
currentPtr--;
elementPopped(node.ns, node.popName, node.node);
node.release(this);
@@ -5100,6 +5031,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
markMalformedIfScript(node.node);
}
assert debugOnlyClearLastStackSlot();
+ if (node.getGroup() == OPTION) {
+ optionElementPopped(node.node);
+ }
currentPtr--;
elementPopped(node.ns, node.popName, node.node);
node.release(this);
@@ -5108,6 +5042,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private void silentPop() throws SAXException {
StackNode<T> node = stack[currentPtr];
assert debugOnlyClearLastStackSlot();
+ assert node.getGroup() != OPTION;
currentPtr--;
node.release(this);
}
@@ -5115,6 +5050,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private void popOnEof() throws SAXException {
StackNode<T> node = stack[currentPtr];
assert debugOnlyClearLastStackSlot();
+ if (node.getGroup() == OPTION) {
+ optionElementPopped(node.node);
+ }
currentPtr--;
markMalformedIfScript(node.node);
elementPopped(node.ns, node.popName, node.node);
@@ -5443,6 +5381,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
T getShadowRootFromHost(T host, T template, String shadowRootMode,
boolean shadowRootIsClonable, boolean shadowRootIsSerializable, boolean shadowRootDelegatesFocus,
+ boolean shadowRootCustomElementRegistry, String shadowRootSlotAssignment,
String shadowRootReferenceTarget) {
return null;
}
@@ -5752,6 +5691,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
protected abstract void detachFromParent(T element) throws SAXException;
+ /**
+ * Called when an option element is popped from the stack.
+ *
+ * https://html.spec.whatwg.org/multipage/form-elements.html#maybe-clone-an-option-into-selectedcontent
+ * Implements "maybe clone an option into selectedcontent" for
+ * customizable select. Subclasses that support DOM operations
+ * should override this to perform the cloning.
+ */
+ protected void optionElementPopped(T option) throws SAXException {
+ // Default: no-op (streaming/SAX mode ignores cloning)
+ }
+
protected abstract boolean hasChildren(T element) throws SAXException;
protected abstract void appendElement(T child, T newParent)
@@ -6499,10 +6450,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
}
- private void errNoSelectInTableScope() throws SAXException {
- err("No \u201Cselect\u201D in table scope.");
- }
-
private void errStartSelectWhereEndSelectExpected() throws SAXException {
err("\u201Cselect\u201D start tag where end tag expected.");
}
@@ -6580,14 +6527,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
err("Saw an end tag after \u201Cbody\u201D had been closed.");
}
- private void errEndTagSeenWithSelectOpen(@Local String name) throws SAXException {
- if (errorHandler == null) {
- return;
- }
- errNoCheck("\u201C" + name
- + "\u201D end tag with \u201Cselect\u201D open.");
- }
-
private void errGarbageInColgroup() throws SAXException {
err("Garbage in \u201Ccolgroup\u201D fragment.");
}
=====================================
src/nu/validator/htmlparser/sax/SAXTreeBuilder.java
=====================================
@@ -34,6 +34,7 @@ import nu.validator.saxtree.Document;
import nu.validator.saxtree.DocumentFragment;
import nu.validator.saxtree.Element;
import nu.validator.saxtree.Node;
+import nu.validator.saxtree.NodeType;
import nu.validator.saxtree.ParentNode;
class SAXTreeBuilder extends TreeBuilder<Element> {
@@ -197,4 +198,140 @@ class SAXTreeBuilder extends TreeBuilder<Element> {
throws SAXException {
element.detach();
}
+
+ @Override
+ // https://html.spec.whatwg.org/multipage/form-elements.html#maybe-clone-an-option-into-selectedcontent
+ // Implements "maybe clone an option into selectedcontent"
+ protected void optionElementPopped(Element option) throws SAXException {
+ // Find the nearest ancestor <select> element
+ Element select = findAncestor(option, "select");
+ if (select == null) {
+ return;
+ }
+ if (select.getAttributes().getIndex("", "multiple") >= 0) {
+ return;
+ }
+
+ // Find the first <selectedcontent> descendant of <select>
+ Element selectedContent = findDescendant(select, "selectedcontent");
+ if (selectedContent == null) {
+ return;
+ }
+
+ // Check option selectedness
+ boolean hasSelected = option.getAttributes().getIndex("", "selected") >= 0;
+ if (!hasSelected && selectedContent.getFirstChild() != null) {
+ // Not the first option and no explicit selected attr
+ return;
+ }
+
+ // Clear selectedcontent children and deep-clone option children
+ selectedContent.clearChildren();
+ deepCloneChildren(option, selectedContent);
+ }
+
+ private Element findAncestor(Element element, String localName) {
+ ParentNode parent = element.getParentNode();
+ while (parent != null) {
+ if (parent.getNodeType() == NodeType.ELEMENT) {
+ Element elt = (Element) parent;
+ if (localName.equals(elt.getLocalName())
+ && "http://www.w3.org/1999/xhtml".equals(elt.getUri())) {
+ return elt;
+ }
+ }
+ if (parent instanceof Node) {
+ parent = ((Node) parent).getParentNode();
+ } else {
+ break;
+ }
+ }
+ return null;
+ }
+
+ private Element findDescendant(Element root, String localName) {
+ Node current = root.getFirstChild();
+ if (current == null) {
+ return null;
+ }
+ Node next;
+ for (;;) {
+ if (current.getNodeType() == NodeType.ELEMENT) {
+ Element elt = (Element) current;
+ if (localName.equals(elt.getLocalName())
+ && "http://www.w3.org/1999/xhtml".equals(
+ elt.getUri())) {
+ return elt;
+ }
+ }
+ if ((next = current.getFirstChild()) != null) {
+ current = next;
+ continue;
+ }
+ for (;;) {
+ if (current.getParentNode() == root) {
+ if ((next = current.getNextSibling()) != null) {
+ current = next;
+ break;
+ }
+ return null;
+ }
+ if ((next = current.getNextSibling()) != null) {
+ current = next;
+ break;
+ }
+ current = (Node) current.getParentNode();
+ }
+ }
+ }
+
+ private void deepCloneChildren(Element source, Element destination)
+ throws SAXException {
+ Node current = source.getFirstChild();
+ if (current == null) {
+ return;
+ }
+ ParentNode destParent = destination;
+ Node next;
+ outer:
+ for (;;) {
+ switch (current.getNodeType()) {
+ case ELEMENT:
+ Element srcElem = (Element) current;
+ Element cloneElem = new Element(null,
+ srcElem.getUri(),
+ srcElem.getLocalName(),
+ srcElem.getQName(),
+ srcElem.getAttributes(),
+ false,
+ srcElem.getPrefixMappings());
+ destParent.appendChild(cloneElem);
+ if ((next = srcElem.getFirstChild()) != null) {
+ destParent = cloneElem;
+ current = next;
+ continue outer;
+ }
+ break;
+ case CHARACTERS:
+ Characters srcChars = (Characters) current;
+ char[] buf = srcChars.getBuffer();
+ destParent.appendChild(
+ new Characters(null, buf, 0, buf.length));
+ break;
+ default:
+ break;
+ }
+ for (;;) {
+ if ((next = current.getNextSibling()) != null) {
+ current = next;
+ break;
+ }
+ if (current.getParentNode() == source) {
+ return;
+ }
+ current = (Node) current.getParentNode();
+ destParent = (ParentNode) destParent.getParentNode();
+ }
+ }
+ }
}
=====================================
src/nu/validator/htmlparser/xom/XOMTreeBuilder.java
=====================================
@@ -23,6 +23,8 @@
package nu.validator.htmlparser.xom;
+import java.util.ArrayDeque;
+
import nu.validator.htmlparser.common.DocumentMode;
import nu.validator.htmlparser.impl.CoalescingTreeBuilder;
import nu.validator.htmlparser.impl.HtmlAttributes;
@@ -348,4 +350,79 @@ class XOMTreeBuilder extends CoalescingTreeBuilder<Element> {
cachedTableIndex = -1;
cachedTable = null;
}
+
+ @Override
+ // https://html.spec.whatwg.org/multipage/form-elements.html#maybe-clone-an-option-into-selectedcontent
+ // Implements "maybe clone an option into selectedcontent"
+ protected void optionElementPopped(Element option) throws SAXException {
+ try {
+ // Find the nearest ancestor <select> element
+ ParentNode ancestor = option.getParent();
+ Element select = null;
+ while (ancestor != null) {
+ if (ancestor instanceof Element) {
+ Element elt = (Element) ancestor;
+ if ("select".equals(elt.getLocalName())
+ && "http://www.w3.org/1999/xhtml".equals(
+ elt.getNamespaceURI())) {
+ select = elt;
+ break;
+ }
+ }
+ ancestor = ancestor.getParent();
+ }
+ if (select == null) {
+ return;
+ }
+ if (select.getAttribute("multiple") != null) {
+ return;
+ }
+
+ // Find the first <selectedcontent> descendant of <select>
+ Element selectedContent = findSelectedContent(select);
+ if (selectedContent == null) {
+ return;
+ }
+
+ // Check option selectedness
+ boolean hasSelected = option.getAttribute("selected") != null;
+ if (!hasSelected && selectedContent.getChildCount() > 0) {
+ // Not the first option and no explicit selected attr
+ return;
+ }
+
+ // Clear selectedcontent children and deep-clone option children
+ selectedContent.removeChildren();
+ for (int i = 0; i < option.getChildCount(); i++) {
+ selectedContent.appendChild(option.getChild(i).copy());
+ }
+ } catch (XMLException e) {
+ fatal(e);
+ }
+ }
+
+ private Element findSelectedContent(Element root) {
+ ArrayDeque<Element> stack = new ArrayDeque<>();
+ for (int i = root.getChildCount() - 1; i >= 0; i--) {
+ Node child = root.getChild(i);
+ if (child instanceof Element) {
+ stack.push((Element) child);
+ }
+ }
+ while (!stack.isEmpty()) {
+ Element current = stack.pop();
+ if ("selectedcontent".equals(current.getLocalName())
+ && "http://www.w3.org/1999/xhtml".equals(
+ current.getNamespaceURI())) {
+ return current;
+ }
+ for (int i = current.getChildCount() - 1; i >= 0; i--) {
+ Node child = current.getChild(i);
+ if (child instanceof Element) {
+ stack.push((Element) child);
+ }
+ }
+ }
+ return null;
+ }
}
=====================================
src/nu/validator/saxtree/CharBufferNode.java
=====================================
@@ -50,6 +50,14 @@ public abstract class CharBufferNode extends Node {
System.arraycopy(buf, start, buffer, 0, length);
}
+ /**
+ * Returns the buffer.
+ * @return the buffer
+ */
+ public char[] getBuffer() {
+ return buffer;
+ }
+
/**
* Returns the wrapped buffer as a string.
*
=====================================
src/nu/validator/saxtree/ParentNode.java
=====================================
@@ -202,7 +202,22 @@ public abstract class ParentNode extends Node {
prev.setNextSibling(node.getNextSibling());
if (lastChild == node) {
lastChild = prev;
- }
+ }
+ }
+ }
+
+ /**
+ * Remove all children from this node.
+ */
+ public void clearChildren() {
+ Node child = firstChild;
+ while (child != null) {
+ Node next = child.getNextSibling();
+ child.setParentNode(null);
+ child.setNextSibling(null);
+ child = next;
}
+ firstChild = null;
+ lastChild = null;
}
}
=====================================
translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java
=====================================
@@ -81,8 +81,14 @@ public class CppTypes {
reservedWords.add("unicode");
}
+ private static Map<String, String> methodRenames = new HashMap<String, String>();
+
+ static {
+ methodRenames.put("htmlaccelEnabled", "mozilla::htmlaccel::htmlaccelEnabled");
+ }
+
private static final String[] TREE_BUILDER_INCLUDES = { "jArray",
- "mozilla/ImportScanner", "mozilla/Likely",
+ "mozilla/ImportScanner",
"nsAHtml5TreeBuilderState", "nsAtom", "nsContentUtils", "nsGkAtoms",
"nsHtml5ArrayCopy", "nsHtml5AtomTable", "nsHtml5DocumentMode",
"nsHtml5Highlighter", "nsHtml5OplessBuilder", "nsHtml5Parser",
@@ -91,12 +97,12 @@ public class CppTypes {
"nsHtml5TreeOpExecutor", "nsHtml5ViewSourceUtils", "nsIContent",
"nsIContentHandle", "nsNameSpaceManager", "nsTraceRefcnt", };
- private static final String[] TOKENIZER_INCLUDES = { "jArray",
+ private static final String[] TOKENIZER_INCLUDES = { "jArray",
"nsAHtml5TreeBuilderState", "nsAtom", "nsGkAtoms",
"nsHtml5ArrayCopy", "nsHtml5AtomTable", "nsHtml5DocumentMode",
"nsHtml5Highlighter", "nsHtml5Macros", "nsHtml5NamedCharacters",
- "nsHtml5NamedCharactersAccel", "nsHtml5String",
- "nsIContent", "nsTraceRefcnt" };
+ "nsHtml5NamedCharactersAccel", "nsHtml5String", "nsHtml5TreeBuilder",
+ "nsIContent", "nsTraceRefcnt", "mozilla/htmlaccel/htmlaccelEnabled" };
private static final String[] STACK_NODE_INCLUDES = { "nsAtom", "nsHtml5AtomTable",
"nsHtml5HtmlAttributes", "nsHtml5String", "nsNameSpaceManager", "nsIContent",
@@ -359,6 +365,14 @@ public class CppTypes {
return candidate;
}
+ public String mapMethodName(String method) {
+ String mapped = methodRenames.get(method);
+ if (mapped == null) {
+ return method;
+ }
+ return mapped;
+ }
+
public String stringForLiteral(String literal) {
return '"' + literal + '"';
}
@@ -486,6 +500,10 @@ public class CppTypes {
return "P::checkChar";
}
+ public String policyPrefix() {
+ return "P::";
+ }
+
public String silentLineFeed() {
return "P::silentLineFeed";
}
@@ -537,8 +555,4 @@ public class CppTypes {
public String crashMacro() {
return "MOZ_CRASH";
}
-
- public String loopPolicyInclude() {
- return "nsHtml5TokenizerLoopPolicies";
- }
}
=====================================
translator-src/nu/validator/htmlparser/cpptranslate/CppVisitor.java
=====================================
@@ -220,7 +220,7 @@ public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
private boolean inConstructorBody = false;
- private String currentMethod = null;
+ protected String currentMethod = null;
private Set<String> labels = null;
@@ -439,16 +439,6 @@ public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
printer.print(className);
printer.printLn(".h\"");
printer.printLn();
-
- if ("Tokenizer".equals(javaClassName)) {
- String loopPolicyInclude = cppTypes.loopPolicyInclude();
- if (loopPolicyInclude != null) {
- printer.print("#include \"");
- printer.print(loopPolicyInclude);
- printer.printLn(".h\"");
- printer.printLn();
- }
- }
}
public void visit(EmptyTypeDeclaration n, LocalSymbolTable arg) {
@@ -1320,6 +1310,9 @@ public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
} else if ("checkChar".equals(n.getName())
&& n.getScope() == null) {
visitCheckChar(n, arg);
+ } else if (n.getName().startsWith("accelerateAdvancement")
+ && n.getScope() == null) {
+ visitAccelerateAdvancement(n, arg);
} else if ("silentCarriageReturn".equals(n.getName())
&& n.getScope() == null) {
visitSilentCarriageReturn(n, arg);
@@ -1402,7 +1395,7 @@ public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
}
}
printTypeArgs(n.getTypeArgs(), arg);
- printer.print(n.getName());
+ printer.print(cppTypes.mapMethodName(n.getName()));
if ("stateLoop".equals(n.getName())
&& "Tokenizer".equals(javaClassName)
&& cppTypes.stateLoopPolicies().length > 0) {
@@ -1646,15 +1639,11 @@ public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
printModifiers(n.getModifiers());
}
- if (cppTypes.requiresTemplateParameter(currentMethod)
+ if (!inHeader() && cppTypes.requiresTemplateParameter(currentMethod)
&& "Tokenizer".equals(javaClassName)
&& cppTypes.stateLoopPolicies().length > 0) {
printer.print("template<class P>");
- if (inHeader()) {
- printer.print(" ");
- } else {
- printer.printLn();
- }
+ printer.printLn();
}
printTypeParameters(n.getTypeParameters(), arg);
@@ -1956,6 +1945,23 @@ public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
printer.print(")");
}
+ private void visitAccelerateAdvancement(MethodCallExpr call, LocalSymbolTable arg) {
+ List<Expression> args = call.getArgs();
+ printer.print(cppTypes.policyPrefix());
+ printer.print(call.getName());
+ printer.print("(this, ");
+ if (call.getArgs() != null) {
+ for (Iterator<Expression> i = call.getArgs().iterator(); i.hasNext();) {
+ Expression e = i.next();
+ e.accept(this, arg);
+ if (i.hasNext()) {
+ printer.print(", ");
+ }
+ }
+ }
+ printer.print(")");
+ }
+
private void visitSilentLineFeed(MethodCallExpr call, LocalSymbolTable arg) {
printer.print(cppTypes.silentLineFeed());
printer.print("(this)");
=====================================
translator-src/nu/validator/htmlparser/cpptranslate/HVisitor.java
=====================================
@@ -182,6 +182,12 @@ public class HVisitor extends CppVisitor {
previousVisibility = Visibility.PUBLIC;
}
}
+ if (cppTypes.requiresTemplateParameter(currentMethod)
+ && "Tokenizer".equals(javaClassName)
+ && cppTypes.stateLoopPolicies().length > 0) {
+ printer.print("template<class P>");
+ printer.printLn();
+ }
if (inline()) {
printer.print("inline ");
}
View it on GitLab: https://salsa.debian.org/java-team/libhtml5parser-java/-/compare/01509c70330e6998604aade7075c1a82b040358e...3f5082d3f440f85d05174fb7130803ef6addab5e
--
View it on GitLab: https://salsa.debian.org/java-team/libhtml5parser-java/-/compare/01509c70330e6998604aade7075c1a82b040358e...3f5082d3f440f85d05174fb7130803ef6addab5e
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20260501/944773a0/attachment.htm>
More information about the pkg-java-commits
mailing list