From dffa760c04824431cbfdf04f4a8eb4034b905891 Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Mon, 7 Mar 2016 10:27:56 +0000 Subject: [PATCH] Fix issue #267 by ignoring hash URIs when making URIs absolute --- Readability.js | 7 +- test/test-pages/base-url/expected.html | 3 + test/test-pages/base-url/source.html | 3 + test/test-pages/ietf-1/expected.html | 218 ++++++++++++------------ test/test-pages/mozilla-1/expected.html | 6 +- test/test-readability.js | 18 +- 6 files changed, 141 insertions(+), 114 deletions(-) diff --git a/Readability.js b/Readability.js index d5c1bd0..f617fda 100644 --- a/Readability.js +++ b/Readability.js @@ -192,7 +192,8 @@ Readability.prototype = { }, /** - * Converts each and uri in the given element to an absolute URI. + * Converts each and uri in the given element to an absolute URI, + * ignoring #ref URIs. * * @param Element * @return void @@ -219,6 +220,10 @@ Readability.prototype = { if (uri.indexOf("./") === 0) return pathBase + uri.slice(2); + // Ignore hash URIs: + if (uri[0] == "#") + return uri; + // Standard relative URI; add entire path. pathBase already includes a // trailing "/". return pathBase + uri; diff --git a/test/test-pages/base-url/expected.html b/test/test-pages/base-url/expected.html index 472451a..c06f1fd 100644 --- a/test/test-pages/base-url/expected.html +++ b/test/test-pages/base-url/expected.html @@ -5,6 +5,9 @@

link

link

link

+

link

+

link

+

link

link

link

Images

diff --git a/test/test-pages/base-url/source.html b/test/test-pages/base-url/source.html index 2e4699e..748b8be 100644 --- a/test/test-pages/base-url/source.html +++ b/test/test-pages/base-url/source.html @@ -19,6 +19,9 @@

link

link

link

+

link

+

link

+

link

link

link

Images

diff --git a/test/test-pages/ietf-1/expected.html b/test/test-pages/ietf-1/expected.html index a68c9bf..49db676 100644 --- a/test/test-pages/ietf-1/expected.html +++ b/test/test-pages/ietf-1/expected.html @@ -49,49 +49,49 @@ Copyright Notice publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must - include Simplified BSD License text as described in Section 4.e of + include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. de Jong [Page 1] -

+

 Internet-Draft              remoteStorage                  December 2014
 
 
 Table of Contents
 
-   1. Introduction...................................................2
-   2. Terminology....................................................3
-   3. Storage model..................................................3
-   4. Requests.......................................................4
-   5. Response codes.................................................7
-   6. Versioning.....................................................7
-   7. CORS headers...................................................8
-   8. Session description............................................8
-   9. Bearer tokens and access control...............................9
-  10. Application-first bearer token issuance.......................10
-  11. Storage-first bearer token issuance...........................11
-  12. Example wire transcripts......................................12
-     12.1. WebFinger................................................12
-     12.2. OAuth dialog form........................................13
-     12.3. OAuth dialog form submission.............................14
-     12.4. OPTIONS preflight........................................15
-     12.5. Initial PUT..............................................15
-     12.6. Subsequent PUT...........................................16
-     12.7. GET......................................................16
-     12.8. DELETE...................................................17
-  13. Distributed versioning........................................17
-  14. Security Considerations.......................................19
-  15. IANA Considerations...........................................20
-  16. Acknowledgments...............................................20
-  17. References....................................................21
-     17.1. Normative References.....................................21
-     17.2. Informative References...................................21
-  18. Authors' addresses............................................22
-
-
-1.  Introduction
+   1. Introduction...................................................2
+   2. Terminology....................................................3
+   3. Storage model..................................................3
+   4. Requests.......................................................4
+   5. Response codes.................................................7
+   6. Versioning.....................................................7
+   7. CORS headers...................................................8
+   8. Session description............................................8
+   9. Bearer tokens and access control...............................9
+  10. Application-first bearer token issuance.......................10
+  11. Storage-first bearer token issuance...........................11
+  12. Example wire transcripts......................................12
+     12.1. WebFinger................................................12
+     12.2. OAuth dialog form........................................13
+     12.3. OAuth dialog form submission.............................14
+     12.4. OPTIONS preflight........................................15
+     12.5. Initial PUT..............................................15
+     12.6. Subsequent PUT...........................................16
+     12.7. GET......................................................16
+     12.8. DELETE...................................................17
+  13. Distributed versioning........................................17
+  14. Security Considerations.......................................19
+  15. IANA Considerations...........................................20
+  16. Acknowledgments...............................................20
+  17. References....................................................21
+     17.1. Normative References.....................................21
+     17.2. Informative References...................................21
+  18. Authors' addresses............................................22
+
+
+1.  Introduction
 
     Many services for data storage are available over the internet. This
     specification describes a vendor-independent interface for such
