dictate-button 1.4.1 → 1.5.1

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Dictate Button (Web Component)
2
2
  ![NPM Version](https://img.shields.io/npm/v/dictate-button)
3
3
 
4
- A customizable web component that adds speech-to-text dictation capabilities to any text input or textarea field on your website.
4
+ A customizable web component that adds speech-to-text dictation capabilities to any text input, textarea field, or contenteditable element on your website.
5
5
 
6
6
  Developed for [dictate-button.io](https://dictate-button.io).
7
7
 
@@ -9,7 +9,7 @@ Developed for [dictate-button.io](https://dictate-button.io).
9
9
 
10
10
  - Easy integration with any website
11
11
  - Compatible with any framework (or no framework)
12
- - Automatic injection into any textarea or text input with the `data-dictate-button-on` attribute (exclusive mode) or without the `data-dictate-button-off` attribute (inclusive mode)
12
+ - Automatic injection into text fields with the `data-dictate-button-on` attribute (exclusive mode) or without the `data-dictate-button-off` attribute (inclusive mode)
13
13
  - Simple speech-to-text functionality with clean UI
14
14
  - Customizable size and API endpoint
15
15
  - Dark and light theme support
@@ -23,6 +23,7 @@ Developed for [dictate-button.io](https://dictate-button.io).
23
23
  - input[type="text"]
24
24
  - input[type="search"]
25
25
  - input (without a type; defaults to text)
26
+ - [contenteditable] elements
26
27
 
27
28
  ## Usage
28
29
 
@@ -39,6 +40,7 @@ Both auto-inject modes:
39
40
  - Automatically run on DOMContentLoaded (or immediately if the DOM is already loaded).
40
41
  - Watch for DOM changes to apply the dictate button to newly added elements.
41
42
  - Set the button’s language from `document.documentElement.lang` (if present). Long codes like `en-GB` are normalized to `en`.
43
+ - Position the button to the top right-hand corner of the text field, respecting its padding with 4px fallback if the padding is not set (0).
42
44
 
43
45
  ### From CDN
44
46
 
@@ -51,13 +53,14 @@ In your HTML `<head>` tag, add the following script tags:
51
53
  <script type="module" crossorigin src="https://cdn.dictate-button.io/inject-exclusive.js"></script>
52
54
  ```
53
55
 
54
- Add the `data-dictate-button-on` attribute to any `textarea`, `input[type="text"]`, `input[type="search"]`, or `input` without a `type` attribute:
56
+ Add the `data-dictate-button-on` attribute to any `textarea`, `input[type="text"]`, `input[type="search"]`, `input` without a `type` attribute, or element with the `contenteditable` attribute:
55
57
 
56
58
  ```html
57
59
  <textarea data-dictate-button-on></textarea>
58
60
  <input type="text" data-dictate-button-on />
59
61
  <input type="search" data-dictate-button-on />
60
62
  <input data-dictate-button-on />
63
+ <div contenteditable data-dictate-button-on />
61
64
  ```
62
65
 
63
66
  #### Option 2: Using the inclusive auto-inject script
@@ -69,7 +72,7 @@ In your HTML `<head>` tag, add the following script tags:
69
72
  <script type="module" crossorigin src="https://cdn.dictate-button.io/inject-inclusive.js"></script>
70
73
  ```
71
74
 
72
- All `textarea`, `input[type="text"]`, `input[type="search"]`, and `input` elements without a `type` attribute that lack `data-dictate-button-off` will be automatically enhanced by default.
75
+ All `textarea`, `input[type="text"]`, `input[type="search"]`, `input` elements without a `type` attribute, and elements with the `contenteditable` attribute that lack `data-dictate-button-off` will be automatically enhanced by default.
73
76
 
74
77
  To disable that for a specific field, add the `data-dictate-button-off` attribute to it this way:
75
78
 
@@ -78,6 +81,7 @@ To disable that for a specific field, add the `data-dictate-button-off` attribut
78
81
  <input type="text" data-dictate-button-off />
79
82
  <input type="search" data-dictate-button-off />
80
83
  <input data-dictate-button-off />
84
+ <div contenteditable data-dictate-button-off />
81
85
  ```
82
86
 
83
87
  #### Option 3: Manual integration
@@ -136,9 +140,9 @@ injectDictateButtonOnLoad(
136
140
  'input.custom-selector', // CSS selector for target elements
137
141
  {
138
142
  buttonSize: 30, // Button size in pixels (optional; default: 30)
139
- watchDomChanges: true, // Watch for DOM changes (optional; default: false)
140
143
  verbose: false, // Log events to console (optional; default: false)
141
- customApiEndpoint: 'https://api.example.com/transcribe' // Optional custom API endpoint
144
+ customApiEndpoint: 'https://api.example.com/transcribe', // Optional custom API endpoint
145
+ watchDomChanges: true // Watch for DOM changes (optional; default: false)
142
146
  }
143
147
  )
144
148
  ```
@@ -1,47 +1,47 @@
1
- const wt = (t, e) => t === e, B = {
2
- equals: wt
1
+ const mt = (t, e) => t === e, j = {
2
+ equals: mt
3
3
  };
4
- let vt = ht;
5
- const S = 1, R = 2, lt = {
4
+ let vt = pt;
5
+ const S = 1, B = 2, at = {
6
6
  owned: null,
7
7
  cleanups: null,
8
8
  context: null,
9
9
  owner: null
10
10
  };
11
11
  var _ = null;
12
- let V = null, Ct = null, p = null, g = null, m = null, L = 0;
13
- function mt(t, e) {
14
- const n = p, o = _, r = t.length === 0, i = e === void 0 ? o : e, l = r ? lt : {
12
+ let V = null, Ct = null, p = null, g = null, C = null, F = 0;
13
+ function St(t, e) {
14
+ const n = p, o = _, r = t.length === 0, i = e === void 0 ? o : e, l = r ? at : {
15
15
  owned: null,
16
16
  cleanups: null,
17
17
  context: i ? i.context : null,
18
18
  owner: i
19
- }, s = r ? t : () => t(() => W(() => $(l)));
19
+ }, s = r ? t : () => t(() => W(() => T(l)));
20
20
  _ = l, p = null;
21
21
  try {
22
- return T(s, !0);
22
+ return $(s, !0);
23
23
  } finally {
24
24
  p = n, _ = o;
25
25
  }
26
26
  }
27
- function at(t, e) {
28
- e = e ? Object.assign({}, B, e) : B;
27
+ function ct(t, e) {
28
+ e = e ? Object.assign({}, j, e) : j;
29
29
  const n = {
30
30
  value: t,
31
31
  observers: null,
32
32
  observerSlots: null,
33
33
  comparator: e.equals || void 0
34
- }, o = (r) => (typeof r == "function" && (r = r(n.value)), ut(n, r));
35
- return [ct.bind(n), o];
34
+ }, o = (r) => (typeof r == "function" && (r = r(n.value)), dt(n, r));
35
+ return [ut.bind(n), o];
36
36
  }
37
- function I(t, e, n) {
38
- const o = dt(t, e, !1, S);
39
- K(o);
37
+ function R(t, e, n) {
38
+ const o = ft(t, e, !1, S);
39
+ L(o);
40
40
  }
41
- function St(t, e, n) {
42
- n = n ? Object.assign({}, B, n) : B;
43
- const o = dt(t, e, !0, 0);
44
- return o.observers = null, o.observerSlots = null, o.comparator = n.equals || void 0, K(o), ct.bind(o);
41
+ function xt(t, e, n) {
42
+ n = n ? Object.assign({}, j, n) : j;
43
+ const o = ft(t, e, !0, 0);
44
+ return o.observers = null, o.observerSlots = null, o.comparator = n.equals || void 0, L(o), ut.bind(o);
45
45
  }
46
46
  function W(t) {
47
47
  if (p === null) return t();
@@ -53,12 +53,12 @@ function W(t) {
53
53
  p = e;
54
54
  }
55
55
  }
56
- function ct() {
56
+ function ut() {
57
57
  if (this.sources && this.state)
58
- if (this.state === S) K(this);
58
+ if (this.state === S) L(this);
59
59
  else {
60
60
  const t = g;
61
- g = null, T(() => D(this), !1), g = t;
61
+ g = null, $(() => I(this), !1), g = t;
62
62
  }
63
63
  if (p) {
64
64
  const t = this.observers ? this.observers.length : 0;
@@ -66,37 +66,37 @@ function ct() {
66
66
  }
67
67
  return this.value;
68
68
  }
69
- function ut(t, e, n) {
69
+ function dt(t, e, n) {
70
70
  let o = t.value;
71
- return (!t.comparator || !t.comparator(o, e)) && (t.value = e, t.observers && t.observers.length && T(() => {
71
+ return (!t.comparator || !t.comparator(o, e)) && (t.value = e, t.observers && t.observers.length && $(() => {
72
72
  for (let r = 0; r < t.observers.length; r += 1) {
73
73
  const i = t.observers[r], l = V && V.running;
74
- l && V.disposed.has(i), (l ? !i.tState : !i.state) && (i.pure ? g.push(i) : m.push(i), i.observers && pt(i)), l || (i.state = S);
74
+ l && V.disposed.has(i), (l ? !i.tState : !i.state) && (i.pure ? g.push(i) : C.push(i), i.observers && gt(i)), l || (i.state = S);
75
75
  }
76
76
  if (g.length > 1e6)
77
77
  throw g = [], new Error();
78
78
  }, !1)), e;
79
79
  }
80
- function K(t) {
80
+ function L(t) {
81
81
  if (!t.fn) return;
82
- $(t);
83
- const e = L;
84
- xt(t, t.value, e);
82
+ T(t);
83
+ const e = F;
84
+ At(t, t.value, e);
85
85
  }
86
- function xt(t, e, n) {
86
+ function At(t, e, n) {
87
87
  let o;
88
88
  const r = _, i = p;
89
89
  p = _ = t;
90
90
  try {
91
91
  o = t.fn(e);
92
92
  } catch (l) {
93
- return t.pure && (t.state = S, t.owned && t.owned.forEach($), t.owned = null), t.updatedAt = n + 1, gt(l);
93
+ return t.pure && (t.state = S, t.owned && t.owned.forEach(T), t.owned = null), t.updatedAt = n + 1, bt(l);
94
94
  } finally {
95
95
  p = i, _ = r;
96
96
  }
97
- (!t.updatedAt || t.updatedAt <= n) && (t.updatedAt != null && "observers" in t ? ut(t, o) : t.value = o, t.updatedAt = n);
97
+ (!t.updatedAt || t.updatedAt <= n) && (t.updatedAt != null && "observers" in t ? dt(t, o) : t.value = o, t.updatedAt = n);
98
98
  }
99
- function dt(t, e, n, o = S, r) {
99
+ function ft(t, e, n, o = S, r) {
100
100
  const i = {
101
101
  fn: t,
102
102
  state: o,
@@ -110,59 +110,59 @@ function dt(t, e, n, o = S, r) {
110
110
  context: _ ? _.context : null,
111
111
  pure: n
112
112
  };
113
- return _ === null || _ !== lt && (_.owned ? _.owned.push(i) : _.owned = [i]), i;
113
+ return _ === null || _ !== at && (_.owned ? _.owned.push(i) : _.owned = [i]), i;
114
114
  }
115
- function ft(t) {
115
+ function ht(t) {
116
116
  if (t.state === 0) return;
117
- if (t.state === R) return D(t);
117
+ if (t.state === B) return I(t);
118
118
  if (t.suspense && W(t.suspense.inFallback)) return t.suspense.effects.push(t);
119
119
  const e = [t];
120
- for (; (t = t.owner) && (!t.updatedAt || t.updatedAt < L); )
120
+ for (; (t = t.owner) && (!t.updatedAt || t.updatedAt < F); )
121
121
  t.state && e.push(t);
122
122
  for (let n = e.length - 1; n >= 0; n--)
123
123
  if (t = e[n], t.state === S)
124
- K(t);
125
- else if (t.state === R) {
124
+ L(t);
125
+ else if (t.state === B) {
126
126
  const o = g;
127
- g = null, T(() => D(t, e[0]), !1), g = o;
127
+ g = null, $(() => I(t, e[0]), !1), g = o;
128
128
  }
129
129
  }
130
- function T(t, e) {
130
+ function $(t, e) {
131
131
  if (g) return t();
132
132
  let n = !1;
133
- e || (g = []), m ? n = !0 : m = [], L++;
133
+ e || (g = []), C ? n = !0 : C = [], F++;
134
134
  try {
135
135
  const o = t();
136
- return At(n), o;
136
+ return Et(n), o;
137
137
  } catch (o) {
138
- n || (m = null), g = null, gt(o);
138
+ n || (C = null), g = null, bt(o);
139
139
  }
140
140
  }
141
- function At(t) {
142
- if (g && (ht(g), g = null), t) return;
143
- const e = m;
144
- m = null, e.length && T(() => vt(e), !1);
141
+ function Et(t) {
142
+ if (g && (pt(g), g = null), t) return;
143
+ const e = C;
144
+ C = null, e.length && $(() => vt(e), !1);
145
145
  }
146
- function ht(t) {
147
- for (let e = 0; e < t.length; e++) ft(t[e]);
146
+ function pt(t) {
147
+ for (let e = 0; e < t.length; e++) ht(t[e]);
148
148
  }
149
- function D(t, e) {
149
+ function I(t, e) {
150
150
  t.state = 0;
151
151
  for (let n = 0; n < t.sources.length; n += 1) {
152
152
  const o = t.sources[n];
153
153
  if (o.sources) {
154
154
  const r = o.state;
155
- r === S ? o !== e && (!o.updatedAt || o.updatedAt < L) && ft(o) : r === R && D(o, e);
155
+ r === S ? o !== e && (!o.updatedAt || o.updatedAt < F) && ht(o) : r === B && I(o, e);
156
156
  }
157
157
  }
158
158
  }
159
- function pt(t) {
159
+ function gt(t) {
160
160
  for (let e = 0; e < t.observers.length; e += 1) {
161
161
  const n = t.observers[e];
162
- n.state || (n.state = R, n.pure ? g.push(n) : m.push(n), n.observers && pt(n));
162
+ n.state || (n.state = B, n.pure ? g.push(n) : C.push(n), n.observers && gt(n));
163
163
  }
164
164
  }
165
- function $(t) {
165
+ function T(t) {
166
166
  let e;
167
167
  if (t.sources)
168
168
  for (; t.sources.length; ) {
@@ -173,11 +173,11 @@ function $(t) {
173
173
  }
174
174
  }
175
175
  if (t.tOwned) {
176
- for (e = t.tOwned.length - 1; e >= 0; e--) $(t.tOwned[e]);
176
+ for (e = t.tOwned.length - 1; e >= 0; e--) T(t.tOwned[e]);
177
177
  delete t.tOwned;
178
178
  }
179
179
  if (t.owned) {
180
- for (e = t.owned.length - 1; e >= 0; e--) $(t.owned[e]);
180
+ for (e = t.owned.length - 1; e >= 0; e--) T(t.owned[e]);
181
181
  t.owned = null;
182
182
  }
183
183
  if (t.cleanups) {
@@ -186,19 +186,19 @@ function $(t) {
186
186
  }
187
187
  t.state = 0;
188
188
  }
189
- function Et(t) {
189
+ function kt(t) {
190
190
  return t instanceof Error ? t : new Error(typeof t == "string" ? t : "Unknown error", {
191
191
  cause: t
192
192
  });
193
193
  }
194
- function gt(t, e = _) {
195
- throw Et(t);
194
+ function bt(t, e = _) {
195
+ throw kt(t);
196
196
  }
197
- function N(t, e) {
197
+ function M(t, e) {
198
198
  return W(() => t(e || {}));
199
199
  }
200
- const j = (t) => St(() => t());
201
- function kt(t, e, n) {
200
+ const N = (t) => xt(() => t());
201
+ function Tt(t, e, n) {
202
202
  let o = n.length, r = e.length, i = o, l = 0, s = 0, a = e[r - 1].nextSibling, u = null;
203
203
  for (; l < r || s < i; ) {
204
204
  if (e[l] === n[s]) {
@@ -208,36 +208,36 @@ function kt(t, e, n) {
208
208
  for (; e[r - 1] === n[i - 1]; )
209
209
  r--, i--;
210
210
  if (r === l) {
211
- const d = i < o ? s ? n[s - 1].nextSibling : n[i - s] : a;
212
- for (; s < i; ) t.insertBefore(n[s++], d);
211
+ const f = i < o ? s ? n[s - 1].nextSibling : n[i - s] : a;
212
+ for (; s < i; ) t.insertBefore(n[s++], f);
213
213
  } else if (i === s)
214
214
  for (; l < r; )
215
215
  (!u || !u.has(e[l])) && e[l].remove(), l++;
216
216
  else if (e[l] === n[i - 1] && n[s] === e[r - 1]) {
217
- const d = e[--r].nextSibling;
218
- t.insertBefore(n[s++], e[l++].nextSibling), t.insertBefore(n[--i], d), e[r] = n[i];
217
+ const f = e[--r].nextSibling;
218
+ t.insertBefore(n[s++], e[l++].nextSibling), t.insertBefore(n[--i], f), e[r] = n[i];
219
219
  } else {
220
220
  if (!u) {
221
221
  u = /* @__PURE__ */ new Map();
222
- let w = s;
223
- for (; w < i; ) u.set(n[w], w++);
222
+ let b = s;
223
+ for (; b < i; ) u.set(n[b], b++);
224
224
  }
225
- const d = u.get(e[l]);
226
- if (d != null)
227
- if (s < d && d < i) {
228
- let w = l, E = 1, P;
229
- for (; ++w < r && w < i && !((P = u.get(e[w])) == null || P !== d + E); )
225
+ const f = u.get(e[l]);
226
+ if (f != null)
227
+ if (s < f && f < i) {
228
+ let b = l, E = 1, P;
229
+ for (; ++b < r && b < i && !((P = u.get(e[b])) == null || P !== f + E); )
230
230
  E++;
231
- if (E > d - s) {
232
- const M = e[l];
233
- for (; s < d; ) t.insertBefore(n[s++], M);
231
+ if (E > f - s) {
232
+ const K = e[l];
233
+ for (; s < f; ) t.insertBefore(n[s++], K);
234
234
  } else t.replaceChild(n[s++], e[l++]);
235
235
  } else l++;
236
236
  else e[l++].remove();
237
237
  }
238
238
  }
239
239
  }
240
- const et = "_$DX_DELEGATE";
240
+ const nt = "_$DX_DELEGATE";
241
241
  function O(t, e, n, o) {
242
242
  let r;
243
243
  const i = () => {
@@ -247,16 +247,16 @@ function O(t, e, n, o) {
247
247
  return l.cloneNode = l, l;
248
248
  }
249
249
  function $t(t, e = window.document) {
250
- const n = e[et] || (e[et] = /* @__PURE__ */ new Set());
250
+ const n = e[nt] || (e[nt] = /* @__PURE__ */ new Set());
251
251
  for (let o = 0, r = t.length; o < r; o++) {
252
252
  const i = t[o];
253
- n.has(i) || (n.add(i), e.addEventListener(i, Ot));
253
+ n.has(i) || (n.add(i), e.addEventListener(i, Pt));
254
254
  }
255
255
  }
256
256
  function k(t, e, n) {
257
257
  n == null ? t.removeAttribute(e) : t.setAttribute(e, n);
258
258
  }
259
- function Tt(t, e, n) {
259
+ function Ot(t, e, n) {
260
260
  if (!e) return n ? k(t, "style") : e;
261
261
  const o = t.style;
262
262
  if (typeof e == "string") return o.cssText = e;
@@ -268,11 +268,11 @@ function Tt(t, e, n) {
268
268
  r = e[i], r !== n[i] && (o.setProperty(i, r), n[i] = r);
269
269
  return n;
270
270
  }
271
- function C(t, e, n, o) {
272
- if (n !== void 0 && !o && (o = []), typeof e != "function") return F(t, e, o, n);
273
- I((r) => F(t, e(), r, n), o);
271
+ function v(t, e, n, o) {
272
+ if (n !== void 0 && !o && (o = []), typeof e != "function") return D(t, e, o, n);
273
+ R((r) => D(t, e(), r, n), o);
274
274
  }
275
- function Ot(t) {
275
+ function Pt(t) {
276
276
  let e = t.target;
277
277
  const n = `$$${t.type}`, o = t.target, r = t.currentTarget, i = (a) => Object.defineProperty(t, "target", {
278
278
  configurable: !0,
@@ -306,7 +306,7 @@ function Ot(t) {
306
306
  } else s();
307
307
  i(o);
308
308
  }
309
- function F(t, e, n, o, r) {
309
+ function D(t, e, n, o, r) {
310
310
  for (; typeof n == "function"; ) n = n();
311
311
  if (e === n) return n;
312
312
  const i = typeof e, l = o !== void 0;
@@ -322,18 +322,18 @@ function F(t, e, n, o, r) {
322
322
  n = x(t, n, o);
323
323
  else {
324
324
  if (i === "function")
325
- return I(() => {
325
+ return R(() => {
326
326
  let s = e();
327
327
  for (; typeof s == "function"; ) s = s();
328
- n = F(t, s, n, o);
328
+ n = D(t, s, n, o);
329
329
  }), () => n;
330
330
  if (Array.isArray(e)) {
331
331
  const s = [], a = n && Array.isArray(n);
332
332
  if (G(s, e, n, r))
333
- return I(() => n = F(t, s, n, o, !0)), () => n;
333
+ return R(() => n = D(t, s, n, o, !0)), () => n;
334
334
  if (s.length === 0) {
335
335
  if (n = x(t, n, o), l) return n;
336
- } else a ? n.length === 0 ? nt(t, s, o) : kt(t, n, s) : (n && x(t), nt(t, s));
336
+ } else a ? n.length === 0 ? rt(t, s, o) : Tt(t, n, s) : (n && x(t), rt(t, s));
337
337
  n = s;
338
338
  } else if (e.nodeType) {
339
339
  if (Array.isArray(n)) {
@@ -360,13 +360,13 @@ function G(t, e, n, o) {
360
360
  } else
361
361
  t.push(s), r = !0;
362
362
  else {
363
- const d = String(s);
364
- a && a.nodeType === 3 && a.data === d ? t.push(a) : t.push(document.createTextNode(d));
363
+ const f = String(s);
364
+ a && a.nodeType === 3 && a.data === f ? t.push(a) : t.push(document.createTextNode(f));
365
365
  }
366
366
  }
367
367
  return r;
368
368
  }
369
- function nt(t, e, n = null) {
369
+ function rt(t, e, n = null) {
370
370
  for (let o = 0, r = e.length; o < r; o++) t.insertBefore(e[o], n);
371
371
  }
372
372
  function x(t, e, n, o) {
@@ -384,43 +384,43 @@ function x(t, e, n, o) {
384
384
  } else t.insertBefore(r, n);
385
385
  return [r];
386
386
  }
387
- function Pt(t) {
387
+ function Mt(t) {
388
388
  return Object.keys(t).reduce((n, o) => {
389
389
  const r = t[o];
390
- return n[o] = Object.assign({}, r), _t(r.value) && !Rt(r.value) && !Array.isArray(r.value) && (n[o].value = Object.assign({}, r.value)), Array.isArray(r.value) && (n[o].value = r.value.slice(0)), n;
390
+ return n[o] = Object.assign({}, r), _t(r.value) && !It(r.value) && !Array.isArray(r.value) && (n[o].value = Object.assign({}, r.value)), Array.isArray(r.value) && (n[o].value = r.value.slice(0)), n;
391
391
  }, {});
392
392
  }
393
- function Mt(t) {
393
+ function Nt(t) {
394
394
  return t ? Object.keys(t).reduce((n, o) => {
395
395
  const r = t[o];
396
396
  return n[o] = _t(r) && "value" in r ? r : {
397
397
  value: r
398
- }, n[o].attribute || (n[o].attribute = Bt(o)), n[o].parse = "parse" in n[o] ? n[o].parse : typeof n[o].value != "string", n;
398
+ }, n[o].attribute || (n[o].attribute = Rt(o)), n[o].parse = "parse" in n[o] ? n[o].parse : typeof n[o].value != "string", n;
399
399
  }, {}) : {};
400
400
  }
401
- function Nt(t) {
401
+ function jt(t) {
402
402
  return Object.keys(t).reduce((n, o) => (n[o] = t[o].value, n), {});
403
403
  }
404
- function jt(t, e) {
405
- const n = Pt(e);
404
+ function Bt(t, e) {
405
+ const n = Mt(e);
406
406
  return Object.keys(e).forEach((r) => {
407
407
  const i = n[r], l = t.getAttribute(i.attribute), s = t[r];
408
- l != null && (i.value = i.parse ? bt(l) : l), s != null && (i.value = Array.isArray(s) ? s.slice(0) : s), i.reflect && rt(t, i.attribute, i.value, !!i.parse), Object.defineProperty(t, r, {
408
+ l != null && (i.value = i.parse ? yt(l) : l), s != null && (i.value = Array.isArray(s) ? s.slice(0) : s), i.reflect && ot(t, i.attribute, i.value, !!i.parse), Object.defineProperty(t, r, {
409
409
  get() {
410
410
  return i.value;
411
411
  },
412
412
  set(a) {
413
413
  const u = i.value;
414
- i.value = a, i.reflect && rt(this, i.attribute, i.value, !!i.parse);
415
- for (let d = 0, w = this.__propertyChangedCallbacks.length; d < w; d++)
416
- this.__propertyChangedCallbacks[d](r, a, u);
414
+ i.value = a, i.reflect && ot(this, i.attribute, i.value, !!i.parse);
415
+ for (let f = 0, b = this.__propertyChangedCallbacks.length; f < b; f++)
416
+ this.__propertyChangedCallbacks[f](r, a, u);
417
417
  },
418
418
  enumerable: !0,
419
419
  configurable: !0
420
420
  });
421
421
  }), n;
422
422
  }
423
- function bt(t) {
423
+ function yt(t) {
424
424
  if (t)
425
425
  try {
426
426
  return JSON.parse(t);
@@ -428,25 +428,25 @@ function bt(t) {
428
428
  return t;
429
429
  }
430
430
  }
431
- function rt(t, e, n, o) {
431
+ function ot(t, e, n, o) {
432
432
  if (n == null || n === !1) return t.removeAttribute(e);
433
433
  let r = o ? JSON.stringify(n) : n;
434
434
  t.__updating[e] = !0, r === "true" && (r = ""), t.setAttribute(e, r), Promise.resolve().then(() => delete t.__updating[e]);
435
435
  }
436
- function Bt(t) {
436
+ function Rt(t) {
437
437
  return t.replace(/\.?([A-Z]+)/g, (e, n) => "-" + n.toLowerCase()).replace("_", "-").replace(/^-/, "");
438
438
  }
439
439
  function _t(t) {
440
440
  return t != null && (typeof t == "object" || typeof t == "function");
441
441
  }
442
- function Rt(t) {
442
+ function It(t) {
443
443
  return Object.prototype.toString.call(t) === "[object Function]";
444
444
  }
445
- function It(t) {
445
+ function Dt(t) {
446
446
  return typeof t == "function" && t.toString().indexOf("class") === 0;
447
447
  }
448
448
  let q;
449
- function Dt(t, e) {
449
+ function Ft(t, e) {
450
450
  const n = Object.keys(e);
451
451
  return class extends t {
452
452
  static get observedAttributes() {
@@ -454,13 +454,15 @@ function Dt(t, e) {
454
454
  }
455
455
  constructor() {
456
456
  super(), this.__initialized = !1, this.__released = !1, this.__releaseCallbacks = [], this.__propertyChangedCallbacks = [], this.__updating = {}, this.props = {};
457
+ for (let r of n)
458
+ this[r] = void 0;
457
459
  }
458
460
  connectedCallback() {
459
461
  if (this.__initialized) return;
460
- this.__releaseCallbacks = [], this.__propertyChangedCallbacks = [], this.__updating = {}, this.props = jt(this, e);
461
- const r = Nt(this.props), i = this.Component, l = q;
462
+ this.__releaseCallbacks = [], this.__propertyChangedCallbacks = [], this.__updating = {}, this.props = Bt(this, e);
463
+ const r = jt(this.props), i = this.Component, l = q;
462
464
  try {
463
- q = this, this.__initialized = !0, It(i) ? new i(r, {
465
+ q = this, this.__initialized = !0, Dt(i) ? new i(r, {
464
466
  element: this
465
467
  }) : i(r, {
466
468
  element: this
@@ -479,7 +481,7 @@ function Dt(t, e) {
479
481
  attributeChangedCallback(r, i, l) {
480
482
  if (this.__initialized && !this.__updating[r] && (r = this.lookupProp(r), r in e)) {
481
483
  if (l == null && !this[r]) return;
482
- this[r] = e[r].parse ? bt(l) : l;
484
+ this[r] = e[r].parse ? yt(l) : l;
483
485
  }
484
486
  }
485
487
  lookupProp(r) {
@@ -499,7 +501,7 @@ function Dt(t, e) {
499
501
  }
500
502
  };
501
503
  }
502
- function Ft(t, e = {}, n = {}) {
504
+ function Lt(t, e = {}, n = {}) {
503
505
  const {
504
506
  BaseElement: o = HTMLElement,
505
507
  extension: r,
@@ -507,13 +509,13 @@ function Ft(t, e = {}, n = {}) {
507
509
  } = n;
508
510
  return (l) => {
509
511
  let s = i.get(t);
510
- return s ? (s.prototype.Component = l, s) : (s = Dt(o, Mt(e)), s.prototype.Component = l, s.prototype.registeredTag = t, i.define(t, s, r), s);
512
+ return s ? (s.prototype.Component = l, s) : (s = Ft(o, Nt(e)), s.prototype.Component = l, s.prototype.registeredTag = t, i.define(t, s, r), s);
511
513
  };
512
514
  }
513
- function Lt(t) {
515
+ function Kt(t) {
514
516
  const e = Object.keys(t), n = {};
515
517
  for (let o = 0; o < e.length; o++) {
516
- const [r, i] = at(t[e[o]]);
518
+ const [r, i] = ct(t[e[o]]);
517
519
  Object.defineProperty(n, e[o], {
518
520
  get: r,
519
521
  set(l) {
@@ -523,30 +525,30 @@ function Lt(t) {
523
525
  }
524
526
  return n;
525
527
  }
526
- function Kt(t) {
528
+ function Ut(t) {
527
529
  if (t.assignedSlot && t.assignedSlot._$owner) return t.assignedSlot._$owner;
528
530
  let e = t.parentNode;
529
531
  for (; e && !e._$owner && !(e.assignedSlot && e.assignedSlot._$owner); )
530
532
  e = e.parentNode;
531
533
  return e && e.assignedSlot ? e.assignedSlot._$owner : t._$owner;
532
534
  }
533
- function Ut(t) {
535
+ function zt(t) {
534
536
  return (e, n) => {
535
537
  const { element: o } = n;
536
- return mt((r) => {
537
- const i = Lt(e);
538
+ return St((r) => {
539
+ const i = Kt(e);
538
540
  o.addPropertyChangedCallback((s, a) => i[s] = a), o.addReleaseCallback(() => {
539
541
  o.renderRoot.textContent = "", r();
540
542
  });
541
543
  const l = t(i, n);
542
- return C(o.renderRoot, l);
543
- }, Kt(o));
544
+ return v(o.renderRoot, l);
545
+ }, Ut(o));
544
546
  };
545
547
  }
546
- function zt(t, e, n) {
547
- return arguments.length === 2 && (n = e, e = {}), Ft(t, e)(Ut(n));
548
+ function Vt(t, e, n) {
549
+ return arguments.length === 2 && (n = e, e = {}), Lt(t, e)(zt(n));
548
550
  }
549
- const Vt = `
551
+ const qt = `
550
552
  :host([theme="dark"]) {
551
553
  color-scheme: only dark;
552
554
  }
@@ -604,61 +606,61 @@ const Vt = `
604
606
  }
605
607
  }
606
608
  `;
607
- var qt = /* @__PURE__ */ O('<div part=container class=dictate-button__container><style></style><div aria-live=polite class=dictate-button__status-announcer style="position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0"></div><button part=button class=dictate-button__button>'), Ht = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--idle"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor role=img aria-hidden=true><path stroke-linecap=round stroke-linejoin=round d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z">'), Gt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--recording"viewBox="0 0 24 24"fill=currentColor role=img aria-hidden=true><circle cx=12 cy=12 r=10>'), Wt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--processing"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><path d="M12 2v4"></path><path d="m16.2 7.8 2.9-2.9"></path><path d="M18 12h4"></path><path d="m16.2 16.2 2.9 2.9"></path><path d="M12 18v4"></path><path d="m4.9 19.1 2.9-2.9"></path><path d="M2 12h4"></path><path d="m4.9 4.9 2.9 2.9">'), Xt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--error"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=4 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><line x1=12 x2=12 y1=4 y2=14></line><line x1=12 x2=12.01 y1=20 y2=20>');
608
- console.debug("dictate-button version:", "1.4.1");
609
- const Jt = "https://api.dictate-button.io/transcribe", v = "dictate-button.io", H = -70, ot = -10, it = 0, Zt = 4, Qt = 0.25, Yt = 0.05;
610
- zt("dictate-button", {
609
+ var Ht = /* @__PURE__ */ O('<div part=container class=dictate-button__container><style></style><div aria-live=polite class=dictate-button__status-announcer style="position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0"></div><button part=button class=dictate-button__button>'), Gt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--idle"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor role=img aria-hidden=true><path stroke-linecap=round stroke-linejoin=round d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z">'), Wt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--recording"viewBox="0 0 24 24"fill=currentColor role=img aria-hidden=true><circle cx=12 cy=12 r=10>'), Xt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--processing"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><path d="M12 2v4"></path><path d="m16.2 7.8 2.9-2.9"></path><path d="M18 12h4"></path><path d="m16.2 16.2 2.9 2.9"></path><path d="M12 18v4"></path><path d="m4.9 19.1 2.9-2.9"></path><path d="M2 12h4"></path><path d="m4.9 4.9 2.9 2.9">'), Jt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--error"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=4 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><line x1=12 x2=12 y1=4 y2=14></line><line x1=12 x2=12.01 y1=20 y2=20>');
610
+ console.debug("dictate-button version:", "1.5.1");
611
+ const Zt = "https://api.dictate-button.io/transcribe", m = "dictate-button.io", H = -70, it = -10, st = 0, Qt = 4, Yt = 0.25, te = 0.05;
612
+ Vt("dictate-button", {
611
613
  size: 30,
612
- apiEndpoint: Jt,
614
+ apiEndpoint: Zt,
613
615
  language: void 0
614
616
  }, (t, {
615
617
  element: e
616
618
  }) => {
617
619
  console.debug("api", t.apiEndpoint);
618
- const [n, o] = at("idle");
619
- let r = null, i = [], l = null, s = null, a = null, u = !1, d = 0;
620
- const w = (f) => f <= H ? 0 : f >= ot ? 1 : (f - H) / (ot - H), E = (f) => {
621
- let y = 0;
622
- for (let b = 0; b < f.length; b++) {
623
- const c = (f[b] - 128) / 128;
624
- y += c * c;
620
+ const [n, o] = ct("idle");
621
+ let r = null, i = null, l = [], s = null, a = null, u = null, f = !1, b = 0;
622
+ const E = (d) => d <= H ? 0 : d >= it ? 1 : (d - H) / (it - H), P = (d) => {
623
+ let w = 0;
624
+ for (let y = 0; y < d.length; y++) {
625
+ const c = (d[y] - 128) / 128;
626
+ w += c * c;
625
627
  }
626
- return Math.sqrt(y / f.length);
627
- }, P = (f) => 20 * Math.log10(Math.max(f, 1e-8)), M = (f) => {
628
- const y = e.shadowRoot.querySelector(".dictate-button__button");
629
- if (!y)
628
+ return Math.sqrt(w / d.length);
629
+ }, K = (d) => 20 * Math.log10(Math.max(d, 1e-8)), X = (d) => {
630
+ const w = e.shadowRoot.querySelector(".dictate-button__button");
631
+ if (!w)
630
632
  return;
631
- const b = it + f * (Zt - it), c = 0 + f * 0.4;
632
- y.style.boxShadow = `0 0 0 ${b}px light-dark(rgba(0, 0, 0, ${c}), rgba(255, 255, 255, ${c}))`;
633
- }, X = () => {
634
- if (!u || !s || !a) return;
635
- s.getByteTimeDomainData(a);
636
- const f = E(a), y = P(f), b = w(y), c = b > d ? Qt : Yt;
637
- d = c * b + (1 - c) * d, M(d), requestAnimationFrame(X);
633
+ const y = st + d * (Qt - st), c = 0 + d * 0.4;
634
+ w.style.boxShadow = `0 0 0 ${y}px light-dark(rgba(0, 0, 0, ${c}), rgba(255, 255, 255, ${c}))`;
635
+ }, J = () => {
636
+ if (!f || !a || !u) return;
637
+ a.getByteTimeDomainData(u);
638
+ const d = P(u), w = K(d), y = E(w), c = y > b ? Yt : te;
639
+ b = c * y + (1 - c) * b, X(b), requestAnimationFrame(J);
638
640
  }, U = () => {
639
- r && r.state !== "inactive" && r.stop(), i = [], u = !1, l && l.state !== "closed" && l.close(), l = null, s = null, a = null, d = 0, M(0);
641
+ r && r.state !== "inactive" && r.stop(), i && (i.getTracks().forEach((d) => d.stop()), i = null), l = [], f = !1, s && s.state !== "closed" && s.close(), s = null, a = null, u = null, b = 0, X(0);
640
642
  };
641
643
  e.addEventListener("disconnected", U);
642
- const yt = async () => {
644
+ const wt = async () => {
643
645
  if (U(), n() === "idle")
644
646
  try {
645
- const f = await navigator.mediaDevices.getUserMedia({
647
+ const d = await navigator.mediaDevices.getUserMedia({
646
648
  audio: !0
647
649
  });
648
- l = new (window.AudioContext || window.webkitAudioContext)();
649
- const y = l.createMediaStreamSource(f);
650
- s = l.createAnalyser(), s.fftSize = 2048, y.connect(s), a = new Uint8Array(s.fftSize), r = new MediaRecorder(f, {
650
+ i = d, s = new (window.AudioContext || window.webkitAudioContext)();
651
+ const w = s.createMediaStreamSource(d);
652
+ a = s.createAnalyser(), a.fftSize = 2048, w.connect(a), u = new Uint8Array(a.fftSize), r = new MediaRecorder(d, {
651
653
  mimeType: "audio/webm"
652
- }), i = [], r.ondataavailable = (b) => {
653
- i.push(b.data);
654
+ }), l = [], r.ondataavailable = (y) => {
655
+ l.push(y.data);
654
656
  }, r.onstop = async () => {
655
- u = !1, o("processing"), A(e, "transcribing:started", "Started transcribing");
656
- const b = new Blob(i, {
657
+ f = !1, o("processing"), A(e, "transcribing:started", "Started transcribing");
658
+ const y = new Blob(l, {
657
659
  type: "audio/webm"
658
660
  });
659
661
  try {
660
662
  const c = new FormData();
661
- c.append("audio", b, "recording.webm"), c.append("origin", window?.location?.origin), t.language && c.append("language", t.language);
663
+ c.append("audio", y, "recording.webm"), c.append("origin", window?.location?.origin), t.language && c.append("language", t.language);
662
664
  const h = await fetch(t.apiEndpoint, {
663
665
  method: "POST",
664
666
  body: c
@@ -668,64 +670,64 @@ zt("dictate-button", {
668
670
  if (n() !== "processing") return;
669
671
  A(e, "transcribing:finished", z.text), o("idle");
670
672
  } catch (c) {
671
- console.error("Failed to transcribe audio:", c), A(e, "transcribing:failed", "Failed to transcribe audio"), J();
673
+ console.error("Failed to transcribe audio:", c), A(e, "transcribing:failed", "Failed to transcribe audio"), Z();
672
674
  }
673
- }, r.start(), A(e, "recording:started", "Started recording"), u = !0, X(), o("recording");
674
- } catch (f) {
675
- console.error("Failed to start recording:", f), A(e, "recording:failed", "Failed to start recording"), J();
675
+ }, r.start(), A(e, "recording:started", "Started recording"), f = !0, J(), o("recording");
676
+ } catch (d) {
677
+ console.error("Failed to start recording:", d), A(e, "recording:failed", "Failed to start recording"), Z();
676
678
  }
677
679
  else
678
680
  A(e, "recording:stopped", "Stopped recording"), o("idle"), U();
679
- }, J = () => {
681
+ }, Z = () => {
680
682
  o("error"), setTimeout(() => o("idle"), 2e3);
681
683
  };
682
684
  return (() => {
683
- var f = qt(), y = f.firstChild, b = y.nextSibling, c = b.nextSibling;
684
- return C(y, Vt), C(b, () => st(n())), c.$$click = yt, C(c, (() => {
685
- var h = j(() => n() === "idle");
686
- return () => h() && N(ee, {});
687
- })(), null), C(c, (() => {
688
- var h = j(() => n() === "recording");
689
- return () => h() && N(ne, {});
690
- })(), null), C(c, (() => {
691
- var h = j(() => n() === "processing");
692
- return () => h() && N(re, {});
693
- })(), null), C(c, (() => {
694
- var h = j(() => n() === "error");
695
- return () => h() && N(oe, {});
696
- })(), null), I((h) => {
697
- var z = `width:${t.size}px;height:${t.size}px"`, Z = te(n()), Q = st(n()), Y = n() === "recording", tt = n() === "processing";
698
- return h.e = Tt(c, z, h.e), Z !== h.t && k(c, "title", h.t = Z), Q !== h.a && k(c, "aria-label", h.a = Q), Y !== h.o && k(c, "aria-pressed", h.o = Y), tt !== h.i && k(c, "aria-busy", h.i = tt), h;
685
+ var d = Ht(), w = d.firstChild, y = w.nextSibling, c = y.nextSibling;
686
+ return v(w, qt), v(y, () => lt(n())), c.$$click = wt, v(c, (() => {
687
+ var h = N(() => n() === "idle");
688
+ return () => h() && M(ne, {});
689
+ })(), null), v(c, (() => {
690
+ var h = N(() => n() === "recording");
691
+ return () => h() && M(re, {});
692
+ })(), null), v(c, (() => {
693
+ var h = N(() => n() === "processing");
694
+ return () => h() && M(oe, {});
695
+ })(), null), v(c, (() => {
696
+ var h = N(() => n() === "error");
697
+ return () => h() && M(ie, {});
698
+ })(), null), R((h) => {
699
+ var z = `width:${t.size}px;height:${t.size}px"`, Q = ee(n()), Y = lt(n()), tt = n() === "recording", et = n() === "processing";
700
+ return h.e = Ot(c, z, h.e), Q !== h.t && k(c, "title", h.t = Q), Y !== h.a && k(c, "aria-label", h.a = Y), tt !== h.o && k(c, "aria-pressed", h.o = tt), et !== h.i && k(c, "aria-busy", h.i = et), h;
699
701
  }, {
700
702
  e: void 0,
701
703
  t: void 0,
702
704
  a: void 0,
703
705
  o: void 0,
704
706
  i: void 0
705
- }), f;
707
+ }), d;
706
708
  })();
707
709
  });
708
- const te = (t) => {
710
+ const ee = (t) => {
709
711
  switch (t) {
710
712
  case "idle":
711
- return `Start dictation (${v})`;
713
+ return `Start dictation (${m})`;
712
714
  case "recording":
713
- return `Stop dictation (${v})`;
715
+ return `Stop dictation (${m})`;
714
716
  case "processing":
715
- return `Stop processing (${v})`;
717
+ return `Stop processing (${m})`;
716
718
  case "error":
717
- return `Click to reset (${v})`;
719
+ return `Click to reset (${m})`;
718
720
  }
719
- }, st = (t) => {
721
+ }, lt = (t) => {
720
722
  switch (t) {
721
723
  case "idle":
722
- return `Start dictation (${v})`;
724
+ return `Start dictation (${m})`;
723
725
  case "recording":
724
- return `Dictation in progress. Click to stop it (${v})`;
726
+ return `Dictation in progress. Click to stop it (${m})`;
725
727
  case "processing":
726
- return `Processing dictation. Click to cancel it (${v})`;
728
+ return `Processing dictation. Click to cancel it (${m})`;
727
729
  case "error":
728
- return `Dictation error. Click to reset (${v})`;
730
+ return `Dictation error. Click to reset (${m})`;
729
731
  }
730
732
  }, A = (t, e, n) => {
731
733
  t.dispatchEvent(new CustomEvent(e, {
@@ -733,5 +735,5 @@ const te = (t) => {
733
735
  bubbles: !0,
734
736
  composed: !0
735
737
  }));
736
- }, ee = () => Ht(), ne = () => Gt(), re = () => Wt(), oe = () => Xt();
738
+ }, ne = () => Gt(), re = () => Wt(), oe = () => Xt(), ie = () => Jt();
737
739
  $t(["click"]);
@@ -3,7 +3,8 @@ const a = 30, n = !0, e = !1, o = [
3
3
  "textarea[data-dictate-button-on]:not([data-dictate-button-enabled])",
4
4
  'input[type="text"][data-dictate-button-on]:not([data-dictate-button-enabled])',
5
5
  'input[type="search"][data-dictate-button-on]:not([data-dictate-button-enabled])',
6
- "input[data-dictate-button-on]:not([type]):not([data-dictate-button-enabled])"
6
+ "input[data-dictate-button-on]:not([type]):not([data-dictate-button-enabled])",
7
+ "*[contenteditable][data-dictate-button-on]:not([data-dictate-button-enabled])"
7
8
  ].join(",");
8
9
  t(o, {
9
10
  buttonSize: a,
@@ -3,7 +3,8 @@ const a = 30, n = !0, o = !1, e = [
3
3
  "textarea:not([data-dictate-button-off]):not([data-dictate-button-enabled])",
4
4
  'input[type="text"]:not([data-dictate-button-off]):not([data-dictate-button-enabled])',
5
5
  'input[type="search"]:not([data-dictate-button-off]):not([data-dictate-button-enabled])',
6
- "input:not([type]):not([data-dictate-button-off]):not([data-dictate-button-enabled])"
6
+ "input:not([type]):not([data-dictate-button-off]):not([data-dictate-button-enabled])",
7
+ "*[contenteditable]:not([data-dictate-button-off]):not([data-dictate-button-enabled])"
7
8
  ].join(",");
8
9
  t(e, {
9
10
  buttonSize: a,
@@ -1,40 +1,40 @@
1
1
  function v(t, c = {}) {
2
- const { buttonSize: i = 30, verbose: o = !1, customApiEndpoint: r } = c, d = document.querySelectorAll(t);
3
- for (const n of d) {
4
- if (n.hasAttribute("data-dictate-button-enabled")) continue;
5
- const u = n.parentNode;
6
- if (!n.isConnected || !u) {
7
- o && console.debug("injectDictateButton: skipping detached field", n);
2
+ const { buttonSize: n = 30, verbose: i = !1, customApiEndpoint: a } = c, l = document.querySelectorAll(t);
3
+ for (const e of l) {
4
+ if (e.hasAttribute("data-dictate-button-enabled")) continue;
5
+ const p = e.parentNode;
6
+ if (!e.isConnected || !p) {
7
+ i && console.debug("injectDictateButton: skipping detached field", e);
8
8
  continue;
9
9
  }
10
- n.setAttribute("data-dictate-button-enabled", "");
11
- const a = document.createElement("div");
12
- a.style.position = "relative";
13
- const l = getComputedStyle(n), g = l.display === "block";
14
- a.style.display = g ? "block" : "inline-block", a.style.width = g ? "100%" : "auto", a.style.color = "inherit", a.classList.add("dictate-button-wrapper"), u.insertBefore(a, n), a.appendChild(n), a.style.margin = l.margin, n.style.margin = "0", n.style.boxSizing = "border-box";
15
- const p = y(l);
16
- n.style.paddingRight = `${i + p * 2}px`;
17
- const e = document.createElement("dictate-button");
18
- e.size = i, e.style.position = "absolute", e.style.right = "0", e.style.top = m(
19
- a,
20
- l,
21
- n.tagName,
22
- i
23
- ) + "px", e.style.marginRight = e.style.marginLeft = `${p}px`, e.style.marginTop = "0", e.style.marginBottom = "0", r && (e.apiEndpoint = r), e.language = h(), e.addEventListener("recording:started", (s) => {
24
- o && console.debug("recording:started", s);
25
- }), e.addEventListener("recording:stopped", (s) => {
26
- o && console.debug("recording:stopped", s);
27
- }), e.addEventListener("recording:failed", (s) => {
28
- o && console.debug("recording:failed", s), b(n);
29
- }), e.addEventListener("transcribing:started", (s) => {
30
- o && console.debug("transcribing:started", s);
31
- }), e.addEventListener("transcribing:finished", (s) => {
32
- o && console.debug("transcribing:finished", s);
33
- const f = s.detail;
34
- T(n, f);
35
- }), e.addEventListener("transcribing:failed", (s) => {
36
- o && console.debug("transcribing:failed", s), b(n);
37
- }), a.appendChild(e);
10
+ e.setAttribute("data-dictate-button-enabled", "");
11
+ const r = document.createElement("div");
12
+ r.style.position = "relative";
13
+ const g = getComputedStyle(e), s = g.display === "block";
14
+ r.style.display = s ? "block" : "inline-block", r.style.width = s ? "100%" : "auto", r.style.color = "inherit", r.classList.add("dictate-button-wrapper"), p.insertBefore(r, e), r.appendChild(e), r.style.margin = g.margin, e.style.margin = "0", e.style.boxSizing = "border-box";
15
+ const u = m(g);
16
+ e.style.paddingRight = `${n + u * 2}px`;
17
+ const o = document.createElement("dictate-button");
18
+ o.size = n, o.style.position = "absolute", o.style.right = "0", o.style.top = E(
19
+ r,
20
+ g,
21
+ e.tagName,
22
+ n
23
+ ) + "px", o.style.marginRight = o.style.marginLeft = `${u}px`, o.style.marginTop = "0", o.style.marginBottom = "0", a && (o.apiEndpoint = a), o.language = h(), o.addEventListener("recording:started", (d) => {
24
+ i && console.debug("recording:started", d);
25
+ }), o.addEventListener("recording:stopped", (d) => {
26
+ i && console.debug("recording:stopped", d);
27
+ }), o.addEventListener("recording:failed", (d) => {
28
+ i && console.debug("recording:failed", d), f(e);
29
+ }), o.addEventListener("transcribing:started", (d) => {
30
+ i && console.debug("transcribing:started", d);
31
+ }), o.addEventListener("transcribing:finished", (d) => {
32
+ i && console.debug("transcribing:finished", d);
33
+ const b = d.detail;
34
+ T(e, b);
35
+ }), o.addEventListener("transcribing:failed", (d) => {
36
+ i && console.debug("transcribing:failed", d), f(e);
37
+ }), r.appendChild(o);
38
38
  }
39
39
  }
40
40
  function h() {
@@ -46,39 +46,93 @@ function h() {
46
46
  return t.split(/[-_]/)[0].toLowerCase();
47
47
  }
48
48
  }
49
- function m(t, c, i, o) {
50
- if (i.toLowerCase() === "textarea") {
51
- const d = parseFloat(c.paddingTop || "0");
52
- return Math.max(4, d);
49
+ function E(t, c, n, i) {
50
+ if (n.toLowerCase() === "textarea") {
51
+ const l = parseFloat(c.paddingTop || "0");
52
+ return Math.max(4, l);
53
53
  }
54
- const r = Math.round(t.clientHeight / 2 - o / 2);
55
- return Math.max(4, r);
54
+ const a = Math.round(t.clientHeight / 2 - i / 2);
55
+ return Math.max(4, a);
56
56
  }
57
- function y(t) {
57
+ function m(t) {
58
58
  const c = parseFloat(t.paddingRight || "0");
59
59
  return Math.max(c, 4);
60
60
  }
61
61
  function T(t, c) {
62
- const i = typeof c == "string" ? c.trim() : String(c ?? "").trim();
63
- if (i.length === 0)
64
- return;
65
- const o = t.selectionStart ?? 0, r = t.selectionEnd ?? 0, d = o > 0 ? t.value.charAt(o - 1) : "", n = d && !/\s/.test(d), u = r < t.value.length ? t.value.charAt(r) : "", a = u && !/\s/.test(u), l = (n ? " " : "") + i + (a ? " " : ""), g = o + l.length, p = typeof t.scrollTop == "number" ? t.scrollTop : null;
62
+ const n = typeof c == "string" ? c.trim() : String(c ?? "").trim();
63
+ n.length !== 0 && (y(t) ? N(t, n) : C(t, n), t.dispatchEvent(new Event("input", { bubbles: !0, composed: !0 })), f(t));
64
+ }
65
+ function f(t) {
66
+ try {
67
+ t.focus({ preventScroll: !0 });
68
+ } catch {
69
+ t.focus();
70
+ }
71
+ }
72
+ function y(t) {
73
+ return t.isContentEditable;
74
+ }
75
+ function C(t, c) {
76
+ const n = t.selectionStart ?? 0, i = t.selectionEnd ?? 0, a = n > 0 ? t.value.charAt(n - 1) : "", l = a && !/\s/.test(a), e = i < t.value.length ? t.value.charAt(i) : "", p = e && !/\s/.test(e), r = (l ? " " : "") + c + (p ? " " : ""), g = n + r.length, s = typeof t.scrollTop == "number" ? t.scrollTop : null;
66
77
  if (typeof t.setRangeText == "function")
67
- t.setRangeText(l, o, r, "end");
78
+ t.setRangeText(r, n, i, "end");
68
79
  else {
69
- t.value = t.value.substring(0, o) + l + t.value.substring(r);
80
+ t.value = t.value.substring(0, n) + r + t.value.substring(i);
70
81
  try {
71
82
  t.selectionStart = g, t.selectionEnd = g;
72
83
  } catch {
73
84
  }
74
85
  }
75
- p !== null && (t.scrollTop = p), t.dispatchEvent(new Event("input", { bubbles: !0, composed: !0 })), b(t);
86
+ s !== null && (t.scrollTop = s);
76
87
  }
77
- function b(t) {
78
- try {
79
- t.focus({ preventScroll: !0 });
80
- } catch {
81
- t.focus();
88
+ function N(t, c) {
89
+ const n = window.getSelection();
90
+ if (!(n && n.rangeCount > 0 && t.contains(n.getRangeAt(0).commonAncestorContainer))) {
91
+ f(t);
92
+ const l = document.createRange();
93
+ l.selectNodeContents(t), l.collapse(!1), n?.removeAllRanges(), n?.addRange(l);
94
+ }
95
+ const a = n?.getRangeAt(0);
96
+ if (a) {
97
+ const l = a.cloneRange(), e = a.cloneRange();
98
+ let p = !1;
99
+ l.collapse(!0);
100
+ try {
101
+ l.setStart(a.startContainer, 0);
102
+ const s = l.toString(), u = s.length > 0 ? s.charAt(s.length - 1) : "";
103
+ p = u !== "" && !/\s/.test(u);
104
+ } catch (s) {
105
+ console.debug(
106
+ "insertIntoContentEditable: Error checking text before cursor:",
107
+ s
108
+ );
109
+ }
110
+ let r = !1;
111
+ e.collapse(!1);
112
+ try {
113
+ if (e.endContainer.nodeType === Node.TEXT_NODE) {
114
+ const o = e.endContainer;
115
+ e.setEnd(o, o.length);
116
+ } else if (e.endContainer.nodeType === Node.ELEMENT_NODE) {
117
+ const o = e.endContainer;
118
+ o.childNodes.length > e.endOffset && e.setEnd(o, e.endOffset + 1);
119
+ }
120
+ const s = e.toString(), u = s.length > 0 ? s.charAt(0) : "";
121
+ r = u !== "" && !/\s/.test(u);
122
+ } catch (s) {
123
+ console.debug(
124
+ "insertIntoContentEditable: Error checking text after cursor:",
125
+ s
126
+ );
127
+ }
128
+ const g = (p ? " " : "") + c + (r ? " " : "");
129
+ try {
130
+ a.deleteContents();
131
+ const s = document.createTextNode(g);
132
+ a.insertNode(s), a.setStartAfter(s), a.setEndAfter(s), n?.removeAllRanges(), n?.addRange(a);
133
+ } catch (s) {
134
+ console.debug("insertIntoContentEditable: Error inserting text:", s), f(t), t.textContent = (t.textContent || "") + g;
135
+ }
82
136
  }
83
137
  }
84
138
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dictate-button",
3
- "version": "1.4.1",
3
+ "version": "1.5.1",
4
4
  "description": "Dictate Button (Web Component)",
5
5
  "keywords": [
6
6
  "custom-element",
@@ -64,19 +64,19 @@
64
64
  },
65
65
  "devDependencies": {
66
66
  "prettier": "^3.6.2",
67
- "typescript": "^5.9.2",
68
- "vite": "^7.1.5",
67
+ "typescript": "^5.9.3",
68
+ "vite": "^7.1.9",
69
69
  "vite-plugin-dts": "^4.5.4",
70
- "vite-plugin-solid": "^2.11.8",
71
- "vite-plugin-static-copy": "^3.1.2"
70
+ "vite-plugin-solid": "^2.11.9",
71
+ "vite-plugin-static-copy": "^3.1.3"
72
72
  },
73
- "homepage": "https://github.com/kkomelin/dictate-button",
73
+ "homepage": "https://github.com/dictate-button/dictate-button",
74
74
  "repository": {
75
75
  "type": "git",
76
- "url": "https://github.com/kkomelin/dictate-button.git"
76
+ "url": "https://github.com/dictate-button/dictate-button.git"
77
77
  },
78
78
  "bugs": {
79
- "url": "https://github.com/kkomelin/dictate-button/issues"
79
+ "url": "https://github.com/dictate-button/dictate-button/issues"
80
80
  },
81
81
  "scripts": {
82
82
  "build": "vite build",