├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 objectlegal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # slate-snippets 2 | Slate snippets 3 | 4 | # General 5 | 6 | ## Queries 7 | 8 | ### Paths 9 | #### Current anchor path 10 | ```js 11 | editor.selection.anchor.path 12 | ``` 13 | 14 | 15 | #### Trim a path to get the parent (e.g. transform [4,2,3] to [4,2]) 16 | ```js 17 | const parentPath = Path.parent(path); 18 | ``` 19 | 20 | ### Nodes, domNode, path 21 | #### Get node by path 22 | ```js 23 | const node = Node.get(editor, path) 24 | ``` 25 | 26 | #### Get path by node 27 | ```js 28 | const path = ReactEditor.findPath(editor, node) 29 | ``` 30 | 31 | #### Find a node's DOM node 32 | ```js 33 | const domNode = ReactEditor.toDOMNode(editor, node) 34 | ``` 35 | 36 | #### Get closest block 37 | ```js 38 | const [blockNode, path] = Editor.above(editor, {match: n => editor.isBlock(n)}) 39 | ``` 40 | 41 | #### Get parent and path of node 42 | ```js 43 | const [node, path] = Editor.parent(editor, nodePath) // <- using specific node path, see above how to get paths 44 | ``` 45 | 46 | #### move the cursos to the end of the document 47 | ```js 48 | ReactEditor.focus(editor); 49 | Transforms.select(editor, Editor.end(editor, [])); 50 | ``` 51 | 52 | ## Commands 53 | 54 | #### Insert text at selection 55 | ```js 56 | Transforms.insertText(editor, 'some text'); 57 | ``` 58 | 59 | #### Insert nodes at selection 60 | ```js 61 | Transforms.insertNodes(editor, [ 62 | {type:'inline_type', children:[{text: 'some text', marks:[]}]}, 63 | {text: ' and some text after the inline', marks: []} 64 | ] 65 | ); 66 | ``` 67 | 68 | #### Insert node at beginning of document 69 | ```js 70 | Transforms.insertNodes(editor, [ 71 | {type:'paragraph', children:[{text: 'some text', marks:[]}]}, 72 | ], 73 | {at:[0]} 74 | ); 75 | ``` 76 | 77 | #### Set node 78 | ```js 79 | Transforms.setNodes(editor, {type: 'paragraph'}, {at: path}) 80 | ``` 81 | 82 | #### Set node text 83 | ```js 84 | Transforms.insertText(editor, 'new text', {at: path}) 85 | ``` 86 | 87 | #### Insert inline + text & navigate to text 88 | ```js 89 | Transforms.insertNodes(editor, [ 90 | { type: 'link', url:'x', children: [{ text:'mja', marks:[] }] }, 91 | { text: '', marks:[] }, 92 | ]); 93 | const nextPoint = Editor.after(editor, editor.selection.anchor); 94 | Editor.setSelection(editor, {anchor:nextPoint, focus:nextPoint}) 95 | ``` 96 | #### Test insert after above commands 97 | ```js 98 | Transforms.insertText(editor, 'text in the following text node') 99 | ``` 100 | 101 | 102 | # Setup & Helpers 103 | 104 | ## Create a withPlugins hook / composer 105 | ```js 106 | import * as plugins from './plugins/'; 107 | 108 | export const withPlugins = (editor) => { 109 | for(let plugin in plugins) { 110 | if(typeof plugins[plugin] !== 'function') continue; 111 | const pluginEditor = plugins[plugin](editor); 112 | if(pluginEditor !== editor) continue; // Invalid plugin 113 | editor = pluginEditor; 114 | } 115 | return editor; 116 | } 117 | ``` 118 | the file plugins/index.js exports all the plugins, e.g. export * from "./plugin1", export * from "./plugin2" etc 119 | 120 | 121 | ## Other helpers 122 | 123 | #### Find the node and path by custom id 124 | ```js 125 | const findById = (root, id, path=[]) => { 126 | if(!root || !root.children || !id) return; 127 | const childLen = root.children.length; 128 | for(let i=0;i { 143 | const isNode = Node.isNode(nodeOrPath); 144 | if(!isNode && !Path.isPath(nodeOrPath)) return; 145 | const node = isNode ? nodeOrPath : Node.get(editor, nodeOrPath); 146 | const path = !isNode ? nodeOrPath : ReactEditor.findPath(editor, node); 147 | Editor.setNodes(editor, {data: deepmerge(data, node.data)}, {at: path}) 148 | } 149 | ``` 150 | 151 | You could use 'deepmerge' or other library for merging data 152 | 153 | 154 | 155 | ## Convert data from v0.47 to v.0.50+ 156 | ```js 157 | const convertNode = (node) => { 158 | const { object, type, data, nodes, ...rest } = node 159 | // We drop `object`, pull up data, convert `nodes` to children and copy the rest across 160 | const element = { 161 | type, 162 | ...rest, 163 | ...(nodes ? { children: nodes.map(convertNode) } : {}), 164 | } 165 | if ((!element.type || element.type === 'text') && typeof element.text !== 'undefined') { 166 | delete element.type; 167 | if(Array.isArray(element.marks)) { 168 | for(const mark of element.marks) { 169 | if(typeof mark === 'string') 170 | element[mark] = true 171 | else if(typeof mark === 'object' && mark.type) { 172 | element[mark.type] = mark.hasOwnProperty('value') ? mark.value : true 173 | } 174 | } 175 | } 176 | } 177 | if(data) element.data = data; 178 | // if(element.type) element.type = element.type.replace("-", "_") 179 | 180 | // Atomic blocks must now have children 181 | if (element.type && !element.children) { 182 | element.children = [ 183 | { 184 | text: '', 185 | }, 186 | ] 187 | } 188 | return element 189 | }; 190 | const convertSlate047to050 = (object) => { 191 | const { nodes } = object.document 192 | return nodes.map(convertNode) 193 | } 194 | ``` 195 | 196 | --------------------------------------------------------------------------------