UNPKG

@atlaskit/editor-plugin-show-diff

Version:

ShowDiff plugin for @atlaskit/editor-core

81 lines (76 loc) 3.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.attrAwareTokenEncoder = void 0; var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils"); var _diffableAttrs = require("../decorations/utils/diffableAttrs"); /** * Attribute-aware token encoder for `prosemirror-changeset`. The default encoder * reduces a node to `node.type.name`, so an attribute-only change (e.g. a table * cell recolour) tokenises identically on both sides and goes undetected. This * folds the diffable attributes (from the shared `diffableAttrs` map) into the * open token so such changes register. */ // Stable composite token; attr names are pre-ordered by the caller. var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) { var _node$attrs; var attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {}; var parts = attrNames.map(function (name) { var _attrs$name; return "".concat(name, "=").concat(JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null)); }); return "".concat(node.type.name, "|").concat(parts.join('|')); }; // Fold a character's marks (type + attrs) into its token so a formatting-only change // (bold/italic/link/colour, or a link whose `href` changes) registers as a real diff. // The default encoder returns just the char code, so marked and unmarked text tokenise // identically. Marks and their attrs are sorted so the token is order-independent. var encodeCharacterWithMarks = function encodeCharacterWithMarks(char, marks) { if (marks.length === 0) { // Fast path: unmarked text keeps the numeric char code (unchanged behaviour). return char; } var markKey = marks.map(function (mark) { var _mark$attrs; var attrs = (_mark$attrs = mark.attrs) !== null && _mark$attrs !== void 0 ? _mark$attrs : {}; var attrParts = Object.keys(attrs).sort().map(function (key) { var _attrs$key; return "".concat(key, "=").concat(JSON.stringify((_attrs$key = attrs[key]) !== null && _attrs$key !== void 0 ? _attrs$key : null)); }); return attrParts.length > 0 ? "".concat(mark.type.name, "(").concat(attrParts.join(','), ")") : mark.type.name; }).sort().join('&'); return "".concat(char, "\0").concat(markKey); }; // Like the library default, but node types with a `diffableAttrs` rule fold their // attrs into the open token, and text characters fold in their marks. Node-end is // unchanged, hence `string | number`. var attrAwareTokenEncoder = exports.attrAwareTokenEncoder = { encodeCharacter: function encodeCharacter(char, marks) { return encodeCharacterWithMarks(char, marks); }, encodeNodeStart: function encodeNodeStart(node) { var _node$attrs2; // Normalise variants (e.g. `panel_c1` → `panel`) so `diffableAttrs` needs one entry. var attrNames = (0, _diffableAttrs.getDiffableAttrNames)((0, _nodeTypeUtils.getBaseNodeTypeName)(node.type), (_node$attrs2 = node.attrs) !== null && _node$attrs2 !== void 0 ? _node$attrs2 : {}); if (attrNames && attrNames.length > 0) { return encodeNodeWithAttrs(node, attrNames); } return node.type.name; }, encodeNodeEnd: function encodeNodeEnd(node) { return -typeID(node.type); }, compareTokens: function compareTokens(a, b) { return a === b; } }; // Mirrors the library's private (unexported) `typeID` so node-end tokens match. function typeID(type) { var cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null)); var id = cache[type.name]; if (id == null) { cache[type.name] = id = Object.keys(type.schema.nodes).indexOf(type.name) + 1; } return id; }