diff --git a/src/editor/block/block.js b/src/editor/block/block.js index 623c16e..c93d98f 100644 --- a/src/editor/block/block.js +++ b/src/editor/block/block.js @@ -24,14 +24,11 @@ let firstBlockDelimiterSize /** * Return a list of blocks in the document from the syntax tree. * syntaxTreeAvailable() should have been called before this function to ensure the syntax tree is available. - * @param {*} state - * @param {*} timeout - * @returns */ -function getBlocksFromSyntaxTree(state, timeout=50) { +function getBlocksFromSyntaxTree(state) { //const timer = startTimer() const blocks = []; - const tree = syntaxTree(state, state.doc.length, timeout) + const tree = syntaxTree(state, state.doc.length) if (tree) { tree.iterate({ enter: (type) => { @@ -73,7 +70,70 @@ function getBlocksFromSyntaxTree(state, timeout=50) { } /** - * Get the blocks for the document state. + * Parse blocks from document's string contents using String.indexOf() + */ +function getBlocksFromString(state) { + //const timer = startTimer() + const blocks = [] + const doc = state.doc + if (doc.length === 0) { + return []; + } + const content = doc.sliceString(0, doc.length) + const delim = "\n∞∞∞" + let pos = 0 + while (pos < doc.length) { + const blockStart = content.indexOf(delim, pos); + if (blockStart != pos) { + console.error("Error parsing blocks, expected delimiter at", pos) + break; + } + const langStart = blockStart + delim.length; + const delimiterEnd = content.indexOf("\n", langStart) + if (delimiterEnd < 0) { + console.error("Error parsing blocks. Delimiter didn't end with newline") + break + } + const langFull = content.substring(langStart, delimiterEnd); + let auto = false; + let lang = langFull; + if (langFull.endsWith("-a")) { + auto = true; + lang = langFull.substring(0, langFull.length - 2); + } + const contentFrom = delimiterEnd + 1; + let blockEnd = content.indexOf(delim, contentFrom); + if (blockEnd < 0) { + blockEnd = doc.length; + } + + const block = { + language: { + name: lang, + auto: auto, + }, + content: { + from: contentFrom, + to: blockEnd, + }, + delimiter: { + from: blockStart, + to: delimiterEnd + 1, + }, + range: { + from: blockStart, + to: blockEnd, + }, + }; + blocks.push(block); + pos = blockEnd; + } + //console.log("getBlocksFromString() took", timer(), "ms") + return blocks; +} + +/** + * Get the blocks from the document state. * If the syntax tree is available, we'll extract the blocks from that. Otherwise * the blocks are parsed from the string contents of the document, which is much faster * than waiting for the tree parsing to finnish. @@ -81,69 +141,14 @@ function getBlocksFromSyntaxTree(state, timeout=50) { function getBlocks(state) { if (syntaxTreeAvailable(state, state.doc.length)) { return getBlocksFromSyntaxTree(state) + } else { + return getBlocksFromString(state) } - //const timer = startTimer() - const blocks = [] - const doc = state.doc - if (doc.length === 0) { - return []; - } - const content = doc.sliceString(0, doc.length) - const delim = "\n∞∞∞" - let pos = 0 - while (pos < doc.length) { - const blockStart = content.indexOf(delim, pos); - if (blockStart != pos) { - console.error("Error parsing blocks, expected delimiter at", pos) - break; - } - const langStart = blockStart + delim.length; - const delimiterEnd = content.indexOf("\n", langStart) - if (delimiterEnd < 0) { - console.error("Error parsing blocks. Delimiter didn't end with newline") - break - } - const langFull = content.substring(langStart, delimiterEnd); - let auto = false; - let lang = langFull; - if (langFull.endsWith("-a")) { - auto = true; - lang = langFull.substring(0, langFull.length - 2); - } - const contentFrom = delimiterEnd + 1; - let blockEnd = content.indexOf(delim, contentFrom); - if (blockEnd < 0) { - blockEnd = doc.length; - } - - const block = { - language: { - name: lang, - auto: auto, - }, - content: { - from: contentFrom, - to: blockEnd, - }, - delimiter: { - from: blockStart, - to: delimiterEnd + 1, - }, - range: { - from: blockStart, - to: blockEnd, - }, - }; - blocks.push(block); - pos = blockEnd; - } - //console.log("getBlocks (string parsing) took", timer(), "ms") - return blocks; } export const blockState = StateField.define({ create(state) { - return getBlocks(state, 1000); + return getBlocks(state); }, update(blocks, transaction) { // if blocks are empty it likely means we didn't get a parsed syntax tree, and then we want to update