The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

HTML::Object::XQuery - HTML XQuery Extension

SYNOPSIS

    use HTML::Object::DOM global_dom => 1;
    use HTML::Object::XQuery;
    my $e = HTML::Object::Element->new || die( HTML::Object::Element->error, "\n" );

VERSION

    v0.3.0

DESCRIPTION

This class extends HTML::Object::DOM::Element and provided jQuery-like methods to manipulate and query HTML objects. It is very extensive and closely mirrors jQuery api with some additional features specific to perl.

By calling use HTML::Object::DOM global_dom => 1;, this will instantiate a global DOM mimicking the one on a web page. This, in turns, enables calls such as:

    $("li")->addClass("hello");

Without the need to specify any context like:

    my $p = HTML::Object::DOM->new;
    my $context = $p->parse_file( "/path/to/some/file.html" );
    $("li", $context)->addClass("hello");

Calling use HTML::Object::DOM global_dom => 1; also enables the use of the special function $(), which is, normally, not possible in perl.

Since HTML::Object::XQuery extends HTML::Object::DOM::Element, but does not inherit from it, you cannot create a HTML::Object::XQuery object. You can simply load HTML::Object::DOM and then load HTML::Object::XQuery to extend the methods available in HTML::Object::DOM::Element

    use HTML::Object::DOM global_dom => 1;
    use HTML::Object::XQuery;
    # and the rest as usua;
    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $some_html ) || die( $p->error );
    $('div')->css({ background => 'red' });

INHERITANCE

    +--------------+     +----------------------------+     +----------------------+
    | HTML::Object | --> | HTML::Object::DOM::Element | --> | HTML::Object::XQuery |
    +--------------+     +----------------------------+     +----------------------+

METHODS

add

Create a new object with elements added to the set of matched elements.

This returns a new collection element. Contrary to what one could assume, this does not add the elements to the dom, but only to the collection.

The argument to "add" can be pretty much anything that $() ("xq") accepts, including a selector expression, elements objects, or an HTML snippet.

Takes:

  • a selector (e.g. '.some-class'); or

  • a collection (i.e. one or more elements resulting from a find or equivalent query); or

  • "HTML fragment to add to the set of matched elements."; or

  • a selector and a context (i.e. an element object); or

  • a element object

Returns a new HTML::Object::Collection object.

For example, consider:

    <ul>
      <li>list item 1</li>
      <li>list item 2</li>
      <li>list item 3</li>
    </ul>
    <p>a paragraph</p>

    $( "li" )->add( "p" )->css( "background-color", "red" );

This will select the li tags, then add the p tag to the collection set of elements objects and finally will apply the css change of background colour.

If we pass an HTML snippet as argument, such as:

    $( "li" )->add( "<p id='new'>new paragraph</p>" )
      ->css( "background-color", "red" );

The paragraph will have been created dynamically and added to the set, but is not yet part of the dom until some methods are used to insert it.

    $( "p" )->clone()->add( "<span>Again</span>" )->appendTo( "body" );

Note: To reverse the "add" you can use $e->not( elements | selector ) to remove elements from the collection results, or "end" to return to the selection before you added.

See https://api.jquery.com/add/

addClass

Provided with a css class name and this will add it to the current object, which can be either a collection object (HTML::Object::Collection), or an html element (HTML::Object::DOM::Element).

See https://api.jquery.com/addClass/

after

Insert content, specified by the parameter, after each element in the set of matched elements.

"after" and "insertAfter" methods perform the same task. The major difference is in the syntax—specifically, in the placement of the content and target. With "after", the content to be inserted comes from the method's argument:

    xq(target)->after( contentToBeInserted );

With "insertAfter", on the other hand, the content precedes the method and is inserted after the target, which in turn is passed as the "insertAfter" method's argument:

    xq(contentToBeInserted)->insertAfter(target);

For example, consider the following HTML:

    <div class="container">
      <h2>Greetings</h2>
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>

    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $html );

Content can be created and then inserted after several elements at once:

    xq( ".inner", $doc )->after( "<p>Test</p>" );

Each inner <div> element gets this new content:

    <div class="container">
      <h2>Greetings</h2>
      <div class="inner">Hello</div>
      <p>Test</p>
      <div class="inner">Goodbye</div>
      <p>Test</p>
    </div>

An element in the DOM can also be selected and inserted after another element:

    xq( ".container", $doc )->after( xq( "h2", $doc ) );

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved rather than cloned:

    <div class="container">
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>
    <h2>Greetings</h2>

You can also pass a code reference that returns the elements to insert.

    xq( "p", $doc )->after(sub {
      return "<div>" + $_->className + "</div>";
    });

https://api.jquery.com/after/

ajax

Perform an asynchronous HTTP (Ajax) request.

This takes an url and an optional hash or hash reference of parameters.

This method requires HTTP::Promise version 0.5.0 or higher to be installed.

The URL can be a contextual URL such as absolute or relative URL provided you have set the value for documentURI in class HTML::Object::DOM::Document, which is the root element of the DOM. You can access it using the getRootNode method.

For example:

    $doc->documentURI = 'https://example.com/some/where';
    my $body = $('body', $doc);
    # The URI will become https://example.com/other/path
    $body->ajax( '/other/path' )->then(sub
    {
        my( $resolve, $reject ) = @$_;
        say "Yeah!";
        # Do some work here...
    });

