Project

General

Profile

Feature #38504 » 0001-Display-pasted-images-in-appropriate-size-on-HiDPI-d.patch

Go MAEDA, 2024-11-28 11:56

View differences:

app/assets/javascripts/attachments.js
229 229
  }
230 230
}
231 231

  
232
function getImageWidth(file) {
233
  return new Promise((resolve, reject) => {
234
    if (file.type.startsWith("image/")) {
235
      const reader = new FileReader();
236
      reader.onload = function(event) {
237
        const img = new Image();
238
        img.onload = function() {
239
          resolve(img.width);
240
        };
241
        img.onerror = reject;
242
        img.src = event.target.result;
243
      };
244
      reader.onerror = reject;
245
      reader.readAsDataURL(file);
246
    } else {
247
      resolve(0);
248
    }
249
  });
250
}
251

  
252
async function getInlineAttachmentMarkup(file) {
253
  const sanitizedFilename = file.name.replace(/[\/\?\%\*\:\|\"\'<>\n\r]+/g, '_');
254
  const inlineFilename = encodeURIComponent(sanitizedFilename)
255
    .replace(/[!()]/g, function(match) { return "%" + match.charCodeAt(0).toString(16) });
256

  
257
  const isFromClipboard = /^clipboard-\d{12}-[a-z0-9]{5}\.\w+$/.test(file.name);
258
  let imageDisplayWidth;
259
  if (isFromClipboard) {
260
    const imageWidth = await getImageWidth(file).catch(() => 0);
261
    imageDisplayWidth = Math.round(imageWidth / window.devicePixelRatio);
262
  }
263
  const hasValidWidth = isFromClipboard && imageDisplayWidth > 0;
264

  
265
  switch (document.body.getAttribute('data-text-formatting')) {
266
    case 'textile':
267
      return hasValidWidth
268
        ? `!{width: ${imageDisplayWidth}px}.${inlineFilename}!`
269
        : `!${inlineFilename}!`;
270
    case 'common_mark':
271
      return hasValidWidth
272
        ? `<img style="width: ${imageDisplayWidth}px;" src="${inlineFilename}"><br>`
273
        : `![](${inlineFilename})`;
274
    default:
275
      // Text formatting is "none" or unknown
276
      return '';
277
  }
278
}
279

  
232 280
function addInlineAttachmentMarkup(file) {
233 281
  // insert uploaded image inline if dropped area is currently focused textarea
234 282
  if($(handleFileDropEvent.target).hasClass('wiki-edit') && $.inArray(file.type, window.wikiImageMimeTypes) > -1) {
235 283
    var $textarea = $(handleFileDropEvent.target);
236 284
    var cursorPosition = $textarea.prop('selectionStart');
237 285
    var description = $textarea.val();
238
    var sanitizedFilename = file.name.replace(/[\/\?\%\*\:\|\"\'<>\n\r]+/, '_');
239
    var inlineFilename = encodeURIComponent(sanitizedFilename)
240
      .replace(/[!()]/g, function(match) { return "%" + match.charCodeAt(0).toString(16) });
241 286
    var newLineBefore = true;
242 287
    var newLineAfter = true;
243 288
    if(cursorPosition === 0 || description.substr(cursorPosition-1,1).match(/\r|\n/)) {
......
247 292
      newLineAfter = false;
248 293
    }
249 294

  
250
    $textarea.val(
251
      description.substring(0, cursorPosition)
252
      + (newLineBefore ? '\n' : '')
253
      + inlineFilename
254
      + (newLineAfter ? '\n' : '')
255
      + description.substring(cursorPosition, description.length)
256
    );
257

  
258
    $textarea.prop({
259
      'selectionStart': cursorPosition + newLineBefore,
260
      'selectionEnd': cursorPosition + inlineFilename.length + newLineBefore
261
    });
262
    $textarea.parents('.jstBlock')
263
      .find('.jstb_img').click();
295
    getInlineAttachmentMarkup(file)
296
      .then(imageMarkup => {
297
        $textarea.val(
298
          description.substring(0, cursorPosition)
299
          + (newLineBefore ? '\n' : '')
300
          + imageMarkup
301
          + (newLineAfter ? '\n' : '')
302
          + description.substring(cursorPosition, description.length)
303
        );
304
      })
264 305

  
265 306
    // move cursor into next line
266 307
    cursorPosition = $textarea.prop('selectionStart');
(5-5/5)