mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +10:00
317 lines
9.9 KiB
JavaScript
317 lines
9.9 KiB
JavaScript
/// <reference path="//Microsoft.WinJS.2.0/js/base.js" />
|
|
/// <reference path="//Microsoft.WinJS.2.0/js/ui.js" />
|
|
|
|
(function (global) {
|
|
"use strict";
|
|
if (typeof global.toStaticHTML === "undefined") global.toStaticHTML = function (str) { return str; };
|
|
if (typeof global.WinJS === "undefined" || !global.WinJS) global.WinJS = {};
|
|
if (typeof global.WinJS.UI === "undefined" || !global.WinJS.UI) global.WinJS.UI = {};
|
|
|
|
// 事件混入
|
|
function mixEventMixin(target) {
|
|
var eventMixin = WinJS.Utilities.eventMixin;
|
|
target.addEventListener = eventMixin.addEventListener;
|
|
target.removeEventListener = eventMixin.removeEventListener;
|
|
target.dispatchEvent = eventMixin.dispatchEvent;
|
|
target._listeners = target._listeners || {};
|
|
}
|
|
|
|
/**
|
|
* 表示 ContentDialog 中的一个按钮命令。
|
|
* @class
|
|
* @param {string} label 按钮显示文本
|
|
* @param {function(Event=): (boolean|void)} [handler] 按钮点击处理函数
|
|
* @param {string} [commandId] 命令唯一标识
|
|
*/
|
|
function ContentDialogCommand(label, handler, commandId) {
|
|
this.label = label;
|
|
this.handler = handler;
|
|
this.commandId = commandId;
|
|
}
|
|
|
|
/**
|
|
* 模拟 WinRT ContentDialog 的对话框
|
|
* @class
|
|
* @memberof WinJS.UI
|
|
* @param {HTMLElement} element 容器
|
|
* @param {Object} [options] 初始化选项
|
|
*/
|
|
function ContentDialog(element, options) {
|
|
var container = element;
|
|
container.innerHTML = toStaticHTML('<div class="win-contentdialog-dialog notice-body"><div class="win-contentdialog-title notice-title"></div><div class="win-contentdialog-content notice-text"></div><div class="win-contentdialog-commands notice-controls"></div></div>');
|
|
container.classList.add("win-contentdialog");
|
|
container.classList.add("notice-back");
|
|
container.classList.add("hide");
|
|
|
|
var title = container.querySelector(".win-contentdialog-title");
|
|
var content = container.querySelector(".win-contentdialog-content");
|
|
var commandContainer = container.querySelector(".win-contentdialog-commands");
|
|
var _isdisposed = false;
|
|
|
|
mixEventMixin(this);
|
|
var self = this;
|
|
|
|
// 命令集合
|
|
this._commands = new WinJS.Binding.List();
|
|
var _showAsyncPromise = null;
|
|
var _showAsyncResolve = null;
|
|
|
|
// 渲染按钮
|
|
function renderCommands() {
|
|
while (commandContainer.firstChild) {
|
|
commandContainer.removeChild(commandContainer.firstChild);
|
|
}
|
|
self._commands.forEach(function (cmd, index) {
|
|
var btn = document.createElement("button");
|
|
btn.classList.add ("notice-btn");
|
|
btn.textContent = cmd.label;
|
|
btn.setAttribute("data-command-id", cmd.commandId || index);
|
|
|
|
btn.addEventListener("click", function (evt) {
|
|
handleCommandClick(cmd, evt);
|
|
});
|
|
|
|
commandContainer.appendChild(btn);
|
|
});
|
|
if (self._commands.length > 0) {
|
|
self.primaryCommandIndex = 0;
|
|
}
|
|
}
|
|
|
|
// 按钮点击处理
|
|
function handleCommandClick(cmd, evt) {
|
|
var result;
|
|
|
|
if (typeof cmd.handler === "function") {
|
|
result = cmd.handler.call(self, evt);
|
|
}
|
|
|
|
function complete() {
|
|
self.hide().then(function () {
|
|
if (_showAsyncResolve) {
|
|
_showAsyncResolve(cmd.commandId);
|
|
clearAsyncState();
|
|
}
|
|
});
|
|
}
|
|
|
|
// handler 返回 false → 不关闭
|
|
if (result === false) return;
|
|
|
|
// handler 返回 Promise → 等待
|
|
if (result && typeof result.then === "function") {
|
|
result.then(complete);
|
|
return;
|
|
}
|
|
|
|
complete();
|
|
}
|
|
|
|
function clearAsyncState() {
|
|
_showAsyncPromise = null;
|
|
_showAsyncResolve = null;
|
|
}
|
|
|
|
// 可取消事件
|
|
function createCancelableEvent(type) {
|
|
var defaultPrevented = false;
|
|
return {
|
|
type: type,
|
|
target: self,
|
|
preventDefault: function () { defaultPrevented = true; },
|
|
get defaultPrevented() { return defaultPrevented; }
|
|
};
|
|
}
|
|
|
|
function raiseEvent(type, cancelable) {
|
|
var eventObj = cancelable ? createCancelableEvent(type) : { type: type, target: self };
|
|
self.dispatchEvent(type, eventObj);
|
|
var handler = self["on" + type];
|
|
if (typeof handler === "function") {
|
|
handler.call(self, eventObj);
|
|
}
|
|
return eventObj;
|
|
}
|
|
|
|
// 命令列表事件
|
|
this._commands.addEventListener("iteminserted", renderCommands);
|
|
this._commands.addEventListener("itemremoved", renderCommands);
|
|
this._commands.addEventListener("itemchanged", renderCommands);
|
|
this._commands.addEventListener("reload", renderCommands);
|
|
|
|
// 属性
|
|
Object.defineProperty(this, "element", { get: function () { return container; }, enumerable: true });
|
|
Object.defineProperty(this, "hidden", { get: function () { return container.classList.contains("hide"); }, enumerable: true });
|
|
Object.defineProperty(this, "title", { get: function () { return title.textContent; }, set: function (v) { title.textContent = v; }, enumerable: true });
|
|
Object.defineProperty(this, "content", {
|
|
get: function () { return content.firstChild; },
|
|
set: function (v) {
|
|
if (typeof v === "string" || typeof v === "number") v = document.createTextNode(v);
|
|
while (content.firstChild) content.removeChild(content.firstChild);
|
|
content.appendChild(v);
|
|
},
|
|
enumerable: true
|
|
});
|
|
Object.defineProperty(this, "commands", { get: function () { return self._commands; }, enumerable: true });
|
|
Object.defineProperty(this, "primaryCommandIndex", {
|
|
get: function () {
|
|
var btns = commandContainer.querySelectorAll("button");
|
|
for (var i = 0; i < btns.length; i++) {
|
|
if (btns[i].type === "submit") return i;
|
|
}
|
|
return -1;
|
|
},
|
|
set: function (value) {
|
|
var btns = commandContainer.querySelectorAll("button");
|
|
for (var i = 0; i < btns.length; i++) {
|
|
btns[i].removeAttribute("type");
|
|
if (i === value) btns[i].type = "submit";
|
|
}
|
|
},
|
|
enumerable: true
|
|
});
|
|
this._darkMode = true;
|
|
this._backgroundColor = null;
|
|
this._foregroundColor = null;
|
|
Object.defineProperty(this, "darkMode", {
|
|
get: function () {
|
|
return self._darkMode;
|
|
},
|
|
set: function (value) {
|
|
self._darkMode = !!value;
|
|
if (self._backgroundColor === null) {
|
|
if (self._darkMode) {
|
|
container.classList.add("win-ui-dark");
|
|
container.classList.remove("win-ui-light");
|
|
} else {
|
|
container.classList.add("win-ui-light");
|
|
container.classList.remove("win-ui-dark");
|
|
}
|
|
}
|
|
},
|
|
enumerable: true
|
|
});
|
|
Object.defineProperty(this, "backgroundColor", {
|
|
get: function () {
|
|
return self._backgroundColor;
|
|
},
|
|
set: function (value) {
|
|
self._backgroundColor = value;
|
|
var dialog = container.querySelector(".win-contentdialog-dialog");
|
|
if (dialog) {
|
|
if (value !== null) {
|
|
dialog.style.backgroundColor = value;
|
|
} else {
|
|
// 还原暗/亮模式背景
|
|
if (self._darkMode) {
|
|
dialog.style.backgroundColor = "rgb(31, 0, 104)";
|
|
} else {
|
|
dialog.style.backgroundColor = "white";
|
|
}
|
|
}
|
|
}
|
|
},
|
|
enumerable: true
|
|
});
|
|
Object.defineProperty(this, "foregroundColor", {
|
|
get: function () {
|
|
return self._foregroundColor;
|
|
},
|
|
set: function (value) {
|
|
self._foregroundColor = value;
|
|
var titleEl = container.querySelector(".win-contentdialog-title");
|
|
var contentEl = container.querySelector(".win-contentdialog-content");
|
|
if (titleEl) titleEl.style.color = value || "";
|
|
if (contentEl) contentEl.style.color = value || "";
|
|
},
|
|
enumerable: true
|
|
});
|
|
container.classList.add("win-ui-dark");
|
|
// 显示 / 隐藏
|
|
this.show = function () {
|
|
if (!container.classList.contains("hide")) return Promise.as();
|
|
var ev = raiseEvent("beforeshow", true);
|
|
if (ev.defaultPrevented) return Promise.as(); // 取消显示时直接返回
|
|
container.classList.remove("hide");
|
|
return new WinJS.Promise(function (complete) {
|
|
setTimeout(function () {
|
|
raiseEvent("aftershow", false);
|
|
complete();
|
|
}, 150);
|
|
});
|
|
};
|
|
|
|
this.hide = function () {
|
|
if (container.classList.contains("hide")) return Promise.as();
|
|
var ev = raiseEvent("beforehide", true);
|
|
if (ev.defaultPrevented) return Promise.as();
|
|
container.classList.add("hide");
|
|
return new WinJS.Promise(function (complete) {
|
|
setTimeout(function () {
|
|
raiseEvent("afterhide", false);
|
|
complete();
|
|
}, 150);
|
|
});
|
|
};
|
|
|
|
// 释放资源
|
|
this.dispose = function () {
|
|
if (!_isdisposed) {
|
|
_isdisposed = true;
|
|
try { container.removeNode(false); } catch (e) { }
|
|
}
|
|
};
|
|
|
|
// 事件回调
|
|
this.onbeforeshow = null;
|
|
this.onaftershow = null;
|
|
this.onbeforehide = null;
|
|
this.onafterhide = null;
|
|
|
|
// showAsync
|
|
this.showAsync = function () {
|
|
if (_showAsyncPromise) return _showAsyncPromise;
|
|
_showAsyncPromise = new WinJS.Promise(function (resolve) {
|
|
_showAsyncResolve = resolve;
|
|
self.show();
|
|
});
|
|
return _showAsyncPromise;
|
|
};
|
|
|
|
// 初始化 options
|
|
if (options) {
|
|
if (options.title !== undefined) this.title = options.title;
|
|
if (options.content !== undefined) this.content = options.content;
|
|
if (options.commands && options.commands.length) {
|
|
options.commands.forEach(function (c) {
|
|
if (c instanceof ContentDialogCommand) {
|
|
self._commands.push(c);
|
|
} else {
|
|
self._commands.push(new ContentDialogCommand(c.label, c.handler, c.commandId));
|
|
}
|
|
});
|
|
renderCommands();
|
|
}
|
|
if (typeof options.primaryCommandIndex === "number") this.primaryCommandIndex = options.primaryCommandIndex;
|
|
if (typeof options.onbeforeshow === "function") this.onbeforeshow = options.onbeforeshow;
|
|
if (typeof options.onaftershow === "function") this.onaftershow = options.onaftershow;
|
|
if (typeof options.onbeforehide === "function") this.onbeforehide = options.onbeforehide;
|
|
if (typeof options.onafterhide === "function") this.onafterhide = options.onafterhide;
|
|
if (options.autoShow === true) this.show();
|
|
}
|
|
}
|
|
|
|
// 快速创建 ContentDialog
|
|
ContentDialog.create = function (content, title) {
|
|
var container = document.createElement("div");
|
|
document.body.appendChild(container);
|
|
return new ContentDialog(container, {
|
|
title: title,
|
|
content: content
|
|
});
|
|
};
|
|
|
|
global.WinJS.UI.ContentDialogCommand = ContentDialogCommand;
|
|
global.WinJS.UI.ContentDialog = ContentDialog;
|
|
|
|
})(this); |