@burger-editor/local 4.0.0-alpha.50 → 4.0.0-alpha.52

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
@@ -286,6 +286,125 @@ export default {
286
286
 
287
287
  カスタムアイテムの作成方法については、[@burger-editor/core のREADME](../core/README.md#カスタムアイテムの作成) を参照してください。
288
288
 
289
+ ## APIエンドポイント
290
+
291
+ ### Health Check API
292
+
293
+ BurgerEditorローカルサーバーが起動中かどうかを確認するためのヘルスチェックAPIを提供しています。
294
+
295
+ #### エンドポイント
296
+
297
+ ```
298
+ GET /api/health
299
+ ```
300
+
301
+ #### レスポンス
302
+
303
+ ```json
304
+ {
305
+ "status": "ok",
306
+ "timestamp": 1737446400000
307
+ }
308
+ ```
309
+
310
+ - `status` (string): サーバーの状態。常に `"ok"` を返します
311
+ - `timestamp` (number): レスポンス生成時のタイムスタンプ(ミリ秒)
312
+
313
+ #### 使用例
314
+
315
+ curlコマンドで確認:
316
+
317
+ ```bash
318
+ curl http://localhost:3000/api/health
319
+ ```
320
+
321
+ JavaScriptで確認:
322
+
323
+ ```javascript
324
+ const response = await fetch('http://localhost:3000/api/health');
325
+ const data = await response.json();
326
+ console.log(data.status); // "ok"
327
+ ```
328
+
329
+ #### クライアント側の自動ヘルスチェック
330
+
331
+ BurgerEditorクライアントは、このAPIを使用してサーバーの接続状態を自動的に監視します。ヘルスチェックの動作は設定ファイルの `healthCheck` オプションでカスタマイズできます:
332
+
333
+ ```javascript
334
+ export default {
335
+ documentRoot: './src',
336
+ assetsRoot: './public',
337
+ healthCheck: {
338
+ enabled: true, // ヘルスチェックを有効化(デフォルト: true)
339
+ interval: 10000, // チェック間隔(ミリ秒)(デフォルト: 10000)
340
+ retryCount: 3, // リトライ回数(デフォルト: 3)
341
+ },
342
+ };
343
+ ```
344
+
345
+ 接続が失われると、クライアントは自動的にリトライを行い、`bge:server-offline` および `bge:server-online` イベントを発行します。
346
+
347
+ ## サーバー設定とヘルスチェックAPI
348
+
349
+ ### getUserConfig()
350
+
351
+ サーバー設定を取得する関数です。`burgereditor.config.js` から設定を読み込み、デフォルト値とマージして返します。
352
+
353
+ ```typescript
354
+ import { getUserConfig } from '@burger-editor/local/get-user-config';
355
+
356
+ const config = await getUserConfig();
357
+ console.log(config.host, config.port); // 'localhost' 5255
358
+ ```
359
+
360
+ **戻り値:** `Promise<LocalServerConfig>`
361
+
362
+ ### createHealthChecker()
363
+
364
+ BurgerEditor local サーバーのヘルスチェックを行う `HealthMonitor` インスタンスを作成します。ブラウザ環境で動作し、サーバーの `/api/health` エンドポイントを定期的にチェックします。
365
+
366
+ ```typescript
367
+ import { getUserConfig } from '@burger-editor/local/get-user-config';
368
+ import { createHealthChecker } from '@burger-editor/local/create-health-checker';
369
+
370
+ const config = await getUserConfig();
371
+ const healthMonitor = createHealthChecker(config);
372
+
373
+ // オプション: カスタムコールバックを設定
374
+ healthMonitor.onOffline = (timestamp) => {
375
+ console.log('Server went offline at', new Date(timestamp));
376
+ // カスタム処理(例: ユーザーに通知を表示)
377
+ };
378
+
379
+ healthMonitor.onOnline = (timestamp) => {
380
+ console.log('Server came online at', new Date(timestamp));
381
+ // カスタム処理(例: 通知を非表示)
382
+ };
383
+
384
+ // 監視を開始
385
+ healthMonitor.start();
386
+
387
+ // 現在の状態を確認
388
+ console.log('Is online?', healthMonitor.isOnline);
389
+
390
+ // 監視を停止
391
+ // healthMonitor.stop();
392
+ ```
393
+
394
+ **パラメータ:**
395
+
396
+ - `config` (LocalServerConfig): `getUserConfig()` で取得したサーバー設定
397
+
398
+ **戻り値:** `HealthMonitor` - ヘルスモニターインスタンス
399
+
400
+ **HealthMonitor API:**
401
+
402
+ - `start()`: 監視を開始
403
+ - `stop()`: 監視を停止
404
+ - `isOnline` (getter): 現在のオンライン状態(boolean)
405
+ - `onOffline` (setter): サーバーがオフラインになった時のコールバック
406
+ - `onOnline` (setter): サーバーがオンラインになった時のコールバック
407
+
289
408
  ## プログラマティックAPI
290
409
 
291
410
  `@burger-editor/local` は、Honoサーバーと同じファイルアップロード機能をプログラムから使用できるAPIを提供しています。
package/dist/client.js CHANGED
@@ -1261,10 +1261,12 @@ let NoHTMLElementError$1 = class NoHTMLElementError extends Error {
1261
1261
  * // => { absNumber: 150, relNumber: 0.75, ... }
1262
1262
  */
1263
1263
  function updateRatio(obj, propName, value) {
1264
- // Create a shallow copy
1265
- const updated = { ...obj };
1266
- // Update the specified property
1267
- updated[propName] = value;
1264
+ const updated = {
1265
+ // Create a shallow copy
1266
+ ...obj,
1267
+ // Update the specified property
1268
+ [propName]: value,
1269
+ };
1268
1270
  // Recalculate dependent properties based on which property was updated
1269
1271
  switch (propName) {
1270
1272
  case 'absNumber': {
@@ -1294,7 +1296,7 @@ var style$b = "/* No Styling */\n";
1294
1296
  var template$b = "<a href=\"\" data-kind=\"primary\" data-before-icon=\"none\" data-after-icon=\"none\" data-bge=\"link:href, target:target, kind:data-kind, before-icon:data-before-icon, after-icon:data-after-icon\">\n\t<div>\n\t\t<span data-bge=\"text\">ボタン</span>\n\t\t<span data-bge=\"subtext\">サブテキスト</span>\n\t</div>\n</a>\n";
1295
1297
 
1296
1298
  var button = createItem$1({
1297
- version: "4.0.0-alpha.49",
1299
+ version: "4.0.0-alpha.51",
1298
1300
  name: "button",
1299
1301
  template: template$b,
1300
1302
  style: style$b,
@@ -1350,7 +1352,7 @@ var style$a = "/* No Styling */\n";
1350
1352
  var template$a = "<details data-bge=\"open:open\">\n\t<summary data-bge=\"summary\">折りたたみコンテンツ</summary>\n\t<div data-bge=\"content\"><p>内容を入力してください</p></div>\n</details>\n";
1351
1353
 
1352
1354
  var details = createItem$1({
1353
- version: "4.0.0-alpha.49",
1355
+ version: "4.0.0-alpha.51",
1354
1356
  name: "details",
1355
1357
  template: template$a,
1356
1358
  style: style$a,
@@ -1364,7 +1366,7 @@ var style$9 = "[data-bgi='download-file'] {\n\t[data-bge*='size'] {\n\t\t&::befo
1364
1366
  var template$9 = "<a href=\"./files/bgeditor/bg-sample.pdf\" target=\"_blank\" data-bge=\"path:href, download:download\">\n\t<div>\n\t\t<span data-bge=\"name\">サンプルダウンロードファイル</span>\n\t\t<span data-bge=\"formated-size, size:data-size\" data-size=\"138158\">134.92kB</span>\n\t</div>\n</a>\n";
1365
1367
 
1366
1368
  var downloadFile = createItem$1({
1367
- version: "4.0.0-alpha.49",
1369
+ version: "4.0.0-alpha.51",
1368
1370
  name: "download-file",
1369
1371
  template: template$9,
1370
1372
  style: style$9,
@@ -1403,7 +1405,7 @@ var style$8 = "[data-bgi='google-maps'] {\n\tdiv {\n\t\tinline-size: 100%;\n\t\t
1403
1405
  var template$8 = "<div data-lat=\"35.681382\" data-lng=\"139.766084\" data-zoom=\"16\" data-bge=\"lat:data-lat, lng:data-lng, zoom:data-zoom\">\n\t<img data-bge=\"img:src\" src=\"https://maps.google.com/maps/api/staticmap?center=35.681382,139.766084&amp;zoom=16&amp;size=640x400&amp;markers=color:red|color:red|35.681382,139.766084&amp;scale=2&amp;key=%googleMapsApiKey%\" width=\"8\" height=\"5\" alt=\"Google Maps\" />\n</div>\n<a href=\"https://maps.apple.com/?q=35.681382,139.766084\" data-bge=\"url:href\" target=\"_blank\"><span>アプリで開く</span></a>\n";
1404
1406
 
1405
1407
  var googleMaps = createItem$1({
1406
- version: "4.0.0-alpha.49",
1408
+ version: "4.0.0-alpha.51",
1407
1409
  name: "google-maps",
1408
1410
  template: template$8,
1409
1411
  style: style$8,
@@ -1538,7 +1540,7 @@ var style$7 = "[data-bgi='hr'] {\n\t--inline-size: 100%;\n\t--border-color: #000
1538
1540
  var template$7 = "<div data-bgi-hr-kind=\"primary\" data-bge=\"kind:data-bgi-hr-kind\">\n\t<hr />\n</div>\n";
1539
1541
 
1540
1542
  var hr = createItem$1({
1541
- version: "4.0.0-alpha.49",
1543
+ version: "4.0.0-alpha.51",
1542
1544
  name: "hr",
1543
1545
  template: template$7,
1544
1546
  style: style$7,
@@ -1628,7 +1630,7 @@ function createWidthState() {
1628
1630
 
1629
1631
  const ORIGIN = "__org";
1630
1632
  var image = createItem$1({
1631
- version: "4.0.0-alpha.49",
1633
+ version: "4.0.0-alpha.51",
1632
1634
  name: "image",
1633
1635
  template: template$6,
1634
1636
  style: style$6,
@@ -1826,7 +1828,7 @@ var style$5 = "[data-bgi='import'] {\n\tbge-import {\n\t\t&::before {\n\t\t\tfon
1826
1828
  var template$5 = "<bge-import data-bge=\":src\" src=\"\"></bge-import>\n";
1827
1829
 
1828
1830
  var importItem = createItem$1({
1829
- version: "4.0.0-alpha.49",
1831
+ version: "4.0.0-alpha.51",
1830
1832
  name: "import",
1831
1833
  template: template$5,
1832
1834
  style: style$5,
@@ -1840,7 +1842,7 @@ var style$4 = "/* No Styling */\n";
1840
1842
  var template$4 = "<div data-bge=\":scrollable\" data-bge-scrollable=\"false\">\n\t<table>\n\t\t<caption data-bge=\"caption\">\n\t\t\tキャプションを入力してください\n\t\t</caption>\n\t\t<tbody data-bge-list>\n\t\t\t<tr>\n\t\t\t\t<th data-bge=\"th\">表組の見出し</th>\n\t\t\t\t<td data-bge=\"td\">表組の内容を入力してください</td>\n\t\t\t</tr>\n\t\t</tbody>\n\t</table>\n</div>\n";
1841
1843
 
1842
1844
  var table = createItem$1({
1843
- version: "4.0.0-alpha.49",
1845
+ version: "4.0.0-alpha.51",
1844
1846
  name: "table",
1845
1847
  template: template$4,
1846
1848
  style: style$4,
@@ -1868,7 +1870,7 @@ var style$3 = "/* No Styling */\n";
1868
1870
  var template$3 = "<h2 data-bge=\"title-h2\">見出しを入力してください</h2>\n";
1869
1871
 
1870
1872
  var titleH2 = createItem$1({
1871
- version: "4.0.0-alpha.49",
1873
+ version: "4.0.0-alpha.51",
1872
1874
  name: "title-h2",
1873
1875
  template: template$3,
1874
1876
  style: style$3,
@@ -1882,7 +1884,7 @@ var style$2 = "/* No Styling */\n";
1882
1884
  var template$2 = "<h3 data-bge=\"title-h3\">見出しを入力してください</h3>\n";
1883
1885
 
1884
1886
  var titleH3 = createItem$1({
1885
- version: "4.0.0-alpha.49",
1887
+ version: "4.0.0-alpha.51",
1886
1888
  name: "title-h3",
1887
1889
  template: template$2,
1888
1890
  style: style$2,
@@ -1896,7 +1898,7 @@ var style$1 = "/* No Styling */\n";
1896
1898
  var template$1 = "<div data-bge=\"wysiwyg\"><p>本文を入力してください</p></div>\n";
1897
1899
 
1898
1900
  var wysiwyg = createItem$1({
1899
- version: "4.0.0-alpha.49",
1901
+ version: "4.0.0-alpha.51",
1900
1902
  name: "wysiwyg",
1901
1903
  template: template$1,
1902
1904
  style: style$1,
@@ -1911,7 +1913,7 @@ var template = "<div data-id=\"3KtWfp0UopM\" data-title=\"YouTube動画\" data-w
1911
1913
 
1912
1914
  const FALLBACK_TITLE = "YouTube\u52D5\u753B";
1913
1915
  var youtube = createItem$1({
1914
- version: "4.0.0-alpha.49",
1916
+ version: "4.0.0-alpha.51",
1915
1917
  name: "youtube",
1916
1918
  template,
1917
1919
  style: style$c,
@@ -2094,6 +2096,14 @@ function importOptions(el, options) {
2094
2096
  if (style2) {
2095
2097
  importStyleOptions(el, style2);
2096
2098
  }
2099
+ const groups = el.querySelectorAll("[data-bge-group]");
2100
+ for (const group of groups) {
2101
+ if (containerProps?.linkarea) {
2102
+ group.dataset.bgeLinkarea = "";
2103
+ } else {
2104
+ delete group.dataset.bgeLinkarea;
2105
+ }
2106
+ }
2097
2107
  }
2098
2108
  async function createPlainStructuredBlockElement(data, createItemElement) {
2099
2109
  const container = document.createElement("div");
@@ -2163,7 +2173,8 @@ function exportContainerProps(containerPropsQuery) {
2163
2173
  wrap: type === "inline" ? findValueFromArray(options, ["wrap", "nowrap"]) : null,
2164
2174
  columns: type === "grid" ? Number.parseInt(findValuePatternFromArray(options, /[1-9]\d*/) ?? "", 10) ?? 1 : null,
2165
2175
  float: type === "float" ? findValueFromArray(options, ["start", "end"]) : null,
2166
- frameSemantics: findValueFromArray(options, ["div", "ul", "ol"]) ?? "div"
2176
+ frameSemantics: findValueFromArray(options, ["div", "ul", "ol"]) ?? "div",
2177
+ linkarea: false
2167
2178
  };
2168
2179
  }
2169
2180
  function exportStyleOptions(el) {
@@ -2187,8 +2198,13 @@ function exportOptions(el) {
2187
2198
  const classList = [...el.classList];
2188
2199
  const id = el.id.replace(/^bge-/, "").trim() || null;
2189
2200
  const style2 = exportStyleOptions(el);
2201
+ const groups = el.querySelectorAll("[data-bge-group]");
2202
+ const hasLinkarea = [...groups].some((group) => Object.hasOwn(group.dataset, "bgeLinkarea"));
2190
2203
  return {
2191
- containerProps,
2204
+ containerProps: {
2205
+ ...containerProps,
2206
+ linkarea: hasLinkarea
2207
+ },
2192
2208
  classList,
2193
2209
  id,
2194
2210
  style: style2
@@ -5671,6 +5687,7 @@ class BlockOptionsDialog extends EditorDialog {
5671
5687
  const float = formData.get("bge-options-float");
5672
5688
  const classes = formData.get("bge-options-classes");
5673
5689
  const id = formData.get("bge-options-id");
5690
+ const linkarea = formData.get("bge-options-linkarea");
5674
5691
  const styles = formData.keys().toArray().filter((key) => key.startsWith("bge-options-style-")).map((key) => {
5675
5692
  const propName = formData.get(key);
5676
5693
  const category = key.replace("bge-options-style-", "");
@@ -5685,7 +5702,8 @@ class BlockOptionsDialog extends EditorDialog {
5685
5702
  autoRepeat: autoRepeat ?? "fixed",
5686
5703
  justify,
5687
5704
  align,
5688
- float
5705
+ float,
5706
+ linkarea: linkarea === "true"
5689
5707
  },
5690
5708
  classList: classes?.toString().split(/\s+/).map((cls) => cls.trim()).filter((cls) => !!cls) ?? [],
5691
5709
  id: id?.toString().trim() || null,
@@ -6293,10 +6311,11 @@ class HealthMonitor {
6293
6311
  return Promise.resolve(true);
6294
6312
  };
6295
6313
  #enabled;
6296
- #engine;
6297
6314
  #failureCount = 0;
6298
6315
  #interval;
6299
6316
  #isOnline = true;
6317
+ #onOffline;
6318
+ #onOnline;
6300
6319
  #retryCount;
6301
6320
  #timeoutId = null;
6302
6321
  /**
@@ -6305,12 +6324,13 @@ class HealthMonitor {
6305
6324
  get isOnline() {
6306
6325
  return this.#isOnline;
6307
6326
  }
6308
- constructor(engine, options) {
6309
- this.#engine = engine;
6327
+ constructor(options) {
6310
6328
  this.#enabled = options?.enabled ?? false;
6311
6329
  this.#interval = options?.interval ?? 1e4;
6312
6330
  this.#retryCount = options?.retryCount ?? 3;
6313
6331
  this.#checkHealth = options?.checkHealth ?? this.#defaultHealthCheck;
6332
+ this.#onOffline = options?.onOffline;
6333
+ this.#onOnline = options?.onOnline;
6314
6334
  }
6315
6335
  /**
6316
6336
  * Start health monitoring
@@ -6347,15 +6367,15 @@ class HealthMonitor {
6347
6367
  * Dispatch server offline event
6348
6368
  */
6349
6369
  #dispatchServerOfflineEvent() {
6350
- const event2 = createBgeEvent("bge:server-offline", { timestamp: Date.now() });
6351
- this.#engine.el.dispatchEvent(event2);
6370
+ const timestamp = Date.now();
6371
+ this.#onOffline?.(timestamp);
6352
6372
  }
6353
6373
  /**
6354
6374
  * Dispatch server online event
6355
6375
  */
6356
6376
  #dispatchServerOnlineEvent() {
6357
- const event2 = createBgeEvent("bge:server-online", { timestamp: Date.now() });
6358
- this.#engine.el.dispatchEvent(event2);
6377
+ const timestamp = Date.now();
6378
+ this.#onOnline?.(timestamp);
6359
6379
  }
6360
6380
  /**
6361
6381
  * Handle health check failure
@@ -6698,7 +6718,17 @@ class BurgerEditorEngine {
6698
6718
  blockClipboard: "bge-copied-block",
6699
6719
  ...options.storageKey
6700
6720
  };
6701
- this.#healthMonitor = new HealthMonitor(this, options.healthCheck);
6721
+ this.#healthMonitor = new HealthMonitor({
6722
+ ...options.healthCheck,
6723
+ onOffline: (timestamp) => {
6724
+ const event2 = createBgeEvent("bge:server-offline", { timestamp });
6725
+ this.el.dispatchEvent(event2);
6726
+ },
6727
+ onOnline: (timestamp) => {
6728
+ const event2 = createBgeEvent("bge:server-online", { timestamp });
6729
+ this.el.dispatchEvent(event2);
6730
+ }
6731
+ });
6702
6732
  this.css = {
6703
6733
  stylesheets: options.config.stylesheets ?? [],
6704
6734
  classList: options.config.classList ?? [],
@@ -14909,12 +14939,12 @@ class NodeViewDesc extends ViewDesc {
14909
14939
  let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
14910
14940
  iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
14911
14941
  if (widget.spec.marks)
14912
- updater.syncToMarks(widget.spec.marks, inline, view);
14942
+ updater.syncToMarks(widget.spec.marks, inline, view, i);
14913
14943
  else if (widget.type.side >= 0 && !insideNode)
14914
- updater.syncToMarks(i == this.node.childCount ? Mark$1.none : this.node.child(i).marks, inline, view);
14944
+ updater.syncToMarks(i == this.node.childCount ? Mark$1.none : this.node.child(i).marks, inline, view, i);
14915
14945
  updater.placeWidget(widget, view, off);
14916
14946
  }, (child2, outerDeco, innerDeco, i) => {
14917
- updater.syncToMarks(child2.marks, inline, view);
14947
+ updater.syncToMarks(child2.marks, inline, view, i);
14918
14948
  let compIndex;
14919
14949
  if (updater.findNodeMatch(child2, outerDeco, innerDeco, i)) ;
14920
14950
  else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child2.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child2, outerDeco, innerDeco, compIndex, view)) ;
@@ -14924,7 +14954,7 @@ class NodeViewDesc extends ViewDesc {
14924
14954
  }
14925
14955
  off += child2.nodeSize;
14926
14956
  });
14927
- updater.syncToMarks([], inline, view);
14957
+ updater.syncToMarks([], inline, view, 0);
14928
14958
  if (this.node.isTextblock)
14929
14959
  updater.addTextblockHacks();
14930
14960
  updater.destroyRest();
@@ -15290,7 +15320,7 @@ class ViewTreeUpdater {
15290
15320
  }
15291
15321
  // Sync the current stack of mark descs with the given array of
15292
15322
  // marks, reusing existing mark descs when possible.
15293
- syncToMarks(marks, inline, view) {
15323
+ syncToMarks(marks, inline, view, parentIndex) {
15294
15324
  let keep = 0, depth = this.stack.length >> 1;
15295
15325
  let maxKeep = Math.min(depth, marks.length);
15296
15326
  while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false)
@@ -15304,8 +15334,10 @@ class ViewTreeUpdater {
15304
15334
  }
15305
15335
  while (depth < marks.length) {
15306
15336
  this.stack.push(this.top, this.index + 1);
15307
- let found2 = -1;
15308
- for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {
15337
+ let found2 = -1, scanTo = this.top.children.length;
15338
+ if (parentIndex < this.preMatch.index)
15339
+ scanTo = Math.min(this.index + 3, scanTo);
15340
+ for (let i = this.index; i < scanTo; i++) {
15309
15341
  let next = this.top.children[i];
15310
15342
  if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) {
15311
15343
  found2 = i;
@@ -16423,6 +16455,7 @@ class InputState {
16423
16455
  this.compositionNodes = [];
16424
16456
  this.compositionEndedAt = -2e8;
16425
16457
  this.compositionID = 1;
16458
+ this.badSafariComposition = false;
16426
16459
  this.compositionPendingChanges = 0;
16427
16460
  this.domChangeCount = 0;
16428
16461
  this.eventHandlers = /* @__PURE__ */ Object.create(null);
@@ -16812,7 +16845,9 @@ editHandlers.compositionend = (view, event2) => {
16812
16845
  view.input.compositionEndedAt = event2.timeStamp;
16813
16846
  view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0;
16814
16847
  view.input.compositionNode = null;
16815
- if (view.input.compositionPendingChanges)
16848
+ if (view.input.badSafariComposition)
16849
+ view.domObserver.forceFlush();
16850
+ else if (view.input.compositionPendingChanges)
16816
16851
  Promise.resolve().then(() => view.domObserver.flush());
16817
16852
  view.input.compositionID++;
16818
16853
  scheduleComposeEnd(view, 20);
@@ -17781,10 +17816,14 @@ class DOMObserver {
17781
17816
  this.observer = window.MutationObserver && new window.MutationObserver((mutations) => {
17782
17817
  for (let i = 0; i < mutations.length; i++)
17783
17818
  this.queue.push(mutations[i]);
17784
- if (ie$1 && ie_version <= 11 && mutations.some((m2) => m2.type == "childList" && m2.removedNodes.length || m2.type == "characterData" && m2.oldValue.length > m2.target.nodeValue.length))
17819
+ if (ie$1 && ie_version <= 11 && mutations.some((m2) => m2.type == "childList" && m2.removedNodes.length || m2.type == "characterData" && m2.oldValue.length > m2.target.nodeValue.length)) {
17785
17820
  this.flushSoon();
17786
- else
17821
+ } else if (safari && view.composing && mutations.some((m2) => m2.type == "childList" && m2.target.nodeName == "TR")) {
17822
+ view.input.badSafariComposition = true;
17823
+ this.flushSoon();
17824
+ } else {
17787
17825
  this.flush();
17826
+ }
17788
17827
  });
17789
17828
  if (useCharData) {
17790
17829
  this.onCharData = (e) => {
@@ -17938,6 +17977,10 @@ class DOMObserver {
17938
17977
  view.docView.markDirty(from2, to);
17939
17978
  checkCSS(view);
17940
17979
  }
17980
+ if (view.input.badSafariComposition) {
17981
+ view.input.badSafariComposition = false;
17982
+ fixUpBadSafariComposition(view, added);
17983
+ }
17941
17984
  this.handleDOMChange(from2, to, typeOver, added);
17942
17985
  if (view.docView && view.docView.dirty)
17943
17986
  view.updateState(view.state);
@@ -18042,6 +18085,31 @@ function blockParent(view, node) {
18042
18085
  }
18043
18086
  return null;
18044
18087
  }
18088
+ function fixUpBadSafariComposition(view, addedNodes) {
18089
+ var _a2;
18090
+ let { focusNode, focusOffset } = view.domSelectionRange();
18091
+ for (let node of addedNodes) {
18092
+ if (((_a2 = node.parentNode) === null || _a2 === void 0 ? void 0 : _a2.nodeName) == "TR") {
18093
+ let nextCell2 = node.nextSibling;
18094
+ while (nextCell2 && (nextCell2.nodeName != "TD" && nextCell2.nodeName != "TH"))
18095
+ nextCell2 = nextCell2.nextSibling;
18096
+ if (nextCell2) {
18097
+ let parent = nextCell2;
18098
+ for (; ; ) {
18099
+ let first2 = parent.firstChild;
18100
+ if (!first2 || first2.nodeType != 1 || first2.contentEditable == "false" || /^(BR|IMG)$/.test(first2.nodeName))
18101
+ break;
18102
+ parent = first2;
18103
+ }
18104
+ parent.insertBefore(node, parent.firstChild);
18105
+ if (focusNode == node)
18106
+ view.domSelection().collapse(node, focusOffset);
18107
+ } else {
18108
+ node.parentNode.removeChild(node);
18109
+ }
18110
+ }
18111
+ }
18112
+ }
18045
18113
  function parseBetween(view, from_, to_) {
18046
18114
  let { node: parent, fromOffset, toOffset, from: from2, to } = view.docView.parseRange(from_, to_);
18047
18115
  let domSel = view.domSelectionRange();
@@ -18481,7 +18549,7 @@ class EditorView {
18481
18549
  this.docView.destroy();
18482
18550
  this.docView = docViewDesc(state2.doc, outerDeco, innerDeco, this.dom, this);
18483
18551
  }
18484
- if (chromeKludge && !this.trackWrites)
18552
+ if (chromeKludge && (!this.trackWrites || !this.dom.contains(this.trackWrites)))
18485
18553
  forceSelUpdate = true;
18486
18554
  }
18487
18555
  if (forceSelUpdate || !(this.input.mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) && anchorInRightPlace(this))) {
@@ -26836,31 +26904,33 @@ function clickHandler(options) {
26836
26904
  if (!view.editable) {
26837
26905
  return false;
26838
26906
  }
26907
+ let link2 = null;
26908
+ if (event2.target instanceof HTMLAnchorElement) {
26909
+ link2 = event2.target;
26910
+ } else {
26911
+ const target = event2.target;
26912
+ if (!target) {
26913
+ return false;
26914
+ }
26915
+ const root2 = options.editor.view.dom;
26916
+ link2 = target.closest("a");
26917
+ if (link2 && !root2.contains(link2)) {
26918
+ link2 = null;
26919
+ }
26920
+ }
26921
+ if (!link2) {
26922
+ return false;
26923
+ }
26839
26924
  let handled = false;
26840
26925
  if (options.enableClickSelection) {
26841
26926
  const commandResult = options.editor.commands.extendMarkRange(options.type.name);
26842
26927
  handled = commandResult;
26843
26928
  }
26844
26929
  if (options.openOnClick) {
26845
- let link2 = null;
26846
- if (event2.target instanceof HTMLAnchorElement) {
26847
- link2 = event2.target;
26848
- } else {
26849
- let a = event2.target;
26850
- const els = [];
26851
- while (a.nodeName !== "DIV") {
26852
- els.push(a);
26853
- a = a.parentNode;
26854
- }
26855
- link2 = els.find((value) => value.nodeName === "A");
26856
- }
26857
- if (!link2) {
26858
- return handled;
26859
- }
26860
26930
  const attrs = getAttributes(view.state, options.type.name);
26861
- const href = (_a2 = link2 == null ? void 0 : link2.href) != null ? _a2 : attrs.href;
26862
- const target = (_b = link2 == null ? void 0 : link2.target) != null ? _b : attrs.target;
26863
- if (link2 && href) {
26931
+ const href = (_a2 = link2.href) != null ? _a2 : attrs.href;
26932
+ const target = (_b = link2.target) != null ? _b : attrs.target;
26933
+ if (href) {
26864
26934
  window.open(href, target);
26865
26935
  handled = true;
26866
26936
  }
@@ -38584,7 +38654,7 @@ var root_5$2 = /* @__PURE__ */ from_html(`<div role="radiogroup" aria-labelledby
38584
38654
  var root_7$2 = /* @__PURE__ */ from_html(`<p>このブロックはコンテナタイプを変更できません。</p>`);
38585
38655
  var root_8$1 = /* @__PURE__ */ from_html(`<label><span>基準列数</span> <output> </output> <input name="bge-options-columns" type="range" min="1" max="5"/></label> <label><span>列の自動調整</span> <select name="bge-options-auto-repeat"><option>固定列数</option><option>auto-fill(空白保持)</option><option>auto-fit(空白最小)</option></select></label> <small>規定幅(<code title="CSSカスタムプロパティ: --bge-auto-repeat-base-width に設定されている値"> </code>)を基準に「基準列数: <code> </code>」で割った数値に近い幅を保ちます。「空白保持」は空のスペースを残し、「空白最小」はアイテムの幅を広げます。</small>`, 1);
38586
38656
  var root_9$1 = /* @__PURE__ */ from_html(`<div role="radiogroup" aria-labelledby="float-group"><div id="float-group">回り込み</div> <label><input type="radio" name="bge-options-float" value="start"/><span>左寄せ</span></label> <label><input type="radio" name="bge-options-float" value="end"/><span>右寄せ</span></label></div>`);
38587
- var root_1$5 = /* @__PURE__ */ from_html(`<fieldset><legend>コンテナ特性</legend> <!> <!> <!> <!> <!></fieldset>`);
38657
+ var root_1$5 = /* @__PURE__ */ from_html(`<fieldset><legend>コンテナ特性</legend> <!> <!> <!> <!> <!> <label><input type="checkbox" name="bge-options-linkarea" value="true"/> <span>リンクエリア機能を有効にする</span></label></fieldset>`);
38588
38658
  var root_12$1 = /* @__PURE__ */ from_html(`<option> </option>`);
38589
38659
  var root_11$1 = /* @__PURE__ */ from_html(`<label><span> </span> <select></select></label>`);
38590
38660
  var root_10$1 = /* @__PURE__ */ from_html(`<fieldset><legend>ブロックのスタイル拡張</legend> <!></fieldset>`);
@@ -38794,6 +38864,9 @@ function Block_options($$anchor, $$props) {
38794
38864
  if (get2(effectiveContainerType) === "float") $$render(consequent_5);
38795
38865
  });
38796
38866
  }
38867
+ var label_18 = sibling(node_6, 2);
38868
+ var input_14 = child(label_18);
38869
+ template_effect(() => input_14.defaultChecked = options.containerProps.linkarea ?? false);
38797
38870
  append2($$anchor2, fieldset);
38798
38871
  };
38799
38872
  if_block(node, ($$render) => {
@@ -38808,8 +38881,8 @@ function Block_options($$anchor, $$props) {
38808
38881
  each(node_8, 17, () => cssProps, ([, category]) => `bge-options-style-${category.id}`, ($$anchor3, $$item) => {
38809
38882
  var $$array = /* @__PURE__ */ user_derived(() => to_array(get2($$item), 2));
38810
38883
  let category = () => get2($$array)[1];
38811
- var label_18 = root_11$1();
38812
- var span = child(label_18);
38884
+ var label_19 = root_11$1();
38885
+ var span = child(label_19);
38813
38886
  var text_6 = child(span);
38814
38887
  var select_3 = sibling(span, 2);
38815
38888
  each(select_3, 21, () => category().properties, ([propName, data]) => propName, ($$anchor4, $$item2) => {
@@ -38832,7 +38905,7 @@ function Block_options($$anchor, $$props) {
38832
38905
  set_text(text_6, category().name);
38833
38906
  set_attribute(select_3, "name", `bge-options-style-${category().id}`);
38834
38907
  });
38835
- append2($$anchor3, label_18);
38908
+ append2($$anchor3, label_19);
38836
38909
  });
38837
38910
  append2($$anchor2, fieldset_1);
38838
38911
  };
@@ -38840,14 +38913,14 @@ function Block_options($$anchor, $$props) {
38840
38913
  if (cssProps.size > 0) $$render(consequent_7);
38841
38914
  });
38842
38915
  }
38843
- var label_19 = sibling(node_7, 2);
38844
- var input_14 = sibling(child(label_19), 2);
38845
- var label_20 = sibling(label_19, 4);
38916
+ var label_20 = sibling(node_7, 2);
38846
38917
  var input_15 = sibling(child(label_20), 2);
38918
+ var label_21 = sibling(label_20, 4);
38919
+ var input_16 = sibling(child(label_21), 2);
38847
38920
  template_effect(
38848
38921
  ($0) => {
38849
- input_14.defaultValue = $0;
38850
- input_15.defaultValue = options.id ?? "";
38922
+ input_15.defaultValue = $0;
38923
+ input_16.defaultValue = options.id ?? "";
38851
38924
  },
38852
38925
  [() => options.classList?.join(" ") ?? ""]
38853
38926
  );