Updated manager and added appx manifest reader.

This commit is contained in:
Bruce
2026-01-24 22:06:55 +08:00
parent 75cb72964d
commit 503ece1c64
60 changed files with 4980 additions and 3819 deletions
+396
View File
@@ -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);