FIX: improve regex used for image sizing controls (#8291)

This commit is contained in:
Joe
2019-11-05 18:40:02 +08:00
committed by GitHub
parent 5502128105
commit 8e419a772f
2 changed files with 55 additions and 25 deletions

View File

@ -836,7 +836,11 @@ export default Component.extend({
return; return;
} }
const replacement = match.replace(imageScaleRegex, `$1,${scale}%$3`); const replacement = match.replace(
imageScaleRegex,
`![$1|$2, ${scale}%]($4)`
);
this.appEvents.trigger( this.appEvents.trigger(
"composer:replace-text", "composer:replace-text",
matchingPlaceholder[index], matchingPlaceholder[index],
@ -851,11 +855,18 @@ export default Component.extend({
// regex matches only upload placeholders with size defined, // regex matches only upload placeholders with size defined,
// which is required for resizing // which is required for resizing
// original string `![28|690x226,5%](upload://ceEfx3vO7bx7Cecv2co1SrnoTpW.png)` // original string `![image|690x220, 50%](upload://1TjaobgKObzpU7xRMw2HuUc87vO.png "image title")`
// match 1 `![28|690x226` // group 1 `image`
// match 2 `5` // group 2 `690x220`
// match 3 `](upload://ceEfx3vO7bx7Cecv2co1SrnoTpW.png)` // group 3 `, 50%`
const imageScaleRegex = /(!\[(?:\S*?(?=\|)\|)*?(?:\d{1,6}x\d{1,6})+?)(?:,?(\d{1,3})?%?)?(\]\(upload:\/\/\S*?\))/g; // group 4 'upload://1TjaobgKObzpU7xRMw2HuUc87vO.png'
// group 4 'upload://1TjaobgKObzpU7xRMw2HuUc87vO.png "image title"'
// Notes:
// Group 3 is optional. group 4 can match images with or without a markdown title.
// All matches are whitespace tolerant as long it's still valid markdown
const imageScaleRegex = /!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?\]\((upload:\/\/.*?)\)/g;
// wraps previewed upload markdown in a codeblock in its own class to keep a track // wraps previewed upload markdown in a codeblock in its own class to keep a track
// of indexes later on to replace the correct upload placeholder in the composer // of indexes later on to replace the correct upload placeholder in the composer

View File

@ -721,49 +721,68 @@ QUnit.test("Image resizing buttons", async assert => {
await click("#create-topic"); await click("#create-topic");
let uploads = [ let uploads = [
// 0 Default markdown with dimensions- should work
"![test|690x313](upload://test.png)", "![test|690x313](upload://test.png)",
"[img]http://example.com/image.jpg[/img]", // 1 Image with scaling percentage, should work
"![anotherOne|690x463](upload://anotherOne.jpeg)", "![test|690x313,50%](upload://test.png)",
"![](upload://withoutAltAndSize.jpeg)", // 2 image with scaling percentage and a proceeding whitespace, should work
"![test|690x313, 50%](upload://test.png)",
// 3 No dimensions, should not work
"![test](upload://test.jpeg)",
// 4 Wrapped in backquetes should not work
"`![test|690x313](upload://test.png)`", "`![test|690x313](upload://test.png)`",
"![withoutSize](upload://withoutSize.png)", // 5 html image - should not work
"<img src='http://someimage.jpg' wight='20' height='20'>", "<img src='http://someimage.jpg' wight='20' height='20'>",
// 6 two images one the same line, but both are syntactically correct - both should work
"![onTheSameLine1|200x200](upload://onTheSameLine1.jpeg) ![onTheSameLine2|250x250](upload://onTheSameLine2.jpeg)", "![onTheSameLine1|200x200](upload://onTheSameLine1.jpeg) ![onTheSameLine2|250x250](upload://onTheSameLine2.jpeg)",
// 7 & 8 Identical images - both should work
"![identicalImage|300x300](upload://identicalImage.png)", "![identicalImage|300x300](upload://identicalImage.png)",
"![identicalImage|300x300](upload://identicalImage.png)" "![identicalImage|300x300](upload://identicalImage.png)",
// 9 Image with whitespaces in alt - should work
"![image with spaces in alt|690x220](upload://test.png)",
// 10 Image with markdown title - should work
`![image|690x220](upload://test.png "image title")`,
// 11 bbcode - should not work
"[img]http://example.com/image.jpg[/img]"
]; ];
await fillIn(".d-editor-input", uploads.join("\n")); await fillIn(".d-editor-input", uploads.join("\n"));
assert.ok( assert.ok(
find(".button-wrapper").length === 6, find(".button-wrapper").length === 9,
"it adds correct amount of scaling button groups" "it adds correct amount of scaling button groups"
); );
uploads[0] = "![test|690x313,50%](upload://test.png)"; // Default
uploads[0] = "![test|690x313, 50%](upload://test.png)";
await click(find(".button-wrapper .scale-btn[data-scale='50']")[0]); await click(find(".button-wrapper .scale-btn[data-scale='50']")[0]);
assertImageResized(assert, uploads); assertImageResized(assert, uploads);
uploads[2] = "![anotherOne|690x463,75%](upload://anotherOne.jpeg)"; // Targets the correct image if two on the same line
await click(find(".button-wrapper .scale-btn[data-scale='75']")[1]); uploads[6] =
"![onTheSameLine1|200x200, 50%](upload://onTheSameLine1.jpeg) ![onTheSameLine2|250x250](upload://onTheSameLine2.jpeg)";
await click(find(".button-wrapper .scale-btn[data-scale='50']")[3]);
assertImageResized(assert, uploads); assertImageResized(assert, uploads);
uploads[7] = // Try the other image on the same line
"![onTheSameLine1|200x200,50%](upload://onTheSameLine1.jpeg) ![onTheSameLine2|250x250](upload://onTheSameLine2.jpeg)"; uploads[6] =
await click(find(".button-wrapper .scale-btn[data-scale='50']")[2]); "![onTheSameLine1|200x200, 50%](upload://onTheSameLine1.jpeg) ![onTheSameLine2|250x250, 75%](upload://onTheSameLine2.jpeg)";
await click(find(".button-wrapper .scale-btn[data-scale='75']")[4]);
assertImageResized(assert, uploads); assertImageResized(assert, uploads);
uploads[7] = // Make sure we target the correct image if there are duplicates
"![onTheSameLine1|200x200,50%](upload://onTheSameLine1.jpeg) ![onTheSameLine2|250x250,75%](upload://onTheSameLine2.jpeg)"; uploads[7] = "![identicalImage|300x300, 50%](upload://identicalImage.png)";
await click(find(".button-wrapper .scale-btn[data-scale='75']")[3]); await click(find(".button-wrapper .scale-btn[data-scale='50']")[5]);
assertImageResized(assert, uploads); assertImageResized(assert, uploads);
uploads[8] = "![identicalImage|300x300,50%](upload://identicalImage.png)"; // Try the other dupe
await click(find(".button-wrapper .scale-btn[data-scale='50']")[4]); uploads[8] = "![identicalImage|300x300, 75%](upload://identicalImage.png)";
await click(find(".button-wrapper .scale-btn[data-scale='75']")[6]);
assertImageResized(assert, uploads); assertImageResized(assert, uploads);
uploads[9] = "![identicalImage|300x300,75%](upload://identicalImage.png)"; // Don't mess with image titles
await click(find(".button-wrapper .scale-btn[data-scale='75']")[5]); uploads[10] = `![image|690x220, 75%](upload://test.png "image title")`;
await click(find(".button-wrapper .scale-btn[data-scale='75']")[8]);
assertImageResized(assert, uploads); assertImageResized(assert, uploads);
await fillIn( await fillIn(