@pallasoft/ps-utilities 2.21.0 → 2.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/http-service.d.ts +1 -0
- package/dist/client/http-service.js +1 -1
- package/dist/common/constants/html-entity-names.d.ts +1 -0
- package/dist/common/constants/html-entity-names.js +34 -0
- package/dist/common/constants/html-heading-styles.d.ts +1 -0
- package/dist/common/constants/html-heading-styles.js +11 -0
- package/dist/common/constants/html-text-config.d.ts +76 -0
- package/dist/common/constants/html-text-config.js +136 -0
- package/dist/common/constants/html-token-kind.d.ts +5 -0
- package/dist/common/constants/html-token-kind.js +8 -0
- package/dist/common/constants/portable-text-config.d.ts +16 -0
- package/dist/common/constants/portable-text-config.js +15 -1
- package/dist/common/html-entity-service.d.ts +6 -0
- package/dist/common/html-entity-service.js +34 -0
- package/dist/common/html-style-service.d.ts +12 -0
- package/dist/common/html-style-service.js +92 -0
- package/dist/common/html-token-service.d.ts +8 -0
- package/dist/common/html-token-service.js +90 -0
- package/dist/common/index.d.ts +1 -0
- package/dist/common/index.js +1 -0
- package/dist/common/portable-text-html-service.d.ts +28 -0
- package/dist/common/portable-text-html-service.js +392 -0
- package/dist/common/portable-text-link-service.d.ts +7 -0
- package/dist/common/portable-text-link-service.js +42 -0
- package/dist/common/portable-text-service.d.ts +7 -4
- package/dist/common/portable-text-service.js +15 -10
- package/dist/common/portable-text-tracking-service.d.ts +7 -0
- package/dist/common/portable-text-tracking-service.js +45 -0
- package/dist/esm/client/http-service.js +1 -1
- package/dist/esm/common/constants/html-entity-names.js +31 -0
- package/dist/esm/common/constants/html-heading-styles.js +8 -0
- package/dist/esm/common/constants/html-text-config.js +133 -0
- package/dist/esm/common/constants/html-token-kind.js +5 -0
- package/dist/esm/common/constants/portable-text-config.js +15 -1
- package/dist/esm/common/html-entity-service.js +25 -0
- package/dist/esm/common/html-style-service.js +85 -0
- package/dist/esm/common/html-token-service.js +83 -0
- package/dist/esm/common/index.js +1 -0
- package/dist/esm/common/portable-text-html-service.js +375 -0
- package/dist/esm/common/portable-text-link-service.js +35 -0
- package/dist/esm/common/portable-text-service.js +14 -9
- package/dist/esm/common/portable-text-tracking-service.js +34 -0
- package/dist/esm/models/html-attributes-data.js +1 -0
- package/dist/esm/models/html-close-token-data.js +1 -0
- package/dist/esm/models/html-context-data.js +1 -0
- package/dist/esm/models/html-conversion-data.js +1 -0
- package/dist/esm/models/html-declarations-data.js +1 -0
- package/dist/esm/models/html-frame-data.js +1 -0
- package/dist/esm/models/html-open-token-data.js +1 -0
- package/dist/esm/models/html-run-data.js +1 -0
- package/dist/esm/models/html-text-token-data.js +1 -0
- package/dist/esm/models/html-token-data.js +1 -0
- package/dist/esm/models/portable-text-block-link.js +1 -0
- package/dist/esm/models/portable-text-content-data.js +1 -0
- package/dist/esm/models/portable-text-image-data.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/models/html-attributes-data.d.ts +1 -0
- package/dist/models/html-attributes-data.js +2 -0
- package/dist/models/html-close-token-data.d.ts +5 -0
- package/dist/models/html-close-token-data.js +2 -0
- package/dist/models/html-context-data.d.ts +6 -0
- package/dist/models/html-context-data.js +2 -0
- package/dist/models/html-conversion-data.d.ts +12 -0
- package/dist/models/html-conversion-data.js +2 -0
- package/dist/models/html-declarations-data.d.ts +1 -0
- package/dist/models/html-declarations-data.js +2 -0
- package/dist/models/html-frame-data.d.ts +13 -0
- package/dist/models/html-frame-data.js +2 -0
- package/dist/models/html-open-token-data.d.ts +8 -0
- package/dist/models/html-open-token-data.js +2 -0
- package/dist/models/html-run-data.d.ts +9 -0
- package/dist/models/html-run-data.js +2 -0
- package/dist/models/html-text-token-data.d.ts +5 -0
- package/dist/models/html-text-token-data.js +2 -0
- package/dist/models/html-token-data.d.ts +4 -0
- package/dist/models/html-token-data.js +2 -0
- package/dist/models/portable-text-block-link.d.ts +7 -0
- package/dist/models/portable-text-block-link.js +2 -0
- package/dist/models/portable-text-content-data.d.ts +3 -0
- package/dist/models/portable-text-content-data.js +2 -0
- package/dist/models/portable-text-image-data.d.ts +7 -0
- package/dist/models/portable-text-image-data.js +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const HtmlTextConfig = {
|
|
2
|
+
skipTags: [
|
|
3
|
+
'head',
|
|
4
|
+
'script',
|
|
5
|
+
'style',
|
|
6
|
+
'title',
|
|
7
|
+
'noscript',
|
|
8
|
+
'template',
|
|
9
|
+
'svg',
|
|
10
|
+
'iframe',
|
|
11
|
+
'object',
|
|
12
|
+
'embed',
|
|
13
|
+
'video',
|
|
14
|
+
'audio',
|
|
15
|
+
'canvas',
|
|
16
|
+
'select',
|
|
17
|
+
'textarea',
|
|
18
|
+
],
|
|
19
|
+
rawTextTags: ['script', 'style', 'title', 'textarea'],
|
|
20
|
+
voidTags: [
|
|
21
|
+
'area',
|
|
22
|
+
'base',
|
|
23
|
+
'br',
|
|
24
|
+
'col',
|
|
25
|
+
'embed',
|
|
26
|
+
'hr',
|
|
27
|
+
'img',
|
|
28
|
+
'input',
|
|
29
|
+
'link',
|
|
30
|
+
'meta',
|
|
31
|
+
'param',
|
|
32
|
+
'source',
|
|
33
|
+
'track',
|
|
34
|
+
'wbr',
|
|
35
|
+
],
|
|
36
|
+
blockTags: [
|
|
37
|
+
'address',
|
|
38
|
+
'article',
|
|
39
|
+
'aside',
|
|
40
|
+
'body',
|
|
41
|
+
'center',
|
|
42
|
+
'dd',
|
|
43
|
+
'details',
|
|
44
|
+
'div',
|
|
45
|
+
'dl',
|
|
46
|
+
'dt',
|
|
47
|
+
'fieldset',
|
|
48
|
+
'figcaption',
|
|
49
|
+
'figure',
|
|
50
|
+
'footer',
|
|
51
|
+
'form',
|
|
52
|
+
'header',
|
|
53
|
+
'html',
|
|
54
|
+
'main',
|
|
55
|
+
'nav',
|
|
56
|
+
'p',
|
|
57
|
+
'pre',
|
|
58
|
+
'section',
|
|
59
|
+
'summary',
|
|
60
|
+
'table',
|
|
61
|
+
'tbody',
|
|
62
|
+
'td',
|
|
63
|
+
'tfoot',
|
|
64
|
+
'th',
|
|
65
|
+
'thead',
|
|
66
|
+
'tr',
|
|
67
|
+
],
|
|
68
|
+
strongTags: ['b', 'strong'],
|
|
69
|
+
emTags: ['i', 'em', 'cite', 'dfn'],
|
|
70
|
+
underlineTags: ['u', 'ins'],
|
|
71
|
+
codeTags: ['code', 'kbd', 'samp', 'tt'],
|
|
72
|
+
linkTag: 'a',
|
|
73
|
+
imageTag: 'img',
|
|
74
|
+
breakTag: 'br',
|
|
75
|
+
ruleTag: 'hr',
|
|
76
|
+
preTag: 'pre',
|
|
77
|
+
quoteTag: 'blockquote',
|
|
78
|
+
listItemTag: 'li',
|
|
79
|
+
orderedListTag: 'ol',
|
|
80
|
+
unorderedListTag: 'ul',
|
|
81
|
+
hiddenClassPattern: /(^|[\s_-])(preheader|pre-header|preview-text|previewtext)([\s_-]|$)/i,
|
|
82
|
+
hiddenDisplay: 'none',
|
|
83
|
+
hiddenVisibility: 'hidden',
|
|
84
|
+
hiddenMso: 'all',
|
|
85
|
+
hiddenAttribute: 'hidden',
|
|
86
|
+
hiddenAria: 'true',
|
|
87
|
+
tinyImageSize: 2,
|
|
88
|
+
importantPattern: /!important/i,
|
|
89
|
+
zeroPattern: /^0(\.0+)?(px|pt|em|rem|%)?$/,
|
|
90
|
+
pixelPattern: /^([0-9.]+)(px)?$/,
|
|
91
|
+
boldWeight: 600,
|
|
92
|
+
largeText: { heading3: 20, heading2: 24, heading1: 30, maxLength: 100 },
|
|
93
|
+
boldHeadingMaxLength: 80,
|
|
94
|
+
headingEndPattern: /[.,;:!?]$/,
|
|
95
|
+
pixelsPerPoint: 1.333,
|
|
96
|
+
pixelsPerEm: 16,
|
|
97
|
+
fontSizePattern: /^([0-9.]+)(px|pt|em|rem)$/,
|
|
98
|
+
commentStart: '<!--',
|
|
99
|
+
commentEnd: '-->',
|
|
100
|
+
declarationSeparator: ';',
|
|
101
|
+
propertySeparator: ':',
|
|
102
|
+
tagSource: '<(\\/?)([a-zA-Z][a-zA-Z0-9:-]*)((?:"[^"]*"|\'[^\']*\'|[^\'">])*)>',
|
|
103
|
+
tagFlags: 'y',
|
|
104
|
+
attributePattern: /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g,
|
|
105
|
+
selfClosingPattern: /\/\s*$/,
|
|
106
|
+
whitespacePattern: /[ \t\r\n\f\u00A0\u2007\u202F]+/g,
|
|
107
|
+
preLineBreakPattern: /\r\n?/g,
|
|
108
|
+
invisiblePattern: /\u00AD|\u034F|[\u200B-\u200F\u2028\u2029\u2060\uFEFF]/g,
|
|
109
|
+
entityPattern: /&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z][a-zA-Z0-9]*);/g,
|
|
110
|
+
maxCodePoint: 0x10ffff,
|
|
111
|
+
numericEntityPrefix: '#',
|
|
112
|
+
hexEntityPrefix: '#x',
|
|
113
|
+
rootName: 'root',
|
|
114
|
+
bodyListLevel: 1,
|
|
115
|
+
trailingBreakPattern: /[ \n]+$/,
|
|
116
|
+
leadingBreakPattern: /^[ \n]+/,
|
|
117
|
+
trailingSpacePattern: / +$/,
|
|
118
|
+
leadingSpacePattern: /^ +/,
|
|
119
|
+
nonBreakingPattern: /[\u00A0\u2007\u202F]/g,
|
|
120
|
+
srcAttribute: 'src',
|
|
121
|
+
altAttribute: 'alt',
|
|
122
|
+
hrefAttribute: 'href',
|
|
123
|
+
styleAttribute: 'style',
|
|
124
|
+
classAttribute: 'class',
|
|
125
|
+
widthAttribute: 'width',
|
|
126
|
+
heightAttribute: 'height',
|
|
127
|
+
aria: 'aria-hidden',
|
|
128
|
+
space: ' ',
|
|
129
|
+
newline: '\n',
|
|
130
|
+
trackingLinePattern: /^\[\s*(?:<)?(https?:\/\/[^\s\]>]+?)(?:>)?\s*\]$/i,
|
|
131
|
+
trackingEllipsis: '...',
|
|
132
|
+
trackingEllipsisCharacter: '\u2026',
|
|
133
|
+
};
|
|
@@ -9,7 +9,21 @@ export const PortableTextConfig = {
|
|
|
9
9
|
bulletPrefix: '- ',
|
|
10
10
|
quotePrefix: '> ',
|
|
11
11
|
numberSuffix: '. ',
|
|
12
|
-
keyPrefix: { block: 'b', span: 's' },
|
|
12
|
+
keyPrefix: { block: 'b', span: 's', link: 'l', image: 'i' },
|
|
13
|
+
blockType: Common.PortableTextConfig.blockType,
|
|
14
|
+
spanType: Common.PortableTextConfig.spanType,
|
|
15
|
+
linkType: Common.PortableTextConfig.linkType,
|
|
16
|
+
imageType: Common.PortableTextConfig.imageType,
|
|
17
|
+
decorators: Common.PortableTextConfig.decorators,
|
|
18
|
+
headingStyles: Common.PortableTextConfig.headingStyles,
|
|
19
|
+
messageStyles: Common.PortableTextConfig.messageStyles,
|
|
20
|
+
linkProtocols: Common.PortableTextConfig.linkProtocols,
|
|
21
|
+
maxListLevel: Common.PortableTextConfig.maxListLevel,
|
|
22
|
+
maxImageSrcLength: Common.PortableTextConfig.maxImageSrcLength,
|
|
23
|
+
maxImageAltLength: Common.PortableTextConfig.maxImageAltLength,
|
|
24
|
+
imageProtocolPattern: Common.PortableTextConfig.imageProtocolPattern,
|
|
25
|
+
maxControlCode: 31,
|
|
26
|
+
deleteCode: 127,
|
|
13
27
|
normalStyle: Common.PortableTextConfig.styles[0],
|
|
14
28
|
quoteStyle: Common.PortableTextConfig.styles[1],
|
|
15
29
|
bulletItem: Common.PortableTextConfig.listItems[0],
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { HtmlEntityNames } from './constants/html-entity-names.js';
|
|
2
|
+
import { HtmlTextConfig } from './constants/html-text-config.js';
|
|
3
|
+
export class HtmlEntityService {
|
|
4
|
+
static decode(value) {
|
|
5
|
+
return value.replace(HtmlTextConfig.entityPattern, (match, body) => HtmlEntityService.resolve(match, body));
|
|
6
|
+
}
|
|
7
|
+
static resolve(match, body) {
|
|
8
|
+
if (body.startsWith(HtmlTextConfig.hexEntityPrefix))
|
|
9
|
+
return HtmlEntityService.fromCode(match, Number.parseInt(body.slice(2), 16));
|
|
10
|
+
if (body.startsWith(HtmlTextConfig.numericEntityPrefix))
|
|
11
|
+
return HtmlEntityService.fromCode(match, Number.parseInt(body.slice(1), 10));
|
|
12
|
+
if (HtmlEntityService.isNamed(body))
|
|
13
|
+
return HtmlEntityNames[body];
|
|
14
|
+
const lower = body.toLowerCase();
|
|
15
|
+
return HtmlEntityService.isNamed(lower) ? HtmlEntityNames[lower] : match;
|
|
16
|
+
}
|
|
17
|
+
static fromCode(match, code) {
|
|
18
|
+
return Number.isInteger(code) && code > 0 && code <= HtmlTextConfig.maxCodePoint
|
|
19
|
+
? String.fromCodePoint(code)
|
|
20
|
+
: match;
|
|
21
|
+
}
|
|
22
|
+
static isNamed(name) {
|
|
23
|
+
return Object.prototype.hasOwnProperty.call(HtmlEntityNames, name);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { HtmlTextConfig } from './constants/html-text-config.js';
|
|
2
|
+
export class HtmlStyleService {
|
|
3
|
+
static parse(style) {
|
|
4
|
+
const declarations = {};
|
|
5
|
+
if (typeof style !== 'string')
|
|
6
|
+
return declarations;
|
|
7
|
+
style.split(HtmlTextConfig.declarationSeparator).forEach((entry) => {
|
|
8
|
+
const index = entry.indexOf(HtmlTextConfig.propertySeparator);
|
|
9
|
+
if (index === -1)
|
|
10
|
+
return;
|
|
11
|
+
const property = entry.slice(0, index).trim().toLowerCase();
|
|
12
|
+
const value = entry
|
|
13
|
+
.slice(index + 1)
|
|
14
|
+
.replace(HtmlTextConfig.importantPattern, '')
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase();
|
|
17
|
+
if (property !== '' && value !== '')
|
|
18
|
+
declarations[property] = value;
|
|
19
|
+
});
|
|
20
|
+
return declarations;
|
|
21
|
+
}
|
|
22
|
+
static isHidden(declarations) {
|
|
23
|
+
return (declarations['display'] === HtmlTextConfig.hiddenDisplay ||
|
|
24
|
+
declarations['visibility'] === HtmlTextConfig.hiddenVisibility ||
|
|
25
|
+
declarations['mso-hide'] === HtmlTextConfig.hiddenMso ||
|
|
26
|
+
HtmlStyleService.isZero(declarations['max-height']) ||
|
|
27
|
+
HtmlStyleService.isZero(declarations['max-width']) ||
|
|
28
|
+
HtmlStyleService.isZero(declarations['font-size']) ||
|
|
29
|
+
HtmlStyleService.isZero(declarations['opacity']));
|
|
30
|
+
}
|
|
31
|
+
static isTiny(declarations) {
|
|
32
|
+
return (HtmlStyleService.pixels(declarations['width']) <= HtmlTextConfig.tinyImageSize ||
|
|
33
|
+
HtmlStyleService.pixels(declarations['height']) <= HtmlTextConfig.tinyImageSize);
|
|
34
|
+
}
|
|
35
|
+
static fontSize(declarations) {
|
|
36
|
+
const value = declarations['font-size'];
|
|
37
|
+
if (typeof value !== 'string')
|
|
38
|
+
return null;
|
|
39
|
+
const match = HtmlTextConfig.fontSizePattern.exec(value);
|
|
40
|
+
if (match === null)
|
|
41
|
+
return null;
|
|
42
|
+
const amount = Number.parseFloat(match[1]);
|
|
43
|
+
if (match[2] === 'pt')
|
|
44
|
+
return amount * HtmlTextConfig.pixelsPerPoint;
|
|
45
|
+
if (match[2] === 'em' || match[2] === 'rem')
|
|
46
|
+
return amount * HtmlTextConfig.pixelsPerEm;
|
|
47
|
+
return amount;
|
|
48
|
+
}
|
|
49
|
+
static bold(declarations) {
|
|
50
|
+
const value = declarations['font-weight'];
|
|
51
|
+
if (typeof value !== 'string')
|
|
52
|
+
return null;
|
|
53
|
+
if (value === 'bold' || value === 'bolder')
|
|
54
|
+
return true;
|
|
55
|
+
if (value === 'normal' || value === 'lighter')
|
|
56
|
+
return false;
|
|
57
|
+
const weight = Number.parseInt(value, 10);
|
|
58
|
+
return Number.isNaN(weight) ? null : weight >= HtmlTextConfig.boldWeight;
|
|
59
|
+
}
|
|
60
|
+
static italic(declarations) {
|
|
61
|
+
const value = declarations['font-style'];
|
|
62
|
+
if (typeof value !== 'string')
|
|
63
|
+
return null;
|
|
64
|
+
if (value === 'italic' || value === 'oblique')
|
|
65
|
+
return true;
|
|
66
|
+
return value === 'normal' ? false : null;
|
|
67
|
+
}
|
|
68
|
+
static underline(declarations) {
|
|
69
|
+
const value = declarations['text-decoration'];
|
|
70
|
+
if (typeof value !== 'string')
|
|
71
|
+
return null;
|
|
72
|
+
if (value.includes('underline'))
|
|
73
|
+
return true;
|
|
74
|
+
return value.includes('none') ? false : null;
|
|
75
|
+
}
|
|
76
|
+
static isZero(value) {
|
|
77
|
+
return typeof value === 'string' && HtmlTextConfig.zeroPattern.test(value);
|
|
78
|
+
}
|
|
79
|
+
static pixels(value) {
|
|
80
|
+
if (typeof value !== 'string')
|
|
81
|
+
return Number.POSITIVE_INFINITY;
|
|
82
|
+
const match = HtmlTextConfig.pixelPattern.exec(value);
|
|
83
|
+
return match === null ? Number.POSITIVE_INFINITY : Number.parseFloat(match[1]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { HtmlTextConfig } from './constants/html-text-config.js';
|
|
2
|
+
import { HtmlTokenKind } from './constants/html-token-kind.js';
|
|
3
|
+
import { HtmlEntityService } from './html-entity-service.js';
|
|
4
|
+
export class HtmlTokenService {
|
|
5
|
+
static tokenize(html) {
|
|
6
|
+
const tokens = [];
|
|
7
|
+
let cursor = 0;
|
|
8
|
+
while (cursor < html.length) {
|
|
9
|
+
const start = html.indexOf('<', cursor);
|
|
10
|
+
if (start === -1) {
|
|
11
|
+
HtmlTokenService.pushText(tokens, html.slice(cursor));
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
HtmlTokenService.pushText(tokens, html.slice(cursor, start));
|
|
15
|
+
cursor = HtmlTokenService.consume(html, start, tokens);
|
|
16
|
+
}
|
|
17
|
+
return tokens;
|
|
18
|
+
}
|
|
19
|
+
static consume(html, start, tokens) {
|
|
20
|
+
if (html.startsWith(HtmlTextConfig.commentStart, start)) {
|
|
21
|
+
const end = html.indexOf(HtmlTextConfig.commentEnd, start + HtmlTextConfig.commentStart.length);
|
|
22
|
+
return end === -1 ? html.length : end + HtmlTextConfig.commentEnd.length;
|
|
23
|
+
}
|
|
24
|
+
const next = html.charAt(start + 1);
|
|
25
|
+
if (next === '!' || next === '?') {
|
|
26
|
+
const end = html.indexOf('>', start);
|
|
27
|
+
return end === -1 ? html.length : end + 1;
|
|
28
|
+
}
|
|
29
|
+
const pattern = new RegExp(HtmlTextConfig.tagSource, HtmlTextConfig.tagFlags);
|
|
30
|
+
pattern.lastIndex = start;
|
|
31
|
+
const match = pattern.exec(html);
|
|
32
|
+
if (match === null) {
|
|
33
|
+
HtmlTokenService.pushText(tokens, '<');
|
|
34
|
+
return start + 1;
|
|
35
|
+
}
|
|
36
|
+
const name = match[2].toLowerCase();
|
|
37
|
+
const end = start + match[0].length;
|
|
38
|
+
if (match[1] === '/') {
|
|
39
|
+
tokens.push({ kind: HtmlTokenKind.Close, name });
|
|
40
|
+
return end;
|
|
41
|
+
}
|
|
42
|
+
tokens.push({
|
|
43
|
+
attributes: HtmlTokenService.attributes(match[3]),
|
|
44
|
+
kind: HtmlTokenKind.Open,
|
|
45
|
+
name,
|
|
46
|
+
selfClosing: HtmlTextConfig.selfClosingPattern.test(match[3]),
|
|
47
|
+
});
|
|
48
|
+
return HtmlTextConfig.rawTextTags.includes(name)
|
|
49
|
+
? HtmlTokenService.skipRawText(html, name, end, tokens)
|
|
50
|
+
: end;
|
|
51
|
+
}
|
|
52
|
+
static skipRawText(html, name, from, tokens) {
|
|
53
|
+
const closing = new RegExp(`</${name}\\s*>`, 'gi');
|
|
54
|
+
closing.lastIndex = from;
|
|
55
|
+
const match = closing.exec(html);
|
|
56
|
+
if (match === null)
|
|
57
|
+
return html.length;
|
|
58
|
+
tokens.push({ kind: HtmlTokenKind.Close, name });
|
|
59
|
+
return match.index + match[0].length;
|
|
60
|
+
}
|
|
61
|
+
static attributes(source) {
|
|
62
|
+
const attributes = {};
|
|
63
|
+
const pattern = new RegExp(HtmlTextConfig.attributePattern.source, HtmlTextConfig.attributePattern.flags);
|
|
64
|
+
let match = pattern.exec(source);
|
|
65
|
+
while (match !== null) {
|
|
66
|
+
const raw = [match[2], match[3], match[4]].find((value) => typeof value === 'string');
|
|
67
|
+
const key = match[1].toLowerCase();
|
|
68
|
+
if (!Object.prototype.hasOwnProperty.call(attributes, key))
|
|
69
|
+
attributes[key] = HtmlEntityService.decode(typeof raw === 'string' ? raw : '');
|
|
70
|
+
match = pattern.exec(source);
|
|
71
|
+
}
|
|
72
|
+
return attributes;
|
|
73
|
+
}
|
|
74
|
+
static pushText(tokens, text) {
|
|
75
|
+
if (text === '')
|
|
76
|
+
return;
|
|
77
|
+
const last = tokens[tokens.length - 1];
|
|
78
|
+
if (last !== undefined && last.kind === HtmlTokenKind.Text)
|
|
79
|
+
last.text += text;
|
|
80
|
+
else
|
|
81
|
+
tokens.push({ kind: HtmlTokenKind.Text, text });
|
|
82
|
+
}
|
|
83
|
+
}
|
package/dist/esm/common/index.js
CHANGED
|
@@ -24,5 +24,6 @@ export * from './error-response-service.js';
|
|
|
24
24
|
export * from './relative-time-service.js';
|
|
25
25
|
export * from './request-client-service.js';
|
|
26
26
|
export * from './json-service.js';
|
|
27
|
+
export * from './portable-text-link-service.js';
|
|
27
28
|
export * from './portable-text-service.js';
|
|
28
29
|
export * from './text-tidy-service.js';
|