Update Shell and Fix Bugs

This commit is contained in:
Bruce
2025-12-07 15:18:40 +08:00
parent 98c0f91b8c
commit bb6b2b7521
51 changed files with 46468 additions and 12601 deletions

View File

@@ -1,16 +1,3 @@
body {
margin: 0;
width: 100%;
height: 100%;
-ms-overflow-style: -ms-autohiding-scrollbar;
user-select: none;
-ms-user-select: none;
}
body * {
-ms-overflow-style: -ms-autohiding-scrollbar;
}
*,
button,
input,
@@ -45,10 +32,26 @@ video,
canvas,
form,
fieldset,
legend {
legend,
.win-type-x-large,
.win-type-xx-large,
.font-fix {
font-family: "Microsoft YaHei", "Segoe UI", "Ebrima", "Nirmala", "Gadugi", "Segoe UI Emoji", "Segoe UI Symbol", "Meiryo", "Leelawadee", "Microsoft JhengHei", "Malgun Gothic", "Estrangelo Edessa", "Microsoft Himalaya", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Tai Le", "Microsoft Yi Baiti", "Mongolian Baiti", "MV Boli", "Myanmar Text", "Javanese Text", "Cambria Math";
}
body {
margin: 0;
width: 100%;
height: 100%;
-ms-overflow-style: -ms-autohiding-scrollbar;
user-select: none;
-ms-user-select: none;
}
body * {
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.pagecontainer {
padding: 0px;
position: absolute;

View File

@@ -357,4 +357,47 @@ Windows.UI.Event.Util.removeEvent(window, "resize", handler);
};
}
module.exports = { debounce: debounce };
})(this);
(function(global) {
"use strict";
var eToEvent = {}; // 存储元素和回调
var lastContent = {}; // 存储上一次的 textContent
// 注册文本变化事件
global.setTextChangeEvent = function(el, fn) {
if (!el || typeof fn !== "function") return;
var id = el.__textChangeId;
if (!id) {
id = Math.random().toString(36).substr(2, 9);
el.__textChangeId = id;
lastContent[id] = el.textContent;
}
eToEvent[id] = { el: el, callback: fn };
};
// 定时轮询
setInterval(function() {
var keys = Object.keys(eToEvent);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var obj = eToEvent[key];
var el = obj.el;
var currentText = el.textContent;
if (currentText !== lastContent[key]) {
lastContent[key] = currentText;
try {
obj.callback.call(el, currentText);
} catch (e) {
// 忽略回调错误
if (typeof console !== "undefined") console.error(e);
}
}
}
}, 20);
})(this);

View File

@@ -127,4 +127,64 @@
};
}
}
})(this);
})(this);
// attachEvent / detachEvent polyfill for IE11+
(function() {
if (!Element.prototype.attachEvent) {
Element.prototype.attachEvent = function(eventName, handler) {
// IE attachEvent 的事件名需要 "on" 前缀
eventName = eventName.toLowerCase();
// 包装函数,模仿旧 IE 的 event 对象
var wrapper = function(e) {
e = e || window.event;
// 兼容 IE 风格 event 属性
e.srcElement = e.target || this;
e.returnValue = true;
e.cancelBubble = false;
// 模拟 IE 的防止默认行为
Object.defineProperty(e, "cancelBubble", {
set: function(val) {
if (val) e.stopPropagation();
}
});
Object.defineProperty(e, "returnValue", {
set: function(val) {
if (val === false) e.preventDefault();
}
});
// 调用原事件处理函数
return handler.call(this, e);
};
// 存储 handler 映射,供 detachEvent 用
if (!this._attachEventWrappers) this._attachEventWrappers = {};
if (!this._attachEventWrappers[eventName]) this._attachEventWrappers[eventName] = [];
this._attachEventWrappers[eventName].push({
original: handler,
wrapped: wrapper
});
this.addEventListener(eventName.replace(/^on/, ""), wrapper, false);
};
Element.prototype.detachEvent = function(eventName, handler) {
eventName = eventName.toLowerCase();
if (!this._attachEventWrappers || !this._attachEventWrappers[eventName]) return;
var list = this._attachEventWrappers[eventName];
for (var i = 0; i < list.length; i++) {
if (list[i].original === handler) {
this.removeEventListener(eventName.replace(/^on/, ""), list[i].wrapped, false);
list.splice(i, 1);
break;
}
}
};
}
})();

View File

@@ -0,0 +1,209 @@
.toggle-switch {
box-sizing: border-box;
border: 2px solid rgb(166, 166, 166);
width: 50px;
height: 19px;
max-width: 50px !important;
max-height: 19px !important;
position: relative;
display: block;
}
.toggle-switch>input[type="checkbox"] {
position: absolute;
opacity: 0;
width: 100%;
height: 100%;
margin: 0;
z-index: 2;
cursor: pointer;
}
.toggle-background {
background-color: rgb(166, 166, 166);
position: absolute;
top: 1px;
left: 1px;
right: 1px;
bottom: 1px;
z-index: 1;
transition: all 0.25s cubic-bezier(0.1, 0.9, 0.2, 1);
}
.toggle-switch>input[type="checkbox"]:disabled {
cursor: not-allowed;
}
.toggle-switch>input[type="checkbox"]:disabled+.toggle-background {
background-color: rgb(224, 224, 224);
}
.toggle-switch>input[type="checkbox"]:disabled~.toggle-switch-border {
border-color: rgb(204, 204, 204);
}
.toggle-switch>input[type="checkbox"]:disabled~.toggle-switch {
border-color: rgb(204, 204, 204);
}
.toggle-switch:hover>input[type="checkbox"]:not(:disabled):not(:checked)+.toggle-background {
background-color: rgb(181, 181, 181);
}
.toggle-switch:active>input[type="checkbox"]:not(:disabled):not(:checked)+.toggle-background {
background-color: rgb(189, 189, 189);
}
.toggle-switch-border {
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
border: 2px solid rgb(166, 166, 166);
pointer-events: none;
z-index: 0;
}
.toggle-background:after {
position: absolute;
content: "";
height: 19px;
width: 12px;
background-color: black;
transition: transform 0.25s cubic-bezier(0.1, 0.9, 0.2, 1);
top: -3px;
left: -3px;
}
.toggle-switch>input[type="checkbox"]:checked+.toggle-background:after {
transform: translateX(38px);
}
.toggle-background:before {
position: absolute;
content: "";
width: 0;
height: 100%;
background-color: rgb(70, 23, 181);
transition: all 0.25s cubic-bezier(0.1, 0.9, 0.2, 1);
top: 0px;
left: 0px;
}
.toggle-switch>input[type="checkbox"]:checked+.toggle-background:before {
width: 100%;
}
.toggle-switch:hover>input:checked:not(:disabled)+.toggle-background:before {
background-color: rgb(90, 43, 202);
}
.toggle-switch:active>input:checked:not(:disabled)+.toggle-background:before {
background-color: rgb(143, 100, 244);
}
.toggle-showstatus {
margin-left: 90px;
}
.toggle-status {
position: absolute;
z-index: 4;
height: 100%;
width: 0px;
}
.toggle-status:before {
content: "Off";
position: absolute;
left: -92px;
top: 50%;
transform: translateY(-50%);
font-weight: bold;
color: black;
font-family: "Microsoft YaHei", "Segoe UI", "Ebrima", "Nirmala", "Gadugi", "Segoe UI Emoji", "Segoe UI Symbol", "Meiryo", "Leelawadee", "Microsoft JhengHei", "Malgun Gothic", "Estrangelo Edessa", "Microsoft Himalaya", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Tai Le", "Microsoft Yi Baiti", "Mongolian Baiti", "MV Boli", "Myanmar Text", "Javanese Text", "Cambria Math";
}
label.toggle-status:has(input:checked)::before {
content: "On";
}
.toggle-switch>input:checked~.toggle-status::before {
content: "On";
}
/* Dark Mode */
.toggle-switch-dark {
border: 2px solid rgb(87, 29, 222);
}
.toggle-background-dark {
background-color: rgb(94, 43, 213);
}
.toggle-switch-dark>input[type="checkbox"]:disabled:not(:checked)+.toggle-background-dark {
background-color: rgb(97, 69, 160);
}
.toggle-switch-dark>input[type="checkbox"]:disabled:checked+.toggle-background-dark {
background-color: rgb(81, 81, 81);
}
.toggle-switch-dark>input[type="checkbox"]:disabled~.toggle-switch-border-dark {
border-color: rgb(79, 26, 204);
}
.toggle-switch-dark>input[type="checkbox"]:disabled~.toggle-switch-dark {
border-color: rgb(79, 26, 204);
}
.toggle-switch-dark:hover>input[type="checkbox"]:not(:disabled):not(:checked)+.toggle-background-dark {
background-color: rgb(120, 83, 207);
}
.toggle-switch-dark:active>input[type="checkbox"]:not(:disabled):not(:checked)+.toggle-background-dark {
background-color: rgb(143, 100, 244);
}
.toggle-switch-border-dark {
border: 2px solid rgb(87, 29, 222);
}
.toggle-background-dark:after {
background-color: white;
}
.toggle-switch-dark>input:disabled+.toggle-background:after {
background-color: rgb(87, 29, 222);
}
.toggle-background-dark:before {
background-color: rgb(70, 23, 181);
}
.toggle-switch-dark:hover>input:checked:not(:disabled)+.toggle-background:before {
background-color: rgb(90, 43, 202);
}
.toggle-switch-dark:active>input:checked:not(:disabled)+.toggle-background:before {
background-color: rgb(143, 100, 244);
}
.toggle-switch-dark>input:checked:disabled+.toggle-background:before {
background-color: rgb(81, 81, 81);
}
.toggle-switch-dark:hover>input:checked:disabled+.toggle-background:before {
background-color: rgb(81, 81, 81);
}
.toggle-switch-dark:active>input:checked:disabled+.toggle-background:before {
background-color: rgb(81, 81, 81);
}
.toggle-status-dark:before {
color: white;
}

