@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
1 lines • 5.21 kB
Source Map (JSON)
{"version":3,"file":"last-active-nodes.cjs","names":[],"sources":["../../../recipes/conversation_view/message_input/last_active_nodes.js"],"sourcesContent":[" \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(([, nodeType]) => nodeType.groups.includes(typesOrGroup))\n .map(([, 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"],"mappings":"+FAgBA,SAAwB,EAAiB,EAAO,EAAc,CAC5D,GAAI,CAAC,EAAO,MAAO,EAAE,CAErB,GAAM,CAAE,OAAM,MAAO,EAAM,UACvB,EAEJ,GAAI,OAAO,GAAiB,SAE1B,EAAQ,OAAO,QAAQ,EAAM,OAAO,MAAM,CACvC,QAAQ,EAAG,KAAc,EAAS,OAAO,SAAS,EAAa,CAAC,CAChE,KAAK,EAAG,MACA,CACL,KAAM,EACP,EACD,KACC,CAEL,EAAQ,EACR,IAAK,IAAM,KAAQ,EACjB,EAAK,KAAO,EAAK,KAAO,EAAY,EAAK,KAAM,EAAM,OAAO,CAAG,KAInE,IAAI,EAAW,KACX,EAAkB,KAChB,EAAe,IAAI,IACnB,EAAgB,IAAI,IAAI,EAAM,CA+BpC,OA7BA,EAAM,IAAI,aAAa,EAAM,GAAK,EAAM,EAAK,IAAW,CACtD,GAAI,EAAc,OAAS,EAAG,MAAO,GACrC,GAAI,CAAC,EAAK,OAAQ,CAChB,IAAM,EAAc,EAAM,OAAQ,GAC3B,EAAK,KAGN,OAAO,EAAK,MAAS,SAAiB,GACnC,EAAK,KAAK,OAAS,EAAK,KAAK,KAH3B,GAIT,CACC,KAAK,GACC,EAAK,WACH,EAAe,EAAK,MAAO,EAAK,WAAW,CADrB,GAE7B,CACA,IACE,GAAmB,GAAa,IAAa,IAC/C,EAAc,OAAO,EAAgB,CACrC,EAAa,IAAI,EAAgB,EAEnC,EAAkB,GAEpB,EAAW,IAEb,CAEE,GACF,EAAa,IAAI,EAAgB,CAG5B,CAAC,GAAG,EAAa,QAAQ,CAAC,CAAC,IAAK,GACjC,EAAK,IACA,EAAK,IACH,OAAO,EAAK,MAAS,SACvB,EAAK,KACH,EAAK,MAAM,KACb,EAAK,KAAK,KAEV,GAET,CAGJ,SAAS,EAAa,EAAY,EAAQ,CACxC,GAAI,OAAO,GAAe,SAAU,CAClC,GAAI,CAAC,EAAO,MAAM,GAChB,MAAM,MACJ,gCAAgC,EAAW,2CAC5C,CAGH,OAAO,EAAO,MAAM,GAGtB,OAAO,EAGT,SAAgB,EACd,EACA,EACA,EACA,CACA,IAAM,EAAO,OAAO,KAAK,EAAQ,CAMjC,OAJK,EAAK,OAIH,EAAK,MAAM,GACZ,EAAQ,OACH,EAAQ,KAAS,EAAQ,GAG9B,OAAO,UAAU,SAAS,KAAK,EAAQ,GAAK,GAAK,kBAC5C,EAAQ,GAAK,KAAK,EAAQ,GAAK,CAGjC,EAAQ,KAAS,EAAQ,GAChC,CAbO"}