@opensumi/ide-components 3.7.2-next-1740450374.0 → 3.7.2-next-1741226843.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +0 -6
- package/dist/index.js +8 -8
- package/lib/icon/iconfont/iconManager.js +1 -1
- package/lib/icon/iconfont/iconManager.js.map +1 -1
- package/lib/input/HistoryInputBox.d.ts +2 -2
- package/lib/input/HistoryInputBox.d.ts.map +1 -1
- package/lib/input/HistoryInputBox.js +1 -1
- package/lib/input/HistoryInputBox.js.map +1 -1
- package/lib/markdown-react/parse.d.ts.map +1 -1
- package/lib/markdown-react/parse.js +63 -80
- package/lib/markdown-react/parse.js.map +1 -1
- package/lib/recycle-tree/tree/TreeNode.d.ts +2 -2
- package/lib/recycle-tree/tree/TreeNode.d.ts.map +1 -1
- package/lib/recycle-tree/tree/TreeNode.js +7 -14
- package/lib/recycle-tree/tree/TreeNode.js.map +1 -1
- package/lib/select/index.d.ts +1 -2
- package/lib/select/index.d.ts.map +1 -1
- package/lib/select/index.js +70 -87
- package/lib/select/index.js.map +1 -1
- package/lib/select/style.less +0 -3
- package/lib/style/base.less +1 -1
- package/lib/utils/warning.js +1 -1
- package/lib/utils/warning.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -5825,7 +5825,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
5825
5825
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
5826
5826
|
|
|
5827
5827
|
"use strict";
|
|
5828
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.iconManager = exports.defaultIconMap = exports.defaultIconfont = void 0;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\nconst warning_1 = tslib_1.__importDefault(__webpack_require__(/*! ../../utils/warning */ \"./src/utils/warning.ts\"));\nconst iconMap_1 = __webpack_require__(/*! ./iconMap */ \"./src/icon/iconfont/iconMap.ts\");\nObject.defineProperty(exports, \"defaultIconfont\", ({ enumerable: true, get: function () { return iconMap_1.defaultIconfont; } }));\n/**\n * 以下为 typo 的字体,做一定兼容\n * key 为 iconName enum, value 为 icon className\n */\nconst typoIconMap = {\n 'search-close': 'close-square',\n 'fold': 'collapse-all',\n 'setting-general': 'setting',\n 'setting-file': 'file-text',\n 'setting-extension': 'extension',\n 'run-debug': 'start',\n 'toggle-breakpoints': 'deactivate-breakpoints',\n // new typos issue\n 'withdraw': 'fallback',\n 'terminate1': 'stop',\n 'stop1': 'stop',\n 'add': 'plus',\n // removed duplicated icons\n 'rundebug': 'start',\n 'terminate': 'stop',\n};\nconst _defaultIconAndTypoIconMap = Object.assign({}, iconMap_1.defaultIconfont, typoIconMap);\nexports.defaultIconMap = new Proxy(_defaultIconAndTypoIconMap, {\n get(obj, prop) {\n const typoValue = typoIconMap[prop];\n (0, warning_1.default)(!typoValue, `Icon '${prop}' was a typo, please use '${typoValue}' instead`);\n return obj[prop];\n },\n});\nclass IconManager {\n constructor() {\n this._ktIconPrefixes = [];\n this._iconMap = {};\n }\n update(prefix, customIconMap) {\n this._iconMap[prefix] = customIconMap;\n this._ktIconPrefixes.push(prefix);\n }\n getIconClx(iconKey) {\n if (!iconKey) {\n (0, warning_1.default)(false, 'not a valid icon key:' + iconKey);\n return [];\n }\n let lastIndex = this._ktIconPrefixes.length;\n while (!this._iconMap[this._ktIconPrefixes[--lastIndex]][iconKey]) {\n if (lastIndex === 0) {\n break;\n }\n }\n const iconValue = this._iconMap[this._ktIconPrefixes[lastIndex]][iconKey];\n if (!iconValue) {\n (0, warning_1.default)(false, '
|
|
5828
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.iconManager = exports.defaultIconMap = exports.defaultIconfont = void 0;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\nconst warning_1 = tslib_1.__importDefault(__webpack_require__(/*! ../../utils/warning */ \"./src/utils/warning.ts\"));\nconst iconMap_1 = __webpack_require__(/*! ./iconMap */ \"./src/icon/iconfont/iconMap.ts\");\nObject.defineProperty(exports, \"defaultIconfont\", ({ enumerable: true, get: function () { return iconMap_1.defaultIconfont; } }));\n/**\n * 以下为 typo 的字体,做一定兼容\n * key 为 iconName enum, value 为 icon className\n */\nconst typoIconMap = {\n 'search-close': 'close-square',\n 'fold': 'collapse-all',\n 'setting-general': 'setting',\n 'setting-file': 'file-text',\n 'setting-extension': 'extension',\n 'run-debug': 'start',\n 'toggle-breakpoints': 'deactivate-breakpoints',\n // new typos issue\n 'withdraw': 'fallback',\n 'terminate1': 'stop',\n 'stop1': 'stop',\n 'add': 'plus',\n // removed duplicated icons\n 'rundebug': 'start',\n 'terminate': 'stop',\n};\nconst _defaultIconAndTypoIconMap = Object.assign({}, iconMap_1.defaultIconfont, typoIconMap);\nexports.defaultIconMap = new Proxy(_defaultIconAndTypoIconMap, {\n get(obj, prop) {\n const typoValue = typoIconMap[prop];\n (0, warning_1.default)(!typoValue, `Icon '${prop}' was a typo, please use '${typoValue}' instead`);\n return obj[prop];\n },\n});\nclass IconManager {\n constructor() {\n this._ktIconPrefixes = [];\n this._iconMap = {};\n }\n update(prefix, customIconMap) {\n this._iconMap[prefix] = customIconMap;\n this._ktIconPrefixes.push(prefix);\n }\n getIconClx(iconKey) {\n if (!iconKey) {\n (0, warning_1.default)(false, 'not a valid icon key:' + iconKey);\n return [];\n }\n let lastIndex = this._ktIconPrefixes.length;\n while (!this._iconMap[this._ktIconPrefixes[--lastIndex]][iconKey]) {\n if (lastIndex === 0) {\n break;\n }\n }\n const iconValue = this._iconMap[this._ktIconPrefixes[lastIndex]][iconKey];\n if (!iconValue) {\n (0, warning_1.default)(false, '图标库缺失图标:' + iconKey);\n return [];\n }\n return [`${this._ktIconPrefixes[lastIndex]}${iconValue}`];\n }\n}\nexports.iconManager = new IconManager();\nconst defaultKtIconPrefix = 'kaitian-icon kticon-';\n// 将 default 的部分先配置进去\nexports.iconManager.update(defaultKtIconPrefix, exports.defaultIconMap);\n\n\n//# sourceURL=webpack://@opensumi/ide-components/./src/icon/iconfont/iconManager.ts?");
|
|
5829
5829
|
|
|
5830
5830
|
/***/ }),
|
|
5831
5831
|
|
|
@@ -6298,7 +6298,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
6298
6298
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
6299
6299
|
|
|
6300
6300
|
"use strict";
|
|
6301
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.CompositeTreeNode = exports.TreeNode = exports.BranchOperatorStatus = void 0;\nexports.spliceArray = spliceArray;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\n/* eslint-disable @typescript-eslint/prefer-for-of */\nconst ide_utils_1 = __webpack_require__(/*! @opensumi/ide-utils */ \"../utils/lib/index.js\");\nconst types_1 = __webpack_require__(/*! ../types */ \"./src/recycle-tree/types/index.ts\");\nconst { Path } = ide_utils_1.path;\n/**\n * 裁剪数组\n *\n * @param arr 裁剪数组\n * @param start 起始位置\n * @param deleteCount 删除或替换位置\n * @param items 插入的数组\n */\nfunction spliceArray(arr, start, deleteCount = 0, items) {\n // 如果没有修改操作,直接返回原数组\n if (deleteCount === 0 && (!items || items.length === 0)) {\n return arr;\n }\n // 直接使用 slice + concat 避免 spread operator\n const before = arr.slice(0, start);\n const after = arr.slice(start + deleteCount);\n return before.concat(items || []).concat(after);\n}\nvar BranchOperatorStatus;\n(function (BranchOperatorStatus) {\n BranchOperatorStatus[BranchOperatorStatus[\"EXPANDED\"] = 1] = \"EXPANDED\";\n BranchOperatorStatus[BranchOperatorStatus[\"SHRINKED\"] = 2] = \"SHRINKED\";\n})(BranchOperatorStatus || (exports.BranchOperatorStatus = BranchOperatorStatus = {}));\nclass TreeNode {\n static is(node) {\n return !!node && 'depth' in node && 'name' in node && 'path' in node && 'id' in node;\n }\n static getTreeNodeById(id) {\n return TreeNode.idToTreeNode.get(id);\n }\n static getTreeNodeByPath(path) {\n return TreeNode.pathToTreeNode.get(path);\n }\n static setTreeNode(id, path, node) {\n TreeNode.idToTreeNode.set(id, node);\n TreeNode.pathToTreeNode.set(path, node);\n }\n static removeTreeNode(id, path) {\n TreeNode.idToTreeNode.delete(id);\n TreeNode.pathToTreeNode.delete(path);\n }\n static getIdByPath(path) {\n return TreeNode.pathToId.get(path);\n }\n static setIdByPath(path, id) {\n return TreeNode.pathToId.set(path, id);\n }\n static getGlobalTreeState(path) {\n let state = TreeNode.pathToGlobalTreeState.get(path);\n if (!state) {\n state = {\n isExpanding: false,\n isLoadingPath: false,\n isRefreshing: false,\n refreshCancelToken: new ide_utils_1.CancellationTokenSource(),\n loadPathCancelToken: new ide_utils_1.CancellationTokenSource(),\n };\n }\n return state;\n }\n static setGlobalTreeState(path, updateState) {\n let state = TreeNode.pathToGlobalTreeState.get(path);\n if (!state) {\n state = {\n isExpanding: false,\n isLoadingPath: false,\n isRefreshing: false,\n refreshCancelToken: new ide_utils_1.CancellationTokenSource(),\n loadPathCancelToken: new ide_utils_1.CancellationTokenSource(),\n };\n }\n state = Object.assign(Object.assign({}, state), updateState);\n TreeNode.pathToGlobalTreeState.set(path, state);\n return state;\n }\n constructor(tree, parent, watcher, optionalMetadata) {\n this._uid = TreeNode.nextId();\n this._parent = parent;\n this._tree = tree;\n this._disposed = false;\n this._visible = true;\n this._metadata = Object.assign({}, (optionalMetadata || {}));\n this._depth = parent ? parent.depth + 1 : 0;\n if (watcher) {\n this._watcher = watcher;\n }\n else if (parent) {\n this._watcher = parent.watcher;\n }\n }\n get disposed() {\n return this._disposed;\n }\n /**\n * 获取基础信息\n */\n get depth() {\n return this._depth;\n }\n get parent() {\n return this._parent;\n }\n set parent(node) {\n this._parent = node;\n // 节点 `parent` 变化,更新当前节点的 `path` 属性\n this._path = '';\n }\n get type() {\n return types_1.TreeNodeType.TreeNode;\n }\n get id() {\n return this._uid;\n }\n set id(id) {\n this._uid = id;\n }\n get displayName() {\n return this.name;\n }\n /**\n * 由于 Tree 对于唯一路径的 path 的依赖\n * 在传入 `name` 值时必须保证其在路径上的唯一性\n * 一般不建议手动管理 `name`,采用默认值即可\n */\n get name() {\n if (!this.parent) {\n return `root_${this.id}`;\n }\n return this.getMetadata('name') || String(this.id);\n }\n set name(name) {\n this.addMetadata('name', name);\n // 节点 `name` 变化,更新当前节点的 `path` 属性\n this._path = '';\n }\n // 节点绝对路径\n get path() {\n if (!this._path) {\n if (!this.parent) {\n this._path = this.name.startsWith(Path.separator) ? this.name : `${Path.separator}${this.name}`;\n }\n else {\n this._path = this.name.startsWith(Path.separator)\n ? `${this.parent.path}${this.name}`\n : `${this.parent.path}${Path.separator}${this.name}`;\n }\n }\n return this._path;\n }\n get checkboxInfo() {\n return {\n checked: false,\n tooltip: '',\n accessibilityInformation: this.accessibilityInformation,\n };\n }\n get accessibilityInformation() {\n return {\n label: this.name,\n role: 'treeitem',\n };\n }\n getMetadata(withKey) {\n if (withKey === 'name' && !this._metadata[withKey]) {\n this._metadata[withKey] = String(TreeNode.nextId());\n }\n return this._metadata[withKey];\n }\n addMetadata(withKey, value) {\n if (!(withKey in this._metadata)) {\n this._metadata[withKey] = value;\n this._watcher.notifyDidChangeMetadata(this, {\n type: types_1.MetadataChangeType.Added,\n key: withKey,\n prevValue: void 0,\n value,\n });\n }\n else {\n const prevValue = this._metadata[withKey];\n this._metadata[withKey] = value;\n this._watcher.notifyDidChangeMetadata(this, { type: types_1.MetadataChangeType.Updated, key: withKey, prevValue, value });\n }\n }\n removeMetadata(withKey) {\n if (withKey in this._metadata) {\n const prevValue = this._metadata[withKey];\n delete this._metadata[withKey];\n this._watcher.notifyDidChangeMetadata(this, {\n type: types_1.MetadataChangeType.Removed,\n key: withKey,\n prevValue,\n value: void 0,\n });\n }\n }\n /**\n * 这里的move操作可能为移动,也可能为重命名\n *\n * @param {ICompositeTreeNode} to\n * @param {string} [name=this.name]\n * @returns\n * @memberof TreeNode\n */\n mv(to, name = this.name) {\n // 一个普通节点必含有父节点,根节点不允许任何操作\n const prevParent = this._parent;\n if (to === null || !CompositeTreeNode.is(to)) {\n this.parent = undefined;\n this.dispose();\n return;\n }\n const didChangeParent = prevParent !== to;\n const prevPath = this.path;\n this._depth = to.depth + 1;\n if (didChangeParent || name !== this.name) {\n this.name = name;\n if (didChangeParent) {\n this._watcher.notifyWillChangeParent(this, prevParent, to);\n }\n if (this.parent) {\n this.parent.unlinkItem(this, true);\n this.parent = to;\n this.parent.insertItem(this);\n }\n if (didChangeParent) {\n this._watcher.notifyDidChangeParent(this, prevParent, to);\n }\n }\n if (this.path !== prevPath) {\n this._watcher.notifyDidChangePath(this);\n }\n }\n get visible() {\n return this._visible;\n }\n setVisible(b) {\n this._visible = b;\n return this;\n }\n dispose() {\n if (this._disposed) {\n return;\n }\n TreeNode.removeTreeNode(this.id, this.path);\n this._disposed = true;\n this._watcher.notifyDidDispose(this);\n }\n}\nexports.TreeNode = TreeNode;\nTreeNode.nextId = (() => {\n let id = 0;\n return () => id++;\n})();\nTreeNode.idToTreeNode = new Map();\nTreeNode.pathToTreeNode = new Map();\nTreeNode.pathToId = new Map();\n// 每颗树都只会在根节点上绑定一个可取消的对象,即同个时间点只能存在一个改变树数据结构的事情\nTreeNode.pathToGlobalTreeState = new Map();\nclass CompositeTreeNode extends TreeNode {\n static defaultSortComparator(a, b) {\n if (a.constructor === b.constructor) {\n return a.name > b.name ? 1 : a.name < b.name ? -1 : 0;\n }\n return CompositeTreeNode.is(a) ? -1 : CompositeTreeNode.is(b) ? 1 : 0;\n }\n static is(node) {\n return !!node && 'children' in node;\n }\n static isRoot(node) {\n return CompositeTreeNode.is(node) && !node.parent;\n }\n generatorWatcher() {\n const emitter = new ide_utils_1.Emitter();\n const onEventChanges = emitter.event;\n const disposeCollection = new ide_utils_1.DisposableCollection();\n const terminateWatch = (path) => {\n this.watchEvents.delete(path);\n };\n const watcher = {\n notifyWillProcessWatchEvent: (target, event) => {\n emitter.fire({ type: types_1.TreeNodeEvent.WillProcessWatchEvent, args: [target, event] });\n },\n notifyWillChangeParent: (target, prevParent, newParent) => {\n emitter.fire({ type: types_1.TreeNodeEvent.WillChangeParent, args: [target, prevParent, newParent] });\n },\n notifyDidChangeParent: (target, prevParent, newParent) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangeParent, args: [target, prevParent, newParent] });\n },\n notifyDidDispose: (target) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidDispose, args: [target] });\n },\n notifyDidProcessWatchEvent: (target, event) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidProcessWatchEvent, args: [target, event] });\n },\n notifyDidChangePath: (target) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangePath, args: [target] });\n },\n notifyWillChangeExpansionState: (target, nowExpanded) => {\n const isVisible = this.isItemVisibleAtSurface(target);\n emitter.fire({ type: types_1.TreeNodeEvent.WillChangeExpansionState, args: [target, nowExpanded, isVisible] });\n },\n notifyDidChangeExpansionState: (target, nowExpanded) => {\n const isVisible = this.isItemVisibleAtSurface(target);\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangeExpansionState, args: [target, nowExpanded, isVisible] });\n },\n notifyDidChangeMetadata: (target, change) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangeMetadata, args: [target, change] });\n },\n notifyDidUpdateBranch: () => {\n emitter.fire({ type: types_1.TreeNodeEvent.BranchDidUpdate, args: [] });\n },\n notifyWillResolveChildren: (target, nowExpanded) => {\n emitter.fire({ type: types_1.TreeNodeEvent.WillResolveChildren, args: [target, nowExpanded] });\n },\n notifyDidResolveChildren: (target, nowExpanded) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidResolveChildren, args: [target, nowExpanded] });\n },\n // 监听所有事件\n on: (event, callback) => {\n const dispose = onEventChanges((data) => {\n if (data.type === event) {\n callback(...data.args);\n }\n });\n disposeCollection.push(dispose);\n return dispose;\n },\n // 监听Watch事件变化\n onWatchEvent: (path, callback) => {\n const terminator = terminateWatch;\n this.watchEvents.set(path, { terminator, callback });\n return terminator;\n },\n dispose: disposeCollection,\n };\n return watcher;\n }\n // parent 为undefined即表示该节点为根节点\n constructor(tree, parent, watcher, optionalMetadata) {\n super(tree, parent, watcher, optionalMetadata);\n this._children = null;\n this._lock = false;\n this.refreshThrottler = new ide_utils_1.ThrottledDelayer(CompositeTreeNode.REFRESH_DELAY);\n this.toRefreshPathQueue = new Set();\n /**\n * 处理 Watch 事件,同时可通过外部手动调 g用节点更新函数进行节点替换,这里为通用的事件管理\n * 如: transferItem,insertItem, unlinkItem等\n * @private\n * @memberof CompositeTreeNode\n */\n this.handleWatchEvent = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () {\n this.watcher.notifyWillProcessWatchEvent(this, event);\n switch (event.type) {\n case types_1.WatchEvent.Moved: {\n const { oldPath, newPath } = event;\n if (typeof oldPath !== 'string') {\n throw new TypeError('Expected oldPath to be a string');\n }\n if (typeof newPath !== 'string') {\n throw new TypeError('Expected newPath to be a string');\n }\n if (Path.isRelative(oldPath)) {\n throw new TypeError('oldPath must be absolute');\n }\n if (Path.isRelative(newPath)) {\n throw new TypeError('newPath must be absolute');\n }\n this.transferItem(oldPath, newPath);\n break;\n }\n case types_1.WatchEvent.Added: {\n const { node } = event;\n if (!TreeNode.is(node)) {\n throw new TypeError('Expected node to be a TreeNode');\n }\n this.insertItem(node);\n break;\n }\n case types_1.WatchEvent.Removed: {\n const { path } = event;\n const pathObject = new Path(path);\n const dirName = pathObject.dir.toString();\n const name = pathObject.base.toString();\n if (dirName === this.path && !!this.children) {\n const item = this.children.find((c) => c.name === name);\n if (item) {\n this.unlinkItem(item);\n }\n }\n break;\n }\n default:\n // 如果当前变化的节点已在数据视图(并非滚动到不可见区域)中不可见,则将该节点折叠,待下次更新即可,\n if (!this.isItemVisibleAtRootSurface(this)) {\n this.isExpanded = false;\n this._children = null;\n }\n else {\n yield this.refresh();\n }\n break;\n }\n this.watcher.notifyDidProcessWatchEvent(this, event);\n });\n this.isExpanded = parent ? false : true;\n this._branchSize = 0;\n if (!parent) {\n this.watchEvents = new Map();\n // 为根节点创建监听器\n this._watcher = this.generatorWatcher();\n this._root = this;\n TreeNode.setTreeNode(this.id, this.path, this);\n }\n else {\n this._watcher = parent.watcher;\n }\n }\n // 重载 name 的 getter/setter,路径改变时需要重新监听文件节点变化\n set name(name) {\n const prevPath = this.path;\n if (!CompositeTreeNode.isRoot(this) && typeof this.watchTerminator === 'function') {\n this.watchTerminator(prevPath);\n this.addMetadata('name', name);\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n }\n else {\n this.addMetadata('name', name);\n }\n // 节点 `name` 变化,更新当前节点的 `path` 属性\n this._path = '';\n }\n get name() {\n // 根节点保证路径不重复\n if (!this.parent) {\n return `root_${this.id}`;\n }\n return this.getMetadata('name');\n }\n // 作为根节点唯一的watcher需要在生成新节点的时候传入\n get watcher() {\n return this._watcher;\n }\n get type() {\n return types_1.TreeNodeType.CompositeTreeNode;\n }\n get children() {\n return this._children;\n }\n get expanded() {\n return this.isExpanded;\n }\n /**\n * 当前可见的分支数量\n *\n * 当节点为展开状态时,其整个分支(递归展平)由上一级的分支(根(位于数据层可见)或处于折叠状态的分支)拥有\n * 当节点为折叠状态时,其整个分支(递归展平)由其上一级父目录展开该节点\n *\n * @readonly\n * @memberof CompositeTreeNode\n */\n get branchSize() {\n return this._branchSize;\n }\n /**\n * 获取当前节点的分支数,一般为顶层节点,如Root上获取\n *\n * @readonly\n * @memberof CompositeTreeNode\n */\n get flattenedBranch() {\n return this._flattenedBranch;\n }\n get lock() {\n return this._lock;\n }\n get root() {\n if ((0, ide_utils_1.isUndefined)(this._root)) {\n this._root = this.getRoot() || null;\n }\n return this._root;\n }\n getRoot() {\n let root = this.parent;\n while (root && root.parent) {\n root = root.parent;\n }\n return root;\n }\n /**\n * 确保此\"目录\"的子级已加载(不影响\"展开\"状态)\n * 如果子级已经加载,则返回的Promise将立即解决\n * 否则,将发出重新加载请求并返回Promise\n * 一旦返回的Promise.resolve,\"CompositeTreeNode#children\" 便可以访问到对于节点\n */\n ensureLoaded(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n if (this._children) {\n return;\n }\n return yield this.hardReloadChildren(token);\n });\n }\n // 展开节点\n setExpanded() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (ensureVisible = true, quiet = false, isOwner = true, token) {\n if (this.disposed) {\n return;\n }\n // 根节点不可折叠\n if (CompositeTreeNode.isRoot(this)) {\n return;\n }\n if (this.isExpanded) {\n return;\n }\n if (isOwner) {\n const state = TreeNode.getGlobalTreeState(this.path);\n state.loadPathCancelToken.cancel();\n state.refreshCancelToken.cancel();\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: true,\n });\n }\n this.isExpanded = true;\n if (this._children === null) {\n this._watcher.notifyWillResolveChildren(this, this.isExpanded);\n yield this.hardReloadChildren(token);\n this._watcher.notifyDidResolveChildren(this, this.isExpanded);\n // 检查其是否展开;可能同时执行了 setCollapsed 方法\n if (!this.isExpanded || (token === null || token === void 0 ? void 0 : token.isCancellationRequested)) {\n if (isOwner) {\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: false,\n });\n }\n return;\n }\n }\n if (ensureVisible && this.parent && CompositeTreeNode.is(this.parent)) {\n /**\n * 在传入 ensureVisible = true 时,这里传入的 token 不能取消所有副作用\n * 故在使用 ensureVisible = true 时必须保证 `setExpanded` 与 `setCollapsed` 的独立性\n * 如需要 `await node.setExpanded(true)` 后再执行 `node.setCollapsed()`\n */\n yield this.parent.setExpanded(true, !quiet, false, token);\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n if (isOwner) {\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: false,\n });\n }\n return;\n }\n if (this.isExpanded) {\n this._watcher.notifyWillChangeExpansionState(this, true);\n // 与根节点合并分支\n this.expandBranch(this, quiet);\n this._watcher.notifyDidChangeExpansionState(this, true);\n }\n if (isOwner) {\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: false,\n });\n TreeNode.setTreeNode(this.id, this.path, this);\n }\n });\n }\n // 获取当前节点下所有展开的节点路径\n getAllExpandedNodePath() {\n var _a, _b;\n const paths = [];\n let start = 0;\n if (!CompositeTreeNode.isRoot(this)) {\n // 找到节点位置下标,向下进一步查找展开目录\n start = ((_a = this.root) === null || _a === void 0 ? void 0 : _a.getIndexAtTreeNodeId(this.id)) + 1;\n }\n const end = start + this.branchSize;\n for (let i = start; i < end; i++) {\n const node = (_b = this.root) === null || _b === void 0 ? void 0 : _b.getTreeNodeAtIndex(i);\n if (CompositeTreeNode.is(node) && node.expanded) {\n paths.push(node.path);\n }\n }\n return paths;\n }\n // 获取当前节点下所有折叠的节点路径\n getAllCollapsedNodePath() {\n let paths = [];\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n if (!CompositeTreeNode.is(child)) {\n continue;\n }\n if (child.isExpanded) {\n paths = paths.concat(child.getAllCollapsedNodePath());\n }\n else {\n paths.push(child.path);\n }\n }\n return paths;\n }\n else {\n return paths;\n }\n }\n /**\n * 处理节点数据,让节点重新加载子节点及初始化 flattenedBranch\n * @param token CancellationToken\n */\n resolveChildrens(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n let childrens = this.children;\n let expandedPaths = [];\n try {\n childrens = (yield this._tree.resolveChildren(this)) || [];\n }\n catch (e) {\n childrens = [];\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return false;\n }\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n // 如果存在上一次缓存的节点,则使用缓存节点的 ID\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n }\n (_a = this._children) === null || _a === void 0 ? void 0 : _a.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n const expandedChilds = [];\n for (let i = 0, len = ((_b = this.children) === null || _b === void 0 ? void 0 : _b.length) || 0; i < len; i++) {\n const subChild = (_c = this.children) === null || _c === void 0 ? void 0 : _c[i];\n if (CompositeTreeNode.is(subChild) && subChild.expanded) {\n const paths = yield subChild.resolveChildrens(token);\n if (paths) {\n expandedPaths = expandedPaths.concat(paths);\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n expandedChilds.push(subChild);\n }\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n return expandedPaths.concat(expandedChilds.map((child) => child.path.toString()));\n });\n }\n updateTreeNodeCache(child) {\n var _a;\n TreeNode.setTreeNode(child.id, child.path, child);\n if (CompositeTreeNode.is(child) && child.expanded && ((_a = child.children) === null || _a === void 0 ? void 0 : _a.length)) {\n for (let i = 0; i < child.children.length; i++) {\n const subChild = child.children[i];\n this.updateTreeNodeCache(subChild);\n }\n }\n }\n /**\n * 静默刷新子节点, 即不触发分支更新事件\n * @param toExpandPaths 待展开的路径\n * @param token CancellationToken\n * @param origin 当 this === origin 时,说明此节点为调用的源头节点\n */\n refreshTreeNodeByPaths() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (toExpandPaths = this.getAllExpandedNodePath(), token, origin) {\n if (!CompositeTreeNode.is(this)) {\n return;\n }\n // 如果某次刷新操作被取消,则下次刷新依旧使用上一次刷新的展开目录进行刷新\n let toExpandPath;\n const originChildren = this.children;\n let childrens = this.children || [];\n if (this.expanded) {\n if (this === origin) {\n try {\n childrens = (yield this._tree.resolveChildren(this)) || [];\n }\n catch (e) {\n childrens = [];\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n if (!this.expanded) {\n // 当请求刷新节点时,如果该节点已经不应该被处理,则清理 Children\n // 下次再被展开时便会自动更新 Children 最新内容\n if (this.children) {\n // 清理子节点,等待下次展开时更新\n if (!!this.children && this.parent) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n child.dispose();\n }\n this._children = null;\n }\n }\n return;\n }\n }\n while ((toExpandPath = toExpandPaths.shift())) {\n const isRelative = toExpandPath.indexOf(`${this.path}${Path.separator}`) > -1;\n if (!isRelative) {\n if (toExpandPath === this.path) {\n toExpandPath = undefined;\n }\n break;\n }\n const child = childrens === null || childrens === void 0 ? void 0 : childrens.find((child) => child.path === toExpandPath);\n // 对于压缩情况的路径需要额外处理一下\n // 如果这里加载的路径是 a/b/c, 有可能目前只加载到 a/b\n if (!child) {\n if (!childrens || childrens.length === 0) {\n break;\n }\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n const isInclude = toExpandPath.indexOf(`${child.path}${Path.separator}`) === 0; // 展开路径包含子节点路径\n if (isInclude && CompositeTreeNode.is(child)) {\n // 包含压缩节点的情况\n if (!CompositeTreeNode.is(child)) {\n // 说明此节点为非折叠节点时不处理\n continue;\n }\n child.isExpanded = true;\n // 加载路径包含当前判断路径,尝试加载该节点再匹配\n const extraExpandedPaths = yield child.resolveChildrens(token);\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n if (extraExpandedPaths) {\n toExpandPaths = toExpandPaths.filter((path) => !extraExpandedPaths.find((a) => a === path));\n }\n if (child.path !== toExpandPath && !toExpandPaths.includes(child.path)) {\n toExpandPaths.unshift(toExpandPath);\n }\n if (toExpandPaths.length > 0) {\n // 不需要重新加载压缩节点的子节点内容\n toExpandPaths =\n (yield child.refreshTreeNodeByPaths([...toExpandPaths], token, origin)) || [];\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n }\n break;\n }\n }\n }\n else if (CompositeTreeNode.is(child)) {\n // 如果节点默认展开,则忽略后续操作\n if (!child.expanded) {\n child.isExpanded = true;\n const extraExpandedPaths = yield child.resolveChildrens(token);\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n if (extraExpandedPaths) {\n toExpandPaths = toExpandPaths.filter((path) => !extraExpandedPaths.find((a) => a.includes(path)));\n }\n if (toExpandPaths.length > 0 && !(token === null || token === void 0 ? void 0 : token.isCancellationRequested)) {\n toExpandPaths =\n (yield child.refreshTreeNodeByPaths([...toExpandPaths], token, origin)) || [];\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n }\n }\n }\n }\n if (toExpandPath) {\n // 仍然存在需要进一步处理的待展开路径\n toExpandPaths.unshift(toExpandPath);\n if (this === origin) {\n // 说明待展开的路径已经不存在,直接处理子节点\n if (originChildren) {\n this.shrinkBranch(this, true);\n for (let i = 0; i < originChildren.length; i++) {\n const child = originChildren[i];\n child === null || child === void 0 ? void 0 : child.dispose();\n }\n }\n const expandedChilds = [];\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n // 如果存在上一次缓存的节点,则使用缓存节点的 ID\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n expandedChilds.push(child);\n }\n }\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree, true);\n this.watcher.notifyDidUpdateBranch();\n }\n if (this.parent !== origin) {\n // 将所有子节点合并至第二层 Children 上,减少后续递归拼接带来额外成本\n this.expandBranch(this, true);\n }\n return toExpandPaths;\n }\n else if (CompositeTreeNode.isRoot(this)) {\n if (this.children) {\n this.shrinkBranch(this, true);\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n child === null || child === void 0 ? void 0 : child.dispose();\n }\n }\n const expandedChilds = [];\n const otherChilds = [];\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n // 如果存在上一次缓存的节点,则使用缓存节点的 ID\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n if (!child.children) {\n yield child.resolveChildrens(token);\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n }\n expandedChilds.push(child);\n }\n else {\n otherChilds.push(child);\n }\n }\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree, true);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n this.updateTreeNodeCache(child);\n }\n for (let i = 0; i < otherChilds.length; i++) {\n const child = otherChilds[i];\n this.updateTreeNodeCache(child);\n }\n // 清理上一次监听函数\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(this.path);\n }\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n this.watcher.notifyDidUpdateBranch();\n }\n else {\n // 非根节点刷新的情况\n const expandedChilds = [];\n if (this === origin) {\n // 通知节点更新\n if (this.children) {\n // 重置旧的节点分支\n this.shrinkBranch(this, true);\n }\n if (this.children) {\n for (let i = 0, len = this.children.length; i < len; i++) {\n const child = this.children[i];\n child.dispose();\n }\n }\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0, len = childrens.length; i < len; i++) {\n const child = childrens[i];\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n expandedChilds.push(child);\n }\n this.updateTreeNodeCache(child);\n }\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n }\n else {\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n if (child.expanded) {\n expandedChilds.push(child);\n }\n }\n }\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(this.path);\n }\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n if (this === origin) {\n this.expandBranch(this);\n }\n }\n }\n else {\n // 仅需处理存在子节点的情况,否则将会影响刷新后的节点长度\n if (this.children) {\n // 清理子节点,等待下次展开时更新\n if (!!this.children && this.parent) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0, len = this.children.length; i < len; i++) {\n const child = this.children[i];\n child.dispose();\n }\n this._children = null;\n }\n }\n return;\n }\n });\n }\n expandedAll() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (collapsedPaths = this.getAllCollapsedNodePath()) {\n // 仅根节点使用\n if (!CompositeTreeNode.isRoot(this)) {\n return;\n }\n collapsedPaths = collapsedPaths.sort((a, b) => Path.pathDepth(a) - Path.pathDepth(b));\n let path;\n while (collapsedPaths.length > 0) {\n path = collapsedPaths.pop();\n const item = TreeNode.getTreeNodeByPath(path);\n if (CompositeTreeNode.is(item)) {\n yield item.setExpanded(false, true);\n }\n }\n // 通知分支树已更新\n this.watcher.notifyDidUpdateBranch();\n });\n }\n collapsedAll() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (expandedPaths = this.getAllExpandedNodePath()) {\n // 仅根节点使用\n if (!CompositeTreeNode.isRoot(this)) {\n return;\n }\n expandedPaths = expandedPaths.sort((a, b) => Path.pathDepth(a) - Path.pathDepth(b));\n let path;\n while (expandedPaths.length > 0) {\n path = expandedPaths.pop();\n const item = TreeNode.getTreeNodeByPath(path);\n if (CompositeTreeNode.is(item)) {\n item.setCollapsed(true);\n }\n }\n // 通知分支树已更新\n this.watcher.notifyDidUpdateBranch();\n });\n }\n // 折叠节点\n setCollapsed(quiet = false) {\n // 根节点不可折叠\n if (CompositeTreeNode.isRoot(this) || this.disposed) {\n return;\n }\n if (!this.isExpanded) {\n return;\n }\n const state = TreeNode.getGlobalTreeState(this.path);\n if (state.isExpanding) {\n // 当节点处于加载子节点过程时,尽管为展开状态,但此时不应该支持折叠节点\n return;\n }\n state.loadPathCancelToken.cancel();\n state.refreshCancelToken.cancel();\n this._watcher.notifyWillChangeExpansionState(this, false);\n if (this._children && this.parent) {\n // 从根节点裁剪分支\n this.shrinkBranch(this, quiet);\n }\n this.isExpanded = false;\n TreeNode.setTreeNode(this.id, this.path, this);\n this._watcher.notifyDidChangeExpansionState(this, false);\n }\n mv(to, name = this.name) {\n const prevPath = this.path;\n super.mv(to, name);\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(prevPath);\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n }\n // 同时移动过子节点\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n child.mv(child.parent, child.name);\n }\n }\n }\n /**\n * 在节点中插入新的节点\n *\n * 直接调用此方法将不会触发onWillHandleWatchEvent和onDidHandleWatchEvent事件\n */\n insertItem(item) {\n if (item.parent !== this) {\n item.mv(this, item.name);\n return;\n }\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n // path / id 是节点唯一标识\n if (this.children[i].path === item.path) {\n this.children[i] = item;\n return;\n }\n }\n }\n const branchSizeIncrease = 1 + (item instanceof CompositeTreeNode && item.expanded ? item._branchSize : 0);\n if (this._children) {\n this._children.push(item);\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n }\n this._branchSize += branchSizeIncrease;\n let master = this;\n // 如果该节点无叶子节点,则继续往上查找合适的插入位置\n while (!master._flattenedBranch) {\n if (master.parent) {\n master = master.parent;\n master._branchSize += branchSizeIncrease;\n }\n }\n if (!this._children) {\n return;\n }\n let relativeInsertionIndex = this._children.indexOf(item);\n let absInsertionIndex;\n const leadingSibling = this._children[relativeInsertionIndex - 1];\n if (leadingSibling) {\n const siblingIdx = master._flattenedBranch.indexOf(leadingSibling.id);\n relativeInsertionIndex =\n siblingIdx +\n (leadingSibling instanceof CompositeTreeNode && leadingSibling.expanded ? leadingSibling._branchSize : 0);\n }\n else {\n relativeInsertionIndex = master._flattenedBranch.indexOf(this.id);\n }\n if (relativeInsertionIndex === -1) {\n if (this._branchSize === 1) {\n // 在空Tree中插入节点时,相对插入位置为0\n relativeInsertionIndex = 0;\n }\n }\n // 非空Tree情况下需要+1,为了容纳自身节点位置,在插入节点下方插入新增节点\n absInsertionIndex = relativeInsertionIndex + 1;\n // 空 Tree 情况下需要重置为 0,避免设置 Uint32Array 时超出范围\n if (master._flattenedBranch.length === 0) {\n absInsertionIndex = 0;\n }\n let branch = [item.id];\n if (item instanceof CompositeTreeNode && item.expanded && item._flattenedBranch) {\n branch = branch.concat(item._flattenedBranch);\n item.setFlattenedBranch(null);\n }\n master.setFlattenedBranch(spliceArray(master._flattenedBranch, absInsertionIndex, 0, branch));\n TreeNode.setTreeNode(item.id, item.path, item);\n return item;\n }\n /**\n * 从父节点中移除节点\n *\n * 直接调用此方法将不会触发onWillHandleWatchEvent和onDidHandleWatchEvent事件\n */\n unlinkItem(item, reparenting) {\n var _a;\n if (!this._children) {\n return;\n }\n const idx = this._children.indexOf(item);\n if (idx === -1) {\n return;\n }\n // 当删除时父节点已不存在界面上时,跳过插入操作\n if (!this.isItemVisibleAtRootSurface(this)) {\n return;\n }\n (_a = this._children) === null || _a === void 0 ? void 0 : _a.splice(idx, 1);\n const branchSizeDecrease = 1 + (item instanceof CompositeTreeNode && item.expanded ? item._branchSize : 0);\n this._branchSize -= branchSizeDecrease;\n // 逐级往上查找节点的父节点,并沿途裁剪分支数\n let master = this;\n while (!master._flattenedBranch) {\n if (master.parent) {\n master = master.parent;\n master._branchSize -= branchSizeDecrease;\n }\n }\n const removalBeginIdx = master._flattenedBranch.indexOf(item.id);\n if (removalBeginIdx === -1) {\n return;\n }\n if (item instanceof CompositeTreeNode && item.expanded) {\n item.setFlattenedBranch(master._flattenedBranch.slice(removalBeginIdx + 1, removalBeginIdx + branchSizeDecrease));\n }\n master.setFlattenedBranch(spliceArray(master._flattenedBranch, removalBeginIdx, branchSizeDecrease));\n if (!reparenting && item.parent === this) {\n item.mv(null);\n }\n }\n /**\n * 转换节点路径\n */\n transferItem(oldPath, newPath) {\n var _a;\n const oldP = new Path(oldPath);\n const from = oldP.dir.toString();\n if (from !== this.path) {\n return;\n }\n const name = oldP.base.toString();\n const item = (_a = this._children) === null || _a === void 0 ? void 0 : _a.find((c) => c.name === name);\n if (!item) {\n return;\n }\n const newP = new Path(newPath);\n const to = newP.dir.toString();\n const destDir = to === from ? this : TreeNode.getTreeNodeByPath(to);\n if (!CompositeTreeNode.is(destDir)) {\n this.unlinkItem(item);\n return;\n }\n item.mv(destDir, newP.base.toString());\n return item;\n }\n dispose() {\n // 如果存在对应文件路径下的监听,同样需要清理掉\n if (this.watchEvents) {\n const watcher = this.watchEvents.get(this.path);\n if (watcher) {\n watcher.terminator();\n }\n this.watchEvents.clear();\n }\n if (this._children) {\n // 移除后应该折叠,因为下次初始化默认值为折叠,否则将会导致下次插入异常\n this.isExpanded = false;\n this._children.forEach((child) => {\n child.dispose();\n });\n this._children = null;\n this._flattenedBranch = null;\n }\n super.dispose();\n }\n /**\n * 设置扁平化的分支信息\n */\n setFlattenedBranch(leaves, withoutNotify) {\n this._flattenedBranch = leaves;\n // Root节点才通知更新\n if (CompositeTreeNode.isRoot(this) && !withoutNotify) {\n this.watcher.notifyDidUpdateBranch();\n }\n }\n /**\n * 展开分支节点\n * @param branch 分支节点\n */\n expandBranch(branch, withoutNotify) {\n if (this !== branch) {\n // 但节点为展开状态时进行裁剪\n if (branch._flattenedBranch) {\n this._branchSize += branch._branchSize;\n }\n }\n // 当前节点为折叠状态,更新分支信息\n if (this !== branch && this._flattenedBranch) {\n const injectionStartIdx = this._flattenedBranch.indexOf(branch.id) + 1;\n if (injectionStartIdx === 0) {\n // 中途发生了branch更新事件,此时的_flattenedBranch可能已被更新,即查找不到branch.id\n // 这种情况在父节点发生了多路径目录的创建定位动作下更易复现\n // 例:文件树在执行a/b/c定位操作时需要请求三次数据,而更新操作可能只需要一次\n // 导致就算更新操作后置执行,也可能比定位操作先执行完,同时将_flattenedBranch更新\n // 最终导致此处查询不到对应节点,下面的shrinkBranch同样可能有相同问题,如点击折叠全部功能时\n return;\n }\n this.setFlattenedBranch(spliceArray(this._flattenedBranch, injectionStartIdx, 0, branch._flattenedBranch), withoutNotify);\n // 取消展开分支对于分支的所有权,即最终只会有顶部Root拥有所有分支信息\n branch.setFlattenedBranch(null, withoutNotify);\n }\n else if (this.parent) {\n this.parent.expandBranch(branch, withoutNotify);\n }\n }\n /**\n * 清理分支节点\n * @param branch 分支节点\n */\n shrinkBranch(branch, withoutNotify) {\n if (this !== branch) {\n // 这里的`this`实际上为父节点\n // `this`的分支大小没有改变,仍然具有相同数量的叶子,但是从父级参照系(即根节点)来看,其分支缩小了\n this._branchSize -= branch._branchSize;\n }\n if (this !== branch && this._flattenedBranch) {\n const removalStartIdx = this._flattenedBranch.indexOf(branch.id) + 1;\n if (removalStartIdx === 0) {\n // 中途发生了branch更新事件,此时的_flattenedBranch可能已被更新,即查找不到branch.id\n return;\n }\n // 返回分支对于分支信息所有权,即将折叠的节点信息再次存储于折叠了的节点中\n branch.setFlattenedBranch(this._flattenedBranch.slice(removalStartIdx, removalStartIdx + branch._branchSize), withoutNotify);\n this.setFlattenedBranch(spliceArray(this._flattenedBranch, removalStartIdx, branch._flattenedBranch ? branch._flattenedBranch.length : 0), withoutNotify);\n }\n else if (this.parent) {\n this.parent.shrinkBranch(branch, withoutNotify);\n }\n }\n /**\n * 加载子节点信息\n * 当返回值为 true 时,正常加载完子节点并同步到数据结构中\n * 返回值为 false 时,加载节点的过程被中断\n *\n * @memberof CompositeTreeNode\n */\n hardReloadChildren(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n let rawItems;\n const oldPath = this.path;\n try {\n // ! `this.path` maybe changed after `resolveChildren` in file tree compact mode\n rawItems = (yield this._tree.resolveChildren(this)) || [];\n }\n catch (e) {\n rawItems = [];\n }\n // 当获取到新的子节点时,如果当前节点正处于非展开状态时,忽略后续裁切逻辑\n // 后续的 expandBranch 也不应该被响应\n if (!this.expanded || (token === null || token === void 0 ? void 0 : token.isCancellationRequested)) {\n return false;\n }\n if (this.path !== oldPath) {\n // do some clean up\n TreeNode.setGlobalTreeState(oldPath, {\n isExpanding: false,\n isLoadingPath: false,\n isRefreshing: false,\n });\n }\n const expandedChilds = [];\n const flatTree = new Array(rawItems.length);\n const tempChildren = new Array(rawItems.length);\n for (let i = 0; i < rawItems.length; i++) {\n const child = rawItems[i];\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n tempChildren[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n if (!child.children) {\n yield child.resolveChildrens(token);\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return false;\n }\n expandedChilds.push(child);\n }\n }\n tempChildren.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < rawItems.length; i++) {\n flatTree[i] = tempChildren[i].id;\n }\n if (this.children) {\n this.shrinkBranch(this);\n }\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n // The Child maybe `undefined`.\n child === null || child === void 0 ? void 0 : child.dispose();\n }\n }\n for (let i = 0; i < tempChildren.length; i++) {\n this.updateTreeNodeCache(tempChildren[i]);\n }\n this._children = tempChildren;\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n // 清理上一次监听函数\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(this.path);\n }\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n return true;\n });\n }\n moveNode(oldPath, newPath) {\n if (typeof oldPath !== 'string') {\n throw new TypeError('Expected oldPath to be a string');\n }\n if (typeof newPath !== 'string') {\n throw new TypeError('Expected newPath to be a string');\n }\n if (Path.isRelative(oldPath)) {\n throw new TypeError('oldPath must be absolute');\n }\n if (Path.isRelative(newPath)) {\n throw new TypeError('newPath must be absolute');\n }\n return this.transferItem(oldPath, newPath);\n }\n addNode(node) {\n if (!TreeNode.is(node)) {\n throw new TypeError('Expected node to be a TreeNode');\n }\n return this.insertItem(node);\n }\n removeNode(path) {\n const pathObject = new Path(path);\n const dirName = pathObject.dir.toString();\n const name = pathObject.base.toString();\n if (dirName === this.path && !!this.children) {\n const item = this.children.find((c) => c.name === name);\n if (item) {\n this.unlinkItem(item);\n }\n }\n }\n // 当没有传入具体路径时,使用当前展开目录作为刷新路径\n refresh(tokenSource, target) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n if (!CompositeTreeNode.isRoot(this)) {\n // 刷新操作只能从根节点进行,便于对重复的刷新操作进行合并\n return yield this.root.refresh(tokenSource, this);\n }\n const state = TreeNode.getGlobalTreeState(this.path);\n if (state.isLoadingPath || state.isExpanding) {\n return;\n }\n let token;\n if (tokenSource && !tokenSource.token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isRefreshing: true,\n refreshCancelToken: tokenSource,\n });\n token = tokenSource.token;\n }\n else {\n if (state.refreshCancelToken.token.isCancellationRequested) {\n const refreshCancelToken = new ide_utils_1.CancellationTokenSource();\n TreeNode.setGlobalTreeState(this.path, {\n isRefreshing: true,\n refreshCancelToken,\n });\n token = refreshCancelToken.token;\n }\n else {\n token = state.refreshCancelToken.token;\n }\n }\n this.toRefreshPathQueue.add((target || this).path);\n yield this.refreshThrottler.trigger(() => this.doRefresh(token));\n TreeNode.setGlobalTreeState(this.path, {\n isRefreshing: false,\n });\n });\n }\n doRefresh(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n const target = this.getRefreshNode() || this;\n if (!CompositeTreeNode.is(target)) {\n return;\n }\n const paths = target.getAllExpandedNodePath();\n yield target.refreshTreeNodeByPaths(paths, token, target);\n });\n }\n getRefreshNode() {\n let paths = Array.from(this.toRefreshPathQueue);\n this.toRefreshPathQueue.clear();\n if (!paths.length) {\n return this.root;\n }\n // 根据路径层级深度进行排序\n paths = paths.sort((a, b) => {\n const depthA = Path.pathDepth(a);\n const depthB = Path.pathDepth(b);\n return depthA - depthB;\n });\n if (paths.length === 1 || Path.pathDepth(paths[0]) === 1) {\n // 说明刷新队列中包含根节点,直接返回根节点进行刷新\n return TreeNode.getTreeNodeByPath(paths[0]);\n }\n const sortedPaths = paths.map((p) => new Path(p));\n let rootPath = sortedPaths[0];\n for (let i = 1, len = sortedPaths.length; i < len; i++) {\n if (rootPath.isEqualOrParent(sortedPaths[i])) {\n continue;\n }\n else {\n while (!rootPath.isRoot) {\n rootPath = rootPath.dir;\n if (!rootPath || rootPath.isEqualOrParent(sortedPaths[i])) {\n break;\n }\n }\n }\n }\n if (rootPath) {\n return TreeNode.getTreeNodeByPath(rootPath.toString());\n }\n return this.root;\n }\n isItemVisibleAtRootSurface(node) {\n let parent = node;\n while (parent.parent) {\n parent = parent.parent;\n }\n return parent.isItemVisibleAtSurface(node);\n }\n /**\n * 检查节点是否可见,而不是被隐藏在节点中\n *\n * 这里的可见并不表示节点在当前视图中可见,而是在用户滚动到特定位置便可看见\n *\n * 隐藏在节点中可能的原因为其父节点中有一个以上处于折叠状态\n */\n isItemVisibleAtSurface(item) {\n if (item === this) {\n return true;\n }\n return !!this._flattenedBranch && this._flattenedBranch.indexOf(item.id) > -1;\n }\n transformToRelativePath(path) {\n const { splitPath } = Path;\n const pathFlag = splitPath(path);\n pathFlag.shift();\n return pathFlag;\n }\n /**\n * 根据路径展开节点树\n * @memberof CompositeTreeNode\n */\n loadTreeNodeByPath(path_1) {\n return tslib_1.__awaiter(this, arguments, void 0, function* (path, quiet = false) {\n if (!CompositeTreeNode.isRoot(this)) {\n return;\n }\n const state = TreeNode.getGlobalTreeState(this.path);\n if (state.isExpanding) {\n return;\n }\n state.refreshCancelToken.cancel();\n state.loadPathCancelToken.cancel();\n const loadPathCancelToken = new ide_utils_1.CancellationTokenSource();\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: true,\n loadPathCancelToken,\n });\n const token = loadPathCancelToken.token;\n const flattenedBranchChilds = [];\n const { splitPath, isRelative } = Path;\n const pathFlag = isRelative(path) ? splitPath(path) : this.transformToRelativePath(path);\n if (pathFlag.length === 0) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return this;\n }\n if (!this.children) {\n yield this.ensureLoaded(token);\n }\n if (token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n let next = this._children;\n let preItem;\n let preItemPath = '';\n let name;\n while (next && (name = pathFlag.shift())) {\n let item = next.find((c) => c.name.indexOf(name) === 0);\n if (item) {\n if (CompositeTreeNode.is(item)) {\n item._watcher.notifyWillChangeExpansionState(item, true);\n item.isExpanded = true;\n if (!item.children) {\n yield item.resolveChildrens(token);\n if (token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n }\n flattenedBranchChilds.push(item);\n item._watcher.notifyDidChangeExpansionState(item, true);\n }\n if (pathFlag.length === 0) {\n preItem = item;\n break;\n }\n }\n // 可能展开后路径发生了变化, 需要重新处理一下当前加载路径\n if (!item && preItem) {\n const compactPath = splitPath(preItem.name).slice(1);\n if (compactPath[0] === name) {\n compactPath.shift();\n while (compactPath.length > 0) {\n if (compactPath[0] === pathFlag[0]) {\n compactPath.shift();\n pathFlag.shift();\n }\n else {\n break;\n }\n }\n name = pathFlag.shift();\n item = next.find((c) => c.name.indexOf(name) === 0);\n }\n }\n // 最终加载到的路径节点\n if (!item || (!CompositeTreeNode.is(item) && pathFlag.length > 0)) {\n break;\n }\n if (CompositeTreeNode.is(item)) {\n const isCompactName = item.name.indexOf(Path.separator) > 0;\n if (isCompactName) {\n const compactPath = splitPath(item.name).slice(1);\n while (compactPath.length > 0) {\n if (compactPath[0] === pathFlag[0]) {\n compactPath.shift();\n pathFlag.shift();\n }\n else {\n break;\n }\n }\n }\n if (!item._children) {\n preItemPath = item.path;\n if (CompositeTreeNode.is(item)) {\n item.isExpanded = true;\n if (!item.children) {\n yield item.resolveChildrens(token);\n if (token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n }\n flattenedBranchChilds.push(item);\n }\n }\n if (item && pathFlag.length === 0) {\n preItem = item;\n break;\n }\n else {\n if (!!preItemPath && preItemPath !== item.path) {\n // 说明此时已发生了路径压缩,如从 a -> a/b/c\n // 需要根据路径变化移除对应的展开路径, 这里只需考虑短变长场景\n const prePaths = splitPath(preItemPath);\n const nextPaths = splitPath(item.path);\n if (nextPaths.length > prePaths.length) {\n pathFlag.splice(0, nextPaths.length - prePaths.length);\n }\n }\n next = item._children;\n preItem = item;\n }\n }\n }\n if (preItem) {\n let child;\n if (preItem.disposed) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n while ((child = flattenedBranchChilds.pop())) {\n child.expandBranch(child, true);\n if (flattenedBranchChilds.length === 0) {\n this.updateTreeNodeCache(child);\n }\n }\n if (!quiet) {\n this.watcher.notifyDidUpdateBranch();\n }\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return preItem;\n }\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n });\n }\n /**\n * 根据节点获取节点ID下标位置\n * @param {number} id\n * @returns\n * @memberof CompositeTreeNode\n */\n getIndexAtTreeNodeId(id) {\n if (this._flattenedBranch) {\n return this._flattenedBranch.indexOf(id);\n }\n return -1;\n }\n /**\n * 根据节点获取节点下标位置\n * @param {ITreeNodeOrCompositeTreeNode} node\n * @returns\n * @memberof CompositeTreeNode\n */\n getIndexAtTreeNode(node) {\n if (this._flattenedBranch) {\n return this._flattenedBranch.indexOf(node.id);\n }\n return -1;\n }\n /**\n * 根据下标位置获取节点\n * @param {number} index\n * @returns\n * @memberof CompositeTreeNode\n */\n getTreeNodeAtIndex(index) {\n var _a;\n const id = (_a = this._flattenedBranch) === null || _a === void 0 ? void 0 : _a[index];\n if (!id) {\n return undefined;\n }\n return TreeNode.getTreeNodeById(id);\n }\n /**\n * 根据节点ID获取节点\n * @param {number} id\n * @returns\n * @memberof CompositeTreeNode\n */\n getTreeNodeById(id) {\n return TreeNode.getTreeNodeById(id);\n }\n /**\n * 根据节点路径获取节点\n * @param {string} path\n * @returns\n * @memberof CompositeTreeNode\n */\n getTreeNodeByPath(path) {\n return TreeNode.getTreeNodeByPath(path);\n }\n}\nexports.CompositeTreeNode = CompositeTreeNode;\nCompositeTreeNode.REFRESH_DELAY = 200;\n\n\n//# sourceURL=webpack://@opensumi/ide-components/./src/recycle-tree/tree/TreeNode.ts?");
|
|
6301
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.CompositeTreeNode = exports.TreeNode = exports.BranchOperatorStatus = void 0;\nexports.spliceArray = spliceArray;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\n/* eslint-disable @typescript-eslint/prefer-for-of */\nconst ide_utils_1 = __webpack_require__(/*! @opensumi/ide-utils */ \"../utils/lib/index.js\");\nconst types_1 = __webpack_require__(/*! ../types */ \"./src/recycle-tree/types/index.ts\");\nconst { Path } = ide_utils_1.path;\n/**\n * 裁剪数组\n *\n * @param arr 裁剪数组\n * @param start 起始位置\n * @param deleteCount 删除或替换位置\n * @param items 插入的数组\n */\nfunction spliceArray(arr, start, deleteCount = 0, items) {\n const a = arr.slice(0);\n a.splice(start, deleteCount, ...(items || []));\n return a;\n}\nvar BranchOperatorStatus;\n(function (BranchOperatorStatus) {\n BranchOperatorStatus[BranchOperatorStatus[\"EXPANDED\"] = 1] = \"EXPANDED\";\n BranchOperatorStatus[BranchOperatorStatus[\"SHRINKED\"] = 2] = \"SHRINKED\";\n})(BranchOperatorStatus || (exports.BranchOperatorStatus = BranchOperatorStatus = {}));\nclass TreeNode {\n static is(node) {\n return !!node && 'depth' in node && 'name' in node && 'path' in node && 'id' in node;\n }\n static getTreeNodeById(id) {\n return TreeNode.idToTreeNode.get(id);\n }\n static getTreeNodeByPath(path) {\n return TreeNode.pathToTreeNode.get(path);\n }\n static setTreeNode(id, path, node) {\n TreeNode.idToTreeNode.set(id, node);\n TreeNode.pathToTreeNode.set(path, node);\n }\n static removeTreeNode(id, path) {\n TreeNode.idToTreeNode.delete(id);\n TreeNode.pathToTreeNode.delete(path);\n }\n static getIdByPath(path) {\n return TreeNode.pathToId.get(path);\n }\n static setIdByPath(path, id) {\n return TreeNode.pathToId.set(path, id);\n }\n static getGlobalTreeState(path) {\n let state = TreeNode.pathToGlobalTreeState.get(path);\n if (!state) {\n state = {\n isExpanding: false,\n isLoadingPath: false,\n isRefreshing: false,\n refreshCancelToken: new ide_utils_1.CancellationTokenSource(),\n loadPathCancelToken: new ide_utils_1.CancellationTokenSource(),\n };\n }\n return state;\n }\n static setGlobalTreeState(path, updateState) {\n let state = TreeNode.pathToGlobalTreeState.get(path);\n if (!state) {\n state = {\n isExpanding: false,\n isLoadingPath: false,\n isRefreshing: false,\n refreshCancelToken: new ide_utils_1.CancellationTokenSource(),\n loadPathCancelToken: new ide_utils_1.CancellationTokenSource(),\n };\n }\n state = Object.assign(Object.assign({}, state), updateState);\n TreeNode.pathToGlobalTreeState.set(path, state);\n return state;\n }\n constructor(tree, parent, watcher, optionalMetadata) {\n this._uid = TreeNode.nextId();\n this._parent = parent;\n this._tree = tree;\n this._disposed = false;\n this._visible = true;\n this._metadata = Object.assign({}, (optionalMetadata || {}));\n this._depth = parent ? parent.depth + 1 : 0;\n if (watcher) {\n this._watcher = watcher;\n }\n else if (parent) {\n this._watcher = parent.watcher;\n }\n }\n get disposed() {\n return this._disposed;\n }\n /**\n * 获取基础信息\n */\n get depth() {\n return this._depth;\n }\n get parent() {\n return this._parent;\n }\n set parent(node) {\n this._parent = node;\n // 节点 `parent` 变化,更新当前节点的 `path` 属性\n this._path = '';\n }\n get type() {\n return types_1.TreeNodeType.TreeNode;\n }\n get id() {\n return this._uid;\n }\n set id(id) {\n this._uid = id;\n }\n get displayName() {\n return this.name;\n }\n /**\n * 由于 Tree 对于唯一路径的 path 的依赖\n * 在传入 `name` 值时必须保证其在路径上的唯一性\n * 一般不建议手动管理 `name`,采用默认值即可\n */\n get name() {\n if (!this.parent) {\n return `root_${this.id}`;\n }\n return this.getMetadata('name') || String(this.id);\n }\n set name(name) {\n this.addMetadata('name', name);\n // 节点 `name` 变化,更新当前节点的 `path` 属性\n this._path = '';\n }\n // 节点绝对路径\n get path() {\n if (!this._path) {\n if (!this.parent) {\n this._path = new Path(`${Path.separator}${this.name}`).toString();\n }\n else {\n this._path = new Path(this.parent.path).join(this.name).toString();\n }\n }\n return this._path;\n }\n get checkboxInfo() {\n return {\n checked: false,\n tooltip: '',\n accessibilityInformation: this.accessibilityInformation,\n };\n }\n get accessibilityInformation() {\n return {\n label: this.name,\n role: 'treeitem',\n };\n }\n getMetadata(withKey) {\n if (withKey === 'name' && !this._metadata[withKey]) {\n this._metadata[withKey] = String(TreeNode.nextId());\n }\n return this._metadata[withKey];\n }\n addMetadata(withKey, value) {\n if (!(withKey in this._metadata)) {\n this._metadata[withKey] = value;\n this._watcher.notifyDidChangeMetadata(this, {\n type: types_1.MetadataChangeType.Added,\n key: withKey,\n prevValue: void 0,\n value,\n });\n }\n else {\n const prevValue = this._metadata[withKey];\n this._metadata[withKey] = value;\n this._watcher.notifyDidChangeMetadata(this, { type: types_1.MetadataChangeType.Updated, key: withKey, prevValue, value });\n }\n }\n removeMetadata(withKey) {\n if (withKey in this._metadata) {\n const prevValue = this._metadata[withKey];\n delete this._metadata[withKey];\n this._watcher.notifyDidChangeMetadata(this, {\n type: types_1.MetadataChangeType.Removed,\n key: withKey,\n prevValue,\n value: void 0,\n });\n }\n }\n /**\n * 这里的move操作可能为移动,也可能为重命名\n *\n * @param {ICompositeTreeNode} to\n * @param {string} [name=this.name]\n * @returns\n * @memberof TreeNode\n */\n mv(to, name = this.name) {\n // 一个普通节点必含有父节点,根节点不允许任何操作\n const prevParent = this._parent;\n if (to === null || !CompositeTreeNode.is(to)) {\n this.parent = undefined;\n this.dispose();\n return;\n }\n const didChangeParent = prevParent !== to;\n const prevPath = this.path;\n this._depth = to.depth + 1;\n if (didChangeParent || name !== this.name) {\n this.name = name;\n if (didChangeParent) {\n this._watcher.notifyWillChangeParent(this, prevParent, to);\n }\n if (this.parent) {\n this.parent.unlinkItem(this, true);\n this.parent = to;\n this.parent.insertItem(this);\n }\n if (didChangeParent) {\n this._watcher.notifyDidChangeParent(this, prevParent, to);\n }\n }\n if (this.path !== prevPath) {\n this._watcher.notifyDidChangePath(this);\n }\n }\n get visible() {\n return this._visible;\n }\n setVisible(b) {\n this._visible = b;\n return this;\n }\n dispose() {\n if (this._disposed) {\n return;\n }\n TreeNode.removeTreeNode(this.id, this.path);\n this._disposed = true;\n this._watcher.notifyDidDispose(this);\n }\n}\nexports.TreeNode = TreeNode;\nTreeNode.nextId = (() => {\n let id = 0;\n return () => id++;\n})();\nTreeNode.idToTreeNode = new Map();\nTreeNode.pathToTreeNode = new Map();\nTreeNode.pathToId = new Map();\n// 每颗树都只会在根节点上绑定一个可取消的对象,即同个时间点只能存在一个改变树数据结构的事情\nTreeNode.pathToGlobalTreeState = new Map();\nclass CompositeTreeNode extends TreeNode {\n static defaultSortComparator(a, b) {\n if (a.constructor === b.constructor) {\n return a.name > b.name ? 1 : a.name < b.name ? -1 : 0;\n }\n return CompositeTreeNode.is(a) ? -1 : CompositeTreeNode.is(b) ? 1 : 0;\n }\n static is(node) {\n return !!node && 'children' in node;\n }\n static isRoot(node) {\n return CompositeTreeNode.is(node) && !node.parent;\n }\n generatorWatcher() {\n const emitter = new ide_utils_1.Emitter();\n const onEventChanges = emitter.event;\n const disposeCollection = new ide_utils_1.DisposableCollection();\n const terminateWatch = (path) => {\n this.watchEvents.delete(path);\n };\n const watcher = {\n notifyWillProcessWatchEvent: (target, event) => {\n emitter.fire({ type: types_1.TreeNodeEvent.WillProcessWatchEvent, args: [target, event] });\n },\n notifyWillChangeParent: (target, prevParent, newParent) => {\n emitter.fire({ type: types_1.TreeNodeEvent.WillChangeParent, args: [target, prevParent, newParent] });\n },\n notifyDidChangeParent: (target, prevParent, newParent) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangeParent, args: [target, prevParent, newParent] });\n },\n notifyDidDispose: (target) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidDispose, args: [target] });\n },\n notifyDidProcessWatchEvent: (target, event) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidProcessWatchEvent, args: [target, event] });\n },\n notifyDidChangePath: (target) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangePath, args: [target] });\n },\n notifyWillChangeExpansionState: (target, nowExpanded) => {\n const isVisible = this.isItemVisibleAtSurface(target);\n emitter.fire({ type: types_1.TreeNodeEvent.WillChangeExpansionState, args: [target, nowExpanded, isVisible] });\n },\n notifyDidChangeExpansionState: (target, nowExpanded) => {\n const isVisible = this.isItemVisibleAtSurface(target);\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangeExpansionState, args: [target, nowExpanded, isVisible] });\n },\n notifyDidChangeMetadata: (target, change) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidChangeMetadata, args: [target, change] });\n },\n notifyDidUpdateBranch: () => {\n emitter.fire({ type: types_1.TreeNodeEvent.BranchDidUpdate, args: [] });\n },\n notifyWillResolveChildren: (target, nowExpanded) => {\n emitter.fire({ type: types_1.TreeNodeEvent.WillResolveChildren, args: [target, nowExpanded] });\n },\n notifyDidResolveChildren: (target, nowExpanded) => {\n emitter.fire({ type: types_1.TreeNodeEvent.DidResolveChildren, args: [target, nowExpanded] });\n },\n // 监听所有事件\n on: (event, callback) => {\n const dispose = onEventChanges((data) => {\n if (data.type === event) {\n callback(...data.args);\n }\n });\n disposeCollection.push(dispose);\n return dispose;\n },\n // 监听Watch事件变化\n onWatchEvent: (path, callback) => {\n const terminator = terminateWatch;\n this.watchEvents.set(path, { terminator, callback });\n return terminator;\n },\n dispose: disposeCollection,\n };\n return watcher;\n }\n // parent 为undefined即表示该节点为根节点\n constructor(tree, parent, watcher, optionalMetadata) {\n super(tree, parent, watcher, optionalMetadata);\n this._children = null;\n this._lock = false;\n this.refreshThrottler = new ide_utils_1.ThrottledDelayer(CompositeTreeNode.REFRESH_DELAY);\n this.toRefreshPathQueue = new Set();\n /**\n * 处理 Watch 事件,同时可通过外部手动调 g用节点更新函数进行节点替换,这里为通用的事件管理\n * 如: transferItem,insertItem, unlinkItem等\n * @private\n * @memberof CompositeTreeNode\n */\n this.handleWatchEvent = (event) => tslib_1.__awaiter(this, void 0, void 0, function* () {\n this.watcher.notifyWillProcessWatchEvent(this, event);\n switch (event.type) {\n case types_1.WatchEvent.Moved: {\n const { oldPath, newPath } = event;\n if (typeof oldPath !== 'string') {\n throw new TypeError('Expected oldPath to be a string');\n }\n if (typeof newPath !== 'string') {\n throw new TypeError('Expected newPath to be a string');\n }\n if (Path.isRelative(oldPath)) {\n throw new TypeError('oldPath must be absolute');\n }\n if (Path.isRelative(newPath)) {\n throw new TypeError('newPath must be absolute');\n }\n this.transferItem(oldPath, newPath);\n break;\n }\n case types_1.WatchEvent.Added: {\n const { node } = event;\n if (!TreeNode.is(node)) {\n throw new TypeError('Expected node to be a TreeNode');\n }\n this.insertItem(node);\n break;\n }\n case types_1.WatchEvent.Removed: {\n const { path } = event;\n const pathObject = new Path(path);\n const dirName = pathObject.dir.toString();\n const name = pathObject.base.toString();\n if (dirName === this.path && !!this.children) {\n const item = this.children.find((c) => c.name === name);\n if (item) {\n this.unlinkItem(item);\n }\n }\n break;\n }\n default:\n // 如果当前变化的节点已在数据视图(并非滚动到不可见区域)中不可见,则将该节点折叠,待下次更新即可,\n if (!this.isItemVisibleAtRootSurface(this)) {\n this.isExpanded = false;\n this._children = null;\n }\n else {\n yield this.refresh();\n }\n break;\n }\n this.watcher.notifyDidProcessWatchEvent(this, event);\n });\n this.isExpanded = parent ? false : true;\n this._branchSize = 0;\n if (!parent) {\n this.watchEvents = new Map();\n // 为根节点创建监听器\n this._watcher = this.generatorWatcher();\n this._root = this;\n TreeNode.setTreeNode(this.id, this.path, this);\n }\n else {\n this._watcher = parent.watcher;\n }\n }\n // 重载 name 的 getter/setter,路径改变时需要重新监听文件节点变化\n set name(name) {\n const prevPath = this.path;\n if (!CompositeTreeNode.isRoot(this) && typeof this.watchTerminator === 'function') {\n this.watchTerminator(prevPath);\n this.addMetadata('name', name);\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n }\n else {\n this.addMetadata('name', name);\n }\n // 节点 `name` 变化,更新当前节点的 `path` 属性\n this._path = '';\n }\n get name() {\n // 根节点保证路径不重复\n if (!this.parent) {\n return `root_${this.id}`;\n }\n return this.getMetadata('name');\n }\n // 作为根节点唯一的watcher需要在生成新节点的时候传入\n get watcher() {\n return this._watcher;\n }\n get type() {\n return types_1.TreeNodeType.CompositeTreeNode;\n }\n get children() {\n return this._children;\n }\n get expanded() {\n return this.isExpanded;\n }\n /**\n * 当前可见的分支数量\n *\n * 当节点为展开状态时,其整个分支(递归展平)由上一级的分支(根(位于数据层可见)或处于折叠状态的分支)拥有\n * 当节点为折叠状态时,其整个分支(递归展平)由其上一级父目录展开该节点\n *\n * @readonly\n * @memberof CompositeTreeNode\n */\n get branchSize() {\n return this._branchSize;\n }\n /**\n * 获取当前节点的分支数,一般为顶层节点,如Root上获取\n *\n * @readonly\n * @memberof CompositeTreeNode\n */\n get flattenedBranch() {\n return this._flattenedBranch;\n }\n get lock() {\n return this._lock;\n }\n get root() {\n if ((0, ide_utils_1.isUndefined)(this._root)) {\n this._root = this.getRoot() || null;\n }\n return this._root;\n }\n getRoot() {\n let root = this.parent;\n while (root && root.parent) {\n root = root.parent;\n }\n return root;\n }\n /**\n * 确保此“目录”的子级已加载(不影响“展开”状态)\n * 如果子级已经加载,则返回的Promise将立即解决\n * 否则,将发出重新加载请求并返回Promise\n * 一旦返回的Promise.resolve,“CompositeTreeNode#children” 便可以访问到对于节点\n */\n ensureLoaded(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n if (this._children) {\n return;\n }\n return yield this.hardReloadChildren(token);\n });\n }\n // 展开节点\n setExpanded() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (ensureVisible = true, quiet = false, isOwner = true, token) {\n if (this.disposed) {\n return;\n }\n // 根节点不可折叠\n if (CompositeTreeNode.isRoot(this)) {\n return;\n }\n if (this.isExpanded) {\n return;\n }\n if (isOwner) {\n const state = TreeNode.getGlobalTreeState(this.path);\n state.loadPathCancelToken.cancel();\n state.refreshCancelToken.cancel();\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: true,\n });\n }\n this.isExpanded = true;\n if (this._children === null) {\n this._watcher.notifyWillResolveChildren(this, this.isExpanded);\n yield this.hardReloadChildren(token);\n this._watcher.notifyDidResolveChildren(this, this.isExpanded);\n // 检查其是否展开;可能同时执行了 setCollapsed 方法\n if (!this.isExpanded || (token === null || token === void 0 ? void 0 : token.isCancellationRequested)) {\n if (isOwner) {\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: false,\n });\n }\n return;\n }\n }\n if (ensureVisible && this.parent && CompositeTreeNode.is(this.parent)) {\n /**\n * 在传入 ensureVisible = true 时,这里传入的 token 不能取消所有副作用\n * 故在使用 ensureVisible = true 时必须保证 `setExpanded` 与 `setCollapsed` 的独立性\n * 如需要 `await node.setExpanded(true)` 后再执行 `node.setCollapsed()`\n */\n yield this.parent.setExpanded(true, !quiet, false, token);\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n if (isOwner) {\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: false,\n });\n }\n return;\n }\n if (this.isExpanded) {\n this._watcher.notifyWillChangeExpansionState(this, true);\n // 与根节点合并分支\n this.expandBranch(this, quiet);\n this._watcher.notifyDidChangeExpansionState(this, true);\n }\n if (isOwner) {\n TreeNode.setGlobalTreeState(this.path, {\n isExpanding: false,\n });\n TreeNode.setTreeNode(this.id, this.path, this);\n }\n });\n }\n // 获取当前节点下所有展开的节点路径\n getAllExpandedNodePath() {\n var _a, _b;\n const paths = [];\n let start = 0;\n if (!CompositeTreeNode.isRoot(this)) {\n // 找到节点位置下标,向下进一步查找展开目录\n start = ((_a = this.root) === null || _a === void 0 ? void 0 : _a.getIndexAtTreeNodeId(this.id)) + 1;\n }\n const end = start + this.branchSize;\n for (let i = start; i < end; i++) {\n const node = (_b = this.root) === null || _b === void 0 ? void 0 : _b.getTreeNodeAtIndex(i);\n if (CompositeTreeNode.is(node) && node.expanded) {\n paths.push(node.path);\n }\n }\n return paths;\n }\n // 获取当前节点下所有折叠的节点路径\n getAllCollapsedNodePath() {\n let paths = [];\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n if (!CompositeTreeNode.is(child)) {\n continue;\n }\n if (child.isExpanded) {\n paths = paths.concat(child.getAllCollapsedNodePath());\n }\n else {\n paths.push(child.path);\n }\n }\n return paths;\n }\n else {\n return paths;\n }\n }\n /**\n * 处理节点数据,让节点重新加载子节点及初始化 flattenedBranch\n * @param token CancellationToken\n */\n resolveChildrens(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n let childrens = this.children;\n let expandedPaths = [];\n try {\n childrens = (yield this._tree.resolveChildren(this)) || [];\n }\n catch (e) {\n childrens = [];\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return false;\n }\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n // 如果存在上一次缓存的节点,则使用缓存节点的 ID\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n }\n (_a = this._children) === null || _a === void 0 ? void 0 : _a.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n const expandedChilds = [];\n for (let i = 0, len = ((_b = this.children) === null || _b === void 0 ? void 0 : _b.length) || 0; i < len; i++) {\n const subChild = (_c = this.children) === null || _c === void 0 ? void 0 : _c[i];\n if (CompositeTreeNode.is(subChild) && subChild.expanded) {\n const paths = yield subChild.resolveChildrens(token);\n if (paths) {\n expandedPaths = expandedPaths.concat(paths);\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n expandedChilds.push(subChild);\n }\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n return expandedPaths.concat(expandedChilds.map((child) => child.path.toString()));\n });\n }\n updateTreeNodeCache(child) {\n var _a;\n TreeNode.setTreeNode(child.id, child.path, child);\n if (CompositeTreeNode.is(child) && child.expanded && ((_a = child.children) === null || _a === void 0 ? void 0 : _a.length)) {\n for (let i = 0; i < child.children.length; i++) {\n const subChild = child.children[i];\n this.updateTreeNodeCache(subChild);\n }\n }\n }\n /**\n * 静默刷新子节点, 即不触发分支更新事件\n * @param toExpandPaths 待展开的路径\n * @param token CancellationToken\n * @param origin 当 this === origin 时,说明此节点为调用的源头节点\n */\n refreshTreeNodeByPaths() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (toExpandPaths = this.getAllExpandedNodePath(), token, origin) {\n if (!CompositeTreeNode.is(this)) {\n return;\n }\n // 如果某次刷新操作被取消,则下次刷新依旧使用上一次刷新的展开目录进行刷新\n let toExpandPath;\n const originChildren = this.children;\n let childrens = this.children || [];\n if (this.expanded) {\n if (this === origin) {\n try {\n childrens = (yield this._tree.resolveChildren(this)) || [];\n }\n catch (e) {\n childrens = [];\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n if (!this.expanded) {\n // 当请求刷新节点时,如果该节点已经不应该被处理,则清理 Children\n // 下次再被展开时便会自动更新 Children 最新内容\n if (this.children) {\n // 清理子节点,等待下次展开时更新\n if (!!this.children && this.parent) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n child.dispose();\n }\n this._children = null;\n }\n }\n return;\n }\n }\n while ((toExpandPath = toExpandPaths.shift())) {\n const isRelative = toExpandPath.indexOf(`${this.path}${Path.separator}`) > -1;\n if (!isRelative) {\n if (toExpandPath === this.path) {\n toExpandPath = undefined;\n }\n break;\n }\n const child = childrens === null || childrens === void 0 ? void 0 : childrens.find((child) => child.path === toExpandPath);\n // 对于压缩情况的路径需要额外处理一下\n // 如果这里加载的路径是 a/b/c, 有可能目前只加载到 a/b\n if (!child) {\n if (!childrens || childrens.length === 0) {\n break;\n }\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n const isInclude = toExpandPath.indexOf(`${child.path}${Path.separator}`) === 0; // 展开路径包含子节点路径\n if (isInclude && CompositeTreeNode.is(child)) {\n // 包含压缩节点的情况\n if (!CompositeTreeNode.is(child)) {\n // 说明此节点为非折叠节点时不处理\n continue;\n }\n child.isExpanded = true;\n // 加载路径包含当前判断路径,尝试加载该节点再匹配\n const extraExpandedPaths = yield child.resolveChildrens(token);\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n if (extraExpandedPaths) {\n toExpandPaths = toExpandPaths.filter((path) => !extraExpandedPaths.find((a) => a === path));\n }\n if (child.path !== toExpandPath && !toExpandPaths.includes(child.path)) {\n toExpandPaths.unshift(toExpandPath);\n }\n if (toExpandPaths.length > 0) {\n // 不需要重新加载压缩节点的子节点内容\n toExpandPaths =\n (yield child.refreshTreeNodeByPaths([...toExpandPaths], token, origin)) || [];\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n }\n break;\n }\n }\n }\n else if (CompositeTreeNode.is(child)) {\n // 如果节点默认展开,则忽略后续操作\n if (!child.expanded) {\n child.isExpanded = true;\n const extraExpandedPaths = yield child.resolveChildrens(token);\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n if (extraExpandedPaths) {\n toExpandPaths = toExpandPaths.filter((path) => !extraExpandedPaths.find((a) => a.includes(path)));\n }\n if (toExpandPaths.length > 0 && !(token === null || token === void 0 ? void 0 : token.isCancellationRequested)) {\n toExpandPaths =\n (yield child.refreshTreeNodeByPaths([...toExpandPaths], token, origin)) || [];\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n }\n }\n }\n }\n if (toExpandPath) {\n // 仍然存在需要进一步处理的待展开路径\n toExpandPaths.unshift(toExpandPath);\n if (this === origin) {\n // 说明待展开的路径已经不存在,直接处理子节点\n if (originChildren) {\n this.shrinkBranch(this, true);\n for (let i = 0; i < originChildren.length; i++) {\n const child = originChildren[i];\n child === null || child === void 0 ? void 0 : child.dispose();\n }\n }\n const expandedChilds = [];\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n // 如果存在上一次缓存的节点,则使用缓存节点的 ID\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n expandedChilds.push(child);\n }\n }\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree, true);\n this.watcher.notifyDidUpdateBranch();\n }\n if (this.parent !== origin) {\n // 将所有子节点合并至第二层 Children 上,减少后续递归拼接带来额外成本\n this.expandBranch(this, true);\n }\n return toExpandPaths;\n }\n else if (CompositeTreeNode.isRoot(this)) {\n if (this.children) {\n this.shrinkBranch(this, true);\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n child === null || child === void 0 ? void 0 : child.dispose();\n }\n }\n const expandedChilds = [];\n const otherChilds = [];\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n // 如果存在上一次缓存的节点,则使用缓存节点的 ID\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n if (!child.children) {\n yield child.resolveChildrens(token);\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return;\n }\n }\n expandedChilds.push(child);\n }\n else {\n otherChilds.push(child);\n }\n }\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree, true);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n this.updateTreeNodeCache(child);\n }\n for (let i = 0; i < otherChilds.length; i++) {\n const child = otherChilds[i];\n this.updateTreeNodeCache(child);\n }\n // 清理上一次监听函数\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(this.path);\n }\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n this.watcher.notifyDidUpdateBranch();\n }\n else {\n // 非根节点刷新的情况\n const expandedChilds = [];\n if (this === origin) {\n // 通知节点更新\n if (this.children) {\n // 重置旧的节点分支\n this.shrinkBranch(this, true);\n }\n if (this.children) {\n for (let i = 0, len = this.children.length; i < len; i++) {\n const child = this.children[i];\n child.dispose();\n }\n }\n const flatTree = new Array(childrens.length);\n this._children = Array(childrens.length);\n for (let i = 0, len = childrens.length; i < len; i++) {\n const child = childrens[i];\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n this._children[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n expandedChilds.push(child);\n }\n this.updateTreeNodeCache(child);\n }\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < childrens.length; i++) {\n flatTree[i] = this._children[i].id;\n }\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n }\n else {\n for (let i = 0; i < childrens.length; i++) {\n const child = childrens[i];\n if (child.expanded) {\n expandedChilds.push(child);\n }\n }\n }\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(this.path);\n }\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n if (this === origin) {\n this.expandBranch(this);\n }\n }\n }\n else {\n // 仅需处理存在子节点的情况,否则将会影响刷新后的节点长度\n if (this.children) {\n // 清理子节点,等待下次展开时更新\n if (!!this.children && this.parent) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0, len = this.children.length; i < len; i++) {\n const child = this.children[i];\n child.dispose();\n }\n this._children = null;\n }\n }\n return;\n }\n });\n }\n expandedAll() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (collapsedPaths = this.getAllCollapsedNodePath()) {\n // 仅根节点使用\n if (!CompositeTreeNode.isRoot(this)) {\n return;\n }\n collapsedPaths = collapsedPaths.sort((a, b) => Path.pathDepth(a) - Path.pathDepth(b));\n let path;\n while (collapsedPaths.length > 0) {\n path = collapsedPaths.pop();\n const item = TreeNode.getTreeNodeByPath(path);\n if (CompositeTreeNode.is(item)) {\n yield item.setExpanded(false, true);\n }\n }\n // 通知分支树已更新\n this.watcher.notifyDidUpdateBranch();\n });\n }\n collapsedAll() {\n return tslib_1.__awaiter(this, arguments, void 0, function* (expandedPaths = this.getAllExpandedNodePath()) {\n // 仅根节点使用\n if (!CompositeTreeNode.isRoot(this)) {\n return;\n }\n expandedPaths = expandedPaths.sort((a, b) => Path.pathDepth(a) - Path.pathDepth(b));\n let path;\n while (expandedPaths.length > 0) {\n path = expandedPaths.pop();\n const item = TreeNode.getTreeNodeByPath(path);\n if (CompositeTreeNode.is(item)) {\n item.setCollapsed(true);\n }\n }\n // 通知分支树已更新\n this.watcher.notifyDidUpdateBranch();\n });\n }\n // 折叠节点\n setCollapsed(quiet = false) {\n // 根节点不可折叠\n if (CompositeTreeNode.isRoot(this) || this.disposed) {\n return;\n }\n if (!this.isExpanded) {\n return;\n }\n const state = TreeNode.getGlobalTreeState(this.path);\n if (state.isExpanding) {\n // 当节点处于加载子节点过程时,尽管为展开状态,但此时不应该支持折叠节点\n return;\n }\n state.loadPathCancelToken.cancel();\n state.refreshCancelToken.cancel();\n this._watcher.notifyWillChangeExpansionState(this, false);\n if (this._children && this.parent) {\n // 从根节点裁剪分支\n this.shrinkBranch(this, quiet);\n }\n this.isExpanded = false;\n TreeNode.setTreeNode(this.id, this.path, this);\n this._watcher.notifyDidChangeExpansionState(this, false);\n }\n mv(to, name = this.name) {\n const prevPath = this.path;\n super.mv(to, name);\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(prevPath);\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n }\n // 同时移动过子节点\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n child.mv(child.parent, child.name);\n }\n }\n }\n /**\n * 在节点中插入新的节点\n *\n * 直接调用此方法将不会触发onWillHandleWatchEvent和onDidHandleWatchEvent事件\n */\n insertItem(item) {\n if (item.parent !== this) {\n item.mv(this, item.name);\n return;\n }\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n // path / id 是节点唯一标识\n if (this.children[i].path === item.path) {\n this.children[i] = item;\n return;\n }\n }\n }\n const branchSizeIncrease = 1 + (item instanceof CompositeTreeNode && item.expanded ? item._branchSize : 0);\n if (this._children) {\n this._children.push(item);\n this._children.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n }\n this._branchSize += branchSizeIncrease;\n let master = this;\n // 如果该节点无叶子节点,则继续往上查找合适的插入位置\n while (!master._flattenedBranch) {\n if (master.parent) {\n master = master.parent;\n master._branchSize += branchSizeIncrease;\n }\n }\n if (!this._children) {\n return;\n }\n let relativeInsertionIndex = this._children.indexOf(item);\n let absInsertionIndex;\n const leadingSibling = this._children[relativeInsertionIndex - 1];\n if (leadingSibling) {\n const siblingIdx = master._flattenedBranch.indexOf(leadingSibling.id);\n relativeInsertionIndex =\n siblingIdx +\n (leadingSibling instanceof CompositeTreeNode && leadingSibling.expanded ? leadingSibling._branchSize : 0);\n }\n else {\n relativeInsertionIndex = master._flattenedBranch.indexOf(this.id);\n }\n if (relativeInsertionIndex === -1) {\n if (this._branchSize === 1) {\n // 在空Tree中插入节点时,相对插入位置为0\n relativeInsertionIndex = 0;\n }\n }\n // 非空Tree情况下需要+1,为了容纳自身节点位置,在插入节点下方插入新增节点\n absInsertionIndex = relativeInsertionIndex + 1;\n // 空 Tree 情况下需要重置为 0,避免设置 Uint32Array 时超出范围\n if (master._flattenedBranch.length === 0) {\n absInsertionIndex = 0;\n }\n let branch = [item.id];\n if (item instanceof CompositeTreeNode && item.expanded && item._flattenedBranch) {\n branch = branch.concat(item._flattenedBranch);\n item.setFlattenedBranch(null);\n }\n master.setFlattenedBranch(spliceArray(master._flattenedBranch, absInsertionIndex, 0, branch));\n TreeNode.setTreeNode(item.id, item.path, item);\n return item;\n }\n /**\n * 从父节点中移除节点\n *\n * 直接调用此方法将不会触发onWillHandleWatchEvent和onDidHandleWatchEvent事件\n */\n unlinkItem(item, reparenting) {\n var _a;\n if (!this._children) {\n return;\n }\n const idx = this._children.indexOf(item);\n if (idx === -1) {\n return;\n }\n // 当删除时父节点已不存在界面上时,跳过插入操作\n if (!this.isItemVisibleAtRootSurface(this)) {\n return;\n }\n (_a = this._children) === null || _a === void 0 ? void 0 : _a.splice(idx, 1);\n const branchSizeDecrease = 1 + (item instanceof CompositeTreeNode && item.expanded ? item._branchSize : 0);\n this._branchSize -= branchSizeDecrease;\n // 逐级往上查找节点的父节点,并沿途裁剪分支数\n let master = this;\n while (!master._flattenedBranch) {\n if (master.parent) {\n master = master.parent;\n master._branchSize -= branchSizeDecrease;\n }\n }\n const removalBeginIdx = master._flattenedBranch.indexOf(item.id);\n if (removalBeginIdx === -1) {\n return;\n }\n if (item instanceof CompositeTreeNode && item.expanded) {\n item.setFlattenedBranch(master._flattenedBranch.slice(removalBeginIdx + 1, removalBeginIdx + branchSizeDecrease));\n }\n master.setFlattenedBranch(spliceArray(master._flattenedBranch, removalBeginIdx, branchSizeDecrease));\n if (!reparenting && item.parent === this) {\n item.mv(null);\n }\n }\n /**\n * 转换节点路径\n */\n transferItem(oldPath, newPath) {\n var _a;\n const oldP = new Path(oldPath);\n const from = oldP.dir.toString();\n if (from !== this.path) {\n return;\n }\n const name = oldP.base.toString();\n const item = (_a = this._children) === null || _a === void 0 ? void 0 : _a.find((c) => c.name === name);\n if (!item) {\n return;\n }\n const newP = new Path(newPath);\n const to = newP.dir.toString();\n const destDir = to === from ? this : TreeNode.getTreeNodeByPath(to);\n if (!CompositeTreeNode.is(destDir)) {\n this.unlinkItem(item);\n return;\n }\n item.mv(destDir, newP.base.toString());\n return item;\n }\n dispose() {\n // 如果存在对应文件路径下的监听,同样需要清理掉\n if (this.watchEvents) {\n const watcher = this.watchEvents.get(this.path);\n if (watcher) {\n watcher.terminator();\n }\n this.watchEvents.clear();\n }\n if (this._children) {\n // 移除后应该折叠,因为下次初始化默认值为折叠,否则将会导致下次插入异常\n this.isExpanded = false;\n this._children.forEach((child) => {\n child.dispose();\n });\n this._children = null;\n this._flattenedBranch = null;\n }\n super.dispose();\n }\n /**\n * 设置扁平化的分支信息\n */\n setFlattenedBranch(leaves, withoutNotify) {\n this._flattenedBranch = leaves;\n // Root节点才通知更新\n if (CompositeTreeNode.isRoot(this) && !withoutNotify) {\n this.watcher.notifyDidUpdateBranch();\n }\n }\n /**\n * 展开分支节点\n * @param branch 分支节点\n */\n expandBranch(branch, withoutNotify) {\n if (this !== branch) {\n // 但节点为展开状态时进行裁剪\n if (branch._flattenedBranch) {\n this._branchSize += branch._branchSize;\n }\n }\n // 当前节点为折叠状态,更新分支信息\n if (this !== branch && this._flattenedBranch) {\n const injectionStartIdx = this._flattenedBranch.indexOf(branch.id) + 1;\n if (injectionStartIdx === 0) {\n // 中途发生了branch更新事件,此时的_flattenedBranch可能已被更新,即查找不到branch.id\n // 这种情况在父节点发生了多路径目录的创建定位动作下更易复现\n // 例:文件树在执行a/b/c定位操作时需要请求三次数据,而更新操作可能只需要一次\n // 导致就算更新操作后置执行,也可能比定位操作先执行完,同时将_flattenedBranch更新\n // 最终导致此处查询不到对应节点,下面的shrinkBranch同样可能有相同问题,如点击折叠全部功能时\n return;\n }\n this.setFlattenedBranch(spliceArray(this._flattenedBranch, injectionStartIdx, 0, branch._flattenedBranch), withoutNotify);\n // 取消展开分支对于分支的所有权,即最终只会有顶部Root拥有所有分支信息\n branch.setFlattenedBranch(null, withoutNotify);\n }\n else if (this.parent) {\n this.parent.expandBranch(branch, withoutNotify);\n }\n }\n /**\n * 清理分支节点\n * @param branch 分支节点\n */\n shrinkBranch(branch, withoutNotify) {\n if (this !== branch) {\n // 这里的`this`实际上为父节点\n // `this`的分支大小没有改变,仍然具有相同数量的叶子,但是从父级参照系(即根节点)来看,其分支缩小了\n this._branchSize -= branch._branchSize;\n }\n if (this !== branch && this._flattenedBranch) {\n const removalStartIdx = this._flattenedBranch.indexOf(branch.id) + 1;\n if (removalStartIdx === 0) {\n // 中途发生了branch更新事件,此时的_flattenedBranch可能已被更新,即查找不到branch.id\n return;\n }\n // 返回分支对于分支信息所有权,即将折叠的节点信息再次存储于折叠了的节点中\n branch.setFlattenedBranch(this._flattenedBranch.slice(removalStartIdx, removalStartIdx + branch._branchSize), withoutNotify);\n this.setFlattenedBranch(spliceArray(this._flattenedBranch, removalStartIdx, branch._flattenedBranch ? branch._flattenedBranch.length : 0), withoutNotify);\n }\n else if (this.parent) {\n this.parent.shrinkBranch(branch, withoutNotify);\n }\n }\n /**\n * 加载子节点信息\n * 当返回值为 true 时,正常加载完子节点并同步到数据结构中\n * 返回值为 false 时,加载节点的过程被中断\n *\n * @memberof CompositeTreeNode\n */\n hardReloadChildren(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n let rawItems;\n const oldPath = this.path;\n try {\n // ! `this.path` maybe changed after `resolveChildren` in file tree compact mode\n rawItems = (yield this._tree.resolveChildren(this)) || [];\n }\n catch (e) {\n rawItems = [];\n }\n // 当获取到新的子节点时,如果当前节点正处于非展开状态时,忽略后续裁切逻辑\n // 后续的 expandBranch 也不应该被响应\n if (!this.expanded || (token === null || token === void 0 ? void 0 : token.isCancellationRequested)) {\n return false;\n }\n if (this.path !== oldPath) {\n // do some clean up\n TreeNode.setGlobalTreeState(oldPath, {\n isExpanding: false,\n isLoadingPath: false,\n isRefreshing: false,\n });\n }\n const expandedChilds = [];\n const flatTree = new Array(rawItems.length);\n const tempChildren = new Array(rawItems.length);\n for (let i = 0; i < rawItems.length; i++) {\n const child = rawItems[i];\n child.id = TreeNode.getIdByPath(child.path) || child.id;\n tempChildren[i] = child;\n TreeNode.setIdByPath(child.path, child.id);\n if (CompositeTreeNode.is(child) && child.expanded) {\n if (!child.children) {\n yield child.resolveChildrens(token);\n }\n if (token === null || token === void 0 ? void 0 : token.isCancellationRequested) {\n return false;\n }\n expandedChilds.push(child);\n }\n }\n tempChildren.sort(this._tree.sortComparator || CompositeTreeNode.defaultSortComparator);\n for (let i = 0; i < rawItems.length; i++) {\n flatTree[i] = tempChildren[i].id;\n }\n if (this.children) {\n this.shrinkBranch(this);\n }\n if (this.children) {\n for (let i = 0; i < this.children.length; i++) {\n const child = this.children[i];\n // The Child maybe `undefined`.\n child === null || child === void 0 ? void 0 : child.dispose();\n }\n }\n for (let i = 0; i < tempChildren.length; i++) {\n this.updateTreeNodeCache(tempChildren[i]);\n }\n this._children = tempChildren;\n this._branchSize = flatTree.length;\n this.setFlattenedBranch(flatTree);\n for (let i = 0; i < expandedChilds.length; i++) {\n const child = expandedChilds[i];\n child.expandBranch(child, true);\n }\n // 清理上一次监听函数\n if (typeof this.watchTerminator === 'function') {\n this.watchTerminator(this.path);\n }\n this.watchTerminator = this.watcher.onWatchEvent(this.path, this.handleWatchEvent);\n return true;\n });\n }\n moveNode(oldPath, newPath) {\n if (typeof oldPath !== 'string') {\n throw new TypeError('Expected oldPath to be a string');\n }\n if (typeof newPath !== 'string') {\n throw new TypeError('Expected newPath to be a string');\n }\n if (Path.isRelative(oldPath)) {\n throw new TypeError('oldPath must be absolute');\n }\n if (Path.isRelative(newPath)) {\n throw new TypeError('newPath must be absolute');\n }\n return this.transferItem(oldPath, newPath);\n }\n addNode(node) {\n if (!TreeNode.is(node)) {\n throw new TypeError('Expected node to be a TreeNode');\n }\n return this.insertItem(node);\n }\n removeNode(path) {\n const pathObject = new Path(path);\n const dirName = pathObject.dir.toString();\n const name = pathObject.base.toString();\n if (dirName === this.path && !!this.children) {\n const item = this.children.find((c) => c.name === name);\n if (item) {\n this.unlinkItem(item);\n }\n }\n }\n // 当没有传入具体路径时,使用当前展开目录作为刷新路径\n refresh(tokenSource, target) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n if (!CompositeTreeNode.isRoot(this)) {\n // 刷新操作只能从根节点进行,便于对重复的刷新操作进行合并\n return yield this.root.refresh(tokenSource, this);\n }\n const state = TreeNode.getGlobalTreeState(this.path);\n if (state.isLoadingPath || state.isExpanding) {\n return;\n }\n let token;\n if (tokenSource && !tokenSource.token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isRefreshing: true,\n refreshCancelToken: tokenSource,\n });\n token = tokenSource.token;\n }\n else {\n if (state.refreshCancelToken.token.isCancellationRequested) {\n const refreshCancelToken = new ide_utils_1.CancellationTokenSource();\n TreeNode.setGlobalTreeState(this.path, {\n isRefreshing: true,\n refreshCancelToken,\n });\n token = refreshCancelToken.token;\n }\n else {\n token = state.refreshCancelToken.token;\n }\n }\n this.toRefreshPathQueue.add((target || this).path);\n yield this.refreshThrottler.trigger(() => this.doRefresh(token));\n TreeNode.setGlobalTreeState(this.path, {\n isRefreshing: false,\n });\n });\n }\n doRefresh(token) {\n return tslib_1.__awaiter(this, void 0, void 0, function* () {\n const target = this.getRefreshNode() || this;\n if (!CompositeTreeNode.is(target)) {\n return;\n }\n const paths = target.getAllExpandedNodePath();\n yield target.refreshTreeNodeByPaths(paths, token, target);\n });\n }\n getRefreshNode() {\n let paths = Array.from(this.toRefreshPathQueue);\n this.toRefreshPathQueue.clear();\n if (!paths.length) {\n return this.root;\n }\n // 根据路径层级深度进行排序\n paths = paths.sort((a, b) => {\n const depthA = Path.pathDepth(a);\n const depthB = Path.pathDepth(b);\n return depthA - depthB;\n });\n if (paths.length === 1 || Path.pathDepth(paths[0]) === 1) {\n // 说明刷新队列中包含根节点,直接返回根节点进行刷新\n return TreeNode.getTreeNodeByPath(paths[0]);\n }\n const sortedPaths = paths.map((p) => new Path(p));\n let rootPath = sortedPaths[0];\n for (let i = 1, len = sortedPaths.length; i < len; i++) {\n if (rootPath.isEqualOrParent(sortedPaths[i])) {\n continue;\n }\n else {\n while (!rootPath.isRoot) {\n rootPath = rootPath.dir;\n if (!rootPath || rootPath.isEqualOrParent(sortedPaths[i])) {\n break;\n }\n }\n }\n }\n if (rootPath) {\n return TreeNode.getTreeNodeByPath(rootPath.toString());\n }\n return this.root;\n }\n isItemVisibleAtRootSurface(node) {\n let parent = node;\n while (parent.parent) {\n parent = parent.parent;\n }\n return parent.isItemVisibleAtSurface(node);\n }\n /**\n * 检查节点是否可见,而不是被隐藏在节点中\n *\n * 这里的可见并不表示节点在当前视图中可见,而是在用户滚动到特定位置便可看见\n *\n * 隐藏在节点中可能的原因为其父节点中有一个以上处于折叠状态\n */\n isItemVisibleAtSurface(item) {\n if (item === this) {\n return true;\n }\n return !!this._flattenedBranch && this._flattenedBranch.indexOf(item.id) > -1;\n }\n transformToRelativePath(path) {\n const { splitPath } = Path;\n const pathFlag = splitPath(path);\n pathFlag.shift();\n return pathFlag;\n }\n /**\n * 根据路径展开节点树\n * @memberof CompositeTreeNode\n */\n loadTreeNodeByPath(path_1) {\n return tslib_1.__awaiter(this, arguments, void 0, function* (path, quiet = false) {\n if (!CompositeTreeNode.isRoot(this)) {\n return;\n }\n const state = TreeNode.getGlobalTreeState(this.path);\n if (state.isExpanding) {\n return;\n }\n state.refreshCancelToken.cancel();\n state.loadPathCancelToken.cancel();\n const loadPathCancelToken = new ide_utils_1.CancellationTokenSource();\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: true,\n loadPathCancelToken,\n });\n const token = loadPathCancelToken.token;\n const flattenedBranchChilds = [];\n const { splitPath, isRelative } = Path;\n const pathFlag = isRelative(path) ? splitPath(path) : this.transformToRelativePath(path);\n if (pathFlag.length === 0) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return this;\n }\n if (!this.children) {\n yield this.ensureLoaded(token);\n }\n if (token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n let next = this._children;\n let preItem;\n let preItemPath = '';\n let name;\n while (next && (name = pathFlag.shift())) {\n let item = next.find((c) => c.name.indexOf(name) === 0);\n if (item) {\n if (CompositeTreeNode.is(item)) {\n item._watcher.notifyWillChangeExpansionState(item, true);\n item.isExpanded = true;\n if (!item.children) {\n yield item.resolveChildrens(token);\n if (token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n }\n flattenedBranchChilds.push(item);\n item._watcher.notifyDidChangeExpansionState(item, true);\n }\n if (pathFlag.length === 0) {\n preItem = item;\n break;\n }\n }\n // 可能展开后路径发生了变化, 需要重新处理一下当前加载路径\n if (!item && preItem) {\n const compactPath = splitPath(preItem.name).slice(1);\n if (compactPath[0] === name) {\n compactPath.shift();\n while (compactPath.length > 0) {\n if (compactPath[0] === pathFlag[0]) {\n compactPath.shift();\n pathFlag.shift();\n }\n else {\n break;\n }\n }\n name = pathFlag.shift();\n item = next.find((c) => c.name.indexOf(name) === 0);\n }\n }\n // 最终加载到的路径节点\n if (!item || (!CompositeTreeNode.is(item) && pathFlag.length > 0)) {\n break;\n }\n if (CompositeTreeNode.is(item)) {\n const isCompactName = item.name.indexOf(Path.separator) > 0;\n if (isCompactName) {\n const compactPath = splitPath(item.name).slice(1);\n while (compactPath.length > 0) {\n if (compactPath[0] === pathFlag[0]) {\n compactPath.shift();\n pathFlag.shift();\n }\n else {\n break;\n }\n }\n }\n if (!item._children) {\n preItemPath = item.path;\n if (CompositeTreeNode.is(item)) {\n item.isExpanded = true;\n if (!item.children) {\n yield item.resolveChildrens(token);\n if (token.isCancellationRequested) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n }\n flattenedBranchChilds.push(item);\n }\n }\n if (item && pathFlag.length === 0) {\n preItem = item;\n break;\n }\n else {\n if (!!preItemPath && preItemPath !== item.path) {\n // 说明此时已发生了路径压缩,如从 a -> a/b/c\n // 需要根据路径变化移除对应的展开路径, 这里只需考虑短变长场景\n const prePaths = splitPath(preItemPath);\n const nextPaths = splitPath(item.path);\n if (nextPaths.length > prePaths.length) {\n pathFlag.splice(0, nextPaths.length - prePaths.length);\n }\n }\n next = item._children;\n preItem = item;\n }\n }\n }\n if (preItem) {\n let child;\n if (preItem.disposed) {\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return;\n }\n while ((child = flattenedBranchChilds.pop())) {\n child.expandBranch(child, true);\n if (flattenedBranchChilds.length === 0) {\n this.updateTreeNodeCache(child);\n }\n }\n if (!quiet) {\n this.watcher.notifyDidUpdateBranch();\n }\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n return preItem;\n }\n TreeNode.setGlobalTreeState(this.path, {\n isLoadingPath: false,\n });\n });\n }\n /**\n * 根据节点获取节点ID下标位置\n * @param {number} id\n * @returns\n * @memberof CompositeTreeNode\n */\n getIndexAtTreeNodeId(id) {\n if (this._flattenedBranch) {\n return this._flattenedBranch.indexOf(id);\n }\n return -1;\n }\n /**\n * 根据节点获取节点下标位置\n * @param {ITreeNodeOrCompositeTreeNode} node\n * @returns\n * @memberof CompositeTreeNode\n */\n getIndexAtTreeNode(node) {\n if (this._flattenedBranch) {\n return this._flattenedBranch.indexOf(node.id);\n }\n return -1;\n }\n /**\n * 根据下标位置获取节点\n * @param {number} index\n * @returns\n * @memberof CompositeTreeNode\n */\n getTreeNodeAtIndex(index) {\n var _a;\n const id = (_a = this._flattenedBranch) === null || _a === void 0 ? void 0 : _a[index];\n if (!id) {\n return undefined;\n }\n return TreeNode.getTreeNodeById(id);\n }\n /**\n * 根据节点ID获取节点\n * @param {number} id\n * @returns\n * @memberof CompositeTreeNode\n */\n getTreeNodeById(id) {\n return TreeNode.getTreeNodeById(id);\n }\n /**\n * 根据节点路径获取节点\n * @param {string} path\n * @returns\n * @memberof CompositeTreeNode\n */\n getTreeNodeByPath(path) {\n return TreeNode.getTreeNodeByPath(path);\n }\n}\nexports.CompositeTreeNode = CompositeTreeNode;\nCompositeTreeNode.REFRESH_DELAY = 200;\n\n\n//# sourceURL=webpack://@opensumi/ide-components/./src/recycle-tree/tree/TreeNode.ts?");
|
|
6302
6302
|
|
|
6303
6303
|
/***/ }),
|
|
6304
6304
|
|
|
@@ -6485,7 +6485,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
6485
6485
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
6486
6486
|
|
|
6487
6487
|
"use strict";
|
|
6488
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SelectOptionsList = exports.Option = void 0;\nexports.isDataOptions = isDataOptions;\nexports.isDataOptionGroups = isDataOptionGroups;\nexports.Select = Select;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\nconst classnames_1 = tslib_1.__importDefault(__webpack_require__(/*! classnames */ \"../../node_modules/classnames/index.js\"));\nconst react_1 = tslib_1.__importStar(__webpack_require__(/*! react */ \"../../node_modules/react/index.js\"));\nconst icon_1 = __webpack_require__(/*! ../icon */ \"./src/icon/index.ts\");\nconst input_1 = __webpack_require__(/*! ../input */ \"./src/input/index.tsx\");\n__webpack_require__(/*! ./style.less */ \"./src/select/style.less\");\nconst Option = (_a) => {\n var { value, children, disabled, onClick, className } = _a, otherProps = tslib_1.__rest(_a, [\"value\", \"children\", \"disabled\", \"onClick\", \"className\"]);\n return (react_1.default.createElement(\"span\", Object.assign({}, otherProps, { className: (0, classnames_1.default)(className, { 'kt-option-disabled': disabled }), onClick: () => onClick && !disabled && onClick(value) }), children));\n};\nexports.Option = Option;\nfunction noop(...args) { }\nfunction getValueWithProps(element, key) {\n if (key) {\n return element.props[key];\n }\n return element.props.value;\n}\nfunction flatChildren(children, warpper) {\n let flatted = [];\n if (Array.isArray(children)) {\n flatted = react_1.default.Children.toArray(children).map(warpper);\n }\n else {\n flatted = [warpper(children)];\n }\n return flatted;\n}\n/**\n * @deprecated\n * 从react node 上获取 props 来比较有点反模式,不符合数据和视图解耦的思想\n */\nfunction getLabelWithChildrenProps(value, children, equals = (v1, v2) => v1 === v2) {\n const nodes = react_1.default.Children.toArray(children).filter((v) => react_1.default.isValidElement(v));\n const currentOption = nodes.find((node) => {\n var _a;\n if (node.props) {\n if (equals((_a = node.props) === null || _a === void 0 ? void 0 : _a.value, value)) {\n return node;\n }\n }\n return null;\n });\n return currentOption === null || currentOption === void 0 ? void 0 : currentOption.props;\n}\nfunction isDataOptions(options) {\n if (!options) {\n return false;\n }\n if (options.length === 0) {\n return true;\n }\n return isDataOption(options[0]);\n}\nfunction isDataOptionGroups(options) {\n if (!options) {\n return false;\n }\n if (options.length === 0) {\n return true;\n }\n return isDataOptionGroup(options[0]);\n}\nfunction isDataOption(option) {\n return option.value !== undefined;\n}\nfunction isDataOptionGroup(option) {\n return option.groupName !== undefined && isDataOptions(option.options);\n}\nfunction defaultOptionRenderer(v) {\n return (react_1.default.createElement(react_1.default.Fragment, null,\n v.data.iconClass ? react_1.default.createElement(\"div\", { className: (0, classnames_1.default)(v.data.iconClass, 'kt-select-option-icon') }) : undefined,\n v.data.label));\n}\nfunction defaultGroupTitleRenderer({ group, index }) {\n return (react_1.default.createElement(\"div\", { key: 'header_' + index, className: 'kt-select-group-header' },\n group.iconClass ? react_1.default.createElement(\"div\", { className: (0, classnames_1.default)(group.iconClass, 'kt-select-option-icon') }) : undefined,\n react_1.default.createElement(\"div\", null, group.groupName)));\n}\nfunction defaultFilterOption(input, option) {\n let strToSearch = option.label;\n if (strToSearch === undefined) {\n try {\n strToSearch = option.value.toString();\n }\n catch (e) {\n strToSearch = undefined;\n }\n }\n if (typeof strToSearch === 'string') {\n return strToSearch.indexOf(input) !== -1;\n }\n return false;\n}\nconst SelectedContent = react_1.default.memo(({ selected, selectedRenderer: CustomSC }) => {\n if (CustomSC) {\n return react_1.default.createElement(CustomSC, { data: selected });\n }\n return (react_1.default.createElement(react_1.default.Fragment, null,\n selected.iconClass && react_1.default.createElement(\"div\", { className: (0, classnames_1.default)(selected.iconClass, 'kt-select-option-icon') }),\n react_1.default.createElement(\"span\", { className: 'kt-select-option' }, selected.label)));\n});\nconst SearchInput = react_1.default.memo(({ value, onChange, placeholder, size = 'default' }) => (react_1.default.createElement(input_1.Input, { className: 'kt-select-search', value: value, size: size, onChange: (e) => onChange(e.target.value), autoFocus: true, placeholder: placeholder || '' })));\nfunction Select({ disabled, options, size = 'default', children, value, onChange, onMouseEnter, optionLabelProp, style, optionStyle, className, maxHeight, equals = (v1, v2) => v1 === v2, optionRenderer = defaultOptionRenderer, groupTitleRenderer, footerComponent, headerComponent, showSearch = false, filterOption = defaultFilterOption, searchPlaceholder = '', emptyComponent, selectedRenderer, onBeforeShowOptions, allowOptionsOverflow, dropdownRenderType = 'fixed', description, notMatchWarning, onSearchChange, }) {\n const [open, setOpen] = (0, react_1.useState)(false);\n const [searchInput, setSearchInput] = (0, react_1.useState)('');\n const selectRef = react_1.default.useRef(null);\n const overlayRef = react_1.default.useRef(null);\n const handleToggleOpen = (0, react_1.useCallback)((e) => {\n e.preventDefault();\n e.stopPropagation();\n if (!open && (onBeforeShowOptions === null || onBeforeShowOptions === void 0 ? void 0 : onBeforeShowOptions())) {\n return;\n }\n setOpen(!open);\n }, [open, onBeforeShowOptions]);\n const getSelectedValue = (0, react_1.useCallback)(() => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (options && isDataOptions(options)) {\n for (const option of options) {\n if (equals(value, option.value)) {\n return {\n iconClass: option.iconClass,\n label: option.label,\n value: option.value,\n };\n }\n }\n return {\n iconClass: (_a = options[0]) === null || _a === void 0 ? void 0 : _a.iconClass,\n label: (_b = options[0]) === null || _b === void 0 ? void 0 : _b.label,\n value: (_c = options[0]) === null || _c === void 0 ? void 0 : _c.value,\n };\n }\n else if (options && isDataOptionGroups(options)) {\n for (const group of options) {\n for (const option of group.options) {\n if (equals(value, option.value)) {\n return {\n iconClass: option.iconClass,\n label: option.label,\n value: option.value,\n };\n }\n }\n }\n return {\n iconClass: (_e = (_d = options[0]) === null || _d === void 0 ? void 0 : _d.options[0]) === null || _e === void 0 ? void 0 : _e.iconClass,\n label: (_g = (_f = options[0]) === null || _f === void 0 ? void 0 : _f.options[0]) === null || _g === void 0 ? void 0 : _g.label,\n value: (_j = (_h = options[0]) === null || _h === void 0 ? void 0 : _h.options[0]) === null || _j === void 0 ? void 0 : _j.value,\n };\n }\n else {\n const nodeOption = children && getLabelWithChildrenProps(value, children);\n if (nodeOption) {\n return {\n label: nodeOption.label || nodeOption.value,\n value: nodeOption.value,\n };\n }\n }\n // 如果当前 value 和任何一个 option 都不匹配,返回当前 value\n return {\n label: value,\n value: value,\n notMatch: true,\n };\n }, [options, value, children]);\n const selected = getSelectedValue();\n const optionsContainerClasses = (0, classnames_1.default)('kt-select-options', {\n ['kt-select-options-visible']: open,\n [`kt-select-options-${size}`]: size,\n });\n const showWarning = notMatchWarning && selected.notMatch;\n const selectClasses = (0, classnames_1.default)('kt-select-value', {\n ['kt-select-warning']: showWarning,\n ['kt-select-disabled']: disabled,\n ['kt-select-value-active']: open,\n [`kt-select-value-${size}`]: size,\n });\n function Wrapper(node, index) {\n var _a;\n if (!node) {\n return null;\n }\n if (typeof node === 'string' || typeof node === 'number') {\n node = (react_1.default.createElement(exports.Option, { value: node, label: String(node), key: `${node}_${index}` }, node));\n }\n const element = node;\n const disabled = ((_a = element.props) === null || _a === void 0 ? void 0 : _a.disabled) || false;\n return (react_1.default.createElement(\"div\", { key: `${element.props.value}_${index}`, className: (0, classnames_1.default)({\n ['kt-select-option-select']: value === element.props.value,\n }), onMouseEnter: () => onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(element.props.value, index), onClick: disabled\n ? noop\n : () => {\n setOpen(false);\n if (onChange) {\n onChange(getValueWithProps(node, optionLabelProp));\n }\n } }, node));\n }\n (0, react_1.useEffect)(() => {\n if (!open && searchInput) {\n setSearchInput('');\n }\n }, []);\n (0, react_1.useEffect)(() => {\n if (!open) {\n return;\n }\n const handleClickOutside = (e) => {\n if (selectRef.current && !selectRef.current.contains(e.target)) {\n setOpen(false);\n }\n };\n document.addEventListener('click', handleClickOutside);\n return () => document.removeEventListener('click', handleClickOutside);\n }, [open]);\n const updateOverlayPosition = (0, react_1.useCallback)(() => {\n if (!selectRef.current || !overlayRef.current) {\n return;\n }\n const selectRect = selectRef.current.getBoundingClientRect();\n const overlayEl = overlayRef.current;\n // 设置宽度\n if (allowOptionsOverflow) {\n overlayEl.style.minWidth = `${selectRect.width}px`;\n overlayEl.style.maxWidth = `${window.innerWidth - selectRect.left - 4}px`;\n }\n else {\n overlayEl.style.width = `${selectRect.width}px`;\n }\n // 计算位置\n const spaceBelow = window.innerHeight - selectRect.bottom - 50;\n const overlayHeight = overlayEl.clientHeight;\n if (spaceBelow < overlayHeight) {\n overlayEl.style.bottom = `${selectRect.height + 4}px`;\n }\n else {\n overlayEl.style.maxHeight = `${spaceBelow}px`;\n overlayEl.style.bottom = 'auto';\n }\n overlayEl.style.position = dropdownRenderType;\n }, [allowOptionsOverflow, dropdownRenderType]);\n (0, react_1.useEffect)(() => {\n if (open) {\n updateOverlayPosition();\n window.addEventListener('resize', updateOverlayPosition);\n return () => window.removeEventListener('resize', updateOverlayPosition);\n }\n }, [open, updateOverlayPosition]);\n const filteredOptions = (0, react_1.useMemo)(() => {\n if (!searchInput) {\n return options;\n }\n if (isDataOptions(options)) {\n return options.filter((o) => filterOption(searchInput, o));\n }\n if (isDataOptionGroups(options)) {\n return options.reduce((groups, group) => {\n const filteredOpts = group.options.filter((o) => filterOption(searchInput, o, group));\n if (filteredOpts.length) {\n groups.push(Object.assign(Object.assign({}, group), { options: filteredOpts }));\n }\n return groups;\n }, []);\n }\n return options;\n }, [options, searchInput, filterOption]);\n const renderSelected = () => (react_1.default.createElement(react_1.default.Fragment, null,\n react_1.default.createElement(SelectedContent, { selected: selected, selectedRenderer: selectedRenderer }),\n react_1.default.createElement(icon_1.Icon, { iconClass: (0, classnames_1.default)((0, icon_1.getIcon)('down'), 'kt-select-value-default-icon') })));\n const handleSearchChange = (0, react_1.useCallback)((value) => {\n setSearchInput(value);\n onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange(value);\n }, [searchInput, onSearchChange]);\n const renderSearch = () => (react_1.default.createElement(SearchInput, { value: searchInput, onChange: handleSearchChange, placeholder: searchPlaceholder }));\n return (react_1.default.createElement(\"div\", { className: (0, classnames_1.default)('kt-select-container', className), ref: selectRef },\n react_1.default.createElement(\"div\", { className: selectClasses, onClick: handleToggleOpen, style: style }, showSearch && open ? renderSearch() : renderSelected()),\n showWarning && react_1.default.createElement(\"div\", { className: 'kt-select-warning-text' }, notMatchWarning),\n open &&\n !searchInput &&\n (isDataOptions(filteredOptions) || isDataOptionGroups(filteredOptions) ? (react_1.default.createElement(exports.SelectOptionsList, { optionRenderer: optionRenderer, options: filteredOptions, equals: equals, optionStyle: optionStyle, currentValue: value, size: size, onSelect: (value) => {\n if (onChange) {\n onChange(value);\n }\n setOpen(false);\n }, groupTitleRenderer: groupTitleRenderer, className: optionsContainerClasses, style: { maxHeight: `${maxHeight}px` }, ref: overlayRef, footerComponent: footerComponent, headerComponent: headerComponent, emptyComponent: emptyComponent })) : (\n // FIXME: to be deprecated\n // 下面这种使用 children 的方式不够标准化,待废弃\n react_1.default.createElement(\"div\", { className: optionsContainerClasses, style: { maxHeight: `${maxHeight}px` }, ref: overlayRef },\n options && options.map((v, i) => Wrapper(v, i)),\n children && flatChildren(children, Wrapper),\n description && react_1.default.createElement(Description, { text: description }),\n react_1.default.createElement(\"div\", { className: 'kt-select-overlay', onClick: handleToggleOpen }))))));\n}\nfunction Description({ text }) {\n return (react_1.default.createElement(react_1.default.Fragment, null,\n react_1.default.createElement(\"div\", { className: 'kt-option-divider' }),\n react_1.default.createElement(\"div\", { className: 'kt-option-description' }, text)));\n}\nexports.SelectOptionsList = react_1.default.forwardRef((props, ref) => {\n const { options, optionRenderer: OPC = defaultOptionRenderer, equals = (v1, v2) => v1 === v2, onSelect, currentValue, optionStyle, size, className, style, groupTitleRenderer: GT = defaultGroupTitleRenderer, renderCheck, headerComponent: HC, footerComponent: FC, emptyComponent: EC, } = props;\n const optionsContainerClasses = (0, classnames_1.default)('kt-select-options', {\n [`kt-select-options-${size}`]: true,\n }, className);\n function renderWithGroup(groups) {\n return groups.map((group, index) => {\n const header = react_1.default.createElement(GT, { group: group, index: index });\n return (react_1.default.createElement(react_1.default.Fragment, { key: 'group_' + index },\n header,\n renderWithoutGroup(group.options)));\n });\n }\n function renderWithoutGroup(options) {\n return (options &&\n options.map((v, index) => {\n const isCurrent = equals(currentValue, v.value);\n return (react_1.default.createElement(exports.Option, { value: index, key: index, className: (0, classnames_1.default)({\n ['kt-select-option-select']: isCurrent,\n ['kt-select-option-default']: true,\n ['kt-option-with-check']: renderCheck,\n }), onClick: () => onSelect(v.value), style: optionStyle },\n renderCheck && equals(currentValue, v.value) ? (react_1.default.createElement(\"div\", { className: 'kt-option-check' },\n react_1.default.createElement(icon_1.Icon, { icon: 'check' }))) : undefined,\n react_1.default.createElement(OPC, { data: v, isCurrent: isCurrent })));\n }));\n }\n let isEmpty;\n if (isDataOptionGroups(options)) {\n isEmpty = options.filter((group) => group.options.length > 0).length === 0;\n }\n else {\n isEmpty = options.length === 0;\n }\n return (react_1.default.createElement(\"div\", { className: optionsContainerClasses, style: style, ref: ref, onClick: (event) => {\n event.stopPropagation();\n } },\n HC ? react_1.default.createElement(HC, null) : null,\n isEmpty && EC ? (react_1.default.createElement(EC, null)) : ((isDataOptionGroups(options) ? renderWithGroup(options) : renderWithoutGroup(options)) || (EC && react_1.default.createElement(EC, null))),\n FC ? react_1.default.createElement(FC, null) : null));\n});\n\n\n//# sourceURL=webpack://@opensumi/ide-components/./src/select/index.tsx?");
|
|
6488
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SelectOptionsList = exports.Option = void 0;\nexports.isDataOptions = isDataOptions;\nexports.isDataOptionGroups = isDataOptionGroups;\nexports.Select = Select;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\nconst classnames_1 = tslib_1.__importDefault(__webpack_require__(/*! classnames */ \"../../node_modules/classnames/index.js\"));\nconst react_1 = tslib_1.__importStar(__webpack_require__(/*! react */ \"../../node_modules/react/index.js\"));\n__webpack_require__(/*! ./style.less */ \"./src/select/style.less\");\nconst icon_1 = __webpack_require__(/*! ../icon */ \"./src/icon/index.ts\");\nconst Option = (_a) => {\n var { value, children, disabled, onClick, className } = _a, otherProps = tslib_1.__rest(_a, [\"value\", \"children\", \"disabled\", \"onClick\", \"className\"]);\n return (react_1.default.createElement(\"span\", Object.assign({}, otherProps, { className: (0, classnames_1.default)(className, { 'kt-option-disabled': disabled }), onClick: () => onClick && !disabled && onClick(value) }), children));\n};\nexports.Option = Option;\nfunction noop(...args) { }\nfunction getValueWithProps(element, key) {\n if (key) {\n return element.props[key];\n }\n return element.props.value;\n}\nfunction flatChildren(children, warpper) {\n let flatted = [];\n if (Array.isArray(children)) {\n flatted = react_1.default.Children.toArray(children).map(warpper);\n }\n else {\n flatted = [warpper(children)];\n }\n return flatted;\n}\n/**\n * @deprecated\n * 从react node 上获取 props 来比较有点反模式,不符合数据和视图解耦的思想\n */\nfunction getLabelWithChildrenProps(value, children, equals = (v1, v2) => v1 === v2) {\n const nodes = react_1.default.Children.toArray(children).filter((v) => react_1.default.isValidElement(v));\n const currentOption = nodes.find((node) => {\n var _a;\n if (node.props) {\n if (equals((_a = node.props) === null || _a === void 0 ? void 0 : _a.value, value)) {\n return node;\n }\n }\n return null;\n });\n return currentOption === null || currentOption === void 0 ? void 0 : currentOption.props;\n}\nfunction isDataOptions(options) {\n if (!options) {\n return false;\n }\n if (options.length === 0) {\n return true;\n }\n return isDataOption(options[0]);\n}\nfunction isDataOptionGroups(options) {\n if (!options) {\n return false;\n }\n if (options.length === 0) {\n return true;\n }\n return isDataOptionGroup(options[0]);\n}\nfunction isDataOption(option) {\n return option.value !== undefined;\n}\nfunction isDataOptionGroup(option) {\n return option.groupName !== undefined && isDataOptions(option.options);\n}\nfunction defaultOptionRenderer(v) {\n return (react_1.default.createElement(react_1.default.Fragment, null,\n v.data.iconClass ? react_1.default.createElement(\"div\", { className: (0, classnames_1.default)(v.data.iconClass, 'kt-select-option-icon') }) : undefined,\n v.data.label));\n}\nfunction defaultGroupTitleRenderer({ group, index }) {\n return (react_1.default.createElement(\"div\", { key: 'header_' + index, className: 'kt-select-group-header' },\n group.iconClass ? react_1.default.createElement(\"div\", { className: (0, classnames_1.default)(group.iconClass, 'kt-select-option-icon') }) : undefined,\n react_1.default.createElement(\"div\", null, group.groupName)));\n}\nfunction defaultFilterOption(input, option) {\n let strToSearch = option.label;\n if (strToSearch === undefined) {\n try {\n strToSearch = option.value.toString();\n }\n catch (e) {\n strToSearch = undefined;\n }\n }\n if (typeof strToSearch === 'string') {\n return strToSearch.indexOf(input) !== -1;\n }\n return false;\n}\nfunction Select({ disabled, options, size = 'default', children, value, onChange, onMouseEnter, optionLabelProp, style, optionStyle, className, maxHeight, equals = (v1, v2) => v1 === v2, optionRenderer = defaultOptionRenderer, groupTitleRenderer, footerComponent, headerComponent, showSearch = false, filterOption = defaultFilterOption, searchPlaceholder = '', emptyComponent, selectedRenderer, onBeforeShowOptions, allowOptionsOverflow, dropdownRenderType = 'fixed', description, notMatchWarning, }) {\n const [open, setOpen] = (0, react_1.useState)(false);\n const [searchInput, setSearchInput] = (0, react_1.useState)('');\n const selectRef = react_1.default.useRef(null);\n const overlayRef = react_1.default.useRef(null);\n const toggleOpen = (0, react_1.useCallback)((e) => {\n e.preventDefault();\n e.stopPropagation();\n const target = !open;\n if (target) {\n if (onBeforeShowOptions && onBeforeShowOptions()) {\n return;\n }\n }\n setOpen(target);\n }, [open, onBeforeShowOptions, onBeforeShowOptions]);\n const getSelectedValue = (0, react_1.useCallback)(() => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (options && isDataOptions(options)) {\n for (const option of options) {\n if (equals(value, option.value)) {\n return {\n iconClass: option.iconClass,\n label: option.label,\n value: option.value,\n };\n }\n }\n return {\n iconClass: (_a = options[0]) === null || _a === void 0 ? void 0 : _a.iconClass,\n label: (_b = options[0]) === null || _b === void 0 ? void 0 : _b.label,\n value: (_c = options[0]) === null || _c === void 0 ? void 0 : _c.value,\n };\n }\n else if (options && isDataOptionGroups(options)) {\n for (const group of options) {\n for (const option of group.options) {\n if (equals(value, option.value)) {\n return {\n iconClass: option.iconClass,\n label: option.label,\n value: option.value,\n };\n }\n }\n }\n return {\n iconClass: (_e = (_d = options[0]) === null || _d === void 0 ? void 0 : _d.options[0]) === null || _e === void 0 ? void 0 : _e.iconClass,\n label: (_g = (_f = options[0]) === null || _f === void 0 ? void 0 : _f.options[0]) === null || _g === void 0 ? void 0 : _g.label,\n value: (_j = (_h = options[0]) === null || _h === void 0 ? void 0 : _h.options[0]) === null || _j === void 0 ? void 0 : _j.value,\n };\n }\n else {\n const nodeOption = children && getLabelWithChildrenProps(value, children);\n if (nodeOption) {\n return {\n label: nodeOption.label || nodeOption.value,\n value: nodeOption.value,\n };\n }\n }\n // 如果当前 value 和任何一个 option 都不匹配,返回当前 value\n return {\n label: value,\n value: value,\n notMatch: true,\n };\n }, [options, value, children]);\n const selected = getSelectedValue();\n const optionsContainerClasses = (0, classnames_1.default)('kt-select-options', {\n ['kt-select-options-visible']: open,\n [`kt-select-options-${size}`]: size,\n });\n const showWarning = notMatchWarning && selected.notMatch;\n const selectClasses = (0, classnames_1.default)('kt-select-value', {\n ['kt-select-warning']: showWarning,\n ['kt-select-disabled']: disabled,\n ['kt-select-value-active']: open,\n [`kt-select-value-${size}`]: size,\n });\n function Wrapper(node, index) {\n var _a;\n if (!node) {\n return null;\n }\n if (typeof node === 'string' || typeof node === 'number') {\n node = (react_1.default.createElement(exports.Option, { value: node, label: String(node), key: `${node}_${index}` }, node));\n }\n const element = node;\n const disabled = ((_a = element.props) === null || _a === void 0 ? void 0 : _a.disabled) || false;\n return (react_1.default.createElement(\"div\", { key: `${element.props.value}_${index}`, className: (0, classnames_1.default)({\n ['kt-select-option-select']: value === element.props.value,\n }), onMouseEnter: () => onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(element.props.value, index), onClick: disabled\n ? noop\n : () => {\n setOpen(false);\n if (onChange) {\n onChange(getValueWithProps(node, optionLabelProp));\n }\n } }, node));\n }\n (0, react_1.useEffect)(() => {\n if (!open && searchInput) {\n setSearchInput('');\n }\n }, []);\n (0, react_1.useEffect)(() => {\n if (selectRef.current && overlayRef.current) {\n const boxRect = selectRef.current.getBoundingClientRect();\n if (allowOptionsOverflow) {\n overlayRef.current.style.minWidth = `${boxRect.width}px`;\n // 防止戳出屏幕\n overlayRef.current.style.maxWidth = `${window.innerWidth - boxRect.left - 4}px`;\n }\n else {\n overlayRef.current.style.width = `${boxRect.width}px`;\n }\n // 防止戳出下方屏幕\n const toBottom = window.innerHeight - boxRect.bottom - 50;\n if (toBottom < overlayRef.current.clientHeight) {\n // 下方距离小于浮层高度,设置向上弹出选择框\n overlayRef.current.style.bottom = selectRef.current.clientHeight + 4 + 'px';\n }\n else {\n // 下方距离大于浮层高度,设置最大高度为下方距离\n overlayRef.current.style.maxHeight = `${toBottom}px`;\n }\n overlayRef.current.style.position = dropdownRenderType === 'fixed' ? 'fixed' : 'absolute';\n }\n if (open) {\n const listener = () => {\n setOpen(false);\n };\n document.addEventListener('click', listener);\n return () => {\n document.removeEventListener('click', listener);\n };\n }\n }, [open]);\n // 根据搜索输入过滤 options\n if (searchInput) {\n if (options && isDataOptions(options)) {\n options = options.filter((o) => filterOption(searchInput, o));\n }\n else if (options && isDataOptionGroups(options)) {\n const result = [];\n for (const group of options) {\n const filteredGroup = {\n iconClass: group.iconClass,\n groupName: group.groupName,\n options: group.options.filter((o) => filterOption(searchInput, o, group)),\n };\n if (filteredGroup.options.length > 0) {\n // 不显示空的group\n result.push(filteredGroup);\n }\n }\n options = result;\n }\n }\n const renderSelected = () => {\n const CustomSC = selectedRenderer;\n return (react_1.default.createElement(react_1.default.Fragment, null,\n CustomSC ? (react_1.default.createElement(CustomSC, { data: selected })) : (react_1.default.createElement(react_1.default.Fragment, null,\n selected.iconClass ? react_1.default.createElement(\"div\", { className: (0, classnames_1.default)(selected.iconClass, 'kt-select-option-icon') }) : undefined,\n react_1.default.createElement(\"span\", { className: 'kt-select-option' }, selected.label))),\n react_1.default.createElement(icon_1.Icon, { iconClass: (0, classnames_1.default)((0, icon_1.getIcon)('down'), 'kt-select-value-default-icon') })));\n };\n const renderSearch = () => (react_1.default.createElement(\"input\", { className: (0, classnames_1.default)('kt-select-search'), onChange: (e) => {\n setSearchInput(e.target.value);\n }, value: searchInput, autoFocus: true, placeholder: searchPlaceholder || '' }));\n return (react_1.default.createElement(\"div\", { className: (0, classnames_1.default)('kt-select-container', className), ref: selectRef },\n react_1.default.createElement(\"div\", { className: selectClasses, onClick: toggleOpen, style: style }, showSearch && open ? renderSearch() : renderSelected()),\n showWarning && react_1.default.createElement(\"div\", { className: 'kt-select-warning-text' }, notMatchWarning),\n open &&\n (isDataOptions(options) || isDataOptionGroups(options) ? (react_1.default.createElement(exports.SelectOptionsList, { optionRenderer: optionRenderer, options: options, equals: equals, optionStyle: optionStyle, currentValue: value, size: size, onSelect: (value) => {\n if (onChange) {\n onChange(value);\n }\n setOpen(false);\n }, groupTitleRenderer: groupTitleRenderer, className: optionsContainerClasses, style: { maxHeight: `${maxHeight}px` }, ref: overlayRef, footerComponent: footerComponent, headerComponent: headerComponent, emptyComponent: emptyComponent })) : (\n // FIXME: to be deprecated\n // 下面这种使用 children 的方式不够标准化,待废弃\n react_1.default.createElement(\"div\", { className: optionsContainerClasses, style: { maxHeight: `${maxHeight}px` }, ref: overlayRef },\n options && options.map((v, i) => Wrapper(v, i)),\n children && flatChildren(children, Wrapper),\n description && react_1.default.createElement(Description, { text: description }),\n react_1.default.createElement(\"div\", { className: 'kt-select-overlay', onClick: toggleOpen }))))));\n}\nfunction Description({ text }) {\n return (react_1.default.createElement(react_1.default.Fragment, null,\n react_1.default.createElement(\"div\", { className: 'kt-option-divider' }),\n react_1.default.createElement(\"div\", { className: 'kt-option-description' }, text)));\n}\nexports.SelectOptionsList = react_1.default.forwardRef((props, ref) => {\n const { options, optionRenderer: OPC = defaultOptionRenderer, equals = (v1, v2) => v1 === v2, onSelect, currentValue, optionStyle, size, className, style, groupTitleRenderer: GT = defaultGroupTitleRenderer, renderCheck, headerComponent: HC, footerComponent: FC, emptyComponent: EC, } = props;\n const optionsContainerClasses = (0, classnames_1.default)('kt-select-options', {\n [`kt-select-options-${size}`]: true,\n }, className);\n function renderWithGroup(groups) {\n return groups.map((group, index) => {\n const header = react_1.default.createElement(GT, { group: group, index: index });\n return (react_1.default.createElement(react_1.default.Fragment, { key: 'group_' + index },\n header,\n renderWithoutGroup(group.options)));\n });\n }\n function renderWithoutGroup(options) {\n return (options &&\n options.map((v, index) => {\n const isCurrent = equals(currentValue, v.value);\n return (react_1.default.createElement(exports.Option, { value: index, key: index, className: (0, classnames_1.default)({\n ['kt-select-option-select']: isCurrent,\n ['kt-select-option-default']: true,\n ['kt-option-with-check']: renderCheck,\n }), onClick: () => onSelect(v.value), style: optionStyle },\n renderCheck && equals(currentValue, v.value) ? (react_1.default.createElement(\"div\", { className: 'kt-option-check' },\n react_1.default.createElement(icon_1.Icon, { icon: 'check' }))) : undefined,\n react_1.default.createElement(OPC, { data: v, isCurrent: isCurrent })));\n }));\n }\n let isEmpty;\n if (isDataOptionGroups(options)) {\n isEmpty = options.filter((group) => group.options.length > 0).length === 0;\n }\n else {\n isEmpty = options.length === 0;\n }\n return (react_1.default.createElement(\"div\", { className: optionsContainerClasses, style: style, ref: ref, onClick: (event) => {\n event.stopPropagation();\n } },\n HC ? react_1.default.createElement(HC, null) : null,\n isEmpty && EC ? (react_1.default.createElement(EC, null)) : ((isDataOptionGroups(options) ? renderWithGroup(options) : renderWithoutGroup(options)) || (EC && react_1.default.createElement(EC, null))),\n FC ? react_1.default.createElement(FC, null) : null));\n});\n\n\n//# sourceURL=webpack://@opensumi/ide-components/./src/select/index.tsx?");
|
|
6489
6489
|
|
|
6490
6490
|
/***/ }),
|
|
6491
6491
|
|
|
@@ -6584,7 +6584,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
6584
6584
|
/***/ ((__unused_webpack_module, exports) => {
|
|
6585
6585
|
|
|
6586
6586
|
"use strict";
|
|
6587
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.warning = warning;\nexports.note = note;\nexports.resetWarned = resetWarned;\nexports.call = call;\nexports.warningOnce = warningOnce;\nexports.noteOnce = noteOnce;\nlet warned = {};\nfunction warning(valid, message) {\n // Support uglify\n if ( true && !valid && console !== undefined) {\n // eslint-disable-next-line no-console\n console.
|
|
6587
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.warning = warning;\nexports.note = note;\nexports.resetWarned = resetWarned;\nexports.call = call;\nexports.warningOnce = warningOnce;\nexports.noteOnce = noteOnce;\nlet warned = {};\nfunction warning(valid, message) {\n // Support uglify\n if ( true && !valid && console !== undefined) {\n // eslint-disable-next-line no-console\n console.error(`Warning: ${message}`);\n }\n}\nfunction note(valid, message) {\n // Support uglify\n if ( true && !valid && console !== undefined) {\n // eslint-disable-next-line no-console\n console.warn(`Note: ${message}`);\n }\n}\nfunction resetWarned() {\n warned = {};\n}\nfunction call(method, valid, message) {\n if (!valid && !warned[message]) {\n method(false, message);\n warned[message] = true;\n }\n}\nfunction warningOnce(valid, message) {\n call(warning, valid, message);\n}\nfunction noteOnce(valid, message) {\n call(note, valid, message);\n}\nexports[\"default\"] = warningOnce;\n\n\n//# sourceURL=webpack://@opensumi/ide-components/./src/utils/warning.ts?");
|
|
6588
6588
|
|
|
6589
6589
|
/***/ }),
|
|
6590
6590
|
|
|
@@ -7176,7 +7176,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
7176
7176
|
/***/ ((__unused_webpack_module, exports) => {
|
|
7177
7177
|
|
|
7178
7178
|
"use strict";
|
|
7179
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.AI_NATIVE_SETTING_GROUP_TITLE = exports.AI_NATIVE_SETTING_GROUP_ID = exports.AINativeSettingSectionsId = void 0;\nvar AINativeSettingSectionsId;\n(function (AINativeSettingSectionsId) {\n /**\n * inline diff preview mode\n */\n AINativeSettingSectionsId[\"InlineDiffPreviewMode\"] = \"ai.native.inlineDiff.preview.mode\";\n AINativeSettingSectionsId[\"InlineChatAutoVisible\"] = \"ai.native.inlineChat.auto.visible\";\n AINativeSettingSectionsId[\"InlineChatCodeActionEnabled\"] = \"ai.native.inlineChat.codeAction.enabled\";\n AINativeSettingSectionsId[\"InterfaceQuickNavigationEnabled\"] = \"ai.native.interface.quickNavigation.enabled\";\n AINativeSettingSectionsId[\"ChatVisibleType\"] = \"ai.native.chat.visible.type\";\n /**\n * Whether to enable prompt engineering, some LLM models may not perform well on prompt engineering.\n */\n AINativeSettingSectionsId[\"IntelligentCompletionsPromptEngineeringEnabled\"] = \"ai.native.intelligentCompletions.promptEngineering.enabled\";\n AINativeSettingSectionsId[\"IntelligentCompletionsDebounceTime\"] = \"ai.native.intelligentCompletions.debounceTime\";\n AINativeSettingSectionsId[\"IntelligentCompletionsCacheEnabled\"] = \"ai.native.intelligentCompletions.cache.enabled\";\n AINativeSettingSectionsId[\"IntelligentCompletionsAlwaysVisible\"] = \"ai.native.intelligentCompletions.alwaysVisible\";\n /**\n * Code edits settings\n */\n AINativeSettingSectionsId[\"CodeEditsLintErrors\"] = \"ai.native.codeEdits.lintErrors\";\n AINativeSettingSectionsId[\"CodeEditsLineChange\"] = \"ai.native.codeEdits.lineChange\";\n
|
|
7179
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.AI_NATIVE_SETTING_GROUP_TITLE = exports.AI_NATIVE_SETTING_GROUP_ID = exports.AINativeSettingSectionsId = void 0;\nvar AINativeSettingSectionsId;\n(function (AINativeSettingSectionsId) {\n /**\n * inline diff preview mode\n */\n AINativeSettingSectionsId[\"InlineDiffPreviewMode\"] = \"ai.native.inlineDiff.preview.mode\";\n AINativeSettingSectionsId[\"InlineChatAutoVisible\"] = \"ai.native.inlineChat.auto.visible\";\n AINativeSettingSectionsId[\"InlineChatCodeActionEnabled\"] = \"ai.native.inlineChat.codeAction.enabled\";\n AINativeSettingSectionsId[\"InterfaceQuickNavigationEnabled\"] = \"ai.native.interface.quickNavigation.enabled\";\n AINativeSettingSectionsId[\"ChatVisibleType\"] = \"ai.native.chat.visible.type\";\n /**\n * Whether to enable prompt engineering, some LLM models may not perform well on prompt engineering.\n */\n AINativeSettingSectionsId[\"IntelligentCompletionsPromptEngineeringEnabled\"] = \"ai.native.intelligentCompletions.promptEngineering.enabled\";\n AINativeSettingSectionsId[\"IntelligentCompletionsDebounceTime\"] = \"ai.native.intelligentCompletions.debounceTime\";\n AINativeSettingSectionsId[\"IntelligentCompletionsCacheEnabled\"] = \"ai.native.intelligentCompletions.cache.enabled\";\n AINativeSettingSectionsId[\"IntelligentCompletionsAlwaysVisible\"] = \"ai.native.intelligentCompletions.alwaysVisible\";\n /**\n * Code edits settings\n */\n AINativeSettingSectionsId[\"CodeEditsLintErrors\"] = \"ai.native.codeEdits.lintErrors\";\n AINativeSettingSectionsId[\"CodeEditsLineChange\"] = \"ai.native.codeEdits.lineChange\";\n})(AINativeSettingSectionsId || (exports.AINativeSettingSectionsId = AINativeSettingSectionsId = {}));\nexports.AI_NATIVE_SETTING_GROUP_ID = 'AI-Native';\nexports.AI_NATIVE_SETTING_GROUP_TITLE = 'AI Native';\n//# sourceMappingURL=ai-native.js.map\n\n//# sourceURL=webpack://@opensumi/ide-components/../core-common/lib/settings/ai-native.js?");
|
|
7180
7180
|
|
|
7181
7181
|
/***/ }),
|
|
7182
7182
|
|
|
@@ -7242,7 +7242,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n//#
|
|
|
7242
7242
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
7243
7243
|
|
|
7244
7244
|
"use strict";
|
|
7245
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.StoragePaths = exports.DefaultStorageProvider = exports.STORAGE_NAMESPACE = exports.STORAGE_SCHEMA = exports.StorageResolverContribution = exports.StorageProvider = void 0;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\nconst di_1 = __webpack_require__(/*! @opensumi/di */ \"../../node_modules/@opensumi/di/dist/index.js\");\nconst ide_utils_1 = __webpack_require__(/*! @opensumi/ide-utils */ \"../utils/lib/index.js\");\nconst contribution_provider_1 = __webpack_require__(/*! ./contribution-provider */ \"../core-common/lib/contribution-provider.js\");\nexports.StorageProvider = Symbol('StorageProvider');\nexports.StorageResolverContribution = Symbol('StorageResolverContribution');\nexports.STORAGE_SCHEMA = {\n SCOPE: 'wsdb',\n GLOBAL: 'gldb',\n};\n// 在该对象定义的存储对象在初始化阶段时将默认通过 LocalStorage 缓存\n// ref: https://github.com/opensumi/core/blob/f512897d691f1aa0d89ff6469ff2251ab2124f71/packages/storage/src/browser/storage.contribution.ts#L49\nexports.STORAGE_NAMESPACE = {\n // workspace database\n WORKBENCH: new ide_utils_1.URI('workbench').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n EXTENSIONS: new ide_utils_1.URI('extensions').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n EXPLORER: new ide_utils_1.URI('explorer').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n LAYOUT: new ide_utils_1.URI('layout').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n RECENT_DATA: new ide_utils_1.URI('recent').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n DEBUG: new ide_utils_1.URI('debug').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n OUTLINE: new ide_utils_1.URI('outline').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n
|
|
7245
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.StoragePaths = exports.DefaultStorageProvider = exports.STORAGE_NAMESPACE = exports.STORAGE_SCHEMA = exports.StorageResolverContribution = exports.StorageProvider = void 0;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\nconst di_1 = __webpack_require__(/*! @opensumi/di */ \"../../node_modules/@opensumi/di/dist/index.js\");\nconst ide_utils_1 = __webpack_require__(/*! @opensumi/ide-utils */ \"../utils/lib/index.js\");\nconst contribution_provider_1 = __webpack_require__(/*! ./contribution-provider */ \"../core-common/lib/contribution-provider.js\");\nexports.StorageProvider = Symbol('StorageProvider');\nexports.StorageResolverContribution = Symbol('StorageResolverContribution');\nexports.STORAGE_SCHEMA = {\n SCOPE: 'wsdb',\n GLOBAL: 'gldb',\n};\n// 在该对象定义的存储对象在初始化阶段时将默认通过 LocalStorage 缓存\n// ref: https://github.com/opensumi/core/blob/f512897d691f1aa0d89ff6469ff2251ab2124f71/packages/storage/src/browser/storage.contribution.ts#L49\nexports.STORAGE_NAMESPACE = {\n // workspace database\n WORKBENCH: new ide_utils_1.URI('workbench').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n EXTENSIONS: new ide_utils_1.URI('extensions').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n EXPLORER: new ide_utils_1.URI('explorer').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n LAYOUT: new ide_utils_1.URI('layout').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n RECENT_DATA: new ide_utils_1.URI('recent').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n DEBUG: new ide_utils_1.URI('debug').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n OUTLINE: new ide_utils_1.URI('outline').withScheme(exports.STORAGE_SCHEMA.SCOPE),\n // global database\n GLOBAL_LAYOUT: new ide_utils_1.URI('layout-global').withScheme(exports.STORAGE_SCHEMA.GLOBAL),\n GLOBAL_EXTENSIONS: new ide_utils_1.URI('extensions').withScheme(exports.STORAGE_SCHEMA.GLOBAL),\n GLOBAL_RECENT_DATA: new ide_utils_1.URI('recent').withScheme(exports.STORAGE_SCHEMA.GLOBAL),\n};\nlet DefaultStorageProvider = class DefaultStorageProvider {\n constructor() {\n this.storageCacheMap = new Map();\n }\n /**\n * 返回对应storageId的Storage类\n */\n async get(storageId) {\n if (this.storageCacheMap.has(storageId.toString())) {\n return this.storageCacheMap.get(storageId.toString());\n }\n const resolvers = this.resolversProvider.getContributions();\n return Promise.race(resolvers.map(async (resolver) => {\n const storageResolver = await resolver.resolve(storageId);\n if (storageResolver) {\n this.storageCacheMap.set(storageId.toString(), storageResolver);\n return storageResolver;\n }\n }));\n }\n};\nexports.DefaultStorageProvider = DefaultStorageProvider;\ntslib_1.__decorate([\n (0, di_1.Autowired)(exports.StorageResolverContribution),\n tslib_1.__metadata(\"design:type\", Object)\n], DefaultStorageProvider.prototype, \"resolversProvider\", void 0);\nexports.DefaultStorageProvider = DefaultStorageProvider = tslib_1.__decorate([\n (0, di_1.Injectable)()\n], DefaultStorageProvider);\nvar StoragePaths;\n(function (StoragePaths) {\n StoragePaths.WINDOWS_APP_DATA_DIR = 'AppData';\n StoragePaths.WINDOWS_ROAMING_DIR = 'Roaming';\n // 可通过AppConfig配置替换,目前仅作为默认值使用\n StoragePaths.DEFAULT_STORAGE_DIR_NAME = '.sumi';\n StoragePaths.DEFAULT_DATA_DIR_NAME = 'datas';\n StoragePaths.MARKETPLACE_DIR = 'extensions';\n StoragePaths.EXTENSIONS_LOGS_DIR = 'extensions';\n StoragePaths.EXTENSIONS_GLOBAL_STORAGE_DIR = 'extension-storage';\n StoragePaths.EXTENSIONS_WORKSPACE_STORAGE_DIR = 'workspace-storage';\n})(StoragePaths || (exports.StoragePaths = StoragePaths = {}));\n//# sourceMappingURL=storage.js.map\n\n//# sourceURL=webpack://@opensumi/ide-components/../core-common/lib/storage.js?");
|
|
7246
7246
|
|
|
7247
7247
|
/***/ }),
|
|
7248
7248
|
|
|
@@ -7286,7 +7286,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n//#
|
|
|
7286
7286
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
7287
7287
|
|
|
7288
7288
|
"use strict";
|
|
7289
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.ECodeEditsSourceTyping = exports.ChatAgentViewServiceToken = exports.ChatServiceToken = exports.IntelligentCompletionsRegistryToken = exports.TerminalRegistryToken = exports.ProblemFixRegistryToken = exports.RenameCandidatesProviderRegistryToken = exports.ResolveConflictRegistryToken = exports.ChatRenderRegistryToken = exports.ChatFeatureRegistryToken = exports.InlineChatFeatureRegistryToken = exports.CancelResponse = exports.ErrorResponse = exports.ReplyResponse = exports.AIBackSerivcePath = exports.AIBackSerivceToken = exports.ECompletionType = void 0;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\ntslib_1.__exportStar(__webpack_require__(/*! ./reporter */ \"../core-common/lib/types/ai-native/reporter.js\"), exports);\nvar ECompletionType;\n(function (ECompletionType) {\n /**\n * 行补全\n */\n ECompletionType[ECompletionType[\"Line\"] = 0] = \"Line\";\n /**\n * 片段补全\n */\n ECompletionType[ECompletionType[\"Snippet\"] = 1] = \"Snippet\";\n /**\n * 块补全\n */\n ECompletionType[ECompletionType[\"Block\"] = 2] = \"Block\";\n})(ECompletionType || (exports.ECompletionType = ECompletionType = {}));\nexports.AIBackSerivceToken = Symbol('AIBackSerivceToken');\nexports.AIBackSerivcePath = 'AIBackSerivcePath';\nclass ReplyResponse {\n get message() {\n return this._message;\n }\n constructor(_message) {\n this._message = _message;\n }\n static is(response) {\n return response instanceof ReplyResponse || (typeof response === 'object' && response.message !== undefined);\n }\n extractCodeContent() {\n const regex = /```\\w*([\\s\\S]+?)\\s*```/;\n const match = regex.exec(this.message);\n return match ? match[1].trim() : this.message.trim();\n }\n updateMessage(msg) {\n this._message = msg;\n }\n}\nexports.ReplyResponse = ReplyResponse;\nclass ErrorResponse {\n constructor(error, message) {\n this.error = error;\n this.message = message;\n }\n static is(response) {\n return response instanceof ErrorResponse || (typeof response === 'object' && response.error !== undefined);\n }\n}\nexports.ErrorResponse = ErrorResponse;\nclass CancelResponse {\n constructor(message) {\n this.message = message;\n this.cancellation = true;\n }\n static is(response) {\n return response instanceof CancelResponse || (typeof response === 'object' && response.cancellation !== undefined);\n }\n}\nexports.CancelResponse = CancelResponse;\n/**\n * DI Token\n */\nexports.InlineChatFeatureRegistryToken = Symbol('InlineChatFeatureRegistryToken');\nexports.ChatFeatureRegistryToken = Symbol('ChatFeatureRegistryToken');\nexports.ChatRenderRegistryToken = Symbol('ChatRenderRegistryToken');\nexports.ResolveConflictRegistryToken = Symbol('ResolveConflictRegistryToken');\nexports.RenameCandidatesProviderRegistryToken = Symbol('RenameCandidatesProviderRegistryToken');\nexports.ProblemFixRegistryToken = Symbol('ProblemFixRegistryToken');\nexports.TerminalRegistryToken = Symbol('TerminalRegistryToken');\nexports.IntelligentCompletionsRegistryToken = Symbol('IntelligentCompletionsRegistryToken');\nexports.ChatServiceToken = Symbol('ChatServiceToken');\nexports.ChatAgentViewServiceToken = Symbol('ChatAgentViewServiceToken');\n// ## Code Edits start ##\nvar ECodeEditsSourceTyping;\n(function (ECodeEditsSourceTyping) {\n ECodeEditsSourceTyping[\"LinterErrors\"] = \"lint_errors\";\n ECodeEditsSourceTyping[\"LineChange\"] = \"line_change\";\n
|
|
7289
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.ECodeEditsSourceTyping = exports.ChatAgentViewServiceToken = exports.ChatServiceToken = exports.IntelligentCompletionsRegistryToken = exports.TerminalRegistryToken = exports.ProblemFixRegistryToken = exports.RenameCandidatesProviderRegistryToken = exports.ResolveConflictRegistryToken = exports.ChatRenderRegistryToken = exports.ChatFeatureRegistryToken = exports.InlineChatFeatureRegistryToken = exports.CancelResponse = exports.ErrorResponse = exports.ReplyResponse = exports.AIBackSerivcePath = exports.AIBackSerivceToken = exports.ECompletionType = void 0;\nconst tslib_1 = __webpack_require__(/*! tslib */ \"../../node_modules/tslib/tslib.es6.mjs\");\ntslib_1.__exportStar(__webpack_require__(/*! ./reporter */ \"../core-common/lib/types/ai-native/reporter.js\"), exports);\nvar ECompletionType;\n(function (ECompletionType) {\n /**\n * 行补全\n */\n ECompletionType[ECompletionType[\"Line\"] = 0] = \"Line\";\n /**\n * 片段补全\n */\n ECompletionType[ECompletionType[\"Snippet\"] = 1] = \"Snippet\";\n /**\n * 块补全\n */\n ECompletionType[ECompletionType[\"Block\"] = 2] = \"Block\";\n})(ECompletionType || (exports.ECompletionType = ECompletionType = {}));\nexports.AIBackSerivceToken = Symbol('AIBackSerivceToken');\nexports.AIBackSerivcePath = 'AIBackSerivcePath';\nclass ReplyResponse {\n get message() {\n return this._message;\n }\n constructor(_message) {\n this._message = _message;\n }\n static is(response) {\n return response instanceof ReplyResponse || (typeof response === 'object' && response.message !== undefined);\n }\n extractCodeContent() {\n const regex = /```\\w*([\\s\\S]+?)\\s*```/;\n const match = regex.exec(this.message);\n return match ? match[1].trim() : this.message.trim();\n }\n updateMessage(msg) {\n this._message = msg;\n }\n}\nexports.ReplyResponse = ReplyResponse;\nclass ErrorResponse {\n constructor(error, message) {\n this.error = error;\n this.message = message;\n }\n static is(response) {\n return response instanceof ErrorResponse || (typeof response === 'object' && response.error !== undefined);\n }\n}\nexports.ErrorResponse = ErrorResponse;\nclass CancelResponse {\n constructor(message) {\n this.message = message;\n this.cancellation = true;\n }\n static is(response) {\n return response instanceof CancelResponse || (typeof response === 'object' && response.cancellation !== undefined);\n }\n}\nexports.CancelResponse = CancelResponse;\n/**\n * DI Token\n */\nexports.InlineChatFeatureRegistryToken = Symbol('InlineChatFeatureRegistryToken');\nexports.ChatFeatureRegistryToken = Symbol('ChatFeatureRegistryToken');\nexports.ChatRenderRegistryToken = Symbol('ChatRenderRegistryToken');\nexports.ResolveConflictRegistryToken = Symbol('ResolveConflictRegistryToken');\nexports.RenameCandidatesProviderRegistryToken = Symbol('RenameCandidatesProviderRegistryToken');\nexports.ProblemFixRegistryToken = Symbol('ProblemFixRegistryToken');\nexports.TerminalRegistryToken = Symbol('TerminalRegistryToken');\nexports.IntelligentCompletionsRegistryToken = Symbol('IntelligentCompletionsRegistryToken');\nexports.ChatServiceToken = Symbol('ChatServiceToken');\nexports.ChatAgentViewServiceToken = Symbol('ChatAgentViewServiceToken');\n// ## Code Edits start ##\nvar ECodeEditsSourceTyping;\n(function (ECodeEditsSourceTyping) {\n ECodeEditsSourceTyping[\"LinterErrors\"] = \"lint_errors\";\n ECodeEditsSourceTyping[\"LineChange\"] = \"line_change\";\n})(ECodeEditsSourceTyping || (exports.ECodeEditsSourceTyping = ECodeEditsSourceTyping = {}));\n// ## Code Edits ends ##\n//# sourceMappingURL=index.js.map\n\n//# sourceURL=webpack://@opensumi/ide-components/../core-common/lib/types/ai-native/index.js?");
|
|
7290
7290
|
|
|
7291
7291
|
/***/ }),
|
|
7292
7292
|
|
|
@@ -7374,7 +7374,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
|
7374
7374
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
7375
7375
|
|
|
7376
7376
|
"use strict";
|
|
7377
|
-
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.
|
|
7377
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.VSCFileChangeType = exports.FileChangeType = exports.FileChangeEvent = exports.FileChange = void 0;\nconst ide_utils_1 = __webpack_require__(/*! @opensumi/ide-utils */ \"../utils/lib/index.js\");\nvar FileChange;\n(function (FileChange) {\n function isUpdated(change, uri) {\n return change.type === FileChangeType.UPDATED && uri.toString() === change.uri;\n }\n FileChange.isUpdated = isUpdated;\n function isAdded(change, uri) {\n return change.type === FileChangeType.ADDED && uri.toString() === change.uri;\n }\n FileChange.isAdded = isAdded;\n function isDeleted(change, uri) {\n return change.type === FileChangeType.DELETED && ide_utils_1.URI.file(change.uri).isEqualOrParent(uri);\n }\n FileChange.isDeleted = isDeleted;\n function isAffected(change, uri) {\n return isDeleted(change, uri) || uri.toString() === change.uri;\n }\n FileChange.isAffected = isAffected;\n function isChanged(change, uri) {\n return !isDeleted(change, uri) && uri.toString() === change.uri;\n }\n FileChange.isChanged = isChanged;\n})(FileChange || (exports.FileChange = FileChange = {}));\nvar FileChangeEvent;\n(function (FileChangeEvent) {\n function isUpdated(event, uri) {\n return event.some((change) => FileChange.isUpdated(change, uri));\n }\n FileChangeEvent.isUpdated = isUpdated;\n function isAdded(event, uri) {\n return event.some((change) => FileChange.isAdded(change, uri));\n }\n FileChangeEvent.isAdded = isAdded;\n function isDeleted(event, uri) {\n return event.some((change) => FileChange.isDeleted(change, uri));\n }\n FileChangeEvent.isDeleted = isDeleted;\n function isAffected(event, uri) {\n return event.some((change) => FileChange.isAffected(change, uri));\n }\n FileChangeEvent.isAffected = isAffected;\n function isChanged(event, uri) {\n return !isDeleted(event, uri) && event.some((change) => FileChange.isChanged(change, uri));\n }\n FileChangeEvent.isChanged = isChanged;\n})(FileChangeEvent || (exports.FileChangeEvent = FileChangeEvent = {}));\nvar FileChangeType;\n(function (FileChangeType) {\n FileChangeType[FileChangeType[\"UPDATED\"] = 0] = \"UPDATED\";\n FileChangeType[FileChangeType[\"ADDED\"] = 1] = \"ADDED\";\n FileChangeType[FileChangeType[\"DELETED\"] = 2] = \"DELETED\";\n})(FileChangeType || (exports.FileChangeType = FileChangeType = {}));\nvar VSCFileChangeType;\n(function (VSCFileChangeType) {\n /**\n * The contents or metadata of a file have changed.\n */\n VSCFileChangeType[VSCFileChangeType[\"Changed\"] = 1] = \"Changed\";\n /**\n * A file has been created.\n */\n VSCFileChangeType[VSCFileChangeType[\"Created\"] = 2] = \"Created\";\n /**\n * A file has been deleted.\n */\n VSCFileChangeType[VSCFileChangeType[\"Deleted\"] = 3] = \"Deleted\";\n})(VSCFileChangeType || (exports.VSCFileChangeType = VSCFileChangeType = {}));\n//# sourceMappingURL=file-watch.js.map\n\n//# sourceURL=webpack://@opensumi/ide-components/../core-common/lib/types/file-watch.js?");
|
|
7378
7378
|
|
|
7379
7379
|
/***/ }),
|
|
7380
7380
|
|
|
@@ -56,7 +56,7 @@ class IconManager {
|
|
|
56
56
|
}
|
|
57
57
|
const iconValue = this._iconMap[this._ktIconPrefixes[lastIndex]][iconKey];
|
|
58
58
|
if (!iconValue) {
|
|
59
|
-
(0, warning_1.default)(false, '
|
|
59
|
+
(0, warning_1.default)(false, '图标库缺失图标:' + iconKey);
|
|
60
60
|
return [];
|
|
61
61
|
}
|
|
62
62
|
return [`${this._ktIconPrefixes[lastIndex]}${iconValue}`];
|