View File

@@ -0,0 +1,888 @@
(function(global) {
/**
* 检查 CSS 选择器是否重复(精确匹配)
* @param {string} targetSelector 要检查的目标选择器(如 ".toggle-switch>input[type="checkbox"]"
* @returns {number} 返回该选择器在样式表中的出现次数
*/
function checkSelectorDuplicate(targetSelector) {
var count = 0;
function traverseRules(rules) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (rule.type === 1) {
if (normalizeSelector(rule.selectorText) === normalizeSelector(targetSelector)) {
count++;
}
} else if (rule.type === 4 || rule.type === 12) {
var nestedRules = rule.cssRules || rule.rules;
if (nestedRules) traverseRules(nestedRules);
}
}
}
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
try {
var rules = sheets[i].cssRules || sheets[i].rules;
if (rules) traverseRules(rules);
} catch (e) {
console.warn('无法读取跨域样式表:', e);
}
}
return count;
}
function normalizeSelector(selector) {
return selector
.replace(/\s*([>+~])\s*/g, '$1')
.replace(/\s{2,}/g, ' ')
.trim();
}
/**
* 通过选择器移除匹配的 CSS 规则
* @param {string} targetSelector 要移除的目标选择器(如 ".toggle-switch>input[type="checkbox"]"
* @returns {number} 返回实际移除的规则数量
*/
function removeCSSRulesBySelector(targetSelector) {
var removedCount = 0;
function traverseAndRemove(rules) {
for (var i = rules.length - 1; i >= 0; i--) {
var rule = rules[i];
if (rule.type === 1) {
if (rule.selectorText === targetSelector) {
if (rules.removeRule) {
rules.removeRule(i);
} else {
rules.deleteRule(i);
}
removedCount++;
}
} else if (rule.type === 4 || rule.type === 12) {
var nestedRules = rule.cssRules || rule.rules;
if (nestedRules) {
traverseAndRemove(nestedRules);
if (nestedRules.length === 0) {
if (rules.removeRule) {
rules.removeRule(i);
} else {
rules.deleteRule(i);
}
}
}
}
}
}
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
try {
var rules = sheets[i].cssRules || sheets[i].rules;
if (rules) traverseAndRemove(rules);
} catch (e) {
console.warn('无法操作跨域样式表:', e);
}
}
return removedCount;
}
var cssPool = {};
var strutil = Bridge.External.String;
var nstrutil = Bridge.NString;
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
function Toggle() {
this.element = null;
Object.defineProperty(this, "value", {
get: function() {
return this.getValue();
},
set: function(value) {
this.setValue(value);
}
});
Object.defineProperty(this, "checked", {
get: function() {
return this.getValue();
},
set: function(value) {
this.setValue(value);
}
});
Object.defineProperty(this, "disabled", {
get: function() {
return this.getDisabled();
},
set: function(value) {
this.setDisabled(value);
}
});
Object.defineProperty(this, "showlabel", {
get: function() {
return this.isShowStatus();
},
set: function(value) {
this.showStatus(value);
}
});
Object.defineProperty(this, "darkMode", {
get: function() {
return this.isDarkMode();
},
set: function(value) {
this.setDarkMode(value);
}
});
Object.defineProperty(this, "id", {
get: function() {
return this.getElementId();
},
set: function(value) {
this.setElementId(value);
}
});
Object.defineProperty(this, "inputId", {
get: function() {
return this.getElementInputElementId();
},
set: function(value) {
this.setElementInputElementId(value);
}
});
Object.defineProperty(this, "status", {
get: function() {
return this.getElementStatus();
}
});
Object.defineProperty(this, "parent", {
get: function() {
return this.getParent();
},
set: function(value) {
this.setParent(value);
}
});
}
Toggle.prototype.create = function() {
this.element = document.createElement("label");
this.element.tabIndex = 0;
this.element.classList.add("toggle-switch");
this.element.id = "toggle-switch" + (new Date()).getTime() + Math.floor(Math.random() * 1000);
var input = document.createElement("input");
input.type = "checkbox";
input.id = this.element.id + "-input";
this.element.addEventListener("keydown", function(event) {
if (event.keyCode == 13) {
input.click();
}
});
var back = document.createElement("div");
back.classList.add("toggle-background");
var border = document.createElement("div");
border.classList.add("toggle-switch-border");
this.element.appendChild(input);
this.element.appendChild(back);
this.element.appendChild(border);
var status = document.createElement("span");
status.classList.add("toggle-status");
this.element.appendChild(status);
status.style.display = "none";
this.element.objController = this;
return this.element;
}
Toggle.prototype.addEventListener = function(type, listener) {
this.element.addEventListener(type, listener);
}
Toggle.prototype.setParent = function(parent) {
if (parent == null) {
return;
}
var parentNode = null;
if (parent instanceof HTMLElement) {
parentNode = parent;
} else if (typeof parent === "string" || parent instanceof String) {
parentNode = document.getElementById(parent);
if (!parentNode) {
return;
}
} else {
console.error("Invalid parent type:", parent);
return;
}
if (!(this.element instanceof Node)) {
console.error("this.element is not a Node:", this.element);
return;
}
parentNode.appendChild(this.element);
}
Toggle.prototype.setValue = function(value) {
var input = this.element.getElementsByTagName("input")[0];
if (input === null) {
return;
}
parseBool = function(str) {
str = "" + str;
for (var i = 0; i < boolTrue.length; i++) {
if (nstrutil.equals(str, boolTrue[i])) {
return true;
}
}
for (var i = 0; i < boolFalse.length; i++) {
if (nstrutil.equals(str, boolFalse[i])) {
return false;
}
}
return null;
};
input.checked = parseBool(value);
}
Toggle.prototype.getValue = function() {
var input = this.element.getElementsByTagName("input")[0];
if (input === null) {
return false;
}
return input.checked;
}
Toggle.prototype.setDisabled = function(disabled) {
var input = this.element.querySelector("input");
if (input === null) {
return;
}
input.disabled = disabled;
}
Toggle.prototype.getDisabled = function() {
var input = this.element.querySelector("input");
if (input === null) {
return false;
}
return input.disabled;
}
Toggle.prototype.isAvailable = function() {
return this.element !== null;
}
Toggle.prototype.destroy = function() {
if (this.element !== null) {
if (this.element.remove) {
this.element.remove();
} else {
this.element.removeNode(true);
}
this.element = null;
}
}
Toggle.prototype.getElementId = function() {
if (this.element === null) {
return null;
}
return this.element.id;
}
Toggle.prototype.setElementId = function(elementId) {
if (this.element === null) {
return false;
}
this.element.id = elementId;
return true;
}
Toggle.prototype.getElement = function() {
return this.element;
}
Toggle.prototype.getElementInput = function() {
if (this.element === null) {
return null;
}
return this.element.getElementsByTagName("input")[0];
}
Toggle.prototype.getElementInputElementId = function() {
var input = this.getElementInput();
if (input === null) {
return null;
}
return input.id;
}
Toggle.prototype.setElementInputElementId = function(elementId) {
var input = this.getElementInput();
if (input === null) {
return false;
}
input.id = elementId;
return true;
}
Toggle.prototype.getElementStatus = function() {
if (this.element === null) {
return null;
}
return this.element.querySelector(".toggle-status");
}
Toggle.prototype.showStatus = function(show) {
var status = this.element.querySelector(".toggle-status");
if (status === null) {
return;
}
if (show) {
status.style.display = "";
if (this.element) {
if (this.element.classList.contains("toggle-showstatus")) {
return;
}
this.element.classList.add("toggle-showstatus");
}
} else {
status.style.display = "none";
if (this.element) {
if (!this.element.classList.contains("toggle-showstatus")) {
return;
}
this.element.classList.remove("toggle-showstatus");
}
}
}
Toggle.prototype.isShowStatus = function() {
return this.element.classList.contains("toggle-showstatus");
}
Toggle.prototype.setDarkMode = function(isDark) {
if (this.element === null) {
return;
}
var element = this.element;
var background = element.querySelector(".toggle-background");
var border = element.querySelector(".toggle-switch-border");
var status = element.querySelector(".toggle-status");
if (isDark) {
element.classList.add("toggle-switch-dark");
background.classList.add("toggle-background-dark");
border.classList.add("toggle-switch-border-dark");
status.classList.add("toggle-status-dark");
} else {
element.classList.remove("toggle-dark");
background.classList.remove("toggle-background-dark");
border.classList.remove("toggle-switch-border-dark");
status.classList.remove("toggle-status-dark");
}
}
Toggle.prototype.isDarkMode = function() {
if (this.element === null) {
return false;
}
return this.element.classList.contains("toggle-switch-dark");
}
function ColorStringToRGBA(input) {
var str = input.replace(/\s+/g, '').toLowerCase();
function hexToRgba(hex) {
hex = hex.slice(1);
if (hex.length === 3 || hex.length === 4) {
hex = hex.split('').map(function(c) { return c + c; }).join('');
}
var r = parseInt(hex.substr(0, 2), 16);
var g = parseInt(hex.substr(2, 2), 16);
var b = parseInt(hex.substr(4, 2), 16);
var a = hex.length === 8 ? parseInt(hex.substr(6, 2), 16) / 255 : 1;
return { r: r, g: g, b: b, a: a };
}
function hslToRgb(h, s, l) {
h = (h % 360 + 360) % 360 / 360;
s = Math.max(0, Math.min(1, s));
l = Math.max(0, Math.min(1, l));
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
var m1 = 2 * l - m2;
function hueToRgb(m1, m2, hK) {
if (hK < 0) hK += 1;
if (hK > 1) hK -= 1;
if (hK * 6 < 1) return m1 + (m2 - m1) * 6 * hK;
if (hK * 2 < 1) return m2;
if (hK * 3 < 2) return m1 + (m2 - m1) * (2 / 3 - hK) * 6;
return m1;
}
return {
r: Math.round(hueToRgb(m1, m2, h + 1 / 3) * 255),
g: Math.round(hueToRgb(m1, m2, h) * 255),
b: Math.round(hueToRgb(m1, m2, h - 1 / 3) * 255),
a: 1
};
}
function parseFunc(func, vals) {
var arr = vals.split(',');
if (/^hsl/.test(func)) {
var h = parseFloat(arr[0]);
var s = parseFloat(arr[1]) / 100;
var l = parseFloat(arr[2]) / 100;
var alpha = arr[3] !== undefined ? (arr[3].indexOf('%') > -1 ? parseFloat(arr[3]) / 100 : parseFloat(arr[3])) : 1;
var rgb = hslToRgb(h, s, l);
rgb.a = alpha;
return rgb;
}
var out = arr.slice(0, 3).map(function(v, i) {
if (v.indexOf('%') > -1) return Math.round(parseFloat(v) / 100 * 255);
return Math.round(parseFloat(v));
});
return {
r: out[0],
g: out[1],
b: out[2],
a: arr[3] !== undefined ? (arr[3].indexOf('%') > -1 ? parseFloat(arr[3]) / 100 : parseFloat(arr[3])) : 1
};
}
function hwbToRgb(h, w, b, a) {
var rgb = hslToRgb(h, 1, 0.5);
w = Math.max(0, Math.min(1, w));
b = Math.max(0, Math.min(1, b));
var sum = w + b;
if (sum > 1) {
var gray = w / sum;
return { r: Math.round(gray * 255), g: Math.round(gray * 255), b: Math.round(gray * 255), a: a };
}
var factor = 1 - w - b;
return {
r: Math.round((rgb.r / 255 * factor + w) * 255),
g: Math.round((rgb.g / 255 * factor + w) * 255),
b: Math.round((rgb.b / 255 * factor + w) * 255),
a: a
};
}
function parseRGBString(rgbString) {
var m = /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d*\.?\d+))?\)/.exec(rgbString);
if (m) {
return { r: +m[1], g: +m[2], b: +m[3], a: m[4] !== undefined ? +m[4] : 1 };
}
return { r: 0, g: 0, b: 0, a: 0 };
}
var m;
if ((m = /^#([0-9a-f]{3,8})$/.exec(str))) {
return hexToRgba(m[0]);
}
if ((m = /^(rgba?|hsla?)\((.+)\)$/.exec(str))) {
return parseFunc(m[1], m[2]);
}
if ((m = /^(hwb)a?\((.+)\)$/.exec(str))) {
var parts = m[2].split(',');
var h = parseFloat(parts[0]);
var w0 = parseFloat(parts[1]) / 100;
var b0 = parseFloat(parts[2]) / 100;
var a0 = parts[3] !== undefined ? (parts[3].indexOf('%') > -1 ? parseFloat(parts[3]) / 100 : parseFloat(parts[3])) : 1;
return hwbToRgb(h, w0, b0, a0);
}
try {
var div = document.createElement('div');
div.style.color = input;
document.body.appendChild(div);
var css = window.getComputedStyle(div).color;
document.body.removeChild(div);
return parseRGBString(css);
} catch (e) {
return { r: 0, g: 0, b: 0, a: 0 };
}
return { r: 0, g: 0, b: 0, a: 0 };
}
function ColorRGBToString(color) {
return "#" + ((1 << 24) + (color.r << 16) + (color.g << 8) + color.b).toString(16).slice(1);
}
function ColorRGBToHex(color) {
return "" + ((1 << 24) + (color.r << 16) + (color.g << 8) + color.b).toString(16).slice(1);
}
function CalcLightHoverColor(_obj_rgb_) {
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0;
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [h * 360, s * 100, l * 100];
}
function hslToRgb(h, s, l) {
h = (h % 360) / 360;
s /= 100;
l /= 100;
var r, g, b;
if (s == 0) {
r = g = b = l;
} else {
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [
Math.round(r * 255),
Math.round(g * 255),
Math.round(b * 255)
];
}
var hsl = rgbToHsl(_obj_rgb_.r, _obj_rgb_.g, _obj_rgb_.b);
hsl[2] = Math.min(98, hsl[2] + 12);
var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
return {
r: rgb[0],
g: rgb[1],
b: rgb[2]
};
}
function CalcLightActiveColor(_obj_rgb_) {
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [h * 360, s * 100, l * 100];
}
function hslToRgb(h, s, l) {
h = (h % 360) / 360;
s /= 100;
l /= 100;
var r, g, b;
if (s === 0) {
r = g = b = l;
} else {
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [
Math.round(r * 255),
Math.round(g * 255),
Math.round(b * 255)
];
}
var hsl = rgbToHsl(_obj_rgb_.r, _obj_rgb_.g, _obj_rgb_.b);
hsl[2] = hsl[2] < 50 ?
hsl[2] * 1.6 :
hsl[2] + (100 - hsl[2]) * 0.3;
hsl[1] = hsl[1] < 80 ?
hsl[1] * 1.3 :
Math.min(100, hsl[1] + 15);
hsl[2] = Math.min(95, Math.max(5, hsl[2]));
hsl[1] = Math.min(100, Math.max(0, hsl[1]));
var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
return { r: rgb[0], g: rgb[1], b: rgb[2] };
}
function GetLightCSSString(_string_selector_, _obj_rgb_) {
var hover = CalcLightHoverColor(_obj_rgb_);
var active = CalcLightActiveColor(_obj_rgb_);
var background = _string_selector_ + "-background";
var css = "";
css += "." + background + ":before" + " {" +
"background-color: " + ColorRGBToString(_obj_rgb_) + ";" +
"}\n";
css += ".toggle-switch:hover>input:checked:not(:disabled)+." + background + ":before {" +
"background-color: " + ColorRGBToString(hover) + ";" +
"}\n";
css += ".toggle-switch:active>input:checked:not(:disabled)+." + background + ":before {" +
"background-color: " + ColorRGBToString(active) + ";" +
"}\n";
return css;
}
function GetDarkCSSString(_string_selector_, _obj_rgb_) {
function rgbToHsl(r, g, b) {
r /= 255;
g /= 255;
b /= 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b),
h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = ((g - b) / d + (g < b ? 6 : 0));
break;
case g:
h = ((b - r) / d + 2);
break;
case b:
h = ((r - g) / d + 4);
break;
}
h /= 6;
}
return { h: h * 360, s: s * 100, l: l * 100 };
}
function hslToRgb(h, s, l) {
s /= 100;
l /= 100;
h /= 360;
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var r, g, b;
if (!s) {
r = g = b = l;
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };
}
function clamp(v, min, max) {
return v < min ? min : (v > max ? max : v);
}
function ColorRGBToString(c) {
return "rgb(" + c.r + ", " + c.g + ", " + c.b + ")";
}
var hsl = rgbToHsl(_obj_rgb_.r, _obj_rgb_.g, _obj_rgb_.b);
var borderRGB = hslToRgb(hsl.h, hsl.s, clamp(hsl.l + 15, 0, 100));
var backgroundRGB = hslToRgb(hsl.h, clamp(hsl.s * 0.9, 0, 100), clamp(hsl.l + 12, 0, 100));
var disabledBgRGB = hslToRgb(hsl.h, clamp(hsl.s * 0.6, 0, 100), clamp(hsl.l + 5, 0, 100));
var disabledBrdRGB = hslToRgb(hsl.h, hsl.s, clamp(hsl.l + 5, 0, 100));
var hoverBgRGB = hslToRgb(hsl.h, clamp(hsl.s * 0.8, 0, 100), clamp(hsl.l + 25, 0, 100));
var activeBgRGB = hslToRgb(hsl.h, clamp(hsl.s * 1.1, 0, 100), clamp(hsl.l + 35, 0, 100));
var hoverChecked = CalcLightHoverColor(_obj_rgb_);
var activeChecked = CalcLightActiveColor(_obj_rgb_);
var base = _string_selector_;
var bgClass = base + "-background";
var brClass = base + "-border";
var css = "";
css += "." + base + " { border-color: " + ColorRGBToString(borderRGB) + "; }\n";
css += "." + bgClass + " { background-color: " + ColorRGBToString(backgroundRGB) + "; }\n";
css += "." + base + ">input[type=\"checkbox\"]:disabled:not(:checked)+." + bgClass +
" { background-color: " + ColorRGBToString(disabledBgRGB) + "; }\n";
css += "." + base + ">input[type=\"checkbox\"]:disabled~." + brClass + "," +
"." + base + ">input[type=\"checkbox\"]:disabled~." + base + "-switch" +
" { border-color: " + ColorRGBToString(disabledBrdRGB) + "; }\n";
css += "." + base + ":hover>input[type=\"checkbox\"]:not(:disabled):not(:checked)+." + bgClass +
" { background-color: " + ColorRGBToString(hoverBgRGB) + "; }\n";
css += "." + base + ":active>input[type=\"checkbox\"]:not(:disabled):not(:checked)+." + bgClass +
" { background-color: " + ColorRGBToString(activeBgRGB) + "; }\n";
css += "." + brClass + " { border-color:" + ColorRGBToString(borderRGB) + "; }\n";
css += "." + base + ">input:disabled+." + base + "-background:after" +
" { background-color: " + ColorRGBToString(borderRGB) + "; }\n";
css += "." + bgClass + ":before { background-color: " + ColorRGBToString(_obj_rgb_) + "; }\n";
css += "." + base + ":hover>input:checked:not(:disabled)+." + bgClass + ":before" +
" { background-color: " + ColorRGBToString(hoverChecked) + "; }\n";
css += "." + base + ":active>input:checked:not(:disabled)+." + bgClass + ":before" +
" { background-color: " + ColorRGBToString(activeChecked) + "; }\n";
return css;
}
Toggle.prototype.setDarkMode = function(dark) {
var element = this.element;
if (this.isDarkMode === dark) {
return;
}
var background = element.querySelector(".toggle-background");
var border = element.querySelector(".toggle-switch-border");
var status = element.querySelector(".toggle-status");
if (this.color) {
var label = ColorRGBToHex(this.color);
var uniid = "toggle-theme-" + label;
var uniidlight = uniid + "-light";
var uniiddark = uniid + "-dark";
}
if (this.element === null) {
return;
}
if (dark) {
element.classList.add("toggle-switch-dark");
background.classList.add("toggle-background-dark");
border.classList.add("toggle-switch-border-dark");
status.classList.add("toggle-status-dark");
if (this.color) {
element.classList.add(uniiddark);
background.classList.add(uniiddark + "-background");
border.classList.add(uniiddark + "-border");
element.classList.remove(uniidlight);
background.classList.remove(uniidlight + "-background");
border.classList.remove(uniidlight + "-border");
}
} else {
element.classList.remove("toggle-dark");
background.classList.remove("toggle-background-dark");
border.classList.remove("toggle-switch-border-dark");
status.classList.remove("toggle-status-dark");
if (this.color) {
element.classList.remove(uniiddark);
background.classList.remove(uniiddark + "-background");
border.classList.remove(uniiddark + "-border");
element.classList.add(uniidlight);
background.classList.add(uniidlight + "-background");
border.classList.add(uniidlight + "-border");
}
}
}
Toggle.prototype.setColor = function(color) {
var rgb = ColorStringToRGBA(color);
this.color = rgb;
var label = ColorRGBToHex(rgb);
var uniid = "toggle-theme-" + label;
var uniidlight = uniid + "-light";
var uniiddark = uniid + "-dark";
if (cssPool[uniid] === undefined || cssPool[uniid] === null) {
cssPool[uniid] = {
light: uniidlight,
dark: uniiddark,
count: 1,
}
var lightCSS = GetLightCSSString(uniidlight, rgb);
var darkCSS = GetDarkCSSString(uniiddark, rgb);
var style = document.createElement("style");
style.type = "text/css";
style.id = uniid;
style.innerHTML = "/* Light Theme */\n" + lightCSS + "\n/* Dark Theme */\n" + darkCSS;
document.head.appendChild(style);
cssPool[uniid].style = style;
} else {
cssPool[uniid].count++;
}
var dark = this.isDarkMode();
this.setDarkMode(!dark);
this.setDarkMode(dark);
}
Toggle.prototype.dispose = function() {
if (this.element) {
removeElement(this.element);
this.element = null;
}
if (this.color) {
var label = ColorRGBToHex(this.color);
var uniid = "toggle-theme-" + label;
var ucss = cssPool[uniid];
if (ucss) {
ucss.count--;
if (ucss.count <= 0) {
removeElement(ucss.style);
delete cssPool[uniid];
}
}
this.color = null;
}
};
Toggle.prototype.destroy = Toggle.prototype.dispose;
Toggle.prototype.setStatusText = function(onText, offText) {
/**
* 动态插入一段 CSS 文本到页面 <head> 中
* @param {string} cssText - 要插入的完整 CSS 文本,如 "body{background:red;}"
* @param {string} [id] - 可选,为 <style> 元素指定 id方便后面删除
*/
function addCssText(cssText, id) {
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
if (id) style.id = id;
style.type = 'text/css';
// 对 IE8- 兼容style.styleSheet.cssText其他浏览器用 textNode
if (style.styleSheet) {
style.styleSheet.cssText = cssText; // :contentReference[oaicite:0]{index=0}
} else {
style.appendChild(document.createTextNode(cssText));
}
head.appendChild(style);
}
/**
* 根据 id 移除之前插入的 <style> 标签
* @param {string} id - addCssText 时指定的 id
*/
function removeCssById(id) {
var style = document.getElementById(id);
if (style && style.parentNode) {
style.parentNode.removeChild(style);
}
}
removeCssById("toggle-status-lang");
var status = this.element.querySelector(".toggle-status");
var csstext = ".toggle-status-lang:before { content: \"" + offText + "\"; }\n";
csstext += "label.toggle-status-lang:has(input:checked)::before { content: \"" + onText + "\"; }\n";
csstext += ".toggle-switch>input:checked~.toggle-status-lang::before { content: \"" + onText + "\"; }\n";
addCssText(csstext, "toggle-status-lang");
status.classList.add("toggle-status-lang");
}
global.Toggle = Toggle;
})(this);

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html>
<head>
<title>App Installer Settings</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">
<script type="text/javascript" src="../../js/module.js"></script>
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../../js/color.js"></script>
<script type="text/javascript" src="../../js/promise.js"></script>
<script type="text/javascript" src="../../js/bridge.js"></script>
<script type="text/javascript" src="../../js/dpimodes.js"></script>
<script type="text/javascript" src="../../js/resources.js"></script>
<script type="text/javascript" src="../../js/animation.js"></script>
<link rel="stylesheet" href="../../fonts/fonts.css">
<script type="text/javascript" src="../../js/event.js"></script>
<script type="text/javascript" src="../../js/tileback.js"></script>
<script type="text/javascript" src="../../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("about");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection">
<div class="section padding">
<h2 data-res-fromfile="publicRes(124)"></h2>
<p data-res-fromfile="getFileResPair(exepath, 300)"></p>
<p style="white-space: pre-wrap;"><span data-res-fromfile="publicRes (130)"></span>&#9;<span id="current-version"></span></p>
<script>
try {
var storage = Bridge.External.Storage;
var path = storage.path;
var versionFilePath = path.combine(path.root, "version");
var versionFile = storage.getFile(versionFilePath);
window.currver = versionFile.content;
} catch (e) {
window.currver = "0.0.0.1";
}
document.getElementById("current-version").textContent = window.currver;
</script>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,166 @@
<!DOCTYPE html>
<html>
<head>
<title>App Installer Settings</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">
<script type="text/javascript" src="../../js/module.js"></script>
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../../js/color.js"></script>
<script type="text/javascript" src="../../js/promise.js"></script>
<script type="text/javascript" src="../../js/bridge.js"></script>
<script type="text/javascript" src="../../js/dpimodes.js"></script>
<script type="text/javascript" src="../../js/resources.js"></script>
<script type="text/javascript" src="../../js/animation.js"></script>
<link rel="stylesheet" href="../../fonts/fonts.css">
<script type="text/javascript" src="../../js/event.js"></script>
<script type="text/javascript" src="../../js/tileback.js"></script>
<script type="text/javascript" src="../../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("general");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection">
<div class="section padding">
<h2 id="page-title" data-res-fromfile="publicRes (101)"></h2>
<div class="win-settings-section">
<br>
<label class="win-label" for="save-wnd-size" id="save-wnd-size-label" data-res-fromfile="publicRes (125)"></label>
<script>
(function() {
"use strict";
var label = document.getElementById("save-wnd-size-label");
var toggle = new Toggle();
toggle.create();
toggle.parent = label.parentNode;
toggle.showlabel = true;
var winjsres = Bridge.External.WinJsStringRes;
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
toggle.inputId = "save-wnd-size";
var ini = Bridge.External.Config.GetConfig();
toggle.addEventListener("change", function() {
ini.set("Settings", "AppInstaller:SavePosAndSizeBeforeCancel", toggle.checked);
});
toggle.checked = parseBool(ini.getSection("Settings").getKey("AppInstaller:SavePosAndSizeBeforeCancel").value);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="default-wndwidth" data-res-fromfile="publicRes(126)"></label><br>
<input type="number" id="default-wndwidth" inputmode="numeric"><br><br>
<label class="win-label" for="default-wndheight" data-res-fromfile="publicRes(127)"></label><br>
<input type="number" id="default-wndheight" inputmode="numeric">
<script>
(function() {
"use strict";
var ini = Bridge.External.Config.GetConfig();
var defWndWInput = document.getElementById("default-wndwidth");
var defWndHInput = document.getElementById("default-wndheight");
var setsect = ini.getSection("Settings");
var defwk = setsect.getKey("AppInstaller:DefaultWidth");
var defhk = setsect.getKey("AppInstaller:DefaultHeight");
defWndWInput.value = defwk.value;
defWndHInput.value = defhk.value;
var eventutil = Windows.UI.Event.Util;
function inputDefaultWidthChangeEvent(e) {
defwk.value = parseInt(defWndWInput.value);
}
function inputDefaultHeightChangeEvent(e) {
defhk.value = parseInt(defWndHInput.value);
}
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
eventutil.addEvent(defWndWInput, "input", debounced_idwc);
eventutil.addEvent(defWndWInput, "propertychange", debounced_idwc);
eventutil.addEvent(defWndWInput, "change", debounced_idwc);
eventutil.addEvent(defWndHInput, "input", debounced_idhc);
eventutil.addEvent(defWndHInput, "propertychange", debounced_idhc);
eventutil.addEvent(defWndHInput, "change", debounced_idhc);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="min-wndwidth" data-res-fromfile="publicRes (128)"></label><br>
<input type="number" id="min-wndwidth" inputmode="numeric"><br><br>
<label class="win-label" for="min-wndheight" data-res-fromfile="publicRes (129)"></label><br>
<input type="number" id="min-wndheight" inputmode="numeric">
<script>
(function() {
"use strict";
var ini = Bridge.External.Config.GetConfig();
var minWndWInput = document.getElementById("min-wndwidth");
var minWndHInput = document.getElementById("min-wndheight");
var setsect = ini.getSection("Settings");
var minwk = setsect.getKey("AppInstaller:MinimumWidth");
var minhk = setsect.getKey("AppInstaller:MinimumHeight");
minWndWInput.value = minwk.value;
minWndHInput.value = minhk.value;
var eventutil = Windows.UI.Event.Util;
function inputDefaultWidthChangeEvent(e) {
minwk.value = parseInt(minWndWInput.value);
}
function inputDefaultHeightChangeEvent(e) {
minhk.value = parseInt(minWndHInput.value);
}
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
eventutil.addEvent(minWndWInput, "input", debounced_idwc);
eventutil.addEvent(minWndWInput, "propertychange", debounced_idwc);
eventutil.addEvent(minWndWInput, "change", debounced_idwc);
eventutil.addEvent(minWndHInput, "input", debounced_idhc);
eventutil.addEvent(minWndHInput, "propertychange", debounced_idhc);
eventutil.addEvent(minWndHInput, "change", debounced_idhc);
})();
</script>
</div>
<div class="win-settings-section">
<br>
<label class="win-label" for="launch-when-ready" id="launch-when-ready-label" data-res-fromfile="getFileResPair(exepath, 330)"></label>
<script>
(function() {
"use strict";
var label = document.getElementById("launch-when-ready-label");
var toggle = new Toggle();
toggle.create();
toggle.parent = label.parentNode;
toggle.showlabel = true;
var winjsres = Bridge.External.WinJsStringRes;
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
toggle.inputId = "launch-when-ready";
var ini = Bridge.External.Config.GetConfig();
toggle.addEventListener("change", function() {
ini.set("Settings", "AppInstaller:LaunchWhenReady", toggle.checked);
});
toggle.checked = parseBool(ini.getSection("Settings").getKey("AppInstaller:LaunchWhenReady").value);
})();
</script>
</div>
</div>
</div>
</body>
</html>

View File

@@ -28,6 +28,11 @@
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("guide");
} catch (e) {}
</script>
</head>
<body>

View File

@@ -12,6 +12,8 @@
}, 50);
var content = guide.querySelector(".main");
var list = slide.querySelector("ul");
var backbtn = slide.querySelector("#back");
var title = slide.querySelector("#apptitle");
list.innerHTML = "";
var items = pages;
var tags = Object.keys(items);
@@ -21,8 +23,10 @@
var item = items[tag];
var li = document.createElement("li");
li.setAttribute("data-page", item.page);
li.setAttribute("data-tag", item.tag);
li.innerHTML = item.title;
eventutil.addEvent(li, "click", function() {
if (li.hasAttribute("data-require-disabled")) return;
content.style.display = "none";
for (var j = 0; j < list.children.length; j++) {
var child = list.children[j];
@@ -32,13 +36,42 @@
content.src = this.getAttribute("data-page");
setTimeout(function() {
content.style.display = "";
Windows.UI.Animation.runAsync(content, Windows.UI.Animation.Keyframes.SlideInFromBottom);
Windows.UI.Animation.runAsync(content, [Windows.UI.Animation.Keyframes.Flyout.toLeft, Windows.UI.Animation.Keyframes.Opacity.visible]);
}, 0);
this.classList.add("selected");
});
list.appendChild(li);
}
content.src = guidePage.page;
global.setDisabledForOperation = function(disabled) {
var list = document.querySelector("#settingpage .guide aside ul");
for (var i = 0; i < list.children.length; i++) {
var child = list.children[i];
if (disabled) {
child.setAttribute("data-require-disabled", "true");
} else {
child.removeAttribute("data-require-disabled");
}
}
if (disabled) {
backbtn.disabled = true;
title.style.marginLeft = backbtn.style.marginLeft;
} else {
backbtn.disabled = false;
title.style.marginLeft = "";
}
}
global.setItemHighlight = function(tag) {
var list = document.querySelector("#settingpage .guide aside ul");
for (var i = 0; i < list.children.length; i++) {
var child = list.children[i];
if (Bridge.NString.equals(child.getAttribute("data-tag"), tag)) {
if (!child.classList.contains("selected")) child.classList.add("selected");
} else {
if (child.classList.contains("selected")) child.classList.remove("selected");
}
}
}
}
OnLoad.add(ready);
})(this);

