wikiparser-node
Version:
A Node.js parser for MediaWiki markup with AST
104 lines (103 loc) • 3.29 kB
JavaScript
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;
;