@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
1 lines • 5.81 kB
Source Map (JSON)
{"version":3,"file":"last_active_nodes.cjs","sources":["../../../../recipes/conversation_view/message_input/last_active_nodes.js"],"sourcesContent":["/* eslint-disable complexity */\n/**\n * This function was taken from this thread and modified to work in pure JS:\n * https://github.com/ueberdosis/tiptap/issues/1058#issuecomment-778254557\n *\n * description: This helper, lastActiveNodes, finds the last (furthest from the root document)\n * matching types in your selection (ignoring nesting), you can give it either a list of args\n * similar to isActive or a group name, calling it like below. It will return a list of node\n * type names that are the last ones active in the selection, if the selection is 'empty'\n * (just the cursor) the returned list will only have at most one name.\n * This lets you build a UI for lists that works the same as most word processors.\n *\n * @param {Object} state the tiptap editor instance state\n * @param {*} typesOrGroup node types or node group name to consider\n * @returns {Array} node(s) that are the farthest from the root that matches the given type or group\n */\nexport default function lastActiveNodes (state, typesOrGroup) {\n if (!state) return [];\n\n const { from, to } = state.selection;\n let types;\n\n if (typeof typesOrGroup === 'string') {\n // types is a name of a node group\n types = Object.entries(state.schema.nodes)\n .filter(([name, nodeType]) => nodeType.groups.includes(typesOrGroup))\n .map(([name, nodeType]) => {\n return {\n type: nodeType,\n };\n });\n } else {\n // types is a list of LastActiveNodeItemOption\n types = typesOrGroup;\n for (const item of types) {\n item.type = item.type ? getNodeType(item.type, state.schema) : null;\n }\n }\n\n let lastNode = null;\n let lastMatchedType = null;\n const matchedTypes = new Set();\n const notFoundTypes = new Set(types);\n\n state.doc.nodesBetween(from, to, (node, pos, parent) => {\n if (notFoundTypes.size === 0) return false;\n if (!node.isText) {\n const matchedType = types.filter((item) => {\n if (!item.type) {\n return true;\n }\n if (typeof item.type === 'string') return false; // Typeguard, shouldn't happen\n return node.type.name === item.type.name;\n })\n .find(item => {\n if (!item.attributes) return true;\n return objectIncludes(node.attrs, item.attributes);\n });\n if (matchedType) {\n if (lastMatchedType && lastNode && (lastNode !== parent)) {\n notFoundTypes.delete(lastMatchedType);\n matchedTypes.add(lastMatchedType);\n }\n lastMatchedType = matchedType;\n }\n lastNode = node;\n }\n });\n\n if (lastMatchedType) {\n matchedTypes.add(lastMatchedType);\n }\n\n return [...matchedTypes.values()].map((item) => {\n if (item.key) {\n return item.key;\n } else if (typeof item.type === 'string') {\n return item.type;\n } else if (item.type?.name) {\n return item.type.name;\n } else {\n return '';\n }\n });\n}\n\nfunction getNodeType (nameOrType, schema) {\n if (typeof nameOrType === 'string') {\n if (!schema.nodes[nameOrType]) {\n throw Error(\n `There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`,\n );\n }\n\n return schema.nodes[nameOrType];\n }\n\n return nameOrType;\n}\n\nexport function objectIncludes (\n object1,\n object2,\n options,\n) {\n const keys = Object.keys(object2);\n\n if (!keys.length) {\n return true;\n }\n\n return keys.every(key => {\n if (options.strict) {\n return object2[key] === object1[key];\n }\n\n if (Object.prototype.toString.call(object2[key]) === '[object RegExp]') {\n return object2[key].test(object1[key]);\n }\n\n return object2[key] === object1[key];\n });\n}\n"],"names":[],"mappings":";;AAgBe,SAAS,gBAAiB,OAAO,cAAc;AAC5D,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,EAAE,MAAM,OAAO,MAAM;AAC3B,MAAI;AAEJ,MAAI,OAAO,iBAAiB,UAAU;AAEpC,YAAQ,OAAO,QAAQ,MAAM,OAAO,KAAK,EACtC,OAAO,CAAC,CAAC,MAAM,QAAQ,MAAM,SAAS,OAAO,SAAS,YAAY,CAAC,EACnE,IAAI,CAAC,CAAC,MAAM,QAAQ,MAAM;AACzB,aAAO;AAAA,QACL,MAAM;AAAA,MAChB;AAAA,IACA,CAAO;AAAA,EACP,OAAS;AAEL,YAAQ;AACR,eAAW,QAAQ,OAAO;AACxB,WAAK,OAAO,KAAK,OAAO,YAAY,KAAK,MAAM,MAAM,MAAM,IAAI;AAAA,IAChE;AAAA,EACF;AAED,MAAI,WAAW;AACf,MAAI,kBAAkB;AACtB,QAAM,eAAe,oBAAI;AACzB,QAAM,gBAAgB,IAAI,IAAI,KAAK;AAEnC,QAAM,IAAI,aAAa,MAAM,IAAI,CAAC,MAAM,KAAK,WAAW;AACtD,QAAI,cAAc,SAAS,EAAG,QAAO;AACrC,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,cAAc,MAAM,OAAO,CAAC,SAAS;AACzC,YAAI,CAAC,KAAK,MAAM;AACd,iBAAO;AAAA,QACR;AACD,YAAI,OAAO,KAAK,SAAS,SAAU,QAAO;AAC1C,eAAO,KAAK,KAAK,SAAS,KAAK,KAAK;AAAA,MAC5C,CAAO,EACE,KAAK,UAAQ;AACZ,YAAI,CAAC,KAAK,WAAY,QAAO;AAC7B,eAAO,eAAe,KAAK,OAAO,KAAK,UAAU;AAAA,MAC3D,CAAS;AACH,UAAI,aAAa;AACf,YAAI,mBAAmB,YAAa,aAAa,QAAS;AACxD,wBAAc,OAAO,eAAe;AACpC,uBAAa,IAAI,eAAe;AAAA,QACjC;AACD,0BAAkB;AAAA,MACnB;AACD,iBAAW;AAAA,IACZ;AAAA,EACL,CAAG;AAED,MAAI,iBAAiB;AACnB,iBAAa,IAAI,eAAe;AAAA,EACjC;AAED,SAAO,CAAC,GAAG,aAAa,OAAQ,CAAA,EAAE,IAAI,CAAC,SAAS;;AAC9C,QAAI,KAAK,KAAK;AACZ,aAAO,KAAK;AAAA,IACb,WAAU,OAAO,KAAK,SAAS,UAAU;AACxC,aAAO,KAAK;AAAA,IAClB,YAAe,UAAK,SAAL,mBAAW,MAAM;AAC1B,aAAO,KAAK,KAAK;AAAA,IACvB,OAAW;AACL,aAAO;AAAA,IACR;AAAA,EACL,CAAG;AACH;AAEA,SAAS,YAAa,YAAY,QAAQ;AACxC,MAAI,OAAO,eAAe,UAAU;AAClC,QAAI,CAAC,OAAO,MAAM,UAAU,GAAG;AAC7B,YAAM;AAAA,QACJ,gCAAgC,UAAU;AAAA,MAClD;AAAA,IACK;AAED,WAAO,OAAO,MAAM,UAAU;AAAA,EAC/B;AAED,SAAO;AACT;AAEO,SAAS,eACd,SACA,SACA,SACA;AACA,QAAM,OAAO,OAAO,KAAK,OAAO;AAEhC,MAAI,CAAC,KAAK,QAAQ;AAChB,WAAO;AAAA,EACR;AAED,SAAO,KAAK,MAAM,SAAO;AAKvB,QAAI,OAAO,UAAU,SAAS,KAAK,QAAQ,GAAG,CAAC,MAAM,mBAAmB;AACtE,aAAO,QAAQ,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC;AAAA,IACtC;AAED,WAAO,QAAQ,GAAG,MAAM,QAAQ,GAAG;AAAA,EACvC,CAAG;AACH;;;"}