@rulecms/source-components-angular 0.3.0 → 0.4.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/fesm2022/rulecms-source-components-angular.mjs +368 -34
- package/fesm2022/rulecms-source-components-angular.mjs.map +1 -1
- package/lib/base-components/display/component-attributes/component-name-to-modify-attribute.d.ts.map +1 -1
- package/lib/base-components/display/components/r-accordion/accordion-attributes.d.ts +1 -0
- package/lib/base-components/display/components/r-accordion/accordion-attributes.d.ts.map +1 -1
- package/lib/base-components/display/components/r-accordion/attribute-edit-mode-configs.d.ts.map +1 -1
- package/lib/base-components/display/components/r-accordion/default-attribute-values.d.ts.map +1 -1
- package/lib/base-components/display/components/r-accordion/r-accordion.component.d.ts +1 -0
- package/lib/base-components/display/components/r-accordion/r-accordion.component.d.ts.map +1 -1
- package/lib/base-components/display/components/r-list/attribute-edit-mode-configs.d.ts.map +1 -1
- package/lib/base-components/display/components/r-list/default-attribute-values.d.ts.map +1 -1
- package/lib/base-components/display/components/r-list/list-attributes.d.ts +1 -0
- package/lib/base-components/display/components/r-list/list-attributes.d.ts.map +1 -1
- package/lib/base-components/display/components/r-list/r-list.component.d.ts +1 -0
- package/lib/base-components/display/components/r-list/r-list.component.d.ts.map +1 -1
- package/lib/base-components/display/components/r-text/attribute-edit-mode-configs.d.ts.map +1 -1
- package/lib/base-components/display/components/r-text/default-attribute-values.d.ts.map +1 -1
- package/lib/base-components/display/components/r-text/r-text.component.d.ts +5 -0
- package/lib/base-components/display/components/r-text/r-text.component.d.ts.map +1 -1
- package/lib/component-library-module.d.ts.map +1 -1
- package/lib/library-version.d.ts +3 -0
- package/lib/library-version.d.ts.map +1 -0
- package/lib/shared/inline-markup/inline-markup.component.d.ts +7 -1
- package/lib/shared/inline-markup/inline-markup.component.d.ts.map +1 -1
- package/lib/shared/inline-markup/parse-inline-markers.d.ts +9 -3
- package/lib/shared/inline-markup/parse-inline-markers.d.ts.map +1 -1
- package/lib/shared/inline-markup/serialize-inline-markers.d.ts.map +1 -1
- package/lib/shared/span-styles/index.d.ts +8 -0
- package/lib/shared/span-styles/index.d.ts.map +1 -0
- package/lib/shared/span-styles/parse-style-declarations.d.ts +28 -0
- package/lib/shared/span-styles/parse-style-declarations.d.ts.map +1 -0
- package/lib/shared/span-styles/resolve-class-names.d.ts +23 -0
- package/lib/shared/span-styles/resolve-class-names.d.ts.map +1 -0
- package/lib/shared/span-styles/resolve-span-style-attributes.d.ts +26 -0
- package/lib/shared/span-styles/resolve-span-style-attributes.d.ts.map +1 -0
- package/lib/shared/span-styles/span-style-item.d.ts +43 -0
- package/lib/shared/span-styles/span-style-item.d.ts.map +1 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/public-api.d.ts.map +1 -1
|
@@ -19,6 +19,10 @@ const defaultAttributeValues$9 = [
|
|
|
19
19
|
name: 'links-3-resolutions',
|
|
20
20
|
defaultValues: {},
|
|
21
21
|
},
|
|
22
|
+
{
|
|
23
|
+
name: 'inline-styles-3-resolutions',
|
|
24
|
+
defaultValues: {},
|
|
25
|
+
},
|
|
22
26
|
];
|
|
23
27
|
|
|
24
28
|
/**
|
|
@@ -351,13 +355,266 @@ function resolveLinkAttributes(item) {
|
|
|
351
355
|
}
|
|
352
356
|
|
|
353
357
|
/**
|
|
354
|
-
*
|
|
358
|
+
* Runtime guard for entries arriving through componentAttributes (untyped,
|
|
359
|
+
* editor-authored data).
|
|
360
|
+
*
|
|
361
|
+
* Only object shape is checked, for the same reason as `isLinkItem`: one bad
|
|
362
|
+
* field must cost that field rather than the whole entry, so per-field
|
|
363
|
+
* validation belongs to `resolveSpanStyleAttributes` where each value is turned
|
|
364
|
+
* into something an element can carry.
|
|
365
|
+
*/
|
|
366
|
+
function isSpanStyleItem(value) {
|
|
367
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* True for a cleared slot. Clearing an entry stores `{}` rather than removing
|
|
371
|
+
* the array element, because marker indexes are 1-based positions: dropping an
|
|
372
|
+
* element would silently repoint every later marker.
|
|
373
|
+
*
|
|
374
|
+
* A `label` alone is a cleared slot. It is the author's note to themselves
|
|
375
|
+
* about which entry this is, and an entry that only has a name applies nothing.
|
|
376
|
+
*/
|
|
377
|
+
function isEmptySpanStyleItem(item) {
|
|
378
|
+
if (!isSpanStyleItem(item)) {
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
return [item.classNames, item.declarations].every((value) => typeof value !== 'string' || value.trim() === '');
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* The entry a `{.n|…}` marker points at, by 1-based position. Tolerant of bad
|
|
385
|
+
* data on every axis — a non-array list, a fractional or out-of-range index, a
|
|
386
|
+
* hole in the array — because none of it may throw during a render.
|
|
387
|
+
*/
|
|
388
|
+
function getSpanStyleItemAt(spanStyles, oneBasedIndex) {
|
|
389
|
+
if (!Array.isArray(spanStyles)) {
|
|
390
|
+
return undefined;
|
|
391
|
+
}
|
|
392
|
+
if (!Number.isInteger(oneBasedIndex) || oneBasedIndex < 1) {
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
const entry = spanStyles[oneBasedIndex - 1];
|
|
396
|
+
return isSpanStyleItem(entry) ? entry : undefined;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* A class name is a *selector* into CSS the customer already ships. This
|
|
401
|
+
* library cannot see those rules, so it cannot validate a name against
|
|
402
|
+
* anything — the only useful question is whether the token could damage the
|
|
403
|
+
* document it lands in, and the answer is almost always no: every renderer sets
|
|
404
|
+
* `class` through a DOM property or a framework binding, never by pasting into
|
|
405
|
+
* markup.
|
|
406
|
+
*
|
|
407
|
+
* So the filter is deliberately permissive. Utility frameworks make class names
|
|
408
|
+
* that look like code — `md:hover:text-lg`, `w-1/2`, `text-[#c00]`,
|
|
409
|
+
* `[&>svg]:size-4` — and a tidier-looking allowlist would reject those and be
|
|
410
|
+
* read as a bug.
|
|
411
|
+
*/
|
|
412
|
+
/** Whitespace separates tokens, so it cannot appear inside one. */
|
|
413
|
+
const TOKEN_SEPARATOR = /\s+/;
|
|
414
|
+
/**
|
|
415
|
+
* Control characters, and the two brace characters. Braces are not dangerous in
|
|
416
|
+
* a class attribute; they are rejected because a token containing one is nearly
|
|
417
|
+
* always an inline marker the author pasted into the wrong field, and silently
|
|
418
|
+
* accepting it would style nothing and explain nothing.
|
|
419
|
+
*/
|
|
420
|
+
// eslint-disable-next-line no-control-regex -- control characters are what this matches
|
|
421
|
+
const REJECTED_IN_TOKEN = /[\u0000-\u001f\u007f{}]/;
|
|
422
|
+
/**
|
|
423
|
+
* Bounds, so a pathological value cannot become a pathological `class`
|
|
424
|
+
* attribute. Both are far past anything a person types by hand.
|
|
425
|
+
*/
|
|
426
|
+
const MAX_TOKENS = 50;
|
|
427
|
+
const MAX_TOKEN_LENGTH = 120;
|
|
428
|
+
const isUsableToken = (token) =>
|
|
429
|
+
// Splitting a blank string yields one empty token, which is not a class name.
|
|
430
|
+
token !== '' && token.length <= MAX_TOKEN_LENGTH && !REJECTED_IN_TOKEN.test(token);
|
|
431
|
+
/**
|
|
432
|
+
* The `class` value for a styling entry, or `undefined` when it has none worth
|
|
433
|
+
* setting.
|
|
434
|
+
*
|
|
435
|
+
* Duplicates collapse and order is the author's. One bad token costs that
|
|
436
|
+
* token: the rest of a mostly-fine list still applies, which is the same
|
|
437
|
+
* per-field tolerance `resolveLinkAttributes` gives a link entry.
|
|
438
|
+
*/
|
|
439
|
+
function resolveClassNames(value) {
|
|
440
|
+
if (typeof value !== 'string') {
|
|
441
|
+
return undefined;
|
|
442
|
+
}
|
|
443
|
+
const tokens = value.trim().split(TOKEN_SEPARATOR).filter(isUsableToken);
|
|
444
|
+
if (tokens.length === 0) {
|
|
445
|
+
return undefined;
|
|
446
|
+
}
|
|
447
|
+
return Array.from(new Set(tokens)).slice(0, MAX_TOKENS).join(' ');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Declarations are split on `;` without tracking quotes, so a value containing
|
|
452
|
+
* a semicolon inside a string — `content: "a;b"` — is cut in half and both
|
|
453
|
+
* halves are then rejected as malformed. That is an acceptable trade: the
|
|
454
|
+
* properties worth setting on a run of words do not take string values, and a
|
|
455
|
+
* quote-aware splitter is a second CSS parser to keep correct.
|
|
456
|
+
*/
|
|
457
|
+
const DECLARATION_SEPARATOR = ';';
|
|
458
|
+
/** `--custom-property`, or an ordinary property with an optional vendor prefix. */
|
|
459
|
+
const PROPERTY_NAME = /^(--[a-zA-Z0-9-]+|-?[a-zA-Z][a-zA-Z0-9-]*)$/;
|
|
460
|
+
/**
|
|
461
|
+
* Properties that do something other than style text, whatever their value.
|
|
462
|
+
*
|
|
463
|
+
* `behavior` and `-moz-binding` attach script to an element through CSS in old
|
|
464
|
+
* engines. They are long dead, and they are named here anyway: the cost is one
|
|
465
|
+
* line, and the alternative is relying on every reader of this file knowing
|
|
466
|
+
* that CSS was once executable.
|
|
467
|
+
*/
|
|
468
|
+
const REJECTED_PROPERTIES = new Set(['behavior', '-moz-binding']);
|
|
469
|
+
/**
|
|
470
|
+
* Constructs that make a declaration do more than describe appearance.
|
|
471
|
+
*
|
|
472
|
+
* `url(` is rejected rather than filtered because every reason to allow it is
|
|
473
|
+
* better served elsewhere: a background image is a component, and a `url()` in
|
|
474
|
+
* authored text is either a tracking pixel, a `data:` payload, or a
|
|
475
|
+
* `javascript:` scheme an older engine will still run. A backslash is rejected
|
|
476
|
+
* for the same reason in one step: CSS escapes let `\75 rl(` spell `url(`, so
|
|
477
|
+
* allowing escapes would mean decoding them before every other check.
|
|
478
|
+
*/
|
|
479
|
+
const REJECTED_IN_VALUE = [
|
|
480
|
+
'url(',
|
|
481
|
+
'expression(',
|
|
482
|
+
'javascript:',
|
|
483
|
+
'vbscript:',
|
|
484
|
+
'@',
|
|
485
|
+
'\\',
|
|
486
|
+
'<',
|
|
487
|
+
'>',
|
|
488
|
+
'/*',
|
|
489
|
+
'*/',
|
|
490
|
+
];
|
|
491
|
+
/** Control characters, and the braces that would end a declaration list. */
|
|
492
|
+
// eslint-disable-next-line no-control-regex -- control characters are what this matches
|
|
493
|
+
const REJECTED_CHARACTERS = /[\u0000-\u001f\u007f{}]/;
|
|
494
|
+
/**
|
|
495
|
+
* React drops `!important` from a style object and warns about it, while the
|
|
496
|
+
* string-based ports would honour it — one authored value behaving differently
|
|
497
|
+
* per platform. It comes off everywhere instead, and the class-names field is
|
|
498
|
+
* the supported way to win a specificity fight.
|
|
499
|
+
*/
|
|
500
|
+
const IMPORTANT_FLAG = /\s*!\s*important\s*$/i;
|
|
501
|
+
/** Bounds well past anything typed by hand, so a pasted stylesheet cannot land here. */
|
|
502
|
+
const MAX_DECLARATIONS = 40;
|
|
503
|
+
const MAX_VALUE_LENGTH = 400;
|
|
504
|
+
const isUsableProperty = (property) => PROPERTY_NAME.test(property) && !REJECTED_PROPERTIES.has(property.toLowerCase());
|
|
505
|
+
const isUsableValue = (value) => {
|
|
506
|
+
if (value === '' || value.length > MAX_VALUE_LENGTH) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
if (REJECTED_CHARACTERS.test(value)) {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
const lowered = value.toLowerCase();
|
|
513
|
+
return !REJECTED_IN_VALUE.some((rejected) => lowered.includes(rejected));
|
|
514
|
+
};
|
|
515
|
+
/**
|
|
516
|
+
* A declaration to the pair it means, or `undefined` when it is malformed or
|
|
517
|
+
* carries something this module will not apply.
|
|
518
|
+
*/
|
|
519
|
+
const parseDeclaration = (declaration) => {
|
|
520
|
+
const separator = declaration.indexOf(':');
|
|
521
|
+
if (separator === -1) {
|
|
522
|
+
return undefined;
|
|
523
|
+
}
|
|
524
|
+
// Only the first colon splits: `background: linear-gradient(…)` keeps the rest.
|
|
525
|
+
const property = declaration.slice(0, separator).trim();
|
|
526
|
+
const value = declaration.slice(separator + 1).replace(IMPORTANT_FLAG, '').trim();
|
|
527
|
+
if (!isUsableProperty(property) || !isUsableValue(value)) {
|
|
528
|
+
return undefined;
|
|
529
|
+
}
|
|
530
|
+
return { property, value };
|
|
531
|
+
};
|
|
532
|
+
/**
|
|
533
|
+
* An authored CSS declaration list to the declarations that will be applied.
|
|
534
|
+
*
|
|
535
|
+
* The list is a denylist over values and an allowlist over property names,
|
|
536
|
+
* which is the same shape as `text-safety/validate-text-content.ts` in the
|
|
537
|
+
* composer and for the same reason: a person writing `color: #c00` should never
|
|
538
|
+
* have to think about this function, while the handful of constructs that turn
|
|
539
|
+
* a declaration into a request or a script are named and refused.
|
|
540
|
+
*
|
|
541
|
+
* A rejected declaration costs only itself. `color: red; behavior: url(x)`
|
|
542
|
+
* still sets the colour, because dropping the whole entry over one bad
|
|
543
|
+
* declaration would lose work the author can see is fine.
|
|
544
|
+
*/
|
|
545
|
+
function parseStyleDeclarations(value) {
|
|
546
|
+
if (typeof value !== 'string') {
|
|
547
|
+
return [];
|
|
548
|
+
}
|
|
549
|
+
const parsed = [];
|
|
550
|
+
const seen = new Set();
|
|
551
|
+
for (const declaration of value.split(DECLARATION_SEPARATOR)) {
|
|
552
|
+
if (declaration.trim() === '') {
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
const pair = parseDeclaration(declaration);
|
|
556
|
+
if (pair === undefined) {
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
// Last one wins, as it would in a real declaration list.
|
|
560
|
+
if (seen.has(pair.property)) {
|
|
561
|
+
parsed[parsed.findIndex((existing) => existing.property === pair.property)] = pair;
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
seen.add(pair.property);
|
|
565
|
+
parsed.push(pair);
|
|
566
|
+
if (parsed.length === MAX_DECLARATIONS) {
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return parsed;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Declarations back to a CSS string, for the places that want a `style`
|
|
574
|
+
* attribute rather than an object — which in this port is every one of them.
|
|
575
|
+
*/
|
|
576
|
+
function formatStyleDeclarations(declarations) {
|
|
577
|
+
return declarations.map(({ property, value }) => `${property}: ${value}`).join('; ');
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Turns a stored styling entry into element attributes, or `undefined` when the
|
|
582
|
+
* entry cannot produce any — missing, cleared, or holding nothing that survived
|
|
583
|
+
* the checks in `resolveClassNames` and `parseStyleDeclarations`. Callers render
|
|
584
|
+
* the plain text in that case, exactly as they do for a link that resolves to
|
|
585
|
+
* nothing.
|
|
586
|
+
*
|
|
587
|
+
* Knows nothing about text, markers, or any one component: this is the piece
|
|
588
|
+
* every component rendering inline markup shares.
|
|
589
|
+
*/
|
|
590
|
+
function resolveSpanStyleAttributes(item) {
|
|
591
|
+
if (!isSpanStyleItem(item)) {
|
|
592
|
+
return undefined;
|
|
593
|
+
}
|
|
594
|
+
const className = resolveClassNames(item.classNames);
|
|
595
|
+
const declarations = parseStyleDeclarations(item.declarations);
|
|
596
|
+
if (className === undefined && declarations.length === 0) {
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
return {
|
|
600
|
+
...(className !== undefined ? { className } : {}),
|
|
601
|
+
...(declarations.length > 0 ? { style: formatStyleDeclarations(declarations) } : {}),
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* `{` + optional mark letters + optional link index + optional `.` and styling
|
|
607
|
+
* index + `|` + text + `}`.
|
|
355
608
|
*
|
|
356
609
|
* Sticky, so it can be tried at one position without slicing the string. The
|
|
357
610
|
* text is everything up to the first `}`, which is what makes markers
|
|
358
611
|
* non-nesting.
|
|
612
|
+
*
|
|
613
|
+
* The dot is what tells the two indexes apart, and it reads as the CSS class
|
|
614
|
+
* selector it usually stands for. It cannot be confused with a link index,
|
|
615
|
+
* because a link index is bare digits and always comes first.
|
|
359
616
|
*/
|
|
360
|
-
const MARKER = /\{([a-z]*)(\d*)
|
|
617
|
+
const MARKER = /\{([a-z]*)(\d*)(?:\.(\d+))?\|([^}]*)\}/y;
|
|
361
618
|
/**
|
|
362
619
|
* One letter per mark. Order is not significant (`{bi1|x}` and `{ib1|x}` are
|
|
363
620
|
* the same span) and repeats are harmless, because the letters resolve to a
|
|
@@ -399,9 +656,9 @@ const resolveMarks = (letters) => {
|
|
|
399
656
|
* The grammar, and everything it deliberately leaves as literal text, is
|
|
400
657
|
* specified in `rulecms/__docs__/__ARCHITECTURE__/INLINE_MARKUP_ARCHITECTURE.md`.
|
|
401
658
|
* In short: a marker is `{`, then lowercase mark letters, then a link index,
|
|
402
|
-
* then `|`, then its text, then `}`. At least one
|
|
403
|
-
* must be present, and everything that does not match that shape
|
|
404
|
-
* verbatim — `{name}`, `{99}`, a lone `{`, JSON fragments, an unterminated
|
|
659
|
+
* then `.` and a styling index, then `|`, then its text, then `}`. At least one
|
|
660
|
+
* of those three must be present, and everything that does not match that shape
|
|
661
|
+
* stays verbatim — `{name}`, `{99}`, a lone `{`, JSON fragments, an unterminated
|
|
405
662
|
* marker, an unknown mark letter, and empty span text.
|
|
406
663
|
*
|
|
407
664
|
* Indexes are 1-based and normalize through a base-10 parse, so `{01|x}` and
|
|
@@ -429,7 +686,7 @@ function parseInlineMarkers(value) {
|
|
|
429
686
|
}
|
|
430
687
|
MARKER.lastIndex = open;
|
|
431
688
|
const match = MARKER.exec(value);
|
|
432
|
-
const run = match ? resolveRun(match[1], match[2], match[3]) : undefined;
|
|
689
|
+
const run = match ? resolveRun(match[1], match[2], match[3], match[4]) : undefined;
|
|
433
690
|
if (run === undefined) {
|
|
434
691
|
// Not a marker: keep the brace as text and look for the next one.
|
|
435
692
|
pendingText += value.slice(cursor, open + 1);
|
|
@@ -447,13 +704,19 @@ function parseInlineMarkers(value) {
|
|
|
447
704
|
/**
|
|
448
705
|
* One matched `{…|…}` to the run it means, or `undefined` when the match is
|
|
449
706
|
* not a marker after all and its opening brace is literal text.
|
|
707
|
+
*
|
|
708
|
+
* `styleDigits` is `undefined` when the marker carried no dot at all, which is
|
|
709
|
+
* different from a dot with nothing after it — the regex does not match that,
|
|
710
|
+
* so it never reaches here.
|
|
450
711
|
*/
|
|
451
|
-
const resolveRun = (letters, digits, text) => {
|
|
712
|
+
const resolveRun = (letters, digits, styleDigits, text) => {
|
|
452
713
|
if (letters === BREAK_TOKEN) {
|
|
453
714
|
// A break carries nothing. `{br|x}` is a mistake, not a break with text.
|
|
454
|
-
return digits === '' &&
|
|
715
|
+
return digits === '' && styleDigits === undefined && text === ''
|
|
716
|
+
? { kind: 'break' }
|
|
717
|
+
: undefined;
|
|
455
718
|
}
|
|
456
|
-
if (letters === '' && digits === '') {
|
|
719
|
+
if (letters === '' && digits === '' && styleDigits === undefined) {
|
|
457
720
|
return undefined;
|
|
458
721
|
}
|
|
459
722
|
// Empty text has no words to mark or link, and staying literal is what shows
|
|
@@ -469,6 +732,7 @@ const resolveRun = (letters, digits, text) => {
|
|
|
469
732
|
kind: 'span',
|
|
470
733
|
text,
|
|
471
734
|
...(digits === '' ? {} : { index: Number.parseInt(digits, 10) }),
|
|
735
|
+
...(styleDigits === undefined ? {} : { styleIndex: Number.parseInt(styleDigits, 10) }),
|
|
472
736
|
marks,
|
|
473
737
|
};
|
|
474
738
|
};
|
|
@@ -492,8 +756,14 @@ class InlineMarkupComponent {
|
|
|
492
756
|
const anchors = runs.map((run) => run.kind === 'span' && run.index !== undefined
|
|
493
757
|
? resolveLinkAttributes(getLinkItemAt(this.links, run.index))
|
|
494
758
|
: undefined);
|
|
759
|
+
const spanStyles = runs.map((run) => run.kind === 'span' && run.styleIndex !== undefined
|
|
760
|
+
? resolveSpanStyleAttributes(getSpanStyleItemAt(this.spanStyles, run.styleIndex))
|
|
761
|
+
: undefined);
|
|
495
762
|
const needsElement = runs.some((run, position) => run.kind === 'break' ||
|
|
496
|
-
(run.kind === 'span' &&
|
|
763
|
+
(run.kind === 'span' &&
|
|
764
|
+
(anchors[position] !== undefined ||
|
|
765
|
+
spanStyles[position] !== undefined ||
|
|
766
|
+
hasMark(run.marks))));
|
|
497
767
|
if (!needsElement) {
|
|
498
768
|
this.renderer.appendChild(this.host.nativeElement, this.renderer.createText(runs.map(plainTextOf).join('')));
|
|
499
769
|
return;
|
|
@@ -507,10 +777,15 @@ class InlineMarkupComponent {
|
|
|
507
777
|
this.renderer.appendChild(this.host.nativeElement, this.renderer.createElement('br'));
|
|
508
778
|
return;
|
|
509
779
|
}
|
|
510
|
-
this.renderer.appendChild(this.host.nativeElement, this.renderSpan(run, anchors[position]));
|
|
780
|
+
this.renderer.appendChild(this.host.nativeElement, this.renderSpan(run, anchors[position], spanStyles[position]));
|
|
511
781
|
});
|
|
512
782
|
}
|
|
513
|
-
|
|
783
|
+
/**
|
|
784
|
+
* The anchor stays innermost and a styling entry becomes the outermost
|
|
785
|
+
* element: the marks say what these words *are*, and the styling says how
|
|
786
|
+
* this run of words looks, which is the container of the other two.
|
|
787
|
+
*/
|
|
788
|
+
renderSpan(run, anchor, spanStyle) {
|
|
514
789
|
let node = anchor === undefined
|
|
515
790
|
? this.renderer.createText(run.text)
|
|
516
791
|
: this.createAnchor(anchor, run.text);
|
|
@@ -522,7 +797,16 @@ class InlineMarkupComponent {
|
|
|
522
797
|
node = wrapper;
|
|
523
798
|
}
|
|
524
799
|
}
|
|
525
|
-
|
|
800
|
+
if (spanStyle === undefined) {
|
|
801
|
+
return node;
|
|
802
|
+
}
|
|
803
|
+
const styled = this.renderer.createElement('span');
|
|
804
|
+
if (spanStyle.className)
|
|
805
|
+
this.renderer.setAttribute(styled, 'class', spanStyle.className);
|
|
806
|
+
if (spanStyle.style)
|
|
807
|
+
this.renderer.setAttribute(styled, 'style', spanStyle.style);
|
|
808
|
+
this.renderer.appendChild(styled, node);
|
|
809
|
+
return styled;
|
|
526
810
|
}
|
|
527
811
|
createAnchor(anchor, text) {
|
|
528
812
|
const el = this.renderer.createElement('a');
|
|
@@ -553,7 +837,7 @@ class InlineMarkupComponent {
|
|
|
553
837
|
}
|
|
554
838
|
}
|
|
555
839
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InlineMarkupComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
556
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: InlineMarkupComponent, isStandalone: true, selector: "rulecms-inline-markup", inputs: { text: "text", links: "links" }, host: { styleAttribute: "display: contents" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true }); }
|
|
840
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: InlineMarkupComponent, isStandalone: true, selector: "rulecms-inline-markup", inputs: { text: "text", links: "links", spanStyles: "spanStyles" }, host: { styleAttribute: "display: contents" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true }); }
|
|
557
841
|
}
|
|
558
842
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InlineMarkupComponent, decorators: [{
|
|
559
843
|
type: Component,
|
|
@@ -567,6 +851,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
567
851
|
type: Input
|
|
568
852
|
}], links: [{
|
|
569
853
|
type: Input
|
|
854
|
+
}], spanStyles: [{
|
|
855
|
+
type: Input
|
|
570
856
|
}] } });
|
|
571
857
|
|
|
572
858
|
class HtmlTagComponent {
|
|
@@ -646,6 +932,13 @@ class RTextComponent {
|
|
|
646
932
|
get links() {
|
|
647
933
|
return this.componentAttributes?.['links-3-resolutions'];
|
|
648
934
|
}
|
|
935
|
+
/**
|
|
936
|
+
* The two index markers — `{n|…}` into the link list and `{.n|…}` into the
|
|
937
|
+
* styling list — resolve by 1-based position against separate attributes.
|
|
938
|
+
*/
|
|
939
|
+
get spanStyles() {
|
|
940
|
+
return this.componentAttributes?.['inline-styles-3-resolutions'];
|
|
941
|
+
}
|
|
649
942
|
get tag() {
|
|
650
943
|
return resolveEnclosingTag(this.componentAttributes);
|
|
651
944
|
}
|
|
@@ -653,12 +946,12 @@ class RTextComponent {
|
|
|
653
946
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: RTextComponent, isStandalone: true, selector: "rulecms-r-text", inputs: { componentAttributes: "componentAttributes", styleProps: "styleProps", className: "className" }, host: { styleAttribute: "display: contents" }, ngImport: i0, template: `
|
|
654
947
|
@if (tag) {
|
|
655
948
|
<rulecms-html-tag [tag]="tag" [styleProps]="styleProps" [className]="className">
|
|
656
|
-
<rulecms-inline-markup [text]="content" [links]="links" />
|
|
949
|
+
<rulecms-inline-markup [text]="content" [links]="links" [spanStyles]="spanStyles" />
|
|
657
950
|
</rulecms-html-tag>
|
|
658
951
|
} @else {
|
|
659
|
-
<rulecms-inline-markup [text]="content" [links]="links" />
|
|
952
|
+
<rulecms-inline-markup [text]="content" [links]="links" [spanStyles]="spanStyles" />
|
|
660
953
|
}
|
|
661
|
-
`, isInline: true, dependencies: [{ kind: "component", type: InlineMarkupComponent, selector: "rulecms-inline-markup", inputs: ["text", "links"] }, { kind: "component", type: HtmlTagComponent, selector: "rulecms-html-tag", inputs: ["tag", "styleProps", "className"] }] }); }
|
|
954
|
+
`, isInline: true, dependencies: [{ kind: "component", type: InlineMarkupComponent, selector: "rulecms-inline-markup", inputs: ["text", "links", "spanStyles"] }, { kind: "component", type: HtmlTagComponent, selector: "rulecms-html-tag", inputs: ["tag", "styleProps", "className"] }] }); }
|
|
662
955
|
}
|
|
663
956
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: RTextComponent, decorators: [{
|
|
664
957
|
type: Component,
|
|
@@ -669,10 +962,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
669
962
|
template: `
|
|
670
963
|
@if (tag) {
|
|
671
964
|
<rulecms-html-tag [tag]="tag" [styleProps]="styleProps" [className]="className">
|
|
672
|
-
<rulecms-inline-markup [text]="content" [links]="links" />
|
|
965
|
+
<rulecms-inline-markup [text]="content" [links]="links" [spanStyles]="spanStyles" />
|
|
673
966
|
</rulecms-html-tag>
|
|
674
967
|
} @else {
|
|
675
|
-
<rulecms-inline-markup [text]="content" [links]="links" />
|
|
968
|
+
<rulecms-inline-markup [text]="content" [links]="links" [spanStyles]="spanStyles" />
|
|
676
969
|
}
|
|
677
970
|
`,
|
|
678
971
|
host: { style: 'display: contents' },
|
|
@@ -724,6 +1017,12 @@ const attributeEditModeConfigs$9 = [
|
|
|
724
1017
|
subHeading: 'Links this text can point at. To link part of the text, wrap those words in {1|linked text}, where the number is the position of the entry in this list counting from 1; clearing an entry leaves its position in place so the other numbers keep pointing where they did, for 3 different device resolutions',
|
|
725
1018
|
defaultValues: {},
|
|
726
1019
|
},
|
|
1020
|
+
{
|
|
1021
|
+
name: 'inline-styles-3-resolutions',
|
|
1022
|
+
heading: 'Class Names & Styles',
|
|
1023
|
+
subHeading: 'Class names and CSS this text can apply to part of itself, e.g. to give a few words their own colour. To apply an entry, wrap those words in {.1|styled text}, where the number is the position of the entry in this list counting from 1; clearing an entry leaves its position in place so the other numbers keep pointing where they did, for 3 different device resolutions',
|
|
1024
|
+
defaultValues: {},
|
|
1025
|
+
},
|
|
727
1026
|
];
|
|
728
1027
|
|
|
729
1028
|
const ComponentIdentifiers = {
|
|
@@ -3223,6 +3522,7 @@ const LIST_MARKER_ATTRIBUTE = 'list-marker-3-resolutions';
|
|
|
3223
3522
|
const LIST_START_ATTRIBUTE = 'list-start-3-resolutions';
|
|
3224
3523
|
const LIST_REVERSED_ATTRIBUTE = 'list-reversed-3-resolutions';
|
|
3225
3524
|
const LIST_LINKS_ATTRIBUTE = 'list-links-3-resolutions';
|
|
3525
|
+
const LIST_INLINE_STYLES_ATTRIBUTE = 'list-inline-styles-3-resolutions';
|
|
3226
3526
|
/** What a freshly dropped list shows before the author types anything. */
|
|
3227
3527
|
const DEFAULT_LIST_ITEMS = 'First item\nSecond item\nThird item';
|
|
3228
3528
|
const LIST_KINDS = ['unordered', 'ordered'];
|
|
@@ -3315,6 +3615,9 @@ class RListComponent {
|
|
|
3315
3615
|
get links() {
|
|
3316
3616
|
return this.componentAttributes?.[LIST_LINKS_ATTRIBUTE];
|
|
3317
3617
|
}
|
|
3618
|
+
get spanStyles() {
|
|
3619
|
+
return this.componentAttributes?.[LIST_INLINE_STYLES_ATTRIBUTE];
|
|
3620
|
+
}
|
|
3318
3621
|
get style() {
|
|
3319
3622
|
return {
|
|
3320
3623
|
...(this.marker !== undefined ? { listStyleType: this.marker } : {}),
|
|
@@ -3339,7 +3642,7 @@ class RListComponent {
|
|
|
3339
3642
|
<ol [ngStyle]="style" [class]="className || undefined" [attr.start]="start" [attr.reversed]="reversed ? true : null">
|
|
3340
3643
|
@for (item of items; track $index) {
|
|
3341
3644
|
<li>
|
|
3342
|
-
<rulecms-inline-markup [text]="item" [links]="links" />
|
|
3645
|
+
<rulecms-inline-markup [text]="item" [links]="links" [spanStyles]="spanStyles" />
|
|
3343
3646
|
</li>
|
|
3344
3647
|
}
|
|
3345
3648
|
</ol>
|
|
@@ -3347,12 +3650,12 @@ class RListComponent {
|
|
|
3347
3650
|
<ul [ngStyle]="style" [class]="className || undefined">
|
|
3348
3651
|
@for (item of items; track $index) {
|
|
3349
3652
|
<li>
|
|
3350
|
-
<rulecms-inline-markup [text]="item" [links]="links" />
|
|
3653
|
+
<rulecms-inline-markup [text]="item" [links]="links" [spanStyles]="spanStyles" />
|
|
3351
3654
|
</li>
|
|
3352
3655
|
}
|
|
3353
3656
|
</ul>
|
|
3354
3657
|
}
|
|
3355
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: InlineMarkupComponent, selector: "rulecms-inline-markup", inputs: ["text", "links"] }] }); }
|
|
3658
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: InlineMarkupComponent, selector: "rulecms-inline-markup", inputs: ["text", "links", "spanStyles"] }] }); }
|
|
3356
3659
|
}
|
|
3357
3660
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: RListComponent, decorators: [{
|
|
3358
3661
|
type: Component,
|
|
@@ -3365,7 +3668,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
3365
3668
|
<ol [ngStyle]="style" [class]="className || undefined" [attr.start]="start" [attr.reversed]="reversed ? true : null">
|
|
3366
3669
|
@for (item of items; track $index) {
|
|
3367
3670
|
<li>
|
|
3368
|
-
<rulecms-inline-markup [text]="item" [links]="links" />
|
|
3671
|
+
<rulecms-inline-markup [text]="item" [links]="links" [spanStyles]="spanStyles" />
|
|
3369
3672
|
</li>
|
|
3370
3673
|
}
|
|
3371
3674
|
</ol>
|
|
@@ -3373,7 +3676,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
3373
3676
|
<ul [ngStyle]="style" [class]="className || undefined">
|
|
3374
3677
|
@for (item of items; track $index) {
|
|
3375
3678
|
<li>
|
|
3376
|
-
<rulecms-inline-markup [text]="item" [links]="links" />
|
|
3679
|
+
<rulecms-inline-markup [text]="item" [links]="links" [spanStyles]="spanStyles" />
|
|
3377
3680
|
</li>
|
|
3378
3681
|
}
|
|
3379
3682
|
</ul>
|
|
@@ -3436,6 +3739,10 @@ const defaultAttributeValues$2 = [
|
|
|
3436
3739
|
name: LIST_LINKS_ATTRIBUTE,
|
|
3437
3740
|
defaultValues: {},
|
|
3438
3741
|
},
|
|
3742
|
+
{
|
|
3743
|
+
name: LIST_INLINE_STYLES_ATTRIBUTE,
|
|
3744
|
+
defaultValues: {},
|
|
3745
|
+
},
|
|
3439
3746
|
];
|
|
3440
3747
|
|
|
3441
3748
|
/**
|
|
@@ -3482,6 +3789,12 @@ const attributeEditModeConfigs$2 = [
|
|
|
3482
3789
|
subHeading: 'Links the items can point at. To link part of an item, wrap those words in {1|linked text}, where the number is the position of the entry in this list counting from 1; clearing an entry leaves its position in place so the other numbers keep pointing where they did, for 3 different device resolutions',
|
|
3483
3790
|
defaultValues: {},
|
|
3484
3791
|
},
|
|
3792
|
+
{
|
|
3793
|
+
name: LIST_INLINE_STYLES_ATTRIBUTE,
|
|
3794
|
+
heading: 'Class Names & Styles',
|
|
3795
|
+
subHeading: 'Class names and CSS the items can apply to part of themselves, e.g. to give a few words their own colour. To apply an entry, wrap those words in {.1|styled text}, where the number is the position of the entry in this list counting from 1; clearing an entry leaves its position in place so the other numbers keep pointing where they did, for 3 different device resolutions',
|
|
3796
|
+
defaultValues: {},
|
|
3797
|
+
},
|
|
3485
3798
|
];
|
|
3486
3799
|
|
|
3487
3800
|
const displayCardEntry$2 = {
|
|
@@ -3528,6 +3841,7 @@ const displayCardEntry$2 = {
|
|
|
3528
3841
|
const ACCORDION_SUMMARY_ATTRIBUTE = 'accordion-summary-3-resolutions';
|
|
3529
3842
|
const ACCORDION_DETAIL_ATTRIBUTE = 'accordion-detail-3-resolutions';
|
|
3530
3843
|
const ACCORDION_LINKS_ATTRIBUTE = 'accordion-links-3-resolutions';
|
|
3844
|
+
const ACCORDION_INLINE_STYLES_ATTRIBUTE = 'accordion-inline-styles-3-resolutions';
|
|
3531
3845
|
const ACCORDION_OPEN_ATTRIBUTE = 'accordion-open-3-resolutions';
|
|
3532
3846
|
const ACCORDION_HEADING_LEVEL_ATTRIBUTE = 'accordion-heading-level-3-resolutions';
|
|
3533
3847
|
/** What a freshly dropped accordion shows before the author types anything. */
|
|
@@ -3655,6 +3969,9 @@ class RAccordionComponent {
|
|
|
3655
3969
|
get links() {
|
|
3656
3970
|
return this.componentAttributes?.[ACCORDION_LINKS_ATTRIBUTE];
|
|
3657
3971
|
}
|
|
3972
|
+
get spanStyles() {
|
|
3973
|
+
return this.componentAttributes?.[ACCORDION_INLINE_STYLES_ATTRIBUTE];
|
|
3974
|
+
}
|
|
3658
3975
|
get open() {
|
|
3659
3976
|
return resolveAccordionOpen(this.componentAttributes);
|
|
3660
3977
|
}
|
|
@@ -3675,12 +3992,12 @@ class RAccordionComponent {
|
|
|
3675
3992
|
</summary>
|
|
3676
3993
|
@for (paragraph of detail; track $index) {
|
|
3677
3994
|
<p>
|
|
3678
|
-
<rulecms-inline-markup [text]="paragraph" [links]="links" />
|
|
3995
|
+
<rulecms-inline-markup [text]="paragraph" [links]="links" [spanStyles]="spanStyles" />
|
|
3679
3996
|
</p>
|
|
3680
3997
|
}
|
|
3681
3998
|
<ng-content />
|
|
3682
3999
|
</details>
|
|
3683
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: InlineMarkupComponent, selector: "rulecms-inline-markup", inputs: ["text", "links"] }, { kind: "component", type: HtmlTagComponent, selector: "rulecms-html-tag", inputs: ["tag", "styleProps", "className"] }] }); }
|
|
4000
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: InlineMarkupComponent, selector: "rulecms-inline-markup", inputs: ["text", "links", "spanStyles"] }, { kind: "component", type: HtmlTagComponent, selector: "rulecms-html-tag", inputs: ["tag", "styleProps", "className"] }] }); }
|
|
3684
4001
|
}
|
|
3685
4002
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: RAccordionComponent, decorators: [{
|
|
3686
4003
|
type: Component,
|
|
@@ -3701,7 +4018,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
3701
4018
|
</summary>
|
|
3702
4019
|
@for (paragraph of detail; track $index) {
|
|
3703
4020
|
<p>
|
|
3704
|
-
<rulecms-inline-markup [text]="paragraph" [links]="links" />
|
|
4021
|
+
<rulecms-inline-markup [text]="paragraph" [links]="links" [spanStyles]="spanStyles" />
|
|
3705
4022
|
</p>
|
|
3706
4023
|
}
|
|
3707
4024
|
<ng-content />
|
|
@@ -3761,6 +4078,10 @@ const defaultAttributeValues$1 = [
|
|
|
3761
4078
|
name: ACCORDION_LINKS_ATTRIBUTE,
|
|
3762
4079
|
defaultValues: {},
|
|
3763
4080
|
},
|
|
4081
|
+
{
|
|
4082
|
+
name: ACCORDION_INLINE_STYLES_ATTRIBUTE,
|
|
4083
|
+
defaultValues: {},
|
|
4084
|
+
},
|
|
3764
4085
|
];
|
|
3765
4086
|
|
|
3766
4087
|
/**
|
|
@@ -3807,6 +4128,12 @@ const attributeEditModeConfigs$1 = [
|
|
|
3807
4128
|
subHeading: 'Links the detail can point at. To link part of the detail, wrap those words in {1|linked text}, where the number is the position of the entry in this list counting from 1; clearing an entry leaves its position in place so the other numbers keep pointing where they did, for 3 different device resolutions',
|
|
3808
4129
|
defaultValues: {},
|
|
3809
4130
|
},
|
|
4131
|
+
{
|
|
4132
|
+
name: ACCORDION_INLINE_STYLES_ATTRIBUTE,
|
|
4133
|
+
heading: 'Class Names & Styles',
|
|
4134
|
+
subHeading: 'Class names and CSS the detail can apply to part of itself, e.g. to give a few words their own colour. To apply an entry, wrap those words in {.1|styled text}, where the number is the position of the entry in this list counting from 1; clearing an entry leaves its position in place so the other numbers keep pointing where they did, for 3 different device resolutions',
|
|
4135
|
+
defaultValues: {},
|
|
4136
|
+
},
|
|
3810
4137
|
];
|
|
3811
4138
|
|
|
3812
4139
|
const displayCardEntry$1 = {
|
|
@@ -4169,6 +4496,7 @@ const componentNameToModifyAttribute = {
|
|
|
4169
4496
|
'embed-loading-3-resolutions': 'embed-loading-3-resolutions',
|
|
4170
4497
|
'enclosing-tag-3-resolutions': 'enclosing-tag-3-resolutions',
|
|
4171
4498
|
'links-3-resolutions': 'links-3-resolutions',
|
|
4499
|
+
'inline-styles-3-resolutions': 'inline-styles-3-resolutions',
|
|
4172
4500
|
// r-list owns its own attribute names — one component per documented
|
|
4173
4501
|
// setting — but reuses existing editors wherever one fits: the multi-line
|
|
4174
4502
|
// text field for its items, the numbered link list for its links, and the
|
|
@@ -4181,6 +4509,7 @@ const componentNameToModifyAttribute = {
|
|
|
4181
4509
|
'list-start-3-resolutions': 'image-text-3-resolutions',
|
|
4182
4510
|
'list-reversed-3-resolutions': 'list-reversed-3-resolutions',
|
|
4183
4511
|
'list-links-3-resolutions': 'links-3-resolutions',
|
|
4512
|
+
'list-inline-styles-3-resolutions': 'inline-styles-3-resolutions',
|
|
4184
4513
|
// r-accordion owns its own attribute names — one component per documented
|
|
4185
4514
|
// setting — and reuses existing editors for everything that fits: the
|
|
4186
4515
|
// multi-line text field for the summary and the detail, and the numbered
|
|
@@ -4191,6 +4520,7 @@ const componentNameToModifyAttribute = {
|
|
|
4191
4520
|
'accordion-open-3-resolutions': 'accordion-open-3-resolutions',
|
|
4192
4521
|
'accordion-heading-level-3-resolutions': 'accordion-heading-level-3-resolutions',
|
|
4193
4522
|
'accordion-links-3-resolutions': 'links-3-resolutions',
|
|
4523
|
+
'accordion-inline-styles-3-resolutions': 'inline-styles-3-resolutions',
|
|
4194
4524
|
// r-mount: the name is a constrained identifier and reuses the shared
|
|
4195
4525
|
// plain-text editor; the props list is a repeatable key/type/value row
|
|
4196
4526
|
// and needs its own editor.
|
|
@@ -4354,6 +4684,9 @@ const BUTTON_LIBRARY_STYLESHEET = `
|
|
|
4354
4684
|
}
|
|
4355
4685
|
`.trim();
|
|
4356
4686
|
|
|
4687
|
+
/** Published package version. `npm version` keeps this in sync with package.json. */
|
|
4688
|
+
const libraryVersion = '0.4.1';
|
|
4689
|
+
|
|
4357
4690
|
/**
|
|
4358
4691
|
* ComponentLibraryModule conformance (the @rulecms/widget-angular contract).
|
|
4359
4692
|
*
|
|
@@ -4367,7 +4700,7 @@ const BUTTON_LIBRARY_STYLESHEET = `
|
|
|
4367
4700
|
*/
|
|
4368
4701
|
const manifest = {
|
|
4369
4702
|
id: 'default',
|
|
4370
|
-
version:
|
|
4703
|
+
version: libraryVersion,
|
|
4371
4704
|
angularPeerRange: '>=17.0.0',
|
|
4372
4705
|
};
|
|
4373
4706
|
/** The render surface: component type → renderable entry. */
|
|
@@ -4399,17 +4732,18 @@ const markLetters = (marks) => MARK_LETTERS.filter(([mark]) => marks[mark])
|
|
|
4399
4732
|
.map(([, letter]) => letter)
|
|
4400
4733
|
.join('');
|
|
4401
4734
|
/**
|
|
4402
|
-
* A span back to its marker. Text that carries
|
|
4403
|
-
* emitted bare: a marker with nothing to say would only be noise an author
|
|
4404
|
-
* to read past, and it round-trips to the same runs either way.
|
|
4735
|
+
* A span back to its marker. Text that carries no marks, no link and no styling
|
|
4736
|
+
* is emitted bare: a marker with nothing to say would only be noise an author
|
|
4737
|
+
* has to read past, and it round-trips to the same runs either way.
|
|
4405
4738
|
*/
|
|
4406
4739
|
const formatSpan = (run) => {
|
|
4407
4740
|
const letters = markLetters(run.marks);
|
|
4408
4741
|
const index = run.index === undefined ? '' : `${run.index}`;
|
|
4409
|
-
|
|
4742
|
+
const styleIndex = run.styleIndex === undefined ? '' : `.${run.styleIndex}`;
|
|
4743
|
+
if (letters === '' && index === '' && styleIndex === '') {
|
|
4410
4744
|
return run.text;
|
|
4411
4745
|
}
|
|
4412
|
-
return `{${letters}${index}|${run.text}}`;
|
|
4746
|
+
return `{${letters}${index}${styleIndex}|${run.text}}`;
|
|
4413
4747
|
};
|
|
4414
4748
|
/** One run as authored text. */
|
|
4415
4749
|
function formatInlineMarker(run) {
|
|
@@ -4439,5 +4773,5 @@ function serializeInlineMarkers(runs) {
|
|
|
4439
4773
|
* Generated bundle index. Do not edit.
|
|
4440
4774
|
*/
|
|
4441
4775
|
|
|
4442
|
-
export { ACCORDION_HEADING_LEVELS, BLOCK_ENCLOSING_TAGS, BUTTON_BORDER_VARIABLE, BUTTON_CLICK_HANDLER_PROP, BUTTON_CSS_VARIABLE_PREFIX, BUTTON_FILL_ACTIVE_VARIABLE, BUTTON_FILL_HOVER_VARIABLE, BUTTON_FILL_VARIABLE, BUTTON_INK_HOVER_VARIABLE, BUTTON_INK_VARIABLE, BUTTON_LIBRARY_STYLESHEET, BUTTON_RING_VARIABLE, BUTTON_SIZES, BUTTON_TONES, BUTTON_VARIANTS, ComponentIdentifiers, DEFAULT_ACCORDION_HEADING_LEVEL, DEFAULT_BUTTON_LABEL, DEFAULT_BUTTON_PRESET, DEFAULT_EMBED_LOADING, DEFAULT_ICON_POSITION, DEFAULT_LIST_KIND, EMBED_ASPECT_RATIOS, EMBED_LOADING_VALUES, EMBED_PROVIDERS, EMBED_UNSHAPED_HEIGHT, ENCLOSING_TAGS, ICON_POSITIONS, INLINE_ENCLOSING_TAGS, InlineMarkupComponent, LIST_KINDS, LIST_MARKERS, MOUNT_NAME_ATTRIBUTE, MOUNT_NAME_PATTERN, MOUNT_PROPS_ATTRIBUTE, MOUNT_PROP_TYPES, REJECTED_HREF_SCHEMES, SIZE_SCALES, TONE_PALETTES, applyButtonColumnStyles, buildButtonPresetStyles, buildButtonRenderStyles, disabledStyles as buttonDisabledStyles, cardGroups$1 as cardGroups, components, editor, formatInlineMarker, getComponentMetadataForEditing, getPreviewCardGroups, getPreviewComponents, getSourceComponentsPlugin, isAllowedEmbedUrl, isAllowedMountName, isBlockEnclosingTag, isButtonSize, isButtonTone, isButtonVariant, isEnclosingTag, isForbiddenMountPropKey, isSafeHref, manifest, normaliseHost, parseInlineLinkMarkers, parseInlineMarkers, resolveButtonPreset, resolveEmbedUrl, resolveLinkAttributes, resolveMountName, resolveMountProps, serializeInlineMarkers, stylesheet, toneCssVariable };
|
|
4776
|
+
export { ACCORDION_HEADING_LEVELS, BLOCK_ENCLOSING_TAGS, BUTTON_BORDER_VARIABLE, BUTTON_CLICK_HANDLER_PROP, BUTTON_CSS_VARIABLE_PREFIX, BUTTON_FILL_ACTIVE_VARIABLE, BUTTON_FILL_HOVER_VARIABLE, BUTTON_FILL_VARIABLE, BUTTON_INK_HOVER_VARIABLE, BUTTON_INK_VARIABLE, BUTTON_LIBRARY_STYLESHEET, BUTTON_RING_VARIABLE, BUTTON_SIZES, BUTTON_TONES, BUTTON_VARIANTS, ComponentIdentifiers, DEFAULT_ACCORDION_HEADING_LEVEL, DEFAULT_BUTTON_LABEL, DEFAULT_BUTTON_PRESET, DEFAULT_EMBED_LOADING, DEFAULT_ICON_POSITION, DEFAULT_LIST_KIND, EMBED_ASPECT_RATIOS, EMBED_LOADING_VALUES, EMBED_PROVIDERS, EMBED_UNSHAPED_HEIGHT, ENCLOSING_TAGS, ICON_POSITIONS, INLINE_ENCLOSING_TAGS, InlineMarkupComponent, LIST_KINDS, LIST_MARKERS, MOUNT_NAME_ATTRIBUTE, MOUNT_NAME_PATTERN, MOUNT_PROPS_ATTRIBUTE, MOUNT_PROP_TYPES, REJECTED_HREF_SCHEMES, SIZE_SCALES, TONE_PALETTES, applyButtonColumnStyles, buildButtonPresetStyles, buildButtonRenderStyles, disabledStyles as buttonDisabledStyles, cardGroups$1 as cardGroups, components, editor, formatInlineMarker, formatStyleDeclarations, getComponentMetadataForEditing, getPreviewCardGroups, getPreviewComponents, getSourceComponentsPlugin, getSpanStyleItemAt, isAllowedEmbedUrl, isAllowedMountName, isBlockEnclosingTag, isButtonSize, isButtonTone, isButtonVariant, isEmptySpanStyleItem, isEnclosingTag, isForbiddenMountPropKey, isSafeHref, isSpanStyleItem, manifest, normaliseHost, parseInlineLinkMarkers, parseInlineMarkers, parseStyleDeclarations, resolveButtonPreset, resolveClassNames, resolveEmbedUrl, resolveLinkAttributes, resolveMountName, resolveMountProps, resolveSpanStyleAttributes, serializeInlineMarkers, stylesheet, toneCssVariable };
|
|
4443
4777
|
//# sourceMappingURL=rulecms-source-components-angular.mjs.map
|