mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-15 19:24:23 +08:00
✨ feat(native-window): 支持标签页拖出为原生独立窗口
- 支持 SQL、数据和结果标签拖出到跨显示器原生窗口 - 通过受认证 loopback bridge 复用主进程后端与状态 - 支持子窗口继续拆窗、聚焦、关闭、还原与异常退出恢复 - 补充多窗口协议、状态同步和跨平台回归测试
This commit is contained in:
110
internal/nativewindow/runtime_script.go
Normal file
110
internal/nativewindow/runtime_script.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package nativewindow
|
||||
|
||||
func detachedRuntimeBridgeScript() string {
|
||||
return `(function () {
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
var existingGo = window.go || {};
|
||||
var nativeNamespace = existingGo.nativewindow || {};
|
||||
var bridge = nativeNamespace.Bridge;
|
||||
var control = nativeNamespace.Control;
|
||||
if (
|
||||
!bridge
|
||||
|| typeof bridge.Invoke !== 'function'
|
||||
|| typeof bridge.WindowID !== 'function'
|
||||
|| typeof bridge.OpenWindow !== 'function'
|
||||
|| typeof bridge.FocusWindow !== 'function'
|
||||
|| typeof bridge.CloseWindow !== 'function'
|
||||
|| typeof bridge.CloseOwnedWindows !== 'function'
|
||||
) {
|
||||
console.error('[GoNavi Detached] native bridge is unavailable');
|
||||
return;
|
||||
}
|
||||
|
||||
var invoke = function (namespace, receiver, method, args) {
|
||||
return bridge.Invoke(namespace, receiver, method, Array.isArray(args) ? args : []);
|
||||
};
|
||||
var buildServiceProxy = function (namespace, receiver) {
|
||||
return new Proxy({}, {
|
||||
get: function (_target, property) {
|
||||
if (typeof property !== 'string') return undefined;
|
||||
return function () {
|
||||
return invoke(namespace, receiver, property, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
var parentWindowManager = {
|
||||
Open: function (request) {
|
||||
return bridge.OpenWindow(request || {});
|
||||
},
|
||||
Focus: function (id) {
|
||||
return bridge.FocusWindow(String(id || ''));
|
||||
},
|
||||
Close: function (id) {
|
||||
return bridge.CloseWindow(String(id || ''));
|
||||
},
|
||||
CloseAll: function () {
|
||||
return bridge.CloseOwnedWindows();
|
||||
}
|
||||
};
|
||||
nativeNamespace = {
|
||||
...nativeNamespace,
|
||||
Manager: parentWindowManager
|
||||
};
|
||||
|
||||
window.go = {
|
||||
...existingGo,
|
||||
nativewindow: nativeNamespace,
|
||||
app: {
|
||||
...(existingGo.app || {}),
|
||||
App: buildServiceProxy('app', 'App')
|
||||
},
|
||||
aiservice: {
|
||||
...(existingGo.aiservice || {}),
|
||||
Service: buildServiceProxy('aiservice', 'Service')
|
||||
}
|
||||
};
|
||||
|
||||
var detached = {
|
||||
active: true,
|
||||
bootstrap: null,
|
||||
bootstrapPromise: null,
|
||||
loadBootstrap: function () {
|
||||
if (!detached.bootstrapPromise) {
|
||||
detached.bootstrapPromise = bridge.Bootstrap().then(function (payload) {
|
||||
detached.bootstrap = payload;
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
return detached.bootstrapPromise;
|
||||
},
|
||||
action: function (action, payload) {
|
||||
return bridge.Action(String(action || ''), payload || {});
|
||||
}
|
||||
};
|
||||
window.__GONAVI_DETACHED__ = detached;
|
||||
window.__GONAVI_DETACHED_RUNTIME__ = {
|
||||
buildType: 'desktop-detached',
|
||||
capabilities: { nativeWindow: true, sharedBackend: true }
|
||||
};
|
||||
|
||||
var detachedWindowIDPromise = Promise.resolve(bridge.WindowID()).then(function (windowID) {
|
||||
return String(windowID || '');
|
||||
});
|
||||
|
||||
var runtime = window.runtime || {};
|
||||
if (typeof runtime.EventsOnMultiple === 'function') {
|
||||
runtime.EventsOnMultiple('` + CommandEventName + `', function (command) {
|
||||
detachedWindowIDPromise.then(function (windowID) {
|
||||
if (!command || String(command.id || '') !== windowID) return;
|
||||
if (command.action === 'close' && control && typeof control.Close === 'function') {
|
||||
control.Close();
|
||||
} else if (command.action === 'focus' && control && typeof control.Focus === 'function') {
|
||||
control.Focus();
|
||||
}
|
||||
});
|
||||
}, -1);
|
||||
}
|
||||
})();`
|
||||
}
|
||||
Reference in New Issue
Block a user