Below are the options supported, mirroring the ones implemented in jQuery, whenever possible:

  • accept

        $el->ajax( $url,
            accept => 'text/html, text/plain, image/*',
        )->then(sub
        (
            # do something...
        });

    String. Set the HTTP Accept header value, such as: text/html, text/plain, image/*

  • accepts

        $el->ajax( $url,
            accepts => [
                mycustomtype => 'application/x-some-custom-type',
            ],
            converters =>
            {
                mycustomtype => sub
                {
                    my $result = shift( @_ );
                    # Do Stuff
                    return( $newresult );
                },
            },
            dataType => 'mycustomtype',
        )->then(sub
        (
            # do something...
        });

    Array reference. This takes an array reference of key-value pairs, with the key being a data type and the value being the MIME-type.

    The data type thus defined should also be set with the converters option.

  • async

        my( $content, $status, $resp, $http ) = $el->ajax( $url,
            async => 0,
        ) || die( $el->error );

    Or

        $el->ajax( $url,
            # No need to specify actually, because it defaults to true.
            async => 1,
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $resp, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    Boolean. This defaults to true. This specifies whether the HTTP request is made asynchronously or synchronously.

    When the HTTP request is made asynchronously, it returns a Promise::Me object that you can use to chain then and catch methods.

    The next then method will receive an HTTP::Promise object

    When it is used synchronously, this method will return 4 values: the $content, the $status, the HTTP::Promise::Response object and the HTTP object used.

  • beforeSend

        $el->ajax( $url,
            beforeSend => sub
            {
                # Receive a HTTP::Promise::Request object
                my $req = shift( @_ );
                # Do some work
                return( $req );
                # Return undef to cancel the query
            },
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $resp, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    This is a pre-request callback function that can be used to modify the HTTP::Promise::Request object, before it is used. Use this to set custom headers, etc. The current HTTP::Promise::Request object is passed as the sole argument to the callback.

    Returning false in the beforeSend function will cancel the request. Otherwise, it expects a valid HTTP::Promise::Request object.

    Cancelling the request means the resulting values returned will be: an empty string, the status abort, undef (because there is no HTTP::Promise::Response object), and the HTTP::Promise object.

    The complete option can accept an array of code reference. Each callback will be called in turn.

  • complete

    A callback as code reference to be called when the request finishes (after success and error callbacks are executed). The callback gets passed three arguments:

    1. the HTTP::Promise::Response object; and
    2. a string categorizing the status of the request (success, notmodified, nocontent, error, timeout, abort, or parsererror); and
    3. the HTTP::Promise object
  • contents

    This option is not used.

  • contentType

    String. By default application/x-www-form-urlencoded; charset=UTF-8

    When sending data to the server, use this content type. Default is application/x-www-form-urlencoded; charset=UTF-8, which is fine for most cases. If you explicitly pass in a content-type to ajax(), then it is always sent to the server (even if no data is sent). You can pass false to tell this method to not set any content type header.

  • context

    This option is not used.

  • converters

        $el->ajax( $url,
            converters =>
            {
                "* text" => sub{ return( Module::Generic::Scalar->new( $_[0] ) ); },
                # true
                "text html" => 1,
                "text json" => sub
                {
                    my $json = shift( @_ );
                    # Do something decoding JSON
                    return( $hash_ref );
                },
                "text xml" => sub
                {
                    my $xml = shift( @_ );
                    # Decode XML
                    return( $xml_object );
                },
            },
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    An object containing dataType-to-dataType converters. Each converter's value is a function that returns the transformed value of the response.

  • crossDomain

    This option is not used.

  • data

    data can be an hash reference, a string or an array reference.

    Data to be sent to the server. If the HTTP method is one that cannot have an entity body, such as GET, the data is appended to the URL.

    When data is an hash reference, this method generates the data string from the hash reference's key/value pairs unless the processData option is set to false. For example, { a: "bc", d: "e,f" } is converted to the string "a=bc&d=e%2Cf". If the value is an array, HTTP::Promise serialises multiple values with same key based on the value of the traditional setting (described below). For example, { a: [1,2] } becomes the string "a%5B%5D=1&a%5B%5D=2" with the default traditional: false setting.

    When data is passed as a string it should already be encoded using the correct encoding for contentType, which by default is application/x-www-form-urlencoded.

  • dataFilter

        $el->ajax( $url,
            dataFilter => sub
            {
                my( $content, $dataType ) = @_;
                # Do some processing on the $content
                return( $new_content );
            },
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    A callback code reference to be used to handle the raw response data of HTTP response. This is a pre-filtering function to sanitise the response. You should return the sanitized data. The function accepts two arguments: The raw data returned from the server and the dataType parameter.

  • dataType

    The type of data that you are expecting back from the server. If none is specified, this method will try to infer it based on the MIME type of the response. The available types (and the result passed as the first argument to your success callback) are:

    • xml

          Returns a XML document that can be processed via jQuery.
    • html

          Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
    • script

          Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string parameter, _=[TIMESTAMP], to the URL unless the cache option is set to true. Note: This will turn POSTs into GETs for remote-domain requests. Prior to jQuery 3.5.0, unsuccessful HTTP responses with a script Content-Type were still executed.
    • json:

      Evaluates the response as JSON and returns a JavaScript object. Cross-domain "json" requests that have a callback placeholder, e.g. ?callback=?, are performed using JSONP unless the request includes jsonp: false in its request options. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead. (See json.org for more information on proper JSON formatting.)

    • jsonp

      Loads in a JSON block using JSONP. Adds an extra "?callback=?" to the end of your URL to specify the callback. Disables caching by appending a query string parameter, "_=[TIMESTAMP]", to the URL unless the cache option is set to true.

    • text

      A plain text string.

    • multiple, space-separated values

      This method can convert a dataType from what it received in the Content-Type header to what you require. For example, if you want a text response to be treated as XML, use text xml for the dataType. You can also make a JSONP request, have it received as text, and interpreted by this method as XML: jsonp text xml. Similarly, a shorthand string such as jsonp xml will first attempt to convert from jsonp to xml, and, failing that, convert from jsonp to text, and then from text to xml.

  • error

    A callback code reference to be called if the request fails. The callback receives three arguments:

    1. the HTTP::Promise::Request object;
    2. a string describing the type of error that occurred; and
    3. an optional exception object, if one occurred.

    Possible values for the second argument (besides null) are timeout, error, abort, and parsererror. When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as Not Found or Internal Server Error. (in HTTP/2 it may instead be an empty string). The error setting can accept an array of callbacks. Each callback will be called in turn.

  • global

    This option is not used.

    Boolean.

    Whether to trigger global Ajax event handlers for this request. The default is true. Set to false to prevent the global handlers like ajaxStart or ajaxStop from being triggered. This can be used to control various Ajax Events.

  • headers

    An object of additional header key/value pairs to send along with requests using the HTTP::Promise object. The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed here. Values in the headers setting can also be overwritten from within the beforeSend function.

  • ifModified

        $el->ajax( $url,
            ifModified =>
            {
                since => 1714023492,
                etag => '33a64df551425fcc55e4d42a148795d9f25f89d4',
                # or, explicitly specifying weak algorithm, which is superflous since it is
                # the default used in the HTTP protocol for If-None-Match
                # etag => 'W/"33a64df551425fcc55e4d42a148795d9f25f89d4"',
            },
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    This takes an hash reference with possible key since and etag

    This allows the request to be successful only if the response has changed since the last request. This is done by checking the Last-Modified header. Default value is false, ignoring the header.

    If since is provided with a value of a 10 digits integer, it will be used to issue a If-Modified-Since HTTP header.

    If etag is provided with a value of alphanumeric characters and _ and -, this will be used to issue an HTTP header If-None-Match

  • isLocal

    This option is not used.

  • jsonp

    This option is not used.

  • jsonpCallback

    This option is not used.

  • method

    This takes a string specifying the HTTP method to use for the request. Supported values are: GET, HEAD, OPTIONS, PATCH, POST, PUT. The value is case-insensitive.

  • mimeType

        # Will issue a Content-Type: application/json
        $el->ajax( $url,
            mimeType => 'application/json',
            data =>
            {
                client_id => 1234567,
                created_on => 1714023492,
            },
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    A mime type to override the HTTP mime type.

  • password

        my $url = "https://john:helloworld@example.com/some/where";
        $el->ajax( $url )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    would result in:

        GET /some/where HTTP/1.1
        Host: example.com
        Authorization: Basic am9objpoZWxsb3dvcmxk

    Or

        my $url = "https://example.com/some/where";
        $el->ajax( $url,
            username => 'john',
            password => 'helloworld',
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    would yield identical result

    A password to be used with the HTTP request in response to an HTTP access authentication request.

    This is to be used in conjonction with the username option. This will result in an HTTP header such as Authorization: Basic am9objpoZWxsb3dvcmxk

    You can also provide it as part of the URL, and it will be removed from the URL before the HTTP request is made.

  • processData

    The way the data is handled depends on their nature, i.e. whether it is an hash reference, or an array reference or a regular string.

    By default, data passed in to the data option as an hash reference or array reference (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type application/x-www-form-urlencoded. If you want to send a DOMDocument, or other non-processed data, set this option to false.

  • scriptAttrs

    This option is not used.

    Original jQuery documentation states:

    Defines an object with additional attributes to be used in a script or jsonp request. The key represents the name of the attribute and the value is the attribute's value. If this object is provided it will force the use of a script-tag transport. For example, this can be used to set nonce, integrity, or crossorigin attributes to satisfy Content Security Policy requirements.

  • scriptCharset

    This option is not used.

    Original jQuery documentation states:

    Only applies when the script transport is used. Sets the charset attribute on the script tag used in the request. Used when the character set on the local page is not the same as the one on the remote script. Alternatively, the charset attribute can be specified in scriptAttrs instead, which will also ensure the use of the script transport.

  • statusCode

    An hash reference of numeric HTTP codes and callback code reference to be called when the response has the corresponding code. For example, the following will alert when the response status is a 404:

        $el->ajax( $url,
            statusCode:
            {
                404 => sub
                {
                    warn( "page not found" );
                }
            }
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    If the request is successful, the status code callbacks take the same parameters as the success callback, i.e. $content, $status, HTTP::Promise::Response object, HTTP::Promise object; if it results in an error (including 3xx redirect), they take the same parameters as the error callback, i.e. HTTP::Promise::Request object, $status, $errorthrown.

  • success

        $el->ajax( $url,
            success => sub
            {
                my( $content, $status, $resp_object ) = @_;
                # Do something
            },
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    Or

        $el->ajax( $url,
            success => [
                sub
                {
                    my( $content, $status, $http_object ) = @_;
                    # Do something
                },
                # another callback
                sub
                {
                    my( $content, $status, $http_object ) = @_;
                    # Do something else
                },
                # and you can add more callbacks
            ],
        )->then(sub
        {
            my( $resolve, $reject ) = @$_;
            my( $content, $status, $http ) = @_;
            # Do something
        })->catch(sub
        {
            my $err = shift( @_ );
            say "An error occurred: ", $err->message;
        });

    A function to be called if the request succeeds. The function gets passed four arguments:

    1. The data returned from the server, formatted according to the dataType parameter or the dataFilter callback function, if specified;
    2. a string describing the status; and
    3. the HTTP::Promise::Response object; and
    4. the HTTP::Promise object.

    The success setting can accept an array of callbacks. Each callback will be called in turn. This is an Ajax Event.

  • timeout

    Set a timeout for the request. The value can be in seconds (an integer) or milliseconds using fractional number such as 0.25 for 250 milliseconds. See select

    A value of 0 means there will be no timeout. The timeout period starts at the point the ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent.

  • traditional

    This option is not used.

    Original jQuery documentation states:

    Set this to true if you wish to use the traditional style of param serialization.

  • type

    An alias for method.

  • url

    A string containing the URL to which the request is sent. This will override the $url argument passed to the ajax method.

  • username

    A username to be used with the HTTP request in response to an HTTP access authentication request.

    This is to be used in conjonction with the password option. This will result in an HTTP header such as Authorization: Basic am9objpoZWxsb3dvcmxk

    You can also provide it as part of the URL, and it will be removed from the URL before the HTTP request is made.

  • xhr

    Callback code reference for creating the HTTP::Promise::Request object. Override to provide your own implementation for HTTP::Promise::Request.

    This will override all parameters provided to instantiate a new HTTP::Promise::Request object. It expects a HTTP::Promise::Request object in return, or will return an error.

  • xhrFields

    This option is not used.

    Original jQuery documentation states:

    An object of fieldName-fieldValue pairs to set on the native XHR object. For example, you can use it to set withCredentials to true for cross-domain requests if needed.

https://api.jquery.com/jQuery.ajax/

See the load method>

ajaxSetup

This is still a work in progress

https://api.jquery.com/jQuery.ajaxSetup/

append

This method inserts the specified content as the last child of each element in the collection (To insert it as the first child, use "prepend").

It takes the following possible arguments:

  • an html string

  • an array reference of html strings

  • an HTML::Object::DOM::Element object

  • code reference

    Will be executed to retrieve the string

For example:

    <h2>Greetings</h2>
    <div class="container">
        <div class="inner">Hello</div>
        <div class="inner">Goodbye</div>
    </div>

This will create content and insert it into several elements at once:

    $( ".inner" )->append( "<p>Test</p>" );

Each inner <div> element gets this new content, such as:

    <h2>Greetings</h2>
    <div class="container">
        <div class="inner">
            Hello
            <p>Test</p>
        </div>
        <div class="inner">
            Goodbye
            <p>Test</p>
        </div>
    </div>

You can also select an element on the page and insert it into another:

    $( ".container" )->append( $( "h2" ) );

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned):

    <div class="container">
        <div class="inner">Hello</div>
        <div class="inner">Goodbye</div>
        <h2>Greetings</h2>
    </div>

Important: If there is more than one target element, however, cloned copies of the inserted element will be created for each target except for the last one.

Additional Arguments

Similar to other content-adding methods such as "prepend" and "before", "append" also supports passing in multiple arguments as input. Supported input includes HTML elements, collection objects, HTML strings, and arrays of HTML elements.

For example, the following will insert two new <div>s and an existing <div> as the last three child nodes of the body:

    my $newdiv1 = $( "<div id='object1'></div>" ),
    my $newdiv2 = $doc->createElement( "div" ),
    my $existingdiv1 = $doc->getElementById( "foo" );
    
    $( "body" )->append( $newdiv1, [ newdiv2, existingdiv1 ] );

https://api.jquery.com/append/

appendTo

Same as "append", except that instead of using the current object, the current object is appended to the object specified.

https://api.jquery.com/appendTo/

attr

If more than 1 values are provided, it will set the attributes with their keys and associated values.

If only one parameter is provided, this will return the corresponding value.

https://api.jquery.com/attr/

before

"before" and "insertBefore" methods perform the same task. The major difference is in the syntax—specifically, in the placement of the content and target. With "before", the content to be inserted comes from the method's argument:

    xq($target)->before( $contentToBeInserted )

With "insertBefore", on the other hand, the content precedes the method and is inserted before the target, which in turn is passed as the "insertBefore" method's argument:

    xq($contentToBeInserted)->insertBefore( $target );

    <div class="container">
      <h2>Greetings</h2>
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>

    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $html );

You can create content and insert it before several elements at once:

    xq( ".inner", $doc )->before( "<p>Test</p>" );

Each inner <div> element gets this new content:

    <div class="container">
      <h2>Greetings</h2>
      <p>Test</p>
      <div class="inner">Hello</div>
      <p>Test</p>
      <div class="inner">Goodbye</div>
    </div>

You can also select an element on the page and insert it before another:

    xq( ".container", $doc )->before( xq( "h2", $doc ) );

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved before the target (not cloned):

    <h2>Greetings</h2>
    <div class="container">
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>

https://api.jquery.com/before/

closest

Takes a selector; or a selector and an HTML::Object::DOM::Element as a context; or a HTML::Object::DOM::Element object "Given a jQuery object that represents a set of DOM elements, the .closest() method searches through these elements and their ancestors in the DOM tree and constructs a new jQuery object from the matching elements."

It returns a HTML::Object::Collection object.

https://api.jquery.com/closest/

cmp

Comparison operator between objects

css

Takes a property name; or an array reference of one or more css properties; or a property name and a value; or a property name and a function; or an hash reference of property name-value pairs

This wil set the css attribute for that element.

css_cache_check

Provided with some data and this will check the checksum to re-use the cache or not.

It returns an empty string when no cache can be re-used.

css_cache_store

Provided with some css data for this element and this will cache it.

data

Provided with a name and some value and this will set the data attribute for this element or collection of elements accordingly.

If the data provided is an hash reference, each key-value pair will be added as data attribute to the element of the collection of elements.

If only a name is provided, with no value, this will return the corresponding value.

https://api.jquery.com/data/

detach

Detach the current element or the collection of elements and return the current object.

https://api.jquery.com/detach/

each

    xq('.some-thing')->each(sub
    {
        my( $i, $e ) = @_;
        # do something
    });

Takes a code reference which receives the element position and element object as parameter.

It returns the current object it was called with.

https://api.jquery.com/each/

empty

This will empty the current element or collection of elements. This mean there will be no children elements anymore.

https://api.jquery.com/empty/

end

Sets or gets an HTML::Object::DOM::Element object.

https://api.jquery.com/end/

eq

Returns the children elements matching the value provided.

This calls "children", which returns an Module::Generic::Array object and calls "index" in Module::Generic::Array with the value provided.

https://api.jquery.com/eq/

even

Returns a new collection of elements whose position is an even number

https://api.jquery.com/even/

exists

Provided an xpath and this will check if the current object exists in the xpath provided.

filter

Takes a selector; or function with arguments are element position (starting from 0) and the element itself, expecting a true value in return; or an array of element objects; or an element object;

https://api.jquery.com/filter/

find

Takes a selector; or Element object

https://api.jquery.com/find/

find_xpath

Provided with an xpath value and this will find and return all matches.

findnodes

Provided with an xpath value and this will find and return all nodes.

findnodes_as_string

Provided with an xpath value and this will find and return all nodes as string.

findnodes_as_strings

Same as "findnodes_as_string", but plural

Provided with an xpath value and this will find and return all nodes as strings.

findvalue

Provided with an xpath value and this will find and return node value.

findvalues

Same as "findvalue", but plural

Provided with an xpath value and this will find and return nodes value.

first

Returns the first element of the collection if the object is a collection, or the element itself.

https://api.jquery.com/first/

get

Returns the current element.

Originally, in jQuery, this returns the underlying DOM element, but here, in perl context, this does not mean much, and we return our own object.

https://api.jquery.com/get/

getDataJson

    <div data-options='{"customer_id": 123, "issued_on": 1713832131}'></div>
    # or, URI encoded
    <div data-options="%7B%22customer_id%22%3A%20123%2C%20%22issued_on%22%3A%201713832131%7D"></div>
    my $elem = $('[data-options]', $doc);
    my $ref = $elem->getDataJson( 'options' );

This method takes the name of the data attribute for the element it is being called on, and returns an hash reference of the JSON data stored.

If this is called on a collection, then it will use the first element in the collection.

Once the JSON decoded, its associated hash reference will be saved in place so that following calls returns it much faster.

If there is no data, it returns an empty hash, but if there is an error, such as decoding the JSON data, then it will set an exception object and return undef in scalar context, or an empty list in list context.

getJSON

    $el->getJSON( $url )->then(sub
    {
        my( $resolve, $reject ) = @$_;
        my( $hash_ref, $status, $resp, $http ) = @_;
        # Do something
    })->catch(sub
    {
        my $err = shift( @_ );
        say "Oh no: $err";
    });

or, with both the data and the success callback specified:

    $el->getJSON( $url, {
        client_id => 1234567,
        tag => 'something',
    }, sub
    {
        # or an array reference depending on the JSON data structure
        my( $hash_ref, $status, $resp, $http ) = @_;
        # Do something
    })->then(sub
    {
        my( $resolve, $reject ) = @$_;
        my( $hash_ref, $status, $resp, $http ) = @_;
        # Do something
    })->catch(sub
    {
        my $err = shift( @_ );
        say "Oh no: $err";
    });

or, with the success callback first, then the data to be sent:

    $el->getJSON( $url, sub
    {
        # or an array reference depending on the JSON data structure
        my( $hash_ref, $status, $resp, $http ) = @_;
        # Do something
    },
    {
        client_id => 1234567,
        tag => 'something',
    })->then(sub
    {
        my( $resolve, $reject ) = @$_;
        my( $hash_ref, $status, $resp, $http ) = @_;
        # Do something
    })->catch(sub
    {
        my $err = shift( @_ );
        say "Oh no: $err";
    });

or, with just the data provided. You can also just provide the success callback instead:

    $el->getJSON( $url, 
    {
        client_id => 1234567,
        tag => 'something',
    })->then(sub
    {
        my( $resolve, $reject ) = @$_;
        my( $hash_ref, $status, $resp, $http ) = @_;
        # Do something
    })->catch(sub
    {
        my $err = shift( @_ );
        say "Oh no: $err";
    });

Load JSON-encoded data from the server using a GET HTTP request.

This takes an URL, an optional data that can be an hash reference, an array reference or a regular string, an optional success callback code reference. The URL is the first argument, but the data and success arguments can be in any order.

The URL can be a file:// URI, and you can even use contextual URL such as absolute or relative URL provided you have set the value for documentURI in class HTML::Object::DOM::Document, which is the root element of the DOM. You can access it using the getRootNode method.

For example:

    $doc->documentURI = 'https://example.com/some/where';
    my $body = $('body', $doc);
    # The URI will become https://example.com/other/path
    $body->getJSON( '/other/path.json' )->then(sub
    {
        my( $resolve, $reject ) = @$_;
        say "Yeah!";
        # Do some work here...
    });

This is a shorthand Ajax method, which is equivalent to:

    $el->ajax({
        dataType => "json",
        url      => $url,
        data     => $data,
        success  => $success
    });

Returns a Promise::Me object.

This method requires HTTP::Promise version 0.5.0 or higher to be installed.

Data that is sent to the server is appended to the URL as a query string. If the value of the data parameter is a plain object, it is converted to a string and url-encoded before it is appended to the URL.

Most implementations will specify a success handler:

    use Class::Array;
    $el->getJSON( "ajax/test.json", sub
    {
        my $data = shift( @_ );
        my $items = Class::Array->new([]);
        Class::Array->new( $data )->each(sub
        {
            my( $key, $val ) = @_;
            $items->push( "<li id='" . $key . "'>" . $val . "</li>" );
        });
        
        $( "<ul/>", 
        {
            class => 'my-new-list',
            html -> $items->join( '' )
        })->appendTo( 'body' );
    });

This example, of course, relies on the structure of the JSON file:

    {
        "one": "Singular sensation",
        "two": "Beady little eyes",
        "three": "Little birds pitch by my doorstep"
    }

Using this structure, the example loops through the requested data, builds an unordered list, and appends it to the body.

The success callback is passed the returned data, which is typically an hash reference or array reference as defined by the JSON structure and parsed using the "decode" in JSON method. It is also passed the text status of the response and the HTTP::Promise::Response object.

getJSON() implements the Promise interface, giving it all the properties, methods, and behavior of a Promise, namely "then" in Promise::Me and "catch" in Promise::Me

It is different from the jQuery interface that implements the methods done, fail and always

    my $promise = $el->getJSON( 'example.json', sub
    {
        say( "success" );
    })->then(sub
    {
        say( "second success" );
    })->catch(sub
    {
        say( "error" );
    });

Example:

Loads the four most recent pictures of Mount Rainier from the Flickr JSONP API.

    my $html = <<EOT+
    <!doctype html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>getJSON demo</title>
            <style>
            img {
                height: 100px;
                float: left;
            }
            </style>
        </head>
        <body>
            <div id="images"></div>
        </body>
    </html>
    EOT

    my $p = HTML::Parser->new;
    my $doc = $p->parse( $html ) || die( $p->error );
    my $body = $('body', $doc);
    use Class::Array;

    my $flickerAPI = 'https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?';
    $body->getJSON( $flickerAPI, 
    {
        tags => "mount rainier",
        tagmode => "any",
        format => "json",
    })->then(sub
    {
        my $data = shift( @_ );
        Class::Array->new( $data->items )->each(sub
        {
            my( $i, $item ) = @_;
            $( '<img>' )->attr( 'src', $item->{media}->{m} )->appendTo( '#images' );
            if( $i === 3 )
            {
                return(0);
            }
        });
    });

Load the JSON data from test.js and access a name from the returned JSON data.

    $body->getJSON( 'test.js', sub
    {
        my $json = shift( @_ );
        say( "JSON Data: " . $json->{users}->[3]->{name} );
    });

Load the JSON data from test.js, passing along additional data, and access a name from the returned JSON data. If an error occurs, report an error message instead.

    $body->getJSON( 'test.js', { name => 'John', time => '2pm' } )->then(sub
    {
        my $json = shift( @_ );
        say( "JSON Data: " . $json->{users}->[3]->{name} );
    })->catch(sub
    {
        my( $resp, $textStatus, $error ) = @_;
        my $err = $textStatus . ", " . $error;
        say( "Request Failed: " . $err );
    });

head2 has

"has" method constructs a new HTML::Object::Collection object from a subset of the original object on which it is called, and that only includes elements with descendants that match the given selector.

Let’s say you wanted to find all paragraphs that have links in them. You’d use:

    my $paragraphs = $xq('p', $doc);
    my $paragraphsWithLinks = $paragraphs->has('a');

The difference with the "find" method[1], is that rather than returning a subset of the object on which it is called, returns a HTML::Object::Collection object representing the elements that match the given selector that are descendants of the original object.

So, similar to the above example, instead of selecting paragraphs that have links in them, we instead get the links themselves that are inside paragraphs:

    my $paragraphs = $xq('p', $doc); 
    my $linksInParagraphs = $paragraphs->find('a');

[1] Paraphrasing the explanation provided by Andy Farrell

See also "children", "filter", "find"

https://api.jquery.com/has/

hasClass

Provided with a css class name and this will returns true if the current element has this class, or false otherwise.

https://api.jquery.com/hasClass/

hide

This is roughly equivalent to calling "css"( "display", "none" ), except that the value of the display property is saved in the object's internal data cache so that display can later be restored to its initial value. If an element has a display value of inline and is hidden then shown, it will once again be displayed inline.

It takes 1 or 2 argument. THe first one originally in jQuery is either a timer in millisecond or an easing effect or some option hash, but since none of this has any effect under perl, the first argument is ignored.

    $elem->hide( $hash_ref, sub{ $_->show() });

However, if there is only one argument and it is a code reference, it is used.

    $elem->hide( sub{ $_->show() });

The optional second argument is a code reference (a callback) that will be called passing it the element object.

It returns the object used to call this method in the first place.

    $elem->hide->show(); # Kind of meaningless, but hey this is an example

https://api.jquery.com/hide/

html

When no argument is provided, this returns the html string of its content for element object, or the html string of the content of the first object if this is a collection object, i.e. a HTML::Object::Collection object.

    my $html_string = $element->html();
    # or, here this is a collection object
    xq('body', $doc)->html();
    # or if this is a single html element object
    xq('body', $doc)->first->html();

When an argument is provided, it takes either some html data as a string, or a code reference.

In the case of a code reference, it is called with the element position, starting at 0 and the old html data string. It expects in returns either:

1. an empty or undefined value, in which case the current element will have its content emptied using "empty"
2. some html data, in which case it is parsed using "parse_data" in HTML::Object::DOM and the object found are used to replace the content of the current element object.
3. an HTML::Object::DOM::Element object whose content elements will be used in replacement of the content of the current object

Quoting jQuery documentation, for example, consider this html:

    <div class="demo-container">
      <div class="demo-box">Demonstration Box</div>
    </div>

Assuming this html is stored in a variable $html:

    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $html ) || die( $p->error, "\n" );

The content of <div class="demo-container"> can be set like this:

    xq( "div.demo-container", $doc )
      ->html( "<p>All new content. <em>You bet!</em></p>" );

That line of code will replace everything inside <div class="demo-container">:

    <div class="demo-container">
      <p>All new content. <em>You bet!</em></p>
    </div>

Or

    xq( "div.demo-container", $doc )->html(sub {
      my $emphasis = "<em>" + $xq( "p", $doc )->length + " paragraphs!</em>";
      return "<p>All new content for " + emphasis + "</p>";
    });

Afer the html value is set, it returns the object it was called with.

To set the content of a <script> element, which does not contain HTML, use the "text" method and not "html".

https://api.jquery.com/html/

index

Search for a given element from among the matched elements.

When no argument is provided, the return value is an integer indicating the position of the element, starting from 0, within its parent.

If "index" is called on a collection of elements (i.e. a HTML::Object::Collection object) and an element object (HTML::Object::DOM::Element) is provided as argument, "index" returns an integer indicating the position of the provided element relative to the original collection.

This would behave as a complementary operation to "get", which accepts an index and returns a element object. Under jQuery, "get" would return DOM element, but there is no such thing in this perl context.

If a selector string is passed as an argument, "index" returns an integer indicating the position of the first element within the object relative to the elements matched by the selector. If the element is not found, -1 will be returned.

For example, consider the following html:

    <ul>
      <li id="foo">foo</li>
      <li id="bar">bar</li>
      <li id="baz">baz</li>
    </ul>

    my $p = HTML::Object::DOM->new;
    my $document = $p->parse_data( $html );

If we retrieve one of the three list items (for example, through one of the element object's functions), "index" can search for this list item within the set of matched elements:

    my $listItem = $document->getElementById( "bar" );
    say( "Index: " + xq( "li", $document )->index( $listItem ) );

We get back the zero-based position of the list item:

    Index: 1

Note that if a collection object (HTML::Object::Collection) is used as the "index" method's argument and it contains more than one element, the first element within that collection will be used.

If we use a string as the "index" method's argument, it is interpreted as a selector string. The first element among the HTML::Object::Collection object's matched elements which also matches this selector is located. If the object is just one HTML::Object::DOM::Element object, the selector is tested against it.

    my $listItem = xq( "#bar", $document );
    say( "Index: " + $listItem->index( "li" ) );

Or, using a single HTML::Object::DOM::Element, the same will check against that element alone.

    my $element = xq( "#bar", $document )->first();
    say( "Index: " + $listItem->index( "li" ) );

Without any arguments, "index" will return the position of the first element, if this is a HTML::Object::Collection, in relation to its siblings, or the position of the element itself if this is just an HTML::Object::DOM::Element

    say( "Index: " + xq( "#bar", $document )->index() );

https://api.jquery.com/index/

insertAfter

Insert every element in the set of matched elements after the target.

The target can be one of a selector, an element object (HTML::Object::DOM::Element), an array of elements objects, or an HTML string.

if the current object is a collection, all of its elements contained will be inserted after the target.

If the current object is just an HTML::Object::DOM::Element object, it will be moved (not copied) after the target.

"after" and "insertAfter" perform the same task. The major difference is in the syntax—specifically, in the placement of the content and target. With "after", the object used to call the method is the container after which the content is inserted. While with "insertAfter", it is the opposite.

For example, consider the following HTML:

    <div class="container">
      <h2>Greetings</h2>
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>

    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $html );

We can create content and insert it after several elements at once:

    xq( "<p>Test</p>", $doc )->insertAfter( ".inner" );

Each inner ≤div> element gets this new content:

    <div class="container">
      <h2>Greetings</h2>
      <div class="inner">Hello</div>
      <p>Test</p>
      <div class="inner">Goodbye</div>
      <p>Test</p>
    </div>

We can also select an element on the page and insert it after another:

    xq( "h2", $doc )->insertAfter( xq( ".container", $doc ) );

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved after the target (not cloned) and a new set consisting of the inserted element is returned:

    <div class="container">
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>
    <h2>Greetings</h2>

If there is more than one target element, however, cloned copies of the inserted element will be created for each target after the first, and that new set (the original element plus clones) is returned.

https://api.jquery.com/insertAfter/

insertBefore

Insert every element in the set of matched elements before the target.

The target can be one of a selector, an element object (HTML::Object::DOM::Element), an array of elements objects, or an HTML string.

if the current object is a collection, all of its elements contained will be inserted before the target.

If the current object is just an HTML::Object::DOM::Element object, it will be moved (not copied) before the target.

"before" and "insertBefore" perform the same task. The major difference is in the syntax—specifically, in the placement of the content and target. With "before", the object used to call the method is the container before which the content is inserted. While with "insertBefore", it is the opposite.

For example, consider the following HTML:

    <div class="container">
      <h2>Greetings</h2>
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>

    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $html );

We can create content and insert it before several elements at once:

    xq( "<p>Test</p>", $doc )->insertBefore( ".inner" );

Each inner ≤div> element gets this new content:

    <div class="container">
      <h2>Greetings</h2>
      <p>Test</p>
      <div class="inner">Hello</div>
      <p>Test</p>
      <div class="inner">Goodbye</div>
    </div>

We can also select an element on the page and insert it before another:

    xq( "h2", $doc )->insertBefore( xq( ".container", $doc ) );

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved before the target (not cloned) and a new set consisting of the inserted element is returned:

    <h2>Greetings</h2>
    <div class="container">
      <div class="inner">Hello</div>
      <div class="inner">Goodbye</div>
    </div>

If there is more than one target element, however, cloned copies of the inserted element will be created for each target after the first, and that new set (the original element plus clones) is returned.

https://api.jquery.com/insertBefore/

is

Check the current matched set of elements against a selector, HTML::Object::DOM::Element, HTML::Object::Collection or a code reference and return true if at least one of these elements matches the given arguments.

Unlike other filtering methods, "is" does not create a new object. Instead, it allows you to test the contents of an object (element or collection) without modification.

Suppose you have a list, with two of its items containing a child element:

    <ul>
      <li>list <strong>item 1</strong></li>
      <li><span>list item 2</span></li>
      <li>list item 3</li>
    </ul>

    my $p = HTML::Object::DOM->new;
    my $doc = $p->parse_data( $html ) || die( $p->error );

You can check if an object is one of the li's like:

    if( $elem->is( 'li' ) )
    {
        # Make the background red
        $elem->css( "background-color", "red" );
    }

"is" can also evaluate expressions related to elements based on a code reference rather than a selector. For each element, if the code reference returns true, "is" returns true as well. For example, given a somewhat more involved HTML snippet:

    <ul>
      <li><strong>list</strong> item 1 - one strong tag</li>
      <li><strong>list</strong> item <strong>2</strong> -
        two <span>strong tags</span></li>
      <li>list item 3</li>
      <li>list item 4</li>
      <li>list item 5</li>
    </ul>

$li here is an element that you have defined earlier in your code.

    my $isWithTwo = $li->is(sub {
        return xq( "strong", $_ )->length == 2;
    });
    if( $isWithTwo ) 
    {
        $li->css( "background-color", "green" );
    } 
    else
    {
        $li->css( "background-color", "red" );
    }

Or

    <form>
      <input type="checkbox">
    </form>
    <div></div>

    my $isFormParent = xq( "input[type='checkbox']", $doc )->parent()->is( "form" );
    xq( "div", $doc )->text( "isFormParent = " + $isFormParent );

Checks against an existing collection of alternating list elements. Blue, alternating list elements set background to yellow while others turn red.

    <ul id="browsers">
      <li>Chrome</li>
      <li>Safari</li>
      <li>Firefox</li>
      <li>Opera</li>
    </ul>
 
    my $alt = xq( "#browsers li:nth-child(2n)", $doc )->css( "background", "#0ff" );
    my $li = xq( "li" );
    if( $li->is( $alt ) )
    {
        $li->css( "background", "yellow" );
    }
    else
    {
        $li->css( "background", "red" );
    }

See https://api.jquery.com/is/

isa_collection

Returns true if the current element is a HTML::Object::Collection object, or false otherwise.

length

Returns the number of children if the current element is a collection, or 1 if the current element is an element.

load

    $e->load( $uri );
    # or
    $e->load( $uri, { key1 => value1, key2 => value2 } );
    # or
    $e->load( $uri, $callback_subroutine );
    # or
    $e->load( $uri, { key1 => value1, key2 => value2 }, $callback_subroutine );

The callback function receives 3 arguments: $responseContent, $textStatus and $responseObject

This method fetches data from the given uri and, when a successful response is detected (i.e. when textStatus is success or notmodified), "load" sets the HTML contents of the matched elements to the returned data. This means that most uses of the method can be quite simple:

    $( "#result" )->load( "https://example.com/some/test.html" );

The URL can be a file:// URI, and you can even use contextual URL such as absolute or relative URL provided you have set the value for documentURI in class HTML::Object::DOM::Document, which is the root element of the DOM. You can access it using the getRootNode method.

For example:

    $doc->documentURI = 'https://example.com/some/where';
    my $body = $('body', $doc);
    # The URI will become https://example.com/other/path
    $body->load( '/other/path', sub
    {
        my( $data, $textStatus, $httpResponse ) = @_;
        say "Yeah!";
        # Do some work here...
    });

Upon error, be it internal, or when the returned http code is not a 2XX code, $textStatus is set to error

If no element is matched by the selector — in this case, if the document does not contain an element with id="result" — the http request will not be sent.

It returns the current element object upon success, or upon error, sets an error and returns undef.

This methods uses LWP::UserAgent to do the work and it must be installed as well as URI, or else this method will return an error.

The uri provided must be an absolute URI, or LWP::UserAgent will return an error.

Callback subroutine

If a callback subroutine is provided, it is executed after post-processing of the HTML with HTML::Object::DOM and insertion of the HTML element objects have been performed. The callback is fired once for each element in the object collection, and $_ is set to each element object in turn.

    $( "#result" )->load( "/somewhere/test.html", sub
    {
        print( "Load was performed.\n" );
    });

The $responseObject is a HTTP::Response object.

The $responseContent is an utf8 decoded (i.e. perl internal utf8) text string.

Request method

The POST method is used if data is provided as an hash reference; otherwise, GET is assumed.

Loading page fragments

This method makes it possible to specify a portion of the remote document to be inserted. This is achieved with a special syntax for the uri parameter. If one or more space characters are included in the string, the portion of the string following the first space is assumed to be a selector that determines the content to be loaded. For example:

    $( "#result" )->load( "/somewhere/test.html #container" );

Upon execution, this method retrieves the content of /somewhere/test.html, but then HTML::Object::DOM parses the returned document to find the element with an ID of container. This element, along with its contents, is inserted into the element with an ID of result, and the rest of the retrieved document is discarded.

For example, given the following HTML document:

    <!DOCTYPE html>
    <html lang="en-GB">
        <head>
            <meta charset="utf-8" />
            <title>load demo</title>
            <meta name="generator" content="BBEdit 13.5" />
        </head>
        <body>
            <b>Projects:</b>
            <ol id="new-projects"></ol>
        </body>
    </html>

We could do:

    use HTML::Object::DOM;
    use Module::Generic::File qw( file );
    my $parser = HTML::Object::DOM->new;
    my $doc = $parser->parse( $html ) || die( $parser->error );
    HTML::Object::DOM->set_dom( $doc );
    my $part = file( "./resources/load.html" );
    my $uri  = $part->uri; # e.g. file:///home/joe/www/resources/load.html
    $( "#new-projects" )->load( "$uri #projects li" );

This would make the following change to the html:

    <ol id="new-projects"><li>jQuery</li><li>jQuery UI</li><li>jQuery Mobile</li><li>QUnit</li><li>Sizzle</li></ol>

Error handling

If an error occurs, the $textStatus would be set to error, which you can check as follows:

$( "#success" ).load( "https://example.org/not-here.html", sub { my( $content, $status, $resp ) = @_; if( $status == "error" ) { my $msg = "Sorry but there was an error: "; $( "#error" )->html( $msg . $resp->code . " " . $resp->message ); } });

See also jQuery documentation on load

map

Provided with a code reference, and this will execute on each of the children.

matches

Provided with a xpath and this will return all matching nodes.

name

Sets or gets the name attribute.

new_attribute

Provided with an hash or hash reference of parameters, and this will return a new HTML::Object::DOM::Attribute object by passing it the parameters.

new_collection

Provided with an hash or hash reference of parameters, and this will return a new HTML::Object::Collection object by passing it the parameters.

new_parser

This will return a new HTML::Object::DOM object.

new_root

Provided with an hash or hash reference of parameters, and this will return a new HTML::Object::DOM::Root object by passing it the parameters.

not

Takes a selector expression; or a element object; or a collection of elements; or an array of element objects to match against the set.

It returns all elements that do not match.

https://api.jquery.com/not/

odd

Returns a new collection of elements whose position is an even number

https://api.jquery.com/odd/

prepend

Takes html string (start with <tag...), text object (HTML::Object::DOM::Text), array or element object or alternatively a code reference that returns the above

https://api.jquery.com/prepend/

prependTo

https://api.jquery.com/prependTo/

promise

Provided with a code reference to be executed asynchronously and this will return a Promise::Me object.

    my $p = $e->promise(sub
    {
       # Some regular code here
    })->then(sub
    {
       my $res = shift( @_ ); # return value from the code executed above
       # more processing...
    })->then(sub
    {
       my $more = shift( @_ ); # return value from the previous then
       # more processing...
    })->catch(sub
    {
       my $exception = shift( @_ ); # error that occured is caught here
    })->finally(sub
    {
       # final processing
    })->then(sub
    {
       # A last then may be added after finally
    };

remove

If the current object is a collection, this will remove all of its children. Otherwise, if this is an element, it will simply remove it.

You can also provide an xpath as an argument and the matching nodes will be removed.

removeAttr

Provided with an attribute name and this will remove it from the collection if the current element is a collection, or from the current element itself if it is a HTML::Parser::Element object.

It returns the current object.

https://api.jquery.com/removeAttr/

removeClass

Provided with a class name and this will remove it from the current element or the current collection.

https://api.jquery.com/removeClass/

replaceWith

Takes html string, array of elements, an element (including a collection object) or a code reference and this will replace the current element with the new element.

https://api.jquery.com/replaceWith/

set_namespace

Set the new namespace for the current node.

show

Since this is a perl context, this only set the inline css 1) back to its previous value, if any; or 2) remove the display property if there was no previous value set.

Any parameter provided will be ignored

See the hide() method for its alter ego.

https://api.jquery.com/show/

string_value

Returns "value" if the current element is comment node. Otherwise, returns "as_text"

tagname

Returns the tag name for the current element.

text

When no argument is provided, this returns the combined text contents, as a scalar object of each element in the set of matched elements, including their descendants.

    my $text = $element->text();
    # or, here this is a collection object
    xq('body', $doc)->text();
    # or if this is a single html element object
    xq('body', $doc)->first->text();

When an argument is provided, it takes either some text data as a string, or a code reference.

In the case of a code reference, it is called with the element position, starting at 0 and the old text data string. It expects in returns either:

1. an empty or undefined value, in which case the current element will have its content emptied using "empty"
2. some text data, and the content of the current element object will be replaced.

Be mindful that this method will add the data as is, and will not treat it as HTML if some were provided. Thus, if some HTML were provided, it would be escaped in order to be rendered properly.

Quoting jQuery documentation, for example, consider this html:

    <div class="demo-container">
        <div class="demo-box">Demonstration Box</div>
        <ul>
            <li>list item 1</li>
            <li>list <strong>item</strong> 2</li>
        </ul>
    </div>

The code $( "div.demo-container" )->text( "<p>This is a test.</p>" ); will produce the following DOM output:

    <div class="demo-container">
        &lt;p&gt;This is a test.&lt;/p&gt;
    </div>

It will appear on a rendered page as though the tags were exposed, like this:

    <p>This is a test</p>

The text() method cannot be used on input elements. For input field text, use the val() method.

Afer the text value is set, it returns the object it was called with.

https://api.jquery.com/text/

toggleClass

Takes a class name; or class name and state (true or false); or array of class names; or array of class names and a state; or a code reference called with the index position of the current class and its name. Returns a space separated list of classes or an array

https://api.jquery.com/toggleClass/

to_number

Returns a new HTML::Object::DOM::Number object by passing it the current node value ("getValue")

toString

Returns the current node value as "as_xml"

xp

Returns an already instantiated XML::XPathEngine object, or instantiate one and returns it.

xq

Ref: <https://api.jquery.com/Types/#jQuery>

    xq( '#myId', $document )
    xq( '<div />', { id => 'Pouec', class => 'Hello' } );
    xq( '<html><head><title>Hello world</title></head><body>Hello!</body></html>' );
    xq();

PRIVATE METHODS

_append_prepend

Called by "append" and "prepend" to do the heavy work.

_append_prepend_to

Takes html string; or selector; or element object; or array of objects; or collection "If there is more than one target element, however, cloned copies of the inserted element will be created for each target except the last, and that new set (the original element plus clones) is returned."

Called by "append_to" and "prepend_to" to do the heavy work.

_before_after

Takes html string (start with <tag...), text object (HTML::Object::DOM::Text), array or element object or alternatively a code reference that returns the above

_child_as_object

called on a parent, with a child as second argument and its rank as third returns the child if it is already an element, or a new HTML::Object::DOM::Text element if it is a plain string

_compare

Takes another element and compares the current one to it. Returns true if they are the same, false otherwise.

It achieves this by check if the current element "eid" in HTML::Object::Element is same, of if the element is a collection it check it is of the same size and the other element is among the collection.

_css_object

If argument is provided, pass a CSS::Object::Builder::Rule object

If no argument is provided, get a CSS::Object::Builder::Rule of the inline css, if any at all.

Returns undef if no css attribute is set yet.

_css_builder

Returns a new CSS*:Object object using the format set to CSS::Object::Format::Inline.

_insert_before_after

Takes selector, html, element or array

    xq( '<p>Test</p>' )->insertBefore( xq( '.inner', $doc ) );
    $elem->insertBefore( '.inner' );

_is_html

Returns true if the data provided looks like html, or false otherwise.

_is_same_node

Returns true if the current element and the provided element have he same "eid"t

_xpath_value

Returns the xpath value fot the current element

ERROR HANDLING

Methods in this package returns undef either because no value is available, or because an error occurred

You can find out about an error after a method call by calling error, such as:

    # Try to change the tag name
    my $rv = $e->tag( $something );
    die( $e->error ) if( !defined( $rv ) );

But keep in mind that an undefined value returned does not necessarily means there was an error. Consider:

    my $div = $('<div />', { class => 'hello' });
    my $id = $div->attr( 'id' );

$id will be undefined because there is no 'id' attribute set, and this is not an error.

If you are using the global dom feature, you can get the posible errors like this:

    $('#someId')->load( '/some/where.html' ) || die( HTML::Object::DOM->error );

"error" in HTML::Object::DOM is guaranteed to be set upon error. You can also get the global variable $HTML::Object::DOM::ERROR

If you prefer, you can choose to make every error fatal and catch them with a try-catch implementation like Nice::Try

    use HTML::Object::DOM
    $HTML::Object::DOM::FATAL_ERROR = 1;
    # or
    use HTML::Object::DOM fatal_error => 1;
    use Nice::Try;

    try
    {
        # Try to change the tag name
        $e->tag( $something );
    }
    catch( $ex )
    {
        die( "Could not change the tag name: ", $ex->message );
    }

Or, if you wanted to filter the exception by class:

    try
    {
        # Try to change the tag name
        $e->tag( $something );
    }
    catch( HTML::Object::Exception $ex )
    {
        die( "An HTML::Object::DOM error occurred: ", $ex->message );
    }
    catch( $ex )
    {
        die( "Caught an exception: $ex\n" );
    }

Note that HTML::Object::Exception object has stringification capability so you can embed it in a string:

    die( "Could not change the tag name: $ex\n" );

TODO

addBack

https://api.jquery.com/addBack/

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

HTML::Object::DOM, HTML::Object::DOM::Attribute, HTML::Object::DOM::Boolean, HTML::Object::DOM::Closing, HTML::Object::DOM::Collection, HTML::Object::DOM::Comment, HTML::Object::DOM::Declaration, HTML::Object::DOM::Document, HTML::Object::DOM::Element, HTML::Object::Exception, HTML::Object::DOM::Literal, HTML::Object::DOM::Number, HTML::Object::DOM::Root, HTML::Object::DOM::Space, HTML::Object::DOM::Text, HTML::Object::XQuery

COPYRIGHT & LICENSE

Copyright (c) 2021 DEGUEST Pte. Ltd.

All rights reserved

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.