"use strict";
var _ExtHostWebviewView_handle, _ExtHostWebviewView_proxy, _ExtHostWebviewView_viewType, _ExtHostWebviewView_webview, _ExtHostWebviewView_isDisposed, _ExtHostWebviewView_isVisible, _ExtHostWebviewView_title, _ExtHostWebviewView_description, _ExtHostWebviewView_badge, _ExtHostWebviewView_onDidChangeVisibility, _ExtHostWebviewView_onDidDispose;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtHostWebviewViews = exports.ExtHostWebviewService = exports.ExtHostWebviewPanel = exports.ExtHostWebview = void 0;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const vscode_1 = require("../../../common/vscode");
const ext_types_1 = require("../../../common/vscode/ext-types");
class ExtHostWebview {
    constructor(handle, proxy, options, cspResourceRoots, extensionLocation) {
        this.cspResourceRoots = cspResourceRoots;
        this.extensionLocation = extensionLocation;
        this._isDisposed = false;
        this._onMessageEmitter = new ide_core_common_1.Emitter();
        this.onDidReceiveMessage = this._onMessageEmitter.event;
        this._handle = handle;
        this._proxy = proxy;
        this._options = options;
    }
    dispose() {
        this._onMessageEmitter.dispose();
    }
    get html() {
        this.assertNotDisposed();
        return this._html;
    }
    set html(value) {
        this.assertNotDisposed();
        if (this._html !== value) {
            this._html = value;
            this._proxy.$setHtml(this._handle, value);
        }
    }
    get options() {
        this.assertNotDisposed();
        return this._options;
    }
    set options(newOptions) {
        this.assertNotDisposed();
        this._proxy.$setOptions(this._handle, newOptions);
        this._options = newOptions;
    }
    postMessage(message) {
        this.assertNotDisposed();
        return this._proxy.$postMessage(this._handle, message);
    }
    assertNotDisposed() {
        if (this._isDisposed) {
            throw new Error('Webview is disposed');
        }
    }
    get resourceRoot() {
        return 'vscode-resource:';
    }
    get cspSource() {
        let cspSource = this.cspResourceRoots.join(' ');
        if (this.extensionLocation) {
            cspSource += ` 'self' vscode-resource:/${this.extensionLocation.path}/`.toLowerCase();
        }
        return cspSource;
    }
    toWebviewResource(resource) {
        return this.asWebviewUri(resource);
    }
    asWebviewUri(localResource) {
        if (localResource.scheme === ide_core_common_1.Schemes.file) {
            return ext_types_1.Uri.from({
                scheme: 'vscode-resource',
                path: localResource.path,
                authority: localResource.authority,
                query: localResource.query,
                fragment: localResource.fragment,
            });
        }
        else {
            return localResource;
        }
    }
}
exports.ExtHostWebview = ExtHostWebview;
class ExtHostWebviewPanel {
    constructor(handle, proxy, viewType, title, viewColumn, editorOptions, webview) {
        this._isDisposed = false;
        this._visible = true;
        this._active = true;
        this._onDisposeEmitter = new ide_core_common_1.Emitter();
        this.onDidDispose = this._onDisposeEmitter.event;
        this._onDidChangeViewStateEmitter = new ide_core_common_1.Emitter();
        this.onDidChangeViewState = this._onDidChangeViewStateEmitter.event;
        this._handle = handle;
        this._proxy = proxy;
        this._viewType = viewType;
        this._options = editorOptions;
        this._viewColumn = viewColumn;
        this._title = title;
        this._webview = webview;
    }
    dispose() {
        if (this._isDisposed) {
            return;
        }
        this._isDisposed = true;
        this._onDisposeEmitter.fire();
        this._proxy.$disposeWebview(this._handle);
        this._webview.dispose();
        this._onDisposeEmitter.dispose();
        this._onDidChangeViewStateEmitter.dispose();
    }
    get webview() {
        this.assertNotDisposed();
        return this._webview;
    }
    get viewType() {
        this.assertNotDisposed();
        return this._viewType;
    }
    get title() {
        this.assertNotDisposed();
        return this._title;
    }
    set title(value) {
        this.assertNotDisposed();
        if (this._title !== value) {
            this._title = value;
            this._proxy.$setTitle(this._handle, value);
        }
    }
    get iconPath() {
        this.assertNotDisposed();
        return this._iconPath;
    }
    set iconPath(value) {
        this.assertNotDisposed();
        if (this._iconPath !== value) {
            this._iconPath = value;
            let param = {
                light: '',
                dark: '',
            };
            if (ext_types_1.Uri.isUri(value)) {
                param = { light: value.toString(), dark: value.toString() };
            }
            else {
                const v = value;
                param = { light: v.light.toString(), dark: v.dark.toString() };
            }
            this._proxy.$setIconPath(this._handle, param);
        }
    }
    get options() {
        return this._options;
    }
    get viewColumn() {
        this.assertNotDisposed();
        return this._viewColumn;
    }
    _setViewColumn(value) {
        this.assertNotDisposed();
        this._viewColumn = value;
    }
    get active() {
        this.assertNotDisposed();
        return this._active;
    }
    _setActive(value) {
        this.assertNotDisposed();
        this._active = value;
    }
    get visible() {
        this.assertNotDisposed();
        return this._visible;
    }
    _setVisible(value) {
        this.assertNotDisposed();
        this._visible = value;
    }
    postMessage(message) {
        this.assertNotDisposed();
        return this._proxy.$postMessage(this._handle, message);
    }
    reveal(viewColumn, preserveFocus) {
        this.assertNotDisposed();
        this._proxy.$reveal(this._handle, {
            viewColumn,
            preserveFocus: !!preserveFocus,
        });
    }
    assertNotDisposed() {
        if (this._isDisposed) {
            throw new Error('Webview is disposed');
        }
    }
}
exports.ExtHostWebviewPanel = ExtHostWebviewPanel;
class ExtHostWebviewService {
    constructor(rpcProtocol) {
        this.rpcProtocol = rpcProtocol;
        this.webviewHandlePool = 1;
        this._webviewPanels = new Map();
        this._localWebviews = new Map();
        this._serializers = new Map();
        this.resourceRoots = [];
        this.rpcProtocol = rpcProtocol;
        this._proxy = this.rpcProtocol.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadWebview);
    }
    async $init() {
        return await this.init();
    }
    async init() {
        this.resourceRoots = await this._proxy.$getWebviewResourceRoots();
    }
    getNextHandle() {
        let nextHandle = 'ext-host-webview-' + this.webviewHandlePool++;
        while (this._webviewPanels.has(nextHandle)) {
            nextHandle = 'ext-host-webview-' + this.webviewHandlePool++;
        }
        return nextHandle;
    }
    createWebview(extensionLocation, viewType, title, showOptions, options = {}, extension) {
        const viewColumn = typeof showOptions === 'object' ? showOptions.viewColumn : showOptions;
        const webviewShowOptions = {
            viewColumn,
            preserveFocus: typeof showOptions === 'object' && !!showOptions.preserveFocus,
        };
        const handle = this.getNextHandle();
        this._proxy.$createWebviewPanel(handle, viewType, title, webviewShowOptions, options, extension);
        const webview = new ExtHostWebview(handle, this._proxy, options, this.resourceRoots, extensionLocation);
        const panel = new ExtHostWebviewPanel(handle, this._proxy, viewType, title, viewColumn, options, webview);
        this._webviewPanels.set(handle, panel);
        return panel;
    }
    $pipeBrowserHostedWebviewPanel(handle, viewType) {
        const webview = new ExtHostWebview(handle, this._proxy, {}, this.resourceRoots);
        const panel = new ExtHostWebviewPanel(handle, this._proxy, viewType, '', vscode_1.ViewColumn.One, {}, webview);
        this._webviewPanels.set(handle, panel);
    }
    createLocalWebview(handle) {
        const webview = new ExtHostWebview(handle, this._proxy, {}, this.resourceRoots);
        this._localWebviews.set(handle, webview);
        return webview;
    }
    registerWebviewPanelSerializer(viewType, serializer) {
        if (this._serializers.has(viewType)) {
            throw new Error(`Serializer for '${viewType}' already registered`);
        }
        this._serializers.set(viewType, serializer);
        this._proxy.$registerSerializer(viewType);
        return new ext_types_1.Disposable(() => {
            this._serializers.delete(viewType);
            this._proxy.$unregisterSerializer(viewType);
        });
    }
    getExtHostWebview(handle) {
        var _a;
        return this._localWebviews.get(handle) || ((_a = this.getWebviewPanel(handle)) === null || _a === void 0 ? void 0 : _a.webview);
    }
    $onMessage(handle, message) {
        var _a;
        (_a = this.getExtHostWebview(handle)) === null || _a === void 0 ? void 0 : _a._onMessageEmitter.fire(message);
    }
    $onDidChangeWebviewPanelViewState(handle, newState) {
        const panel = this.getWebviewPanel(handle);
        if (panel) {
            const viewColumn = newState.position;
            if (panel.active !== newState.active || panel.visible !== newState.visible || panel.viewColumn !== viewColumn) {
                panel._setActive(newState.active);
                panel._setVisible(newState.visible);
                panel._setViewColumn(viewColumn);
                panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel });
            }
        }
    }
    async $onDidDisposeWebviewPanel(handle) {
        const panel = this.getWebviewPanel(handle);
        if (panel) {
            panel.dispose();
            this._webviewPanels.delete(handle);
        }
    }
    async $deserializeWebviewPanel(webviewHandle, viewType, title, state, position, options) {
        const serializer = this._serializers.get(viewType);
        if (!serializer) {
            throw new Error(`No serializer found for '${viewType}'`);
        }
        const webview = new ExtHostWebview(webviewHandle, this._proxy, options, this.resourceRoots);
        const revivedPanel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, position, options, webview);
        this._webviewPanels.set(webviewHandle, revivedPanel);
        return serializer.deserializeWebviewPanel(revivedPanel, state);
    }
    getWebviewPanel(handle) {
        return this._webviewPanels.get(handle);
    }
}
exports.ExtHostWebviewService = ExtHostWebviewService;
class ExtHostWebviewView extends ide_core_common_1.Disposable {
    constructor(handle, proxy, viewType, title, webview, isVisible) {
        super();
        _ExtHostWebviewView_handle.set(this, void 0);
        _ExtHostWebviewView_proxy.set(this, void 0);
        _ExtHostWebviewView_viewType.set(this, void 0);
        _ExtHostWebviewView_webview.set(this, void 0);
        _ExtHostWebviewView_isDisposed.set(this, false);
        _ExtHostWebviewView_isVisible.set(this, void 0);
        _ExtHostWebviewView_title.set(this, void 0);
        _ExtHostWebviewView_description.set(this, void 0);
        _ExtHostWebviewView_badge.set(this, void 0);
        _ExtHostWebviewView_onDidChangeVisibility.set(this, new ide_core_common_1.Emitter());
        this.onDidChangeVisibility = tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_onDidChangeVisibility, "f").event;
        _ExtHostWebviewView_onDidDispose.set(this, new ide_core_common_1.Emitter());
        // @ts-ignore
        this.onDidDispose = tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_onDidDispose, "f").event;
        // @ts-ignore
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_viewType, viewType, "f");
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_title, title, "f");
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_handle, handle, "f");
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_proxy, proxy, "f");
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_webview, webview, "f");
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_isVisible, isVisible, "f");
        this.addDispose(tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_onDidChangeVisibility, "f"));
        this.addDispose(tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_onDidDispose, "f"));
    }
    dispose() {
        if (tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_isDisposed, "f")) {
            return;
        }
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_isDisposed, true, "f");
        tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_onDidDispose, "f").fire();
        tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_webview, "f").dispose();
        super.dispose();
    }
    get title() {
        this.assertNotDisposed();
        return tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_title, "f");
    }
    set title(value) {
        this.assertNotDisposed();
        if (tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_title, "f") !== value) {
            tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_title, value, "f");
            tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_proxy, "f").$setWebviewViewTitle(tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_handle, "f"), value);
        }
    }
    get description() {
        this.assertNotDisposed();
        return tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_description, "f");
    }
    set description(value) {
        this.assertNotDisposed();
        if (tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_description, "f") !== value) {
            tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_description, value, "f");
            tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_proxy, "f").$setWebviewViewDescription(tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_handle, "f"), value);
        }
    }
    get badge() {
        this.assertNotDisposed();
        return tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_badge, "f");
    }
    set badge(badge) {
        this.assertNotDisposed();
        if (tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_badge, "f") !== badge) {
            tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_badge, badge, "f");
            tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_proxy, "f").$setBadge(tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_handle, "f"), badge);
        }
    }
    get visible() {
        return tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_isVisible, "f");
    }
    get webview() {
        return tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_webview, "f");
    }
    get viewType() {
        return tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_viewType, "f");
    }
    /* internal */ _setVisible(visible) {
        if (visible === tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_isVisible, "f") || tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_isDisposed, "f")) {
            return;
        }
        tslib_1.__classPrivateFieldSet(this, _ExtHostWebviewView_isVisible, visible, "f");
        tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_onDidChangeVisibility, "f").fire();
    }
    show(preserveFocus) {
        this.assertNotDisposed();
        tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_proxy, "f").$show(tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_handle, "f"), !!preserveFocus);
    }
    assertNotDisposed() {
        if (tslib_1.__classPrivateFieldGet(this, _ExtHostWebviewView_isDisposed, "f")) {
            throw new Error('Webview is disposed');
        }
    }
}
_ExtHostWebviewView_handle = new WeakMap(), _ExtHostWebviewView_proxy = new WeakMap(), _ExtHostWebviewView_viewType = new WeakMap(), _ExtHostWebviewView_webview = new WeakMap(), _ExtHostWebviewView_isDisposed = new WeakMap(), _ExtHostWebviewView_isVisible = new WeakMap(), _ExtHostWebviewView_title = new WeakMap(), _ExtHostWebviewView_description = new WeakMap(), _ExtHostWebviewView_badge = new WeakMap(), _ExtHostWebviewView_onDidChangeVisibility = new WeakMap(), _ExtHostWebviewView_onDidDispose = new WeakMap();
class ExtHostWebviewViews {
    constructor(rpcProtocol, _extHostWebview) {
        this._extHostWebview = _extHostWebview;
        this._viewProviders = new Map();
        this._webviewViews = new Map();
        this._proxy = rpcProtocol.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadWebviewView);
    }
    registerWebviewViewProvider(extension, viewType, provider, webviewOptions) {
        if (this._viewProviders.has(viewType)) {
            throw new Error(`View provider for '${viewType}' already registered`);
        }
        this._viewProviders.set(viewType, { provider, extension });
        this._proxy.$registerWebviewViewProvider(extension, viewType, webviewOptions);
        return new ext_types_1.Disposable(() => {
            this._viewProviders.delete(viewType);
            this._proxy.$unregisterWebviewViewProvider(viewType);
        });
    }
    async $resolveWebviewView(webviewHandle, viewType, title, state, cancellation) {
        const entry = this._viewProviders.get(viewType);
        if (!entry) {
            throw new Error(`No view provider found for '${viewType}'`);
        }
        const { provider } = entry;
        const webview = this._extHostWebview.createLocalWebview(webviewHandle);
        const revivedView = new ExtHostWebviewView(webviewHandle, this._proxy, viewType, title, webview, true);
        this._webviewViews.set(webviewHandle, revivedView);
        await provider.resolveWebviewView(revivedView, { state }, cancellation);
    }
    async $onDidChangeWebviewViewVisibility(webviewHandle, visible) {
        const webviewView = this.getWebviewView(webviewHandle);
        webviewView._setVisible(visible);
    }
    async $disposeWebviewView(webviewHandle) {
        var _a;
        this._webviewViews.delete(webviewHandle);
        (_a = this._extHostWebview.getWebviewPanel(webviewHandle)) === null || _a === void 0 ? void 0 : _a.dispose();
    }
    getWebviewView(handle) {
        const entry = this._webviewViews.get(handle);
        if (!entry) {
            throw new Error('No webview found');
        }
        return entry;
    }
}
exports.ExtHostWebviewViews = ExtHostWebviewViews;
//# sourceMappingURL=ext.host.api.webview.js.map