Move url related utility methods to @converse/headless
This commit is contained in:
parent
bff714f24c
commit
b90a435833
1063
package-lock.json
generated
1063
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -115,7 +115,6 @@
|
|||
"favico.js-slevomat": "^0.3.11",
|
||||
"jed": "1.1.1",
|
||||
"lit": "^2.0.0-rc.2",
|
||||
"urijs": "^1.19.6",
|
||||
"xss": "^1.0.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* @license Mozilla Public License (MPLv2)
|
||||
*/
|
||||
import Storage from '@converse/skeletor/src/storage.js';
|
||||
import URI from 'urijs';
|
||||
import _converse from '@converse/headless/shared/_converse';
|
||||
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
||||
import dayjs from 'dayjs';
|
||||
|
@ -1416,6 +1417,7 @@ Object.assign(converse, {
|
|||
Model,
|
||||
Promise,
|
||||
Strophe,
|
||||
URI,
|
||||
dayjs,
|
||||
html,
|
||||
log,
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
"pluggable.js": "3.0.1",
|
||||
"sizzle": "^2.3.5",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"strophe.js": "1.4.2"
|
||||
"strophe.js": "1.4.2",
|
||||
"urijs": "^1.19.6"
|
||||
}
|
||||
}
|
||||
|
|
103
src/headless/utils/url.js
Normal file
103
src/headless/utils/url.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
import URI from 'urijs';
|
||||
import log from '@converse/headless/log';
|
||||
import { api } from '@converse/headless/core';
|
||||
|
||||
function checkTLS (uri) {
|
||||
return (
|
||||
window.location.protocol === 'http:' ||
|
||||
(window.location.protocol === 'https:' && uri.protocol().toLowerCase() === 'https')
|
||||
);
|
||||
}
|
||||
|
||||
export function getURI (url) {
|
||||
try {
|
||||
return url instanceof URI ? url : new URI(url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function checkFileTypes (types, url) {
|
||||
const uri = getURI(url);
|
||||
if (uri === null || !checkTLS(uri)) {
|
||||
return false;
|
||||
}
|
||||
const filename = uri.filename().toLowerCase();
|
||||
return !!types.filter(ext => filename.endsWith(ext)).length;
|
||||
}
|
||||
|
||||
function isDomainAllowed (whitelist, url) {
|
||||
const uri = getURI(url);
|
||||
const subdomain = uri.subdomain();
|
||||
const domain = uri.domain();
|
||||
const fulldomain = `${subdomain ? `${subdomain}.` : ''}${domain}`;
|
||||
return whitelist.includes(domain) || whitelist.includes(fulldomain);
|
||||
}
|
||||
|
||||
export function filterQueryParamsFromURL (url) {
|
||||
const paramsArray = api.settings.get('filter_url_query_params');
|
||||
if (!paramsArray) return url;
|
||||
const parsed_uri = getURI(url);
|
||||
return parsed_uri.removeQuery(paramsArray).toString();
|
||||
}
|
||||
|
||||
export function isAudioDomainAllowed (url) {
|
||||
const embed_audio = api.settings.get('embed_audio');
|
||||
if (!Array.isArray(embed_audio)) {
|
||||
return embed_audio;
|
||||
}
|
||||
try {
|
||||
return isDomainAllowed(embed_audio, url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isVideoDomainAllowed (url) {
|
||||
const embed_videos = api.settings.get('embed_videos');
|
||||
if (!Array.isArray(embed_videos)) {
|
||||
return embed_videos;
|
||||
}
|
||||
try {
|
||||
return isDomainAllowed(embed_videos, url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isImageDomainAllowed (url) {
|
||||
const show_images_inline = api.settings.get('show_images_inline');
|
||||
if (!Array.isArray(show_images_inline)) {
|
||||
return show_images_inline;
|
||||
}
|
||||
try {
|
||||
return isDomainAllowed(show_images_inline, url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isURLWithImageExtension (url) {
|
||||
return checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], url);
|
||||
}
|
||||
|
||||
export function isAudioURL (url) {
|
||||
return checkFileTypes(['.ogg', '.mp3', '.m4a'], url);
|
||||
}
|
||||
|
||||
export function isVideoURL (url) {
|
||||
return checkFileTypes(['.mp4', '.webm'], url);
|
||||
}
|
||||
|
||||
export function isImageURL (url) {
|
||||
const regex = api.settings.get('image_urls_regex');
|
||||
return regex?.test(url) || isURLWithImageExtension(url);
|
||||
}
|
||||
|
||||
export function isEncryptedFileURL (url) {
|
||||
return url.startsWith('aesgcm://');
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
/* global libsignal */
|
||||
import URI from 'urijs';
|
||||
import difference from 'lodash-es/difference';
|
||||
import log from '@converse/headless/log';
|
||||
import tpl_audio from 'templates/audio.js';
|
||||
|
@ -12,7 +11,7 @@ import { __ } from 'i18n';
|
|||
import { _converse, converse, api } from '@converse/headless/core';
|
||||
import { html } from 'lit';
|
||||
import { initStorage } from '@converse/headless/shared/utils.js';
|
||||
import { isAudioURL, isImageURL, isVideoURL, getURI } from 'utils/html.js';
|
||||
import { isAudioURL, isImageURL, isVideoURL, getURI } from '@converse/headless/utils/url.js';
|
||||
import concat from 'lodash-es/concat';
|
||||
import { until } from 'lit/directives/until.js';
|
||||
import {
|
||||
|
@ -25,7 +24,7 @@ import {
|
|||
stringToArrayBuffer
|
||||
} from '@converse/headless/utils/arraybuffer.js';
|
||||
|
||||
const { $msg, Strophe, sizzle, u } = converse.env;
|
||||
const { $msg, Strophe, URI, sizzle, u } = converse.env;
|
||||
|
||||
|
||||
async function encryptMessage (plaintext) {
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import { converse } from "@converse/headless/core";
|
||||
import { getURI } from 'utils/html.js';
|
||||
import { html } from 'lit';
|
||||
import { isImageDomainAllowed, } from 'utils/html';
|
||||
import { getURI, isImageDomainAllowed } from '@converse/headless/utils/url.js';
|
||||
|
||||
const u = converse.env.utils;
|
||||
|
||||
function isValidURL (url) {
|
||||
// We don't consider relative URLs as valid
|
||||
|
@ -30,7 +27,7 @@ export default (o) => {
|
|||
<div class="card-body">
|
||||
${ o.title ? tpl_url_wrapper(o, o => html`<h5 class="card-title">${o.title}</h5>`) : ''}
|
||||
${ o.description ? html`<p class="card-text"><converse-rich-text text=${o.description}></converse-rich-text></p>` : '' }
|
||||
${ o.url ? html`<p class="card-text"><a href="${o.url}" target="_blank" rel="noopener">${u.getURI(o.url).domain()}</a></p>` : '' }
|
||||
${ o.url ? html`<p class="card-text"><a href="${o.url}" target="_blank" rel="noopener">${getURI(o.url).domain()}</a></p>` : '' }
|
||||
</div>` : '' }
|
||||
</div>`;
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import URI from 'urijs';
|
||||
import { AsyncDirective } from 'lit/async-directive.js';
|
||||
import { converse } from '@converse/headless/core';
|
||||
import { directive } from 'lit/directive.js';
|
||||
import { getHyperlinkTemplate, isURLWithImageExtension } from 'utils/html.js';
|
||||
import { getHyperlinkTemplate } from 'utils/html.js';
|
||||
import { html } from 'lit';
|
||||
import { isURLWithImageExtension } from '@converse/headless/utils/url.js';
|
||||
|
||||
const { URI } = converse.env;
|
||||
|
||||
class ImageDirective extends AsyncDirective {
|
||||
render (src, href, onLoad, onClick) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import URI from 'urijs';
|
||||
import log from '@converse/headless/log';
|
||||
import tpl_audio from 'templates/audio.js';
|
||||
import tpl_image from 'templates/image.js';
|
||||
import tpl_video from 'templates/video.js';
|
||||
import { _converse, api } from '@converse/headless/core';
|
||||
import { _converse, api, converse } from '@converse/headless/core';
|
||||
import { containsDirectives, getDirectiveAndLength, getDirectiveTemplate, isQuoteDirective } from './styling.js';
|
||||
import { getHyperlinkTemplate } from 'utils/html.js';
|
||||
import {
|
||||
convertASCII2Emoji,
|
||||
getCodePointReferences,
|
||||
|
@ -13,7 +13,6 @@ import {
|
|||
} from '@converse/headless/plugins/emoji/index.js';
|
||||
import {
|
||||
filterQueryParamsFromURL,
|
||||
getHyperlinkTemplate,
|
||||
isAudioDomainAllowed,
|
||||
isAudioURL,
|
||||
isEncryptedFileURL,
|
||||
|
@ -21,9 +20,12 @@ import {
|
|||
isImageURL,
|
||||
isVideoDomainAllowed,
|
||||
isVideoURL
|
||||
} from 'utils/html.js';
|
||||
} from '@converse/headless/utils/url.js';
|
||||
|
||||
import { html } from 'lit';
|
||||
|
||||
const { URI } = converse.env;
|
||||
|
||||
const isString = s => typeof s === 'string';
|
||||
|
||||
// We don't render more than two line-breaks, replace extra line-breaks with
|
||||
|
@ -92,8 +94,8 @@ export class RichText extends String {
|
|||
*/
|
||||
addHyperlinks (text, offset) {
|
||||
const objs = [];
|
||||
const parse_options = { 'start': /\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi };
|
||||
try {
|
||||
const parse_options = { 'start': /\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi };
|
||||
URI.withinString(
|
||||
text,
|
||||
(url, start, end) => {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* @license Mozilla Public License (MPLv2)
|
||||
* @description This is the DOM/HTML utilities module.
|
||||
*/
|
||||
import URI from 'urijs';
|
||||
import isFunction from 'lodash-es/isFunction';
|
||||
import log from '@converse/headless/log';
|
||||
import tpl_audio from 'templates/audio.js';
|
||||
|
@ -19,7 +18,8 @@ import tpl_form_username from '../templates/form_username.js';
|
|||
import tpl_hyperlink from 'templates/hyperlink.js';
|
||||
import tpl_video from 'templates/video.js';
|
||||
import u from '../headless/utils/core';
|
||||
import { api, converse } from '@converse/headless/core';
|
||||
import { converse } from '@converse/headless/core';
|
||||
import { getURI, isAudioURL, isImageURL, isVideoURL } from '@converse/headless/utils/url.js';
|
||||
import { render } from 'lit';
|
||||
|
||||
const { sizzle } = converse.env;
|
||||
|
@ -52,99 +52,6 @@ function slideOutWrapup (el) {
|
|||
el.style.height = '';
|
||||
}
|
||||
|
||||
export function getURI (url) {
|
||||
try {
|
||||
return url instanceof URI ? url : new URI(url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function checkTLS (uri) {
|
||||
return (
|
||||
window.location.protocol === 'http:' ||
|
||||
(window.location.protocol === 'https:' && uri.protocol().toLowerCase() === 'https')
|
||||
);
|
||||
}
|
||||
|
||||
function checkFileTypes (types, url) {
|
||||
const uri = getURI(url);
|
||||
if (uri === null || !checkTLS(uri)) {
|
||||
return false;
|
||||
}
|
||||
const filename = uri.filename().toLowerCase();
|
||||
return !!types.filter(ext => filename.endsWith(ext)).length;
|
||||
}
|
||||
|
||||
export function isURLWithImageExtension (url) {
|
||||
return checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], url);
|
||||
}
|
||||
|
||||
export function isAudioURL (url) {
|
||||
return checkFileTypes(['.ogg', '.mp3', '.m4a'], url);
|
||||
}
|
||||
|
||||
export function isVideoURL (url) {
|
||||
return checkFileTypes(['.mp4', '.webm'], url);
|
||||
}
|
||||
|
||||
export function isEncryptedFileURL (url) {
|
||||
return url.startsWith('aesgcm://');
|
||||
}
|
||||
|
||||
export function isImageURL (url) {
|
||||
const regex = api.settings.get('image_urls_regex');
|
||||
return regex?.test(url) || isURLWithImageExtension(url);
|
||||
}
|
||||
|
||||
function isDomainAllowed (whitelist, url) {
|
||||
const uri = getURI(url);
|
||||
const subdomain = uri.subdomain();
|
||||
const domain = uri.domain();
|
||||
const fulldomain = `${subdomain ? `${subdomain}.` : ''}${domain}`;
|
||||
return whitelist.includes(domain) || whitelist.includes(fulldomain);
|
||||
}
|
||||
|
||||
export function isAudioDomainAllowed (url) {
|
||||
const embed_audio = api.settings.get('embed_audio');
|
||||
if (!Array.isArray(embed_audio)) {
|
||||
return embed_audio;
|
||||
}
|
||||
try {
|
||||
return isDomainAllowed(embed_audio, url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isVideoDomainAllowed (url) {
|
||||
const embed_videos = api.settings.get('embed_videos');
|
||||
if (!Array.isArray(embed_videos)) {
|
||||
return embed_videos;
|
||||
}
|
||||
try {
|
||||
return isDomainAllowed(embed_videos, url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isImageDomainAllowed (url) {
|
||||
const show_images_inline = api.settings.get('show_images_inline');
|
||||
if (!Array.isArray(show_images_inline)) {
|
||||
return show_images_inline;
|
||||
}
|
||||
try {
|
||||
return isDomainAllowed(show_images_inline, url);
|
||||
} catch (error) {
|
||||
log.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getFileName (uri) {
|
||||
try {
|
||||
return decodeURI(uri.filename());
|
||||
|
@ -166,11 +73,11 @@ export function getOOBURLMarkup (url) {
|
|||
if (uri === null) {
|
||||
return url;
|
||||
}
|
||||
if (u.isVideoURL(uri)) {
|
||||
if (isVideoURL(uri)) {
|
||||
return tpl_video(url);
|
||||
} else if (u.isAudioURL(uri)) {
|
||||
} else if (isAudioURL(uri)) {
|
||||
return tpl_audio(url);
|
||||
} else if (u.isImageURL(uri)) {
|
||||
} else if (isImageURL(uri)) {
|
||||
return tpl_file(uri.toString(), getFileName(uri));
|
||||
} else {
|
||||
return tpl_file(uri.toString(), getFileName(uri));
|
||||
|
@ -340,13 +247,6 @@ export function getHyperlinkTemplate (url) {
|
|||
return url;
|
||||
}
|
||||
|
||||
export function filterQueryParamsFromURL (url) {
|
||||
const paramsArray = api.settings.get('filter_url_query_params');
|
||||
if (!paramsArray) return url;
|
||||
const parsed_uri = getURI(url);
|
||||
return parsed_uri.removeQuery(paramsArray).toString();
|
||||
}
|
||||
|
||||
u.slideInAllElements = function (elements, duration = 300) {
|
||||
return Promise.all(Array.from(elements).map(e => u.slideIn(e, duration)));
|
||||
};
|
||||
|
@ -591,15 +491,6 @@ u.xForm2TemplateResult = function (field, stanza, options) {
|
|||
}
|
||||
};
|
||||
|
||||
Object.assign(u, {
|
||||
filterQueryParamsFromURL,
|
||||
getURI,
|
||||
isAudioURL,
|
||||
isImageURL,
|
||||
isImageDomainAllowed,
|
||||
isURLWithImageExtension,
|
||||
isVideoURL,
|
||||
getOOBURLMarkup,
|
||||
});
|
||||
Object.assign(u, { getOOBURLMarkup });
|
||||
|
||||
export default u;
|
||||
|
|
Loading…
Reference in New Issue
Block a user