Bug 1315440
- Follow-up: Fix advance edit when shortened data URIs are used. r=mkmelin
This commit is contained in:
Родитель
58abf93dce
Коммит
9d381b420b
|
@ -30,6 +30,8 @@ var gOriginalSrc = "";
|
|||
var gHaveDocumentUrl = false;
|
||||
var gTimerID;
|
||||
var gValidateTab;
|
||||
var gFullDataURI;
|
||||
var gListenerAttached = false;
|
||||
|
||||
// These must correspond to values in EditorDialog.css for each theme
|
||||
// (unfortunately, setting "style" attribute here doesn't work!)
|
||||
|
@ -68,13 +70,52 @@ function ImageStartup()
|
|||
gDialog.OkButton = document.documentElement.getButton("accept");
|
||||
}
|
||||
|
||||
function onCopyOrCut(event) {
|
||||
// Put the original data URI onto the clipboard in case the value
|
||||
// is a shortened data URI.
|
||||
let startPos = gDialog.srcInput.selectionStart;
|
||||
if (startPos == undefined)
|
||||
return;
|
||||
let endPos = gDialog.srcInput.selectionEnd;
|
||||
let selection = gDialog.srcInput.value.substring(startPos, endPos).trim();
|
||||
|
||||
// Test that a) the user selected the whole value,
|
||||
// b) the value is a data URI,
|
||||
// c) it contains the ellipsis we added. Otherwise it could be
|
||||
// a new value that the user pasted in.
|
||||
if (selection == gDialog.srcInput.value.trim() &&
|
||||
/^data:/i.test(selection) && selection.includes("…")) {
|
||||
event.clipboardData.setData("text/plain", gFullDataURI);
|
||||
if (event.type == "cut") {
|
||||
// We have to cut the selection manually. Since we tested that
|
||||
// everything was selected, we can just reset the field.
|
||||
gDialog.srcInput.value = "";
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// Set dialog widgets with attribute data
|
||||
// We get them from globalElement copy so this can be used
|
||||
// by AdvancedEdit(), which is shared by all property dialogs
|
||||
function InitImage()
|
||||
{
|
||||
// Set the controls to the image's attributes
|
||||
gDialog.srcInput.value = globalElement.getAttribute("src");
|
||||
var src = globalElement.getAttribute("src");
|
||||
|
||||
// Shorten data URIs for display.
|
||||
gDialog.srcInput.value = src.replace(/(data:[^;]*;base64,)(.*)/i,
|
||||
function(match, nonDataPart, dataPart) {
|
||||
if (!gListenerAttached) {
|
||||
gDialog.srcInput.addEventListener("copy", onCopyOrCut);
|
||||
gDialog.srcInput.addEventListener("cut", onCopyOrCut);
|
||||
gListenerAttached = true;
|
||||
}
|
||||
gDialog.srcInput.setAttribute("tooltip", "shortenedDataURI");
|
||||
gFullDataURI = src;
|
||||
return nonDataPart + dataPart.substring(0, 5) + "…" +
|
||||
dataPart.substring(dataPart.length - 30);
|
||||
});
|
||||
|
||||
// Set "Relativize" checkbox according to current URL state
|
||||
SetRelativeCheckbox();
|
||||
|
@ -278,6 +319,11 @@ function LoadPreviewImage()
|
|||
var imageSrc = TrimString(gDialog.srcInput.value);
|
||||
if (!imageSrc)
|
||||
return;
|
||||
if (/^data:/i.test(imageSrc) && imageSrc.includes("…"))
|
||||
{
|
||||
// Restore URIs from the original.
|
||||
imageSrc = gFullDataURI;
|
||||
}
|
||||
|
||||
try {
|
||||
// Remove the image URL from image cache so it loads fresh
|
||||
|
@ -458,16 +504,25 @@ function ValidateImage()
|
|||
|
||||
// We must convert to "file:///" or "http://" format else image doesn't load!
|
||||
let src = gDialog.srcInput.value.trim();
|
||||
var checkbox = document.getElementById("MakeRelativeCheckbox");
|
||||
try
|
||||
{
|
||||
if (checkbox && !checkbox.checked)
|
||||
{
|
||||
src = Services.uriFixup.createFixupURI(src, Components.interfaces.nsIURIFixup.FIXUP_FLAG_NONE).spec;
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
globalElement.setAttribute("src", src);
|
||||
if (/^data:/i.test(src) && src.includes("…"))
|
||||
{
|
||||
// Restore shortened URIs from the original.
|
||||
src = gFullDataURI;
|
||||
}
|
||||
else
|
||||
{
|
||||
var checkbox = document.getElementById("MakeRelativeCheckbox");
|
||||
try
|
||||
{
|
||||
if (checkbox && !checkbox.checked)
|
||||
{
|
||||
src = Services.uriFixup.createFixupURI(src, Components.interfaces.nsIURIFixup.FIXUP_FLAG_NONE).spec;
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
globalElement.setAttribute("src", src);
|
||||
}
|
||||
|
||||
let title = gDialog.titleInput.value.trim();
|
||||
if (title)
|
||||
|
|
|
@ -23,14 +23,15 @@ function Startup()
|
|||
// 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)
|
||||
{
|
||||
gDialog.srcInput.addEventListener("paste", onPaste);
|
||||
|
||||
selection = (selection.replace(/<body[^>]*>/,"")).replace(/<\/body>/,"");
|
||||
|
||||
// Shorten data URIs for display.
|
||||
|
@ -47,12 +48,12 @@ function Startup()
|
|||
|
||||
function replaceDataURIs(input)
|
||||
{
|
||||
return input.replace(/(src|href)(="data:[^;]*;base64,)([^"]+)/gi,
|
||||
function(match, attr, nonDataPart, dataPart) {
|
||||
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 attr + nonDataPart + gShortDataStrings.get(dataPart);
|
||||
return nonDataPart + gShortDataStrings.get(dataPart);
|
||||
}
|
||||
|
||||
let l = 5;
|
||||
|
@ -68,23 +69,16 @@ function replaceDataURIs(input)
|
|||
// 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", onCopy);
|
||||
gDialog.srcInput.addEventListener("cut", onCut);
|
||||
gDialog.srcInput.addEventListener("copy", onCopyOrCut);
|
||||
gDialog.srcInput.addEventListener("cut", onCopyOrCut);
|
||||
gListenerAttached = true;
|
||||
}
|
||||
|
||||
return attr + nonDataPart + key;
|
||||
return nonDataPart + key;
|
||||
});
|
||||
}
|
||||
|
||||
function onCut(event) {
|
||||
commonCopyCut(event, true);
|
||||
}
|
||||
function onCopy(event) {
|
||||
commonCopyCut(event, false);
|
||||
}
|
||||
|
||||
function commonCopyCut(event, isCut)
|
||||
function onCopyOrCut(event)
|
||||
{
|
||||
let startPos = gDialog.srcInput.selectionStart;
|
||||
if (startPos == undefined)
|
||||
|
@ -93,14 +87,14 @@ function commonCopyCut(event, isCut)
|
|||
let clipboard = gDialog.srcInput.value.substring(startPos, endPos);
|
||||
|
||||
// Add back the original data URIs we stashed away earlier.
|
||||
clipboard = clipboard.replace(/(data:[^;]*;base64,)([^"]+)/gi,
|
||||
clipboard = clipboard.replace(/(data:[^;]*;base64,)([^"' >]+)/gi,
|
||||
function(match, nonDataPart, key) {
|
||||
if (!gFullDataStrings.has(key))
|
||||
return match; // user changed data URI
|
||||
return nonDataPart + gFullDataStrings.get(key);
|
||||
});
|
||||
event.clipboardData.setData("text/plain", clipboard);
|
||||
if (isCut) {
|
||||
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);
|
||||
|
@ -131,11 +125,11 @@ function onAccept()
|
|||
return false;
|
||||
|
||||
// Add back the original data URIs we stashed away earlier.
|
||||
html = html.replace(/(src|href)(="data:[^;]*;base64,)([^"]+)/gi,
|
||||
function(match, attr, nonDataPart, key) {
|
||||
html = html.replace(/(data:[^;]*;base64,)([^"' >]+)/gi,
|
||||
function(match, nonDataPart, key) {
|
||||
if (!gFullDataStrings.has(key))
|
||||
return match; // user changed data URI
|
||||
return attr + nonDataPart + gFullDataStrings.get(key);
|
||||
return nonDataPart + gFullDataStrings.get(key);
|
||||
});
|
||||
|
||||
try {
|
||||
|
|
|
@ -48,19 +48,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
addEventListener("load", OnLoadOverlay, false);
|
||||
|
||||
function OnAcceptOverlay()
|
||||
{
|
||||
// Restore data URI. We need to restore if there is a data URI and we
|
||||
// find the ellipsis we added. The user could have pasted a full new
|
||||
// data URI which we don't want to lose.
|
||||
if (/^data:/i.test(gMsgCompInputElement.value.trim()) &&
|
||||
gMsgCompInputElement.value.includes("...")) {
|
||||
gMsgCompInputElement.value = gMsgCompPrevInputValue;
|
||||
}
|
||||
}
|
||||
addEventListener("dialogaccept", OnAcceptOverlay, false);
|
||||
addEventListener("load", OnLoadOverlay, false);
|
||||
|
||||
function SetAttachCheckbox()
|
||||
{
|
||||
|
@ -114,49 +103,6 @@
|
|||
attach = (mozDoNotSend != "true");
|
||||
|
||||
gMsgCompAttachSourceElement.checked = attach;
|
||||
|
||||
// Shorten data URIs for display. Let's not use an ellipsis character
|
||||
// since this will look funny in the advanced edit dialogue.
|
||||
gMsgCompInputElement.value = gMsgCompInputElement
|
||||
.value.replace(/(data:[^;]*;base64,)(.*)/i,
|
||||
function(match, nonDataPart, dataPart) {
|
||||
gMsgCompInputElement.addEventListener("copy", onCopy);
|
||||
gMsgCompInputElement.addEventListener("cut", onCut);
|
||||
gMsgCompInputElement.setAttribute("tooltip", "shortenedDataURI");
|
||||
return nonDataPart + dataPart.substring(0, 5) + "..." +
|
||||
dataPart.substring(dataPart.length - 30);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onCut(event) {
|
||||
commonCopyCut(event, true);
|
||||
}
|
||||
function onCopy(event) {
|
||||
commonCopyCut(event, false);
|
||||
}
|
||||
function commonCopyCut(event, isCut) {
|
||||
// Put the original data URI onto the clipboard in case the value
|
||||
// is a shortened data URI.
|
||||
let startPos = gMsgCompInputElement.selectionStart;
|
||||
if (startPos == undefined)
|
||||
return;
|
||||
let endPos = gMsgCompInputElement.selectionEnd;
|
||||
let selection = gMsgCompInputElement.value.substring(startPos, endPos).trim();
|
||||
|
||||
// Test that a) the user selected the whole value,
|
||||
// b) the value is a data URI,
|
||||
// c) it contains the ellipsis we added. Otherwise it could be
|
||||
// a new value that the user pasted in.
|
||||
if (selection == gMsgCompInputElement.value.trim() &&
|
||||
/^data:/i.test(selection) && selection.includes("...")) {
|
||||
event.clipboardData.setData("text/plain", gMsgCompPrevInputValue);
|
||||
if (isCut) {
|
||||
// We have to cut the selection manually. Since we tested that
|
||||
// everything was selected, we can just reset the field.
|
||||
gMsgCompInputElement.value = "";
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче