Fossil SCM
/chat: change the Embed button to a toggle checkbox to show/hide the embedded iframe.
Commit
956515f67734b42c4889d9e17e1cbfd504643e0db8fb4b9bcd74f0d018591b2b
Parent
41767a2e5f08198…
2 files changed
+23
-6
+4
+23
-6
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -890,10 +890,17 @@ | ||
| 890 | 890 | d.getHours(),":", |
| 891 | 891 | (d.getMinutes()+100).toString().slice(1,3), |
| 892 | 892 | ' ', dowMap[d.getDay()] |
| 893 | 893 | ].join(''); |
| 894 | 894 | }; |
| 895 | + | |
| 896 | + const canEmbedFile = function f(filename){ | |
| 897 | + if(!f.$rx){ | |
| 898 | + f.$rx = /\.html$/i; | |
| 899 | + } | |
| 900 | + return f.$rx.test(filename); | |
| 901 | + }; | |
| 895 | 902 | |
| 896 | 903 | cf.prototype = { |
| 897 | 904 | scrollIntoView: function(){ |
| 898 | 905 | this.e.content.scrollIntoView(); |
| 899 | 906 | }, |
| @@ -946,26 +953,36 @@ | ||
| 946 | 953 | // ^^^ add m.fname to URL to cause downloaded file to have that name. |
| 947 | 954 | "(" + m.fname + " " + m.fsize + " bytes)" |
| 948 | 955 | ) |
| 949 | 956 | D.attr(a,'target','_blank'); |
| 950 | 957 | D.append(w, a); |
| 951 | - if(/\.html$/i.test(m.fname)){ | |
| 958 | + if(canEmbedFile(m.fname)){ | |
| 952 | 959 | /* Add an option to embed HTML attachments in an iframe. The primary |
| 953 | 960 | use case is attached diffs. */ |
| 954 | 961 | D.addClass(contentTarget, 'wide'); |
| 955 | 962 | 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); | |
| 963 | + const self = this; | |
| 964 | + const btnEmbed = D.attr(D.checkbox("1", false), 'id', | |
| 965 | + 'embed-'+ds.msgid); | |
| 966 | + const btnLabel = D.label(btnEmbed, "Toggle embedded"); | |
| 967 | + btnEmbed.addEventListener('change',function(){ | |
| 968 | + if(self.e.iframe){ | |
| 969 | + if(btnEmbed.checked) D.removeClass(self.e.iframe, 'hidden'); | |
| 970 | + else D.addClass(self.e.iframe, 'hidden'); | |
| 971 | + return; | |
| 972 | + } | |
| 973 | + D.disable(btnEmbed); | |
| 974 | + const iframe = self.e.iframe = document.createElement('iframe'); | |
| 975 | + D.append(embedTarget, iframe); | |
| 960 | 976 | iframe.addEventListener('load', function(){ |
| 977 | + D.enable(btnEmbed); | |
| 961 | 978 | iframe.style.maxHeight = iframe.style.height |
| 962 | 979 | = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; |
| 963 | 980 | }); |
| 964 | 981 | iframe.setAttribute('src', downloadUri); |
| 965 | 982 | }); |
| 966 | - D.append(w, btnEmbed); | |
| 983 | + D.append(w, btnEmbed, btnLabel); | |
| 967 | 984 | } |
| 968 | 985 | contentTarget.appendChild(w); |
| 969 | 986 | } |
| 970 | 987 | } |
| 971 | 988 | if(m.xmsg){ |
| 972 | 989 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -890,10 +890,17 @@ | |
| 890 | d.getHours(),":", |
| 891 | (d.getMinutes()+100).toString().slice(1,3), |
| 892 | ' ', dowMap[d.getDay()] |
| 893 | ].join(''); |
| 894 | }; |
| 895 | |
| 896 | cf.prototype = { |
| 897 | scrollIntoView: function(){ |
| 898 | this.e.content.scrollIntoView(); |
| 899 | }, |
| @@ -946,26 +953,36 @@ | |
| 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 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -890,10 +890,17 @@ | |
| 890 | d.getHours(),":", |
| 891 | (d.getMinutes()+100).toString().slice(1,3), |
| 892 | ' ', dowMap[d.getDay()] |
| 893 | ].join(''); |
| 894 | }; |
| 895 | |
| 896 | const canEmbedFile = function f(filename){ |
| 897 | if(!f.$rx){ |
| 898 | f.$rx = /\.html$/i; |
| 899 | } |
| 900 | return f.$rx.test(filename); |
| 901 | }; |
| 902 | |
| 903 | cf.prototype = { |
| 904 | scrollIntoView: function(){ |
| 905 | this.e.content.scrollIntoView(); |
| 906 | }, |
| @@ -946,26 +953,36 @@ | |
| 953 | // ^^^ add m.fname to URL to cause downloaded file to have that name. |
| 954 | "(" + m.fname + " " + m.fsize + " bytes)" |
| 955 | ) |
| 956 | D.attr(a,'target','_blank'); |
| 957 | D.append(w, a); |
| 958 | if(canEmbedFile(m.fname)){ |
| 959 | /* Add an option to embed HTML attachments in an iframe. The primary |
| 960 | use case is attached diffs. */ |
| 961 | D.addClass(contentTarget, 'wide'); |
| 962 | const embedTarget = this.e.content; |
| 963 | const self = this; |
| 964 | const btnEmbed = D.attr(D.checkbox("1", false), 'id', |
| 965 | 'embed-'+ds.msgid); |
| 966 | const btnLabel = D.label(btnEmbed, "Toggle embedded"); |
| 967 | btnEmbed.addEventListener('change',function(){ |
| 968 | if(self.e.iframe){ |
| 969 | if(btnEmbed.checked) D.removeClass(self.e.iframe, 'hidden'); |
| 970 | else D.addClass(self.e.iframe, 'hidden'); |
| 971 | return; |
| 972 | } |
| 973 | D.disable(btnEmbed); |
| 974 | const iframe = self.e.iframe = document.createElement('iframe'); |
| 975 | D.append(embedTarget, iframe); |
| 976 | iframe.addEventListener('load', function(){ |
| 977 | D.enable(btnEmbed); |
| 978 | iframe.style.maxHeight = iframe.style.height |
| 979 | = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; |
| 980 | }); |
| 981 | iframe.setAttribute('src', downloadUri); |
| 982 | }); |
| 983 | D.append(w, btnEmbed, btnLabel); |
| 984 | } |
| 985 | contentTarget.appendChild(w); |
| 986 | } |
| 987 | } |
| 988 | if(m.xmsg){ |
| 989 |
+4
| --- src/style.chat.css | ||
| +++ src/style.chat.css | ||
| @@ -44,10 +44,14 @@ | ||
| 44 | 44 | } |
| 45 | 45 | body.chat .message-widget-content.wide { |
| 46 | 46 | /* Special case for when embedding content which we really want to |
| 47 | 47 | expand, namely iframes. */ |
| 48 | 48 | width: 98%; |
| 49 | +} | |
| 50 | +body.chat .message-widget-content > .attachment-link { | |
| 51 | + display: flex; | |
| 52 | + flex-direction: row; | |
| 49 | 53 | } |
| 50 | 54 | body.chat .message-widget-content > .attachment-link > a { |
| 51 | 55 | margin-right: 1em; |
| 52 | 56 | } |
| 53 | 57 | body.chat .message-widget-content > iframe { |
| 54 | 58 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -44,10 +44,14 @@ | |
| 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 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -44,10 +44,14 @@ | |
| 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 { |
| 51 | display: flex; |
| 52 | flex-direction: row; |
| 53 | } |
| 54 | body.chat .message-widget-content > .attachment-link > a { |
| 55 | margin-right: 1em; |
| 56 | } |
| 57 | body.chat .message-widget-content > iframe { |
| 58 |