浏览代码

Append `.png` to failed image URLs without extensions

Otherwise Imgur URLs don't render
JC Brand 4 年之前
父节点
当前提交
831a9fa224
共有 5 个文件被更改,包括 26 次插入17 次删除
  1. 6 2
      docs/source/configuration.rst
  2. 1 1
      spec/mentions.js
  3. 4 9
      spec/messages.js
  4. 11 2
      src/templates/directives/image.js
  5. 4 3
      src/utils/html.js

+ 6 - 2
docs/source/configuration.rst

@@ -910,9 +910,13 @@ If the given value is negative or ``0``, this feature is disabled.
 image_urls_regex
 ----------------
 
-Any URLs in a message that matches the regex in this setting will be considered an image and displayed inline.
+* Default: ``null``
+
+Any URL in a message that matches the regex in this setting will be considered an image and rendered, if `show_images_inline`_ is set to ``true``.
+If the image cannot be rendered, a hyperlink will be rendered instead.
+
 
-E.g. ``/^https?:\/\/(?:www.)?(?:imgur\.com\/\w{7})\/?$/i``
+For example, to render Imgur images inline, you can use the following regex: ``/^https?:\/\/(?:www.)?(?:imgur\.com\/\w{7})\/?$/i``
 
 jid
 ---

+ 1 - 1
spec/mentions.js

@@ -1,4 +1,4 @@
-/*global mock */
+/*global mock, converse */
 
 const { Promise, Strophe, $msg, $pres } = converse.env;
 const u = converse.env.utils;

+ 4 - 9
spec/messages.js

@@ -972,22 +972,17 @@ describe("A Chat Message", function () {
         expect(view.model.sendMessage).toHaveBeenCalled();
         msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
         expect(msg.textContent.trim()).toEqual('hello world');
-        expect(msg.querySelectorAll('img').length).toEqual(2);
-
-        // @XXX This test isn't really testing anything - needs revisiting
-        // Non-https images aren't rendered
-        message = base_url+"/logo/conversejs-filled.svg";
-        expect(view.content.querySelectorAll('img').length).toBe(4);
-        mock.sendMessage(view, message);
-        expect(view.content.querySelectorAll('img').length).toBe(4);
+        expect(msg.querySelectorAll('img.chat-image').length).toEqual(2);
 
         // Configured image URLs are rendered
         _converse.api.settings.set('image_urls_regex', /^https?:\/\/(?:www.)?(?:imgur\.com\/\w{7})\/?$/i);
-        message = 'http://imgur.com/xxxxxxx';
+        message = 'https://imgur.com/oxymPax';
         mock.sendMessage(view, message);
         await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 5, 1000);
         expect(view.content.querySelectorAll('.chat-content .chat-image').length).toBe(5);
 
+        // Check that the Imgur URL gets a .png attached to make it render
+        await u.waitUntil(() => Array.from(view.el.querySelectorAll('.chat-content .chat-image')).pop().src.endsWith('png'), 1000);
         done();
     }));
 

+ 11 - 2
src/templates/directives/image.js

@@ -4,8 +4,17 @@ import { directive, html } from "lit-html";
 
 export const renderImage = directive((url, onLoad, onClick) => part => {
     function onError () {
-        part.setValue(converse.env.utils.convertUrlToHyperlink(url));
-        part.commit();
+        const u = converse.env.utils;
+        if (u.isURLWithImageExtension(url)) {
+            part.setValue(u.convertUrlToHyperlink(url));
+            part.commit();
+        } else {
+            // Before giving up and falling back to just rendering a hyperlink,
+            // we attach `.png` and try one more time.
+            // This works with some Imgur URLs
+            part.setValue(renderImage(`${url}.png`, onLoad, onClick));
+            part.commit();
+        }
     }
     part.setValue(
         html`<a href="${url}"

+ 4 - 3
src/utils/html.js

@@ -76,11 +76,12 @@ function checkFileTypes (types, url) {
 
 u.isAudioURL = url => checkFileTypes(['.ogg', '.mp3', '.m4a'], url);
 u.isVideoURL = url => checkFileTypes(['.mp4', '.webm'], url);
+
+u.isURLWithImageExtension = url => checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], url);
+
 u.isImageURL = url => {
     const regex = api.settings.get('image_urls_regex');
-    return regex
-        ? regex.test(url)
-        : checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], url);
+    return regex ? regex.test(url) : u.isURLWithImageExtension(url);
 }
 u.isImageDomainAllowed = url => {
     try {