View File

@@ -1,16 +1,18 @@
(function(global) {
"use strict";
function getPage(page, display) {
function getPage(tag, page, display) {
return {
tag: tag,
page: page,
title: display
};
}
var pages = {
general: getPage("appinstaller/general.html", getPublicRes(101)),
theme: getPage("appinstaller/theme.html", getPublicRes(102)),
update: getPage("update.html", getPublicRes(103))
general: getPage("general", "appinstaller/general.html", getPublicRes(101)),
theme: getPage("theme", "appinstaller/theme.html", getPublicRes(102)),
update: getPage("update", "update.html", getPublicRes(103)),
about: getPage("about", "appinstaller/about.html", getPublicRes(124))
};
Object.defineProperty(global, "pages", {
get: function() {
@@ -19,7 +21,7 @@
});
Object.defineProperty(global, "guidePage", {
get: function() {
return getPage("appinstaller/guide.html", "Guide");
return getPage("guide", "appinstaller/guide.html", "Guide");
}
});
})(this);

View File

@@ -9,4 +9,22 @@
global.slideback = slideback;
global.exepath = exepath;
global.visual = ve;
var strutil = Bridge.External.String;
var nstrutil = Bridge.NString;
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
global.parseBool = function(str) {
str = "" + str;
for (var i = 0; i < boolTrue.length; i++) {
if (nstrutil.equals(str, boolTrue[i])) {
return true;
}
}
for (var i = 0; i < boolFalse.length; i++) {
if (nstrutil.equals(str, boolFalse[i])) {
return false;
}
}
return null;
};
})(this);

