@yuneta/gobj-ui 5.9.0 → 5.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/yui_clipboard.js +67 -1
- package/src/yui_clipboard.test.js +72 -0
package/package.json
CHANGED
package/src/yui_clipboard.js
CHANGED
|
@@ -140,4 +140,70 @@ function yui_copy_table_json(tabulator)
|
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
/***************************************************************
|
|
144
|
+
* Show a button as "done": swap its icon for a check and
|
|
145
|
+
* its label for the given text. Idempotent — calling it
|
|
146
|
+
* twice does not lose the original.
|
|
147
|
+
*
|
|
148
|
+
* The TIMING is not here on purpose. A view arms its own
|
|
149
|
+
* C_TIMER and calls yui_button_unmark() from the timeout
|
|
150
|
+
* action, so going back is an FSM transition and shows up
|
|
151
|
+
* in the machine trace, instead of a setTimeout nobody can
|
|
152
|
+
* see. gobj-ui owns the look; the view owns the when.
|
|
153
|
+
*
|
|
154
|
+
* Expects the Bulma button shape both views use:
|
|
155
|
+
* <button><span class="icon"><span class="yi-…">
|
|
156
|
+
* <span>label</span></button>
|
|
157
|
+
* The label is optional (icon-only buttons on a phone).
|
|
158
|
+
***************************************************************/
|
|
159
|
+
function yui_button_mark_done($button, label)
|
|
160
|
+
{
|
|
161
|
+
if(!$button) {
|
|
162
|
+
log_error("yui_button_mark_done(): no button");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let $icon = $button.querySelector("span.icon > span");
|
|
167
|
+
let $label = $button.querySelector("span.icon ~ span");
|
|
168
|
+
|
|
169
|
+
if($icon && $button.dataset.yuiIconWas === undefined) {
|
|
170
|
+
$button.dataset.yuiIconWas = $icon.className;
|
|
171
|
+
$icon.className = "yi-check";
|
|
172
|
+
}
|
|
173
|
+
if($label && $button.dataset.yuiLabelWas === undefined) {
|
|
174
|
+
$button.dataset.yuiLabelWas = $label.textContent;
|
|
175
|
+
$label.textContent = label;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/***************************************************************
|
|
180
|
+
* Put the button back the way it was. Safe to call when
|
|
181
|
+
* it was never marked.
|
|
182
|
+
***************************************************************/
|
|
183
|
+
function yui_button_unmark($button)
|
|
184
|
+
{
|
|
185
|
+
if(!$button) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let $icon = $button.querySelector("span.icon > span");
|
|
190
|
+
let $label = $button.querySelector("span.icon ~ span");
|
|
191
|
+
|
|
192
|
+
if($icon && $button.dataset.yuiIconWas !== undefined) {
|
|
193
|
+
$icon.className = $button.dataset.yuiIconWas;
|
|
194
|
+
delete $button.dataset.yuiIconWas;
|
|
195
|
+
}
|
|
196
|
+
if($label && $button.dataset.yuiLabelWas !== undefined) {
|
|
197
|
+
$label.textContent = $button.dataset.yuiLabelWas;
|
|
198
|
+
delete $button.dataset.yuiLabelWas;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export {
|
|
203
|
+
yui_copy_text,
|
|
204
|
+
yui_copy_json,
|
|
205
|
+
yui_table_rows,
|
|
206
|
+
yui_copy_table_json,
|
|
207
|
+
yui_button_mark_done,
|
|
208
|
+
yui_button_unmark,
|
|
209
|
+
};
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
yui_copy_json,
|
|
11
11
|
yui_table_rows,
|
|
12
12
|
yui_copy_table_json,
|
|
13
|
+
yui_button_mark_done,
|
|
14
|
+
yui_button_unmark,
|
|
13
15
|
} from "./yui_clipboard.js";
|
|
14
16
|
|
|
15
17
|
let written;
|
|
@@ -110,3 +112,73 @@ test("copy_table_json: counts the SELECTION when there is one", async () => {
|
|
|
110
112
|
let active = [{id: 1}, {id: 2}, {id: 3}];
|
|
111
113
|
await expect(yui_copy_table_json(fake_table(active, [{id: 2}]))).resolves.toBe(1);
|
|
112
114
|
});
|
|
115
|
+
|
|
116
|
+
/*============================================================
|
|
117
|
+
* yui_button_mark_done / yui_button_unmark
|
|
118
|
+
*
|
|
119
|
+
* Doubles instead of jsdom: the library has no DOM test
|
|
120
|
+
* environment and does not need one for this. What is worth
|
|
121
|
+
* testing here is the save/restore bookkeeping; that the
|
|
122
|
+
* selectors match the real markup is the app's job to prove.
|
|
123
|
+
*============================================================*/
|
|
124
|
+
function fake_button(with_label)
|
|
125
|
+
{
|
|
126
|
+
let $icon = {className: "yi-copy"};
|
|
127
|
+
let $label = with_label? {textContent: "Copy JSON"} : null;
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
$icon: $icon,
|
|
131
|
+
$label: $label,
|
|
132
|
+
dataset: {},
|
|
133
|
+
querySelector: function(sel) {
|
|
134
|
+
if(sel === "span.icon > span") {
|
|
135
|
+
return $icon;
|
|
136
|
+
}
|
|
137
|
+
return $label;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
test("mark_done: swaps the glyph for a check and the label", () => {
|
|
143
|
+
let $b = fake_button(true);
|
|
144
|
+
yui_button_mark_done($b, "Copied");
|
|
145
|
+
expect($b.$icon.className).toBe("yi-check");
|
|
146
|
+
expect($b.$label.textContent).toBe("Copied");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("unmark: puts the original glyph and label back", () => {
|
|
150
|
+
let $b = fake_button(true);
|
|
151
|
+
yui_button_mark_done($b, "Copied");
|
|
152
|
+
yui_button_unmark($b);
|
|
153
|
+
expect($b.$icon.className).toBe("yi-copy");
|
|
154
|
+
expect($b.$label.textContent).toBe("Copy JSON");
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("mark_done twice does NOT lose the original", () => {
|
|
158
|
+
let $b = fake_button(true);
|
|
159
|
+
yui_button_mark_done($b, "Copied");
|
|
160
|
+
yui_button_mark_done($b, "Copied again");
|
|
161
|
+
yui_button_unmark($b);
|
|
162
|
+
expect($b.$icon.className).toBe("yi-copy");
|
|
163
|
+
expect($b.$label.textContent).toBe("Copy JSON");
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test("an icon-only button (no label) round-trips too", () => {
|
|
167
|
+
let $b = fake_button(false);
|
|
168
|
+
yui_button_mark_done($b, "Copied");
|
|
169
|
+
expect($b.$icon.className).toBe("yi-check");
|
|
170
|
+
yui_button_unmark($b);
|
|
171
|
+
expect($b.$icon.className).toBe("yi-copy");
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("unmark on a button that was never marked is a no-op", () => {
|
|
175
|
+
let $b = fake_button(true);
|
|
176
|
+
yui_button_unmark($b);
|
|
177
|
+
expect($b.$icon.className).toBe("yi-copy");
|
|
178
|
+
expect($b.$label.textContent).toBe("Copy JSON");
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("mark_done without a button is reported, not thrown", () => {
|
|
182
|
+
expect(() => yui_button_mark_done(null, "Copied")).not.toThrow();
|
|
183
|
+
expect(() => yui_button_unmark(null)).not.toThrow();
|
|
184
|
+
});
|