Commit Graph

578 Commits

Author SHA1 Message Date
Dan Fockler be7bc8f423 make string comparison faster 2015-08-15 06:36:27 -07:00
Dan Fockler fc38b39aa3 make string comparison a bit faster 2015-08-15 06:34:09 -07:00
Daniel Fockler 496811a23f Fixes #127 2015-08-14 16:15:49 -07:00
Yorick Peterse 0977be81bb Release 1.2.2 2015-08-14 14:49:26 +02:00
Yorick Peterse 9b98e75115 Use pop/push vs shift/unshift in each_node
While the performance difference between the old and new approach is
pretty much negligible, it's simply not needed to use #shift/#unshift
here.

Thanks to Mon_Ouie from the #ruby IRC channel for suggesting this.
2015-08-07 14:08:54 +02:00
Yorick Peterse 32b75bf62c Reset the owner ivar in LRU#synchronize
Without this the following could happen:

1. Thread A acquires the lock and sets the ownership to A.
2. Thread A yields and returns
3. Thread B tries to acquire the lock
4. At this exact moment Thread A calls the "synchronize" method again
   and sees that the "owner" variable is still set to Thread A
5. Both thread A and B can now access the underlying data in parallel,
   possibly leading to corrupted objects

This can be demonstrated using the following script:

    require 'oga'

    lru = Oga::LRU.new(64)

    threads = 50.times.map do
      Thread.new do
        loop do
          number = rand(100)

          lru[number] = number
        end
      end
    end

    threads.each(&:join)

Run this for a while on either JRuby or Rubinius and you'll end up with
errors such as "ConcurrencyError: Detected invalid array contents due to
unsynchronized modifications with concurrent users" on JRuby or
"ArgumentError: negative array size" on Rubinius.

Resetting the owner variable ensures the above can never happen. Thanks
to @chrisseaton for bringing this up earlier today.
2015-08-03 21:47:40 +02:00
Jakub Pawlowicz ed3cbe7975 Fixes #129 - lexing superfluous end tags.
Prevents a superfluous end tag of a self-closing HTML tag from
closing its parent element prematurely, for example:

```html
<object><param></param><param></param></object>
```

(note <param> is self closing) being turned into:

