@leanix/components 0.2.240 → 0.2.241
Sign up to get free protection for your applications and to get access to all the features.
- 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 = [];
|