So I have this function to strip out scripts from the page, but some scripts that are many lines long are still showing up. Is there a way to remove all scripts from the page that loads.
function filterData(data){
// filter all the nasties out
// no body tags
data = data.replace(/<?\/body[^>]*>/g,'');
// no linebreaks
data = data.replace(/[\r|\n]+/g,'');
// no comments
data = data.replace(/<--[\S\s]*?-->/g,'');
// no noscript blocks
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g,'');
// no script blocks
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g,'');
// no self closing scripts
data = data.replace(/<script.*\/>/,'');
// [... add as needed ...]
return data;
}
Here is an example of the script that comes through in the html
<script type="text/javascript">
var ccKeywords="keyword=";
if (typeof(ccauds) != 'undefined')
{
for (var cci = 0; cci < ccauds.Profile.Audiences.Audience.length; cci++)
{
if (cci > 0) ccKeywords += "&keyword="; ccKeywords += ccauds.Profile.Audiences.Audience[cci].abbr;
}
}
</script>
If I got you right, you need to remove all <script> tags with inner code from piece of HTML string. In this case you can try the following regular expression:
data.replace(/<script.*?>[\s\S]*?<\/script>/ig, "");
It should successfully work with one-liners and multi-liners, and does not affect other tags.
DEMO: http://jsfiddle.net/9jBSD/
checkout sugar.js - http://sugarjs.com/
it has a removeTags method that should do what you want
http://sugarjs.com/api/String/removeTags
function filterData(data){
var root = document.createElement("body");
root.innerHTML = data;
$(root).find("script,noscript").remove();
function removeAttrs( node ) {
$.each( node.attributes, function( index, attr ) {
if( attr.name.toLowerCase().indexOf("on") === 0 ) {
node.removeAttribute(attr.name);
}
});
}
function walk( root ) {
removeAttrs(root);
$( root.childNodes ).each( function() {
if( this.nodeType === 3 ) {
if( !$.trim( this.nodeValue ).length ) {
$(this).remove();
}
}
else if( this.nodeType === 8 ) {
$(this).remove();
}
else if( this.nodeType === 1 ) {
walk(this);
}
});
}
walk(root);
return root.innerHTML;
}
filterData("<script>alert('hello');</script></noscript></script><div onclick='alert'>hello</div>\n\n<!-- comment -->");
//"<div>hello</div>"
Related
Hopefully a quick question.
I'm using a JSON file to write out some html and populate with variables from the JSON and append it to part of my html file. This works and is fine. However, I now want to use a different script to apply show and hide filters based on class attributes to the html that has been printed. For some reason, this isn't working. If I just copy and paste the html with variables back into the original document after its been printed out, then the script works though. Is this an issues of synchronicity?
Here's the second script I'm looking to execute if it helps:
$(document).ready(function(){
var targets = $('.filter'),
buttons = $('.filter-button');
buttons.click(function(){
var value = $(this).data('filter');
if(value == "all")
{
buttons.removeClass('checked');
targets.show();
}
else
{
if($(this).hasClass('checked'))
{
$(this).removeClass('checked');
var checkedClasses = buttons.filter('.checked').toArray().map(function(btn){return $(btn).data('filter');});
if(checkedClasses.length == 0)
{
buttons.removeClass('checked');
targets.show();
}
else
{
checkedClasses = $.grep(checkedClasses, function(n, i){ return n != value }),
selector = '.' + checkedClasses.join('.'),
show = targets.filter(selector);
targets.not(show).hide();
show.show();
}
}
else
{
$(this).addClass('checked');
var checkedClasses = buttons.filter('.checked').toArray().map(function(btn){return $(btn).data('filter');}),
selector = '.' + checkedClasses.join('.'),
show = targets.filter(selector);
targets.not(show).hide();
show.show();
}
}
});
});
I was inspired by this topic Show/Hide form fields based on value of other fields and made some changes to working it not only on select.
Here is example:
var ObserverPlugin = (function(){
// here will be stored every DOM object which has
// data-observe attr and data-name attr (data-name will be served
// as a key , which will store another object with a reference to the DOM object
// how many object does it observe)
var observers = {},
publishers = [];
var _setStylesheet = (function() {
// Create the <style> tag
var style = document.createElement("style");
// Add a media (and/or media query) here if you'd like!
// style.setAttribute("media", "screen")
// style.setAttribute("media", "only screen and (max-width : 1024px)")
// WebKit hack :(
style.appendChild(document.createTextNode(""));
// Add the <style> element to the page
document.head.appendChild(style);
return style.sheet;
})();
// observer pattern & revealing module pattern
var observer = (function(){
var topics = {};
var publish = function(topic, reference) {
// if there is no topic on the publish call, well get out !
if (!topics[topic]) {
return false;
}
// self invoked funciton, which calls the function passed when
// the topic was subscribed (if more then one function was published on the same topic
// then call each one of them)
(function(){
var subscribers = topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func(topic, reference);
}
})();
};
var subscribe = function(topic, func) {
if (!topics[topic]) {
topics[topic] = [];
}
topics[topic].push({
func: func
});
};
return {
subscribe: subscribe,
publish: publish,
topics: topics
}
})();
// creates random string, used to make data-name random for observers
var _makeRandomString = function() {
var text = "";
var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ ) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
// verifies if eleme existis in array, if not, returns false
var _isInside = function( elem, array ) {
return array.indexOf(elem) > -1;
};
// topic is the topic
// reference is a reference to the DOM object clicked
var _observerFunction = function(topic, reference) {
var number = reference.attr('data-publish-value');
var topics = topic.toString().split(' ');
var length = topics.length;
//var display;
for( var key in observers ) {
for( var i = 0; i < length; i +=1 ) {
if( _isInside( topics[i], observers[key].topicsObserved ) ) {
// it exists
observers[key].sum += Number(number);
// 'number' is a string, so we have to convert it back to number
}
}
if( observers[key].sum === 1 ) {
// it is 0, so show that goddam DOM obj ! :))
// again, put here 'var' for clarity
// does not affect the code
//display = 'block';
_changeProperty(key,observers[key].property,1);
}
else {
// it is not 0, so hide it
//display = 'none';
_changeProperty(key,observers[key].property,0);
}
//observers[key].reference.css('display', display);
}
// change value to -1 or 1
if( number === '-1' ) {
reference.attr('data-publish-value', '1');
}
else {
reference.attr('data-publish-value', '-1');
}
};
/*
* lets say we have 3 DOM objects with data-publish="1"
and 2 DOM objects with data-publish="2"
and one with data-observe="1 2";
so data-observe has to be called 5 times in order for him to be shown on the page;
each DOM object with data-publish will be added at runtime a data-value attribute
which will be -1 or 1. each time it is clicked or changed, it changes to the opposite.
this serves as data-observes will have a property named sum, which will be in the previous case 5
5 gets calculated with -1, or 1 when clicked data-publish DOM object.
So if i click first at data-publish="1" , 5 becomes 4. if i click again the same data-publish, becomes 5.
when sum property becomes 0, the data-observe is shown.
this function calculates how many data-publish="1" exists and so on
(it also does the other stuff needed for publishers)
*/
var _managePublishers = function() {
$('[data-publish]').each(function(){
var el = $(this);
// adds that value data, remember it? :D
el.attr('data-publish-value', '-1');
// trim in case data-publish = "1 2 3" and store in an array
var publisher = el.data('publish').toString();
// we subscripe 'publisher' topic, but we check each string in topic
// here is tricky. if one publishers has more than one topic inside data-publish
// then we subscribe topic, but we check for topic's substring in publishers
var topics = publisher.split(' ');
if( !observer.topics[publisher] ) {
// we subscribe data-publish topic, becouse when we click it we want to fire something, no?
observer.subscribe( publisher, _observerFunction );
}
// but here in publishers we add only the substrings
for( var key in topics ) {
if( publishers[topics[key]] ) {
// the publisher exists
publishers[topics[key]] += 1;
}
else {
// the publisher doesn't exist
publishers[topics[key]] = 1;
}
}
});
};
// gets the observers, calculates sum, caches their reference
var _manageObservers = function() {
$('[data-observe]').each(function(){
var el = $(this);
// create random data-name
el.attr('data-observe-name', _makeRandomString());
var datas = el.data('observe').toString().split(' '); // make an array again if we have multiple attachments
observers[el.data('observe-name')] = (function(){
var sum = (function(){
var sum2 = 0;
// if datas[key] is found in publishers array, add it to sum
for( var key in datas ) {
var temp = publishers[datas[key]];
if( temp ) {
sum2 += temp;
}
}
return sum2;
})();
var reference = el, topicsObserved = datas; // caching, so it is faster !
// we need this when a user clicks data-publish, we need to see which DOM obj. are observing this.
// i really like revealing module pattern...i got used to it
return {
sum: sum,
reference: reference,
topicsObserved: topicsObserved,
property: $(reference).data('observe-property') //style-display[none/block],attr-disable/-,class-active/inactive
}
})();
})
};
var _changeProperty = function(observer, property, status) {
if(property === "style") {
if(status === 1) {
observers[observer].reference.css('display', 'block');
}
else {
observers[observer].reference.css('display', 'none');
}
}
else if(property === "attr") {
if(status === 1) {
$(observers[observer].reference).removeAttr('disabled');
}
else {
$(observers[observer].reference).attr('disabled','disabled');
}
}
else if(property === "class") {
if(status === 1) {
$(observers[observer].reference).removeClass('inactive');
}
else {
$(observers[observer].reference).addClass('inactive');
}
}
};
var init = function() {
_managePublishers();
_manageObservers();
$('[data-publish]:not(select)').on( 'click', function(){
observer.publish( $(this).data('publish'), $(this) );
});
$('select[data-publish]').on('change', function(){
var cache = $(this);
// if in this select there is an option which has value 1(there is chance that it triggered a succesfull publish) we publish that too
//observer.publish( cache.find('[data-value="1"]').data('publish'), cache.find('[data-value="1"]') );
var el = cache.find(':selected');
observer.publish( el.data('publish'), el );
});
$('[data-publish]').each( function() {
if(this.type !== 'radio' || this.type !== 'checkbox' || this.nodeName !== 'SELECT') {
observer.publish( $(this).data('publish'), $(this) );
}
});
// when observers[xx].sum is 0 it must be activated always, otherwise it is always invisible
$.each( observers, function( key, value ) {
if(value.topicsObserved) {
$.each( value.topicsObserved, function( key2, value2 ) {
if(!publishers.hasOwnProperty(value2)) {
$(value.reference).css('display', 'block');
return;
}
if(value.property === "style") {
_setStylesheet.insertRule('[data-observe-name="'+key+'"] {display: none;}', _setStylesheet.rules.length);
}
else if(value.property === "attr") {
$(value.reference).attr('disabled','disabled');
_setStylesheet.insertRule('[disabled] {cursor: not-allowed;}', _setStylesheet.rules.length);
}
else if(value.property === "class") {
$(value.reference).addClass('inactive');
}
});
}
});
};
return {
init: init,
publish: observer.publish,
subscribe: observer.subscribe
}
})();
ObserverPlugin.init();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" name="form">
<input type="text" name="text" value="">
<div class="wraper">
<label><input type="radio" name="typ" value="subscribe" checked data-publish="newslist" >Subscribe</label>
<label><input type="radio" name="typ" value="unsubscribe" data-publish="unsubscribe" >Unsubscribe</label>
</div>
<div class="wraper">
<button type="submit" name="subscription" value="1" data-observe="newslist" data-observe-property="attr" >
<span>Send</span>
</button>
</div>
<div data-observe="unsubscribe" data-observe-property="style">
<label>
<input type="checkbox" name="confirm" value="1" data-publish="newslist">
<span>Confirm</span>
</label>
</div>
</form>
jsfiddler also here https://jsfiddle.net/ogxusLja/
Problem is that radio inputs fired click event always, not only on
change to second radio input.
Another problem is that Confirm
checkbox is hidden on load.
Expected behavior:
Selected Unsubscribe radio will enable the Send button and hide the Confirm checkbox.
Selected Subscribe radio and Confirm checkbox will together enable the Send button.
Selected Subscribe radio or 'Confirm checkbox' (if only one is selected) Send button will be disabled.
How can I tell, in JavaScript/jQuery if a link is Javascript?
For example:
Trigger
Trying to make sure a script only logs links, and not javascript, anchors, etc.
Basically I need to capture the href of the link as I .each through them (already done) I just need a reliable way to check that variable to see if it is javascript, ie, function w/e
var rand = function() {
return Math.random().toString(36).substr(2);
};
$(function(){
$('#lhcb a').each(function() {
var rawlink = $(this).attr("href");
var link = encodeURIComponent( rawlink );
var token = rand();
var href = $(this).prop('href');
var proceed = $.get( "lhc/link.php?link=" + link + "&a=c", function( data ) {
if ( data == 1 ) {
return true;
} else {
return false;
}
});
if ( href.match("^javascript:") ) {
proceed = false;
}
if ( rawlink.charAt(0) != '#' ) {
if ( proceed ) {
$(this).after( " <span style='font-size:xx-small;'>( Hits: <span id='" + token + "'></span> )</span>" );
$.get( "lhc/link.php?link=" + link + "&a=q", function( data ) {
$('#' + token).html(data);
});
$(this).attr( "href", "lhc/link.php?link=" + link + "&a=g" );
}
}
});
});
This is what I have, but as mentioned below, it wouldn't be able to see if the href is just a function without the JavaScript declaration.
A little script can help. I wrote a sample:
http://jsfiddle.net/qXkHX/
var normalLinks = [];
$("a").each(function(i) {
var a = $(this);
var href = $.trim(a.attr("href"));
if(href.indexOf("javascript:") !== 0) normalLinks.push(href);
});
$("#result").text(normalLinks.join(","));
It iterates through the anchors in the document and pushes every link that does not start with javascript:. Maybe this helps.
I have Javascript functions called start() that have multiple functions to load using window.onload function. However, I have below function that works independently fine. However, if I write it inside the window.onload, then it doesn't work.
//START()
window.onload = start;
function start()
{
loadValues();
showState4();
}
Code that does work independently fine.
window.onload=function(){
document.getElementById("src2TargetAll").onclick = function() {
sureTransfer(document.getElementById("net"), document.getElementById("target"), true);
};
};
I tried re-writing the code as follows in window.onload but it doesn't work. How to re-write the below code in single window.onload function.
window.onload = start;
function start()
{
loadValues(); //loadValues() and showState4() works fine without sendValues().
showState4();
sendValuess(); // tested this sendValues without above two functions and that also works fine. but three functions in window.onload creates a problem
}
function sendValuess(){
document.getElementById("src2TargetAll").onclick = function() {
sureTransfer(document.getElementById("net"), document.getElementById("target"), true);
};
};
Error that I get after adding sendValues() to window.onload is as follows:
STOP RUNNING THIS SCRIPT?
A SCRIPT ON THIS PAGE IS CAUSING YOUR WEB BROWSER TO RUN SLOWLY. IF IT CONTINUES TO RUN, YOUR COMPUTER MIGHT BECOME UNRESPONSIVE.
below is the code for loadValues and other functions as requested by a person who trying to help me:
function showState4(){
var me = document.getElementById('stk1');
var values = ''; //populate selected options
for (var i=0; i<me.length; i++)
if (me.options[i].selected)
values += me.options[i].value + ',';
values = values.substring(0, values.length-1);
var selected=[values];
var temp= new Array();
temp = values.split(",");
var del = document.getElementById('StakeHolder');
for(var i=0; i<del.length; i++)
{
for(var j=0;j<temp.length;j++)
{
if(temp[j] == del.options[i].value)
{
del.options[i].selected = true;
}
}
}
}
function loadValues()
{
var RD_REQ_RT_ID = "<%=RD_REQ_RT_ID %>";
if(RD_REQ_RT_ID=="null")
{
document.getElementById('requestType').value="";
}
else{
document.getElementById('requestType').value=RD_REQ_RT_ID;
}
)
_
function sureTransfer(from, to, all) {
if ( from.getElementsByTagName && to.appendChild ) {
while ( getCount(from, !all) > 0 ) {
transfer(from, to, all);
}
}
}
function getCount(target, isSelected) {
var options = target.getElementsByTagName("option");
if ( !isSelected ) {
return options.length;
}
var count = 0;
for ( i = 0; i < options.length; i++ ) {
if ( isSelected && options[i].selected ) {
count++;
}
}
return count;
}
function transfer(from, to, all) {
if ( from.getElementsByTagName && to.appendChild ) {
var options = from.getElementsByTagName("option");
for ( i = 0; i < options.length; i++ ) {
if ( all ) {
to.appendChild(options[i]);
} else {
if ( options[i].selected ) {
to.appendChild(options[i]);
}
}
}
}
}
How to add sendValuess() to window.onload without any issue?
window.addEventListener will not work in IE so use window.attachEvent
You can do something like this
function fun1(){
// do something
}
function fun2(){
// do something
}
var addFunctionOnWindowLoad = function(callback){
if(window.addEventListener){
window.addEventListener('load',callback,false);
}else{
window.attachEvent('onload',callback);
}
}
addFunctionOnWindowLoad(fun1);
addFunctionOnWindowLoad(fun2);
The error:
STOP RUNNING THIS SCRIPT?
A SCRIPT ON THIS PAGE IS CAUSING YOUR WEB BROWSER TO RUN SLOWLY.
IF IT CONTINUES TO RUN, YOUR COMPUTER MIGHT BECOME UNRESPONSIVE.
It occures when IE is running in compatibility mode. (happens while using FB and Google+)
goto "Tools" menu and select the "Compatibility View Settings" option. This will open a window where you can turn off the feature "Display all websites using Compatibility View".
I tried my best to convert JavaScript to FBJS according to this page: http://wiki.developers.facebook.com/index.php/FBJS.
Yet my tabs are still not working properly. Does anyone have any suggestions how to fix this so I can click through the tabs and display and hide content accordingly:
<script type="text/javascript"><!--
var tabLinks = [];
var contentDivs = [];
function init() {
var tabListItems = document.getElementById('tabs').getChildNodes();
for ( var i = 0; i < tabListItems.length; i++ ) {
if ( tabListItems[i].getNodeName("LI") ) {
var tabLink = getFirstChildWithTagName( tabListItems[i], 'A' );
var id = getHash( tabLink.getAttribute('href') );
tabLinks[id] = tabLink;
contentDivs[id] = document.getElementById( id );
}
}
var i = 0;
for ( var id in tabLinks ) {
tabLinks[id].addEventListener(onclick, showTab)
tabLinks[id].addEventListener(onfocus, function() { this.blur() };
if ( i == 0 ) tabLinks[id].setClassName('selected');
i++;)
}
var i = 0;
for ( var id in contentDivs ) {
if ( i != 0 ) contentDivs[id].setClassName('tabContent hide');
i++;
}
}
function showTab() {
var selectedId = getHash( this.getAttribute('href') );
for ( var id in contentDivs ) {
if ( id == selectedId ) {
tabLinks[id].setClassName('selected');
contentDivs[id].setClassName('tabContent');
} else {
tabLinks[id].setClassName('');
contentDivs[id].setClassName('tabContent hide');
}
}
return false;
}
function getFirstChildWithTagName( element, tagName ) {
for ( var i = 0; i < element.getChildNodes().length; i++ ) {
if ( element.getChildNodes[i].getNodeName(tagName) ) return element.getChildNodes[i];
}
}
function getHash( url ) {
var hashPos = url.getLastIndexOf ( '#' );
return url.getSubString( hashPos + 1 );
}
init();
--></script>
Thanks for any response.
FBML tabs (which use FBJS) are deprecated now and will be disabled in the future. You should create a new application with IFRAME tab (which is by default now).
IFRAME tabs are just tabs with IFRAME inside, and your code is loaded into this iframe from a specified URL as any other web page. You can use any Javascript frameworks in it (like jQuery), so you don't need to learn how to write FBJS.
Setup a Facebook page that uses a Facebook app. Make sure you set up your app using an iFrame that points to a file on your server. You'll get a lot more freedom using an iFrame when it comes to Javascript and it's a great way to leverage a CMS if you're going to need to do that as well. Best of Luck!