| | @@ -630,11 +630,11 @@ |
| 630 | 630 | this.setMessage() after initialization. |
| 631 | 631 | */ |
| 632 | 632 | const cf = function(){ |
| 633 | 633 | this.e = { |
| 634 | 634 | body: D.addClass(D.div(), 'message-widget'), |
| 635 | | - tab: D.addClass(D.span(), 'message-widget-tab'), |
| 635 | + tab: D.addClass(D.div(), 'message-widget-tab'), |
| 636 | 636 | content: D.addClass(D.div(), 'message-widget-content') |
| 637 | 637 | }; |
| 638 | 638 | D.append(this.e.body, this.e.tab, this.e.content); |
| 639 | 639 | this.e.tab.setAttribute('role', 'button'); |
| 640 | 640 | if(arguments.length){ |
| | @@ -692,14 +692,14 @@ |
| 692 | 692 | D.clearElement(this.e.tab); |
| 693 | 693 | var contentTarget = this.e.content; |
| 694 | 694 | var eXFrom /* element holding xfrom name */; |
| 695 | 695 | if(m.xfrom){ |
| 696 | 696 | eXFrom = D.append(D.addClass(D.span(), 'xfrom'), m.xfrom); |
| 697 | | - D.append( |
| 698 | | - this.e.tab, eXFrom, |
| 699 | | - D.text(" #",(m.msgid||'???'),' @ ',theTime(d)) |
| 700 | | - ); |
| 697 | + const wrapper = D.append( |
| 698 | + D.span(), eXFrom, |
| 699 | + D.text(" #",(m.msgid||'???'),' @ ',theTime(d))) |
| 700 | + D.append(this.e.tab, wrapper); |
| 701 | 701 | }else{/*notification*/ |
| 702 | 702 | D.addClass(this.e.body, 'notification'); |
| 703 | 703 | if(m.isError){ |
| 704 | 704 | D.addClass([contentTarget, this.e.tab], 'error'); |
| 705 | 705 | } |
| | @@ -751,25 +751,25 @@ |
| 751 | 751 | if(F.pikchr){ |
| 752 | 752 | F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr')); |
| 753 | 753 | } |
| 754 | 754 | } |
| 755 | 755 | } |
| 756 | | - this.e.tab.addEventListener('click', this._handleLegendClicked, false); |
| 757 | | - if(eXFrom){ |
| 756 | + this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false); |
| 757 | + /*if(eXFrom){ |
| 758 | 758 | eXFrom.addEventListener('click', ()=>this.e.tab.click(), false); |
| 759 | | - } |
| 759 | + }*/ |
| 760 | 760 | return this; |
| 761 | 761 | }, |
| 762 | 762 | /* Event handler for clicking .message-user elements to show their |
| 763 | 763 | timestamps. */ |
| 764 | 764 | _handleLegendClicked: function f(ev){ |
| 765 | 765 | if(!f.popup){ |
| 766 | 766 | /* Timestamp popup widget */ |
| 767 | | - f.popup = new F.PopupWidget({ |
| 768 | | - cssClass: ['fossil-tooltip', 'chat-message-popup'], |
| 767 | + f.popup = { |
| 768 | + e: D.addClass(D.div(), 'chat-message-popup'), |
| 769 | 769 | refresh:function(){ |
| 770 | | - const eMsg = this._eMsg; |
| 770 | + const eMsg = this.$eMsg/*.message-widget element*/; |
| 771 | 771 | if(!eMsg) return; |
| 772 | 772 | D.clearElement(this.e); |
| 773 | 773 | const d = new Date(eMsg.dataset.timestamp); |
| 774 | 774 | if(d.getMinutes().toString()!=="NaN"){ |
| 775 | 775 | // Date works, render informative timestamps |
| | @@ -802,22 +802,27 @@ |
| 802 | 802 | Chat.deleteMessageElem(eMsg); |
| 803 | 803 | }); |
| 804 | 804 | if(Chat.userMayDelete(eMsg)){ |
| 805 | 805 | const btnDeleteGlobal = D.button("Delete globally"); |
| 806 | 806 | D.append(toolbar, btnDeleteGlobal); |
| 807 | | - btnDeleteGlobal.addEventListener('click', function(){ |
| 808 | | - self.hide(); |
| 809 | | - Chat.deleteMessage(eMsg); |
| 807 | + F.confirmer(btnDeleteGlobal,{ |
| 808 | + pinSize: true, |
| 809 | + ticks: F.config.confirmerButtonTicks, |
| 810 | + confirmText: "Confirm delete?", |
| 811 | + onconfirm:function(){ |
| 812 | + self.hide(); |
| 813 | + Chat.deleteMessage(eMsg); |
| 814 | + } |
| 810 | 815 | }); |
| 811 | 816 | } |
| 812 | 817 | const toolbar2 = D.addClass(D.div(), 'toolbar'); |
| 813 | 818 | D.append(this.e, toolbar2); |
| 814 | 819 | const btnToggleText = D.button("Toggle text mode"); |
| 815 | 820 | btnToggleText.addEventListener('click', function(){ |
| 816 | 821 | self.hide(); |
| 817 | 822 | Chat.toggleTextMode(eMsg); |
| 818 | | - }); |
| 823 | + },false); |
| 819 | 824 | D.append(toolbar2, btnToggleText); |
| 820 | 825 | if(eMsg.dataset.xfrom){ |
| 821 | 826 | /* Add a link to the /timeline filtered on this user. */ |
| 822 | 827 | const timelineLink = D.attr( |
| 823 | 828 | D.a(F.repoUrl('timeline',{ |
| | @@ -826,32 +831,33 @@ |
| 826 | 831 | }), "User's Timeline"), |
| 827 | 832 | 'target', '_blank' |
| 828 | 833 | ); |
| 829 | 834 | D.append(toolbar2, timelineLink); |
| 830 | 835 | } |
| 831 | | - }/*refresh()*/ |
| 832 | | - }); |
| 833 | | - f.popup.installHideHandlers(); |
| 834 | | - f.popup.hide = function(){ |
| 835 | | - delete this._eMsg; |
| 836 | | - D.clearElement(this.e); |
| 837 | | - return this.show(false); |
| 838 | | - }; |
| 836 | + const tab = eMsg.querySelector('.message-widget-tab'); |
| 837 | + D.append(tab, this.e); |
| 838 | + D.removeClass(this.e, 'hidden'); |
| 839 | + }/*refresh()*/, |
| 840 | + hide: function(){ |
| 841 | + D.addClass(D.clearElement(this.e), 'hidden'); |
| 842 | + delete this.$eMsg; |
| 843 | + }, |
| 844 | + show: function(tgtMsg){ |
| 845 | + if(tgtMsg === this.$eMsg){ |
| 846 | + this.hide(); |
| 847 | + return; |
| 848 | + } |
| 849 | + this.$eMsg = tgtMsg; |
| 850 | + this.refresh(); |
| 851 | + } |
| 852 | + }/*f.popup*/; |
| 839 | 853 | }/*end static init*/ |
| 840 | | - const rect = ev.target.getBoundingClientRect(); |
| 841 | | - const eMsg = ev.target.parentNode/*the owning .message-widget element*/; |
| 842 | | - f.popup._eMsg = eMsg; |
| 843 | | - let x = rect.left, y = rect.topm; |
| 844 | | - f.popup.show(ev.target)/*so we can get its computed size*/; |
| 845 | | - if(eMsg.dataset.xfrom===Chat.me |
| 846 | | - && document.body.classList.contains('my-messages-right')){ |
| 847 | | - // Shift popup to the left for right-aligned messages to avoid |
| 848 | | - // truncation off the right edge of the page. |
| 849 | | - const pRect = f.popup.e.getBoundingClientRect(); |
| 850 | | - x = rect.right - pRect.width; |
| 851 | | - } |
| 852 | | - f.popup.show(x, y); |
| 854 | + let theMsg = ev.target; |
| 855 | + while( theMsg && !theMsg.classList.contains('message-widget')){ |
| 856 | + theMsg = theMsg.parentNode; |
| 857 | + } |
| 858 | + if(theMsg) f.popup.show(theMsg); |
| 853 | 859 | }/*_handleLegendClicked()*/ |
| 854 | 860 | }; |
| 855 | 861 | return cf; |
| 856 | 862 | })()/*MessageWidget*/; |
| 857 | 863 | |
| | @@ -900,11 +906,11 @@ |
| 900 | 906 | const items = event.clipboardData.items, |
| 901 | 907 | item = items[0]; |
| 902 | 908 | if(!item || !item.type) return; |
| 903 | 909 | else if('file'===item.kind){ |
| 904 | 910 | updateDropZoneContent(false/*clear prev state*/); |
| 905 | | - updateDropZoneContent(items[0].getAsFile()); |
| 911 | + updateDropZoneContent(item.getAsFile()); |
| 906 | 912 | } |
| 907 | 913 | }, false); |
| 908 | 914 | /* Add help button for drag/drop/paste zone */ |
| 909 | 915 | Chat.e.inputFile.parentNode.insertBefore( |
| 910 | 916 | F.helpButtonlets.create( |
| 911 | 917 | |