| NEWS | R Documentation |
NEWS file for the selectr package
Changes in version 0.7-0
NEW FEATURES
The
querySelector()family now accepts a set of nodes, so queries can be chained: the xml2xml_nodesetor XMLXMLNodeSetreturned by one call can be passed to the next. The selector is evaluated from each node in turn, and a node matching from more than one of them is returned once, at the position it first matched.The
querySelector()family now uses thehtmltranslator by default for documents parsed as HTML (byXML::htmlParse()orxml2::read_html()), so names match case-insensitively and:checked,:disabled,:linkand:lang()behave as in a browser without passingtranslator = "html". An explicittranslatorstill wins, and the choice carries through a chain of queries.An xml2
xml_missing, as returned by a failedxml_find_first(), is now accepted by thequerySelector()family and yields no matches rather than an error.A new
?selectorshelp topic documents every selector, combinator and pseudo-class selectr understands, which translators support each, and where the implementation diverges from CSS Selectors Level 4.The
htmlandxhtmltranslators now support:read-write,:read-only,:placeholder-shownand:default, which were previously unknown; on thegenerictranslator they never match. Pseudo-classes needing live document state, such as:indeterminate, remain unknown.
MINOR CHANGES
Parse errors now include a source-pointer block showing the selector with a caret (
^) beneath the offending character, aligned correctly across tabs and wide characters.Parse, translation and argument errors are now structured conditions inheriting a common
selectr_errorclass, so callers need not match on message text:selectr_parse_error(fields$selector,$pos),selectr_translation_error(fields$selector,$featureand$pos/$column), andselectr_argument_error. Message text is unchanged.A reported position -
$posand the caret - now points at the token the message names rather than wherever the parser stopped; for example the caret under"a||b"sits on the first|, and under"a:before:empty"on the:beforecalled misplaced.The minimum required version of R has been increased from
3.3to3.6, required byerrorCondition().-
css_to_xpath()now signals an error whenselector,prefixortranslatorhave lengths that are not all 1 or the common (maximum) length, instead of recycling and silently mispairing them. Generated XPath expressions are shorter and cheaper to evaluate, with no change to the node set selected. Pseudo-class translations drop disjuncts ruled out by the compound's element name (prefixed and
*|-qualified compounds included), name the element before testing anything else of it, factor out conditions every disjunct shares, and write enumerated attribute-value sets as a singlecontains(); a compound holding a never-matching simple selector folds to[0]alone; and a condition or selector-list branch repeating an earlier one exactly is kept once (":is(a, a)"gives"*[self::a]"). Code comparingcss_to_xpath()output against stored strings will need updating.Arithmetic in the generated XPath now has a space on both sides of the operator (
"(count(preceding-sibling::*) + 2)","string-length(@href) - 2"). The XPath is unchanged in meaning, but the string differs.Translating long selectors is measurably faster: the tokenizer matches against a bounded window of the remaining input rather than re-slicing it per token, and translator instances are cached and reused. The test suite has been migrated to testthat edition 3.
-
querySelector()no longer finds every match to return the first: it asks XPath for the first node directly on XML inputs, and stops at the first matching node of anxml_nodeset. The node returned is unchanged.
BUG FIXES
The
htmltranslator now compares the values of the attributes HTML defines as ASCII case-insensitive (type,rel,lang,dir, ... - the list in HTML's "Case-sensitivity of selectors") without regard to case, as a browser does, so"input[type=radio]"selects<input type="RADIO">. A trailingsflag asks for the exact comparison back.class,id,href,name,data-*, namespaced attributes and thegeneric/xhtmltranslators are unaffected.The
htmltranslator now lowercases element and attribute names by foldingA-Zonly, as an HTML parser does.tolower()also mapped non-ASCII letters, and by locale, so a selector such as"\C4"became a name test no document could match.-
:placeholder-shownnow requires a non-emptyplaceholderand, for<input>, atypethe attribute applies to (so notcheckbox,date,submit, ...); both previously matched. An
<input>of typerange,color,submit,image,resetorbuttonis now neither:requirednor:optionalunder thehtmlandxhtmltranslators, joiningtype="hidden", sincerequireddoes not apply to them.A large
An+Bvalue is now written into the generated XPath in full. Values of five or more digits used R's default number printing, socss_to_xpath(":nth-child(100001)")produced"... = 1e+05", which XPath 1.0 has no syntax for (libxml2 accepted it, so matches were correct but not portable).An
AorBtoo large for an R integer (e.g.":nth-child(99999999999)") is now saturated to.Machine$integer.maxinstead of raising an error; no document has that many siblings, so the clamped series selects the same nodes.The
html-qualified pseudo-classes (:checked,:disabled,:enabled,:link/:any-link,:optional,:required) now identify elements by local name, matching thexhtmltranslator's rule for type selectors; previously they matched nothing, or the wrong elements, on a namespaced document. Thehtmltranslator is unaffected in practice.-
querySelectorNS()andquerySelectorAllNS()now search only within the node given, as their un-namespaced counterparts do: the namespace filter was an absolute path (//svg:*) and is now relative (descendant-or-self::svg:*). Queries from a document are unaffected. A selector with a long chain of combinators is now translated by walking the parse tree in a loop rather than recursively; beyond a few hundred combinators these failed with "evaluation nested too deeply". Deeply nested functional pseudo-classes (e.g. hundreds of
:not()) now raise aselectr_translation_errorinstead of letting the base R error escape.An unusually long selector is now translated without being cached, rather than failing with "variable names are limited to 10000 bytes" - the translation cache keys are R symbols.
A backslash at the very end of a selector is now decoded per css-syntax instead of raising an error: in an identifier or hash name it becomes U+FFFD, and inside an open string it is dropped and the string auto-closed.
A unicode escape decoding to a null, surrogate or out-of-range code point (e.g.
"\0","\D800","\110000") now yields U+FFFD as css-syntax requires, instead ofNAor an empty string.-
An+Bexpressions are now validated while parsing, so a malformed value is reported with a source position and names the pseudo-class it appeared in. -
An+Bexpressions are now read from tokens rather than decoded text, so a digit written as an escape is no longer taken for an integer:":nth-child(\32 )"and friends are rejected as browsers reject them. Escapes spelling letters are unaffected (":nth-child(\65 ven)"is still"even"). A number with an identifier written straight onto it is now the single
<dimension-token>css-syntax makes it, so":nth-child(2n+1of b)"and":nth-child(1of b)"are rejected as browsers reject them. The spelling with a space, and dimensionsAn+Bdoes admit ("2n+1","2n-1"), are unaffected.An ID selector's hash must now be identifier-shaped:
"#1", other hashes starting with a digit or-plus a digit, and a lone"#-"are rejected with a hint on escaping, instead of being silently mistranslated.A lone
-is now a delimiter rather than a name, so"-","a - b"and".-"are rejected instead of translated into an expression nothing can match. Names that do start with-("-a","--a","--","\-") are unaffected, as is the sign in":nth-child(2n - 1)".-
-->and<!--are now read as the single CDC and CDO tokens CSS makes them and rejected whole at their starting position. A-->inside a name is unchanged, so"a-->b"still selects abchild of ana--. An empty
:is()or:where()argument list is now accepted per its<forgiving-selector-list>grammar and matches nothing, instead of raising a parse error.-
:lang()ranges must now be comma-separated; whitespace alone (":lang(en fr)") is no longer a separator. Multi-token wildcard ranges such as":lang(*-CH)"are unaffected. -
:lang(*)now matches only elements whose language is known - one inheriting a non-emptylangorxml:lang- instead of every element. The
xhtmltranslator's:lang()now also readsxml:lang, preferring it overlangon the nearest declaring ancestor-or-self, per HTML's language-determination rules.An
<option>in a disabled<optgroup>, and an<optgroup>or<option>whose nearest ancestor<select>is disabled, are now:disabledunder thehtmlandxhtmltranslators without an attribute of their own, per HTML's "actually disabled". The walk stops where the standard stops, so an<option>in a<datalist>stays:enabled.An
<input type="hidden">is now:disabledwhen it carriesdisabled(or sits in a disabled<fieldset>) and:enabledotherwise; previously it was neither, a carve-out HTML does not make. The:required/:optionalcarve-out is unchanged.A
<fieldset>inside a disabled<fieldset>is now:disabled, following the rule already applied to form controls (descendants outside the first<legend>child).-
:linkand:any-linkno longer match a<link>element with anhref: HTML's hyperlink elements for these pseudo-classes are<a>and<area>only, so"link:link"now matches nothing. The of-type pseudo-classes now reject a namespaced wildcard subject (e.g.
"svg|*:first-of-type") with a translation error, instead of silently counting siblings by namespace rather than expanded name.An unprefixed element name that cannot be written as an XPath name test is now pinned to the null namespace (
"é"gives*[name() = 'é' and namespace-uri() = '']), giving it the same meaning as a plain"p"; previously it also matched in a default namespace.An element or attribute name whose local part cannot be written as an XPath name test now keeps its prefix in the node test and compares the local part alone (
"svg|di\[v"givessvg:*[local-name() = 'di[v']), so the prefix resolves through the supplied namespace map instead of matching whatever prefix the document happens to use.A namespace prefix that is not a valid XPath
NCName(e.g."\31 ns|div") is now rejected with a translation error, since thename()comparison previously emitted tested the document's spelling rather than the bound URI. A non-ASCII prefix (e.g."äöü|a") is now translated instead.-
NAand empty-string values in thensargument of thequerySelectorNS()family are now rejected rather than used as a namespace URI. A name in the
nsargument that is not a valid XMLNCName(e.g.c("s p" = "urn:s")) is now rejected; previously it was interpolated into XPath that failed to compile, giving a libxml2 warning and no matches. The condition matches the one applied to prefixes written in selectors.A zero-length
nsargument (character(0)orlist()) to the xml2querySelector()family now means "no namespaces" and skips thexml_ns()walk, rather than behaving likeNULL.A
selectororprefixholding bytes invalid in their declared encoding is now rejected with aselectr_argument_error, instead of surfacing base R's "invalid multibyte string".An invalid
translatorargument now raises a message naming thetranslatorargument and the value passed, instead ofmatch.arg()'s message naming an internal argument. Unambiguous abbreviations are still accepted.-
p:nth-of-type(n of .a)and the other of-type pseudo-classes now report the same "'of' is only allowed in :nth-child() and :nth-last-child()" error as:nth-child(), instead of a confusing "Expected an argument". -
:nth-child(0)(and otherAn+Bwitha == 0andb < 1) now gives the tidy[0]early exit rather than[count(preceding-sibling::*) = -1]. A handful of parser and argument messages have been reworded. Positions embedded in message text no longer duplicate the caret gutter (they are still given, as "at position N", where the gutter is suppressed). Four messages now name the actual problem: an R-level XML tree is reported as one; a functional pseudo-element such as
::part()is reported as unsupported;div.5gets the escaping hint#5already had; and[data-id=1]is told to quote the value.The
htmlandxhtml:lang()now implements Selectors 4 / RFC 4647 extended filtering, so:lang(de-DE)matcheslang="de-Latn-DE". Thegenerictranslator keeps Selectors 3 prefix matching, as XPath 1.0'slang()cannot express skipped subtags.:lang("")now matches an untagged element per spec, rather than only a literallang="".A
:lang()range that is not an RFC 4647 extended language range (e.g.":lang(en-)",":lang(--x)",":lang(en*)") is now rejected, naming the offending range; previously such ranges were normalised and over-matched.An empty item in the comma-separated
:lang()argument list (":lang(en, )") is now rejected rather than silently dropped, as the<ident>#grammar requires.A
:lang()range of nothing but wildcards (":lang(\"*-*\")") now matches any element with a known language, as":lang(*)"does, rather than producing an empty predicate.An escaped
*before a|is now rejected as the namespace prefix it is: only the delimiter*means "any namespace", so"\2a|a"and"[\2a|href]"now raise "The namespace prefix '*' is not an XPath name ...", where they previously matched every namespace."*|a"and"[*|href]"are unchanged.-
"*|\2a"now selects an element named*in any namespace, as"ns|\2a"and"\2a"already did; the local name was tested against the character*rather than for being the universal selector, so the selector matched every element.
Changes in version 0.6-0
This release is a fairly major change. It comes about via a port to a Rust implementation which uses a robust browser-quality selector parsing engine. With behavioural comparison tests, several bug fixes, features, and performance enhancements were identified and resolved.
NEW FEATURES
Added support for case-sensitivity flags in attribute selectors:
[attr="value" i]matches the attribute value ASCII case-insensitively, while[attr="value" s]explicitly requests the default case-sensitive matching.The
:requiredand:optionalpseudo-classes are now supported. With thehtmlorxhtmltranslator they match form elements (inputother thantype="hidden",select,textarea) by the presence or absence of therequiredattribute; with thegenerictranslator they translate to a never-matching expression, as:checkeddoes.The
:focus-withinand:focus-visiblepseudo-classes are now accepted and, like the rest of the user-action family (:focus,:hover,:active, ...), translate to a never-matching expression, since a static document has no such dynamic state. They previously raised "The pseudo-class ... is unknown".Added support for a leading
:scopepseudo-class, anchoring the selector at the queried node:querySelectorAll(node, ":scope > a")returns only theachildren ofnode.css_to_xpath()translates such selectors with the XPathselfaxis in place of theprefixargument (":scope > a"becomes"self::*/a"). A:scopeanywhere else in a selector cannot be expressed in XPath 1.0 and is rejected with a clear error.-
:not()may now appear inside the arguments of functional pseudo-classes (e.g.:not(:not(a)),:is(:not(.x)),:nth-child(2 of :not(.foo))). -
:has()now supports leading combinators in its arguments (e.g.e:has(> img),e:has(~ p),e:has(+ p)). Functional pseudo-class arguments may now be complex selectors (contain combinators):
:is(a b),:not(a > b),e:has(> a b), andli:nth-child(2 of ol li)previously produced an "Expected an argument" error and are now translated.
MINOR CHANGES
The performance of selectr has been improved roughly 2x. There are several smaller changes that have contributed to this.
The unsupported Selectors 4 column combinator now raises "The column combinator '||' is not supported" instead of a raw tokenizer error, and an unknown functional pseudo-class is reported with the user's hyphenated spelling (
:nth-col(), previously:nth_col()).Generated XPath expressions now include parentheses only when precedence requires them (an or-expression joined with another condition):
e[id][title]translates toe[@id and @title]rather thane[(@id) and (@title)]. The expressions are semantically unchanged, but code comparingcss_to_xpath()output against stored strings will need updating.Attribute blocks, functional pseudo-classes, and strings left unclosed at the end of a selector are now auto-closed, as css-syntax requires:
[rel=stylesheetand:lang(frparse and translate exactly as their closed forms, as does a string missing its closing quote.The stringr and methods dependencies have been dropped. R6 is now the only package selectr imports, shrinking the install footprint.
-
css_to_xpath()now translates each distinct combination of selector, prefix, and translator only once per call, so duplicates in a vectorized call are not re-translated. The adjacent sibling combinator no longer emits a tautological
[self::*]predicate when the right-hand side does not name an element:h1 + *[rel=up]now translates toh1/following-sibling::*[1][@rel = 'up'].The minimum required version of R has been increased from
3.0to3.3, matching what the code (which usesstartsWith()) has in fact required for some time.
REMOVED FEATURES
The non-standard extensions inherited from the Python 'cssselect' package — the
:contains("text")pseudo-class and the[attr!=value]attribute operator — have been removed and now produce an error. Standard alternatives::not([attr=value])for the former operator, and an XPathcontains(., 'text')predicate applied outside of selectr for:contains().
BUG FIXES
With the
htmlorxhtmltranslator,:any-linknow matches the same elements as:link.:any-linkmeans ":link or :visited", a superset of:link, but it previously translated to a never-matching expression while:linkmatched - the subset relation inverted. (In a static document no link is visited, so the two pseudo-classes coincide.)Escape sequences in identifiers, hashes, and strings are now decoded in a single left-to-right pass, as css-syntax requires, so an escaped backslash followed by hex digits is no longer decoded twice:
e[foo="x\\79 z"]now matchesx\79 zrather thanxyz.A prefixed wildcard inside a pseudo-class argument (e.g.
:is(svg|*)) now translates to the node testself::svg:*rather than the never-matching comparisonname() = 'svg:*'.When
:lang()is given an invalid argument after valid ones (e.g.:lang(en, 5)), the error now reports the offending argument rather than the first one.Strings containing a raw newline are now rejected with "Unclosed string", as the CSS grammar requires.
The namespace argument of the
querySelector()family of functions now signals an error when given a list containing an element that is not a single string; previously the prefix-to-URI pairing was silently corrupted.-
:only-childand:only-of-typenow match the root element, consistent with:first-child:last-child, which Selectors defines:only-childto be equivalent to. The HTML translator's
:enabledand:disabledpseudo-classes now matchinputelements that have notypeattribute (which default totype=text).-
:dir()now enforces its CSS Selectors Level 4 argument grammar of exactly one identifier, rejecting the strings, wildcards, and lists (e.g.:dir(ltr, rtl)) it previously accepted via the shared:lang()grammar. Prefixed element names inside pseudo-class arguments (e.g.
:is(svg|g),:nth-child(2 of svg|g)) are now matched with an XPath name test (self::svg:g, or the path step.//svg:gfor:has()) instead of aname()string comparison, so the prefix resolves through the namespace map supplied at evaluation time (URI-based), just as at the top level of a selector.The no-namespace form
|enow retains its namespace constraint when the element name cannot be written as an XPath name test (e.g. a Unicode name such as|é); previously such names also matched in a default namespace.The of-type pseudo-classes now work on element names that cannot be written as an XPath name test (e.g.
é:only-of-type,*|e:first-of-type); previously these failed with the misleading error "*:only-of-type is not implemented".The
querySelector()andquerySelectorAll()methods for xml2 documents now accept a named list as thensargument, consistent with the methods for XML documents.The
querySelector()family of functions now signals an error when theselectorargument is not a single character string; previously all but the first selector were silently ignored when querying the document.-
css_to_xpath()now signals an error when any of its arguments containNAvalues; previouslyNAs were removed before recycling, silently shifting the pairing of the remaining values. -
An+Bexpressions are now matched ASCII case-insensitively, as required by CSS Syntax, so:nth-child(2N),:nth-child(ODD), and:nth-child(EVEN)are no longer rejected. -
An+Bexpressions now only permit whitespace around the sign that separates theBvalue, so an invalid selector such as:nth-child(3 7)is rejected rather than silently treated as:nth-child(37). -
An+Bexpressions now reject non-integer values (e.g.:nth-child(1.9),:nth-child(2e1)) rather than silently truncating them. Computing the specificity of a
:has()selector with a single argument (e.g.e:has(img)) no longer fails with "incorrect number of dimensions".Computing the specificity of a single-argument
:is()or:matches()selector no longer fails, and the specificity of the compound the pseudo-class is attached to is no longer dropped:div:is(.foo)now reports (0, 1, 1) rather than (0, 1, 0).Nesting
:has()inside:has()(e.g.section:has(article:has(div))) is now rejected, as required by CSS Selectors Level 4 and matching browsers; sibling uses such ase:has(a):has(b)remain valid.-
:lang()and:dir()no longer accept a lone-, which is not a valid CSS identifier. Attribute selectors with an empty value (e.g.
[attr=""]) no longer throw an error for the=and|=operators.The HTML translator no longer lowercases attribute values, only attribute names, so
[data-state="Active"]no longer silently misses matches.The any namespace selector
*|eand the no namespace selector|eno longer both collapse to the bare namee:*|enow translates to*[local-name() = 'e']so it matchesein any namespace, and similarly for[*|attr].Unicode escapes are now supported in identifiers and ID selectors, not just strings, and are decoded to the characters they represent:
#\31 23(an ID starting with a digit) no longer fails to tokenize, and"\E9"matchesérather than the literal valueE9.The alternatives of
:is(),:matches(), and:where()are now grouped as a single condition:div.foo:is(.a, .b)translates tofoo and (a or b)rather thanfoo or a or b, and stacked uses such ase:is(.a):is(.b)now require both conditions rather than either.The universal selector
*is no longer silently dropped when it appears alongside other arguments in a selector list::is(div, *)now matches every element,:not(div, *)matches nothing, and:nth-child(2 of div, *)counts all siblings.Wildcard language ranges such as
:lang(en-*)now match under the generic (XML) translator; previously they translated tolang('en-'), which can never match.
Changes in version 0.5-1
BUG FIXES
Fixed handling of CSS unicode escapes in attribute values. This would be observed when the attribute value contained hexadecimal sequences like
(abcdef)where the characters inside the parentheses were not properly escaped. This fix ensures that such sequences are correctly translated to their XPath equivalents. Thanks to André Veríssimo for reporting the issue.
Changes in version 0.5-0
NEW FEATURES
Added support for CSS Selectors Level 4 pseudo-classes
:is(),:where(), and:has(). The:is()pseudo-class matches elements against a list of selectors, taking the maximum specificity from its arguments. The:where()pseudo-class works similarly to:is()but always has zero specificity. The:has()pseudo-class represents an element if any of the relative selectors match when anchored against that element, with specificity calculated from the maximum of its arguments.Added support for complex selectors in
:nth-child()and:nth-last-child()using theof Ssyntax (e.g.,:nth-child(2 of .foo)). This allows matching the nth child that matches a specific selector or selector list.Extended
:not()to accept multiple selectors separated by commas (e.g.,:not(.foo, #bar)), following CSS Selectors Level 4. Specificity is now calculated as the maximum specificity among all arguments, rather than the sum.Added support for additional CSS Selectors Level 4 pseudo-classes:
:any-link,:target-within, and:local-link. These pseudo-classes do not match any elements in static XML/HTML documents and translate to XPath expressions that always evaluate to false. For now, most of the new Level 4 pseudo-classes that depend on dynamic document state e.g.:user-validand:placeholder-shownare not implemented, but may be at a future date to be non-matching selectors.The
:lang()and:dir()pseudo-classes now support multiple comma-separated arguments (e.g.,:lang(en, fr, de)).Added
:matches()as a backwards-compatible alias for:is().
MINOR CHANGES
Improved sibling selector translation to use a more compact form. For the adjacent sibling combinator
a + b, the generated XPath now usesa/following-sibling::*[1][self::b]instead ofa/following-sibling::*[(name() = 'b') and (position() = 1)].The descendant combinator
a bnow usesa//binstead ofa/descendant::bfor a more concise XPath. Unfortunately a similar optimisation cannot be applied to in general when attempting to replacedescendant-or-self::with.//aas it would prevent root nodes being matched correctly.Improved validation of CSS selector arguments. Better error messages are now provided when pseudo-elements appear inside functional pseudo-classes where they are not permitted (e.g., inside
:is(),:matches(),:where(), or:has()).Enhanced input validation for
:lang()and:dir()pseudo-classes to ensure proper argument formatting and to reject invalid or empty language tags.Improved handling of edge cases in selector parsing, including better validation of class selector syntax and more robust handling of null or missing element components.
Simplified method registration for XML and xml2 objects. No longer necessary to hook into package load/unload events.
Changes in version 0.4-2
MINOR CHANGES
Improve handling of vectors of length > 1 in logical comparison. Contributed by Garrick Aden-Buie.
Minor improvements to error message construction. Contributed by Michael Chirico.
Changes in version 0.4-1
BUG FIXES
When the R.oo package is attached, the use of class selectors no longer worked. This is due to the use of the
Classname for R.oo's base class object, where selectr was also using it (but not exporting) the same name ofClassfor representing a class selector. Consequently, selectr's code was changed to rename the class to avoid any clashing. Because it was not exported, this is purely an internal change. Thanks to Francois Lemaire-Sicre for reporting the issue.
Changes in version 0.4-0
MINOR CHANGES
Large rewrite of internals to use the R6 OO system instead of Reference Classes. This does not affect any external facing code as the results should be identical to the previous implementation, which is why this change is marked as minor. Initial and crude performance testing (by running the test suite) indicates that the R6 implementation is approximately twice as fast at generating XPath as the Reference Classes implementation.
The minimum required version of R for selectr has been increased from
2.15.2to3.0as that is the minimum required version of R6.Minor performance enhancements have been made. Not only is R6 faster than Reference Classes, the use of string formatting has been replaced with string concatenation. Additionally dynamic calling of methods via
do.call()has been replaced with direct method calls.
BUG FIXES
The issues in previous releases where methods can sometimes be missing should now be resolved. The bug appeared to lie in core Reference Classes code. By switching to R6, this type of issue should no longer be possible.
Changes in version 0.3-2
MINOR CHANGES
Improved method registration for XML and xml2 objects. Avoids checks on each use and is only performed once per dependent package load/unload.
BUG FIXES
In some environments, reference class methods were missing at runtime. This appears to be due to some internal behaviour in them methods package where methods are registered on an objects when the
$operator is used for a field or method. Instead, when a method is missing, they are manually bound to the object.
Changes in version 0.3-1
MINOR CHANGES
Enabled partial matching on the translator argument to
css_to_xpath(). Instead of defaulting to a generic translator, a non-matching argument will be returned with an error.Introduced many more unit tests via the covr package. This enabled dead code to be trimmed and also identified areas of code which needed improvement. Minor enhancements include: tolerate whitespace within a
:not(), more consistent results returned from parser methods, improvements to argument parsing.
BUG FIXES
The
|=attribute matching operator was not being parsed correctly for the generic translator.Handle scenario where a CSS comment is unclosed. Results in everything after the comment start to be removed (which may or may not result in a valid selector).
Changes in version 0.3-0
MAJOR CHANGES
Added support for documents from the xml2 package.
selectr now also does not strictly depend on the XML package. If either the XML or xml2 packages are present (which are required for the
querySelectormethods to work) thenquerySelectorwill begin to work for them. This also enables selectr to be used for translation-only.
BUG FIXES
Improve support for nth-*(an+b) selectors. Ported from cssselect.
Changes in version 0.2-3
MINOR CHANGES
Code cleanup contributed by Kun Ren (#1).
Updated DESCRIPTION to include URL and BugReports fields. Also update email address.
BUG FIXES
Fix behaviour for nth-*(an+b) pseudo-class selectors for negative a's. Contributed to cssselect by Paul Tremberth, ported to R.
Escape delimiting characters to support new version of the stringr package. Probably should have been done in the first place. Reported by Hadley Wickham (#5).
Changes in version 0.2-2
MINOR CHANGES
Corrected licence to BSD 3 clause. This was the licence in use previously, but has now been made more explicit.
Removed 'Enhances' field because we import functions from XML. This choice is made because XML is a required package, rather than an optional package that can be worked with. This and the previous change have been made to keep up with recent changes in R-devel.
Changes in version 0.2-1
MINOR FEATURES
Added a 'CITATION' file which cites a technical report on the package.
-
show()methods are now available on internal objects, making interactive extensibility and bug-fixing easier. This is simply wrapping therepr()methods (mirroring the Python source) that the same objects have.
BUG FIXES
Use the session character encoding to determine whether to run unicode tests. Tests break in non-unicode sessions otherwise.
Changes in version 0.2-0
NEW FEATURES
Introduced new functions
querySelectorNS()andquerySelectorAllNS()to ease the use of namespaces within a document. Previously this would have required knowledge of XPath.
BUG FIXES
Fix meaning of
:empty, whitespace is not empty.Use
lang()for XML documents with the:lang()CSS selector.-
|identno longer produces a parsing error, but is now equivalent to just 'ident'.
Changes in version 0.1-1
BUG FIXES
Now testing unicode only in non-Windows platforms on package check. Output should still be consistent, just depends on the current charset being unicode.
Changes in version 0.1-0
NEW FEATURES
Initial port of the Python 'cssselect' package. Code is very literally ported, including the test suite.
Wrapped translation functionality into a single function,
css_to_xpath().Created two convenience functions,
querySelector()andquerySelectorAll(). These mirror the behaviour of the same functions present in a web browser.querySelector()returns a node, whilequerySelectorAll()returns a list of nodes.