From dfd1f0cf5e521fd6721ca58bd5e79809ac7b41c6 Mon Sep 17 00:00:00 2001 From: Jacob Benz <jacob.benz@stud.h-da.de> Date: Fri, 17 May 2024 11:13:54 +0200 Subject: [PATCH] Add lb-tag after Shift+Enter as linebreak for transcribing workflow --- .../src/js/tinymce/tinymceWrapper.ts | 105 +++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/packages/cwrc-leafwriter/src/js/tinymce/tinymceWrapper.ts b/packages/cwrc-leafwriter/src/js/tinymce/tinymceWrapper.ts index ea4aa873..c3eabc6b 100644 --- a/packages/cwrc-leafwriter/src/js/tinymce/tinymceWrapper.ts +++ b/packages/cwrc-leafwriter/src/js/tinymce/tinymceWrapper.ts @@ -297,7 +297,9 @@ export const tinymceWrapperInit = function ({ writer.event('writerKeydown').publish(event); }; - const onKeyUpHandler = (event: KeyboardEvent) => { + const onKeyUpHandler = async (event: KeyboardEvent) => { + const { overmindState, overmindActions } = writer; + // nav keys and backspace check switch (event.code) { case 'Home': @@ -437,7 +439,106 @@ export const tinymceWrapperInit = function ({ if (event.shiftKey) { // TODO replace linebreaks inserted on shift+enter with schema specific linebreak tag // for now just undo the linebreak in the text - node.normalize(); + // This schema specific linebreak is now lb. With this decision and our handling of lb and similiar self-closing tags below, + // we implicitly narrowed the scope of LEAF-Writer to TEI and TEI only. + if (!writer) return; + + // Detect tags that can be inserted an the current position and check that lb is one of them + const xpath = writer.utilities.getElementXPath(node); + if (!xpath) return; + const index = 0; + const selection: PossibleNodesAtTargetSelection = { + type: 'inside', + xpath: xpath ?? '', + }; + const request: PossibleNodesAtTarget = { xpath, index, selection }; + // console.log(request); + + const tags = await overmindActions.validator.getPossibleNodesAt(request); // get possible nodes from validator for current xpath-locattion and inside this location + if (!tags) { // If we did not get anythin back from the validator-worker, we have to end, since we can't check if lb is allowed. + node.normalize(); + writer.event('writerKeyup').publish(event); + return + } + //console.log(tags) + + let lbIsAllowed = false + tags.map(({ name, fullName, invalid, documentation }) => { + if (name === "lb") { + lbIsAllowed = true + } + }) + + if (lbIsAllowed === true) { // Add new lb-tag at current position + //console.log("Yes, we can [lb]!") + //console.log(curnode) + //console.log(writer.editor.currentBookmark) + //console.log(writer.editor?.selection.getBookmark(1)) + log.info("inserting lb-tag after Shift+Enter press") + // Insert new lb-tag at current position (adapted code from File "tagger.ts") + const id = writer.getUniqueId('dom_'); + const bookmark = writer.editor.currentBookmark + const tagName = "lb" + + let $newlbnode: JQuery<any>; + + // this is meant for user text selections + //@ts-ignore + let newlbnode = bookmark.rng.commonAncestorContainer; + while ( + newlbnode.nodeType == Node.TEXT_NODE || + (newlbnode.nodeType == Node.ELEMENT_NODE && !newlbnode.hasAttribute('_tag')) + ) { + newlbnode = newlbnode.parentNode; + } + $newlbnode = $(newlbnode); + + // noteWrapper handling + let $noteWrapper: JQuery<any> | null = null; + const noteAttr_tag = $newlbnode.attr('_tag'); + const entityType = noteAttr_tag + ? writer.schemaManager.mapper.getEntityTypeForTag(noteAttr_tag) + : null; + + + const editorTagName = writer.schemaManager.getTagForEditor(tagName); + let open_tag = `<${editorTagName} id="${id}" _tag="lb"`; + // We have to check if text is allowed in the tag we want to add. + let textallowed = writer.schemaManager.canTagContainText(tagName); + open_tag += ` _textallowed="${textallowed}"`; + + + const close_tag = '</' + editorTagName + '>'; + // const close_tag = '</' + editorTagName + '>' + '\uFEFF'; + let content = `${open_tag}${close_tag}`; + + // default action = add + //@ts-ignore + writer.editor?.selection.moveToBookmark(bookmark); + + //@ts-ignore + const range: Range = writer.editor?.selection.getRng(true); + const tempNode = $('<span data-mce-bogus="1">', writer.editor?.getDoc()); + //@ts-ignore + range.surroundContents(tempNode[0]); + tempNode.replaceWith(content); + + const newTag = $(`#${id}`, writer.editor?.getBody()); + writer.event('tagAdded').publish(newTag[0]); + + writer.editor?.undoManager.add(); + // place the cursor at the end of the tag's contents + //@ts-ignore + const rng: Range = writer.editor?.selection.getRng(true); + //@ts-ignore + rng.selectNodeContents($(`#${id}`, writer.editor?.getBody())[0]); + rng.collapse(false); + writer.editor?.selection.setRng(rng); + + + } else { + node.normalize(); + } } else { // empty tag check // insert zero-width non-breaking space so empty tag takes up space -- GitLab