mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
125 lines
4.2 KiB
JavaScript
125 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
import React from 'react';
|
|
|
|
import { getLinkRegex, isEmail } from './regex';
|
|
|
|
|
|
/**
|
|
* Escape HTML in a string so it can be injected safely using React's `dangerouslySetInnerHTML`
|
|
*
|
|
* @param {string} s String to be sanitized
|
|
* @return {string} Sanitized string
|
|
*
|
|
* Taken from: http://stackoverflow.com/a/17546215/597097
|
|
*/
|
|
export function escapeHTML(s) {
|
|
return document.createElement('div').appendChild(document.createTextNode(s)).parentNode.innerHTML;
|
|
}
|
|
|
|
/**
|
|
* Set the title in the browser window.
|
|
*/
|
|
export function setDocumentTitle(title) {
|
|
document.title = title;
|
|
}
|
|
|
|
/**
|
|
* @param {string} elementType: string, is the type of the element, such as link, meta, etc.
|
|
* @param {string} elementId id of the element
|
|
* @param {object} elementAttributes: hash table containing the attributes of the relevant element
|
|
*/
|
|
function constructHeadElement(elementType, elementId, elementAttributes) {
|
|
const head = (document.head || document.getElementsByTagName('head')[0]);
|
|
const element = document.createElement(elementType);
|
|
const oldElement = document.getElementById(elementId);
|
|
|
|
element.setAttribute('id', elementId);
|
|
|
|
for (let k in elementAttributes) {
|
|
try {
|
|
element.setAttribute(k, elementAttributes[k]);
|
|
} catch(e) {
|
|
console.warn(e.message);
|
|
}
|
|
}
|
|
|
|
if (oldElement) {
|
|
head.removeChild(oldElement);
|
|
}
|
|
|
|
head.appendChild(element);
|
|
}
|
|
|
|
/**
|
|
* Accepts a dictionary of dictionaries which comprises a part or all of html head part
|
|
* @param {object} headObject {link : {id1: {rel: ... }}}
|
|
*/
|
|
export function constructHead(headObject){
|
|
for (let k in headObject){
|
|
const favicons = headObject[k];
|
|
for (let f in favicons){
|
|
constructHeadElement(k, f, favicons[f]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Replaces the links and emails in a given string with anchor elements.
|
|
*
|
|
* @param {string} string String to anchorize
|
|
* @param {(object)} options Options object for anchorizing
|
|
* @param {(boolean)} emails Whether or not to replace emails (default: true)
|
|
* @param {(boolean)} links Whether or not to replace links (default: true)
|
|
* @param {(string)} target Anchor target attribute (default: '_blank')
|
|
* @return {string|React.element[]} Anchorized string as usable react element, either as an array of
|
|
* elements or just a string
|
|
*/
|
|
export function anchorize(string, { emails: replaceEmail = true, links: replaceLink = true, target = '_blank' } = {}) {
|
|
if (!replaceEmail && !replaceLink) {
|
|
return string;
|
|
}
|
|
|
|
const linkRegex = getLinkRegex();
|
|
const strWithAnchorElems = [];
|
|
let lastMatchIndex = 0;
|
|
let regexMatch;
|
|
|
|
while (regexMatch = linkRegex.exec(string)) {
|
|
const [ matchedStr, schemeName ] = regexMatch;
|
|
const matchedStrIsEmail = isEmail(matchedStr);
|
|
|
|
let anchorizedMatch;
|
|
if (matchedStrIsEmail && replaceEmail) {
|
|
anchorizedMatch = (<a href={`mailto:${matchedStr}`}>{matchedStr}</a>);
|
|
} else if (!matchedStrIsEmail && replaceLink) {
|
|
anchorizedMatch = (<a href={`${schemeName ? matchedStr : ('http://' + matchedStr)}`} target={target}>{matchedStr}</a>);
|
|
}
|
|
|
|
// We only need to add an element to the array and update the lastMatchIndex if we actually create an anchor
|
|
if (anchorizedMatch) {
|
|
// First add the string between the end of the last anchor text and the start of the current match
|
|
const currentMatchStartIndex = linkRegex.lastIndex - matchedStr.length;
|
|
|
|
if (lastMatchIndex !== currentMatchStartIndex) {
|
|
strWithAnchorElems.push(string.substring(lastMatchIndex, currentMatchStartIndex));
|
|
}
|
|
|
|
strWithAnchorElems.push(anchorizedMatch);
|
|
|
|
lastMatchIndex = linkRegex.lastIndex;
|
|
}
|
|
}
|
|
|
|
if (strWithAnchorElems.length) {
|
|
// Add the string between the end of the last anchor and the end of the string
|
|
if (lastMatchIndex !== string.length) {
|
|
strWithAnchorElems.push(string.substring(lastMatchIndex));
|
|
}
|
|
|
|
return strWithAnchorElems;
|
|
} else {
|
|
return string;
|
|
}
|
|
}
|