@@ -105,7 +105,7 @@ Table of Contents
 
 
 de Jong                                                         [Page 2]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -124,11 +124,11 @@ Table of Contents
     The exact details of these four actions are described in this
     specification.
 
-2. Terminology
+2. Terminology
 
     The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
     "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-    document are to be interpreted as described in RFC 2119 [WORDS].
+    document are to be interpreted as described in RFC 2119 [WORDS].
 
     "SHOULD" and "SHOULD NOT" are appropriate when valid exceptions to a
     general requirement are known to exist or appear to exist, and it is
@@ -137,7 +137,7 @@ Table of Contents
     implement the general requirement when such failure would result in
     interoperability failure.
 
-3. Storage model
+3. Storage model
 
     The server stores data in nodes that form a tree structure.
     Internal nodes are called 'folders' and leaf nodes are called
@@ -155,7 +155,7 @@ Table of Contents
 
 
 de Jong                                                         [Page 3]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -165,12 +165,12 @@ Table of Contents
        * content length
        * content
 
-4. Requests
+4. Requests
 
-    Client-to-server requests SHOULD be made over https [HTTPS], and
-    servers MUST comply with HTTP/1.1 [HTTP]. Specifically, they
+    Client-to-server requests SHOULD be made over https [HTTPS], and
+    servers MUST comply with HTTP/1.1 [HTTP]. Specifically, they
     MUST support chunked transfer coding on PUT requests. Servers MAY
-    also offer an optional switch from https to SPDY [SPDY].
+    also offer an optional switch from https to SPDY [SPDY].
 
     A request is considered successful if the HTTP response code is in
     the 2xx range (e.g. 200 OK, 201 Created), and unsuccessful if an
@@ -205,14 +205,14 @@ Table of Contents
 
 
 de Jong                                                         [Page 4]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
     field, representing the folder's current version.
 
     A successful GET request to a folder MUST be responded to with a
-    JSON-LD [JSON-LD] document (content type 'application/ld+json'),
+    JSON-LD [JSON-LD] document (content type 'application/ld+json'),
     containing as its 'items' field a map in which contained documents
     appear as entries <item_name> to a document description, and
     contained non-empty folders appear as entries <item_name> '/' to a
@@ -255,7 +255,7 @@ Table of Contents
 
 
 de Jong                                                         [Page 5]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -266,9 +266,9 @@ Table of Contents
     gzipped when requested by the client, since the two bodies would not
     be identical byte-for-byte.
 
-    Servers MAY support Content-Range headers [RANGE] on GET requests,
+    Servers MAY support Content-Range headers [RANGE] on GET requests,
     but whether or not they do SHOULD be announced through the <ranges>
-    variable mentioned below in section 10.
+    variable mentioned below in section 10.
 
     A successful PUT request to a document MUST result in:
 
@@ -281,7 +281,7 @@ Table of Contents
          document's new content type,
        * its version being updated, as well as that of its parent folder
          and further ancestor folders, using a strong validator [HTTP,
-         section 7.2].
+         section 7.2].
 
     The response MUST contain a strong ETag header, with the document's
     new version (for instance a hash of its contents) as its value.
@@ -305,14 +305,14 @@ Table of Contents
 
 
 de Jong                                                         [Page 6]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
-5. Response codes
+5. Response codes
 
-    Response codes SHOULD be given as defined by [HTTP, section 6] and
-    [BEARER, section 3.1]. The following is a non-normative checklist
+    Response codes SHOULD be given as defined by [HTTP, section 6] and
+    [BEARER, section 3.1]. The following is a non-normative checklist
     of status codes that are likely to occur in practice:
 
        * 500 if an internal server error occurs,
