mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +10:00
Update reader.
This commit is contained in:
@@ -396,7 +396,7 @@
|
||||
</div>
|
||||
<div class="controls">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="preinst-enablelaunch" class="win-checkbox">
|
||||
<input type="checkbox" id="preinst-enablelaunch" class="win-checkbox" style="margin-left: 0;">
|
||||
<label for="preinst-enablelaunch" data-res-byname="IDS_LAUNCHWHENREADY"></label>
|
||||
</div>
|
||||
<div class="command">
|
||||
|
||||
@@ -118,4 +118,12 @@
|
||||
return Bridge.String.toupper(this);
|
||||
};
|
||||
}
|
||||
if (typeof String.prototype.format !== "function") {
|
||||
String.prototype.format = function() {
|
||||
var args = arguments;
|
||||
return this.replace(/{(\d+)}/g, function(match, number) {
|
||||
return typeof args[number] !== "undefined" ? args[number] : match;
|
||||
});
|
||||
};
|
||||
}
|
||||
})(this);
|
||||
@@ -363,6 +363,19 @@
|
||||
));
|
||||
}
|
||||
};
|
||||
Object.defineProperty(this, "length", {
|
||||
get: function() {
|
||||
return _list.length;
|
||||
},
|
||||
enumerable: true,
|
||||
});
|
||||
this.getDatas = function() { return _list; }
|
||||
this.forEach = function(callback, args) {
|
||||
if (typeof callback !== "function") return;
|
||||
for (var i = 0; i < _list.length; i++) {
|
||||
callback.apply(this, [_list[i], i].concat(Array.prototype.slice.call(arguments, 1)));
|
||||
}
|
||||
};
|
||||
this._getKey = getKey;
|
||||
}
|
||||
var MAX_ANIMATE_COUNT = 100;
|
||||
@@ -609,10 +622,16 @@
|
||||
});
|
||||
PMDataListView.prototype._updateEmptyView = function() {
|
||||
if (!this._emptyView) return;
|
||||
|
||||
// container 中是否还有 item
|
||||
var hasItem = this.container.children.length > 0;
|
||||
|
||||
var itemVisibleLength = 0;
|
||||
for (var i = 0; i < this.container.children.length; i++) {
|
||||
var child = this.container.children[i];
|
||||
if (!child) continue;
|
||||
if (child.style.display !== "none" && child.style.display !== "hidden" && child.style.opacity !== 0 && child.style.visibility !== "hidden") {
|
||||
itemVisibleLength++;
|
||||
}
|
||||
}
|
||||
hasItem = hasItem && itemVisibleLength > 0;
|
||||
if (hasItem) {
|
||||
if (this._emptyView.parentNode) {
|
||||
this._emptyView.style.display = "none";
|
||||
@@ -802,6 +821,7 @@
|
||||
};
|
||||
PMDataListView.prototype.refresh = function() {
|
||||
this._refreshVisibility();
|
||||
this._updateEmptyView();
|
||||
};
|
||||
global.DataView.ChangeEvent = PMChangeEvent;
|
||||
global.DataView.DataSource = PMDataSource;
|
||||
|
||||
562
shared/html/js/dboxapi.js
Normal file
562
shared/html/js/dboxapi.js
Normal file
@@ -0,0 +1,562 @@
|
||||
/**
|
||||
* DBox API
|
||||
* Docs: https://dbox.tools/api/docs
|
||||
*/
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
function joinUrl(url, path) {
|
||||
if (url.charAt(url.length - 1) === "/") {
|
||||
url = url.slice(0, -1);
|
||||
}
|
||||
if (path.charAt(0) === "/") {
|
||||
path = path.slice(1);
|
||||
}
|
||||
return url + "/" + path;
|
||||
}
|
||||
|
||||
function buildParams(params) {
|
||||
var queryString = "";
|
||||
var keys = Object.keys(params);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var value = params[key];
|
||||
if (value === null || value === void 0) {
|
||||
continue;
|
||||
}
|
||||
queryString += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
|
||||
}
|
||||
return queryString.slice(0, -1);
|
||||
}
|
||||
var baseUrl = "https://dbox.tools/";
|
||||
var baseApiUrl = joinUrl(baseUrl, "api");
|
||||
var dboxApi = {
|
||||
/**
|
||||
* @enum {string} DBox.API.System
|
||||
* @readonly
|
||||
*/
|
||||
System: {
|
||||
/** @type {string} Xbox */
|
||||
xbox: "XBOX",
|
||||
/** @type {string} Xbox 360 */
|
||||
xbox360: "XBOX360",
|
||||
/** @type {string} Xbox One */
|
||||
xboxOne: "XBOXONE",
|
||||
/** @type {string} Xbox Series X */
|
||||
xboxSeriesX: "XBOXSERIESX",
|
||||
/** @type {string} PC */
|
||||
pc: "PC",
|
||||
/** @type {string} PS3 */
|
||||
mobile: "MOBILE"
|
||||
},
|
||||
Discs: {
|
||||
/**
|
||||
* Get and filter discs
|
||||
* @param {string | null} name query
|
||||
* @param {DBox.API.System} system query
|
||||
* @param {integer | number} [limit] query, default: 100
|
||||
* @param {integer | number} [offset] query, default: 0
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getDiscs: function(name, system, limit, offset) {
|
||||
var params = {};
|
||||
if (name) params.name = name;
|
||||
if (system) params.system = system;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
|
||||
return joinUrl(baseApiUrl, "discs") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single disc by DBox ID
|
||||
* @param {integer | number} discId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleDiscById: function(discId) {
|
||||
return joinUrl(baseApiUrl, "discs/" + discId);
|
||||
},
|
||||
/**
|
||||
* Get single disc by Redump ID
|
||||
* @param {integer | number} redumpId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleDiscByRedumpId: function(redumpId) {
|
||||
return joinUrl(baseApiUrl, "discs/redump/" + redumpId);
|
||||
},
|
||||
/**
|
||||
* Get single disc by its XMID (OG XBOX only)
|
||||
* @param {string} xmid path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleDiscByXMId: function(xmid) {
|
||||
return joinUrl(baseApiUrl, "discs/xmid/" + xmid);
|
||||
},
|
||||
/**
|
||||
* Get single disc by its XeMID (XBOX 360 only)
|
||||
* @param {string} xeMid path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleDiscByXeMId: function(xeMid) {
|
||||
return joinUrl(baseApiUrl, "discs/xemid/" + xeMid);
|
||||
},
|
||||
/**
|
||||
* Get single disc by its media ID. Media ID v1 (XBOX & XBOX 360) and Media ID v2 (XBOX One & XBOX Series) are combined in a single query
|
||||
* @param {string} mediaId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleDiscByMediaId: function(mediaId) {
|
||||
return joinUrl(baseApiUrl, "discs/media_id/" + mediaId);
|
||||
},
|
||||
/**
|
||||
* Get the dirs and files (if available) for a disc. Filetype indicates if it is a supported filetype that has further metadata available in the database.
|
||||
* @param {integer | number} discId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getDiscFiles: function(discId) {
|
||||
return joinUrl(baseApiUrl, "discs/" + discId + "/files");
|
||||
}
|
||||
},
|
||||
Releases: {
|
||||
/**
|
||||
* Get and filter releases
|
||||
* @param {string | null} name query
|
||||
* @param {string | null} edition query
|
||||
* @param {string | null} barcode query
|
||||
* @param {DBox.API.System} system query
|
||||
* @param {integer | number} limit query, default: 100
|
||||
* @param {integer | number} offset query, default: 0
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getReleases: function(name, edition, barcode, system, limit, offset) {
|
||||
var params = {};
|
||||
if (name) params.name = name;
|
||||
if (edition) params.edition = edition;
|
||||
if (barcode) params.barcode = barcode;
|
||||
if (system) params.system = system;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
return joinUrl(baseApiUrl, "releases") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single release by DBox ID
|
||||
* @param {string} releaseId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleRelease: function(releaseId) {
|
||||
return joinUrl(baseApiUrl, "releases/" + releaseId);
|
||||
}
|
||||
},
|
||||
Files: {
|
||||
/**
|
||||
* Get all discs that contain a particular file. NOTE: not all discs have been parsed on file-level yet
|
||||
* @param {string} md5 path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getFiles: function(md5) {
|
||||
return joinUrl(baseApiUrl, "files/" + md5 + "/discs");
|
||||
},
|
||||
/**
|
||||
* Filter all distinct xbe files. NOTE: not all discs have been parsed on file-level yet
|
||||
* @param {string | null} titleId query
|
||||
* @param {integer | null} allowrdMedia query
|
||||
* @param {integer | null} region query, Available values: 1, 2, 3, 4, 7, 2147483648
|
||||
* @param {integer | null} gameRating query
|
||||
* @param {integer | null} discNumber query
|
||||
* @param {integer | null} version query
|
||||
* @param {integer | number} limit query, default: 100
|
||||
* @param {integer | number} offset query, default: 0
|
||||
* @returns
|
||||
*/
|
||||
getXbeFiles: function(titleId, allowrdMedia, region, gameRating, discNumber, version, limit, offset) {
|
||||
if (region !== null && region !== undefined) {
|
||||
var valid = [1, 2, 3, 4, 7, 2147483648];
|
||||
if (!valid.includes(region)) throw new Error('Invalid region');
|
||||
}
|
||||
var params = {};
|
||||
if (titleId) params.title_id = titleId;
|
||||
if (allowrdMedia) params.allowrd_media = allowrdMedia;
|
||||
if (region) params.region = region;
|
||||
if (gameRating) params.game_rating = gameRating;
|
||||
if (discNumber) params.disc_number = discNumber;
|
||||
if (version) params.version = version;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
return joinUrl(baseApiUrl, "files/xbe") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get xbe file by md5. NOTE: not all discs have been parsed on file-level yet
|
||||
* @param {string} md5 path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getXbeFileByMd5: function(md5) {
|
||||
return joinUrl(baseApiUrl, "files/xbe/" + md5);
|
||||
},
|
||||
/**
|
||||
* Get stfs file by md5. NOTE: not all discs have been parsed on file-level yet
|
||||
* @param {string} md5 path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getStfsFileByMd5: function(md5) {
|
||||
return joinUrl(baseApiUrl, "files/stfs/" + md5);
|
||||
},
|
||||
},
|
||||
TitleIDs: {
|
||||
/**
|
||||
* Get and filter title IDs
|
||||
* @param {string | (string | null)} name query
|
||||
* @param {DBox.API.System | null} system query
|
||||
* @param {string | (string | null)($uuid)} bingId query
|
||||
* @param {string | (string | null)($uuid)} serviceConfigId query
|
||||
* @param {integer} limit query, default: 100
|
||||
* @param {integer} offset query, default: 0
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getTitleIds: function(name, system, bingId, serviceConfigId, limit, offset) {
|
||||
var params = {};
|
||||
if (name) params.name = name;
|
||||
if (system) params.system = system;
|
||||
if (bingId) params.bing_id = bingId;
|
||||
if (serviceConfigId) params.service_config_id = serviceConfigId;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
return joinUrl(baseApiUrl, "title_ids") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single title ID by its hexadecimal value
|
||||
* @param {string} titleId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleTitleId: function(titleId) {
|
||||
return joinUrl(baseApiUrl, "title_ids/" + titleId);
|
||||
}
|
||||
},
|
||||
Achievements: {
|
||||
/**
|
||||
* Get achievements for a title-id. Xbox 360/GFWL only
|
||||
* @param {string} titleId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getAchievementsV1: function(titleId) {
|
||||
return joinUrl(baseApiUrl, "achievements/v1/" + titleId);
|
||||
},
|
||||
/**
|
||||
* Get achievements for a title-id. Xbox One/Series only
|
||||
* @param {string} titleId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getAchievementsV2: function(titleId) {
|
||||
return joinUrl(baseApiUrl, "achievements/v2/" + titleId);
|
||||
},
|
||||
},
|
||||
Marketplace: {
|
||||
/**
|
||||
* Get and filter marketplace products
|
||||
* @param {integer | (integer | null)} productType query
|
||||
* @param {integer} limit query, default: 100
|
||||
* @param {integer} offset query, default: 0
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getProducts: function(productType, limit, offset) {
|
||||
var params = {};
|
||||
if (productType) params.product_type = productType;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
return joinUrl(baseApiUrl, "marketplace/products") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single marketplace product by marketplace product ID
|
||||
* @param {string} productId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleProduct: function(productId) {
|
||||
return joinUrl(baseApiUrl, "marketplace/products/" + productId);
|
||||
},
|
||||
/**
|
||||
* Get children of a marketplace product
|
||||
* @param {string} productId path, required
|
||||
* @param {integer | (integer | null)} productType query
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getProductChildren: function(productId, productType) {
|
||||
var params = {};
|
||||
if (productType) params.product_type = productType;
|
||||
return joinUrl(baseApiUrl, "marketplace/products/" + productId + "/children") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get and filter marketplace product instances
|
||||
* @param {string | (string | null)($uuid)} productId query
|
||||
* @param {string | (string | null)} hexOfferId query
|
||||
* @param {integer | (integer | null)} licenseTypeId query
|
||||
* @param {integer | (integer | null)} packageType query
|
||||
* @param {integer | (integer | null)} gameRegion query
|
||||
* @param {integer} limit query, default: 100
|
||||
* @param {integer} offset query, default: 0
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getProductInstances: function(productId, hexOfferId, licenseTypeId, packageType, gameRegion, limit, offset) {
|
||||
var params = {};
|
||||
if (productId) params.product_id = productId;
|
||||
if (hexOfferId) params.hex_offer_id = hexOfferId;
|
||||
if (licenseTypeId) params.license_type_id = licenseTypeId;
|
||||
if (packageType) params.package_type = packageType;
|
||||
if (gameRegion) params.game_region = gameRegion;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
return joinUrl(baseApiUrl, "marketplace/product-instances") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single marketplace product instance by marketplace product instance ID
|
||||
* @param {string} instanceId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getProductInstanceById: function(instanceId) {
|
||||
return joinUrl(baseApiUrl, "marketplace/product-instances/" + instanceId);
|
||||
},
|
||||
/**
|
||||
* Get all marketplace product types
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getProductTypes: function() {
|
||||
return joinUrl(baseApiUrl, "marketplace/product-types");
|
||||
},
|
||||
/**
|
||||
* Get single marketplace category
|
||||
* @param {integer} productTypeId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleProductType: function(productTypeId) {
|
||||
return joinUrl(baseApiUrl, "marketplace/product-types/" + productTypeId);
|
||||
},
|
||||
/**
|
||||
* Get and filter all marketplace categories
|
||||
* @param {integer | (integer | null)} parent query
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getCategories: function(parent) {
|
||||
var params = {};
|
||||
if (parent) params.parent = parent;
|
||||
return joinUrl(baseApiUrl, "marketplace/categories") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single marketplace category
|
||||
* @param {integer} categoryId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleCategory: function(categoryId) {
|
||||
return joinUrl(baseApiUrl, "marketplace/categories/" + categoryId);
|
||||
},
|
||||
/**
|
||||
* Get all marketplace locales
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getLocales: function() {
|
||||
return joinUrl(baseApiUrl, "marketplace/locales");
|
||||
},
|
||||
/**
|
||||
* Get single marketplace locale by locale string
|
||||
* @param {string} localeId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleLocale: function(localeId) {
|
||||
return joinUrl(baseApiUrl, "marketplace/locales/" + localeId);
|
||||
},
|
||||
},
|
||||
/**
|
||||
* Enum for product types, used in store API
|
||||
* @enum {string} DBox.API.ProductType
|
||||
*/
|
||||
ProductType: {
|
||||
application: "Application",
|
||||
avatarItem: "AvatarItem",
|
||||
consumable: "Consumable",
|
||||
durable: "Durable",
|
||||
game: "Game",
|
||||
movie: "Movie",
|
||||
pass: "PASS",
|
||||
tvSeries: "TvSeries",
|
||||
tvSeason: "TvSeason",
|
||||
tvEpisode: "TVEpisode",
|
||||
unmanagedConsumable: "UnmanagedConsumable",
|
||||
},
|
||||
/**
|
||||
* Enum for product families, used in store API
|
||||
* @enum {string} DBox.API.ProductFamily
|
||||
*/
|
||||
ProductFamily: {
|
||||
apps: "Apps",
|
||||
avatars: "Avatars",
|
||||
games: "Games",
|
||||
movies: "Movies",
|
||||
passes: "Passes",
|
||||
tv: "TV",
|
||||
},
|
||||
/**
|
||||
* Enum for order by, used in store API
|
||||
* @enum {string} DBox.API.OrderBy
|
||||
*/
|
||||
OrderBy: {
|
||||
productId: "product_id",
|
||||
titleId: "title_id",
|
||||
revisionId: "revision_id",
|
||||
/** such as "23654onetwoonestudio.cctv_kdpw61jgbrs34" */
|
||||
packageFamilyName: "package_family_name",
|
||||
/** such as "23654onetwoonestudio.cctv" */
|
||||
packageIdentityName: "package_identity_name",
|
||||
},
|
||||
/**
|
||||
* Enum for order direction, used in store API
|
||||
* @enum {string} DBox.API.OrderDirection
|
||||
*/
|
||||
OrderDirection: {
|
||||
/** @type {string} 升序 */
|
||||
asc: "asc",
|
||||
/** @type {string} 降序 */
|
||||
desc: "desc",
|
||||
},
|
||||
Store: {
|
||||
/**
|
||||
* Get store products
|
||||
* @param {string | (string | null)} category query
|
||||
* @param {string | (string | null)} titleId query
|
||||
* @param {DBox.API.ProductType | null} productType query
|
||||
* @param {DBox.API.ProductFamily | null} productFamily query
|
||||
* @param {DBox.API.OrderBy | null} orderBy query, default: productId
|
||||
* @param {DBox.API.OrderDirection | null} orderDirection query, default: asc
|
||||
* @param {integer} limit query, default: 100
|
||||
* @param {integer} offset query, default: 0
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getProducts: function(category, titleId, productType, productFamily, orderBy, orderDirection, limit, offset) {
|
||||
var params = {};
|
||||
if (category) params.category = category;
|
||||
if (titleId) params.title_id = titleId;
|
||||
if (productType) params.product_type = productType;
|
||||
if (productFamily) params.product_family = productFamily;
|
||||
if (orderBy) params.order_by = orderBy;
|
||||
if (orderDirection) params.order_direction = orderDirection;
|
||||
if (limit) params.limit = limit;
|
||||
if (offset) params.offset = offset;
|
||||
return joinUrl(baseApiUrl, "store/products") +
|
||||
"?" + buildParams(params);
|
||||
},
|
||||
/**
|
||||
* Get single store product
|
||||
* @param {string} productId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleProduct: function(productId) {
|
||||
return joinUrl(baseApiUrl, "store/products/" + productId);
|
||||
},
|
||||
/**
|
||||
* Get all related products for a product id. Includes both child and parent relationships. Check the product-ids for relationship direction. The relationship_type is parent -> child direction. Same combinations can appear multiple times with different relationship types.
|
||||
* @param {string} productId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getAllReleatedProducts: function(productId) {
|
||||
return joinUrl(baseApiUrl, "store/products/" + productId + "/related");
|
||||
},
|
||||
/**
|
||||
* Get single sku for store product
|
||||
* @param {string} productId path, required
|
||||
* @param {string} skuId path, required
|
||||
* @returns {string} request URL, method: GET
|
||||
*/
|
||||
getSingleSkuFromProduct: function(productId, skuId) {
|
||||
return joinUrl(baseApiUrl, "store/products/" + productId + "/sku/" + skuId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getXhr() {
|
||||
var xmlhttp;
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch (e) {
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch (E) {
|
||||
xmlhttp = false;
|
||||
}
|
||||
}
|
||||
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
}
|
||||
return xmlhttp;
|
||||
}
|
||||
/**
|
||||
* Send an HTTP request to the DBox API and return a Promise that resolves with the response.
|
||||
* @param {string} api DBox API
|
||||
* @param {string} method
|
||||
* @param {[boolean]} isAsync default: true
|
||||
* @param {[string]} username
|
||||
* @param {[string]} pwd
|
||||
* @returns {Promise <XMLHttpRequest>} A Promise that resolves with the response.
|
||||
*/
|
||||
var dboxXHR = function(api, method, isAsync, username, pwd) {
|
||||
method = method || "GET";
|
||||
if (typeof isAsync === "undefined" || isAsync === null) isAsync = true;
|
||||
var xhr = getXhr();
|
||||
if (username && pwd) {
|
||||
try {
|
||||
xhr.open(method, api, isAsync, username, pwd);
|
||||
} catch (e) {
|
||||
xhr.open(method, api, isAsync);
|
||||
}
|
||||
} else {
|
||||
xhr.open(method, api, isAsync);
|
||||
}
|
||||
return new Promise(function(c, e) {
|
||||
try {
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
if (c) c(xhr);
|
||||
} else {
|
||||
if (e) e(xhr.statusText + " (" + xhr.status + ")");
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send("");
|
||||
} catch (ex) {
|
||||
if (e) e(ex);
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Send an HTTP request to the DBox API and return a Promise that resolves with the response as JSON.
|
||||
* @param {string} api DBox API
|
||||
* @param {string} method
|
||||
* @param {[boolean]} isAsync default: true
|
||||
* @param {[string]} username
|
||||
* @param {[string]} pwd
|
||||
* @returns {Promise <object>} A Promise that resolves with the response as JSON.
|
||||
*/
|
||||
dboxXHR.parseJson = function(api, method, isAsync, username, pwd) {
|
||||
return dboxXHR(api, method, isAsync, username, pwd).then(function(xhr) {
|
||||
return JSON.parse(xhr.responseText);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* DBox namespace
|
||||
* @namespace {DBox}
|
||||
*/
|
||||
global.DBox = {
|
||||
/**
|
||||
* DBox API namespace
|
||||
* @namespace {DBox.API}
|
||||
*/
|
||||
API: dboxApi,
|
||||
/**
|
||||
* @function {DBox.XHR}
|
||||
*/
|
||||
xhr: dboxXHR,
|
||||
};
|
||||
})(this);
|
||||
206
shared/html/js/http.js
Normal file
206
shared/html/js/http.js
Normal file
@@ -0,0 +1,206 @@
|
||||
(function(global) {
|
||||
if (typeof global.Web === "undefined") global.Web = {};
|
||||
|
||||
function dataToString(obj) {
|
||||
if (typeof obj === "string") return obj;
|
||||
if (typeof obj === "object") return JSON.stringify(obj);
|
||||
return String(obj);
|
||||
}
|
||||
global.Web.Http = {
|
||||
Request: function() {
|
||||
var inst = external.Web.Http.createHttpRequest();
|
||||
this.open = function(method, url) { inst.open(method, url); };
|
||||
this.getHeaders = function() { return JSON.parse(inst.getHeadersToJson()); };
|
||||
this.getHeader = function(swName) { try { return inst.getHeader(swName); } catch (e) { return void 0; } };
|
||||
this.setHeader = function(swName, swValue) { inst.setHeader(swName, swValue); };
|
||||
this.removeHeader = function(swName) { inst.removeHeader(swName); };
|
||||
this.clearHeader = function() { inst.clearHeader(); };
|
||||
this.updateHeaders = function(headers) {
|
||||
var keys = Object.keys(headers);
|
||||
this.clearHeader();
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
this.setHeader(keys[i], dataToString(headers[keys[i]]));
|
||||
}
|
||||
};
|
||||
this.setHeaders = function(headers) {
|
||||
var keys = Object.keys(headers);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
inst.setHeader(keys[i], dataToString(headers[keys[i]]));
|
||||
}
|
||||
};
|
||||
this.send = function(body, encoding) { return inst.send(body, encoding); };
|
||||
this.sendAsync = function(body, encoding) {
|
||||
if (!encoding) encoding = "utf-8";
|
||||
return new Promise(function(c, e) {
|
||||
try {
|
||||
inst.sendAsync(body, encoding, function(resp) {
|
||||
if (c) c(resp);
|
||||
});
|
||||
} catch (ex) { if (e) e(ex); }
|
||||
});
|
||||
};
|
||||
Object.defineProperty(this, "timeout", {
|
||||
get: function() { return inst.timeout; },
|
||||
set: function(value) { inst.timeout = value; }
|
||||
});
|
||||
Object.defineProperty(this, "readWriteTimeout", {
|
||||
get: function() { return inst.readWriteTimeout; },
|
||||
set: function(value) { inst.readWriteTimeout = value; }
|
||||
});
|
||||
Object.defineProperty(this, "allowAutoRedirect", {
|
||||
get: function() { return inst.allowAutoRedirect; },
|
||||
set: function(value) { inst.allowAutoRedirect = value; }
|
||||
});
|
||||
Object.defineProperty(this, "allowWriteStreamBuffering", {
|
||||
get: function() { return inst.allowWriteStreamBuffering; },
|
||||
set: function(value) { inst.allowWriteStreamBuffering = value; }
|
||||
});
|
||||
Object.defineProperty(this, "keepAlive", {
|
||||
get: function() { return inst.keepAlive; },
|
||||
set: function(value) { inst.keepAlive = value; }
|
||||
});
|
||||
Object.defineProperty(this, "maximumAutomaticRedirections", {
|
||||
get: function() { return inst.maximumAutomaticRedirections; },
|
||||
set: function(value) { inst.maximumAutomaticRedirections = value; }
|
||||
});
|
||||
Object.defineProperty(this, "userAgent", {
|
||||
get: function() { return inst.userAgent; },
|
||||
set: function(value) { inst.userAgent = value; }
|
||||
});
|
||||
Object.defineProperty(this, "referer", {
|
||||
get: function() { return inst.referer; },
|
||||
set: function(value) { inst.referer = value; }
|
||||
});
|
||||
Object.defineProperty(this, "contentType", {
|
||||
get: function() { return inst.contentType; },
|
||||
set: function(value) { inst.contentType = value; }
|
||||
});
|
||||
Object.defineProperty(this, "accept", {
|
||||
get: function() { return inst.accept; },
|
||||
set: function(value) { inst.accept = value; }
|
||||
});
|
||||
Object.defineProperty(this, "proxy", {
|
||||
get: function() { return inst.proxy; },
|
||||
set: function(value) { inst.proxy = value; }
|
||||
});
|
||||
Object.defineProperty(this, "cookieContainer", {
|
||||
get: function() { return inst.cookieContainer; },
|
||||
set: function(value) { inst.cookieContainer = value; }
|
||||
});
|
||||
Object.defineProperty(this, "protocolVersion", {
|
||||
get: function() { return inst.protocolVersion; },
|
||||
set: function(value) { inst.protocolVersion = value; }
|
||||
});
|
||||
Object.defineProperty(this, "preAuthenticate", {
|
||||
get: function() { return inst.preAuthenticate; },
|
||||
set: function(value) { inst.preAuthenticate = value; }
|
||||
});
|
||||
Object.defineProperty(this, "credentials", {
|
||||
get: function() { return inst.credentials; },
|
||||
set: function(value) { inst.credentials = value; }
|
||||
});
|
||||
Object.defineProperty(this, "automaticDecompression", {
|
||||
get: function() { return inst.automaticDecompression; },
|
||||
set: function(value) { inst.automaticDecompression = value; }
|
||||
});
|
||||
this.dispose = function() { inst.dispose(); };
|
||||
},
|
||||
Header: {
|
||||
// 通用头(既可用于请求也可用于响应)
|
||||
General: {
|
||||
cacheControl: "Cache-Control",
|
||||
connection: "Connection",
|
||||
date: "Date",
|
||||
pragma: "Pragma",
|
||||
trailer: "Trailer",
|
||||
transferEncoding: "Transfer-Encoding",
|
||||
upgrade: "Upgrade",
|
||||
via: "Via",
|
||||
warning: "Warning"
|
||||
},
|
||||
// 请求头
|
||||
Request: {
|
||||
accept: "Accept",
|
||||
acceptCharset: "Accept-Charset",
|
||||
acceptEncoding: "Accept-Encoding",
|
||||
acceptLanguage: "Accept-Language",
|
||||
authorization: "Authorization",
|
||||
expect: "Expect",
|
||||
from: "From",
|
||||
host: "Host",
|
||||
ifMatch: "If-Match",
|
||||
ifModifiedSince: "If-Modified-Since",
|
||||
ifNoneMatch: "If-None-Match",
|
||||
ifRange: "If-Range",
|
||||
ifUnmodifiedSince: "If-Unmodified-Since",
|
||||
maxForwards: "Max-Forwards",
|
||||
proxyAuthorization: "Proxy-Authorization",
|
||||
range: "Range",
|
||||
referer: "Referer",
|
||||
te: "TE",
|
||||
userAgent: "User-Agent"
|
||||
},
|
||||
// 响应头
|
||||
Response: {
|
||||
acceptRanges: "Accept-Ranges",
|
||||
age: "Age",
|
||||
allow: "Allow",
|
||||
contentEncoding: "Content-Encoding",
|
||||
contentLanguage: "Content-Language",
|
||||
contentLength: "Content-Length",
|
||||
contentLocation: "Content-Location",
|
||||
contentRange: "Content-Range",
|
||||
contentType: "Content-Type",
|
||||
etag: "ETag",
|
||||
expires: "Expires",
|
||||
lastModified: "Last-Modified",
|
||||
location: "Location",
|
||||
proxyAuthenticate: "Proxy-Authenticate",
|
||||
retryAfter: "Retry-After",
|
||||
server: "Server",
|
||||
setCookie: "Set-Cookie",
|
||||
vary: "Vary",
|
||||
wwwAuthenticate: "WWW-Authenticate"
|
||||
},
|
||||
// CORS 相关头(常单独列出,也可归入请求/响应)
|
||||
Cors: {
|
||||
accessControlAllowOrigin: "Access-Control-Allow-Origin",
|
||||
accessControlAllowCredentials: "Access-Control-Allow-Credentials",
|
||||
accessControlAllowHeaders: "Access-Control-Allow-Headers",
|
||||
accessControlAllowMethods: "Access-Control-Allow-Methods",
|
||||
accessControlExposeHeaders: "Access-Control-Expose-Headers",
|
||||
accessControlMaxAge: "Access-Control-Max-Age",
|
||||
accessControlRequestHeaders: "Access-Control-Request-Headers",
|
||||
accessControlRequestMethod: "Access-Control-Request-Method",
|
||||
origin: "Origin"
|
||||
},
|
||||
// 安全/非标准常用头
|
||||
Security: {
|
||||
xFrameOptions: "X-Frame-Options",
|
||||
xContentTypeOptions: "X-Content-Type-Options",
|
||||
xXssProtection: "X-XSS-Protection",
|
||||
strictTransportSecurity: "Strict-Transport-Security",
|
||||
contentSecurityPolicy: "Content-Security-Policy",
|
||||
referrerPolicy: "Referrer-Policy",
|
||||
xRequestedWith: "X-Requested-With",
|
||||
xForwardedFor: "X-Forwarded-For",
|
||||
xForwardedProto: "X-Forwarded-Proto",
|
||||
xRealIp: "X-Real-IP"
|
||||
}
|
||||
},
|
||||
Method: {
|
||||
get: "GET",
|
||||
post: "POST",
|
||||
put: "PUT",
|
||||
delete: "DELETE",
|
||||
head: "HEAD",
|
||||
options: "OPTIONS",
|
||||
trace: "TRACE",
|
||||
connect: "CONNECT"
|
||||
},
|
||||
Version: {
|
||||
v1_0: "1.0",
|
||||
v1_1: "1.1",
|
||||
}
|
||||
}
|
||||
})(this);
|
||||
@@ -162,15 +162,16 @@
|
||||
}
|
||||
oldTags.push(k);
|
||||
promises.push(
|
||||
anime.runAsync(p.page, [
|
||||
anime.Keyframes.Opacity.hidden
|
||||
]).then((function(page, key) {
|
||||
return function() {
|
||||
page.style.display = "none";
|
||||
page.style.opacity = 0;
|
||||
emit("unload", key);
|
||||
};
|
||||
})(p.page, k))
|
||||
(function(page, key) {
|
||||
// 返回 anime.runAsync 产生的 Promise
|
||||
return anime.runAsync(page, [anime.Keyframes.Opacity.hidden])
|
||||
.then(function() {
|
||||
page.style.display = "none";
|
||||
page.style.opacity = 0;
|
||||
page.style.height = 0;
|
||||
emit("unload", key);
|
||||
});
|
||||
})(p.page, k)
|
||||
);
|
||||
p.guide.classList.remove("selected");
|
||||
}
|
||||
|
||||
@@ -52,7 +52,13 @@
|
||||
},
|
||||
cancelAll: function() { external.Package.Reader.cancelAll(); },
|
||||
addApplicationReadItem: function(swItemName) { return external.Package.Reader.addApplicationItem(swItemName); },
|
||||
removeApplicationReadItem: function(swItemName) { return external.Package.Reader.removeApplicationItem(swItemName); }
|
||||
removeApplicationReadItem: function(swItemName) { return external.Package.Reader.removeApplicationItem(swItemName); },
|
||||
updateApplicationReadItems: function(aswArray) {
|
||||
external.Package.Reader.updateApplicationItems(aswArray);
|
||||
},
|
||||
getApplicationReadItems: function() {
|
||||
return JSON.parse(external.Package.Reader.getApplicationItemsToJson());
|
||||
},
|
||||
},
|
||||
manager: {
|
||||
add: function(swPkgPath, uOptions) {
|
||||
@@ -169,5 +175,76 @@
|
||||
cancelAll: function() { mgr.cancelAll(); },
|
||||
active: function(swAppUserModelID, swArgs) { return mgr.activeApp(swAppUserModelID, swArgs || null); }
|
||||
},
|
||||
utils: (function() {
|
||||
// 解析包全名,格式: <name>_<version>_<processorArchitecture>_<resourceId>_<publisherId>
|
||||
// resourceId 可能为空(表现为两个连续下划线)
|
||||
function parsePackageFullName(fullName) {
|
||||
var parts = fullName.split('_');
|
||||
// 按格式应有5部分: [name, version, architecture, resourceId, publisherId]
|
||||
return {
|
||||
name: parts[0],
|
||||
version: parts[1],
|
||||
architecture: parts[2],
|
||||
resourceId: parts[3],
|
||||
publisherId: parts[4]
|
||||
};
|
||||
}
|
||||
|
||||
// 解析包系列名,格式: <name>_<publisherId>
|
||||
function parsePackageFamilyName(familyName) {
|
||||
var underscoreIndex = familyName.indexOf('_');
|
||||
if (underscoreIndex === -1) {
|
||||
// 异常情况,按原字符串处理,但题目不会出现
|
||||
return { name: familyName, publisherId: '' };
|
||||
}
|
||||
return {
|
||||
name: familyName.substring(0, underscoreIndex),
|
||||
publisherId: familyName.substring(underscoreIndex + 1)
|
||||
};
|
||||
}
|
||||
|
||||
// 将对象转换为包全名字符串
|
||||
// 对象应包含 name, version, architecture, publisherId 字段,resourceId 可选
|
||||
function stringifyPackageFullName(pkg) {
|
||||
var resourcePart = (pkg.resourceId === undefined || pkg.resourceId === null) ? '' : pkg.resourceId;
|
||||
return pkg.name + '_' + pkg.version + '_' + pkg.architecture + '_' + resourcePart + '_' + pkg.publisherId;
|
||||
}
|
||||
|
||||
// 将对象转换为包系列名字符串
|
||||
// 对象应包含 name, publisherId 字段
|
||||
function stringifyPackageFamilyName(pkgFamily) {
|
||||
return pkgFamily.name + '_' + pkgFamily.publisherId;
|
||||
}
|
||||
return {
|
||||
parsePackageFullName: parsePackageFullName,
|
||||
parsePackageFamilyName: parsePackageFamilyName,
|
||||
stringifyPackageFullName: stringifyPackageFullName,
|
||||
stringifyPackageFamilyName: stringifyPackageFamilyName,
|
||||
isDependency: function(swPkgIdentityName) {
|
||||
var list = [
|
||||
"Microsoft.Net.Native.Framework",
|
||||
"Microsoft.Net.Native.Runtime",
|
||||
"Microsoft.Net.CoreRuntime",
|
||||
"WindowsPreview.Kinect",
|
||||
"Microsoft.VCLibs",
|
||||
"Microsoft.WinJS",
|
||||
"Microsoft.UI.Xaml",
|
||||
"Microsoft.WindowsAppRuntime",
|
||||
"Microsoft.Advertising.XAML",
|
||||
"Microsoft.Midi.Gmdls",
|
||||
"Microsoft.Services.Store.Engagement",
|
||||
"Microsoft.Media.PlayReadyClient"
|
||||
];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (swPkgIdentityName.toLowerCase().indexOf(list[i].toLowerCase()) !== -1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})()
|
||||
};
|
||||
global.Package.Reader = global.Package.reader;
|
||||
global.Package.Manager = global.Package.manager;
|
||||
global.Package.Utils = global.Package.utils;
|
||||
})(this);
|
||||
@@ -529,4 +529,102 @@
|
||||
}
|
||||
global.Set = Set;
|
||||
}
|
||||
})(this);
|
||||
(function(global) {
|
||||
// 如果原生 WeakMap 已存在,则不覆盖
|
||||
if (typeof global.WeakMap !== "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
function WeakMap(iterable) {
|
||||
// 必须使用 new 调用
|
||||
if (!(this instanceof WeakMap)) {
|
||||
throw new TypeError('Constructor WeakMap requires "new"');
|
||||
}
|
||||
|
||||
// 私有存储:每个实例独立维护一个键值对数组
|
||||
var entries = [];
|
||||
|
||||
// 验证 key 必须是对象或函数(不能是 null 或原始值)
|
||||
function validateKey(key) {
|
||||
if (key === null || (typeof key !== 'object' && typeof key !== 'function')) {
|
||||
throw new TypeError('WeakMap key must be an object');
|
||||
}
|
||||
}
|
||||
|
||||
// 设置键值对
|
||||
this.set = function(key, value) {
|
||||
validateKey(key);
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
if (entries[i][0] === key) {
|
||||
entries[i][1] = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
entries.push([key, value]);
|
||||
return this;
|
||||
};
|
||||
|
||||
// 获取键对应的值
|
||||
this.get = function(key) {
|
||||
validateKey(key);
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
if (entries[i][0] === key) {
|
||||
return entries[i][1];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// 判断是否存在指定键
|
||||
this.has = function(key) {
|
||||
validateKey(key);
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
if (entries[i][0] === key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// 删除指定键及其值
|
||||
this.delete = function(key) {
|
||||
validateKey(key);
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
if (entries[i][0] === key) {
|
||||
entries.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// 处理可选的初始化参数(iterable,例如 [[key1, value1], [key2, value2]])
|
||||
if (iterable !== null && iterable !== undefined) {
|
||||
// 支持数组或类数组(具备 forEach 方法的对象)
|
||||
if (typeof iterable.forEach === 'function') {
|
||||
var self = this;
|
||||
iterable.forEach(function(item) {
|
||||
if (!Array.isArray(item) || item.length < 2) {
|
||||
throw new TypeError('Iterator value is not an entry object');
|
||||
}
|
||||
self.set(item[0], item[1]);
|
||||
});
|
||||
} else if (typeof iterable.length === 'number') {
|
||||
// 类数组对象(如 arguments)
|
||||
for (var i = 0; i < iterable.length; i++) {
|
||||
var item = iterable[i];
|
||||
if (!Array.isArray(item) || item.length < 2) {
|
||||
throw new TypeError('Iterator value is not an entry object');
|
||||
}
|
||||
this.set(item[0], item[1]);
|
||||
}
|
||||
} else {
|
||||
throw new TypeError('WeakMap iterable is not iterable');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 挂载到全局对象
|
||||
global.WeakMap = WeakMap;
|
||||
})(this);
|
||||
@@ -502,6 +502,22 @@
|
||||
if (!p.removeEventListener) p.removeEventListener = PromisePolyfill.removeEventListener;
|
||||
if (!p.dispatchEvent) p.dispatchEvent = PromisePolyfill.dispatchEvent;
|
||||
if (!p.onerror) p.onerror = null;
|
||||
if (typeof p.prototype.then !== "function") {
|
||||
p.prototype.then = function(onFulfilled, onRejected) {
|
||||
return new p(function(resolve, reject) {
|
||||
this.then(resolve, reject);
|
||||
}).then(onFulfilled, onRejected);
|
||||
};
|
||||
}
|
||||
if (typeof p.prototype.done !== "function") {
|
||||
p.prototype.done = function(onFulfilled, onRejected) {
|
||||
this.then(onFulfilled, onRejected)["catch"](function(ex) {
|
||||
setTimeout(function() {
|
||||
throw ex;
|
||||
}, 0);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
if (typeof global.WinJS !== "undefined" && typeof global.WinJS.Promise !== "undefined") {
|
||||
var wp = global.WinJS.Promise;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
});
|
||||
var themeColor = Bridge.UI.themeColor;
|
||||
pagemgr.register("reader", document.getElementById("tag-reader"), document.getElementById("page-reader"));
|
||||
pagemgr.register("acquire", document.getElementById("tag-acquire"), document.getElementById("page-acquire"));
|
||||
pagemgr.go("reader");
|
||||
});
|
||||
})(this);
|
||||
1357
shared/html/js/storergapi.js
Normal file
1357
shared/html/js/storergapi.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -352,6 +352,13 @@ aside>nav ul li div[role=img] {
|
||||
}
|
||||
|
||||
.ispage {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
box-sizing: border-box;
|
||||
opacity: 1;
|
||||
transition: all 0.4s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.ispage.padding {
|
||||
padding: 44px 60px;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Package Manager</title>
|
||||
<title>Package Reader</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -32,6 +32,9 @@
|
||||
<script type="text/javascript" src="libs/msgbox/msgbox.js"></script>
|
||||
<script type="text/javascript" src="js/init.js"></script>
|
||||
<script type="text/javascript" src="js/pkginfo.js"></script>
|
||||
<script type="text/javascript" src="js/http.js"></script>
|
||||
<script type="text/javascript" src="js/storergapi.js"></script>
|
||||
<script type="text/javascript" src="js/dboxapi.js"></script>
|
||||
<script type="text/javascript" src="js/datasrc.js"></script>
|
||||
<script type="text/javascript" src="js/appbar.js"></script>
|
||||
<script type="text/javascript" src="js/pagemgr.js"></script>
|
||||
@@ -55,8 +58,8 @@
|
||||
<body>
|
||||
<div id="readerpage" class="pagecontainer full">
|
||||
<div class="page full guide fold">
|
||||
<main class="main padding">
|
||||
<div id="page-reader" style="display: none;" class="ispage">
|
||||
<main class="main">
|
||||
<div id="page-reader" style="display: none;" class="ispage padding">
|
||||
<h2>读取</h2>
|
||||
<p>请选择一个包,获取其信息。</p>
|
||||
<div>
|
||||
@@ -365,6 +368,292 @@
|
||||
})(this);
|
||||
</script>
|
||||
</div>
|
||||
<div id="page-acquire" style="display: none;" class="ispage padding">
|
||||
<h2>获取</h2>
|
||||
<div id="acquire-forbidden" style="width: 100%;">
|
||||
<p>由于来自 store.rg-adguard.net 的限制,现在暂时无法实现对包的获取。请自行打开下面 URL 进行访问。</p>
|
||||
<a onclick="external.Process.open ('https://store.rg-adguard.net')">store.rg-adguard.net</a>
|
||||
</div>
|
||||
<div id="acquire-enable" style="width: 100%;">
|
||||
<p>请在下面的输入框中输入要查询的内容,设置好参数后将进行查询。</p>
|
||||
<div>
|
||||
<div>
|
||||
<input type="text" id="acquire-input">
|
||||
<select id="acquire-valuetype" name="type">
|
||||
<option value="url">分享链接</option>
|
||||
<option value="ProductId">产品 ID</option>
|
||||
<option value="PackageFamilyName">包系列名</option>
|
||||
<option value="CategoryId">类别 ID</option>
|
||||
</select>
|
||||
<select id="acquire-channel" name="ring">
|
||||
<option title="Windows Insider Fast" value="WIF">快速</option>
|
||||
<option title="Windows Insider Slow" value="WIS">慢速</option>
|
||||
<option title="Release Preview" value="RP" selected>发布预览</option>
|
||||
<option title="Default OS" value="Retail">正式</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<div class="itemrow">
|
||||
<input type="checkbox" id="acquire-smartquery" style="margin-left: 0px;">
|
||||
<label for="acquire-smartquery">自动查询</label>
|
||||
</div>
|
||||
<button id="acquire-query">查询</button>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.acquire-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
align-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
-ms-user-select: element;
|
||||
user-select: all;
|
||||
}
|
||||
|
||||
.acquire-item #name {
|
||||
font-size: 11pt;
|
||||
width: 100%;
|
||||
line-height: 1.3em;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.acquire-item .medium {
|
||||
width: 100%;
|
||||
font-size: 10pt;
|
||||
line-height: 1.2em;
|
||||
font-weight: normal;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.acquire-item .medium div {
|
||||
text-align: center;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.acquire-item .medium #ext {
|
||||
text-align: left;
|
||||
max-width: 100px;
|
||||
/*min-width: 97px;*/
|
||||
}
|
||||
|
||||
.acquire-item .medium div:nth-child(1),
|
||||
.acquire-item .medium div:nth-child(3),
|
||||
.acquire-item .medium div:nth-child(5) {
|
||||
background-color: #e9fff5;
|
||||
}
|
||||
|
||||
.acquire-item .medium div:nth-child(2),
|
||||
.acquire-item .medium div:nth-child(4),
|
||||
.acquire-item .medium div:nth-child(6) {
|
||||
background-color: #ffffef;
|
||||
}
|
||||
|
||||
.acquire-item .bottom {
|
||||
font-weight: bold;
|
||||
font-size: 9pt;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.acquire-item #hashpart {
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.acquire-item:hover {
|
||||
background-color: rgba(0, 0, 0, 0.122);
|
||||
}
|
||||
|
||||
.acquire-item #download {
|
||||
cursor: pointer;
|
||||
font-size: 10pt;
|
||||
}
|
||||
</style>
|
||||
<div id="acquire-template" class="acquire-item" style="display: none;">
|
||||
<div id="name" class="top" title="Identity Name">Identity Name</div>
|
||||
<div class="medium">
|
||||
<div id="ext" title="File Type">Appx</div>
|
||||
<div id="version" title="Version">1.0.0.0</div>
|
||||
<div id="architecture" title="Processor Architecture">neutral</div>
|
||||
<div id="publisherId" title="Identity Publisher Id"></div>
|
||||
<div id="size" title="File Size"></div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div id="hashpart"><span>SHA-1: </span><span id="hash"></span></div>
|
||||
<div><a download id="download" href="">点击下载</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="acquire-loading">
|
||||
<br>
|
||||
<div class="container itemrow">
|
||||
<progress class="win-ring" style="margin-right: 10px;"></progress>
|
||||
<span class="win-label title" data-res-resxml="MANAGER_APP_INSTALLEDAPPS_LOADING"></span>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
<div id="acquire-result" style="width: 100%;">
|
||||
<p style="font-weight: normal;" title="Category ID"><span>类别 ID</span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p>
|
||||
<h3>以下可能为检索到的应用</h3>
|
||||
<div id="acquire-list-app" style="width: 100%;"></div>
|
||||
<h3>以下可能为检索到的依赖项</h3>
|
||||
<div id="acquire-list-dep" style="width: 100%;"></div>
|
||||
</div>
|
||||
<script>
|
||||
(function(global) {
|
||||
var conf = external.Config.current;
|
||||
var set = conf.getSection("Settings");
|
||||
var isForbidden = !set.getKey("EnableAcquire").readBool(false);
|
||||
var acquireInput = document.getElementById("acquire-input");
|
||||
var acquireValuetype = document.getElementById("acquire-valuetype");
|
||||
var acquireChannel = document.getElementById("acquire-channel");
|
||||
var acquireSmartquery = document.getElementById("acquire-smartquery");
|
||||
var acquireQuery = document.getElementById("acquire-query");
|
||||
var acquireResult = document.getElementById("acquire-result");
|
||||
var acquireListApp = document.getElementById("acquire-list-app");
|
||||
var acquireListDep = document.getElementById("acquire-list-dep");
|
||||
var acquireForbidden = document.getElementById("acquire-forbidden");
|
||||
var acquireEnable = document.getElementById("acquire-enable");
|
||||
var acquireCategoryid = document.getElementById("acquire-categoryid");
|
||||
var acquireTemplate = document.getElementById("acquire-template");
|
||||
var acquireLoading = document.getElementById("acquire-loading");
|
||||
var acquireLoadingRing = acquireLoading.querySelector(".win-ring");
|
||||
var acquireLoadingLabel = acquireLoading.querySelector(".win-label");
|
||||
acquireForbidden.style.display = isForbidden ? "" : "none";
|
||||
acquireEnable.style.display = isForbidden ? "none" : "";
|
||||
acquireResult.style.display = isForbidden ? "none" : "none";
|
||||
var dataSrc = {
|
||||
apps: new DataView.DataSource(),
|
||||
deps: new DataView.DataSource()
|
||||
};
|
||||
var putils = Package.Utils;
|
||||
var templateFunc = function(item, index) {
|
||||
var node = acquireTemplate.cloneNode(true);
|
||||
node.style.display = "";
|
||||
node.id = "";
|
||||
var lastDotIndex = item.file.lastIndexOf(".");
|
||||
var fileNamePart = lastDotIndex !== -1 ? item.file.substring(0, lastDotIndex) : item.file;
|
||||
var fileExtension = lastDotIndex !== -1 ? item.file.substring(lastDotIndex + 1) : "";
|
||||
var identityName = putils.parsePackageFullName(fileNamePart);
|
||||
node.querySelector("#name").textContent = identityName.name;
|
||||
node.querySelector("#ext").textContent = fileExtension;
|
||||
node.querySelector("#version").textContent = identityName.version;
|
||||
node.querySelector("#architecture").textContent = identityName.architecture;
|
||||
node.querySelector("#publisherId").textContent = identityName.publisherId;
|
||||
node.querySelector("#size").textContent = item.size;
|
||||
node.querySelector("#hash").textContent = item.sha1;
|
||||
node.title = item.file;
|
||||
node.querySelector("#download").href = item.url;
|
||||
node.querySelector("#download").title = item.url;
|
||||
return node;
|
||||
};
|
||||
var listView = {
|
||||
apps: new DataView.ListView(acquireListApp, templateFunc),
|
||||
deps: new DataView.ListView(acquireListDep, templateFunc)
|
||||
};
|
||||
listView.apps.bind(dataSrc.apps);
|
||||
listView.deps.bind(dataSrc.deps);
|
||||
var keys = Object.keys(listView);
|
||||
keys.forEach(function(k, i) {
|
||||
var listview = listView[k];
|
||||
var p = document.createElement("p");
|
||||
p.textContent = "还没有内容...";
|
||||
listview.emptyView = p;
|
||||
});
|
||||
acquireLoading.statusBar = new TransitionPanel(acquireLoading, {
|
||||
axis: "y",
|
||||
speed: 500,
|
||||
});
|
||||
acquireSmartquery.onchange = function() {
|
||||
acquireValuetype.disabled =
|
||||
acquireChannel.disabled = this.checked;
|
||||
};
|
||||
acquireSmartquery.checked = set.getKey("AcquireSmartQuery").readBool(false);
|
||||
acquireValuetype.disabled =
|
||||
acquireChannel.disabled = acquireSmartquery.checked;
|
||||
acquireQuery.onclick = function() {
|
||||
var self = this;
|
||||
self.disabled = true;
|
||||
acquireResult.style.display = "none";
|
||||
acquireLoadingRing.style.display = "";
|
||||
acquireLoading.statusBar.show();
|
||||
var queryFunc = StoreRG.xhr.parse;
|
||||
if (acquireSmartquery.checked) {
|
||||
queryFunc = StoreRG.xhr.smartQuery;
|
||||
}
|
||||
acquireInput.disabled =
|
||||
acquireSmartquery.disabled =
|
||||
acquireValuetype.disabled =
|
||||
acquireChannel.disabled = true;
|
||||
queryFunc = StoreRG.test;
|
||||
acquireLoadingLabel.textContent = "正在查询...";
|
||||
queryFunc(acquireInput.value, acquireValuetype.value, acquireChannel.value).then(function(result) {
|
||||
acquireCategoryid.textContent = result.categoryId;
|
||||
var applist = [];
|
||||
var deplist = [];
|
||||
result.datas.forEach(function(item, index) {
|
||||
if (item.file.indexOf(".BlockMap") >= 0) return;
|
||||
if (putils.isDependency(item.file)) {
|
||||
deplist.push(item);
|
||||
} else {
|
||||
applist.push(item);
|
||||
}
|
||||
});
|
||||
dataSrc.apps.updateList(applist, function(item) {
|
||||
return item.file;
|
||||
});
|
||||
listView.apps.refresh();
|
||||
dataSrc.deps.updateList(deplist, function(item) {
|
||||
return item.file;
|
||||
});
|
||||
listView.deps.refresh();
|
||||
acquireLoadingLabel.textContent = "已获取到 {0} 个信息"
|
||||
.replace("{0}", applist.length + deplist.length);
|
||||
}, function(err) {
|
||||
dataSrc.apps.clear();
|
||||
dataSrc.deps.clear();
|
||||
listView.apps.refresh();
|
||||
listView.deps.refresh();
|
||||
acquireLoadingLabel.textContent = err.message || err;
|
||||
return Promise.wrap();
|
||||
}).done(function() {
|
||||
acquireResult.style.display = "";
|
||||
setTimeout(function() {
|
||||
acquireLoading.statusBar.hide();
|
||||
}, 10000);
|
||||
self.disabled = false;
|
||||
acquireLoadingRing.style.display = "none";
|
||||
acquireInput.disabled =
|
||||
acquireSmartquery.disabled = false;
|
||||
acquireValuetype.disabled =
|
||||
acquireChannel.disabled = acquireSmartquery.checked;
|
||||
});
|
||||
}
|
||||
})(this);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<aside class="win-ui-dark">
|
||||
<nav class="container">
|
||||
@@ -390,6 +679,10 @@
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span>
|
||||
</li>
|
||||
<li id="tag-acquire">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span>
|
||||
</li>
|
||||
<li id="tag-settings">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="MANAGER_SETTINGS"></span>
|
||||
|
||||
Reference in New Issue
Block a user