Update manager and add features for App Installer.

This commit is contained in:
Bruce
2026-01-31 22:03:03 +08:00
parent 0c87a2cdcd
commit d91948eaff
37 changed files with 3645 additions and 923 deletions
+184
View File
@@ -0,0 +1,184 @@
(function(global) {
"use strict";
/**
* TransitionPanel
* axis: 'x' | 'y' | 'both'
* speed: 'fast' | 'medium' | 'slow'
* el: DOM 元素
*/
function TransitionPanel(el, options) {
if (!el) throw new Error("TransitionPanel requires a DOM element.");
this.el = el;
this.opts = options || {};
this.axis = this.opts.axis || 'y';
this.speed = this.opts.speed || 'medium';
// 初始化状态
this._shown = false;
this._events = {};
// 确保基础类 statusbar
if (!el.classList.contains('statusbar')) el.classList.add('statusbar');
// 确保 axis 类存在(x/y/both
if (this.axis === 'x' && !el.classList.contains('x')) el.classList.add('x');
else if (this.axis === 'y' && !el.classList.contains('y')) el.classList.add('y');
else if (this.axis === 'both' && !el.classList.contains('both')) el.classList.add('both');
// 添加速度类
if (this.speed === 'fast') el.classList.add('fast');
else if (this.speed === 'medium') el.classList.add('medium');
else el.classList.add('slow');
// 内容变化自动刷新
this._bindContentChange();
}
function maxWidth(el) {
var cw = 0;
var ow = 0;
var rw = 0;
var sw = 0;
try { cw = el.clientWidth; } catch (e) {}
try { ow = el.offsetWidth; } catch (e) {}
try { rw = el.getBoundingClientRect().width; } catch (e) {}
try { sw = el.scrollWidth; } catch (e) {}
return Math.max(cw, ow, rw, sw);
}
function maxHeight(el) {
var ch = 0;
var oh = 0;
var rh = 0;
var sh = 0;
try { ch = el.clientHeight; } catch (e) {}
try { oh = el.offsetHeight; } catch (e) {}
try { rh = el.getBoundingClientRect().height; } catch (e) {}
try { sh = el.scrollHeight; } catch (e) {}
return Math.max(ch, oh, rh, sh);
}
// 显示
TransitionPanel.prototype.show = function() {
if (this._shown) return;
this._emit('beforeshow');
this._shown = true;
var el = this.el;
setTimeout(function() {
this._emit('show');
if (this.axis !== 'x') el.style.height = maxHeight(el) + 'px';
if (this.axis !== 'y') el.style.width = maxWidth(el) + 'px';
if (this.axis === 'both') {
el.style.height = maxHeight(el) + 'px';
el.style.width = maxWidth(el) + 'px';
}
this._afterTransition('aftershow');
}.bind(this), 16);
};
// 隐藏
TransitionPanel.prototype.hide = function() {
if (!this._shown) return;
this._emit('beforehide');
this._shown = false;
var el = this.el;
// 锁定当前尺寸
if (this.axis !== 'x') el.style.height = maxHeight(el) + 'px';
if (this.axis !== 'y') el.style.width = maxWidth(el) + 'px';
if (this.axis === 'both') {
el.style.height = maxHeight(el) + 'px';
el.style.width = maxWidth(el) + 'px';
}
setTimeout(function() {
this._emit('hide');
// 回到折叠状态尺寸(依赖 x/y/both 类)
if (this.axis !== 'x') el.style.height = '';
if (this.axis !== 'y') el.style.width = '';
if (this.axis === 'both') {
el.style.height = '';
el.style.width = '';
}
this._afterTransition('afterhide');
}.bind(this), 16);
};
// 刷新尺寸(显示中)
TransitionPanel.prototype.refresh = function() {
if (!this._shown) return;
var el = this.el;
if (this.axis !== 'x') el.style.height = el.scrollHeight + 'px';
if (this.axis !== 'y') el.style.width = el.scrollWidth + 'px';
};
// 内容变化自动刷新
TransitionPanel.prototype._bindContentChange = function() {
if (!global.setTextChangeEvent) return;
var self = this;
global.setTextChangeEvent(this.el, function() {
if (self._shown) self.refresh();
});
};
// transitionend 回调处理
TransitionPanel.prototype._afterTransition = function(evt) {
var el = this.el;
var called = false;
var duration = this.speed === 'fast' ? 300 : (this.speed === 'medium' ? 500 : 700);
function done() {
if (called) return;
called = true;
el.removeEventListener('transitionend', done);
if (evt) this._emit(evt);
}
el.addEventListener('transitionend', done.bind(this));
setTimeout(done.bind(this), duration + 30);
};
// 生命周期事件绑定
TransitionPanel.prototype.on = function(name, fn) {
(this._events[name] || (this._events[name] = [])).push(fn);
};
// 事件触发
TransitionPanel.prototype._emit = function(name) {
var list = this._events[name];
if (!list) return;
for (var i = 0; i < list.length; i++) {
try { list[i].call(this); } catch (e) { console.error(e); }
}
};
// 只读属性 shown
Object.defineProperty(TransitionPanel.prototype, 'shown', {
get: function() { return this._shown; }
});
// 销毁
TransitionPanel.prototype.dispose = function() {
// 移除所有事件回调
this._events = {};
// 清理 el 内联样式
if (this.el) {
this.el.style.height = '';
this.el.style.width = '';
}
this._shown = false;
// 可选:删除内容变化监听(如果使用全局 setTextChangeEvent
if (global.Windows && global.Windows.UI && global.Windows.UI.Event && global.Windows.UI.Event.Monitor) {
// 这里可以 detach 所有回调
// 视具体实现可扩展
}
};
// 全局暴露
global.TransitionPanel = TransitionPanel;
})(this);