@@ -342,27 +342,27 @@ Table of Contents
     Clients SHOULD also handle the case where a response takes too long
     to arrive, or where no response is received at all.
 
-6. Versioning
+6. Versioning
 
-    All successful requests MUST return an 'ETag' header [HTTP] with, in
+    All successful requests MUST return an 'ETag' header [HTTP] with, in
     the case of GET, the current version, in the case of PUT, the new
     version, and in case of DELETE, the version that was deleted. All
     successful GET requests MUST return an 'Expires: 0' header. PUT and
-    DELETE requests MAY have an 'If-Match' request header [COND], and
+    DELETE requests MAY have an 'If-Match' request header [COND], and
     MUST fail with a 412 response code if that doesn't match the
     document's current version.
 
 
 
 de Jong                                                         [Page 7]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
     GET requests MAY have a comma-separated list of revisions in an
-    'If-None-Match' header [COND], and SHOULD be responded to with a 304
+    'If-None-Match' header [COND], and SHOULD be responded to with a 304
     response if that list includes the document or folder's current
-    version. A PUT request MAY have an 'If-None-Match: *' header [COND],
+    version. A PUT request MAY have an 'If-None-Match: *' header [COND],
     in which case it MUST fail with a 412 response code if the document
     already exists.
 
@@ -372,14 +372,14 @@ Table of Contents
     A provider MAY offer version rollback functionality to its users,
     but this specification does not define the user interface for that.
 
-7. CORS headers
+7. CORS headers
 
-    All responses MUST carry CORS headers [CORS]. The server MUST also
+    All responses MUST carry CORS headers [CORS]. The server MUST also
     reply to OPTIONS requests as per CORS. For GET requests, a wildcard
     origin MAY be returned, but for PUT and DELETE requests, the
     response MUST echo back the Origin header sent by the client.
 
-8. Session description
+8. Session description
 
     The information that a client needs to receive in order to be able
     to connect to a server SHOULD reach the client as described in the
@@ -387,12 +387,12 @@ Table of Contents
 
        * <storage_root>, consisting of 'https://' followed by a server
          host, and optionally a server port and a path prefix as per
-         [IRI]. Examples:
+         [IRI]. Examples:
          * 'https://example.com' (host only)
          * 'https://example.com:8080' (host and port)
          * 'https://example.com/path/to/storage' (host, port and
            path prefix; note there is no trailing slash)
-       * <access_token> as per [OAUTH]. The token SHOULD be hard to
+       * <access_token> as per [OAUTH]. The token SHOULD be hard to
          guess and SHOULD NOT be reused from one client to another. It
          can however be reused in subsequent interactions with the same
          client, as long as that client is still trusted. Example:
@@ -405,7 +405,7 @@ Table of Contents
 
 
 de Jong                                                         [Page 8]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -420,7 +420,7 @@ Table of Contents
     * https://storage.example.com/bob/public/documents/
     * https://storage.example.com/bob/public/documents/draft.txt
 
-9. Bearer tokens and access control
+9. Bearer tokens and access control
 
     A bearer token represents one or more access scopes. These access
     scopes are represented as strings of the form <module> <level>,
@@ -442,7 +442,7 @@ Table of Contents
     As a special exceptions, GET requests to a document (but not a
     folder) whose path starts with '/public/' are always allowed. They,
     as well as OPTIONS requests, can be made without a bearer token.
-    Unless [KERBEROS] is used (see section 10 below), all other requests
+    Unless [KERBEROS] is used (see section 10 below), all other requests
     SHOULD present a bearer token with sufficient access scope, using a
     header of the following form (no double quotes here):
 
@@ -451,20 +451,20 @@ Table of Contents
     In addition, providing the access token via a HTTP query parameter
     for GET requests MAY be supported by the server, although its use
     is not recommended, due to its security deficiencies; see [BEARER,
-    section 2.3].
+    section 2.3].
 
 
 de Jong                                                         [Page 9]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
 
-10. Application-first bearer token issuance
+10. Application-first bearer token issuance
 
     To make a remoteStorage server available as 'the remoteStorage of
     <account> at <host>', exactly one link of the following format