View File

@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<title>App Installer Settings</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">
<script type="text/javascript" src="../../js/module.js"></script>
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
<script type="text/javascript" src="../../js/color.js"></script>
<script type="text/javascript" src="../../js/promise.js"></script>
<script type="text/javascript" src="../../js/bridge.js"></script>
<script type="text/javascript" src="../../js/dpimodes.js"></script>
<script type="text/javascript" src="../../js/resources.js"></script>
<script type="text/javascript" src="../../js/animation.js"></script>
<link rel="stylesheet" href="../../fonts/fonts.css">
<script type="text/javascript" src="../../js/event.js"></script>
<script type="text/javascript" src="../../js/tileback.js"></script>
<script type="text/javascript" src="../../js/load.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<script>
try {
window.parent.setItemHighlight("theme");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection">
<div class="section padding">
<h2 id="page-title" data-res-fromfile="publicRes (102)"></h2>
<div class="win-settings-section">
<br>
<label>主题模式</label><br>
<select>
<option>深色</option>
<option>浅色</option>
<option>自动变换</option>
<option>自定义</option>
</select>
<br>
</div>
<div class="win-settings-section">
<br>
<label>自动变换选项</label><br>
<select>
<option>跟随系统</option>
<option>设置变换时间</option>
</select><br>
<div class="win-settings-section" id="item-automode">
<p>设置变换时间</p>
<div class="win-settings-row">
<div class="win-settings-label" style="font-weight: normal;">白天</div>
<div class="win-settings-control">
<div data-win-control="WinJS.UI.TimePicker" data-win-options="{ hour: 9, minute: 0, clock: '24HourClock' }">
</div>
</div>
</div>
<div class="win-settings-row">
<div class="win-settings-label" style="font-weight: normal;">夜晚</div>
<div class="win-settings-control">
<div data-win-control="WinJS.UI.TimePicker" data-win-options="{ hour: 18, minute: 0, clock: '24HourClock' }">
</div>
</div>
</div>
</div>
</div>
<div class="win-settings-section" id="item-theme">
<br>
<label>主题模式</label><br>
<script>
(function() {
var sect = document.getElementById("item-theme");
var toggle = new Toggle();
toggle.create();
toggle.parent = sect;
toggle.setColor("#202020");
toggle.showlabel = true;
toggle.setStatusText("深色", "浅色");
})();
</script>
<br>
<label>选择主题</label>
<div id="theme-items-select" data-win-control="WinJS.UI.ListView"></div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -46,7 +46,7 @@
}, 50);
setTimeout(function() {
content.style.display = "";
Windows.UI.Animation.runAsync(content, Windows.UI.Animation.Keyframes.SlideInFromBottom);
Windows.UI.Animation.runAsync(content, [Windows.UI.Animation.Keyframes.Flyout.toLeft, Windows.UI.Animation.Keyframes.Opacity.visible]);
}, 100);
}
OnLoad.add(ready);

