Fossil SCM
/chat: experimentally add an Embed button to HTML attachments which embeds their contents in an iframe.
Commit
d9e3ed5e209cccf6df2c5e1c24ea205648ec92ce3935f17ccb4042367c9eb969
Parent
90b8921b6c7b584…
2 files changed
+24
-4
+20
-1
+24
-4
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -936,18 +936,38 @@ | ||
| 936 | 936 | && Chat.settings.getBool('images-inline',true) |
| 937 | 937 | ){ |
| 938 | 938 | contentTarget.appendChild(D.img("chat-download/" + m.msgid)); |
| 939 | 939 | ds.hasImage = 1; |
| 940 | 940 | }else{ |
| 941 | - const a = D.a( | |
| 942 | - window.fossil.rootPath+ | |
| 943 | - 'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname), | |
| 941 | + // Add a download link. | |
| 942 | + const downloadUri = window.fossil.rootPath+ | |
| 943 | + 'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname); | |
| 944 | + const w = D.addClass(D.div(), 'attachment-link'); | |
| 945 | + const a = D.a(downloadUri, | |
| 944 | 946 | // ^^^ add m.fname to URL to cause downloaded file to have that name. |
| 945 | 947 | "(" + m.fname + " " + m.fsize + " bytes)" |
| 946 | 948 | ) |
| 947 | 949 | D.attr(a,'target','_blank'); |
| 948 | - contentTarget.appendChild(a); | |
| 950 | + D.append(w, a); | |
| 951 | + if(/\.html$/i.test(m.fname)){ | |
| 952 | + /* Add an option to embed HTML attachments in an iframe. The primary | |
| 953 | + use case is attached diffs. */ | |
| 954 | + D.addClass(contentTarget, 'wide'); | |
| 955 | + const embedTarget = this.e.content; | |
| 956 | + const btnEmbed = D.button("Embed", function(){ | |
| 957 | + D.remove(btnEmbed); | |
| 958 | + const iframe = document.createElement('iframe'); | |
| 959 | + D.append(embedTarget, iframe); | |
| 960 | + iframe.addEventListener('load', function(){ | |
| 961 | + iframe.style.maxHeight = iframe.style.height | |
| 962 | + = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; | |
| 963 | + }); | |
| 964 | + iframe.setAttribute('src', downloadUri); | |
| 965 | + }); | |
| 966 | + D.append(w, btnEmbed); | |
| 967 | + } | |
| 968 | + contentTarget.appendChild(w); | |
| 949 | 969 | } |
| 950 | 970 | } |
| 951 | 971 | if(m.xmsg){ |
| 952 | 972 | if(m.fsize>0){ |
| 953 | 973 | /* We have file/image content, so need another element for |
| 954 | 974 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -936,18 +936,38 @@ | |
| 936 | && Chat.settings.getBool('images-inline',true) |
| 937 | ){ |
| 938 | contentTarget.appendChild(D.img("chat-download/" + m.msgid)); |
| 939 | ds.hasImage = 1; |
| 940 | }else{ |
| 941 | const a = D.a( |
| 942 | window.fossil.rootPath+ |
| 943 | 'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname), |
| 944 | // ^^^ add m.fname to URL to cause downloaded file to have that name. |
| 945 | "(" + m.fname + " " + m.fsize + " bytes)" |
| 946 | ) |
| 947 | D.attr(a,'target','_blank'); |
| 948 | contentTarget.appendChild(a); |
| 949 | } |
| 950 | } |
| 951 | if(m.xmsg){ |
| 952 | if(m.fsize>0){ |
| 953 | /* We have file/image content, so need another element for |
| 954 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -936,18 +936,38 @@ | |
| 936 | && Chat.settings.getBool('images-inline',true) |
| 937 | ){ |
| 938 | contentTarget.appendChild(D.img("chat-download/" + m.msgid)); |
| 939 | ds.hasImage = 1; |
| 940 | }else{ |
| 941 | // Add a download link. |
| 942 | const downloadUri = window.fossil.rootPath+ |
| 943 | 'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname); |
| 944 | const w = D.addClass(D.div(), 'attachment-link'); |
| 945 | const a = D.a(downloadUri, |
| 946 | // ^^^ add m.fname to URL to cause downloaded file to have that name. |
| 947 | "(" + m.fname + " " + m.fsize + " bytes)" |
| 948 | ) |
| 949 | D.attr(a,'target','_blank'); |
| 950 | D.append(w, a); |
| 951 | if(/\.html$/i.test(m.fname)){ |
| 952 | /* Add an option to embed HTML attachments in an iframe. The primary |
| 953 | use case is attached diffs. */ |
| 954 | D.addClass(contentTarget, 'wide'); |
| 955 | const embedTarget = this.e.content; |
| 956 | const btnEmbed = D.button("Embed", function(){ |
| 957 | D.remove(btnEmbed); |
| 958 | const iframe = document.createElement('iframe'); |
| 959 | D.append(embedTarget, iframe); |
| 960 | iframe.addEventListener('load', function(){ |
| 961 | iframe.style.maxHeight = iframe.style.height |
| 962 | = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; |
| 963 | }); |
| 964 | iframe.setAttribute('src', downloadUri); |
| 965 | }); |
| 966 | D.append(w, btnEmbed); |
| 967 | } |
| 968 | contentTarget.appendChild(w); |
| 969 | } |
| 970 | } |
| 971 | if(m.xmsg){ |
| 972 | if(m.fsize>0){ |
| 973 | /* We have file/image content, so need another element for |
| 974 |
+20
-1
| --- src/style.chat.css | ||
| +++ src/style.chat.css | ||
| @@ -29,19 +29,38 @@ | ||
| 29 | 29 | /* Center-aligns a system-level notification message. */ |
| 30 | 30 | align-items: center; |
| 31 | 31 | } |
| 32 | 32 | /* The content area of a message. */ |
| 33 | 33 | body.chat .message-widget-content { |
| 34 | - display: inline-block; | |
| 34 | + display: flex; | |
| 35 | + flex-direction: column; | |
| 35 | 36 | border-radius: 0.25em; |
| 36 | 37 | border: 1px solid rgba(0,0,0,0.2); |
| 37 | 38 | box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29); |
| 38 | 39 | padding: 0.25em 0.5em; |
| 39 | 40 | margin-top: 0; |
| 40 | 41 | min-width: 9em /*avoid unsightly "underlap" with the neighboring |
| 41 | 42 | .message-widget-tab element*/; |
| 42 | 43 | white-space: normal; |
| 44 | +} | |
| 45 | +body.chat .message-widget-content.wide { | |
| 46 | + /* Special case for when embedding content which we really want to | |
| 47 | + expand, namely iframes. */ | |
| 48 | + width: 98%; | |
| 49 | +} | |
| 50 | +body.chat .message-widget-content > .attachment-link > a { | |
| 51 | + margin-right: 1em; | |
| 52 | +} | |
| 53 | +body.chat .message-widget-content > iframe { | |
| 54 | + width: 100%; | |
| 55 | + max-width: 100%; | |
| 56 | + resize: both; | |
| 57 | +} | |
| 58 | +body.chat .message-widget-content> a { | |
| 59 | + /* Cosmetic: keep skin-induced on-hover underlining from shifting | |
| 60 | + content placed below this. */ | |
| 61 | + border-bottom: 1px transparent; | |
| 43 | 62 | } |
| 44 | 63 | body.chat.monospace-messages .message-widget-content, |
| 45 | 64 | body.chat.monospace-messages .chat-input-field{ |
| 46 | 65 | font-family: monospace; |
| 47 | 66 | } |
| 48 | 67 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -29,19 +29,38 @@ | |
| 29 | /* Center-aligns a system-level notification message. */ |
| 30 | align-items: center; |
| 31 | } |
| 32 | /* The content area of a message. */ |
| 33 | body.chat .message-widget-content { |
| 34 | display: inline-block; |
| 35 | border-radius: 0.25em; |
| 36 | border: 1px solid rgba(0,0,0,0.2); |
| 37 | box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29); |
| 38 | padding: 0.25em 0.5em; |
| 39 | margin-top: 0; |
| 40 | min-width: 9em /*avoid unsightly "underlap" with the neighboring |
| 41 | .message-widget-tab element*/; |
| 42 | white-space: normal; |
| 43 | } |
| 44 | body.chat.monospace-messages .message-widget-content, |
| 45 | body.chat.monospace-messages .chat-input-field{ |
| 46 | font-family: monospace; |
| 47 | } |
| 48 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -29,19 +29,38 @@ | |
| 29 | /* Center-aligns a system-level notification message. */ |
| 30 | align-items: center; |
| 31 | } |
| 32 | /* The content area of a message. */ |
| 33 | body.chat .message-widget-content { |
| 34 | display: flex; |
| 35 | flex-direction: column; |
| 36 | border-radius: 0.25em; |
| 37 | border: 1px solid rgba(0,0,0,0.2); |
| 38 | box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29); |
| 39 | padding: 0.25em 0.5em; |
| 40 | margin-top: 0; |
| 41 | min-width: 9em /*avoid unsightly "underlap" with the neighboring |
| 42 | .message-widget-tab element*/; |
| 43 | white-space: normal; |
| 44 | } |
| 45 | body.chat .message-widget-content.wide { |
| 46 | /* Special case for when embedding content which we really want to |
| 47 | expand, namely iframes. */ |
| 48 | width: 98%; |
| 49 | } |
| 50 | body.chat .message-widget-content > .attachment-link > a { |
| 51 | margin-right: 1em; |
| 52 | } |
| 53 | body.chat .message-widget-content > iframe { |
| 54 | width: 100%; |
| 55 | max-width: 100%; |
| 56 | resize: both; |
| 57 | } |
| 58 | body.chat .message-widget-content> a { |
| 59 | /* Cosmetic: keep skin-induced on-hover underlining from shifting |
| 60 | content placed below this. */ |
| 61 | border-bottom: 1px transparent; |
| 62 | } |
| 63 | body.chat.monospace-messages .message-widget-content, |
| 64 | body.chat.monospace-messages .chat-input-field{ |
| 65 | font-family: monospace; |
| 66 | } |
| 67 |