Skip to content

Instantly share code, notes, and snippets.

@planetcrypton
Last active February 22, 2016 08:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save planetcrypton/12829cad4e07bd0ca069 to your computer and use it in GitHub Desktop.
Save planetcrypton/12829cad4e07bd0ca069 to your computer and use it in GitHub Desktop.
Ember JS Helper for converting parts of a text (non-mark-down) to HTML whenever certain patterns are recognized
/**
* $ ember test --filter "text-2-html"
*/
import { text2Html } from '../../../helpers/text-2-html';
import { module, test } from 'qunit';
module('Unit | Helper | text 2 html');
const input = "Hey\nHow're ya doin'?\nSorry you can't get through.\nWhy don't you leave me your name, mine is @planetcrypton, and your number, mine is +4512345678, and I'll get back to you.\nDon't forget to visit http://www.wearedelasoul.com/\nMail me at plug2@reversed-yogurt.com #oldschool #plug1 #plug2 #plug3";
test('test all possibilites on', function(assert) {
const params = [input];
const hash = {
target : "_system",
hashTagURLPrefix : "https://twitter.com/hashtag/",
mentionURLPrefix : "https://twitter.com/",
phone : true
};
const result = text2Html(params, hash);
// line-break
assert.equal(result.indexOf("Hey<br>"), 0);
// hyper-link
assert.equal(result.indexOf("<a href=\"http://www.wearedelasoul.com/\" target=\""+hash.target+"\"") > -1, true);
// e-mail
assert.equal(result.indexOf("<a href=\"mailto:plug2@reversed-yogurt.com\"") > -1, true);
// phone
assert.equal(result.indexOf("<a href=\"tel:+4512345678\"") > -1, true);
// hash-tag
assert.equal(result.indexOf("<a href=\"https://twitter.com/hashtag/oldschool\" target=\""+hash.target+"\"") > -1, true);
// mention
assert.equal(result.indexOf("<a href=\"https://twitter.com/planetcrypton\" target=\""+hash.target+"\"") > -1, true);
// mention-@ should be shown in the link's text-node, by default
assert.equal(result.indexOf(">@planetcrypton<") > -1, true);
// mention-@ shouldn't be shown in the link's text-node now
hash.mentionAtShown = false;
const resultNoAtSign = text2Html(params, hash);
assert.equal(result.indexOf(">@planetcrypton<"), -1);
});
test('test all possibilites off', function(assert) {
const params = [input];
const hash = {
nl : false,
url : false,
email : false
};
const result = text2Html(params, hash);
// input will always be escaped due to: Ember.Handlebars.Utils.escapeExpression()
const compare = input.replace(/\'/g,'&#39;');
// no changes, apart from escaped input
assert.equal(input, compare);
});
import Ember from 'ember';
/**
* Converts parts of a text (non-mark-down) to HTML
* whenever certain patterns are recognized
*
* By default it converts:
* - new-lines (attribute "nl":)
* - URLs (attribute "url")
* - e-mails (attribute "email")
*
* When configured it converts too:
* - phone-numbers (attribute "phone") -- note: buggy!!
* - hash-tags (attribute "hashTagURLPrefix")
* - mentions (attribute "mentionURLPrefix" and "mentionAtShown")
*
* Usage:
* // basic
* {{text-2-html item.message}}
*
* // defining target
* {{text-2-html item.message target='_system'}}
*
* // convert phone-number, note this is somehow buggy
* {{text-2-html item.message target='_system' phone=true}}
*
* // hash-tags & mentions, twitter links
* {{text-2-html item.message hashTagURLPrefix='https://www.twitter.com/hashtag/' mentionURLPrefix='https://www.twitter.com/'}}
*
* // hash-tags & mentions, hiding the @-sign for mentions, facebook style
* {{text-2-html item.message hashTagURLPrefix='https://www.facebook.com/hashtag/' mentionURLPrefix='https://www.facebook.com/' mentionAtShown=false}}
*
*
* @param {array} params - Parameters. Only first index used for text-input
* @param {Object} hash - Hash containing optional keyword-paramters
* @param {boolean} [hash.nl=true] - convert new-lines
* @param {boolean} [hash.url=true] - convert URLs
* @param {boolean} [hash.email=true] - convert e-mail-addresses
* @param {boolean} [hash.phone=false] - convert phone-numbers
* @param {string} [hash.target=_blank] - define target for all links
* @param {string} [hash.hashTagURLPrefix=null] - convert hash-tags and define the URL-prefix
* @param {string} [hash.mentionURLPrefix=null] - convert mentions and define the URL-prefix
* @param {boolean} [hash.mentionAtShown=true] - show / hide the @-sign for mentions
* @return {string} - HTML-formatted version of the text-input
*/
export function text2Html(params, hash) {
let text = params[0];
const doNl = hash['nl'] === false ? false : true; // default true
const doUrl = hash['url'] === false ? false : true; // default true
const doEmail = hash['email'] === false ? false : true; // default true
const doPhone = hash['phone'] ? true : false; // default false
const target = hash['target'] || "_blank"; // default "_blank"
const hashTagURLPrefix = hash['hashTagURLPrefix'] || null; // default null
const mentionURLPrefix = hash['mentionURLPrefix'] || null; // default null
const mentionAtShown = hash['mentionAtShown'] === false ? false : true; // default true
// we don't trust anything :)
text = Ember.Handlebars.Utils.escapeExpression(text);
// line-breaks
if( doNl ){
text = text.replace(/(\r\n|\n|\r)/gm, "<br>\n");
}
// hyper-links
if( doUrl ){
const hlRe = /([^"])(https?:\/\/[a-zA-Z0-9\.\-\/]+(?:\?[a-zA-Z0-9=\&]+)?(?:#[\w]+)?)/gi;
text = text.replace(hlRe, "$1<a href=\"$2\" target=\""+target+"\">$2</a>");
}
// email-addresses
if( doEmail ) {
const emRe = /(^|\s)([A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4})/igm;
text = text.replace(emRe, "$1<a href=\"mailto:$2\">$2</a>");
}
// phone-numbers
if( doPhone ) {
/**
* Recognizes:
*
* (123) 456-7890
* +(123) 456-7890
* +(123)-456-7890
* +(123) - 456-7890
* +(123) - 456-78-90
* 123-456-7890
* 123.456.7890
* 1234567890
* +31636363634
* 075-63546725
*/
const phRe = /(^|\s)([+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*)/g;
// still buggy as "2016" will be accepted as a phone-number...
text = text.replace(phRe, "$1<a href=\"tel:$2\">$2</a>");
}
// hash-tags
if( hashTagURLPrefix ) {
text = text.replace(/(^|\s)#([a-z\d][\w-]*)/ig, "$1<a href=\""+hashTagURLPrefix+"$2\" target=\""+target+"\">#$2</a>");
}
// mentions
if( mentionURLPrefix ) {
text = text.replace(/(^|\s)@([a-z\d][\w-]*)/ig, "$1<a href=\""+mentionURLPrefix+"$2\" target=\""+target+"\">"+(mentionAtShown ? "@" : "")+"$2</a>");
}
return new Ember.Handlebars.SafeString(text);
}
// export default Ember.Helper.helper(text2Html);
export default Ember.HTMLBars.makeBoundHelper(text2Html);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment