Commit Graph

454 Commits

Author SHA1 Message Date
Yorick Peterse ad4f650c5d Fixed XML entity encoding/decoding ordering.
Thanks to @krasnoukhov for providing the initial patch, which this commit is
largely based on.

This fixes #49.
2014-11-17 22:39:43 +01:00
Yorick Peterse cd86d5d294 Allow removal of element attributes. 2014-11-17 09:00:40 +01:00
Yorick Peterse 804646cc5e Don't modify raw namespaces.
When calling Element#available_namespaces the list of namespaces returned by
Element#namespaces must not be modified.
2014-11-17 00:01:16 +01:00
Yorick Peterse 6753d6a26d Slightly better docs for the XPath/CSS parsers. 2014-11-16 23:40:19 +01:00
Yorick Peterse 57adabc068 Ensure SAX after_element receives meaningful args
This changes the behaviour of after_element when parsing documents using the SAX
parsing API. Previously it would always receive a nil argument, which is kinda
pointless. This commit changes that by making sure it receives a namespace name
(if any) and the element name.

This fixes #54.
2014-11-16 23:32:32 +01:00
Yorick Peterse 23b408fe4f Cleaned up CSS parser code for counting siblings. 2014-11-15 18:31:08 +01:00
Yorick Peterse b464815577 Fixed AST generation for nth-(first|last)-of-type. 2014-11-15 18:27:15 +01:00
Yorick Peterse 9eead81a7c Fixed AST for :only-of-type 2014-11-15 18:08:26 +01:00
Yorick Peterse 1c301d40e2 Properly fixed AST for first-of-type/last-of-type
This requires keeping track of the current element being processed. This in turn
allows the usage of count() + preceding-sibling/following-sibling.
2014-11-15 17:58:56 +01:00
Yorick Peterse f1d574f342 Evaluate XPath predicates for every context node.
Instead of evaluating a predicate once for all context nodes, they should
instead be evaluated separately per context node.
2014-11-15 00:31:44 +01:00
Yorick Peterse 6daa3e7a00 Reverted AST changes for first-of-type
Functions can't be used in combination with axes, so I'll just need to fix the
position() function to work properly.
2014-11-14 23:51:46 +01:00
Yorick Peterse 2d6a2be2e8 Revert "Fixed XPath AST for :last-of-type"
Axes can't be used in combination with functions.

This reverts commit b0b572a584.
2014-11-14 23:49:49 +01:00
Yorick Peterse b0b572a584 Fixed XPath AST for :last-of-type
This should count following nodes, not merely the position.
2014-11-14 23:27:15 +01:00
Yorick Peterse 0128dc50ae Fixed CSS evaluation of :first-of-type
The old XPath "position() = 1" would work in Nokogiri due to the way they
retrieve descendants. In Oga however this would simply always return the first
node.

To fix this Oga now counts the amount of preceding siblings that match the same
full name.
2014-11-14 01:25:03 +01:00
Yorick Peterse e3a26c5d15 Allow querying of nodes using CSS. 2014-11-14 01:05:29 +01:00
Yorick Peterse 01b88d8c68 Use correct root for preceding/following(-sibling)
This ensures these axes work correctly when scoped to a node instead of a
document.
2014-11-13 01:11:29 +01:00
Yorick Peterse b0f6409d1e Wrap predicate nodes around others in CSS ASTs. 2014-11-13 00:47:26 +01:00
Yorick Peterse 817a5e075b Wrap predicate AST nodes _around_ other nodes.
This means that "foo[1]" uses this AST:

    (predicate (test nil "foo") (int 1))

Instead of this AST:

    (test nil "foo" (int 1))

This makes it easier for the XPath evaluator to process predicates correctly.
2014-11-12 22:59:38 +01:00
Yorick Peterse 857ac517d5 Added XML::NodeSet#==
This method can be used to compare two NodeSet instances. By using
XML::NodeSet#equal_nodes?() the need for exposing the "nodes" instance variable
is also removed.
2014-11-09 18:33:16 +01:00
Yorick Peterse a586a512b8 Removed support for CSS such as "|X"
This expression could be used to get all elements that _don't_ have any
namespace. The problem is that this can't be expressed as just a node test,
instead the resulting XPath would have to look something like the following:

    X[local-name() = name()]

However, since the XPath predicates are already created for pseudo classes and
such, also injecting the above into it would be a real big pain. As such I've
decided not to support it.
2014-11-05 00:45:40 +01:00
Yorick Peterse 1c20ef52ae XPath idents can't start with a star.
That is, names such as "*foo" are not valid. This was most likely a typo in the
first place.
2014-11-05 00:38:17 +01:00
Yorick Peterse 61801fe562 Allow CSS identifiers to start with an underscore. 2014-11-05 00:37:40 +01:00
Yorick Peterse f1316c50fb Allow XPath idents to start with an underscore.
This is valid in XML so XPath should support it as well.
2014-11-05 00:35:47 +01:00
Yorick Peterse eb3a3e7630 Use the descendant axis for CSS selectors.
Instead of using "descendant-or-self" Oga will use "descendant". This ensures
that expressions such as "foo *" don't return a set also including the "foo"
element.

