diff options
Diffstat (limited to 'comm/suite/editor/components/dialogs/content/EdInsSrc.js')
-rw-r--r-- | comm/suite/editor/components/dialogs/content/EdInsSrc.js | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/comm/suite/editor/components/dialogs/content/EdInsSrc.js b/comm/suite/editor/components/dialogs/content/EdInsSrc.js new file mode 100644 index 0000000000..0f0304ef1e --- /dev/null +++ b/comm/suite/editor/components/dialogs/content/EdInsSrc.js @@ -0,0 +1,160 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Insert Source HTML dialog */ + +/* import-globals-from ../../composer/content/editorUtilities.js */ +/* import-globals-from EdDialogCommon.js */ + +var gFullDataStrings = new Map(); +var gShortDataStrings = new Map(); +var gListenerAttached = false; + +document.addEventListener("dialogaccept", onAccept); +document.addEventListener("dialogcancel", onCancel); + +function Startup() { + let editor = GetCurrentEditor(); + if (!editor) { + window.close(); + return; + } + + document.documentElement.getButton("accept").removeAttribute("default"); + + // Create dialog object to store controls for easy access + gDialog.srcInput = document.getElementById("srcInput"); + + // Attach a paste listener so we can detect pasted data URIs we need to shorten. + gDialog.srcInput.addEventListener("paste", onPaste); + + let selection; + try { + selection = editor.outputToString( + "text/html", + kOutputFormatted | kOutputSelectionOnly | kOutputWrap + ); + } catch (e) {} + if (selection) { + selection = selection.replace(/<body[^>]*>/, "").replace(/<\/body>/, ""); + + // Shorten data URIs for display. + selection = replaceDataURIs(selection); + + if (selection) { + gDialog.srcInput.value = selection; + } + } + // Set initial focus + gDialog.srcInput.focus(); + SetWindowLocation(); +} + +function replaceDataURIs(input) { + return input.replace(/(data:.+;base64,)([^"' >]+)/gi, function( + match, + nonDataPart, + dataPart + ) { + if (gShortDataStrings.has(dataPart)) { + // We found the exact same data URI, just return the shortened URI. + return nonDataPart + gShortDataStrings.get(dataPart); + } + + let l = 5; + let key; + // Normally we insert the ellipsis after five characters but if it's not unique + // we include more data. + do { + key = dataPart.substr(0, l) + "…" + dataPart.substr(dataPart.length - 10); + l++; + } while (gFullDataStrings.has(key) && l < dataPart.length - 10); + gFullDataStrings.set(key, dataPart); + gShortDataStrings.set(dataPart, key); + + // Attach listeners. In case anyone copies/cuts from the HTML window, + // we want to restore the data URI on the clipboard. + if (!gListenerAttached) { + gDialog.srcInput.addEventListener("copy", onCopyOrCut); + gDialog.srcInput.addEventListener("cut", onCopyOrCut); + gListenerAttached = true; + } + + return nonDataPart + key; + }); +} + +function onCopyOrCut(event) { + let startPos = gDialog.srcInput.selectionStart; + if (startPos == undefined) { + return; + } + let endPos = gDialog.srcInput.selectionEnd; + let clipboard = gDialog.srcInput.value.substring(startPos, endPos); + + // Add back the original data URIs we stashed away earlier. + clipboard = clipboard.replace(/(data:.+;base64,)([^"' >]+)/gi, function( + match, + nonDataPart, + key + ) { + if (!gFullDataStrings.has(key)) { + // User changed data URI. + return match; + } + return nonDataPart + gFullDataStrings.get(key); + }); + event.clipboardData.setData("text/plain", clipboard); + if (event.type == "cut") { + // We have to cut the selection manually. + gDialog.srcInput.value = + gDialog.srcInput.value.substr(0, startPos) + + gDialog.srcInput.value.substr(endPos); + } + event.preventDefault(); +} + +function onPaste(event) { + let startPos = gDialog.srcInput.selectionStart; + if (startPos == undefined) { + return; + } + let endPos = gDialog.srcInput.selectionEnd; + let clipboard = event.clipboardData.getData("text/plain"); + + // We do out own paste by replacing the selection with the pre-processed + // clipboard data. + gDialog.srcInput.value = + gDialog.srcInput.value.substr(0, startPos) + + replaceDataURIs(clipboard) + + gDialog.srcInput.value.substr(endPos); + event.preventDefault(); +} + +function onAccept(event) { + let html = gDialog.srcInput.value; + if (!html) { + event.preventDefault(); + return; + } + + // Add back the original data URIs we stashed away earlier. + html = html.replace(/(data:.+;base64,)([^"' >]+)/gi, function( + match, + nonDataPart, + key + ) { + if (!gFullDataStrings.has(key)) { + // User changed data URI. + return match; + } + return nonDataPart + gFullDataStrings.get(key); + }); + + try { + GetCurrentEditor().insertHTML(html); + } catch (e) {} + SaveWindowLocation(); +} |