@aquera/nile-elements 1.9.8 → 1.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/{index-df196058.cjs.js → index-50880eb7.cjs.js} +2 -2
- package/dist/index-50880eb7.cjs.js.map +1 -0
- package/dist/index-6832c52b.cjs.js +2 -0
- package/dist/index-6832c52b.cjs.js.map +1 -0
- package/dist/index-747d1880.cjs.js +2 -0
- package/dist/index-747d1880.cjs.js.map +1 -0
- package/dist/{index-249de90a.esm.js → index-7b1c9857.esm.js} +1 -1
- package/dist/index-a487d8b4.esm.js +1 -0
- package/dist/index-ba47645d.esm.js +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1589 -1277
- package/dist/katex-44476ab4.esm.js +1 -0
- package/dist/katex-f4186f87.cjs.js +2 -0
- package/dist/katex-f4186f87.cjs.js.map +1 -0
- package/dist/nile-checkbox/nile-checkbox.cjs.js +1 -1
- package/dist/nile-checkbox/nile-checkbox.cjs.js.map +1 -1
- package/dist/nile-checkbox/nile-checkbox.esm.js +1 -1
- package/dist/nile-color-picker/index.cjs.js +1 -1
- package/dist/nile-color-picker/index.esm.js +1 -1
- package/dist/nile-color-picker/nile-color-picker.cjs.js +1 -1
- package/dist/nile-color-picker/nile-color-picker.cjs.js.map +1 -1
- package/dist/nile-color-picker/nile-color-picker.esm.js +1 -1
- package/dist/nile-combobox/index.cjs.js +1 -1
- package/dist/nile-combobox/index.esm.js +1 -1
- package/dist/nile-combobox/nile-combobox.cjs.js +1 -1
- package/dist/nile-combobox/nile-combobox.esm.js +1 -1
- package/dist/nile-detail/index.cjs.js +1 -1
- package/dist/nile-detail/index.esm.js +1 -1
- package/dist/nile-detail/nile-detail.cjs.js +1 -1
- package/dist/nile-detail/nile-detail.esm.js +1 -1
- package/dist/nile-nav-tab/nile-nav-tab.cjs.js +1 -1
- package/dist/nile-nav-tab/nile-nav-tab.cjs.js.map +1 -1
- package/dist/nile-nav-tab/nile-nav-tab.css.cjs.js +1 -1
- package/dist/nile-nav-tab/nile-nav-tab.css.cjs.js.map +1 -1
- package/dist/nile-nav-tab/nile-nav-tab.css.esm.js +11 -0
- package/dist/nile-nav-tab/nile-nav-tab.esm.js +1 -1
- package/dist/nile-nav-tab-group/nile-nav-tab-group.css.cjs.js +1 -1
- package/dist/nile-nav-tab-group/nile-nav-tab-group.css.cjs.js.map +1 -1
- package/dist/nile-nav-tab-group/nile-nav-tab-group.css.esm.js +1 -2
- package/dist/nile-wysiwyg-editor/engine/commands.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/commands.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/commands.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/create-state.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/index.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/index.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/keymap.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/embeds.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/image.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/math-view.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/math-view.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/math-view.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/style-block-view.cjs.js +2 -0
- package/dist/nile-wysiwyg-editor/engine/plugins/style-block-view.cjs.js.map +1 -0
- package/dist/nile-wysiwyg-editor/engine/plugins/style-block-view.esm.js +1 -0
- package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/plugins/tables.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/sanitize.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/schema.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/schema.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/schema.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/engine/selection-state.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/index.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/index.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/math/katex-renderer.cjs.js +2 -0
- package/dist/nile-wysiwyg-editor/math/katex-renderer.cjs.js.map +1 -0
- package/dist/nile-wysiwyg-editor/math/katex-renderer.esm.js +1 -0
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.esm.js +22 -3
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.esm.js +7 -6
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.cjs.js +2 -0
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.cjs.js.map +1 -0
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.esm.js +1 -0
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.esm.js +33 -54
- package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.esm.js +83 -95
- package/dist/nile-wysiwyg-editor/types.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/types.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/types.esm.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/bubble-item.cjs.js +2 -0
- package/dist/nile-wysiwyg-editor/ui/bubble-item.cjs.js.map +1 -0
- package/dist/nile-wysiwyg-editor/ui/bubble-item.esm.js +1 -0
- package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/bubble-menu.esm.js +23 -15
- package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/code-block-menu.esm.js +3 -3
- package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/embed-panel.esm.js +2 -2
- package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/math-panel.esm.js +0 -3
- package/dist/nile-wysiwyg-editor/ui/preview.cjs.js +2 -0
- package/dist/nile-wysiwyg-editor/ui/preview.cjs.js.map +1 -0
- package/dist/nile-wysiwyg-editor/ui/preview.esm.js +8 -0
- package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/source-view.esm.js +225 -24
- package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/suggest-list.esm.js +9 -9
- package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/table-grid-picker.esm.js +115 -13
- package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js +1 -1
- package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js.map +1 -1
- package/dist/nile-wysiwyg-editor/ui/table-menu.esm.js +13 -12
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/nile-checkbox/nile-checkbox.js +1 -0
- package/dist/src/nile-checkbox/nile-checkbox.js.map +1 -1
- package/dist/src/nile-color-picker/nile-color-picker.d.ts +1 -0
- package/dist/src/nile-color-picker/nile-color-picker.js +1 -0
- package/dist/src/nile-color-picker/nile-color-picker.js.map +1 -1
- package/dist/src/nile-nav-tab/nile-nav-tab.css.js +11 -0
- package/dist/src/nile-nav-tab/nile-nav-tab.css.js.map +1 -1
- package/dist/src/nile-nav-tab/nile-nav-tab.d.ts +2 -0
- package/dist/src/nile-nav-tab/nile-nav-tab.js +13 -0
- package/dist/src/nile-nav-tab/nile-nav-tab.js.map +1 -1
- package/dist/src/nile-nav-tab-group/nile-nav-tab-group.css.js +1 -2
- package/dist/src/nile-nav-tab-group/nile-nav-tab-group.css.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/index.d.ts +1 -0
- package/dist/src/nile-wysiwyg-editor/engine/index.js +1 -0
- package/dist/src/nile-wysiwyg-editor/engine/index.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.js +3 -0
- package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.d.ts +19 -4
- package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.js +23 -18
- package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.d.ts +8 -3
- package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.js +41 -4
- package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/plugins/style-block-view.d.ts +17 -0
- package/dist/src/nile-wysiwyg-editor/engine/plugins/style-block-view.js +174 -0
- package/dist/src/nile-wysiwyg-editor/engine/plugins/style-block-view.js.map +1 -0
- package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js +33 -2
- package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/pm.test.js +49 -8
- package/dist/src/nile-wysiwyg-editor/engine/pm.test.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/sanitize.d.ts +12 -0
- package/dist/src/nile-wysiwyg-editor/engine/sanitize.js +76 -8
- package/dist/src/nile-wysiwyg-editor/engine/sanitize.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/engine/schema.d.ts +2 -0
- package/dist/src/nile-wysiwyg-editor/engine/schema.js +154 -2
- package/dist/src/nile-wysiwyg-editor/engine/schema.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/index.d.ts +5 -0
- package/dist/src/nile-wysiwyg-editor/index.js +3 -0
- package/dist/src/nile-wysiwyg-editor/index.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/math/katex-renderer.d.ts +38 -0
- package/dist/src/nile-wysiwyg-editor/math/katex-renderer.js +40 -0
- package/dist/src/nile-wysiwyg-editor/math/katex-renderer.js.map +1 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js +22 -3
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.d.ts +36 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js +125 -8
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js +5 -2
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.d.ts +2 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.js +1 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.d.ts +55 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.js +79 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.js.map +1 -0
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.js +33 -54
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.d.ts +50 -2
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.js +158 -102
- package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/types.d.ts +4 -2
- package/dist/src/nile-wysiwyg-editor/types.js +2 -2
- package/dist/src/nile-wysiwyg-editor/types.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/bubble-item.d.ts +48 -0
- package/dist/src/nile-wysiwyg-editor/ui/bubble-item.js +69 -0
- package/dist/src/nile-wysiwyg-editor/ui/bubble-item.js.map +1 -0
- package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.d.ts +17 -2
- package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js +128 -35
- package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/embed-panel.d.ts +2 -1
- package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js +4 -3
- package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/math-panel.js +0 -3
- package/dist/src/nile-wysiwyg-editor/ui/math-panel.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/preview.d.ts +20 -0
- package/dist/src/nile-wysiwyg-editor/ui/preview.js +44 -0
- package/dist/src/nile-wysiwyg-editor/ui/preview.js.map +1 -0
- package/dist/src/nile-wysiwyg-editor/ui/source-view.d.ts +35 -3
- package/dist/src/nile-wysiwyg-editor/ui/source-view.js +337 -24
- package/dist/src/nile-wysiwyg-editor/ui/source-view.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/suggest-list.d.ts +1 -0
- package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js +9 -0
- package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.d.ts +13 -2
- package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js +166 -10
- package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js.map +1 -1
- package/dist/src/nile-wysiwyg-editor/ui/table-menu.d.ts +1 -0
- package/dist/src/nile-wysiwyg-editor/ui/table-menu.js +10 -8
- package/dist/src/nile-wysiwyg-editor/ui/table-menu.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/xml-25c4108a.esm.js +1 -0
- package/dist/xml-90fd974e.cjs.js +2 -0
- package/dist/xml-90fd974e.cjs.js.map +1 -0
- package/package.json +2 -1
- package/rollup.config.js +1 -0
- package/src/index.ts +8 -0
- package/src/nile-checkbox/nile-checkbox.ts +1 -0
- package/src/nile-color-picker/nile-color-picker.ts +1 -0
- package/src/nile-nav-tab/nile-nav-tab.css.ts +11 -0
- package/src/nile-nav-tab/nile-nav-tab.ts +17 -0
- package/src/nile-nav-tab-group/nile-nav-tab-group.css.ts +1 -2
- package/src/nile-wysiwyg-editor/engine/index.ts +1 -0
- package/src/nile-wysiwyg-editor/engine/plugins/embed-view.ts +3 -0
- package/src/nile-wysiwyg-editor/engine/plugins/embeds.ts +26 -20
- package/src/nile-wysiwyg-editor/engine/plugins/math-view.ts +45 -4
- package/src/nile-wysiwyg-editor/engine/plugins/style-block-view.ts +178 -0
- package/src/nile-wysiwyg-editor/engine/plugins/tables.ts +34 -2
- package/src/nile-wysiwyg-editor/engine/pm.test.ts +58 -8
- package/src/nile-wysiwyg-editor/engine/sanitize.ts +71 -8
- package/src/nile-wysiwyg-editor/engine/schema.ts +158 -7
- package/src/nile-wysiwyg-editor/index.ts +5 -0
- package/src/nile-wysiwyg-editor/math/katex-renderer.ts +59 -0
- package/src/nile-wysiwyg-editor/math/katex.d.ts +17 -0
- package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.ts +22 -3
- package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.ts +5 -2
- package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.ts +142 -7
- package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.ts +2 -0
- package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar-item.ts +68 -0
- package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.ts +33 -54
- package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.ts +202 -108
- package/src/nile-wysiwyg-editor/types.ts +6 -4
- package/src/nile-wysiwyg-editor/ui/bubble-item.ts +60 -0
- package/src/nile-wysiwyg-editor/ui/bubble-menu.ts +147 -40
- package/src/nile-wysiwyg-editor/ui/embed-panel.ts +4 -3
- package/src/nile-wysiwyg-editor/ui/math-panel.ts +0 -3
- package/src/nile-wysiwyg-editor/ui/preview.ts +42 -0
- package/src/nile-wysiwyg-editor/ui/source-view.ts +339 -31
- package/src/nile-wysiwyg-editor/ui/suggest-list.ts +10 -0
- package/src/nile-wysiwyg-editor/ui/table-grid-picker.ts +160 -10
- package/src/nile-wysiwyg-editor/ui/table-menu.ts +10 -8
- package/vscode-html-custom-data.json +75 -6
- package/dist/index-353172ed.esm.js +0 -1
- package/dist/index-b387a9f4.cjs.js +0 -2
- package/dist/index-b387a9f4.cjs.js.map +0 -1
- package/dist/index-cc1385e0.cjs.js +0 -2
- package/dist/index-cc1385e0.cjs.js.map +0 -1
- package/dist/index-dedc38a6.esm.js +0 -1
- package/dist/index-df196058.cjs.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-view.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/embed-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"embed-view.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/embed-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEhE,8EAA8E;AAC9E,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;GAIG;AACH,MAAM,OAAO,SAAS;IAKpB,YACU,IAAY,EACpB,IAAgB,EAChB,MAAgC;QAFxB,SAAI,GAAJ,IAAI,CAAQ;QAIpB,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,qBAAqB,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,OAAO,EACP,0FAA0F,CAC3F,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE,qBAAqB,CAAC,CAAC;QAClE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,mBAAmB,CACjB,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,GAAG,EACR,KAAK,CAAC,EAAE;YACN,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;YACrB,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,OAAO;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,IAAI,CAAC,QAAQ,CACX,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CACzE,CAAC;QACJ,CAAC,EACD,eAAe,CAChB,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,IAAY;QAC7B,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1D,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG;YAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,qBAAqB,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC;QACpE,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;;YAChC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QAC5B,CAAC;QACD,+DAA+D;QAC/D,IAAI,KAAK;YAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;;YACjD,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,KAAY;QACpB,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { Node as PMNode } from 'prosemirror-model';\nimport { EditorView, NodeView } from 'prosemirror-view';\nimport { attachResizeHandles, isResizeEvent } from './image-view';\nimport { EMBED_SANDBOX, EMBED_REFERRER_POLICY } from './embeds';\n\n/** Below this a 16:9 player is unusable and its own controls stop fitting. */\nconst MIN_EMBED_WIDTH = 160;\n\n/**\n * Video embed (YouTube/Vimeo/Loom) with the same corner drag-resize handles\n * as images. Only the width is dragged; the 16:9 aspect ratio comes from CSS,\n * so the height follows automatically.\n */\nexport class EmbedView implements NodeView {\n dom: HTMLDivElement;\n\n private iframe: HTMLIFrameElement;\n\n constructor(\n private node: PMNode,\n view: EditorView,\n getPos: () => number | undefined\n ) {\n this.dom = document.createElement('div');\n this.dom.className = 'nile-wysiwyg__embed';\n this.iframe = document.createElement('iframe');\n this.iframe.setAttribute('frameborder', '0');\n this.iframe.setAttribute('allowfullscreen', 'true');\n this.iframe.setAttribute(\n 'allow',\n 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'\n );\n this.iframe.setAttribute('sandbox', EMBED_SANDBOX);\n this.iframe.setAttribute('referrerpolicy', EMBED_REFERRER_POLICY);\n this.dom.appendChild(this.iframe);\n this.applyAttrs(node);\n\n attachResizeHandles(\n this.dom,\n this.dom,\n width => {\n const pos = getPos();\n if (pos === undefined || !view.editable) return;\n const current = view.state.doc.nodeAt(pos);\n if (!current) return;\n view.dispatch(\n view.state.tr.setNodeMarkup(pos, undefined, { ...current.attrs, width })\n );\n },\n MIN_EMBED_WIDTH\n );\n }\n\n private applyAttrs(node: PMNode): void {\n const { src, provider, title, width, align } = node.attrs;\n if (this.iframe.getAttribute('src') !== src) this.iframe.setAttribute('src', src);\n this.dom.setAttribute('data-embed-provider', provider ?? 'generic');\n if (title) this.iframe.title = title;\n else this.iframe.removeAttribute('title');\n if (width) {\n this.dom.setAttribute('data-width', String(width));\n this.dom.style.width = `${width}px`;\n } else {\n this.dom.removeAttribute('data-width');\n this.dom.style.width = '';\n }\n // Block alignment via auto margins (mirrors the image figure).\n if (align) this.dom.setAttribute('data-align', align);\n else this.dom.removeAttribute('data-align');\n this.dom.style.marginLeft = align === 'center' || align === 'right' ? 'auto' : '';\n this.dom.style.marginRight = align === 'center' ? 'auto' : '';\n }\n\n update(node: PMNode): boolean {\n if (node.type !== this.node.type) return false;\n this.node = node;\n this.applyAttrs(node);\n return true;\n }\n\n stopEvent(event: Event): boolean {\n return isResizeEvent(event);\n }\n\n ignoreMutation(): boolean {\n return true;\n }\n}\n"]}
|
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
import { Plugin } from 'prosemirror-state';
|
|
2
2
|
export interface EmbedTarget {
|
|
3
3
|
src: string;
|
|
4
|
-
provider: 'youtube' | 'vimeo' | 'loom';
|
|
4
|
+
provider: 'youtube' | 'vimeo' | 'loom' | 'generic';
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Sandbox tokens applied to every embed iframe. Notably this OMITS
|
|
8
|
+
* `allow-top-navigation`, so a framed page cannot redirect the whole tab
|
|
9
|
+
* (the main clickjacking/phishing vector); scripts and same-origin are
|
|
10
|
+
* allowed so third-party players still run. Kept in sync with the sanitizer.
|
|
11
|
+
*/
|
|
12
|
+
export declare const EMBED_SANDBOX = "allow-scripts allow-same-origin allow-presentation allow-popups";
|
|
13
|
+
/** Limits the referrer leaked to the embedded third-party host. */
|
|
14
|
+
export declare const EMBED_REFERRER_POLICY = "strict-origin-when-cross-origin";
|
|
15
|
+
/**
|
|
16
|
+
* Converts a URL into an embed target. Known providers (YouTube/Vimeo/Loom)
|
|
17
|
+
* are canonicalized to their dedicated embed URLs; any other `https://` URL
|
|
18
|
+
* is accepted as a `generic` embed. The iframe is always sandboxed on render
|
|
19
|
+
* (see EMBED_SANDBOX), so untrusted hosts cannot navigate the top window.
|
|
20
|
+
* Returns null only for non-https or unparseable URLs.
|
|
9
21
|
*/
|
|
10
22
|
export declare function toEmbedUrl(url: string): EmbedTarget | null;
|
|
11
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* True when a URL is permitted as an embed src (sanitizer check). Any
|
|
25
|
+
* `https://` URL is allowed; the iframe is sandboxed at render time.
|
|
26
|
+
*/
|
|
12
27
|
export declare function isAllowedEmbedSrc(src: string): boolean;
|
|
13
28
|
/**
|
|
14
29
|
* Pasting a bare provider URL onto an empty selection inserts an embed
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { Plugin } from 'prosemirror-state';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Sandbox tokens applied to every embed iframe. Notably this OMITS
|
|
4
|
+
* `allow-top-navigation`, so a framed page cannot redirect the whole tab
|
|
5
|
+
* (the main clickjacking/phishing vector); scripts and same-origin are
|
|
6
|
+
* allowed so third-party players still run. Kept in sync with the sanitizer.
|
|
7
|
+
*/
|
|
8
|
+
export const EMBED_SANDBOX = 'allow-scripts allow-same-origin allow-presentation allow-popups';
|
|
9
|
+
/** Limits the referrer leaked to the embedded third-party host. */
|
|
10
|
+
export const EMBED_REFERRER_POLICY = 'strict-origin-when-cross-origin';
|
|
11
|
+
/**
|
|
12
|
+
* Converts a URL into an embed target. Known providers (YouTube/Vimeo/Loom)
|
|
13
|
+
* are canonicalized to their dedicated embed URLs; any other `https://` URL
|
|
14
|
+
* is accepted as a `generic` embed. The iframe is always sandboxed on render
|
|
15
|
+
* (see EMBED_SANDBOX), so untrusted hosts cannot navigate the top window.
|
|
16
|
+
* Returns null only for non-https or unparseable URLs.
|
|
5
17
|
*/
|
|
6
18
|
export function toEmbedUrl(url) {
|
|
7
19
|
let parsed;
|
|
@@ -29,42 +41,35 @@ export function toEmbedUrl(url) {
|
|
|
29
41
|
if (/^[\w-]{6,20}$/.test(id)) {
|
|
30
42
|
return { src: `https://www.youtube-nocookie.com/embed/${id}`, provider: 'youtube' };
|
|
31
43
|
}
|
|
32
|
-
return null;
|
|
33
44
|
}
|
|
34
45
|
// Vimeo: vimeo.com/123456789, player.vimeo.com/video/123456789
|
|
35
|
-
if (host === 'vimeo.com' || host === 'player.vimeo.com') {
|
|
46
|
+
else if (host === 'vimeo.com' || host === 'player.vimeo.com') {
|
|
36
47
|
const match = /\/(?:video\/)?(\d{6,12})(?:$|[/?])/.exec(parsed.pathname);
|
|
37
48
|
if (match) {
|
|
38
49
|
return { src: `https://player.vimeo.com/video/${match[1]}`, provider: 'vimeo' };
|
|
39
50
|
}
|
|
40
|
-
return null;
|
|
41
51
|
}
|
|
42
52
|
// Loom: loom.com/share/ID or loom.com/embed/ID
|
|
43
|
-
if (host === 'loom.com') {
|
|
53
|
+
else if (host === 'loom.com') {
|
|
44
54
|
const match = /^\/(share|embed)\/([0-9a-f]{16,40})/.exec(parsed.pathname);
|
|
45
55
|
if (match) {
|
|
46
56
|
return { src: `https://www.loom.com/embed/${match[2]}`, provider: 'loom' };
|
|
47
57
|
}
|
|
48
|
-
return null;
|
|
49
58
|
}
|
|
50
|
-
|
|
59
|
+
// Any other https URL: embed as-is, sandboxed.
|
|
60
|
+
return { src: parsed.href, provider: 'generic' };
|
|
51
61
|
}
|
|
52
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* True when a URL is permitted as an embed src (sanitizer check). Any
|
|
64
|
+
* `https://` URL is allowed; the iframe is sandboxed at render time.
|
|
65
|
+
*/
|
|
53
66
|
export function isAllowedEmbedSrc(src) {
|
|
54
|
-
let parsed;
|
|
55
67
|
try {
|
|
56
|
-
|
|
68
|
+
return new URL(src.trim()).protocol === 'https:';
|
|
57
69
|
}
|
|
58
70
|
catch {
|
|
59
71
|
return false;
|
|
60
72
|
}
|
|
61
|
-
if (parsed.protocol !== 'https:')
|
|
62
|
-
return false;
|
|
63
|
-
const host = parsed.hostname.replace(/^www\./, '');
|
|
64
|
-
return (((host === 'youtube.com' || host === 'youtube-nocookie.com') &&
|
|
65
|
-
parsed.pathname.startsWith('/embed/')) ||
|
|
66
|
-
(host === 'player.vimeo.com' && parsed.pathname.startsWith('/video/')) ||
|
|
67
|
-
(host === 'loom.com' && parsed.pathname.startsWith('/embed/')));
|
|
68
73
|
}
|
|
69
74
|
/**
|
|
70
75
|
* Pasting a bare provider URL onto an empty selection inserts an embed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embeds.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/embeds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAO3C
|
|
1
|
+
{"version":3,"file":"embeds.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/embeds.ts"],"names":[],"mappings":"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","sourcesContent":["import { Plugin } from 'prosemirror-state';\n\nexport interface EmbedTarget {\n src: string;\n provider: 'youtube' | 'vimeo' | 'loom' | 'generic';\n}\n\n/**\n * Sandbox tokens applied to every embed iframe. Notably this OMITS\n * `allow-top-navigation`, so a framed page cannot redirect the whole tab\n * (the main clickjacking/phishing vector); scripts and same-origin are\n * allowed so third-party players still run. Kept in sync with the sanitizer.\n */\nexport const EMBED_SANDBOX = 'allow-scripts allow-same-origin allow-presentation allow-popups';\n\n/** Limits the referrer leaked to the embedded third-party host. */\nexport const EMBED_REFERRER_POLICY = 'strict-origin-when-cross-origin';\n\n/**\n * Converts a URL into an embed target. Known providers (YouTube/Vimeo/Loom)\n * are canonicalized to their dedicated embed URLs; any other `https://` URL\n * is accepted as a `generic` embed. The iframe is always sandboxed on render\n * (see EMBED_SANDBOX), so untrusted hosts cannot navigate the top window.\n * Returns null only for non-https or unparseable URLs.\n */\nexport function toEmbedUrl(url: string): EmbedTarget | null {\n let parsed: URL;\n try {\n parsed = new URL(url.trim());\n } catch {\n return null;\n }\n if (parsed.protocol !== 'https:') return null;\n const host = parsed.hostname.replace(/^www\\./, '');\n\n // YouTube: watch?v=ID, youtu.be/ID, shorts/ID, embed/ID\n if (host === 'youtube.com' || host === 'youtube-nocookie.com' || host === 'youtu.be') {\n let id = '';\n if (host === 'youtu.be') id = parsed.pathname.slice(1).split('/')[0];\n else if (parsed.pathname === '/watch') id = parsed.searchParams.get('v') ?? '';\n else {\n const match = /^\\/(embed|shorts)\\/([\\w-]+)/.exec(parsed.pathname);\n if (match) id = match[2];\n }\n if (/^[\\w-]{6,20}$/.test(id)) {\n return { src: `https://www.youtube-nocookie.com/embed/${id}`, provider: 'youtube' };\n }\n }\n\n // Vimeo: vimeo.com/123456789, player.vimeo.com/video/123456789\n else if (host === 'vimeo.com' || host === 'player.vimeo.com') {\n const match = /\\/(?:video\\/)?(\\d{6,12})(?:$|[/?])/.exec(parsed.pathname);\n if (match) {\n return { src: `https://player.vimeo.com/video/${match[1]}`, provider: 'vimeo' };\n }\n }\n\n // Loom: loom.com/share/ID or loom.com/embed/ID\n else if (host === 'loom.com') {\n const match = /^\\/(share|embed)\\/([0-9a-f]{16,40})/.exec(parsed.pathname);\n if (match) {\n return { src: `https://www.loom.com/embed/${match[2]}`, provider: 'loom' };\n }\n }\n\n // Any other https URL: embed as-is, sandboxed.\n return { src: parsed.href, provider: 'generic' };\n}\n\n/**\n * True when a URL is permitted as an embed src (sanitizer check). Any\n * `https://` URL is allowed; the iframe is sandboxed at render time.\n */\nexport function isAllowedEmbedSrc(src: string): boolean {\n try {\n return new URL(src.trim()).protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Pasting a bare provider URL onto an empty selection inserts an embed\n * instead of plain text. (Pasting over selected text still creates a link.)\n */\nexport function embedPastePlugin(): Plugin {\n return new Plugin({\n props: {\n handlePaste(view, event) {\n const { state } = view;\n if (!state.selection.empty) return false;\n const text = event.clipboardData?.getData('text/plain')?.trim();\n if (!text || /\\s/.test(text)) return false;\n const target = toEmbedUrl(text);\n if (!target) return false;\n const embed = state.schema.nodes.embed.create({\n src: target.src,\n provider: target.provider,\n });\n view.dispatch(state.tr.replaceSelectionWith(embed).scrollIntoView());\n return true;\n },\n },\n });\n}\n"]}
|
|
@@ -3,13 +3,18 @@ import { NodeView } from 'prosemirror-view';
|
|
|
3
3
|
/** Turns a LaTeX string into HTML (KaTeX/MathJax/MathML). Host-provided. */
|
|
4
4
|
export type MathRenderer = (latex: string, display: 'inline' | 'block') => string;
|
|
5
5
|
/**
|
|
6
|
-
* Inline atom rendering a math formula.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Inline atom rendering a math formula. Precedence:
|
|
7
|
+
* 1. A host-supplied `mathRenderer` (full control — e.g. KaTeX HTML, MathJax).
|
|
8
|
+
* 2. The built-in default: KaTeX compiled to **MathML**, which browsers render
|
|
9
|
+
* natively with no stylesheet or web fonts (works cleanly inside the
|
|
10
|
+
* editor's shadow root).
|
|
11
|
+
* 3. If KaTeX can't load / parse, the raw LaTeX stays visible.
|
|
9
12
|
*/
|
|
10
13
|
export declare class MathView implements NodeView {
|
|
11
14
|
dom: HTMLSpanElement;
|
|
12
15
|
private renderer?;
|
|
16
|
+
/** Bumps on every render so a slow async KaTeX result for a stale node is dropped. */
|
|
17
|
+
private token;
|
|
13
18
|
constructor(node: PMNode, renderer?: MathRenderer);
|
|
14
19
|
private render;
|
|
15
20
|
update(node: PMNode): boolean;
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
|
|
2
|
+
* Lazy-loaded KaTeX module (loaded once, only when the first formula renders,
|
|
3
|
+
* so editors without math pay nothing). Resolves to the katex default export.
|
|
4
|
+
*/
|
|
5
|
+
let katexPromise = null;
|
|
6
|
+
function loadKatex() {
|
|
7
|
+
if (!katexPromise) {
|
|
8
|
+
katexPromise = import('katex').then(m => m.default);
|
|
9
|
+
}
|
|
10
|
+
return katexPromise;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Inline atom rendering a math formula. Precedence:
|
|
14
|
+
* 1. A host-supplied `mathRenderer` (full control — e.g. KaTeX HTML, MathJax).
|
|
15
|
+
* 2. The built-in default: KaTeX compiled to **MathML**, which browsers render
|
|
16
|
+
* natively with no stylesheet or web fonts (works cleanly inside the
|
|
17
|
+
* editor's shadow root).
|
|
18
|
+
* 3. If KaTeX can't load / parse, the raw LaTeX stays visible.
|
|
5
19
|
*/
|
|
6
20
|
export class MathView {
|
|
7
21
|
constructor(node, renderer) {
|
|
22
|
+
/** Bumps on every render so a slow async KaTeX result for a stale node is dropped. */
|
|
23
|
+
this.token = 0;
|
|
8
24
|
this.renderer = renderer;
|
|
9
25
|
this.dom = document.createElement('span');
|
|
10
26
|
this.dom.contentEditable = 'false';
|
|
@@ -20,6 +36,8 @@ export class MathView {
|
|
|
20
36
|
this.dom.setAttribute('data-math', latex);
|
|
21
37
|
this.dom.setAttribute('data-math-display', display);
|
|
22
38
|
this.dom.title = latex;
|
|
39
|
+
const token = ++this.token;
|
|
40
|
+
// 1. Host renderer wins.
|
|
23
41
|
if (this.renderer) {
|
|
24
42
|
try {
|
|
25
43
|
// Host renderer output is trusted (same trust level as uploadHandler).
|
|
@@ -27,10 +45,29 @@ export class MathView {
|
|
|
27
45
|
return;
|
|
28
46
|
}
|
|
29
47
|
catch {
|
|
30
|
-
// Fall
|
|
48
|
+
// Fall through to the built-in renderer.
|
|
31
49
|
}
|
|
32
50
|
}
|
|
51
|
+
// 2. Built-in KaTeX → MathML. Show raw LaTeX until the (lazy) engine loads.
|
|
33
52
|
this.dom.textContent = latex;
|
|
53
|
+
loadKatex()
|
|
54
|
+
.then(katex => {
|
|
55
|
+
if (token !== this.token)
|
|
56
|
+
return; // node changed while loading
|
|
57
|
+
try {
|
|
58
|
+
this.dom.innerHTML = katex.renderToString(latex, {
|
|
59
|
+
output: 'mathml',
|
|
60
|
+
displayMode: display === 'block',
|
|
61
|
+
throwOnError: false,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
this.dom.textContent = latex;
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.catch(() => {
|
|
69
|
+
/* KaTeX unavailable — keep the raw LaTeX already shown. */
|
|
70
|
+
});
|
|
34
71
|
}
|
|
35
72
|
update(node) {
|
|
36
73
|
if (node.type.name !== 'math')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math-view.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/math-view.ts"],"names":[],"mappings":"AAMA
|
|
1
|
+
{"version":3,"file":"math-view.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/math-view.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,IAAI,YAAY,GACd,IAAI,CAAC;AACP,SAAS,SAAS;IAChB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,QAAQ;IAQnB,YAAY,IAAY,EAAE,QAAuB;QAHjD,sFAAsF;QAC9E,UAAK,GAAG,CAAC,CAAC;QAGhB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,OAAO,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IAEO,MAAM,CAAC,IAAY;QACzB,MAAM,KAAK,GAAI,IAAI,CAAC,KAAK,CAAC,KAAgB,IAAI,EAAE,CAAC;QACjD,MAAM,OAAO,GAAI,IAAI,CAAC,KAAK,CAAC,OAA8B,IAAI,QAAQ,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,SAAS;YAChB,OAAO,KAAK,OAAO;gBACjB,CAAC,CAAC,8CAA8C;gBAChD,CAAC,CAAC,oBAAoB,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;QAEvB,MAAM,KAAK,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC;QAE3B,yBAAyB;QACzB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,uEAAuE;gBACvE,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBACnD,OAAO;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;YAC3C,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;QAC7B,SAAS,EAAE;aACR,IAAI,CAAC,KAAK,CAAC,EAAE;YACZ,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,6BAA6B;YAC/D,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE;oBAC/C,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,OAAO,KAAK,OAAO;oBAChC,YAAY,EAAE,KAAK;iBACpB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,2DAA2D;QAC7D,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0EAA0E;IAC1E,cAAc;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { Node as PMNode } from 'prosemirror-model';\nimport { NodeView } from 'prosemirror-view';\n\n/** Turns a LaTeX string into HTML (KaTeX/MathJax/MathML). Host-provided. */\nexport type MathRenderer = (latex: string, display: 'inline' | 'block') => string;\n\n/**\n * Lazy-loaded KaTeX module (loaded once, only when the first formula renders,\n * so editors without math pay nothing). Resolves to the katex default export.\n */\nlet katexPromise: Promise<{ renderToString(tex: string, opts?: Record<string, unknown>): string }> | null =\n null;\nfunction loadKatex() {\n if (!katexPromise) {\n katexPromise = import('katex').then(m => m.default);\n }\n return katexPromise;\n}\n\n/**\n * Inline atom rendering a math formula. Precedence:\n * 1. A host-supplied `mathRenderer` (full control — e.g. KaTeX HTML, MathJax).\n * 2. The built-in default: KaTeX compiled to **MathML**, which browsers render\n * natively with no stylesheet or web fonts (works cleanly inside the\n * editor's shadow root).\n * 3. If KaTeX can't load / parse, the raw LaTeX stays visible.\n */\nexport class MathView implements NodeView {\n dom: HTMLSpanElement;\n\n private renderer?: MathRenderer;\n\n /** Bumps on every render so a slow async KaTeX result for a stale node is dropped. */\n private token = 0;\n\n constructor(node: PMNode, renderer?: MathRenderer) {\n this.renderer = renderer;\n this.dom = document.createElement('span');\n this.dom.contentEditable = 'false';\n this.render(node);\n }\n\n private render(node: PMNode): void {\n const latex = (node.attrs.latex as string) ?? '';\n const display = (node.attrs.display as 'inline' | 'block') ?? 'inline';\n this.dom.className =\n display === 'block'\n ? 'nile-wysiwyg__math nile-wysiwyg__math--block'\n : 'nile-wysiwyg__math';\n this.dom.setAttribute('data-math', latex);\n this.dom.setAttribute('data-math-display', display);\n this.dom.title = latex;\n\n const token = ++this.token;\n\n // 1. Host renderer wins.\n if (this.renderer) {\n try {\n // Host renderer output is trusted (same trust level as uploadHandler).\n this.dom.innerHTML = this.renderer(latex, display);\n return;\n } catch {\n // Fall through to the built-in renderer.\n }\n }\n\n // 2. Built-in KaTeX → MathML. Show raw LaTeX until the (lazy) engine loads.\n this.dom.textContent = latex;\n loadKatex()\n .then(katex => {\n if (token !== this.token) return; // node changed while loading\n try {\n this.dom.innerHTML = katex.renderToString(latex, {\n output: 'mathml',\n displayMode: display === 'block',\n throwOnError: false,\n });\n } catch {\n this.dom.textContent = latex;\n }\n })\n .catch(() => {\n /* KaTeX unavailable — keep the raw LaTeX already shown. */\n });\n }\n\n update(node: PMNode): boolean {\n if (node.type.name !== 'math') return false;\n this.render(node);\n return true;\n }\n\n /** Atom node: ProseMirror owns selection; never read our subtree back. */\n ignoreMutation(): boolean {\n return true;\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Node as PMNode } from 'prosemirror-model';
|
|
2
|
+
import { NodeView } from 'prosemirror-view';
|
|
3
|
+
/**
|
|
4
|
+
* Node view for an author `<style>` block. It injects the CSS live — scoped to
|
|
5
|
+
* the content root — so the styles apply to the document as authored, with no
|
|
6
|
+
* visible chip. The block itself renders nothing (a hidden `<style>` host); it
|
|
7
|
+
* round-trips to `<style>` in the output via the schema's toDOM, and the same
|
|
8
|
+
* raw CSS is what the HTML-source preview renders.
|
|
9
|
+
*/
|
|
10
|
+
export declare class StyleBlockView implements NodeView {
|
|
11
|
+
private node;
|
|
12
|
+
dom: HTMLElement;
|
|
13
|
+
private styleEl;
|
|
14
|
+
constructor(node: PMNode);
|
|
15
|
+
update(node: PMNode): boolean;
|
|
16
|
+
ignoreMutation(): boolean;
|
|
17
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/** Content root the editor mounts the document under. Author CSS is scoped to
|
|
2
|
+
* it so a rule such as `div { background: green }` styles the content only and
|
|
3
|
+
* can never paint the editor chrome (toolbar, panels, surface) that shares the
|
|
4
|
+
* same shadow root. */
|
|
5
|
+
const CONTENT_SCOPE = '.ProseMirror';
|
|
6
|
+
/** Advances past a quoted string starting at `i` (the opening quote), honoring
|
|
7
|
+
* backslash escapes; returns the index just after the closing quote. */
|
|
8
|
+
function skipString(css, i) {
|
|
9
|
+
const quote = css[i];
|
|
10
|
+
i += 1;
|
|
11
|
+
while (i < css.length) {
|
|
12
|
+
if (css[i] === '\\') {
|
|
13
|
+
i += 2;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (css[i] === quote)
|
|
17
|
+
return i + 1;
|
|
18
|
+
i += 1;
|
|
19
|
+
}
|
|
20
|
+
return i;
|
|
21
|
+
}
|
|
22
|
+
/** Splits on a top-level separator, ignoring ones inside (), [] or strings. */
|
|
23
|
+
function splitTopLevel(str, sep) {
|
|
24
|
+
const parts = [];
|
|
25
|
+
let depth = 0;
|
|
26
|
+
let buf = '';
|
|
27
|
+
for (let i = 0; i < str.length; i += 1) {
|
|
28
|
+
const c = str[i];
|
|
29
|
+
if (c === '"' || c === "'") {
|
|
30
|
+
const end = skipString(str, i);
|
|
31
|
+
buf += str.slice(i, end);
|
|
32
|
+
i = end - 1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (c === '(' || c === '[')
|
|
36
|
+
depth += 1;
|
|
37
|
+
else if (c === ')' || c === ']')
|
|
38
|
+
depth -= 1;
|
|
39
|
+
if (c === sep && depth === 0) {
|
|
40
|
+
parts.push(buf);
|
|
41
|
+
buf = '';
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
buf += c;
|
|
45
|
+
}
|
|
46
|
+
parts.push(buf);
|
|
47
|
+
return parts;
|
|
48
|
+
}
|
|
49
|
+
/** Confines one complex selector to the content root. `html`/`body`/`:root`
|
|
50
|
+
* map onto the root itself. */
|
|
51
|
+
function scopeSelector(selector, scope) {
|
|
52
|
+
const sel = selector.trim();
|
|
53
|
+
if (!sel)
|
|
54
|
+
return sel;
|
|
55
|
+
if (/^(?:html|body|:root)$/i.test(sel))
|
|
56
|
+
return scope;
|
|
57
|
+
const root = sel.match(/^(?:html|body|:root)\b\s*/i);
|
|
58
|
+
return root ? `${scope} ${sel.slice(root[0].length)}`.trim() : `${scope} ${sel}`;
|
|
59
|
+
}
|
|
60
|
+
/** Confines a comma-separated selector list to the content root. */
|
|
61
|
+
function scopeSelectorList(list, scope) {
|
|
62
|
+
return splitTopLevel(list, ',')
|
|
63
|
+
.map(part => scopeSelector(part, scope))
|
|
64
|
+
.filter(Boolean)
|
|
65
|
+
.join(', ');
|
|
66
|
+
}
|
|
67
|
+
const NESTED_AT_RULES = new Set(['media', 'supports', 'container', 'layer', 'scope']);
|
|
68
|
+
/**
|
|
69
|
+
* Scopes every rule in a CSS block to the content root by prefixing selectors,
|
|
70
|
+
* keeping each declaration block **verbatim**. Declarations are never re-parsed
|
|
71
|
+
* (a CSSOM round-trip drops `var()` inside shorthands, e.g. gradient text), and
|
|
72
|
+
* strings/nested braces are tracked so `content: "}"` can't derail it. Nested
|
|
73
|
+
* conditionals (`@media`, `@supports`, …) recurse; other at-rules
|
|
74
|
+
* (`@keyframes`, `@font-face`, …) pass through untouched.
|
|
75
|
+
*/
|
|
76
|
+
function scopeBlock(css, scope) {
|
|
77
|
+
let out = '';
|
|
78
|
+
let i = 0;
|
|
79
|
+
const n = css.length;
|
|
80
|
+
while (i < n) {
|
|
81
|
+
let j = i;
|
|
82
|
+
while (j < n) {
|
|
83
|
+
const c = css[j];
|
|
84
|
+
if (c === '"' || c === "'") {
|
|
85
|
+
j = skipString(css, j);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (c === '{' || c === ';')
|
|
89
|
+
break;
|
|
90
|
+
j += 1;
|
|
91
|
+
}
|
|
92
|
+
if (j >= n) {
|
|
93
|
+
out += css.slice(i);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
if (css[j] === ';') {
|
|
97
|
+
// A statement at-rule (e.g. a stray @charset) — keep verbatim.
|
|
98
|
+
out += css.slice(i, j + 1);
|
|
99
|
+
i = j + 1;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const prelude = css.slice(i, j).trim();
|
|
103
|
+
let depth = 1;
|
|
104
|
+
let k = j + 1;
|
|
105
|
+
while (k < n && depth > 0) {
|
|
106
|
+
const c = css[k];
|
|
107
|
+
if (c === '"' || c === "'") {
|
|
108
|
+
k = skipString(css, k);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (c === '{')
|
|
112
|
+
depth += 1;
|
|
113
|
+
else if (c === '}')
|
|
114
|
+
depth -= 1;
|
|
115
|
+
k += 1;
|
|
116
|
+
}
|
|
117
|
+
const body = css.slice(j + 1, k - 1);
|
|
118
|
+
if (prelude.startsWith('@')) {
|
|
119
|
+
const name = (prelude.match(/^@([a-z-]+)/i)?.[1] ?? '').toLowerCase();
|
|
120
|
+
out += NESTED_AT_RULES.has(name)
|
|
121
|
+
? `${prelude} {${scopeBlock(body, scope)}}`
|
|
122
|
+
: `${prelude} {${body}}`;
|
|
123
|
+
}
|
|
124
|
+
else if (prelude) {
|
|
125
|
+
out += `${scopeSelectorList(prelude, scope)} {${body}}`;
|
|
126
|
+
}
|
|
127
|
+
i = k;
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
/** Returns author CSS confined to the content root. */
|
|
132
|
+
function scopeCss(css, scope) {
|
|
133
|
+
if (!css.trim())
|
|
134
|
+
return '';
|
|
135
|
+
try {
|
|
136
|
+
return scopeBlock(css, scope);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return css;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Node view for an author `<style>` block. It injects the CSS live — scoped to
|
|
144
|
+
* the content root — so the styles apply to the document as authored, with no
|
|
145
|
+
* visible chip. The block itself renders nothing (a hidden `<style>` host); it
|
|
146
|
+
* round-trips to `<style>` in the output via the schema's toDOM, and the same
|
|
147
|
+
* raw CSS is what the HTML-source preview renders.
|
|
148
|
+
*/
|
|
149
|
+
export class StyleBlockView {
|
|
150
|
+
constructor(node) {
|
|
151
|
+
this.node = node;
|
|
152
|
+
this.dom = document.createElement('div');
|
|
153
|
+
this.dom.className = 'nile-wysiwyg__style-block';
|
|
154
|
+
this.dom.contentEditable = 'false';
|
|
155
|
+
// A <style> applies regardless of its (display:none) host, so the block is
|
|
156
|
+
// invisible yet its rules take effect on the content.
|
|
157
|
+
this.styleEl = document.createElement('style');
|
|
158
|
+
this.styleEl.textContent = scopeCss(node.attrs.css, CONTENT_SCOPE);
|
|
159
|
+
this.dom.append(this.styleEl);
|
|
160
|
+
}
|
|
161
|
+
update(node) {
|
|
162
|
+
if (node.type !== this.node.type)
|
|
163
|
+
return false;
|
|
164
|
+
if (node.attrs.css !== this.node.attrs.css) {
|
|
165
|
+
this.styleEl.textContent = scopeCss(node.attrs.css, CONTENT_SCOPE);
|
|
166
|
+
}
|
|
167
|
+
this.node = node;
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
ignoreMutation() {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=style-block-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-block-view.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/style-block-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { Node as PMNode } from 'prosemirror-model';\nimport { NodeView } from 'prosemirror-view';\n\n/** Content root the editor mounts the document under. Author CSS is scoped to\n * it so a rule such as `div { background: green }` styles the content only and\n * can never paint the editor chrome (toolbar, panels, surface) that shares the\n * same shadow root. */\nconst CONTENT_SCOPE = '.ProseMirror';\n\n/** Advances past a quoted string starting at `i` (the opening quote), honoring\n * backslash escapes; returns the index just after the closing quote. */\nfunction skipString(css: string, i: number): number {\n const quote = css[i];\n i += 1;\n while (i < css.length) {\n if (css[i] === '\\\\') {\n i += 2;\n continue;\n }\n if (css[i] === quote) return i + 1;\n i += 1;\n }\n return i;\n}\n\n/** Splits on a top-level separator, ignoring ones inside (), [] or strings. */\nfunction splitTopLevel(str: string, sep: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let buf = '';\n for (let i = 0; i < str.length; i += 1) {\n const c = str[i];\n if (c === '\"' || c === \"'\") {\n const end = skipString(str, i);\n buf += str.slice(i, end);\n i = end - 1;\n continue;\n }\n if (c === '(' || c === '[') depth += 1;\n else if (c === ')' || c === ']') depth -= 1;\n if (c === sep && depth === 0) {\n parts.push(buf);\n buf = '';\n continue;\n }\n buf += c;\n }\n parts.push(buf);\n return parts;\n}\n\n/** Confines one complex selector to the content root. `html`/`body`/`:root`\n * map onto the root itself. */\nfunction scopeSelector(selector: string, scope: string): string {\n const sel = selector.trim();\n if (!sel) return sel;\n if (/^(?:html|body|:root)$/i.test(sel)) return scope;\n const root = sel.match(/^(?:html|body|:root)\\b\\s*/i);\n return root ? `${scope} ${sel.slice(root[0].length)}`.trim() : `${scope} ${sel}`;\n}\n\n/** Confines a comma-separated selector list to the content root. */\nfunction scopeSelectorList(list: string, scope: string): string {\n return splitTopLevel(list, ',')\n .map(part => scopeSelector(part, scope))\n .filter(Boolean)\n .join(', ');\n}\n\nconst NESTED_AT_RULES = new Set(['media', 'supports', 'container', 'layer', 'scope']);\n\n/**\n * Scopes every rule in a CSS block to the content root by prefixing selectors,\n * keeping each declaration block **verbatim**. Declarations are never re-parsed\n * (a CSSOM round-trip drops `var()` inside shorthands, e.g. gradient text), and\n * strings/nested braces are tracked so `content: \"}\"` can't derail it. Nested\n * conditionals (`@media`, `@supports`, …) recurse; other at-rules\n * (`@keyframes`, `@font-face`, …) pass through untouched.\n */\nfunction scopeBlock(css: string, scope: string): string {\n let out = '';\n let i = 0;\n const n = css.length;\n while (i < n) {\n let j = i;\n while (j < n) {\n const c = css[j];\n if (c === '\"' || c === \"'\") {\n j = skipString(css, j);\n continue;\n }\n if (c === '{' || c === ';') break;\n j += 1;\n }\n if (j >= n) {\n out += css.slice(i);\n break;\n }\n if (css[j] === ';') {\n // A statement at-rule (e.g. a stray @charset) — keep verbatim.\n out += css.slice(i, j + 1);\n i = j + 1;\n continue;\n }\n const prelude = css.slice(i, j).trim();\n let depth = 1;\n let k = j + 1;\n while (k < n && depth > 0) {\n const c = css[k];\n if (c === '\"' || c === \"'\") {\n k = skipString(css, k);\n continue;\n }\n if (c === '{') depth += 1;\n else if (c === '}') depth -= 1;\n k += 1;\n }\n const body = css.slice(j + 1, k - 1);\n if (prelude.startsWith('@')) {\n const name = (prelude.match(/^@([a-z-]+)/i)?.[1] ?? '').toLowerCase();\n out += NESTED_AT_RULES.has(name)\n ? `${prelude} {${scopeBlock(body, scope)}}`\n : `${prelude} {${body}}`;\n } else if (prelude) {\n out += `${scopeSelectorList(prelude, scope)} {${body}}`;\n }\n i = k;\n }\n return out;\n}\n\n/** Returns author CSS confined to the content root. */\nfunction scopeCss(css: string, scope: string): string {\n if (!css.trim()) return '';\n try {\n return scopeBlock(css, scope);\n } catch {\n return css;\n }\n}\n\n/**\n * Node view for an author `<style>` block. It injects the CSS live — scoped to\n * the content root — so the styles apply to the document as authored, with no\n * visible chip. The block itself renders nothing (a hidden `<style>` host); it\n * round-trips to `<style>` in the output via the schema's toDOM, and the same\n * raw CSS is what the HTML-source preview renders.\n */\nexport class StyleBlockView implements NodeView {\n dom: HTMLElement;\n\n private styleEl: HTMLStyleElement;\n\n constructor(private node: PMNode) {\n this.dom = document.createElement('div');\n this.dom.className = 'nile-wysiwyg__style-block';\n this.dom.contentEditable = 'false';\n\n // A <style> applies regardless of its (display:none) host, so the block is\n // invisible yet its rules take effect on the content.\n this.styleEl = document.createElement('style');\n this.styleEl.textContent = scopeCss(node.attrs.css, CONTENT_SCOPE);\n this.dom.append(this.styleEl);\n }\n\n update(node: PMNode): boolean {\n if (node.type !== this.node.type) return false;\n if (node.attrs.css !== this.node.attrs.css) {\n this.styleEl.textContent = scopeCss(node.attrs.css, CONTENT_SCOPE);\n }\n this.node = node;\n return true;\n }\n\n ignoreMutation(): boolean {\n return true;\n }\n}\n"]}
|
|
@@ -1,4 +1,32 @@
|
|
|
1
|
-
import { tableEditing, columnResizing } from 'prosemirror-tables';
|
|
1
|
+
import { tableEditing, columnResizing, TableView } from 'prosemirror-tables';
|
|
2
|
+
/**
|
|
3
|
+
* TableView that also reflects the author's `class`/`id` onto the inner
|
|
4
|
+
* `<table>` element (the base TableView leaves it bare and puts its own class on
|
|
5
|
+
* the wrapper div). The attributes round-trip via the schema's toDOM on export;
|
|
6
|
+
* this makes `table.grid …` style rules match in the live editor too. Passed to
|
|
7
|
+
* `columnResizing` as its `View`, so column resizing keeps working.
|
|
8
|
+
*/
|
|
9
|
+
class HtmlAttrTableView extends TableView {
|
|
10
|
+
constructor(node, defaultCellMinWidth) {
|
|
11
|
+
super(node, defaultCellMinWidth);
|
|
12
|
+
this.applyHtmlAttrs(node);
|
|
13
|
+
}
|
|
14
|
+
applyHtmlAttrs(node) {
|
|
15
|
+
const htmlClass = node.attrs.htmlClass;
|
|
16
|
+
const htmlId = node.attrs.htmlId;
|
|
17
|
+
this.table.className = htmlClass ?? '';
|
|
18
|
+
if (htmlId)
|
|
19
|
+
this.table.id = htmlId;
|
|
20
|
+
else
|
|
21
|
+
this.table.removeAttribute('id');
|
|
22
|
+
}
|
|
23
|
+
update(node) {
|
|
24
|
+
const updated = super.update(node);
|
|
25
|
+
if (updated)
|
|
26
|
+
this.applyHtmlAttrs(node);
|
|
27
|
+
return updated;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
2
30
|
/**
|
|
3
31
|
* prosemirror-tables wiring: cell selections, fix-tables normalization, and
|
|
4
32
|
* draggable column resizing (widths persist as `data-colwidth`). The CSS
|
|
@@ -6,6 +34,9 @@ import { tableEditing, columnResizing } from 'prosemirror-tables';
|
|
|
6
34
|
* is inlined in nile-wysiwyg-editor.css.ts.
|
|
7
35
|
*/
|
|
8
36
|
export function tablePlugins() {
|
|
9
|
-
return [
|
|
37
|
+
return [
|
|
38
|
+
columnResizing({ View: HtmlAttrTableView }),
|
|
39
|
+
tableEditing({ allowTableNodeSelection: true }),
|
|
40
|
+
];
|
|
10
41
|
}
|
|
11
42
|
//# sourceMappingURL=tables.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/tables.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../../../src/nile-wysiwyg-editor/engine/plugins/tables.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE7E;;;;;;GAMG;AACH,MAAM,iBAAkB,SAAQ,SAAS;IACvC,YAAY,IAAY,EAAE,mBAA2B;QACnD,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEO,cAAc,CAAC,IAAY;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAA0B,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAuB,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,SAAS,IAAI,EAAE,CAAC;QACvC,IAAI,MAAM;YAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC;;YAC9B,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,OAAO;YAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,cAAc,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;QAC3C,YAAY,CAAC,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC","sourcesContent":["import { Plugin } from 'prosemirror-state';\nimport { Node as PMNode } from 'prosemirror-model';\nimport { tableEditing, columnResizing, TableView } from 'prosemirror-tables';\n\n/**\n * TableView that also reflects the author's `class`/`id` onto the inner\n * `<table>` element (the base TableView leaves it bare and puts its own class on\n * the wrapper div). The attributes round-trip via the schema's toDOM on export;\n * this makes `table.grid …` style rules match in the live editor too. Passed to\n * `columnResizing` as its `View`, so column resizing keeps working.\n */\nclass HtmlAttrTableView extends TableView {\n constructor(node: PMNode, defaultCellMinWidth: number) {\n super(node, defaultCellMinWidth);\n this.applyHtmlAttrs(node);\n }\n\n private applyHtmlAttrs(node: PMNode): void {\n const htmlClass = node.attrs.htmlClass as string | null;\n const htmlId = node.attrs.htmlId as string | null;\n this.table.className = htmlClass ?? '';\n if (htmlId) this.table.id = htmlId;\n else this.table.removeAttribute('id');\n }\n\n update(node: PMNode): boolean {\n const updated = super.update(node);\n if (updated) this.applyHtmlAttrs(node);\n return updated;\n }\n}\n\n/**\n * prosemirror-tables wiring: cell selections, fix-tables normalization, and\n * draggable column resizing (widths persist as `data-colwidth`). The CSS\n * these plugins rely on (.selectedCell, .column-resize-handle, .resize-cursor)\n * is inlined in nile-wysiwyg-editor.css.ts.\n */\nexport function tablePlugins(): Plugin[] {\n return [\n columnResizing({ View: HtmlAttrTableView }),\n tableEditing({ allowTableNodeSelection: true }),\n ];\n}\n"]}
|