Nokogiri solves this problem in a somewhat different way by using //foo//* for
the CSS expression "foo *". While this works in Nokogiri the expression
"descendant-or-self::node()" is slow as a snail in Oga (due to its nature of
retrieving _all_ nodes first). By using "descendant" we can work around this
problem.
2014-11-05 00:22:09 +01:00
Yorick Peterse 602f2fe8bb Apply node() type tests to the document too.
When running XPath queries such as "self::node()" the result should be a set
containing the document itself. This in turn fixes expressions such as
descendant-or-self::node()/a.
2014-11-04 23:41:45 +01:00
Yorick Peterse de04c61df9 Parsing support for the :empty pseudo. 2014-11-04 00:00:23 +01:00
Yorick Peterse 1b870406de Parsing support for the :only-of-type pseudo. 2014-11-03 23:47:25 +01:00
Yorick Peterse 2cf058457d Parsing support for the :only-child pseudo. 2014-11-03 23:27:56 +01:00
Yorick Peterse 759bb71d17 Parsing support for the :last-of-type pseudo. 2014-11-03 23:01:44 +01:00
Yorick Peterse 10632eafd4 Parsing support for the :first-of-type pseudo. 2014-11-03 23:00:15 +01:00
Yorick Peterse 7a606a11d3 Parsing support for the :last-child pseudo class. 2014-11-03 22:58:08 +01:00
Yorick Peterse b4fec3cc8c Parsing support for the :first-child pseudo class. 2014-11-03 22:45:00 +01:00
Yorick Peterse 020d979fba Parsing support for :nth-last-of-type(). 2014-11-03 22:15:21 +01:00
Yorick Peterse bc8be9f725 Fixed various incorrect YARD tags. 2014-11-02 21:23:29 +01:00
Yorick Peterse 2e1320c2dc Explicit return in step_modulo_value. 2014-11-02 19:32:02 +01:00
Yorick Peterse ab8b451dc3 Parsing support for :nth-of-type() 2014-11-02 19:29:39 +01:00
Yorick Peterse 0faceffacb Parsing support for nth-child(n+X) 2014-11-02 19:29:09 +01:00
Yorick Peterse 8d8d74ec41 Drop nth-child support of all negative sequences
This removes parsing support for selectors such as :nth-child(-n-6). According
to the CSS spec this isn't valid anyway (confirmed by testing it in Chromium).
As a result there's no point in supporting it in any way.
2014-11-02 19:19:05 +01:00
Yorick Peterse b31288b7d2 Use correct modulo for nth-child and negatives. 2014-11-02 18:53:23 +01:00
Yorick Peterse 9cce93fc4a Parsing support for :nth-last-child. 2014-11-01 20:58:28 +01:00
Yorick Peterse 03f897c2b7 Support for all possible nth-child arguments.
That is, as far as I can tell based on Nokogiri's behaviour (which Oga now
matches).
2014-10-30 23:03:46 +01:00
Yorick Peterse 0e6aefb727 Fixed parsing of nth-child(n) and nth-child(-n) 2014-10-30 00:24:31 +01:00
Yorick Peterse 87f6b9c723 Basic support for :nth-child()
This already includes support for formulas such as 2n, odd, even and 2n+1.
Negative formulas, just "n" and others are not yet supported.
2014-10-28 00:21:11 +01:00
Yorick Peterse 46646e2ace Support for custom grouping of XPath expressions.
This allows the use of expressions such as "(A or B) and C".

This fixes #59.
2014-10-26 22:38:05 +01:00
Yorick Peterse 39c0f7147c Support for parsing the :root pseudo class. 2014-10-26 22:20:23 +01:00
Yorick Peterse 32764c9a14 Proper parsing support for all CSS operators. 2014-10-26 12:45:43 +01:00
Yorick Peterse 24ae791f00 Better support for lexing multi-line strings.
When lexing multi-line strings everything used to work fine as long as the input
were to be read as a whole. However, when using an IO instance all hell would
break loose. Due to the lexer reading IO instances on a per line basis,
sometimes Ragel would end up setting "ts" to NULL. For example, the following
input would break the lexer:

    <foo class="\nbar" />

Due to the input being read per line, the following data would be sent to the
lexer:

    <foo class="\n
    bar" />

This would result in different (or NULL) pointers being used for building a
string, in turn resulting in memory allocation errors.

To work around this the string lexing setup has been broken into separate
machines for single and double quoted strings. The tokens used have also been
changed so that instead of just "T_STRING" there are now the following tokens:

* T_STRING_SQUOTE
* T_STRING_DQUOTE
* T_STRING_BODY

A string can have multiple T_STRING_BODY tokens (= multi-line strings, only the
case for IO inputs). These strings are stitched back together by the parser.

This fixes #58.
2014-10-26 11:39:56 +01:00
Yorick Peterse b304b8b077 Fixed descendant-or-self with a predicate.
Processing of this axis along with a predicate wouldn't quite work out. Even if
the predicate returned false the node would still be matched (which should not
be the case).
2014-10-23 01:12:10 +02:00
Yorick Peterse 7ee7f25239 Support for parsing CSS axes. 2014-10-23 00:42:45 +02:00
Yorick Peterse 9955f61bcb Renamed CSS axis tokens.
These have been renamed as following:

T_CHILD => T_GREATER
T_FOLLOWING => T_TILDE
T_FOLLOWING_DIRECT => T_PLUS
2014-10-21 23:25:11 +02:00