Fossil SCM

Rescoped the chat timestamp popup widget into a deeper scope (less visible/leaky). Moved the duplicated click-somewhere-to-close-popup handlers into PopupWidget.installClickToHide() method.

stephan 2020-12-23 07:59 chatroom-dev
Commit 6bccbc20ea208283e55adeec8f3a07abd4d6424c41d07add6e69e5d21ecba1d4
2 files changed +26 -28 +18 -9
+26 -28
--- src/chat.js
+++ src/chat.js
@@ -69,46 +69,44 @@
6969
/* Returns an almost-ISO8601 form of Date object d. */
7070
const iso8601ish = function(d){
7171
return d.toISOString()
7272
.replace('T',' ').replace(/\.\d+/,'').replace('Z', ' GMT');
7373
};
74
- /* Timestampt popup widget */
75
- const tsPopup = new F.PopupWidget({
76
- cssClass: ['fossil-tooltip', 'chat-timestamp'],
77
- refresh:function(){
78
- const D = F.dom;
79
- D.clearElement(this.e);
80
- const d = new Date(this._timestamp+"Z");
81
- if(d.getMinutes().toString()!=="NaN"){
82
- // Date works, render informative timestamps
83
- D.append(this.e, localTimeString(d)," client-local", D.br(),
84
- iso8601ish(d));
85
- }else{
86
- // Date doesn't work, so dumb it down...
87
- D.append(this.e, this._timestamp," GMT");
88
- }
89
- }
90
- });
91
- const hidePopup = ()=>tsPopup.hide();
92
- tsPopup.e.addEventListener('click', hidePopup, false);
93
- document.body.addEventListener('click', hidePopup, true);
94
- document.body.addEventListener('keydown', function(ev){
95
- if(tsPopup.isShown() && 27===ev.which) tsPopup.hide();
96
- }, true);
9774
/* Event handler for clicking .message-user elements to show their
9875
timestamps. */
99
- const handleLegendClicked = function(ev){
76
+ const handleLegendClicked = function f(ev){
77
+ if(!f.popup){
78
+ /* Timestamp popup widget */
79
+ f.popup = new F.PopupWidget({
80
+ cssClass: ['fossil-tooltip', 'chat-timestamp'],
81
+ refresh:function(){
82
+ const D = F.dom;
83
+ D.clearElement(this.e);
84
+ const d = new Date(this._timestamp+"Z");
85
+ if(d.getMinutes().toString()!=="NaN"){
86
+ // Date works, render informative timestamps
87
+ D.append(this.e, localTimeString(d)," client-local", D.br(),
88
+ iso8601ish(d));
89
+ }else{
90
+ // Date doesn't work, so dumb it down...
91
+ D.append(this.e, this._timestamp," GMT");
92
+ }
93
+ }
94
+ });
95
+ const hidePopup = ()=>f.popup.hide();
96
+ f.popup.installClickToHide();
97
+ }
10098
const rect = ev.target.getBoundingClientRect();
101
- tsPopup._timestamp = ev.target.dataset.timestamp;
99
+ f.popup._timestamp = ev.target.dataset.timestamp;
102100
let x = rect.left, y = rect.top - 10;
103
- tsPopup.show(ev.target)/*so we can get its computed size*/;
101
+ f.popup.show(ev.target)/*so we can get its computed size*/;
104102
// Shift to the left for right-aligned messages
105103
if('right'===ev.target.getAttribute('align')){
106
- const pRect = tsPopup.e.getBoundingClientRect();
104
+ const pRect = f.popup.e.getBoundingClientRect();
107105
x -= pRect.width/3*2;
108106
}
109
- tsPopup.show(x, y);
107
+ f.popup.show(x, y);
110108
};
111109
112110
function newcontent(jx){
113111
var i;
114112
for(i=0; i<jx.msgs.length; ++i){
115113
--- src/chat.js
+++ src/chat.js
@@ -69,46 +69,44 @@
69 /* Returns an almost-ISO8601 form of Date object d. */
70 const iso8601ish = function(d){
71 return d.toISOString()
72 .replace('T',' ').replace(/\.\d+/,'').replace('Z', ' GMT');
73 };
74 /* Timestampt popup widget */
75 const tsPopup = new F.PopupWidget({
76 cssClass: ['fossil-tooltip', 'chat-timestamp'],
77 refresh:function(){
78 const D = F.dom;
79 D.clearElement(this.e);
80 const d = new Date(this._timestamp+"Z");
81 if(d.getMinutes().toString()!=="NaN"){
82 // Date works, render informative timestamps
83 D.append(this.e, localTimeString(d)," client-local", D.br(),
84 iso8601ish(d));
85 }else{
86 // Date doesn't work, so dumb it down...
87 D.append(this.e, this._timestamp," GMT");
88 }
89 }
90 });
91 const hidePopup = ()=>tsPopup.hide();
92 tsPopup.e.addEventListener('click', hidePopup, false);
93 document.body.addEventListener('click', hidePopup, true);
94 document.body.addEventListener('keydown', function(ev){
95 if(tsPopup.isShown() && 27===ev.which) tsPopup.hide();
96 }, true);
97 /* Event handler for clicking .message-user elements to show their
98 timestamps. */
99 const handleLegendClicked = function(ev){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100 const rect = ev.target.getBoundingClientRect();
101 tsPopup._timestamp = ev.target.dataset.timestamp;
102 let x = rect.left, y = rect.top - 10;
103 tsPopup.show(ev.target)/*so we can get its computed size*/;
104 // Shift to the left for right-aligned messages
105 if('right'===ev.target.getAttribute('align')){
106 const pRect = tsPopup.e.getBoundingClientRect();
107 x -= pRect.width/3*2;
108 }
109 tsPopup.show(x, y);
110 };
111
112 function newcontent(jx){
113 var i;
114 for(i=0; i<jx.msgs.length; ++i){
115
--- src/chat.js
+++ src/chat.js
@@ -69,46 +69,44 @@
69 /* Returns an almost-ISO8601 form of Date object d. */
70 const iso8601ish = function(d){
71 return d.toISOString()
72 .replace('T',' ').replace(/\.\d+/,'').replace('Z', ' GMT');
73 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74 /* Event handler for clicking .message-user elements to show their
75 timestamps. */
76 const handleLegendClicked = function f(ev){
77 if(!f.popup){
78 /* Timestamp popup widget */
79 f.popup = new F.PopupWidget({
80 cssClass: ['fossil-tooltip', 'chat-timestamp'],
81 refresh:function(){
82 const D = F.dom;
83 D.clearElement(this.e);
84 const d = new Date(this._timestamp+"Z");
85 if(d.getMinutes().toString()!=="NaN"){
86 // Date works, render informative timestamps
87 D.append(this.e, localTimeString(d)," client-local", D.br(),
88 iso8601ish(d));
89 }else{
90 // Date doesn't work, so dumb it down...
91 D.append(this.e, this._timestamp," GMT");
92 }
93 }
94 });
95 const hidePopup = ()=>f.popup.hide();
96 f.popup.installClickToHide();
97 }
98 const rect = ev.target.getBoundingClientRect();
99 f.popup._timestamp = ev.target.dataset.timestamp;
100 let x = rect.left, y = rect.top - 10;
101 f.popup.show(ev.target)/*so we can get its computed size*/;
102 // Shift to the left for right-aligned messages
103 if('right'===ev.target.getAttribute('align')){
104 const pRect = f.popup.e.getBoundingClientRect();
105 x -= pRect.width/3*2;
106 }
107 f.popup.show(x, y);
108 };
109
110 function newcontent(jx){
111 var i;
112 for(i=0; i<jx.msgs.length; ++i){
113
--- src/fossil.popupwidget.js
+++ src/fossil.popupwidget.js
@@ -182,11 +182,27 @@
182182
this.e.style.removeProperty('top');
183183
}
184184
return this;
185185
},
186186
187
- hide: function(){return this.show(false)}
187
+ hide: function(){return this.show(false)},
188
+
189
+ /**
190
+ A convenience method which adds click handlers to this popup's
191
+ main element and document.body to hide the popup when either
192
+ element is clicked or the ESC key is pressed. Only call this
193
+ once per instance, if at all. Returns this;
194
+ */
195
+ installClickToHide: function f(){
196
+ this.e.addEventListener('click', ()=>this.show(false), false);
197
+ document.body.addEventListener('click', ()=>this.show(false), true);
198
+ const self = this;
199
+ document.body.addEventListener('keydown', function(ev){
200
+ if(self.isShown() && 27===ev.which) self.show(false);
201
+ }, true);
202
+ return this;
203
+ }
188204
}/*F.PopupWidget.prototype*/;
189205
190206
/**
191207
Internal impl for F.toast() and friends.
192208
@@ -297,18 +313,11 @@
297313
cssClass: ['fossil-tooltip', 'help-buttonlet-content'],
298314
refresh: function(){
299315
}
300316
});
301317
fch.popup.e.style.maxWidth = '80%'/*of body*/;
302
- const hide = ()=>fch.popup.hide();
303
- fch.popup.e.addEventListener('click', hide, false);
304
- document.body.addEventListener('click', hide, true);
305
- document.body.addEventListener('keydown', function(ev){
306
- if(fch.popup.isShown() && 27===ev.which){
307
- fch.popup.hide();
308
- }
309
- }, true);
318
+ fch.popup.installClickToHide();
310319
}
311320
D.append(D.clearElement(fch.popup.e), ev.target.$helpContent);
312321
var popupRect = ev.target.getClientRects()[0];
313322
var x = popupRect.left, y = popupRect.top;
314323
if(x<0) x = 0;
315324
--- src/fossil.popupwidget.js
+++ src/fossil.popupwidget.js
@@ -182,11 +182,27 @@
182 this.e.style.removeProperty('top');
183 }
184 return this;
185 },
186
187 hide: function(){return this.show(false)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188 }/*F.PopupWidget.prototype*/;
189
190 /**
191 Internal impl for F.toast() and friends.
192
@@ -297,18 +313,11 @@
297 cssClass: ['fossil-tooltip', 'help-buttonlet-content'],
298 refresh: function(){
299 }
300 });
301 fch.popup.e.style.maxWidth = '80%'/*of body*/;
302 const hide = ()=>fch.popup.hide();
303 fch.popup.e.addEventListener('click', hide, false);
304 document.body.addEventListener('click', hide, true);
305 document.body.addEventListener('keydown', function(ev){
306 if(fch.popup.isShown() && 27===ev.which){
307 fch.popup.hide();
308 }
309 }, true);
310 }
311 D.append(D.clearElement(fch.popup.e), ev.target.$helpContent);
312 var popupRect = ev.target.getClientRects()[0];
313 var x = popupRect.left, y = popupRect.top;
314 if(x<0) x = 0;
315
--- src/fossil.popupwidget.js
+++ src/fossil.popupwidget.js
@@ -182,11 +182,27 @@
182 this.e.style.removeProperty('top');
183 }
184 return this;
185 },
186
187 hide: function(){return this.show(false)},
188
189 /**
190 A convenience method which adds click handlers to this popup's
191 main element and document.body to hide the popup when either
192 element is clicked or the ESC key is pressed. Only call this
193 once per instance, if at all. Returns this;
194 */
195 installClickToHide: function f(){
196 this.e.addEventListener('click', ()=>this.show(false), false);
197 document.body.addEventListener('click', ()=>this.show(false), true);
198 const self = this;
199 document.body.addEventListener('keydown', function(ev){
200 if(self.isShown() && 27===ev.which) self.show(false);
201 }, true);
202 return this;
203 }
204 }/*F.PopupWidget.prototype*/;
205
206 /**
207 Internal impl for F.toast() and friends.
208
@@ -297,18 +313,11 @@
313 cssClass: ['fossil-tooltip', 'help-buttonlet-content'],
314 refresh: function(){
315 }
316 });
317 fch.popup.e.style.maxWidth = '80%'/*of body*/;
318 fch.popup.installClickToHide();
 
 
 
 
 
 
 
319 }
320 D.append(D.clearElement(fch.popup.e), ev.target.$helpContent);
321 var popupRect = ev.target.getClientRects()[0];
322 var x = popupRect.left, y = popupRect.top;
323 if(x<0) x = 0;
324

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button