-    SHOULD be added to the WebFinger record [WEBFINGER] of <account> at
+    SHOULD be added to the WebFinger record [WEBFINGER] of <account> at
     <host>:
 
     {
@@ -479,7 +479,7 @@ Table of Contents
 
     Here <storage_root> and <storage_api> are as per "Session
     description" above, and <auth-dialog> SHOULD be either null or a
-    URL where an OAuth 2.0 implicit-grant flow dialog [OAUTH] is
+    URL where an OAuth 2.0 implicit-grant flow dialog [OAUTH] is
     presented.
 
     If <auth-dialog> is a URL, the user can supply their credentials
@@ -491,7 +491,7 @@ Table of Contents
 
     If <auth-dialog> is null, the client will not have a way to obtain
     an access token, and SHOULD send all requests without Authorization
-    header, and rely on Kerberos [KERBEROS] instead for requests that
+    header, and rely on Kerberos [KERBEROS] instead for requests that
     would normally be sent with a bearer token, but servers SHOULD NOT
     impose any such access barriers for resources that would normally
     not require an access token.
@@ -500,19 +500,19 @@ Table of Contents
     Non-breaking examples that have been proposed so far, include a
     "http://tools.ietf.org/html/rfc6750#section-2.3" property, set to
     the string value "true" if the server supports passing the bearer
-    token in the URI query parameter as per section 2.3 of [BEARER],
+    token in the URI query parameter as per section 2.3 of [BEARER],
     instead of in the request header.
 
 
 de Jong                                                        [Page 10]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
 
     Another example is "http://tools.ietf.org/html/rfc7233" with a
     string value of "GET" if Content-Range headers are supported for
-    GET requests as per [RANGE], "PUT" if they are supported for PUT
+    GET requests as per [RANGE], "PUT" if they are supported for PUT
     requests, and "GET,PUT" if supported for both.
 
     Both these proposals are non-breaking extensions, since the client
@@ -523,7 +523,7 @@ Table of Contents
     A "http://remotestorage.io/spec/web-authoring" property has been
     proposed with a string value of the fully qualified domain name to
     which web authoring content is published if the server supports web
-    authoring as per [AUTHORING]. Note that this extension is a breaking
+    authoring as per [AUTHORING]. Note that this extension is a breaking
     extension in the sense that it divides users into "haves", whose
     remoteStorage accounts allow them to author web content, and
     "have-nots", whose remoteStorage account does not support this
@@ -535,10 +535,10 @@ Table of Contents
     client_id parameter in favor of relying on the redirect_uri
     parameter for client identification.
 
-11. Storage-first bearer token issuance
+11. Storage-first bearer token issuance
 
     The provider MAY also present a dashboard to the user, where they
-    have some way to add open web app manifests [MANIFEST]. Adding a
+    have some way to add open web app manifests [MANIFEST]. Adding a
     manifest to the dashboard is considered equivalent to clicking
     'accept' in the dialog of the application-first flow. Removing one
     is considered equivalent to revoking its access token.
@@ -547,7 +547,7 @@ Table of Contents
     field SHOULD be present in the root of such an application manifest
     document, with entries <module> -> '{"access": "readonly"}' for
     <level> 'r' or '{"access": "readwrite"}' for <level> 'rw', as
-    prescribed in [DATASTORE].
+    prescribed in [DATASTORE].
 
     When the user gestures they want to use a certain application whose
     manifest is present on the dashboard, the dashboard SHOULD redirect
@@ -555,7 +555,7 @@ Table of Contents
 
 
 de Jong                                                        [Page 11]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -593,19 +593,19 @@ Table of Contents
     debug tool, thus bypassing the need for an OAuth dance. Clients
     SHOULD NOT rely on this in production.
 
-12. Example wire transcripts
+12. Example wire transcripts
 
     The following examples are not normative ("\" indicates a line was
     wrapped).
 
-12.1. WebFinger
+12.1. WebFinger
 
     In application-first, an in-browser application might issue the
     following request, using XMLHttpRequest and CORS:
 
 
 de Jong                                                        [Page 12]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -645,7 +645,7 @@ motestorage-04",
            }]
          }
 