```html
<object><param/></object><param/>
```
2015-07-23 13:16:11 +01:00
Yorick Peterse 5d0e8c99af Release 1.2.1 2015-07-01 00:24:07 +02:00
Jakub Pawlowicz 6786dde3f0 Splits entity decoding into two steps.
Doing decimal & hex decoding separately results in a nicer code
which does not refer to string matching and slicing.
2015-06-30 17:56:26 +02:00
Jakub Pawlowicz 6fc3ef425b Fixes #118 - decoding invalid entities.
Previous regular expression was too greedy in terms of matching
letters from outside of A-F hex scope, and matching letters when
not in hex mode.
2015-06-30 17:56:26 +02:00
Yorick Peterse 8990a62224 Release 1.2.0 2015-06-30 10:58:05 +02:00
Yorick Peterse 71960fff87 Added CSS :nth() pseudo class
This is a Nokogiri extension (as far as I'm aware) but it's useful
enough to also include in Oga. Selectors such as "foo:nth(2)" are simply
compiled to XPath "descendant::foo[position() = 2]".

Fixes #123
2015-06-29 20:51:38 +02:00
Yorick Peterse d26b48feb4 CSS parsing support for commas
The lexer already had the basic plumbing in place but apparently I
completely forgot to also implement the required bits in the parser.

Fixes #121
2015-06-29 18:59:01 +02:00
Yorick Peterse dccf7a7e06 Release 1.1.0 2015-06-29 16:45:21 +02:00
Tero Tasanen 0b4791b277 Ability to replace a node with another node or string
```
element = Oga::XML::Element.new(:name => 'div')
some_node.replace(element)
```

You can also pass a `String` to  `replace` and it will be replaced with
a `Oga::XML::Text` node

```
some_node.replace('this will replace the current node with a text node')
```

closes #115
2015-06-17 21:27:50 +03:00
Yorick Peterse fe7e2e4f74 Use ternary "if" when encoding attribute values 2015-06-16 22:48:42 +02:00
Yorick Peterse 074b53c18c Fix entity encoding of attribute values
This ensures that single and double quotes are also encoded, previously
they would be left as is.

Fixes #113
2015-06-16 22:47:10 +02:00
Yorick Peterse e0837fd44e Fixed YARD parameter name 2015-06-16 11:14:22 +02:00
Yorick Peterse b701a9bdd4 Release 1.0.3 2015-06-16 11:13:06 +02:00
Yorick Peterse b6d34a406d Removed redundant returns 2015-06-16 00:51:51 +02:00
Yorick Peterse bcffd86c50 Removed usage of YARD @!attribute macros 2015-06-16 00:04:10 +02:00
Yorick Peterse 2c18a51ba9 Support for strict parsing of XML documents
Currently this only disabled the automatic insertion of closing tags, in
the future this may also disable other features if deemed worth the
effort.

Fixes #107
2015-06-15 23:53:11 +02:00
Yorick Peterse 4031c4f843 Nuked Oga::XML::Lexer#html
This method was rather pointless since there's already a "html?" method.
2015-06-15 23:45:20 +02:00
Yorick Peterse 020cd34083 Mark the XML lexer class as private
I was supposed to mark this as private for 1.0 but completely forgot.
2015-06-15 23:18:11 +02:00
Yorick Peterse af7f2674af Decoding of entities with numbers
This ensures that entities such as "&frac12;" are decoded properly.
Previously this would be ignored as the regular expression used for this
only matched [a-zA-Z].

This was adapted from PR #111.
2015-06-07 17:42:24 +02:00
Yorick Peterse 5951a6f187 Release 1.0.2 2015-06-03 06:53:31 +02:00
Yorick Peterse 4bfeea2590 Use require vs require_relative
See ruby-ll commit b27fe7cc109a39184ac984405a1e452868f3fac9 for a more
in-depth explanation of this.
2015-06-03 06:42:30 +02:00
Yorick Peterse d0d597e2d9 Allow script/template in various table elements
Fixes #105
2015-05-23 10:46:49 +02:00
Yorick Peterse 5182d0c488 Correct closing of unclosed, nested HTML elements
Previous HTML such as this would be lexed incorrectly:

    <div>
        <ul>
            <li>foo
        </ul>
        inside div
    </div>
    outside div

The lexer would see this as the following instead:

    <div>
        <ul>
            <li>foo</li>
            inside div
        </ul>
    outside div
    </div>

This commit exposes the name of the closing tag to
XML::Lexer#on_element_end (omitted for self closing tags). This can be
used to automatically close nested tags that were left open, ensuring
the above HTML is lexer correctly.

The new setup ignores namespace prefixes as these are not used in HTML,
XML in turn won't even run the code to begin with since it doesn't allow
one to leave out closing tags.
2015-05-23 09:59:50 +02:00
Yorick Peterse 3c6263d8de Updated list of elements that close <p> tags 2015-05-21 21:11:41 +02:00
Yorick Peterse 04948eb211 Release 1.0.1 2015-05-21 11:42:06 +02:00
Yorick Peterse 2766d5f27f Pack HTML entities using "U*"
See https://github.com/YorickPeterse/oga/issues/90#issuecomment-89859273
for more details, apparently I didn't fix this before.
2015-05-21 11:26:01 +02:00
Yorick Peterse c97c1b6899 Do not encode single/double quotes as entities
By encoding single/double quotes we can potentially break input, so lets
stop doing this. This now ensures that this:

    <foo>a"b</foo>

Is actually serialized back into the exact same instead of being
serialized into:

    <foo>a&quot;b</foo>
2015-05-21 11:23:44 +02:00
Yorick Peterse cab47f155c Release 1.0.0 2015-05-20 22:44:59 +02:00
Yorick Peterse 688a1fff0e Use blacklists/whitelists for HTML closing rules
This allows for more fine grained control over when to close certain
elements. For example, an unclosed <tr> element should be closed first
when bumping into any element other than <td> or <th>. Using the old
NodeNameSet this would mean having to list every possible HTML element
out there. Using this new setup one can just create a whitelist of the
<td> and <th> elements.
2015-05-18 00:32:29 +02:00
Yorick Peterse 132d112f5f Removed NodeNameSet class 2015-05-17 21:59:43 +02:00
Yorick Peterse cec8798694 Mark HTML_VOID_ELEMENTS as private 2015-05-17 21:59:14 +02:00
Yorick Peterse bcc101b819 Use Whitelist for HTML_VOID_ELEMENTS 2015-05-17 21:59:00 +02:00
Yorick Peterse 596a9b18d6 Use Whitelist for LITERAL_HTML_ELEMENTS 2015-05-17 21:56:38 +02:00
Yorick Peterse ca16a2976e Added Blacklist/Whitelist classes
These will be used in favour of the NodeNameSet class.
2015-05-17 21:55:06 +02:00
Yorick Peterse 1c095ddaff Added more HTML closing rules for colgroup/caption 2015-05-12 23:14:48 +02:00
Yorick Peterse 1e0b7feb02 Recursively closing of parent HTML elements
When closing certain HTML elements the lexer should also close whatever
parent elements remain. For example, consider the following HTML:

    <table>
        <thead>
            <tr>
                <th>Foo
                <th>Bar
        <tbody>
            ...
        </tbody>
    </table>

Here the "<tbody>" element shouldn't only close the "<th>Bar" element
but also the parent "<tr>" and "<thead>" elements. This ensures we'd end
up with the following HTML:

    <table>
        <thead>
            <tr>
                <th>Foo</th>
                <th>Bar</th>
            </tr>
        </thead>
        <tbody>
            ...
        </tbody>
    </table>

Instead of garbage along the lines of this:

    <table>
        <thead>
            <tr>
                <th>Foo</th>
                <th>Bar</th>
        <tbody>
            ...
        </tbody>
    </table></tr></thead>

Fixes #99 (hopefully for good this time)
2015-05-12 00:35:00 +02:00
Yorick Peterse df96b3d3bb Define the public API using YARD/semver 2015-05-11 21:34:34 +02:00
Yorick Peterse ecdeeacd76 Use Symbol#equal? instead of Symbol#==
At least on JRuby and Rubinius this can be quite a bit faster. On MRI
the difference is not really significant.
2015-05-07 23:03:03 +02:00
Yorick Peterse 5c7c4a6110 Don't use a splat with AST::Node#to_a
By using AST::Node#children directly with a splat we save ourselves an
extra method call. This in turn speeds up both the
xpath/evaluator/big_xml_average_bench.rb and
xpath/evaluator/node_matches_bench.rb benchmarks a little bit.
2015-05-07 01:23:27 +02:00
Yorick Peterse 0298e7068c Don't use Namespace#to_s when matching namespaces
This is a waste of time as it allocates a new String on every call.
2015-05-07 01:04:03 +02:00
Yorick Peterse b9145d83f8 Less html? calls in Element#available_namespaces
Previously it would always call the "html?" method, even if the
available namespaces were already set.
2015-05-07 01:02:59 +02:00
Yorick Peterse b5e63dc50e Improved perf of XPath::Evaluator#node_matches?
Using the benchmark xpath/evaluator/node_matches_bench.rb the results
prior to this commit were as following for 3 cases:

    name only:          737633 i/s
    namespace wildcard: 612196 i/s
    name wildcard:      516030 i/s

With this commit said numbers have changed to the following:

    name only:          746086  i/s
    namespace wildcard: 1097168 i/s
    name wildcard:      1151255 i/s

This results in the following increase of performance for each case:

    name only:          1,011x (insignificant)
    namespace wildcard: 1,79x
    name wildcard:      2,23x

In the benchmark xpath/evaluator/big_xml_average_bench.rb the difference
isn't really noticable as said benchmark only queries elements by names,
of which the performance hasn't really improved.
2015-05-07 00:05:25 +02:00
Yorick Peterse 69180ff686 Extra closing rules for caption/colgroup/head/body
Fixes #99
2015-05-03 01:09:07 +02:00
Yorick Peterse 4b1c296936 Automatically closing of certain HTML tags
This ensures that HTML such as this:

    <li>foo
    <li>bar

is parsed as this:

    <li>foo</li>
    <li>bar</li>

and not as this:

    <li>
        foo
        <li>bar</li>
    </li>

Fixes #97
2015-04-27 18:43:26 +02:00