mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-06-19 22:00:09 +10:00
Updated manager and added appx manifest reader.
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
// 基类:提供 element 管理与基础 dispose 行为
|
||||
function PMAppBarBaseMember() {
|
||||
var _element = null;
|
||||
Object.defineProperty(this, "element", {
|
||||
configurable: true, // <- 关键:允许子类重定义该属性
|
||||
enumerable: false,
|
||||
get: function() { return _element; },
|
||||
set: function(value) {
|
||||
_element = value;
|
||||
try {
|
||||
if (_element) {
|
||||
// 让 DOM 节点可以反查到对应的 member
|
||||
_element.appBarMember = this;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
// 可被子类或外部调用来从 DOM 中移除自身
|
||||
this.dispose = function() {
|
||||
try {
|
||||
if (this.element && this.element.parentNode) {
|
||||
this.element.parentNode.removeChild(this.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
};
|
||||
}
|
||||
|
||||
function PMAppBarCommand() {
|
||||
PMAppBarBaseMember.call(this);
|
||||
var _button = document.createElement("button");
|
||||
var _iconcontainer = document.createElement("span");
|
||||
var _iconnode = document.createElement("span");
|
||||
var _labelnode = document.createElement("span");
|
||||
_button.appendChild(_iconcontainer);
|
||||
_iconcontainer.appendChild(_iconnode);
|
||||
_button.appendChild(_labelnode);
|
||||
_button.classList.add("win-command");
|
||||
_button.setAttribute("role", "menuitem");
|
||||
_iconcontainer.classList.add("win-commandicon");
|
||||
_iconcontainer.classList.add("win-commandring");
|
||||
_iconnode.classList.add("win-commandimage");
|
||||
_labelnode.classList.add("win-label");
|
||||
_iconcontainer.tabIndex = -1;
|
||||
_iconnode.tabIndex = -1;
|
||||
_labelnode.tabIndex = -1;
|
||||
_button.classList.add("win-global");
|
||||
Windows.UI.Event.Util.addEvent(_button, "keydown", function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
_button.click();
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "element", {
|
||||
get: function() { return _button; },
|
||||
set: function(value) { _button = value; }
|
||||
});
|
||||
Object.defineProperty(this, "icon", {
|
||||
get: function() { return _iconnode.innerHTML; },
|
||||
set: function(value) { _iconnode.innerHTML = value; }
|
||||
});
|
||||
Object.defineProperty(this, "label", {
|
||||
get: function() { return _labelnode.textContent; },
|
||||
set: function(value) { _labelnode.textContent = value; }
|
||||
});
|
||||
Object.defineProperty(this, "onclick", {
|
||||
get: function() { return _button.onclick; },
|
||||
set: function(value) { _button.onclick = value; }
|
||||
});
|
||||
Object.defineProperty(this, "selectable", {
|
||||
get: function() { return _button.classList.contains("win-selectable"); },
|
||||
set: function(value) {
|
||||
try { Windows.UI.Event.Util.removeEvent(this.element, "click", selectHandler); } catch (e) {}
|
||||
_button.classList.toggle("win-selectable", value);
|
||||
if (!value) {
|
||||
if (_button.classList.contains("win-selected")) {
|
||||
_button.classList.remove("win-selected");
|
||||
}
|
||||
}
|
||||
if (value) Windows.UI.Event.Util.addEvent(this.element, "click", selectHandler);
|
||||
else Windows.UI.Event.Util.removeEvent(this.element, "click", selectHandler);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "selected", {
|
||||
get: function() { return _button.classList.contains("win-selected"); },
|
||||
set: function(value) { _button.classList.toggle("win-selected", value); }
|
||||
});
|
||||
Object.defineProperty(this, "disabled", {
|
||||
get: function() { try { return this.element.disabled; } catch (e) { return false; } },
|
||||
set: function(value) { try { this.element.disabled = value; } catch (e) {} }
|
||||
});
|
||||
// global 或 selection (始终显示或有选择时显示)
|
||||
Object.defineProperty(this, "section", {
|
||||
get: function() {
|
||||
if (_button.classList.contains("win-global")) return "global";
|
||||
if (_button.classList.contains("win-selection")) return "selection";
|
||||
return "none";
|
||||
},
|
||||
set: function(value) {
|
||||
_button.classList.remove("win-global");
|
||||
_button.classList.remove("win-selection");
|
||||
if (value == "global") _button.classList.add("win-global");
|
||||
if (value == "selection") _button.classList.add("win-selection");
|
||||
}
|
||||
});
|
||||
|
||||
function selectHandler(event) {
|
||||
_button.classList.toggle("win-selected");
|
||||
}
|
||||
this.addEventListener = function(type, listener) {
|
||||
try { Windows.UI.Event.Util.addEvent(this.element, type, listener); } catch (e) {}
|
||||
};
|
||||
this.removeEventListener = function(type, listener) {
|
||||
try { Windows.UI.Event.Util.removeEvent(this.element, type, listener); } catch (e) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function PMAppBarSeparator() {
|
||||
PMAppBarBaseMember.call(this);
|
||||
var _hr = document.createElement("hr");
|
||||
_hr.classList.add("win-command");
|
||||
_hr.classList.add("win-global");
|
||||
_hr.setAttribute("role", "separator");
|
||||
Object.defineProperty(this, "element", {
|
||||
get: function() { return _hr; },
|
||||
set: function(value) { _hr = value; }
|
||||
});
|
||||
}
|
||||
|
||||
function PMAppBar(container) {
|
||||
var _container = container;
|
||||
var _enable = true;
|
||||
|
||||
function init(node) {
|
||||
var classNames = [
|
||||
"win-overlay",
|
||||
"win-commandlayout",
|
||||
"win-appbar",
|
||||
"appbar"
|
||||
]
|
||||
try {
|
||||
for (var i = 0; i < classNames.length; i++) {
|
||||
if (!node.classList.contains(classNames[i]))
|
||||
node.classList.add(classNames[i]);
|
||||
}
|
||||
} catch (e) {}
|
||||
try {
|
||||
node.appBarControl = this;
|
||||
} catch (e) {}
|
||||
}
|
||||
Object.defineProperty(this, "element", {
|
||||
get: function() { return _container; },
|
||||
set: function(value) {
|
||||
_container = value;
|
||||
init(value);
|
||||
// 将已有成员渲染到新的容器中
|
||||
try {
|
||||
// 先移除所有成员 DOM(如果之前挂载过)
|
||||
for (var i = 0; i < this._members.length; i++) {
|
||||
try {
|
||||
var mEl = this._members[i].element;
|
||||
if (mEl && mEl.parentNode === _container) {
|
||||
_container.removeChild(mEl);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
// 重新挂载所有成员,按数组顺序
|
||||
for (i = 0; i < this._members.length; i++) {
|
||||
try {
|
||||
var el = this._members[i].element;
|
||||
if (el) _container.appendChild(el);
|
||||
} catch (e) {}
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
|
||||
// 成员管理
|
||||
this._members = [];
|
||||
|
||||
// 返回内部数组引用(只读语义上)
|
||||
Object.defineProperty(this, "members", {
|
||||
get: function() { return this._members; }
|
||||
});
|
||||
|
||||
// 添加成员到末尾,返回索引;若失败返回 -1
|
||||
this.add = function(member) {
|
||||
if (!member || !member.element) return -1;
|
||||
this._members.push(member);
|
||||
try {
|
||||
if (_container) _container.appendChild(member.element);
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return this._members.length - 1;
|
||||
};
|
||||
this.addMember = this.add; // alias
|
||||
|
||||
// 在指定索引处插入(如果 index 为 undefined 或超范围,则 append)
|
||||
this.insertAt = function(member, index) {
|
||||
if (!member || !member.element) return -1;
|
||||
var len = this._members.length;
|
||||
if (typeof index !== "number" || index < 0 || index > len) {
|
||||
return this.add(member);
|
||||
}
|
||||
this._members.splice(index, 0, member);
|
||||
try {
|
||||
if (_container) {
|
||||
var refNode = _container.childNodes[index] || null;
|
||||
_container.insertBefore(member.element, refNode);
|
||||
}
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return index;
|
||||
};
|
||||
|
||||
// remove 接受成员对象或索引
|
||||
this.remove = function(memberOrIndex) {
|
||||
var idx = -1;
|
||||
if (typeof memberOrIndex === "number") {
|
||||
idx = memberOrIndex;
|
||||
} else {
|
||||
idx = this._members.indexOf(memberOrIndex);
|
||||
}
|
||||
if (idx < 0 || idx >= this._members.length) return false;
|
||||
var removed = this._members.splice(idx, 1)[0];
|
||||
try {
|
||||
if (removed && removed.element && removed.element.parentNode) {
|
||||
removed.element.parentNode.removeChild(removed.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return true;
|
||||
};
|
||||
|
||||
// 替换指定索引的成员,返回 true/false
|
||||
this.replaceAt = function(index, member) {
|
||||
if (!member || !member.element) return false;
|
||||
if (typeof index !== "number" || index < 0 || index >= this._members.length) return false;
|
||||
var old = this._members[index];
|
||||
this._members[index] = member;
|
||||
try {
|
||||
if (_container && old && old.element) {
|
||||
// 如果 old.element 在容器中,直接 replaceChild
|
||||
if (old.element.parentNode === _container) {
|
||||
_container.replaceChild(member.element, old.element);
|
||||
} else {
|
||||
// 备用:在位置 index 插入
|
||||
var ref = _container.childNodes[index] || null;
|
||||
_container.insertBefore(member.element, ref);
|
||||
}
|
||||
} else if (_container) {
|
||||
// 没有 old 元素,直接 append
|
||||
_container.appendChild(member.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return true;
|
||||
};
|
||||
|
||||
this.getMember = function(index) {
|
||||
return this._members[index];
|
||||
};
|
||||
|
||||
this.indexOf = function(member) {
|
||||
return this._members.indexOf(member);
|
||||
};
|
||||
|
||||
this.clear = function() {
|
||||
while (this._members.length) {
|
||||
var m = this._members.shift();
|
||||
try {
|
||||
if (m && m.element && m.element.parentNode) {
|
||||
m.element.parentNode.removeChild(m.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
};
|
||||
|
||||
var timer = null;
|
||||
var isupdating = false;
|
||||
|
||||
function waitTimer(ms) {
|
||||
clearTimeout(timer);
|
||||
isupdating = true;
|
||||
timer = setTimeout(function(t) {
|
||||
isupdating = false;
|
||||
t = null;
|
||||
}, ms, timer);
|
||||
}
|
||||
Object.defineProperty(this, "isupdating", {
|
||||
get: function() { return isupdating; }
|
||||
});
|
||||
var touchHide = document.createElement("div");
|
||||
touchHide.classList.add("appbar-touchhide");
|
||||
touchHide.style.display = "none";
|
||||
Windows.UI.Event.Util.addEvent(touchHide, "click", function(event) {
|
||||
touchHide.style.display = "none";
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
document.body.appendChild(touchHide);
|
||||
|
||||
function showTouchHide() {
|
||||
if (touchHide == null || touchHide == void 0) {
|
||||
touchHide = document.createElement("div");
|
||||
touchHide.classList.add("appbar-touchhide");
|
||||
}
|
||||
touchHide.style.display = "";
|
||||
}
|
||||
|
||||
function hideTouchHide() {
|
||||
touchHide.style.display = "none";
|
||||
}
|
||||
this.show = function() {
|
||||
try {
|
||||
if (!_enable) return;
|
||||
if (!this.element.classList.contains("show"))
|
||||
this.element.classList.add("show");
|
||||
waitTimer(500);
|
||||
showTouchHide();
|
||||
} catch (e) {}
|
||||
};
|
||||
this.hide = function() {
|
||||
try {
|
||||
if (this.element.classList.contains("show"))
|
||||
this.element.classList.remove("show");
|
||||
waitTimer(500);
|
||||
hideTouchHide();
|
||||
} catch (e) {}
|
||||
};
|
||||
this.setSelectionActive = function(active) {
|
||||
this._hasSelection = !!active;
|
||||
this._updateSelectionVisibility();
|
||||
};
|
||||
this._updateSelectionVisibility = function() {
|
||||
for (var i = 0; i < this._members.length; i++) {
|
||||
var el = this._members[i].element;
|
||||
if (el && el.classList && el.classList.contains("win-selection")) {
|
||||
el.style.display = this._hasSelection ? "" : "none";
|
||||
}
|
||||
}
|
||||
};
|
||||
Object.defineProperty(this, "enabled", {
|
||||
get: function() { return _enable; },
|
||||
set: function(value) {
|
||||
_enable = value;
|
||||
if (!value) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "isshowing", {
|
||||
get: function() { return this.element.classList.contains("show"); },
|
||||
set: function(value) {
|
||||
if (value) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
this._eventShowHandler = function(event) {
|
||||
if (!this.isshowing) this.show();
|
||||
else this.hide();
|
||||
};
|
||||
this._eventHideHandler = function(event) {
|
||||
this.hide();
|
||||
};
|
||||
var EventUtil = Windows.UI.Event.Util;
|
||||
var self = this;
|
||||
EventUtil.addEvent(document, "contextmenu", function(event) {
|
||||
self._eventShowHandler(event);
|
||||
event.preventDefault();
|
||||
});
|
||||
var pressTimer = null;
|
||||
|
||||
EventUtil.addEvent(document, "mousedown", function(event) {
|
||||
if (!self._enable) return;
|
||||
pressTimer = setTimeout(function(e) {
|
||||
self._eventShowHandler(e);
|
||||
event.preventDefault();
|
||||
}, 600, event);
|
||||
});
|
||||
|
||||
EventUtil.addEvent(document, "mouseup", function() {
|
||||
clearTimeout(pressTimer);
|
||||
});
|
||||
}
|
||||
global.AppBar = {
|
||||
AppBar: PMAppBar,
|
||||
Command: PMAppBarCommand,
|
||||
Separator: PMAppBarSeparator,
|
||||
BaseMember: PMAppBarBaseMember
|
||||
};
|
||||
})(this);
|
||||
Reference in New Issue
Block a user