-12.2. OAuth dialog form
+12.2. OAuth dialog form
 
     Once the in-browser application has discovered the server's OAuth
     end-point, it will typically redirect the user to this URL, in
@@ -655,7 +655,7 @@ motestorage-04",
 
 
 de Jong                                                        [Page 13]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -675,7 +675,7 @@ unhosted.5apps.com&response_type=token HTTP/1.1
             <title>Allow access?</title>
         ...
 
-12.3. OAuth dialog form submission
+12.3. OAuth dialog form submission
 
     When the user submits the form, the request would look something
     like this:
@@ -700,12 +700,12 @@ low
         Location:https://drinks-unhosted.5apps.com/#access_token=j2YnGt\
 XjzzzHNjkd1CJxoQubA1o%3D&token_type=bearer&state=
 
-12.4. OPTIONS preflight
+12.4. OPTIONS preflight
 
 
 
 de Jong                                                        [Page 14]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -728,7 +728,7 @@ XjzzzHNjkd1CJxoQubA1o%3D&token_type=bearer&state=
         Access-Control-Allow-Headers: Authorization, Content-Length, Co\
 ntent-Type, Origin, X-Requested-With, If-Match, If-None-Match
 
-12.5. Initial PUT
+12.5. Initial PUT
 
     An initial PUT may contain an 'If-None-Match: *' header, like this:
 
@@ -751,11 +751,11 @@ ntent-Type, Origin, X-Requested-With, If-Match, If-None-Match
         Access-Control-Allow-Origin: https://drinks-unhosted.5apps.com
         ETag: "1382694045000"
 
-12.6. Subsequent PUT
+12.6. Subsequent PUT
 
 
 de Jong                                                        [Page 15]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -781,7 +781,7 @@ e.io/spec/modules/myfavoritedrinks/drink"}
         Access-Control-Allow-Origin: https://drinks-unhosted.5apps.com
         ETag: "1382694048000"
 
-12.7. GET
+12.7. GET
 
     A GET request would also include the bearer token, and optionally
     an If-None-Match header:
@@ -805,7 +805,7 @@ e.io/spec/modules/myfavoritedrinks/drink"}
 
 
 de Jong                                                        [Page 16]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -840,7 +840,7 @@ charset=UTF-8","Content-Length":106}}}
         HTTP/1.1 404 Not Found
         Access-Control-Allow-Origin: https://drinks-unhosted.5apps.com
 
-12.8. DELETE
+12.8. DELETE
 
     A DELETE request may look like this:
 
@@ -855,7 +855,7 @@ charset=UTF-8","Content-Length":106}}}
 
 
 de Jong                                                        [Page 17]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -865,7 +865,7 @@ charset=UTF-8","Content-Length":106}}}
         Access-Control-Allow-Origin: https://drinks-unhosted.5apps.com
         ETag: "1382694048000"
 
-13. Distributed versioning
+13. Distributed versioning
 
     This section is non-normative, and is intended to explain some of
     the design choices concerning ETags and folder listings. At the
@@ -905,7 +905,7 @@ charset=UTF-8","Content-Length":106}}}
 
 
 de Jong                                                        [Page 18]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -927,7 +927,7 @@ charset=UTF-8","Content-Length":106}}}
     but it is up to whichever client discovers a given version
     conflict, to resolve it.
 
-14. Security Considerations
+14. Security Considerations
 
     To prevent man-in-the-middle attacks, the use of https instead of
     http is important for both the interface itself and all end-points
@@ -955,7 +955,7 @@ charset=UTF-8","Content-Length":106}}}
 
 
 de Jong                                                        [Page 19]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -972,7 +972,7 @@ charset=UTF-8","Content-Length":106}}}
     The server SHOULD also detect and stop denial-of-service attacks
     that aim to overwhelm its interface with too much traffic.
 
-15. IANA Considerations
+15. IANA Considerations
 
     This document registers the 'remotestorage' link relation, as well
     as the following WebFinger properties:
@@ -982,7 +982,7 @@ charset=UTF-8","Content-Length":106}}}
       * "http://tools.ietf.org/html/rfc7233"
       * "http://remotestorage.io/spec/web-authoring"
 
-16. Acknowledgements
+16. Acknowledgements
 
     The authors would like to thank everybody who contributed to the
     development of this protocol, including Kenny Bentley, Javier Diaz,
