UNPKG

wikiparser-node

Version:

A Node.js parser for MediaWiki markup with AST

104 lines (103 loc) 3.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.undo = exports.mixin = exports.setChildNodes = exports.isToken = exports.Shadow = void 0; exports.Shadow = { running: false, /** @private */ run(callback) { const { running } = this; this.running = true; try { const { Token: AnyToken } = require('../src/index'); const result = callback(); if (result instanceof AnyToken && !result.getAttribute('built')) { result.afterBuild(); } this.running = running; return result; } catch (e) /* istanbul ignore next */ { this.running = running; throw e; } }, rev: 0, }; /** * 是否是某一特定类型的节点 * @param type 节点类型 */ const isToken = (type) => (node) => node.type === type; exports.isToken = isToken; /** * 更新chldNodes * @param parent 父节点 * @param position 子节点位置 * @param deleteCount 移除的子节点数量 * @param inserted 插入的子节点 */ const setChildNodes = (parent, position, deleteCount, inserted = []) => { let nodes = parent.getChildNodes(), removed; if (nodes.length === deleteCount) { removed = nodes; nodes = inserted; } else { removed = nodes.splice(position, deleteCount, ...inserted); } for (let i = 0; i < inserted.length; i++) { const node = inserted[i]; node.setAttribute('parentNode', parent); node.setAttribute('nextSibling', nodes[position + i + 1]); node.setAttribute('previousSibling', nodes[position + i - 1]); } nodes[position - 1]?.setAttribute('nextSibling', nodes[position]); nodes[position + inserted.length]?.setAttribute('previousSibling', nodes[position + inserted.length - 1]); parent.setAttribute('childNodes', nodes); /* NOT FOR BROWSER */ for (const node of removed) { node.setAttribute('parentNode', undefined); } /* NOT FOR BROWSER END */ return removed; }; exports.setChildNodes = setChildNodes; /* NOT FOR BROWSER ONLY */ /** * 同步混入的类名 * @param target 混入的目标 * @param source 混入的源 */ const mixin = (target, source) => { Object.defineProperty(target, 'name', { value: source.name }); }; exports.mixin = mixin; /* NOT FOR BROWSER ONLY END */ /* NOT FOR BROWSER */ /** * 撤销最近一次Mutation * @param e 事件 * @param data 事件数据 * @throws `RangeError` 无法撤销的事件类型 */ const undo = (e, data) => { const { target, type } = e; switch (data.type) { case 'remove': (0, exports.setChildNodes)(target, data.position, 0, [data.removed]); break; case 'insert': (0, exports.setChildNodes)(target, data.position, 1); break; case 'replace': (0, exports.setChildNodes)(target.parentNode, data.position, 1, [data.oldToken]); break; case 'text': target.setAttribute('data', data.oldText); break; /* istanbul ignore next */ default: throw new RangeError(`Unable to undo events with an unknown type: ${type}`); } }; exports.undo = undo;