1/* 2 * code.ts 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16import { Plugin, PluginKey } from 'prosemirror-state'; 17 18import { CodeViewOptions, canInsertNodeAtPos } from './node'; 19import { ResolvedPos, Slice, Fragment } from 'prosemirror-model'; 20 21export const kCodeAttr = 0; 22export const kCodeText = 1; 23 24export function codeNodeSpec() { 25 return { 26 content: 'text*', 27 group: 'block', 28 marks: '', 29 code: true, 30 defining: true, 31 isolating: true, 32 }; 33} 34 35export function codeViewClipboardPlugin(codeViews: { [key: string]: CodeViewOptions }) { 36 return new Plugin({ 37 key: new PluginKey('code-view-clipboard'), 38 props: { 39 clipboardTextParser: (text: string, $context: ResolvedPos): any => { 40 // see if any of the code views want to handle this text 41 for (const codeViewType of Object.keys(codeViews)) { 42 const codeView = codeViews[codeViewType]; 43 if (codeView.createFromPastePattern && codeView.createFromPastePattern.test(text)) { 44 const schema = $context.node().type.schema; 45 const nodeType = schema.nodes[codeViewType]; 46 if (canInsertNodeAtPos($context, nodeType)) { 47 const textNode = schema.text(text); 48 const codeNode = nodeType.createAndFill({}, textNode); 49 return new Slice(Fragment.from(codeNode), 0, 0); 50 } 51 } 52 } 53 return null; 54 }, 55 }, 56 }); 57} 58