feat(modal): add cancellable shared runtime
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0647c501ba
commit
d79b063bf9
12 files changed
+999
-392
No files matched your search
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* AKSRT frontend request adapter.
|
||||
*
|
||||
* Owns the injected REST root, nonce headers, response envelopes, and
|
||||
* abort-aware error normalization used by modal loaders.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function (window) {
|
||||
"use strict";
|
||||
|
||||
function data() {
|
||||
return window.aksrtData || window.aksrt || {};
|
||||
}
|
||||
|
||||
function restBase() {
|
||||
var config = data();
|
||||
var raw = config.restUrl || config.apiUrl || config.rest_url || "";
|
||||
var siteUrl = config.siteUrl || config.homeUrl || (window.location.origin + "/");
|
||||
|
||||
if (window.location.protocol === "https:" && siteUrl.substring(0, 5) === "http:") {
|
||||
siteUrl = "https:" + siteUrl.substring(5);
|
||||
}
|
||||
|
||||
if (raw) return String(raw).replace(/\/$/, "");
|
||||
return String(siteUrl).replace(/\/$/, "") + "/index.php?rest_route=/aksrt/v1";
|
||||
}
|
||||
|
||||
function appendQuery(url, query) {
|
||||
if (!query) return url;
|
||||
var parts = [];
|
||||
|
||||
if (typeof query === "string") {
|
||||
parts = query.replace(/^\?/, "").split("&").filter(Boolean);
|
||||
} else if (typeof query === "object") {
|
||||
Object.keys(query).forEach(function (key) {
|
||||
if (query[key] === undefined || query[key] === null) return;
|
||||
parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(String(query[key])));
|
||||
});
|
||||
}
|
||||
|
||||
if (!parts.length) return url;
|
||||
return url + (url.indexOf("?") >= 0 ? "&" : "?") + parts.join("&");
|
||||
}
|
||||
|
||||
function url(path, query) {
|
||||
path = String(path || "");
|
||||
var inlineQuery = "";
|
||||
var queryIndex = path.indexOf("?");
|
||||
|
||||
if (queryIndex >= 0) {
|
||||
inlineQuery = path.slice(queryIndex + 1);
|
||||
path = path.slice(0, queryIndex);
|
||||
}
|
||||
|
||||
if (/^https?:\/\//i.test(path)) {
|
||||
return appendQuery(path, query || inlineQuery);
|
||||
}
|
||||
|
||||
if (path.charAt(0) !== "/") path = "/" + path;
|
||||
var base = restBase();
|
||||
var result = base.indexOf("rest_route=") >= 0 ? base + path : base + path;
|
||||
return appendQuery(result, query || inlineQuery);
|
||||
}
|
||||
|
||||
function headers(options) {
|
||||
var config = data();
|
||||
var source = (options && options.headers) || {};
|
||||
var result = {};
|
||||
var nonce = config.restNonce || config.nonce || "";
|
||||
|
||||
Object.keys(source).forEach(function (key) {
|
||||
result[key] = source[key];
|
||||
});
|
||||
|
||||
if (!result.Accept) result.Accept = "application/json, text/html;q=0.9, */*;q=0.8";
|
||||
if (nonce && !result["X-WP-Nonce"]) result["X-WP-Nonce"] = nonce;
|
||||
|
||||
if (options && options.body !== undefined && options.body !== null &&
|
||||
!(window.FormData && options.body instanceof window.FormData) &&
|
||||
!result["Content-Type"]) {
|
||||
result["Content-Type"] = "application/json";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function responseError(result) {
|
||||
var json = result.json;
|
||||
var message = json && (json.message || (json.data && json.data.message));
|
||||
var error = new Error(message || (result.status ? "请求失败(HTTP " + result.status + ")" : "请求失败"));
|
||||
error.status = result.status;
|
||||
error.code = result.status === 401 ? "unauthorized" : "http_error";
|
||||
error.response = result;
|
||||
error.json = json;
|
||||
return error;
|
||||
}
|
||||
|
||||
function parseResponse(response) {
|
||||
return response.text().then(function (text) {
|
||||
var type = (response.headers.get("content-type") || "").toLowerCase();
|
||||
var json = null;
|
||||
var trimmed = String(text || "").trim();
|
||||
|
||||
if (type.indexOf("application/json") >= 0 || trimmed.charAt(0) === "{" || trimmed.charAt(0) === "[") {
|
||||
try {
|
||||
json = trimmed ? JSON.parse(trimmed) : {};
|
||||
} catch (error) {
|
||||
json = null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
headers: response.headers,
|
||||
text: text,
|
||||
json: json,
|
||||
data: json && json.data !== undefined ? json.data : json,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function request(path, options) {
|
||||
options = Object.assign({}, options || {});
|
||||
var requestUrl = url(path, options.query);
|
||||
delete options.query;
|
||||
|
||||
var fetchOptions = Object.assign({}, options, {
|
||||
credentials: options.credentials || "same-origin",
|
||||
headers: headers(options),
|
||||
});
|
||||
|
||||
return window.fetch(requestUrl, fetchOptions).then(function (response) {
|
||||
return parseResponse(response);
|
||||
}).then(function (result) {
|
||||
if (!result.ok || (result.json && result.json.success === false)) {
|
||||
throw responseError(result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
window.AksrtRequest = {
|
||||
url: url,
|
||||
request: request,
|
||||
get: function (path, options) {
|
||||
return request(path, Object.assign({}, options || {}, { method: "GET" }));
|
||||
},
|
||||
post: function (path, body, options) {
|
||||
return request(path, Object.assign({}, options || {}, {
|
||||
method: "POST",
|
||||
body: body,
|
||||
}));
|
||||
},
|
||||
};
|
||||
})(window);
|
||||
Reference in new issue
Block a user