@@ -995,9 +995,9 @@ charset=UTF-8","Content-Length":106}}}
     Rick van Rein, Mark Nottingham, Julian Reschke, and Markus
     Lanthaler, among many others.
 
-17. References
+17. References
 
-17.1. Normative References
+17.1. Normative References
 
     [WORDS]
         Bradner, S., "Key words for use in RFCs to Indicate Requirement
@@ -1005,7 +1005,7 @@ charset=UTF-8","Content-Length":106}}}
 
 
 de Jong                                                        [Page 20]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -1019,10 +1019,10 @@ charset=UTF-8","Content-Length":106}}}
         "WebFinger", RFC7033, September 2013.
 
     [OAUTH]
-        "Section 4.2: Implicit Grant", in: Hardt, D. (ed), "The OAuth
+        "Section 4.2: Implicit Grant", in: Hardt, D. (ed), "The OAuth
         2.0 Authorization Framework", RFC6749, October 2012.
 
-17.2. Informative References
+17.2. Informative References
 
     [HTTPS]
         Rescorla, E., "HTTP Over TLS", RFC2818, May 2000.
@@ -1055,7 +1055,7 @@ charset=UTF-8","Content-Length":106}}}
 
 
 de Jong                                                        [Page 21]
-

+

 Internet-Draft              remoteStorage                  December 2014
 
 
@@ -1083,7 +1083,7 @@ charset=UTF-8","Content-Length":106}}}
         September 2014. https://github.com/michielbdejong/resite/wiki
         /Using-remoteStorage-for-web-authoring
 
-18. Authors' addresses
+18. Authors' addresses
 
     Michiel B. de Jong
     IndieHosters
@@ -1109,4 +1109,4 @@ de Jong                                                        [Page 22]
 

Html markup produced by rfcmarkup 1.111, available from https://tools.ietf.org/tools/rfcmarkup/ - + \ No newline at end of file diff --git a/test/test-pages/mozilla-1/expected.html b/test/test-pages/mozilla-1/expected.html index 1863fa7..b1011d4 100644 --- a/test/test-pages/mozilla-1/expected.html +++ b/test/test-pages/mozilla-1/expected.html @@ -28,14 +28,14 @@

Try it now -
Learn more +
Learn more
Preview of the currently selected theme
-

Add-ons

+

Add-ons

Add-ons are like apps that you install to add features to Firefox. They let you compare prices, check the weather, listen to music, send a tweet and more.

  • Read the latest news & blogs
  • @@ -49,7 +49,7 @@
    -

    Awesome Bar

    +

    Awesome Bar

    The Awesome Bar learns as you browse to make your version of Firefox unique. Find and return to your favorite sites without having to remember a URL.

    See what it can do for you
    Firefox Awesome Bar
    diff --git a/test/test-readability.js b/test/test-readability.js index fb5adb7..1225dbe 100644 --- a/test/test-readability.js +++ b/test/test-readability.js @@ -77,7 +77,14 @@ function runTestsWithItems(label, domGenerationFn, uri, source, expectedContent, if (n.nodeType == 3) { return "#text(" + htmlTransform(n.textContent) + ")"; } - return n.localName + "#" + n.id + ".(" + n.className + ")"; + var rv = n.localName; + if (n.id) { + rv += "#" + n.id; + } + if (n.className) { + rv += ".(" + n.className + ")"; + } + return rv; } var actualDOM = domGenerationFn(result.content); var expectedDOM = domGenerationFn(expectedContent); @@ -98,6 +105,15 @@ function runTestsWithItems(label, domGenerationFn, uri, source, expectedContent, if (actualText != expectedText) { return false; } + // Compare attributes for element nodes: + } else if (actualNode.nodeType == 1) { + expect(actualNode.attributes.length).eql(expectedNode.attributes.length); + for (var i = 0; i < actualNode.attributes.length; i++) { + var attr = actualNode.attributes[i].name; + var actualValue = actualNode.getAttribute(attr); + var expectedValue = expectedNode.getAttribute(attr); + expect(expectedValue, "node '" + actualDesc + "' attribute " + attr + " should match").eql(actualValue); + } } } else { return false;