View File

@@ -179,6 +179,12 @@ aside .container ul li:focus {
border: 1px solid white;
}
aside .container ul li:disabled,
aside .container ul li[data-require-disabled] {
background-color: rgba(0, 0, 0, 0);
color: rgba(0, 0, 0, 0.5);
}
#back:disabled {
display: none;
}

View File

@@ -33,14 +33,12 @@
.section .block {
width: 100%;
height: auto;
margin-top: 10px;
margin-bottom: 10px;
box-sizing: border-box;
position: relative;
transition: all 0.5s cubic-bezier(0.1, 0.9, 0.2, 1);
overflow-x: hidden;
overflow-y: hidden;
background-color: blanchedalmond;
/* background-color: blanchedalmond; */
}
.pagesection .section {
@@ -174,16 +172,86 @@
);
});
};
var process = Bridge.External.Process;
global.createProcessAsync = function(cmdline, filepath, wndshow, runpath) {
return new WinJS.Promise(function(resolve, reject) {
var callback = resolve || reject;
process.runAsync(cmdline, filepath, wndshow, runpath, callback);
});
};
global.createProcess = function(cmdline, filepath, wndshow, wait, runpath) {
return process.run(cmdline, filepath, wndshow, wait, runpath);
};
global.wndDisplayMode = {
hide: 0, // SW_HIDE
showNormal: 1, // SW_SHOWNORMAL / SW_NORMAL
showMinimized: 2, // SW_SHOWMINIMIZED
showMaximized: 3, // SW_SHOWMAXIMIZED
showNoActivate: 4, // SW_SHOWNOACTIVATE
show: 5, // SW_SHOW
minimize: 6, // SW_MINIMIZE
showMinNoActivate: 7, // SW_SHOWMINNOACTIVE
showNA: 8, // SW_SHOWNA
restore: 9, // SW_RESTORE
showDefault: 10, // SW_SHOWDEFAULT
forceMinimize: 11 // SW_FORCEMINIMIZE
};
})(this);
</script>
<script>
function formatBytesSize(bytes) {
if (isNaN(bytes) || bytes < 0) return "0 B";
var units = ["B", "KB", "MB", "GB", "TB", "PB"];
var i = 0;
var num = bytes;
while (num >= 1024 && i < units.length - 1) {
num = num / 1024;
i++;
}
// 保留 2 位小数,整数不显示小数
if (num >= 100) num = Math.round(num);
else if (num >= 10) num = Math.round(num * 10) / 10;
else num = Math.round(num * 100) / 100;
return num + " " + units[i];
}
function formatBytesTransmissionSpeed(bps) {
if (isNaN(bps) || bps < 0) return "0 B/s";
var units = ["B/s", "KB/s", "MB/s", "GB/s", "TB/s"];
var i = 0;
var num = bps;
while (num >= 1024 && i < units.length - 1) {
num = num / 1024;
i++;
}
if (num >= 100) num = Math.round(num);
else if (num >= 10) num = Math.round(num * 10) / 10;
else num = Math.round(num * 100) / 100;
return num + " " + units[i];
}
</script>
<script>
try {
window.parent.setItemHighlight("update");
} catch (e) {}
</script>
</head>
<body>
<div class="pagecontainer full pagesection" style="overflow-y: auto;">
<div class="section padding">
<h2 id="section-title" data-res-fromfile="publicRes (103)"></h2>
<p id="section-desc" style="white-space: pre-wrap;">在这里,检查一下应用的更新。</p>
<p><span data-res-fromfile="publicRes (104)"></span>&#9;<span id="current-version"></span></p>
<p id="section-desc" style="white-space: pre-wrap;" data-res-fromfile="publicRes (105)"></p>
<p style="white-space: pre-wrap;"><span data-res-fromfile="publicRes (104)"></span>&#9;<span id="current-version"></span></p>
<script>
try {
var storage = Bridge.External.Storage;
@@ -199,19 +267,20 @@
</div>
<div class="section padding" style="">
<div class="block" id="check-update-block" style="height: 0px;">
<span id="loading-amine">123</span><span id="check-update-text">正在检查更新...</span><br>
<span id="loading-amine">123</span><span id="check-update-text" data-res-fromfile="publicRes (106)"></span><br>
<progress id="progress" min="0" max="100"></progress>
<a target="_blank" id="doc-link">查看文档</a>
<a target="_blank" id="doc-link" data-res-fromfile="publicRes (107)"></a>
</div>
</div>
<div class="section padding" style="margin: 10px 0;"><button id="check-update" data-action="check">检查更新</button></div>
<div class="section padding" style="margin: 10px 0;"><button id="check-update" data-action="check" data-res-fromfile="publicRes (115)"></button></div>
<div class="section padding" style="display: none; overflow-y: auto; height: 0px; transition: all 0.5s cubic-bezier(0.1, 0.9, 0.2, 1); margin-top: 20px;">
<h2>获取到的更新信息</h2>
<h2 data-res-fromfile="publicRes (108)"></h2>
<div class="block" id="newversion-details">
<h3 id="newversion-title"><span>最新版本</span>: <span id="newversion-version"></span></h3>
<h3 id="newversion-title"><span data-res-fromfile="publicRes (109)"></span>: <span id="newversion-version"></span></h3>
<span id="newversion-releasedate"></span><br>
<a id="newversion-url" target="_blank">查看链接</a><br>
<span>发布说明: </span><a id="newversion-desc-showall-hide">展开</a>
<a id="newversion-url" target="_blank" data-res-fromfile="publicRes (110)"></a><br>
<span data-res-fromfile="publicRes (111)"></span>:
<a id="newversion-desc-showall-hide" data-res-fromfile="publicRes (122)"></a>
<div id="newversion-desc"></div>
</div>
</div>
@@ -255,11 +324,11 @@
var parentSection = newVersionBlock.parentNode;
if (parentSection.hasAttribute("data-showall") == true) {
parentSection.removeAttribute("data-showall");
newVersionDescShowOrHide.textContent = "展开";
newVersionDescShowOrHide.textContent = getPublicRes(122);
parentSection.style.height = parentSection.getAttribute("data-height") + "px";
} else {
parentSection.setAttribute("data-showall", true);
newVersionDescShowOrHide.textContent = "收起";
newVersionDescShowOrHide.textContent = getPublicRes(123);
parentSection.style.height = "auto";
}
debunced_resize();
@@ -270,8 +339,9 @@
var self = this;
this.disabled = true;
progress.removeAttribute("value");
window.parent.setDisabledForOperation(true);
if (checkUpdateBtn.getAttribute("data-action") == "check") {
checkUpdateText.textContent = "正在检查更新...";
checkUpdateText.textContent = getPublicRes(106);
checkUpdateBlock.style.height = checkUpdateBlock.scrollHeight + "px";
progress.style.display = "";
docLink.style.display = "none";
@@ -285,17 +355,17 @@
WinJS.xhr({
url: "https://api.github.com/repos/modernw/App-Installer-For-Windows-8.x-Reset/releases/latest"
}).done(function(resp) {
console.log("success", resp);
// console.log("success", resp);
var json = JSON.parse(resp.responseText);
console.log(json);
// console.log(json);
self.disabled = false;
newVersionVersion.textContent = json.name;
newVersionVersion.setAttribute("data-version", json.tag_name);
window.newver = json.tag_name;
newVersionReleaseDate.textContent = "发布日期: " + json.published_at;
newVersionReleaseDate.textContent = getPublicRes(112) + ": " + json.published_at;
newVersionUrl.href = json.html_url;
newVersionDesc.innerHTML = markdown.toHTML(json.body);
checkUpdateText.textContent = "检查更新完成";
checkUpdateText.textContent = getPublicRes(113);
progress.style.display = "none";
newVersionBlock.parentNode.style.display = "";
stopProcess = false;
@@ -303,63 +373,86 @@
for (var i = 0; i < json.assets.length; i++) {
if (json.assets[i].browser_download_url.indexOf("/InstallerSetup.exe") > -1) {
window.downloadUrl = json.assets[i].browser_download_url;
window.fileDigest = json.assets[i].digest;
break;
}
}
if (compareVersion(window.currver, window.newver) > 0) {
checkUpdateText.textContent = "当前已是最新版本";
checkUpdateBtn.textContent = "检查更新";
if (compareVersion(window.currver, window.newver) >= 0) {
checkUpdateText.textContent = getPublicRes(114);
checkUpdateBtn.textContent = getPublicRes(115);
checkUpdateBtn.setAttribute("data-action", "check");
} else {
checkUpdateText.textContent = "有新版本可用: " + window.newver;
checkUpdateBtn.textContent = "下载更新";
checkUpdateText.textContent = Bridge.String.format(getPublicRes(116), window.newver);
checkUpdateBtn.textContent = getPublicRes(118);
checkUpdateBtn.setAttribute("data-action", "download");
}
window.parent.setDisabledForOperation(false);
}, function(error) {
console.log("error", error);
// console.log("error", error);
var json = JSON.parse(error.responseText);
checkUpdateText.textContent = json.message;
progress.style.display = "none";
docLink.style.display = "";
docLink.href = json.documentation_url;
self.disabled = false;
window.parent.setDisabledForOperation(false);
});
} catch (error) {
console.log("error", error);
// console.log("error", error);
checkUpdateText.textContent = error.message || e || "Unknown Exception"
progress.style.display = "none";
docLink.style.display = "none";
docLink.href = "";
self.disabled = false;
window.parent.setDisabledForOperation(false);
}
} else if (checkUpdateBtn.getAttribute("data-action") == "download") {
var storage = Bridge.External.Storage;
var path = storage.path;
stopProcess = true;
newVersionBlock.parentNode.style.height = "0px";
checkUpdateText.textContent = "正在下载更新...";
checkUpdateText.textContent = getPublicRes(117);
progress.style.display = "";
checkUpdateBlock.style.height = checkUpdateBlock.scrollHeight + "px";
var anime = Windows.UI.Animation;
var strutil = Bridge.External.String;
function setError(error) {
console.error("download error", error);
checkUpdateText.textContent = "下载失败,请重试: " + error.reason;
//console.error("download error", error);
checkUpdateText.textContent = strutil.format(getPublicRes(119), error.reason);
progress.style.display = "none";
self.disabled = false;
self.textContent = "重试";
window.parent.setDisabledForOperation(false);
checkUpdateBlock.style.height = checkUpdateBlock.scrollHeight + "px";
}
function setException(e) {
console.error("download exception", e);
checkUpdateText.textContent = "下载出现异常,请重试: " + e.message;
//console.error("download exception", e);
checkUpdateText.textContent = strutil.format(getPublicRes(119), e.message);
window.parent.setDisabledForOperation(false);
checkUpdateBlock.style.height = checkUpdateBlock.scrollHeight + "px";
}
function setComplete(complete) {
console.log("download complete", complete);
checkUpdateText.textContent = "下载完成,即将进行安装...";
// console.log("download complete", complete);
checkUpdateText.textContent = getPublicRes(120);
var cmdline = strutil.format("\"{0}\" /passive", tempfile);
var appinstallerpath = path.combine(path.root, "appinstaller.exe");
var settingsapppath = path.combine(path.root, "settings.exe");
window.parent.setDisabledForOperation(false);
var process = Bridge.External.Process;
process.kill(appinstallerpath, true, false);
checkUpdateBlock.style.height = checkUpdateBlock.scrollHeight + "px";
createProcess(cmdline, tempfile, wndDisplayMode.showNormal, false);
process.kill(settingsapppath, true, false);
//Bridge.External.closeWindow();
}
progress.value = 0;
anime.loading(checkUpdateLoading, true);
downloadFile(downloadUrl, "E:\\Profiles\\Bruce\\Desktop\\InstallerSetup.exe").done(
var tempdir = path.expand("%temp%");
var tempfile = path.combine(tempdir, "InstallerSetup.exe");
downloadFile(downloadUrl, tempfile).done(
function(complete) {
anime.loading(checkUpdateLoading, false);
if (complete.status == "ok") setComplete(complete);
@@ -370,9 +463,10 @@
setError(error);
},
function(prog) {
console.log("download progress", progress);
//console.log("download progress", prog);
progress.value = prog.progress;
checkUpdateText.textContent = "正在下载更新... (" + Math.round(prog.progress) + "%)";
checkUpdateText.textContent = strutil.format(getPublicRes(121), Math.floor(prog.progress), formatBytesSize(prog.received), formatBytesSize(prog.total));
checkUpdateBlock.style.height = checkUpdateBlock.scrollHeight + "px";
}
)
}