fix: prevent duplicate titles on Taobao login page

Keep a single native title on the entry page even when the host ignores title clearing. Preserve centered headers elsewhere and normalize manifest line endings during shared-code checks.
This commit is contained in:
xsl
2026-11-05 10:43:01 +08:00
parent 873b45d3a5
commit 0e34eeb1df
6 changed files with 38 additions and 9 deletions
+10 -5
View File
@@ -11,32 +11,37 @@ function layout(platform) {
function page(definition, platform, options) {
options = options || {};
definition.data = Object.assign({ brandHeader: layout() }, definition.data);
// Taobao may report success yet keep its entry-page app title visible.
// Login must never draw a second title, including its very first frame.
if (options.nativeTitleOnly) definition.data.brandHeader.showTitle = false;
var load = definition.onLoad, resize = definition.onResize, show = definition.onShow,
ready = definition.onReady, hide = definition.onHide, unload = definition.onUnload;
function refresh(instance) {
var next = layout(platform);
if (instance.data.brandHeader) next.showTitle = instance.data.brandHeader.showTitle;
if (options.nativeTitleOnly) next.showTitle = false;
instance.setData({ brandHeader: next });
}
function clearNativeTitle(instance) {
function syncNativeTitle(instance) {
if (!platform || typeof platform.setNavigationBar !== 'function') return;
var seq = instance.brandHeaderSeq = (instance.brandHeaderSeq || 0) + 1, settled = false;
function result(ok) {
if (settled) return; settled = true;
if (!instance.brandHeaderVisible || instance.brandHeaderSeq !== seq) return;
if (options.nativeTitleOnly) return;
// The entry page can retain a platform-owned app name. If clearing is
// explicitly rejected, show one native title rather than two titles.
if (!ok && !options.nativeTitleFallback) return;
instance.setData({ brandHeader: Object.assign({}, instance.data.brandHeader, { showTitle: ok }) });
}
try {
var pending = platform.setNavigationBar({ title: '\u200b', success: function () { result(true); }, fail: function () { result(false); } });
var pending = platform.setNavigationBar({ title: options.nativeTitleOnly ? TITLE : '\u200b', success: function () { result(true); }, fail: function () { result(false); } });
if (pending && typeof pending.then === 'function') Promise.resolve(pending).then(function () { result(true); }, function () { result(false); });
} catch (_) { result(false); }
}
definition.onLoad = function () { this.brandHeaderVisible = true; refresh(this); clearNativeTitle(this); if (load) return load.apply(this, arguments); };
definition.onShow = function () { this.brandHeaderVisible = true; clearNativeTitle(this); if (show) return show.apply(this, arguments); };
definition.onReady = function () { clearNativeTitle(this); if (ready) return ready.apply(this, arguments); };
definition.onLoad = function () { this.brandHeaderVisible = true; refresh(this); syncNativeTitle(this); if (load) return load.apply(this, arguments); };
definition.onShow = function () { this.brandHeaderVisible = true; syncNativeTitle(this); if (show) return show.apply(this, arguments); };
definition.onReady = function () { syncNativeTitle(this); if (ready) return ready.apply(this, arguments); };
definition.onHide = function () { this.brandHeaderVisible = false; this.brandHeaderSeq = (this.brandHeaderSeq || 0) + 1; if (hide) return hide.apply(this, arguments); };
definition.onUnload = function () { this.brandHeaderVisible = false; this.brandHeaderSeq = (this.brandHeaderSeq || 0) + 1; if (unload) return unload.apply(this, arguments); };
definition.onResize = function () { refresh(this); if (resize) return resize.apply(this, arguments); };