diff --git a/package-lock.json b/package-lock.json index 82dedffc..4fb9f732 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3705,6 +3705,11 @@ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=" }, + "browser-split": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz", + "integrity": "sha1-ewl1dPjj6tYG+0Zk5krf3aKYGpM=" + }, "browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", @@ -12077,6 +12082,11 @@ "lodash._isiterateecall": "^3.0.0" } }, + "lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=" + }, "lodash.filter": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", @@ -12092,6 +12102,11 @@ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" }, + "lodash.forown": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", + "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=" + }, "lodash.initial": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.initial/-/lodash.initial-4.1.1.tgz", @@ -12123,6 +12138,11 @@ "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=" }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" + }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -12199,6 +12219,11 @@ "lodash.keys": "^3.0.0" } }, + "lodash.remove": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.remove/-/lodash.remove-4.7.0.tgz", + "integrity": "sha1-8x0x58OaBpDVB07A02JxYjNO5iY=" + }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -12228,8 +12253,7 @@ "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "lodash.where": { "version": "3.1.0", @@ -13964,6 +13988,14 @@ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" }, + "parse-sel": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-sel/-/parse-sel-1.0.0.tgz", + "integrity": "sha1-uTANK7lGoGwiyY4gjkeyCIaQy90=", + "requires": { + "browser-split": "0.0.1" + } + }, "parse5": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", @@ -16470,6 +16502,20 @@ "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-0.7.1.tgz", "integrity": "sha512-uIOCq6rfkBZg2VdSopy9jL0cIOdrkHCcwOjDsLnjef6Z5oPoD8V7nKI8de4gP5GfvyqLY0RBDJP8LVU19Nsw5Q==" }, + "snabbdom-to-html": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/snabbdom-to-html/-/snabbdom-to-html-5.1.0.tgz", + "integrity": "sha512-Fir4/BLW7HRQYAgj2JLOK7BoY3nIfQuwBhCdLdxL/vwgyR+9HRzYWokDcs1IVA7QdDmD84YAdv/8A55NIQEnWQ==", + "requires": { + "lodash.escape": "^4.0.1", + "lodash.forown": "^4.4.0", + "lodash.kebabcase": "^4.1.1", + "lodash.remove": "^4.7.0", + "lodash.uniq": "^4.5.0", + "object-assign": "^4.1.0", + "parse-sel": "^1.0.0" + } + }, "snabbdom-virtualize": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/snabbdom-virtualize/-/snabbdom-virtualize-0.7.0.tgz", diff --git a/package.json b/package.json index 8b5d657b..704e77f9 100644 --- a/package.json +++ b/package.json @@ -115,6 +115,7 @@ "mousetrap": "^1.6.1", "parse5": "^3.0.3", "snabbdom": "^0.7.1", + "snabbdom-to-html": "^5.1.0", "snabbdom-virtualize": "^0.7.0", "to": "^0.2.9", "turndown": "^4.0.1", diff --git a/src/editor/config.js b/src/editor/config.js index 23d14e46..ff584919 100644 --- a/src/editor/config.js +++ b/src/editor/config.js @@ -113,8 +113,7 @@ export const CLASS_OR_ID = genUpper2LowerKeyHash([ 'AG_TIGHT_LIST_ITEM', 'AG_HTML_TAG', 'AG_LINK', - 'AG_HARD_LINE_BREAK', - 'AG_OFF_SCREEN' + 'AG_HARD_LINE_BREAK' ]) export const codeMirrorConfig = { diff --git a/src/editor/index.css b/src/editor/index.css index c7562b4b..f5c6ea2d 100644 --- a/src/editor/index.css +++ b/src/editor/index.css @@ -33,11 +33,6 @@ h6.ag-active::before { font-weight: 100; } -.ag-off-screen { - position: absolute; - left: 100vw; -} - .ag-paragraph:empty::after, .ag-line:empty:after { content: '\200B' diff --git a/src/editor/parser/StateRender.js b/src/editor/parser/StateRender.js index 00cf914d..7b00ef3d 100644 --- a/src/editor/parser/StateRender.js +++ b/src/editor/parser/StateRender.js @@ -1,7 +1,7 @@ import virtualize from 'snabbdom-virtualize/strings' import { CLASS_OR_ID, IMAGE_EXT_REG } from '../config' import { conflict, isLengthEven, union, isEven, getUniqueId, loadImage, getImageSrc } from '../utils' -import { insertBefore, insertAfter, operateClassName } from '../utils/domManipulate' +import { insertAfter, operateClassName } from '../utils/domManipulate' import { tokenizer } from './parse' import { validEmoji } from '../emojis' @@ -13,6 +13,7 @@ const patch = snabbdom.init([ // Init patch function with chosen modules require('snabbdom/modules/dataset').default ]) const h = require('snabbdom/h').default // helper function for creating vnodes +const toHTML = require('snabbdom-to-html') const toVNode = require('snabbdom/tovnode').default class StateRender { @@ -20,18 +21,6 @@ class StateRender { this.eventCenter = eventCenter this.loadImageMap = new Map() this.container = null - this.offScreen = null - this.init() - } - - init () { - let section = document.querySelector(`.${CLASS_OR_ID['AG_OFF_SCREEN']}`) - if (!section) { - section = document.createElement('section') - section.classList.add(CLASS_OR_ID['AG_OFF_SCREEN']) - document.body.appendChild(section) - } - this.offScreen = section } setContainer (container) { @@ -255,12 +244,9 @@ class StateRender { const cursorOutMostBlock = activeBlocks[activeBlocks.length - 1] // If cursor is not in render blocks, need to render cursor block independently const needRenderCursorBlock = blocks.indexOf(cursorOutMostBlock) === -1 - const newVnode = h(`section.${CLASS_OR_ID['AG_OFF_SCREEN']}`, blocks.map(block => this.renderBlock(block, cursor, activeBlocks, matches))) - const { offScreen } = this + const newVnode = h('section', blocks.map(block => this.renderBlock(block, cursor, activeBlocks, matches))) + const html = toHTML(newVnode).replace(/^
([\s\S]+?)<\/section>$/, '$1') - patch(offScreen, newVnode) - - const renderedDoms = offScreen.children const needToRemoved = [] const firstOldDom = startKey ? document.querySelector(`#${startKey}`) @@ -273,14 +259,10 @@ class StateRender { } nextSibling && needToRemoved.push(nextSibling) - Array.from(renderedDoms).forEach(dom => { - insertBefore(dom, firstOldDom) - }) + firstOldDom.insertAdjacentHTML('beforebegin', html) Array.from(needToRemoved).forEach(dom => dom.remove()) - offScreen.textContent = '' - // Render cursor block independently if (needRenderCursorBlock) { const { key } = cursorOutMostBlock