From 0226e0ca0dc70f9a0310b3eef045ee1c1e0ca3ac Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Tue, 13 Dec 2022 20:00:46 +0300 Subject: split into a separate repo --- .../test/test-pages/002/expected.html | 418 +++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 vendor/fivefilters/readability.php/test/test-pages/002/expected.html (limited to 'vendor/fivefilters/readability.php/test/test-pages/002/expected.html') diff --git a/vendor/fivefilters/readability.php/test/test-pages/002/expected.html b/vendor/fivefilters/readability.php/test/test-pages/002/expected.html new file mode 100644 index 0000000..564f9a9 --- /dev/null +++ b/vendor/fivefilters/readability.php/test/test-pages/002/expected.html @@ -0,0 +1,418 @@ +
+
+

For more than a decade the Web has used XMLHttpRequest (XHR) to achieve + asynchronous requests in JavaScript. While very useful, XHR is not a very + nice API. It suffers from lack of separation of concerns. The input, output + and state are all managed by interacting with one object, and state is + tracked using events. Also, the event-based model doesn’t play well with + JavaScript’s recent focus on Promise- and generator-based asynchronous + programming.

+

The Fetch API intends + to fix most of these problems. It does this by introducing the same primitives + to JS that are used in the HTTP protocol. In addition, it introduces a + utility function fetch() that succinctly captures the intention + of retrieving a resource from the network.

+

The Fetch specification, which + defines the API, nails down the semantics of a user agent fetching a resource. + This, combined with ServiceWorkers, is an attempt to:

+
    +
  1. Improve the offline experience.
  2. +
  3. Expose the building blocks of the Web to the platform as part of the + extensible web movement.
  4. +
+

As of this writing, the Fetch API is available in Firefox 39 (currently + Nightly) and Chrome 42 (currently dev). Github has a Fetch polyfill.

+ +

Feature detection

+ +

Fetch API support can be detected by checking for Headers,Request, Response or fetch on + the window or worker scope.

+ +

Simple fetching

+ +

The most useful, high-level part of the Fetch API is the fetch() function. + In its simplest form it takes a URL and returns a promise that resolves + to the response. The response is captured as a Response object.

+
fetch("/data.json").then(function(res) {
+  // res instanceof Response == true.
+  if (res.ok) {
+    res.json().then(function(data) {
+      console.log(data.entries);
+    });
+  } else {
+    console.log("Looks like the response wasn't perfect, got status", res.status);
+  }
+}, function(e) {
+  console.log("Fetch failed!", e);
+});
+
+

Submitting some parameters, it would look like this:

+
fetch("http://www.example.org/submit.php", {
+  method: "POST",
+  headers: {
+    "Content-Type": "application/x-www-form-urlencoded"
+  },
+  body: "firstName=Nikhil&favColor=blue&password=easytoguess"
+}).then(function(res) {
+  if (res.ok) {
+    alert("Perfect! Your settings are saved.");
+  } else if (res.status == 401) {
+    alert("Oops! You are not authorized.");
+  }
+}, function(e) {
+  alert("Error submitting form!");
+});
+
+

The fetch() function’s arguments are the same as those passed + to the +
+Request() constructor, so you may directly pass arbitrarily + complex requests to fetch() as discussed below.

+ +

Headers

+ +

Fetch introduces 3 interfaces. These are Headers, Request and +
+Response. They map directly to the underlying HTTP concepts, + but have +
certain visibility filters in place for privacy and security reasons, + such as +
supporting CORS rules and ensuring cookies aren’t readable by third parties.

+

The Headers interface is + a simple multi-map of names to values:

