Fossil SCM

Added fossil.confirmer pinSize option which tells it to try to pin the confirmation element's width to the maximum of its initial and awaiting-confirmation widths, to avoid layout reflow while awaiting confirmation.

stephan 2020-08-11 15:23 trunk
Commit b12cae857cdadbd75b7946f35514c3587b3b9d08202d90e4966d053447a11a87
1 file changed +32 -4
--- src/fossil.confirmer.js
+++ src/fossil.confirmer.js
@@ -81,10 +81,21 @@
8181
action has been confirmed, immediately before the onconfirm or
8282
ontimeout callback. The intention of the callback is to update the
8383
label of the target element. If .ticks is set but .ontick is not
8484
then a default implementation is used which updates the element with
8585
the .confirmText, prepending a countdown to it.
86
+
87
+ .pinSize = if true AND confirmText is set, calculate the larger of
88
+ the element's original and confirmed size and pin it to the larger
89
+ of those sizes to avoid layout reflows when confirmation is
90
+ running. The pinning is implemented by setting its minWidth and
91
+ maxWidth style properties to the same value. This does not work if
92
+ the element text is updated dynamically via ontick(). This ONLY
93
+ works if the element is in the DOM and is not hidden (e.g. via
94
+ display:none) at the time this routine is called, otherwise we
95
+ cannot calculate its size. If the element needs to be hidden, hide
96
+ it after initializing the confirmer.
8697
8798
.debug = boolean. If truthy, it sends some debug output to the dev
8899
console to track what it's doing.
89100
90101
Various notes:
@@ -99,17 +110,26 @@
99110
- Due to the nature of multi-threaded code, it is potentially possible
100111
that confirmation and timeout actions BOTH happen if the user
101112
triggers the associated action at "just the right millisecond"
102113
before the timeout is triggered.
103114
104
-TODO: add an invert option which activates if the timeout is reached
105
-and "times out" if the element is clicked again. e.g. a button which
106
-says "Saving..." and cancels the op if it's clicked again, else it
107
-saves after X time/ticks.
115
+TODO:
116
+
117
+- Add an invert option which activates if the timeout is reached and
118
+"times out" if the element is clicked again. e.g. a button which says
119
+"Saving..." and cancels the op if it's clicked again, else it saves
120
+after X time/ticks.
121
+
122
+- Internally we save/restore the initial text of non-INPUT elements
123
+using innerHTML. We should instead move their child nodes aside (into
124
+an internal out-of-DOM element) and restore them as needed.
108125
109126
Terse Change history:
110127
128
+- 20200811
129
+ - Added pinSize option.
130
+
111131
- 20200507:
112132
- Add a tick-based countdown in order to more easily support
113133
updating the target element with the countdown.
114134
115135
- 20200506:
@@ -138,10 +158,18 @@
138158
const isInput = f.isInput(target);
139159
const updateText = function(msg){
140160
if(isInput) target.value = msg;
141161
else target.innerHTML = msg;
142162
}
163
+ if(opt.pinSize && opt.confirmText){
164
+ const digits = (''+(opt.timeout/1000 || opt.ticks)).length;
165
+ const lblLong = "("+("00000000".substr(0,digits))+") "+opt.confirmText;
166
+ const w1 = parseFloat(window.getComputedStyle(target).width);
167
+ updateText(lblLong);
168
+ const w2 = parseFloat(window.getComputedStyle(target).width);
169
+ target.style.minWidth = target.style.maxWidth = (w1>w2 ? w1 : w2)+"px";
170
+ }
143171
updateText(this.opt.initialText);
144172
if(this.opt.ticks && !this.opt.ontick){
145173
this.opt.ontick = function(tick){
146174
updateText("("+tick+") "+self.opt.confirmText);
147175
};
148176
--- src/fossil.confirmer.js
+++ src/fossil.confirmer.js
@@ -81,10 +81,21 @@
81 action has been confirmed, immediately before the onconfirm or
82 ontimeout callback. The intention of the callback is to update the
83 label of the target element. If .ticks is set but .ontick is not
84 then a default implementation is used which updates the element with
85 the .confirmText, prepending a countdown to it.
 
 
 
 
 
 
 
 
 
 
 
86
87 .debug = boolean. If truthy, it sends some debug output to the dev
88 console to track what it's doing.
89
90 Various notes:
@@ -99,17 +110,26 @@
99 - Due to the nature of multi-threaded code, it is potentially possible
100 that confirmation and timeout actions BOTH happen if the user
101 triggers the associated action at "just the right millisecond"
102 before the timeout is triggered.
103
104 TODO: add an invert option which activates if the timeout is reached
105 and "times out" if the element is clicked again. e.g. a button which
106 says "Saving..." and cancels the op if it's clicked again, else it
107 saves after X time/ticks.
 
 
 
 
 
 
108
109 Terse Change history:
110
 
 
 
111 - 20200507:
112 - Add a tick-based countdown in order to more easily support
113 updating the target element with the countdown.
114
115 - 20200506:
@@ -138,10 +158,18 @@
138 const isInput = f.isInput(target);
139 const updateText = function(msg){
140 if(isInput) target.value = msg;
141 else target.innerHTML = msg;
142 }
 
 
 
 
 
 
 
 
143 updateText(this.opt.initialText);
144 if(this.opt.ticks && !this.opt.ontick){
145 this.opt.ontick = function(tick){
146 updateText("("+tick+") "+self.opt.confirmText);
147 };
148
--- src/fossil.confirmer.js
+++ src/fossil.confirmer.js
@@ -81,10 +81,21 @@
81 action has been confirmed, immediately before the onconfirm or
82 ontimeout callback. The intention of the callback is to update the
83 label of the target element. If .ticks is set but .ontick is not
84 then a default implementation is used which updates the element with
85 the .confirmText, prepending a countdown to it.
86
87 .pinSize = if true AND confirmText is set, calculate the larger of
88 the element's original and confirmed size and pin it to the larger
89 of those sizes to avoid layout reflows when confirmation is
90 running. The pinning is implemented by setting its minWidth and
91 maxWidth style properties to the same value. This does not work if
92 the element text is updated dynamically via ontick(). This ONLY
93 works if the element is in the DOM and is not hidden (e.g. via
94 display:none) at the time this routine is called, otherwise we
95 cannot calculate its size. If the element needs to be hidden, hide
96 it after initializing the confirmer.
97
98 .debug = boolean. If truthy, it sends some debug output to the dev
99 console to track what it's doing.
100
101 Various notes:
@@ -99,17 +110,26 @@
110 - Due to the nature of multi-threaded code, it is potentially possible
111 that confirmation and timeout actions BOTH happen if the user
112 triggers the associated action at "just the right millisecond"
113 before the timeout is triggered.
114
115 TODO:
116
117 - Add an invert option which activates if the timeout is reached and
118 "times out" if the element is clicked again. e.g. a button which says
119 "Saving..." and cancels the op if it's clicked again, else it saves
120 after X time/ticks.
121
122 - Internally we save/restore the initial text of non-INPUT elements
123 using innerHTML. We should instead move their child nodes aside (into
124 an internal out-of-DOM element) and restore them as needed.
125
126 Terse Change history:
127
128 - 20200811
129 - Added pinSize option.
130
131 - 20200507:
132 - Add a tick-based countdown in order to more easily support
133 updating the target element with the countdown.
134
135 - 20200506:
@@ -138,10 +158,18 @@
158 const isInput = f.isInput(target);
159 const updateText = function(msg){
160 if(isInput) target.value = msg;
161 else target.innerHTML = msg;
162 }
163 if(opt.pinSize && opt.confirmText){
164 const digits = (''+(opt.timeout/1000 || opt.ticks)).length;
165 const lblLong = "("+("00000000".substr(0,digits))+") "+opt.confirmText;
166 const w1 = parseFloat(window.getComputedStyle(target).width);
167 updateText(lblLong);
168 const w2 = parseFloat(window.getComputedStyle(target).width);
169 target.style.minWidth = target.style.maxWidth = (w1>w2 ? w1 : w2)+"px";
170 }
171 updateText(this.opt.initialText);
172 if(this.opt.ticks && !this.opt.ontick){
173 this.opt.ontick = function(tick){
174 updateText("("+tick+") "+self.opt.confirmText);
175 };
176

Keyboard Shortcuts

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