From a495a3894c98e0176d658b7789088defcc88794d Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Thu, 28 Nov 2024 00:15:12 +0900 Subject: [PATCH] Display pasted images in appropriate size on HiDPI displays --- app/assets/javascripts/attachments.js | 75 +++++++++++++++++++++------ 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/attachments.js b/app/assets/javascripts/attachments.js index e8e9ac6e8..df9c7090e 100644 --- a/app/assets/javascripts/attachments.js +++ b/app/assets/javascripts/attachments.js @@ -229,15 +229,60 @@ function setupFileDrop() { } } +function getImageWidth(file) { + return new Promise((resolve, reject) => { + if (file.type.startsWith("image/")) { + const reader = new FileReader(); + reader.onload = function(event) { + const img = new Image(); + img.onload = function() { + resolve(img.width); + }; + img.onerror = reject; + img.src = event.target.result; + }; + reader.onerror = reject; + reader.readAsDataURL(file); + } else { + resolve(0); + } + }); +} + +async function getInlineAttachmentMarkup(file) { + const sanitizedFilename = file.name.replace(/[\/\?\%\*\:\|\"\'<>\n\r]+/g, '_'); + const inlineFilename = encodeURIComponent(sanitizedFilename) + .replace(/[!()]/g, function(match) { return "%" + match.charCodeAt(0).toString(16) }); + + const isFromClipboard = /^clipboard-\d{12}-[a-z0-9]{5}\.\w+$/.test(file.name); + let imageDisplayWidth; + if (isFromClipboard) { + const imageWidth = await getImageWidth(file).catch(() => 0); + imageDisplayWidth = Math.round(imageWidth / window.devicePixelRatio); + } + const hasValidWidth = isFromClipboard && imageDisplayWidth > 0; + + switch (document.body.getAttribute('data-text-formatting')) { + case 'textile': + return hasValidWidth + ? `!{width: ${imageDisplayWidth}px}.${inlineFilename}!` + : `!${inlineFilename}!`; + case 'common_mark': + return hasValidWidth + ? `
` + : `![](${inlineFilename})`; + default: + // Text formatting is "none" or unknown + return ''; + } +} + function addInlineAttachmentMarkup(file) { // insert uploaded image inline if dropped area is currently focused textarea if($(handleFileDropEvent.target).hasClass('wiki-edit') && $.inArray(file.type, window.wikiImageMimeTypes) > -1) { var $textarea = $(handleFileDropEvent.target); var cursorPosition = $textarea.prop('selectionStart'); var description = $textarea.val(); - var sanitizedFilename = file.name.replace(/[\/\?\%\*\:\|\"\'<>\n\r]+/, '_'); - var inlineFilename = encodeURIComponent(sanitizedFilename) - .replace(/[!()]/g, function(match) { return "%" + match.charCodeAt(0).toString(16) }); var newLineBefore = true; var newLineAfter = true; if(cursorPosition === 0 || description.substr(cursorPosition-1,1).match(/\r|\n/)) { @@ -247,20 +292,16 @@ function addInlineAttachmentMarkup(file) { newLineAfter = false; } - $textarea.val( - description.substring(0, cursorPosition) - + (newLineBefore ? '\n' : '') - + inlineFilename - + (newLineAfter ? '\n' : '') - + description.substring(cursorPosition, description.length) - ); - - $textarea.prop({ - 'selectionStart': cursorPosition + newLineBefore, - 'selectionEnd': cursorPosition + inlineFilename.length + newLineBefore - }); - $textarea.parents('.jstBlock') - .find('.jstb_img').click(); + getInlineAttachmentMarkup(file) + .then(imageMarkup => { + $textarea.val( + description.substring(0, cursorPosition) + + (newLineBefore ? '\n' : '') + + imageMarkup + + (newLineAfter ? '\n' : '') + + description.substring(cursorPosition, description.length) + ); + }) // move cursor into next line cursorPosition = $textarea.prop('selectionStart'); -- 2.47.0