+
var content = "Hello World";
+var reqHeaders = new Headers();
+reqHeaders.append("Content-Type", "text/plain"
+reqHeaders.append("Content-Length", content.length.toString());
+reqHeaders.append("X-Custom-Header", "ProcessThisImmediately");
+
+

The same can be achieved by passing an array of arrays or a JS object + literal +
to the constructor:

+
reqHeaders = new Headers({
+  "Content-Type": "text/plain",
+  "Content-Length": content.length.toString(),
+  "X-Custom-Header": "ProcessThisImmediately",
+});
+
+

The contents can be queried and retrieved:

+
console.log(reqHeaders.has("Content-Type")); // true
+console.log(reqHeaders.has("Set-Cookie")); // false
+reqHeaders.set("Content-Type", "text/html");
+reqHeaders.append("X-Custom-Header", "AnotherValue");
+ 
+console.log(reqHeaders.get("Content-Length")); // 11
+console.log(reqHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
+ 
+reqHeaders.delete("X-Custom-Header");
+console.log(reqHeaders.getAll("X-Custom-Header")); // []
+
+

Some of these operations are only useful in ServiceWorkers, but they provide +
a much nicer API to Headers.

+

Since Headers can be sent in requests, or received in responses, and have + various limitations about what information can and should be mutable, Headers objects + have a guard property. This is not exposed to the Web, but + it affects which mutation operations are allowed on the Headers object. +
Possible values are:

+
    +
  • “none”: default.
  • +
  • “request”: guard for a Headers object obtained from a Request (Request.headers).
  • +
  • “request-no-cors”: guard for a Headers object obtained from a Request + created +
    with mode “no-cors”.
  • +
  • “response”: naturally, for Headers obtained from Response (Response.headers).
  • +
  • “immutable”: Mostly used for ServiceWorkers, renders a Headers object +
    read-only.
  • +
+

The details of how each guard affects the behaviors of the Headers object + are +
in the specification. For example, + you may not append or set a “request” guarded Headers’ “Content-Length” + header. Similarly, inserting “Set-Cookie” into a Response header is not + allowed so that ServiceWorkers may not set cookies via synthesized Responses.

+

All of the Headers methods throw TypeError if name is not a + valid HTTP Header name. The mutation operations will throw TypeError + if there is an immutable guard. Otherwise they fail silently. For example:

+
var res = Response.error();
+try {
+  res.headers.set("Origin", "http://mybank.com");
+} catch(e) {
+  console.log("Cannot pretend to be a bank!");
+}
+
+ +

Request

+ +

The Request interface defines a request to fetch a resource over HTTP. + URL, method and headers are expected, but the Request also allows specifying + a body, a request mode, credentials and cache hints.

+

The simplest Request is of course, just a URL, as you may do to GET a + resource.

+
var req = new Request("/index.html");
+console.log(req.method); // "GET"
+console.log(req.url); // "http://example.com/index.html"
+
+

You may also pass a Request to the Request() constructor to + create a copy. +
(This is not the same as calling the clone() method, which + is covered in +
the “Reading bodies” section.).

+
var copy = new Request(req);
+console.log(copy.method); // "GET"
+console.log(copy.url); // "http://example.com/index.html"
+
+

Again, this form is probably only useful in ServiceWorkers.

+

The non-URL attributes of the Request can only be set by passing + initial +
values as a second argument to the constructor. This argument is a dictionary.

+
var uploadReq = new Request("/uploadImage", {
+  method: "POST",
+  headers: {
+    "Content-Type": "image/png",
+  },
+  body: "image data"
+});
+
+

The Request’s mode is used to determine if cross-origin requests lead + to valid responses, and which properties on the response are readable. + Legal mode values are "same-origin", "no-cors" (default) + and "cors".

+

The "same-origin" mode is simple, if a request is made to another + origin with this mode set, the result is simply an error. You could use + this to ensure that +
a request is always being made to your origin.

+
var arbitraryUrl = document.getElementById("url-input").value;
+fetch(arbitraryUrl, { mode: "same-origin" }).then(function(res) {
+  console.log("Response succeeded?", res.ok);
+}, function(e) {
+  console.log("Please enter a same-origin URL!");
+});
+
+

The "no-cors" mode captures what the web platform does by default + for scripts you import from CDNs, images hosted on other domains, and so + on. First, it prevents the method from being anything other than “HEAD”, + “GET” or “POST”. Second, if any ServiceWorkers intercept these requests, + they may not add or override any headers except for these. + Third, JavaScript may not access any properties of the resulting Response. + This ensures that ServiceWorkers do not affect the semantics of the Web + and prevents security and privacy issues that could arise from leaking + data across domains.

+

"cors" mode is what you’ll usually use to make known cross-origin + requests to access various APIs offered by other vendors. These are expected + to adhere to +
the CORS protocol. + Only a limited set of + headers is exposed in the Response, but the body is readable. For example, + you could get a list of Flickr’s most interesting photos + today like this:

+
var u = new URLSearchParams();
+u.append('method', 'flickr.interestingness.getList');
+u.append('api_key', '<insert api key here>');
+u.append('format', 'json');
+u.append('nojsoncallback', '1');
+ 
+var apiCall = fetch('https://api.flickr.com/services/rest?' + u);
+ 
+apiCall.then(function(response) {
+  return response.json().then(function(json) {
+    // photo is a list of photos.
+    return json.photos.photo;
+  });
+}).then(function(photos) {
+  photos.forEach(function(photo) {
+    console.log(photo.title);
+  });
+});
+
+

You may not read out the “Date” header since Flickr does not allow it + via +
+Access-Control-Expose-Headers.

+
response.headers.get("Date"); // null
+
+

The credentials enumeration determines if cookies for the other + domain are +
sent to cross-origin requests. This is similar to XHR’s withCredentials +
flag, but tri-valued as "omit" (default), "same-origin" and "include".

+

The Request object will also give the ability to offer caching hints to + the user-agent. This is currently undergoing some security review. + Firefox exposes the attribute, but it has no effect.

+

Requests have two read-only attributes that are relevant to ServiceWorkers +
intercepting them. There is the string referrer, which is + set by the UA to be +
the referrer of the Request. This may be an empty string. The other is +
+context which is a rather large enumeration defining + what sort of resource is being fetched. This could be “image” if the request + is from an + <img>tag in the controlled document, “worker” if it is an attempt to load a + worker script, and so on. When used with the fetch() function, + it is “fetch”.

+ +

Response

+ +

Response instances are returned by calls to fetch(). + They can also be created by JS, but this is only useful in ServiceWorkers.

+

We have already seen some attributes of Response when we looked at fetch(). + The most obvious candidates are status, an integer (default + value 200) and statusText (default value “OK”), which correspond + to the HTTP status code and reason. The ok attribute is just + a shorthand for checking that status is in the range 200-299 + inclusive.

+

headers is the Response’s Headers object, with guard “response”. + The url attribute reflects the URL of the corresponding request.

+

Response also has a type, which is “basic”, “cors”, “default”, + “error” or +
“opaque”.

+
    +
  • "basic": normal, same origin response, with all headers exposed + except +
    “Set-Cookie” and “Set-Cookie2″.
  • +
  • "cors": response was received from a valid cross-origin request. + Certain headers and the bodymay be accessed.
  • +
  • "error": network error. No useful information describing + the error is available. The Response’s status is 0, headers are empty and + immutable. This is the type for a Response obtained from Response.error().
  • +
  • "opaque": response for “no-cors” request to cross-origin + resource. Severely
    + restricted
    +
  • +
+

The “error” type results in the fetch() Promise rejecting with + TypeError.

+

There are certain attributes that are useful only in a ServiceWorker scope. + The +
idiomatic way to return a Response to an intercepted request in ServiceWorkers + is:

+
addEventListener('fetch', function(event) {
+  event.respondWith(new Response("Response body", {
+    headers: { "Content-Type" : "text/plain" }
+  });
+});
+
+

As you can see, Response has a two argument constructor, where both arguments + are optional. The first argument is a body initializer, and the second + is a dictionary to set the status, statusText and headers.

+

The static method Response.error() simply returns an error + response. Similarly, Response.redirect(url, status) returns + a Response resulting in +
a redirect to url.

+ +

Dealing with bodies

+ +

Both Requests and Responses may contain body data. We’ve been glossing + over it because of the various data types body may contain, but we will + cover it in detail now.

+

A body is an instance of any of the following types.

+ +

In addition, Request and Response both offer the following methods to + extract their body. These all return a Promise that is eventually resolved + with the actual content.

+
    +
  • arrayBuffer() +
  • +
  • blob() +
  • +
  • json() +
  • +
  • text() +
  • +
  • formData() +
  • +
+

This is a significant improvement over XHR in terms of ease of use of + non-text data!

+

Request bodies can be set by passing body parameters:

+
var form = new FormData(document.getElementById('login-form'));
+fetch("/login", {
+  method: "POST",
+  body: form
+})
+
+

Responses take the first argument as the body.

+
var res = new Response(new File(["chunk", "chunk"], "archive.zip",
+                       { type: "application/zip" }));
+
+

Both Request and Response (and by extension the fetch() function), + will try to intelligently determine the content type. + Request will also automatically set a “Content-Type” header if none is + set in the dictionary.

+ +

Streams and cloning

+ +

It is important to realise that Request and Response bodies can only be + read once! Both interfaces have a boolean attribute bodyUsed to + determine if it is safe to read or not.

+
var res = new Response("one time use");
+console.log(res.bodyUsed); // false
+res.text().then(function(v) {
+  console.log(res.bodyUsed); // true
+});
+console.log(res.bodyUsed); // true
+ 
+res.text().catch(function(e) {
+  console.log("Tried to read already consumed Response");
+});
+
+

This decision allows easing the transition to an eventual stream-based Fetch + API. The intention is to let applications consume data as it arrives, allowing + for JavaScript to deal with larger files like videos, and perform things + like compression and editing on the fly.

+

Often, you’ll want access to the body multiple times. For example, you + can use the upcoming Cache API to + store Requests and Responses for offline use, and Cache requires bodies + to be available for reading.

+

So how do you read out the body multiple times within such constraints? + The API provides a clone() method on the two interfaces. This + will return a clone of the object, with a ‘new’ body. clone() MUST + be called before the body of the corresponding object has been used. That + is, clone() first, read later.

+
addEventListener('fetch', function(evt) {
+  var sheep = new Response("Dolly");
+  console.log(sheep.bodyUsed); // false
+  var clone = sheep.clone();
+  console.log(clone.bodyUsed); // false
+ 
+  clone.text();
+  console.log(sheep.bodyUsed); // false
+  console.log(clone.bodyUsed); // true
+ 
+  evt.respondWith(cache.add(sheep.clone()).then(function(e) {
+    return sheep;
+  });
+});
+
+ +

Future improvements

+ +

Along with the transition to streams, Fetch will eventually have the ability + to abort running fetch()es and some way to report the progress + of a fetch. These are provided by XHR, but are a little tricky to fit in + the Promise-based nature of the Fetch API.

+

You can contribute to the evolution of this API by participating in discussions + on the WHATWG mailing list and + in the issues in the Fetch and + ServiceWorkerspecifications.

+

For a better web!

+

The author would like to thank Andrea Marchesini, Anne van Kesteren and Ben
+Kelly for helping with the specification and implementation.
+

+ +
+ + +
\ No newline at end of file -- cgit v1.2.3