diff --git a/.gitignore b/.gitignore index 8b32124b..795770de 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ npm-debug.log .bsp .metals .vscode +.yalc +yalc.lock +.bloop +metals.sbt diff --git a/package-lock.json b/package-lock.json index 816dcb5d..c3aff5f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1272,6 +1272,24 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@guardian/prosemirror-editor": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@guardian/prosemirror-editor/-/prosemirror-editor-0.2.0.tgz", + "integrity": "sha512-3P2DuXOwed7DIgM5G/wBeQ4ipMZ5epenfywX9O94dSgdyEFy/OSE/hbJPzbm/NXtWj+DflrUK8F/4Xkw5qo7Cw==", + "requires": { + "prosemirror-commands": "^1.5.0", + "prosemirror-history": "^1.3.0", + "prosemirror-inputrules": "^1.2.0", + "prosemirror-keymap": "^1.2.0", + "prosemirror-menu": "^1.2.1", + "prosemirror-model": "^1.19.0", + "prosemirror-schema-basic": "^1.2.1", + "prosemirror-schema-list": "^1.2.2", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.30.1", + "valid-url": "^1.0.9" + } + }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -2621,6 +2639,11 @@ "object-assign": "^4.1.1" } }, + "crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -4168,11 +4191,6 @@ "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", "dev": true }, - "html-janitor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/html-janitor/-/html-janitor-2.0.4.tgz", - "integrity": "sha512-92J5h9jNZRk30PMHapjHEJfkrBWKCOy0bq3oW2pBungky6lzYSoboBGPMvxl1XRKB2q+kniQmsLsPbdpY7RM2g==" - }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -4775,11 +4793,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash-amd": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/lodash-amd/-/lodash-amd-3.5.0.tgz", - "integrity": "sha512-YGKhQBJAhglKepycxPtdR8oXXv7VsagH3+hiOGan09ej/CRMlZ5r8PzrSDRY7bsV9y90l3+A5gyTR+9zzyXg9w==" - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", @@ -5424,6 +5437,11 @@ "word-wrap": "~1.2.3" } }, + "orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -5751,6 +5769,110 @@ } } }, + "prosemirror-commands": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", + "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==", + "requires": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "prosemirror-history": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.3.2.tgz", + "integrity": "sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==", + "requires": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "prosemirror-inputrules": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.2.1.tgz", + "integrity": "sha512-3LrWJX1+ULRh5SZvbIQlwZafOXqp1XuV21MGBu/i5xsztd+9VD15x6OtN6mdqSFI7/8Y77gYUbQ6vwwJ4mr6QQ==", + "requires": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "prosemirror-keymap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", + "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "requires": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "prosemirror-menu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", + "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "requires": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "prosemirror-model": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.3.tgz", + "integrity": "sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ==", + "requires": { + "orderedmap": "^2.0.0" + } + }, + "prosemirror-schema-basic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz", + "integrity": "sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==", + "requires": { + "prosemirror-model": "^1.19.0" + } + }, + "prosemirror-schema-list": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz", + "integrity": "sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==", + "requires": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "requires": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "prosemirror-transform": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.8.0.tgz", + "integrity": "sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==", + "requires": { + "prosemirror-model": "^1.0.0" + } + }, + "prosemirror-view": { + "version": "1.32.4", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.32.4.tgz", + "integrity": "sha512-WoT+ZYePp0WQvp5coABAysheZg9WttW3TSEUNgsfDQXmVOJlnjkbFbXicKPvWFLiC0ZjKt1ykbyoVKqhVnCiSQ==", + "requires": { + "prosemirror-model": "^1.16.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -6340,6 +6462,11 @@ "glob": "^7.1.3" } }, + "rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -6469,56 +6596,6 @@ } } }, - "scribe-editor": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/scribe-editor/-/scribe-editor-2.3.0.tgz", - "integrity": "sha512-PkOhmLw5PCCnxtCt/glECcaRBcHcn0DKh61skJm0Yey9hIYvDElY9wjCzypijHwEh9Hptkn0Hfzi8dU54uC3ZA==", - "requires": { - "immutable": "~3.7.3", - "lodash-amd": "~3.5.0" - }, - "dependencies": { - "immutable": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", - "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==" - } - } - }, - "scribe-plugin-keyboard-shortcuts": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/scribe-plugin-keyboard-shortcuts/-/scribe-plugin-keyboard-shortcuts-0.1.1.tgz", - "integrity": "sha512-/Xk5rlv34l69OXv2DwqM7xkUsG2NWGThGvdf+WJH88Dbnpi/9axj7VF/NR4xzDW5ptI6ZvP4TjPWU2mSfNr0iA==", - "requires": { - "lodash-amd": "~2.4.1" - }, - "dependencies": { - "lodash-amd": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash-amd/-/lodash-amd-2.4.1.tgz", - "integrity": "sha512-WEUDkyddJe1c6biddZTTKj0oj50wmbIyykqcF9NC6rul5X2pbDifTdIwiML4+CLfE3FdjKH/XojBV8+Ns57LoQ==" - } - } - }, - "scribe-plugin-link-prompt-command": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/scribe-plugin-link-prompt-command/-/scribe-plugin-link-prompt-command-0.4.0.tgz", - "integrity": "sha512-M9SycMxVlDyr0AWr4+1NUUDfS+gsTgFg6bZRRpDql5AFISMCckdSkpr5p/hi0l4SngLJaIt9h6Gnf/xnE9y5Gg==" - }, - "scribe-plugin-sanitizer": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/scribe-plugin-sanitizer/-/scribe-plugin-sanitizer-0.1.11.tgz", - "integrity": "sha512-u0PVk54Ys/SORmh7edK7VoYMA14CMFXjvLBSYUmFF//IpPYa1gdJxQ0pcPiOs0KxWWq2yFGOjHZ43R5lH2q60A==", - "requires": { - "html-janitor": "^2.0.4", - "lodash-amd": "~3.5.0" - } - }, - "scribe-plugin-toolbar": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/scribe-plugin-toolbar/-/scribe-plugin-toolbar-0.2.2.tgz", - "integrity": "sha512-VX+8BDMVXWyKmv70K4yEj5liZebLxBO/DnizKIpfqoNNpJYSEJFRfSwyoYz2f1WUrflSl8ow6rzw9p0MubTaDQ==" - }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -7737,6 +7814,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -7773,6 +7855,11 @@ "replace-ext": "^1.0.0" } }, + "w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, "warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", diff --git a/package.json b/package.json index d9342f25..0b3a440e 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "client-dev": "node ./public/devserver.js" }, "dependencies": { + "@guardian/prosemirror-editor": "^0.2.0", "ajv": "^6.12.3", "babel-loader": "^8.2.5", "css-loader": "^3.6.0", @@ -37,11 +38,6 @@ "reqwest": "^2.0.5", "sass": "^1.55.0", "sass-loader": "^8.0.2", - "scribe-editor": "^2.1.1", - "scribe-plugin-keyboard-shortcuts": "^0.1.1", - "scribe-plugin-link-prompt-command": "^0.4.0", - "scribe-plugin-sanitizer": "^0.1.10", - "scribe-plugin-toolbar": "^0.2.2", "style-loader": "^2.0.0", "svg-sprite": "^2.0.2", "url-loader": "^0.5.7", diff --git a/public/app.js b/public/app.js index d2198913..e444c946 100644 --- a/public/app.js +++ b/public/app.js @@ -7,6 +7,7 @@ import {setStore} from './util/storeAccessor'; import {router} from './router'; import './style/main.scss'; +import '@guardian/prosemirror-editor/dist/style.css' function extractConfigFromPage() { diff --git a/public/components/TagEdit/formComponents/TagDescription.react.js b/public/components/TagEdit/formComponents/TagDescription.react.js index 3c80523c..690f1e60 100644 --- a/public/components/TagEdit/formComponents/TagDescription.react.js +++ b/public/components/TagEdit/formComponents/TagDescription.react.js @@ -1,5 +1,11 @@ import React from 'react'; -import ReactScribe from '../../utils/ReactScribe.react'; +import { RichTextEditor, customMultiBlockTextConfig, transformToLegacyMarkup } from '@guardian/prosemirror-editor'; + + +const config = customMultiBlockTextConfig({ + allowedNodes: ["text", "paragraph", "hard_break"], + allowedMarks: ["strong", "em", "link"] +}) export default class TagDescription extends React.Component { @@ -9,7 +15,7 @@ export default class TagDescription extends React.Component { updateDescription(html) { this.props.updateTag(Object.assign({}, this.props.tag, { - description: html + description: transformToLegacyMarkup(html) })); } @@ -22,13 +28,10 @@ export default class TagDescription extends React.Component {
-
diff --git a/public/components/utils/ReactScribe.react.js b/public/components/utils/ReactScribe.react.js deleted file mode 100644 index 5ee5c650..00000000 --- a/public/components/utils/ReactScribe.react.js +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; -import Scribe from 'scribe-editor'; -import scribeKeyboardShortcutsPlugin from 'scribe-plugin-keyboard-shortcuts'; -import scribePluginToolbar from 'scribe-plugin-toolbar'; -import scribePluginLinkPromptCommand from 'scribe-plugin-link-prompt-command'; -import scribePluginSanitizer from 'scribe-plugin-sanitizer' - -export default class ReactScribe extends React.Component { - - constructor(props) { - super(props); - - this.onContentChange = this.onContentChange.bind(this); - } - - componentDidMount() { - if (!this.props.disabled) { - this.scribe = new Scribe(this.refs.editor); - - this.configureScribe(); - - this.scribe.on('content-changed', this.onContentChange); - } - } - - UNSAFE_componentWillUnmount() { - if (!this.props.disabled) { - this.scribe.off('content-changed', this.onContentChange); - } - } - - configureScribe() { - - this.scribe.use(scribePluginLinkPromptCommand()); - this.scribe.use(scribeKeyboardShortcutsPlugin({ - bold: function (event) { return event.metaKey && event.keyCode === 66; }, // b - italic: function (event) { return event.metaKey && event.keyCode === 73; }, // i - linkPrompt: function (event) { return event.metaKey && !event.shiftKey && event.keyCode === 75; }, // k - unlink: function (event) { return event.metaKey && event.shiftKey && event.keyCode === 75; } // shft + k - })); - this.scribe.use(scribePluginSanitizer({ - tags: { - p: {}, - i: {}, - b: {}, - a: { - href: true - } - } - })); - - this.scribe.use(scribePluginToolbar(this.refs.toolbar)); - } - - shouldComponentUpdate(nextProps) { - return nextProps.value !== this.refs.editor.innerHTML; - } - - onContentChange() { - const newContent = this.refs.editor.innerHTML; - - if (newContent !== this.props.value) { - this.props.onChange(newContent); - } - } - - render () { - return ( -
-
-
Bold
-
Italic
-
Link
-
Unlink
-
-
-
- ); - } -}