diff --git a/front/vue/components/DiploPanel.vue b/front/vue/components/DiploPanel.vue index 82409240c3d97e54fa341ce7953f0d8dbfc8d93d..cb8b21b2126b1ddcd06c30f94739cd7af583ff3a 100644 --- a/front/vue/components/DiploPanel.vue +++ b/front/vue/components/DiploPanel.vue @@ -87,6 +87,8 @@ export default Vue.extend({ }.bind(this)); this.refresh(); + + }, methods: { empty() { @@ -250,35 +252,129 @@ export default Vue.extend({ tmp.remove(); return clean; }, + onPaste(e) { - let pastedData = e.clipboardData.getData('text/plain'); - let pasted_data_split = pastedData.split('\n'); + let diplomaticLines=document.querySelector("#diplomatic-lines"); + var types, pastedData, savedContent; + + // Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+) + if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) { + types = e.clipboardData.types; + if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.indexOf && types.indexOf('text/html') !== -1)) { + // Extract data and pass it to callback + pastedData = e.clipboardData.getData('text/html'); + //pastedData = e.clipboardData.getData('text/plain'); + this.processPaste(diplomaticLines, pastedData); - if (pasted_data_split.length == 1) { - let content = this.cleanSource(pastedData); - document.execCommand('insertText', false, content); - } else { - const selection = window.getSelection(); - let range = selection.getRangeAt(0); - let target = range.startContainer.nodeType==Node.TEXT_NODE?range.startContainer.parentNode:range.startContainer; - let start = Array.prototype.indexOf.call(this.$refs.diplomaticLines.children, target); - let newDiv, child = this.$refs.diplomaticLines.children[start]; - for (let i = 0; i < pasted_data_split.length; i++) { - newDiv = this.appendLine(child); - newDiv.textContent = this.cleanSource(pasted_data_split[i]); - // trick to get at least 'some' ctrl+z functionality - // this fails in spectacular ways differently in firefox and chrome... so no ctrl+z - /* range.setStart(newDiv, 0); - * selection.removeAllRanges(); - * selection.addRange(range); - * document.execCommand("insertText", false, this.cleanSource(content)); */ + // Stop the data from actually being pasted + e.stopPropagation(); + e.preventDefault(); + return false; + }else { + + // Extract data and pass it to callback + pastedData = e.clipboardData.getData('text/plain'); + //pastedData = e.clipboardData.getData('text/plain'); + this.processPaste(diplomaticLines, pastedData); + + // Stop the data from actually being pasted + e.stopPropagation(); + e.preventDefault(); + return false; } } + + // Everything else: Move existing element contents to a DocumentFragment for safekeeping + savedContent = document.createDocumentFragment(); + while(diplomaticLines.childNodes.length > 0) { + savedContent.appendChild(diplomaticLines.childNodes[0]); + } + + // Then wait for browser to paste content into it and cleanup + this.waitForPastedData(diplomaticLines, savedContent); + return true; + }, + processPaste(diplomaticLines, replacementText) + { + // store initial number of segemnted lines: + let nativeNumberOfLines = diplomaticLines.getElementsByTagName('div').length; - this.$refs.saveNotif.classList.remove('hide'); - this.constrainLineNumber(); - e.preventDefault(); + let sel; + if (window.getSelection) { + sel = window.getSelection(); + + if (sel.rangeCount) + { + // put the replacementn text into a div element to manage content as tags + let tmpDiv = document.createElement('div'); + let textLines = new Array(); + tmpDiv.innerHTML = replacementText; // important sile texte à récupérer est au format html + + // convert html/plain text CR into a normalized separator ([CR]): + let divs = tmpDiv.getElementsByTagName("div"); + if(divs.length > 0) // some html content, mainly from another transcription panel + { + for(var i=0;i<divs.length;i++) + { + textLines.push(divs[i].textContent + '[CR]'); + } + }else{ // plain text with some included CR chars + var regCR = new RegExp("[\r]{0,1}\n", "g"); + var plainTextLines = replacementText.split(regCR); + + for(var i=0;i<plainTextLines.length;i++) + { + textLines.push(plainTextLines[i] + '[CR]'); + } + } + replacementText = textLines.join(''); + + // place this text as content of a div + var newNode = document.createElement('div'); newNode.innerHTML = replacementText; + var cursor = sel.getRangeAt(0); + cursor.deleteContents(); + // paste text on the selection (cursor position or range): + cursor.insertNode(newNode); + + // convert the whole html text lines into a single string with normalized separator ([CR]) + let content = ''; + tmpDiv.innerHTML = diplomaticLines.innerHTML; + divs = tmpDiv.getElementsByTagName("div"); + var numberOfLines = divs.length; + var indexLine = 0; + var currentDiv; + while(typeof(divs[0]) != "undefined") + { + currentDiv = divs[0]; + var innerContent = currentDiv.textContent; + content += innerContent; + + // add a CR char for each div/ only if not last line and does not contain a CR char at the end: + if((indexLine < numberOfLines-1)&&(innerContent.substring(innerContent.length - 4) != '[CR]')) + content += '[CR]'; + // to avoid doublons, we remove each div tag from tmpDiv: + currentDiv.parentNode.removeChild(currentDiv); + indexLine++; + } + + // convert each new line into a div element + textLines = content.split('[CR]'); + tmpDiv.innerHTML = ''; + for(var i=0;i<textLines.length;i++) + { + tmpDiv.innerHTML +='<div title="">'+textLines[i]+'</div>'; + } + + // update panel content! : + diplomaticLines.innerHTML = tmpDiv.innerHTML; + } + } else if (document.selection && document.selection.createRange) { + + range = document.selection.createRange(); + range.text = replacementText; + } }, + showOverlay(ev) { let target = ev.target.nodeType==Node.TEXT_NODE?ev.target.parentNode:ev.target; let index = Array.prototype.indexOf.call(target.parentNode.children, target);