@diplodoc/tabs-extension 3.9.0 → 3.10.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.
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
8
11
  var __commonJS = (cb, mod) => function __require() {
9
12
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
13
  };
@@ -29,6 +32,444 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
32
  mod
30
33
  ));
31
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
36
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
37
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
38
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
39
+
40
+ // node_modules/@diplodoc/utils/build/cjs/common/index.js
41
+ var require_common = __commonJS({
42
+ "node_modules/@diplodoc/utils/build/cjs/common/index.js"(exports2, module2) {
43
+ "use strict";
44
+ var __defProp2 = Object.defineProperty;
45
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
46
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
47
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
48
+ var __export2 = (target, all) => {
49
+ for (var name in all)
50
+ __defProp2(target, name, { get: all[name], enumerable: true });
51
+ };
52
+ var __copyProps2 = (to, from, except, desc) => {
53
+ if (from && typeof from === "object" || typeof from === "function") {
54
+ for (let key of __getOwnPropNames2(from))
55
+ if (!__hasOwnProp2.call(to, key) && key !== except)
56
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
57
+ }
58
+ return to;
59
+ };
60
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
61
+ var index_exports2 = {};
62
+ __export2(index_exports2, {
63
+ AttrsParser: () => AttrsParser,
64
+ createIDGenerator: () => createIDGenerator,
65
+ createIDGeneratorByStrategy: () => createIDGeneratorByStrategy2,
66
+ createLoadQueue: () => createLoadQueue,
67
+ getQueueStore: () => getQueueStore,
68
+ getScriptStore: () => getScriptStore,
69
+ isBrowser: () => isBrowser,
70
+ parseMdAttrs: () => parseMdAttrs
71
+ });
72
+ module2.exports = __toCommonJS2(index_exports2);
73
+ var _key, _pending, _isInsideQuotation, _didQuotationClosed, _currentKeyType, _selectors, _handlers, _a;
74
+ var AttrsParser = (_a = class {
75
+ constructor(value) {
76
+ __privateAdd(this, _key);
77
+ __privateAdd(this, _pending);
78
+ __privateAdd(this, _isInsideQuotation);
79
+ __privateAdd(this, _didQuotationClosed);
80
+ __privateAdd(this, _currentKeyType);
81
+ __privateAdd(this, _selectors);
82
+ __privateAdd(this, _handlers);
83
+ this.DELIMITER = "=";
84
+ this.SEPARATOR = " ";
85
+ this.QUOTATION = '"';
86
+ this.ALLOWED_CHARS = /[a-zA-Z0-9_\- {}.|/]/;
87
+ this.VALIDATION_CHARS = /[a-zA-Z0-9_\- {}.#="|/]/;
88
+ this.state = {};
89
+ __privateSet(this, _key, "");
90
+ __privateSet(this, _pending, "");
91
+ __privateSet(this, _isInsideQuotation, false);
92
+ __privateSet(this, _didQuotationClosed, false);
93
+ __privateSet(this, _selectors, {
94
+ id: /#/,
95
+ class: /\./,
96
+ attr: /[a-zA-Z-_]/
97
+ });
98
+ __privateSet(this, _handlers, Object.entries(__privateGet(this, _selectors)));
99
+ if (value) {
100
+ this.parse(value);
101
+ }
102
+ }
103
+ parse(target) {
104
+ const content = this.extract(target.trim());
105
+ if (!content) {
106
+ return {};
107
+ }
108
+ this.clear();
109
+ this.state = {};
110
+ for (const char of content) {
111
+ this.next(char);
112
+ }
113
+ this.next(this.SEPARATOR);
114
+ this.clear();
115
+ return this.state;
116
+ }
117
+ apply(target) {
118
+ const { attr: singleKeyAttrs = [], ...fullAttrs } = this.state;
119
+ for (const [property, values] of Object.entries(fullAttrs)) {
120
+ target.attrJoin(property, values.join(" "));
121
+ }
122
+ for (const attr of singleKeyAttrs) {
123
+ target.attrJoin(attr, "true");
124
+ }
125
+ }
126
+ extract(target) {
127
+ if (!target.startsWith("{")) {
128
+ return false;
129
+ }
130
+ let balance = 1;
131
+ for (let i = 1; i < target.length; i++) {
132
+ const char = target[i];
133
+ if (char === "}") {
134
+ balance--;
135
+ }
136
+ if (char === "{") {
137
+ balance++;
138
+ }
139
+ if (balance === 0) {
140
+ const contentInside = target.slice(1, i).trim();
141
+ return contentInside;
142
+ }
143
+ if (balance < 0) {
144
+ return false;
145
+ }
146
+ if (!this.VALIDATION_CHARS.test(char)) {
147
+ return false;
148
+ }
149
+ }
150
+ return false;
151
+ }
152
+ next(value) {
153
+ if (!__privateGet(this, _currentKeyType)) {
154
+ __privateSet(this, _currentKeyType, this.type(value));
155
+ if (__privateGet(this, _currentKeyType) === "attr") {
156
+ __privateSet(this, _pending, value);
157
+ }
158
+ return;
159
+ }
160
+ if (this.isSeparator(value)) {
161
+ if (!__privateGet(this, _pending)) {
162
+ if (!__privateGet(this, _isInsideQuotation)) {
163
+ this.append(__privateGet(this, _key), " ");
164
+ this.clear();
165
+ return;
166
+ }
167
+ }
168
+ if (!__privateGet(this, _key) && __privateGet(this, _pending)) {
169
+ this.append();
170
+ this.clear();
171
+ return;
172
+ }
173
+ if (__privateGet(this, _isInsideQuotation) && !__privateGet(this, _didQuotationClosed)) {
174
+ __privateSet(this, _pending, __privateGet(this, _pending) + value);
175
+ return;
176
+ }
177
+ if (__privateGet(this, _isInsideQuotation) && __privateGet(this, _didQuotationClosed)) {
178
+ this.append(__privateGet(this, _key), __privateGet(this, _pending));
179
+ }
180
+ if (!__privateGet(this, _isInsideQuotation) && !__privateGet(this, _didQuotationClosed)) {
181
+ this.append(__privateGet(this, _key), __privateGet(this, _pending));
182
+ }
183
+ this.clear();
184
+ return;
185
+ }
186
+ if (this.isAllowedChar(value)) {
187
+ __privateSet(this, _pending, __privateGet(this, _pending) + value);
188
+ return;
189
+ }
190
+ if (this.isQuotation(value)) {
191
+ if (__privateGet(this, _isInsideQuotation)) {
192
+ __privateSet(this, _didQuotationClosed, true);
193
+ } else {
194
+ __privateSet(this, _isInsideQuotation, true);
195
+ }
196
+ }
197
+ if (this.isDelimiter(value)) {
198
+ if (__privateGet(this, _key)) {
199
+ __privateSet(this, _pending, __privateGet(this, _pending) + value);
200
+ return;
201
+ }
202
+ __privateSet(this, _key, __privateGet(this, _pending));
203
+ __privateSet(this, _pending, "");
204
+ }
205
+ }
206
+ type(of) {
207
+ var _a2;
208
+ return (_a2 = __privateGet(this, _handlers).find(([_, regex]) => regex.test(of))) == null ? void 0 : _a2[0];
209
+ }
210
+ append(key = __privateGet(this, _currentKeyType), value = __privateGet(this, _pending)) {
211
+ if (!key) {
212
+ return;
213
+ }
214
+ if (!this.state[key]) {
215
+ this.state[key] = [];
216
+ }
217
+ this.state[key].push(value);
218
+ }
219
+ clear() {
220
+ __privateSet(this, _key, "");
221
+ __privateSet(this, _pending, "");
222
+ __privateSet(this, _isInsideQuotation, false);
223
+ __privateSet(this, _didQuotationClosed, false);
224
+ __privateSet(this, _currentKeyType, void 0);
225
+ }
226
+ isDelimiter(target) {
227
+ return target === this.DELIMITER;
228
+ }
229
+ isSeparator(target) {
230
+ return target === this.SEPARATOR;
231
+ }
232
+ isQuotation(target) {
233
+ return target === this.QUOTATION;
234
+ }
235
+ isAllowedChar(target) {
236
+ return this.ALLOWED_CHARS.test(target);
237
+ }
238
+ }, _key = new WeakMap(), _pending = new WeakMap(), _isInsideQuotation = new WeakMap(), _didQuotationClosed = new WeakMap(), _currentKeyType = new WeakMap(), _selectors = new WeakMap(), _handlers = new WeakMap(), _a);
239
+ function parseMdAttrs(md, src, pos, max) {
240
+ if (pos >= max) {
241
+ return null;
242
+ }
243
+ if (src.charCodeAt(pos) !== 123) {
244
+ return null;
245
+ }
246
+ const attrs = {};
247
+ ++pos;
248
+ pos = skipBlanks(src, pos, max);
249
+ for (; pos < max; pos = skipBlanks(src, pos, max)) {
250
+ if (src.charCodeAt(pos) === 125) {
251
+ ++pos;
252
+ return { pos, attrs };
253
+ }
254
+ const c = src.charCodeAt(pos);
255
+ if (c === 35) {
256
+ ++pos;
257
+ const rst = parseUnsurroundedName(src, pos, max);
258
+ if (rst === null) {
259
+ return null;
260
+ }
261
+ pos = rst.pos;
262
+ const key = "id", value = rst.name;
263
+ if (typeof attrs[key] === "undefined") {
264
+ attrs[key] = [value];
265
+ } else {
266
+ attrs[key].push(value);
267
+ }
268
+ } else if (c === 46) {
269
+ ++pos;
270
+ const rst = parseUnsurroundedName(src, pos, max);
271
+ if (rst === null) {
272
+ return null;
273
+ }
274
+ pos = rst.pos;
275
+ const key = "class", value = rst.name;
276
+ if (typeof attrs[key] === "undefined") {
277
+ attrs[key] = [value];
278
+ } else {
279
+ attrs[key].push(value);
280
+ }
281
+ } else {
282
+ let rst = parseAttrName(src, pos, max);
283
+ if (rst === null) {
284
+ return null;
285
+ }
286
+ const key = rst.name;
287
+ pos = rst.pos;
288
+ pos = skipBlanks(src, pos, max);
289
+ if (pos >= max) {
290
+ return null;
291
+ }
292
+ let value;
293
+ if (src.charCodeAt(pos) === 61) {
294
+ ++pos;
295
+ pos = skipBlanks(src, pos, max);
296
+ if (pos >= max) {
297
+ return null;
298
+ }
299
+ const c2 = src.charCodeAt(pos);
300
+ if (c2 === 34 || c2 === 39) {
301
+ const rst2 = md.helpers.parseLinkTitle(src, pos, max);
302
+ if (!rst2.ok) {
303
+ return null;
304
+ }
305
+ value = rst2.str;
306
+ pos = rst2.pos;
307
+ } else {
308
+ rst = parseUnsurroundedName(src, pos, max);
309
+ if (rst === null) {
310
+ return null;
311
+ }
312
+ value = rst.name;
313
+ pos = rst.pos;
314
+ }
315
+ } else {
316
+ if (isBlank(src.charCodeAt(pos - 1))) {
317
+ --pos;
318
+ }
319
+ value = "";
320
+ }
321
+ if (typeof value !== "undefined") {
322
+ if (typeof attrs[key] === "undefined") {
323
+ attrs[key] = [value];
324
+ } else {
325
+ attrs[key].push(value);
326
+ }
327
+ }
328
+ }
329
+ if (pos >= max) {
330
+ return null;
331
+ }
332
+ const charBetween = src.charCodeAt(pos);
333
+ if (!isBlank(charBetween) && charBetween !== 125) {
334
+ return null;
335
+ }
336
+ }
337
+ return null;
338
+ function isBlank(code) {
339
+ return md.utils.isSpace(code) || code === 10;
340
+ }
341
+ function skipBlanks(src2, pos2, max2) {
342
+ for (; pos2 < max2; pos2++) {
343
+ const code = src2.charCodeAt(pos2);
344
+ if (!isBlank(code)) {
345
+ break;
346
+ }
347
+ }
348
+ return pos2;
349
+ }
350
+ }
351
+ var ATTR_NAME_RE = /^[a-z][a-z0-9\-_]*/;
352
+ function parseAttrName(src, pos, max) {
353
+ const oldPos = pos;
354
+ const rst = src.slice(pos, max).match(ATTR_NAME_RE);
355
+ if (rst === null) {
356
+ return null;
357
+ }
358
+ pos += rst[0].length;
359
+ return { pos, name: src.slice(oldPos, pos) };
360
+ }
361
+ var UNSURROUNDED_STRING_RE = /^[a-z0-9\-_]+/i;
362
+ function parseUnsurroundedName(src, pos, max) {
363
+ const oldPos = pos;
364
+ const rst = src.slice(pos, max).match(UNSURROUNDED_STRING_RE);
365
+ if (rst === null) {
366
+ return null;
367
+ }
368
+ pos += rst[0].length;
369
+ return { pos, name: src.slice(oldPos, pos) };
370
+ }
371
+ var isBrowser = () => {
372
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
373
+ };
374
+ var QUEUES_SYMBOL = /* @__PURE__ */ Symbol.for("extension-load-queues");
375
+ var SINGLE_QUEUE_SYMBOL = /* @__PURE__ */ Symbol.for("single-queue");
376
+ var getScriptStore = (storeKey) => {
377
+ if (isBrowser()) {
378
+ if (!window[storeKey]) {
379
+ window[storeKey] = [];
380
+ } else if (!Array.isArray(window[storeKey])) {
381
+ throw new Error(`Expected window[${String(storeKey)}] to be an array`);
382
+ }
383
+ return window[storeKey];
384
+ } else {
385
+ throw new Error("Cannot initialize QueueStore in a non-browser environment.");
386
+ }
387
+ };
388
+ var ensureQueuesSymbolInitialized = () => {
389
+ if (isBrowser()) {
390
+ if (typeof window[QUEUES_SYMBOL] !== "object" || window[QUEUES_SYMBOL] === null) {
391
+ window[QUEUES_SYMBOL] = {};
392
+ }
393
+ } else {
394
+ throw new Error("Cannot initialize QueueStore in a non-browser environment.");
395
+ }
396
+ };
397
+ var getQueueStore = (queueKey) => {
398
+ var _a2;
399
+ ensureQueuesSymbolInitialized();
400
+ return ((_a2 = window[QUEUES_SYMBOL]) == null ? void 0 : _a2[queueKey]) || false;
401
+ };
402
+ var createHandleQueueCreated = (queueKey) => {
403
+ ensureQueuesSymbolInitialized();
404
+ return (created) => {
405
+ window[QUEUES_SYMBOL][queueKey] = created;
406
+ };
407
+ };
408
+ var createLoadQueue = ({
409
+ store,
410
+ createController,
411
+ queueKey = SINGLE_QUEUE_SYMBOL,
412
+ isQueueCreated = getQueueStore(queueKey),
413
+ onQueueCreated = createHandleQueueCreated(queueKey)
414
+ }) => {
415
+ if (!store || isQueueCreated) {
416
+ return;
417
+ }
418
+ onQueueCreated(true);
419
+ const controller = createController();
420
+ const queue = store.splice(0, store.length);
421
+ store.push = function(...args) {
422
+ args.forEach((callback) => {
423
+ queue.push(callback);
424
+ unqueue();
425
+ });
426
+ return queue.length;
427
+ };
428
+ let processing = false;
429
+ function unqueue() {
430
+ if (!processing) {
431
+ next();
432
+ }
433
+ }
434
+ async function next() {
435
+ processing = true;
436
+ const callback = queue.shift();
437
+ if (callback) {
438
+ await callback(controller);
439
+ return next();
440
+ }
441
+ processing = false;
442
+ }
443
+ unqueue();
444
+ };
445
+ function createIDGenerator() {
446
+ const counters = /* @__PURE__ */ new Map();
447
+ return function generateID(prefix) {
448
+ if (!prefix) {
449
+ return Math.random().toString(36).substr(2, 8);
450
+ }
451
+ counters.set(prefix, (counters.get(prefix) || 0) + 1);
452
+ return `${prefix}-${counters.get(prefix)}`;
453
+ };
454
+ }
455
+ function createIDGeneratorByStrategy2(strategy = "random") {
456
+ switch (strategy) {
457
+ case "deterministic":
458
+ return createIDGenerator();
459
+ case "constant":
460
+ return () => "1";
461
+ case "random":
462
+ default:
463
+ return (prefix) => {
464
+ if (!prefix) {
465
+ return Math.random().toString(36).substr(2, 8);
466
+ }
467
+ return `${prefix}-${Math.random().toString(36).substr(2, 8)}`;
468
+ };
469
+ }
470
+ }
471
+ }
472
+ });
32
473
 
33
474
  // node_modules/github-slugger/regex.js
34
475
  var require_regex = __commonJS({
@@ -74,11 +515,14 @@ var require_github_slugger = __commonJS({
74
515
  });
75
516
 
76
517
  // src/plugin/index.ts
77
- var plugin_exports = {};
78
- __export(plugin_exports, {
518
+ var index_exports = {};
519
+ __export(index_exports, {
79
520
  transform: () => transform
80
521
  });
81
- module.exports = __toCommonJS(plugin_exports);
522
+ module.exports = __toCommonJS(index_exports);
523
+
524
+ // src/plugin/transform.ts
525
+ var import_utils6 = __toESM(require_common());
82
526
 
83
527
  // src/common.ts
84
528
  var TAB_RE = /`?{% list tabs .*?%}`?/;
@@ -103,13 +547,8 @@ var TABS_ACCORDION_CLASSNAME = "yfm-tabs-accordion";
103
547
  var TABS_RADIO_CLASSNAME = "yfm-tabs-vertical";
104
548
  var VERTICAL_TAB_CLASSNAME = "yfm-vertical-tab";
105
549
  var TAB_DATA_VERTICAL_TAB = "data-diplodoc-vertical-tab";
106
- var GLOBAL_SYMBOL = Symbol.for("diplodocTabs");
107
550
 
108
551
  // src/plugin/utils/strings.ts
109
- function generateID() {
110
- const id = Math.random().toString(36).substr(2, 8);
111
- return id.substring(id.length - 8);
112
- }
113
552
  function trim(target) {
114
553
  return target.trim();
115
554
  }
@@ -216,7 +655,7 @@ function addHiddenProperty(box, field, value) {
216
655
  }
217
656
 
218
657
  // src/plugin/variants/regular.ts
219
- var regular = (tabs, state, { containerClasses, tabsGroup, runId, variant: orientation }) => {
658
+ var regular = (tabs, state, { containerClasses, tabsGroup, runId, variant: orientation, generateID }) => {
220
659
  var _a, _b;
221
660
  const tabsTokens = [];
222
661
  const tabListTokens = [];
@@ -271,7 +710,7 @@ var regular = (tabs, state, { containerClasses, tabsGroup, runId, variant: orien
271
710
  const didTabHasActiveAttr = isTabSelected(tab);
272
711
  const isTabActive = hasDefaultOpenTab ? didTabHasActiveAttr : i === 0;
273
712
  tab.name = getName(tab);
274
- const tabPanelId = generateID();
713
+ const tabPanelId = generateID("regular");
275
714
  verticalTabInput.block = true;
276
715
  verticalTabInput.attrJoin("class", "radio");
277
716
  verticalTabInput.attrSet("type", "radio");
@@ -339,7 +778,7 @@ var regular = (tabs, state, { containerClasses, tabsGroup, runId, variant: orien
339
778
  };
340
779
 
341
780
  // src/plugin/variants/radio.ts
342
- var radio = (tabs, state, { containerClasses, tabsGroup, runId }) => {
781
+ var radio = (tabs, state, { containerClasses, tabsGroup, runId, generateID }) => {
343
782
  var _a, _b;
344
783
  const tabsTokens = [];
345
784
  const tabsOpen = new state.Token("tabs_open", "div", 1);
@@ -384,7 +823,7 @@ var radio = (tabs, state, { containerClasses, tabsGroup, runId }) => {
384
823
  const tabKey = getTabKey(tab);
385
824
  const didTabHasActiveAttr = isTabSelected(tab);
386
825
  tab.name = getName(tab);
387
- const tabPanelId = generateID();
826
+ const tabPanelId = generateID("radio");
388
827
  verticalTabInput.block = true;
389
828
  verticalTabInput.attrJoin("class", "radio");
390
829
  verticalTabInput.attrSet("type", "radio");
@@ -434,7 +873,7 @@ var radio = (tabs, state, { containerClasses, tabsGroup, runId }) => {
434
873
  };
435
874
 
436
875
  // src/plugin/variants/dropdown.ts
437
- var dropdown = (tabs, state, { containerClasses, tabsGroup, runId }) => {
876
+ var dropdown = (tabs, state, { containerClasses, tabsGroup, runId, generateID }) => {
438
877
  var _a, _b;
439
878
  const dropdownTokens = [];
440
879
  const dropdownOpen = new state.Token("dropdown_open", "div", 1);
@@ -510,7 +949,7 @@ var dropdown = (tabs, state, { containerClasses, tabsGroup, runId }) => {
510
949
  const tabId = getTabId(tab, { runId });
511
950
  const didTabHasActiveAttr = isTabSelected(tab);
512
951
  tab.name = getName(tab);
513
- const tabPanelId = generateID();
952
+ const tabPanelId = generateID("dropdown");
514
953
  tabPanelOpen.map = getContentMap(tabs[i].tokens);
515
954
  tabPanelOpen.block = true;
516
955
  tabPanelClose.block = true;
@@ -529,7 +968,7 @@ var dropdown = (tabs, state, { containerClasses, tabsGroup, runId }) => {
529
968
  };
530
969
 
531
970
  // src/plugin/variants/accordion.ts
532
- var accordion = (tabs, state, { containerClasses, tabsGroup, runId }) => {
971
+ var accordion = (tabs, state, { containerClasses, tabsGroup, runId, generateID }) => {
533
972
  var _a, _b;
534
973
  const tabsTokens = [];
535
974
  const tabsOpen = new state.Token("tabs_open", "div", 1);
@@ -571,7 +1010,7 @@ var accordion = (tabs, state, { containerClasses, tabsGroup, runId }) => {
571
1010
  const tabKey = getTabKey(tab);
572
1011
  const didTabHasActiveAttr = isTabSelected(tab);
573
1012
  tab.name = getName(tab);
574
- const tabPanelId = generateID();
1013
+ const tabPanelId = generateID("accordion");
575
1014
  tabOpen.map = tabs[i].listItem.map;
576
1015
  tabOpen.markup = tabs[i].listItem.markup;
577
1016
  tabPanelOpen.map = getContentMap(tabs[i].tokens);
@@ -645,15 +1084,21 @@ function matchCloseToken(tokens, i) {
645
1084
  return tokens[i].type === "paragraph_open" && tokens[i + 1].type === "inline" && tokens[i + 1].content.trim() === "{% endlist %}";
646
1085
  }
647
1086
  function matchOpenToken(tokens, i) {
648
- return tokens[i].type === "paragraph_open" && tokens[i + 1].type === "inline" && tokens[i + 1].content.match(TAB_RE);
1087
+ if (tokens[i].type !== "paragraph_open" || tokens[i + 1].type !== "inline") {
1088
+ return null;
1089
+ }
1090
+ return tokens[i + 1].content.match(TAB_RE);
649
1091
  }
650
- function props(content) {
1092
+ function props(content, generateID) {
651
1093
  const clean = trim(content.replace("list tabs", ""));
652
1094
  const props2 = clean.split(" ");
653
1095
  const result = {
654
1096
  content: clean,
655
1097
  variant: "regular" /* Regular */,
656
- group: `${DEFAULT_TABS_GROUP_PREFIX}${generateID()}`
1098
+ // DEFAULT_TABS_GROUP_PREFIX ends with '-', so strip it before passing to generateID
1099
+ // which appends '-N' itself. Result: 'defaultTabsGroup-1', 'defaultTabsGroup-2', …
1100
+ // TabsController checks group.startsWith(DEFAULT_TABS_GROUP_PREFIX) which still matches.
1101
+ group: generateID(DEFAULT_TABS_GROUP_PREFIX.replace(/-$/, ""))
657
1102
  };
658
1103
  for (const prop of props2) {
659
1104
  const [key, value] = prop.split("=").map(trim);
@@ -796,7 +1241,8 @@ function transform({
796
1241
  features = defaultFeatures
797
1242
  } = {}) {
798
1243
  return function tabs(md, options) {
799
- const { output = "." } = options || {};
1244
+ const { output = ".", generateID: externalGenerateID } = options || {};
1245
+ const generateID = externalGenerateID != null ? externalGenerateID : (0, import_utils6.createIDGeneratorByStrategy)("random");
800
1246
  const plugin = (state) => {
801
1247
  const { env, tokens } = state;
802
1248
  const runId = String(++runsCounter);
@@ -810,7 +1256,7 @@ function transform({
810
1256
  continue;
811
1257
  }
812
1258
  const { content, closeTokenIndex, extraTokensAfterClose } = result;
813
- const parsedProps = props(content);
1259
+ const parsedProps = props(content, generateID);
814
1260
  if (!features.enabledVariants[parsedProps.variant]) {
815
1261
  parsedProps.variant = "regular" /* Regular */;
816
1262
  }
@@ -820,7 +1266,8 @@ function transform({
820
1266
  containerClasses,
821
1267
  tabsGroup: parsedProps.group,
822
1268
  variant: parsedProps.variant,
823
- runId
1269
+ runId,
1270
+ generateID
824
1271
  });
825
1272
  state.tokens.splice(
826
1273
  i,
@@ -846,7 +1293,7 @@ function transform({
846
1293
  };
847
1294
  try {
848
1295
  md.core.ruler.before("curly_attributes", "tabs", plugin);
849
- } catch (e) {
1296
+ } catch {
850
1297
  md.core.ruler.push("tabs", plugin);
851
1298
  }
852
1299
  };