Below code works on the Mootools library, I would like it to work on jQuery if possible, I so far had no luck.
HTML
<p id="test">#user has an email address of user#email.com. See! the regexp works #people!</p>
MooTools
$('test').set('html', $('test').get('html').replace(/\B\#([\w\-]+)/gim, function(match, name){
return '' + match + '';
}));
Fiddle
Try this:
$('#test').html($('#test').html().replace(/\B\#([\w\-]+)/gim, function(match, name){
return '' + match + '';
}));
Example fiddle
Fiddled with this a bit for you:
$('#test').html($('#test').html().replace(/\B\#([\w\-]+)/gim, function(match, name){
return '' + match + '';
}));
The key differences are:
finding test by id by prefixing the selector with #
using element.html() method to get and set html, instead of get and set
A mootools native solution for tweets - i know you want to go the jquery route but for reference.
String.implement({
linkify: function(){
// courtesy of Jeremy Parrish (rrish.org)
return String(this).replace(/(https?:\/\/[\w\-:;?&=+.%#\/]+)/gi, '$1')
.replace(/(^|\W)#(\w+)/g, '$1#$2')
.replace(/(^|\W)#(\w+)/g, '$1#$2');
}
});
var tests = [
"#user has an email address of user#email.com. See! the regexp works #people!",
"#d_mitar likes #mootools a fair bit. http://foo.com#bar"
];
// on proto
tests.each(function(el) {
new Element("div", {
html: el.linkify()
}).inject(document.body);
});
// on host object
tests.each(function(el) {
new Element("div", {
html: String.linkify(el)
}).inject(document.body);
});
http://jsfiddle.net/dimitar/fG4KF/
this also deals with converting hash tags and URLs
Related
I'm new to AngularJS and trying to create a simple app that will allow me to upload files to my Laravel driven website. I want the form to show me the preview of what the uploaded item will look like. So I am using ng-model to achieve this and I have stumbled upon the following:
I have an input with some basic bootstrap stylings and I am using custom brackets for AngularJS templating (because as I mentioned, I am using Laravel with its blading system). And I need to remove spaces from the input (as I type it) and replace them with dashes:
<div class="form-group"><input type="text" plaeholder="Title" name="title" class="form-control" ng-model="gnTitle" /></div>
And then I have this:
<a ng-href="/art/[[gnTitle | spaceless]]" target="_blank">[[gnTitle | lowercase]]</a>
And my app.js looks like this:
var app = angular.module('neoperdition',[]);
app.config(function($interpolateProvider){
$interpolateProvider.startSymbol('[[').endSymbol(']]');
});
app.filter('spaceless',function(){
return function(input){
input.replace(' ','-');
}
});
I get the following error:
TypeError: Cannot read property 'replace' of undefined
I understand that I need to define the value before I filter it, but I'm not sure where to define it exactly. And also, if I define it, I don't want it to change my placeholder.
There are few things missing in your filter. First of all you need to return new string. Secondary, regular expression is not correct, you should use global modifier in order to replace all space characters. Finally you also need to check if the string is defined, because initially model value can be undefined, so .replace on undefined will throw error.
All together:
app.filter('spaceless',function() {
return function(input) {
if (input) {
return input.replace(/\s+/g, '-');
}
}
});
Demo: http://plnkr.co/edit/5Rd1SLjvNI18MDpSEP0a?p=preview
Bravi just try this filter
for eaxample {{X | replaceSpaceToDash}}
app.filter('replaceSpaceToDash', function(){
var replaceSpaceToDash= function( input ){
var words = input.split( ' ' );
for ( var i = 0, len = words.length; i < len; i++ )
words[i] = words[i].charAt( 0 ) + words[i].slice( 1 );
return words.join( '-' );
};
return replaceSpaceToDash;
});
First, you have to inject your filter in you module by adding it's name to the array :
var app = angular.module('neoperdition',['spaceless']);
Secondly, the function of the filter have to return something. The String.prototype.replace() return a new String. so you have to return it :
app.filter('spaceless',function(){
return function(input){
return input.replace(' ','-');
}
});
Edit: dfsq's answer being a lot more accurate than mine.
Is it possible to check the XMLHttpRequestObject.responseText value using if condition instead of just displaying it?
I have tried like this.
var a=XMLHttpRequestObject.responseText;
if(a=="false")
{
document.getElementById("show_mark").innerHTML =a;
}
I know its wrong,but i need to do like this.Is there any other alternative way for doing this?Help me i am completely a newbie to AJAX.
It is possible that the response text has added white spaces. To remove white spaces at the start and end of a string use string.trim().
In your case a=a.trim()
If trim is not available in your browser's JavaScript interpreter add in
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
Source
Finally i found the mistake.Its not the white spaces around the value.Actually its all the html tags like <html><body>false</body> etc., I removed these characters with the help of this code. I got the answer.
var a=XMLHttpRequestObject.responseText;
a = a.replace(/&(lt|gt);/g, function (strMatch, p1){
return (p1 == "lt")? "<" : ">";
});
var b = (a.replace(/<\/?[^>]+(>|$)/g, "")).trim();
if(b=="false")
{
document.getElementById("show_mark").innerHTML =b;
}
Thanks for the support.
A user of my HTML 5 application can enter his name in a form, and this name will be displayed elsewhere. More specifically, it will become the innerHTML of some HTML element.
The problem is that this can be exploited if one enters valid HTML markup in the form, i.e. some sort of HTML injection, if you will.
The user's name is only stored and displayed on the client side so in the end the user himself is the only one who is affected, but it's still sloppy.
Is there a way to escape a string before I put it in an elements innerHTML in Dojo? I guess that Dojo at one point did in fact have such a function (dojo.string.escape()) but it doesn't exist in version 1.7.
Thanks.
dojox.html.entities.encode(myString);
Dojo has the module dojox/html/entities for HTML escaping. Unfortunately, the official documentation still provides only pre-1.7, non-AMD example.
Here is an example how to use that module with AMD:
var str = "<strong>some text</strong>"
require(['dojox/html/entities'], function(entities) {
var escaped = entities.encode(str)
console.log(escaped)
})
Output:
<strong>some text</strong>
As of Dojo 1.10, the escape function is still part of the string module.
http://dojotoolkit.org/api/?qs=1.10/dojo/string
Here's how you can use it as a simple template system.
require([
'dojo/string'
], function(
string
){
var template = '<h1>${title}</h1>';
var message = {title: 'Hello World!<script>alert("Doing something naughty here...")</script>'}
var html = string.substitute(
template
, message
, string.escape
);
});
I tried to find out how other libraries implement this function and I stole the idea of the following from MooTools:
var property = (document.createElement('div').textContent == null) ? 'innerText': 'textContent';
elem[property] = "<" + "script" + ">" + "alert('a');" + "</" + "script" + ">";
So according to MooTools there is either the innerText or the textContent property which can escape HTML.
Check this example of dojo.replace:
require(["dojo/_base/lang"], function(lang){
function safeReplace(tmpl, dict){
// convert dict to a function, if needed
var fn = lang.isFunction(dict) ? dict : function(_, name){
return lang.getObject(name, false, dict);
};
// perform the substitution
return lang.replace(tmpl, function(_, name){
if(name.charAt(0) == '!'){
// no escaping
return fn(_, name.slice(1));
}
// escape
return fn(_, name).
replace(/&/g, "&").
replace(/</g, "<").
replace(/>/g, ">").
replace(/"/g, """);
});
}
// that is how we use it:
var output = safeReplace("<div>{0}</div",
["<script>alert('Let\' break stuff!');</script>"]
);
});
Source: http://dojotoolkit.org/reference-guide/1.7/dojo/replace.html#escaping-substitutions
I'm using this regular expression for detect if an url ends with a jpg :
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|]*^\.jpg)/ig;
it detects the url : e.g. http://www.blabla.com/sdsd.jpg
but now i want to detect that the url doesn't ends with an jpg extension, i try with this :
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|]*[^\.jpg]\b)/ig;
but only get http://www.blabla.com/sdsd
then i used this :
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|]*[^\.jpg]$)/ig;
it works if the url is alone, but dont work if the text is e.g. :
http://www.blabla.com/sdsd.jpg text
Try using a negative lookahead.
(?!\.jpg)
What you have now, [^\.jpg] is saying "any character BUT a period or the letters j, p, or g".
EDIT Here's an answer using negative look ahead and file extensions.
Update
Knowing this is a "url finder" now, here's a better solution:
// parseUri 1.2.2
// (c) Steven Levithan <stevenlevithan.com>
// MIT License
// --- http://blog.stevenlevithan.com/archives/parseuri
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
};
parseUri.options = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:#]*)(?::([^:#]*))?)?#)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:#]+:[^:#\/]*#)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:#]*)(?::([^:#]*))?)?#)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};//end parseUri
function convertUrls(element){
var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig
element.innerHTML = element.innerHTML.replace(urlRegex,function(url){
if (parseUri(url).file.match(/\.(jpg|png|gif|bmp)$/i))
return '<img src="'+url+'" alt="'+url+'" />';
return ''+url+'';
});
}
I used a parseUri method and a slightly different RegEx for detecting the links. Between the two, you can go through and replace the links within an element with either a link or the image equivalent.
Note that my version checks most images types using /\.(jpg|png|gif|bmp)$/i, however this can be altered to explicitly capture jpg using /\.jpg$/i. A demo can be found here.
The usage should be pretty straight forward, pass the function an HTML element you want parsed. You can capture it using any number of javascript methods (getElementByID, getElementsByTagName, ...). Hand it off to this function, and it will take care of the rest.
You can also alter it and add it tot he string protoype so it can be called natively. This version could be performed like so:
String.prototype.convertUrls = function(){
var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig
return this.replace(urlRegex,function(url){
if (parseUri(url).file.match(/\.(jpg|png|gif|bmp)$/i))
return '<img src="'+url+'" alt="'+url+'" />';
return ''+url+'';
});
}
function convertUrls(element){
element.innerHTML = element.innerHTML.convertUrls();
}
(Note the logic has moved to the prototype function and the element function just calls the new string extension)
This working revision can be found here
Define the URL regex from the RFC 3986 appendix:
function hasJpgExtension(myUrl) {
var urlRegex = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
var match = myUrl.match(urlRegex);
if (!match) { return false; }
Whitelist the protocol
if (!/^https?/i.test(match[2])) { return false; }
Grab the path portion so that you can filter out the query and the fragment.
var path = match[5];
Decode it so to normalize any %-encoded characters in the path.
path = decodeURIComponenent(path);
And finally, check that it ends with the appropriate extension:
return /\.jpg$/i.test(path);
}
This is a simple solution from the post of #Brad and don't need the parseUri function:
function convertUrls(text){
var urlRegex = /((\b(https?|ftp|file):\/\/|www)[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
var result = text.replace(urlRegex,function(url){
if (url.match(/\.(jpg|png|gif|bmp)$/i))
return '<img width="185" src="'+url+'" alt="'+url+'" />';
else if(url.match(/^(www)/i))
return ''+url+'';
return ''+url+'';
});
return result;
}
The same result :
http://jsfiddle.net/dnielF/CC9Va/
I don't know if this is the best solution but works for me :D thanks !
Generally you can check all the extensions with some like (for pictures):
([^\s]+(\.(?i)(jpg|jpeg|png|gif|bmp))$)
the questions says it all :)
eg. we have >, we need > using only javascript
Update: It seems jquery is the easy way out. But, it would be nice to have a lightweight solution. More like a function which is capable to do this by itself.
You could do something like this:
String.prototype.decodeHTML = function() {
var map = {"gt":">" /* , … */};
return this.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);?/gi, function($0, $1) {
if ($1[0] === "#") {
return String.fromCharCode($1[1].toLowerCase() === "x" ? parseInt($1.substr(2), 16) : parseInt($1.substr(1), 10));
} else {
return map.hasOwnProperty($1) ? map[$1] : $0;
}
});
};
function decodeEntities(s){
var str, temp= document.createElement('p');
temp.innerHTML= s;
str= temp.textContent || temp.innerText;
temp=null;
return str;
}
alert(decodeEntities('<'))
/* returned value: (String)
<
*/
I know there are libraries out there, but here are a couple of solutions for browsers. These work well when placing html entity data strings into human editable areas where you want the characters to be shown, such as textarea's or input[type=text].
I add this answer as I have to support older versions of IE and I feel that it wraps up a few days worth of research and testing. I hope somebody finds this useful.
First this is for more modern browsers using jQuery, Please note that this should NOT be used if you have to support versions of IE before 10 (7, 8, or 9) as it will strip out the newlines leaving you with just one long line of text.
if (!String.prototype.HTMLDecode) {
String.prototype.HTMLDecode = function () {
var str = this.toString(),
$decoderEl = $('<textarea />');
str = $decoderEl.html(str)
.text()
.replace(/<br((\/)|( \/))?>/gi, "\r\n");
$decoderEl.remove();
return str;
};
}
This next one is based on kennebec's work above, with some differences which are mostly for the sake of older IE versions. This does not require jQuery, but does still require a browser.
if (!String.prototype.HTMLDecode) {
String.prototype.HTMLDecode = function () {
var str = this.toString(),
//Create an element for decoding
decoderEl = document.createElement('p');
//Bail if empty, otherwise IE7 will return undefined when
//OR-ing the 2 empty strings from innerText and textContent
if (str.length == 0) {
return str;
}
//convert newlines to <br's> to save them
str = str.replace(/((\r\n)|(\r)|(\n))/gi, " <br/>");
decoderEl.innerHTML = str;
/*
We use innerText first as IE strips newlines out with textContent.
There is said to be a performance hit for this, but sometimes
correctness of data (keeping newlines) must take precedence.
*/
str = decoderEl.innerText || decoderEl.textContent;
//clean up the decoding element
decoderEl = null;
//replace back in the newlines
return str.replace(/<br((\/)|( \/))?>/gi, "\r\n");
};
}
/*
Usage:
var str = ">";
return str.HTMLDecode();
returned value:
(String) >
*/
Here is a "class" for decoding whole HTML document.
HTMLDecoder = {
tempElement: document.createElement('span'),
decode: function(html) {
var _self = this;
html.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);/gi,
function(str) {
_self.tempElement.innerHTML= str;
str = _self.tempElement.textContent || _self.tempElement.innerText;
return str;
}
);
}
}
Note that I used Gumbo's regexp for catching entities but for fully valid HTML documents (or XHTML) you could simpy use /&[^;]+;/g.
There is nothing built in, but there are many libraries that have been written to do this.
Here is one.
And here one that is a jQuery plugin.