@leanix/components 0.2.240 → 0.2.241
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/esm2020/lib/core-ui/pipes/linkify/linkify.pipe.mjs +66 -61
- package/fesm2015/leanix-components.mjs +65 -60
- package/fesm2015/leanix-components.mjs.map +1 -1
- package/fesm2020/leanix-components.mjs +65 -60
- package/fesm2020/leanix-components.mjs.map +1 -1
- package/lib/core-ui/pipes/linkify/linkify.pipe.d.ts +2 -0
- package/package.json +1 -1
@@ -1155,72 +1155,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImpor
|
|
1155
1155
|
class LxLinkifyPipe {
|
1156
1156
|
transform(text) {
|
1157
1157
|
if (text && typeof text === 'string') {
|
1158
|
-
|
1159
|
-
|
1160
|
-
* Keeping track of this index prevents infinite loops
|
1161
|
-
* where a previously processed link starts with the same characters
|
1162
|
-
* as a second link.
|
1163
|
-
* e.g. https://angular.io/docs followed by https://angular.io
|
1164
|
-
*/
|
1165
|
-
let nextIndexToStartReplacingFrom = 0;
|
1166
|
-
const rawLinkMatches = this.getAllRegexMatches(LxLinkifyPipe.HTTP_LINK_REGEX, text);
|
1167
|
-
rawLinkMatches.forEach((rawLinkMatch) => {
|
1168
|
-
const [url] = rawLinkMatch;
|
1169
|
-
const wrapUrlInAnchor = (sanitizedUrlMatch) => {
|
1170
|
-
const firstPart = textWithRawLinks.substring(0, nextIndexToStartReplacingFrom);
|
1171
|
-
const anchorTagHtml = `<a href="${sanitizedUrlMatch}" target="_blank" rel="noopener noreferrer">${sanitizedUrlMatch}</a>`;
|
1172
|
-
const secondPart = textWithRawLinks.substring(nextIndexToStartReplacingFrom).replace(sanitizedUrlMatch, anchorTagHtml);
|
1173
|
-
textWithRawLinks = firstPart + secondPart;
|
1174
|
-
nextIndexToStartReplacingFrom = rawLinkMatch.index + anchorTagHtml.length;
|
1175
|
-
};
|
1176
|
-
if (url) {
|
1177
|
-
/*
|
1178
|
-
* TODO: get rid of all this code once Safari supports negative lookbehinds in regular expressions
|
1179
|
-
* The following is RegExp that handles the same stuff as the JS code below:
|
1180
|
-
*
|
1181
|
-
* /(?:(?:(?<!\]\())(?:https|http):\/\/)(?:[^\s/$.?#][^\s]*(?<![\.)]))/gi;
|
1182
|
-
*
|
1183
|
-
* Demo on regex101: https://regex101.com/r/7Vl9bg/1
|
1184
|
-
*
|
1185
|
-
* Check lookbehind support here: https://caniuse.com/?search=lookbehind
|
1186
|
-
*/
|
1187
|
-
const lastUrlCharacterIndex = rawLinkMatch.index + url.length - 1;
|
1188
|
-
const textUsedToPerformMatching = rawLinkMatch.input;
|
1189
|
-
const lastCharacterInUrl = textUsedToPerformMatching[lastUrlCharacterIndex];
|
1190
|
-
if (lastCharacterInUrl === '.') {
|
1191
|
-
const characterAfterUrl = textUsedToPerformMatching[lastUrlCharacterIndex + 1];
|
1192
|
-
if (!characterAfterUrl || characterAfterUrl === ' ' || characterAfterUrl === '\n') {
|
1193
|
-
const urlWithoutDotAtTheEnd = url.slice(0, -1);
|
1194
|
-
wrapUrlInAnchor(urlWithoutDotAtTheEnd);
|
1195
|
-
}
|
1196
|
-
}
|
1197
|
-
else if (rawLinkMatch.index > 3) {
|
1198
|
-
const twoCharactersInFrontOfTheLink = `${textUsedToPerformMatching[rawLinkMatch.index - 2]}${textUsedToPerformMatching[rawLinkMatch.index - 1]}`;
|
1199
|
-
if (twoCharactersInFrontOfTheLink && twoCharactersInFrontOfTheLink !== '](') {
|
1200
|
-
// only wrap url in anchor when it is not a named markdown link
|
1201
|
-
wrapUrlInAnchor(url);
|
1202
|
-
}
|
1203
|
-
}
|
1204
|
-
else {
|
1205
|
-
wrapUrlInAnchor(url);
|
1206
|
-
}
|
1207
|
-
}
|
1208
|
-
});
|
1209
|
-
let textWithRawAndNamedLinks = textWithRawLinks;
|
1210
|
-
const namedLinkMatches = this.getAllRegexMatches(LxLinkifyPipe.NAMED_LINK_REGEX, textWithRawLinks);
|
1211
|
-
namedLinkMatches.forEach((namedLinkMatch) => {
|
1212
|
-
const [source, name, url] = namedLinkMatch;
|
1213
|
-
const urlIsValid = url && !/javascript\:/i.test(url);
|
1214
|
-
if (source && name && urlIsValid) {
|
1215
|
-
textWithRawAndNamedLinks = textWithRawAndNamedLinks.replace(source, `<a href="${url}" target="_blank" rel="noopener noreferrer">${name}</a>`);
|
1216
|
-
}
|
1217
|
-
});
|
1158
|
+
const textWithRawLinks = this.wrapRawHttpLinksWithAnchorTags(text);
|
1159
|
+
const textWithRawAndNamedLinks = this.turnMarkdownStyleLinksIntoAnchorTags(textWithRawLinks);
|
1218
1160
|
return textWithRawAndNamedLinks;
|
1219
1161
|
}
|
1220
1162
|
else {
|
1221
1163
|
return text;
|
1222
1164
|
}
|
1223
1165
|
}
|
1166
|
+
turnMarkdownStyleLinksIntoAnchorTags(text) {
|
1167
|
+
let textWithRawAndNamedLinks = text;
|
1168
|
+
const namedLinkMatches = this.getAllRegexMatches(LxLinkifyPipe.NAMED_LINK_REGEX, text);
|
1169
|
+
namedLinkMatches.forEach((namedLinkMatch) => {
|
1170
|
+
const [source, name, url] = namedLinkMatch;
|
1171
|
+
const urlIsValid = url && !/javascript\:/i.test(url);
|
1172
|
+
if (source && name && urlIsValid) {
|
1173
|
+
textWithRawAndNamedLinks = textWithRawAndNamedLinks.replace(source, `<a href="${url}" target="_blank" rel="noopener noreferrer">${name}</a>`);
|
1174
|
+
}
|
1175
|
+
});
|
1176
|
+
return textWithRawAndNamedLinks;
|
1177
|
+
}
|
1178
|
+
wrapRawHttpLinksWithAnchorTags(text) {
|
1179
|
+
let textWithRawLinks = text;
|
1180
|
+
/**
|
1181
|
+
* Keeping track of this index prevents infinite loops
|
1182
|
+
* where a previously processed link starts with the same characters
|
1183
|
+
* as a second link.
|
1184
|
+
* e.g. https://angular.io/docs followed by https://angular.io
|
1185
|
+
*/
|
1186
|
+
let nextIndexToStartReplacingFrom = 0;
|
1187
|
+
const rawLinkMatches = this.getAllRegexMatches(LxLinkifyPipe.HTTP_LINK_REGEX, text);
|
1188
|
+
rawLinkMatches.forEach((rawLinkMatch) => {
|
1189
|
+
const [url] = rawLinkMatch;
|
1190
|
+
const wrapUrlInAnchor = (sanitizedUrlMatch) => {
|
1191
|
+
const firstPart = textWithRawLinks.substring(0, nextIndexToStartReplacingFrom);
|
1192
|
+
const anchorTagHtml = `<a href="${sanitizedUrlMatch}" target="_blank" rel="noopener noreferrer">${sanitizedUrlMatch}</a>`;
|
1193
|
+
const secondPart = textWithRawLinks.substring(nextIndexToStartReplacingFrom).replace(sanitizedUrlMatch, anchorTagHtml);
|
1194
|
+
textWithRawLinks = firstPart + secondPart;
|
1195
|
+
nextIndexToStartReplacingFrom = rawLinkMatch.index + anchorTagHtml.length;
|
1196
|
+
};
|
1197
|
+
if (url) {
|
1198
|
+
/*
|
1199
|
+
* TODO: get rid of all this code once Safari supports negative lookbehinds in regular expressions
|
1200
|
+
* The following is RegExp that handles the same stuff as the JS code below:
|
1201
|
+
*
|
1202
|
+
* /(?:(?:(?<!\]\())(?:https|http):\/\/)(?:[^\s/$.?#][^\s]*(?<![\.)]))/gi;
|
1203
|
+
*
|
1204
|
+
* Demo on regex101: https://regex101.com/r/7Vl9bg/1
|
1205
|
+
*
|
1206
|
+
* Check lookbehind support here: https://caniuse.com/?search=lookbehind
|
1207
|
+
*/
|
1208
|
+
const lastUrlCharacterIndex = rawLinkMatch.index + url.length - 1;
|
1209
|
+
const textUsedToPerformMatching = rawLinkMatch.input;
|
1210
|
+
const lastCharacterInUrl = textUsedToPerformMatching[lastUrlCharacterIndex];
|
1211
|
+
const twoCharactersInFrontOfTheLink = rawLinkMatch.index > 3
|
1212
|
+
? `${textUsedToPerformMatching[rawLinkMatch.index - 2]}${textUsedToPerformMatching[rawLinkMatch.index - 1]}`
|
1213
|
+
: '';
|
1214
|
+
const isMarkdownSyntaxLink = twoCharactersInFrontOfTheLink === '](';
|
1215
|
+
if (!isMarkdownSyntaxLink && lastCharacterInUrl === '.') {
|
1216
|
+
const characterAfterUrl = textUsedToPerformMatching[lastUrlCharacterIndex + 1];
|
1217
|
+
if (!characterAfterUrl || characterAfterUrl === ' ' || characterAfterUrl === '\n') {
|
1218
|
+
const urlWithoutDotAtTheEnd = url.slice(0, -1);
|
1219
|
+
wrapUrlInAnchor(urlWithoutDotAtTheEnd);
|
1220
|
+
}
|
1221
|
+
}
|
1222
|
+
else if (!isMarkdownSyntaxLink) {
|
1223
|
+
wrapUrlInAnchor(url);
|
1224
|
+
}
|
1225
|
+
}
|
1226
|
+
});
|
1227
|
+
return textWithRawLinks;
|
1228
|
+
}
|
1224
1229
|
getAllRegexMatches(regex, input) {
|
1225
1230
|
let match;
|
1226
1231
|
const matches = [];
|