Remove CSS selectors and it's related properties if needed - javascript

I am trying to remove specific CSS selectors, and if there is no more selectors for a list of properties than the script removes it...
I was able to get a part of the script working: http://jsfiddle.net/jnbdz/MarRr/5/
Here is the code:
$$('button')[0].addEvent('click', function(){
var css = document.id('css').get('text');
var newCss = css.replace(/(\n|\r|\s\s)/g, "")
.replace(/(,\s*body\s*(?={)|,\s*body\s*(?=,)|body\s*,|,\s*head\s*(?={)|,\s*head\s*(?=,)|head\s*,)/gi, "")
.replace(/(body\s*(?={)|head\s*(?={))/gi, "")
.replace(/(^\{[^}]*?\}|\}\s*\{[^}]*?\})/gim, "");
document.id('cleancss').set('text', newCss);
});
The problem is that if I remove the line breaks the script I wrote wont be able to remove the properties that are not related to any selectors...
If I keep the line breaks it works...
Also, I would like to know from coders that are good with ReGex if my code is good...
Thanks a lot in advance for any help.

In the last replace you're using the multiline flag. That can't work, if you have only one line, which you do after the first replace. So lets keep the linebreaks first and remove them after the removal of the selectors.
You also can simplify the regexes a bit. Use x(?=a|b) instead of x(?=a)|x(?=b). You also don't need the lazy match [^\}]*?.
Below is a working example. For clarity I only removed the body selector.
$$('button')[0].addEvent('click', function(){
var css = document.id('css').get('text');
var newCss = css
// replace multiple tabs or spaces by one
.replace(/( |\t)+/g, " ")
// remove space at beginning of line
.replace(/(^\s)/gm, "")
// remove body in selector lists
.replace(/(,\s*body\s*(?={|,)|body\s*,)/gi, "")
// remove body before {
.replace(/(body\s*(?={))/gi, "")
// remove rules without selector
.replace(/[\n\r]+\{[^\}]*\}/g, "")
// remove linebreaks
.replace(/[\n\r]+/g, "");
document.id('cleancss').set('text', newCss);
});
You could further compress the stylesheet by removing spaces in front of { or after : and ,

Related

Replace non-code text on webpage

I searched through a bunch of related questions that help with replacing site innerHTML using JavaScript, but most reply on targetting the ID or Class of the text. However, my can be either inside a span or td tag, possibly elsewhere. I finally was able to gather a few resources to make the following code work:
$("body").children().each(function() {
$(this).html($(this).html().replace(/\$/g,"%"));
});
The problem with the above code is that I randomly see some code artifacts or other issues on the loaded page. I think it has something to do with there being multiple "$" part of the website code and the above script is converting it to %, hence breaking things.using JavaScript or Jquery
Is there any way to modify the code (JavaScript/jQuery) so that it does not affect code elements and only replaces the visible text (i.e. >Here<)?
Thanks!
---Edit---
It looks like the reason I'm getting a conflict with some other code is that of this error "Uncaught TypeError: Cannot read property 'innerText' of undefined". So I'm guessing there are some elements that don't have innerText (even though they don't meet the regex criteria) and it breaks other inline script code.
Is there anything I can add or modify the code with to not try the .replace if it doesn't meet the regex expression or to not replace if it's undefined?
Wholesale regex modifications to the DOM are a little dangerous; it's best to limit your work to only the DOM nodes you're certain you need to check. In this case, you want text nodes only (the visible parts of the document.)
This answer gives a convenient way to select all text nodes contained within a given element. Then you can iterate through that list and replace nodes based on your regex, without having to worry about accidentally modifying the surrounding HTML tags or attributes:
var getTextNodesIn = function(el) {
return $(el)
.find(":not(iframe, script)") // skip <script> and <iframe> tags
.andSelf()
.contents()
.filter(function() {
return this.nodeType == 3; // text nodes only
}
);
};
getTextNodesIn($('#foo')).each(function() {
var txt = $(this).text().trim(); // trimming surrounding whitespace
txt = txt.replace(/^\$\d$/g,"%"); // your regex
$(this).replaceWith(txt);
})
console.log($('#foo').html()); // tags and attributes were not changed
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo"> Some sample data, including bits that a naive regex would trip up on:
foo<span data-attr="$1">bar<i>$1</i>$12</span><div>baz</div>
<p>$2</p>
$3
<div>bat</div>$0
<!-- $1 -->
<script>
// embedded script tag:
console.log("<b>$1</b>"); // won't be replaced
</script>
</div>
I did it solved it slightly differently and test each value against regex before attempting to replace it:
var regEx = new RegExp(/^\$\d$/);
var allElements = document.querySelectorAll("*");
for (var i = 0; i < allElements.length; i++){
var allElementsText = allElements[i].innerText;
var regExTest = regEx.test(allElementsText);
if (regExTest=== true) {
console.log(el[i]);
var newText = allElementsText.replace(regEx, '%');
allElements[i].innerText=newText;
}
}
Does anyone see any potential issues with this?
One issue I found is that it does not work if part of the page refreshes after the page has loaded. Is there any way to have it re-run the script when new content is generated on page?

Slice first character from paragraph element, replace content and add class. jQuery

I am close to getting this function working, but not quite there yet.
The basic logic says find any p element that contains "+", strip the "+" from the text and try and replace the existing content with the new content and add a class.
Initially I had all of the matched elements being returned and concatenated into a single paragraph. So I tried to create an each function. I am now seeing the right results in the console, but I am not sure how to replace the content for the matched paragraph only (using $(this)).
I've made a fiddle here: http://jsfiddle.net/lharby/x4NRv/
Code below:
// remove bespoke text and add class
$qmarkText = $('.post p:contains("+")').each(function() {
$qStr = $(this).text().slice(1);
$qmarkText.replaceWith('<p class="subhead-tumblr"' + $qStr + '</p>');
console.log($qStr);
});
I know that $qmarkText is not quite but not sure how to fix this, have tried several variations.
Hopefully someone can help me out.
You could use following snippet:
// remove bespoke text and add class
$qmarkText = $('p').filter(function () {
return $(this).text().substring(0, 1) === "+"
}).each(function () {
$qStr = $(this).text().slice(1);
$(this).replaceWith('<p class="subhead-tumblr">' + $qStr + '</p>');
});
DEMO
This avoid using :contains() which will match even character '+' is inside content text, not only at the beginning.

JQuery to Trim leading white space only?

I am theming a JSP app that has a table header with dynamically generated data (I think it's called Jasper Reports?) and I don't have access to any template files for the output. I've gotten things to look pretty good with a little JQuery foo.
But I am still having one issue, there seems to be white space in some span tags within the headers td > spans:
<td><span> My Heading</span></td>
Note the white space before the word "My".
I found this nifty bit of code to trim white space but the issue is that it takes all white space out.
var pane = $('span');
pane.val($.trim(pane.val()).replace(/\s*[\r\n]+\s*/g, '\n')
.replace(/(<[^\/][^>]*>)\s*/g, '$1')
.replace(/\s*(<\/[^>]+>)/g, '$1'));
So now using this code, it ends up as:
<td><span>MyHeading</span></td>
Ideally I would like to modify it so just the first bit of white space is removed but none after that.
Use .text() to get the string value.
var pane = $('span');
pane.html($.trim(pane.text()));
http://jsfiddle.net/gaboesquivel/cHevR/
Edit:
the above code won't work as it overwrites the text if it there's more than 1 span in the document
You need to iterate the array of spans
//array of all the spans that are children of a td element
var spansArray = $('td > span');
//iterate the array
spansArray.each(function() {
var $this = $(this);
$this.html($.trim($this.text()));
});​
http://jsfiddle.net/gaboesquivel/cHevR/2/
Try this:
.replace(/^\s+/g, "");
That should trim any whitespace at the beginning of the string. Alternatively, you can make it trim trailing whitespace using a slightly different expression. See here:
http://www.toptip.ca/2010/02/javascript-trim-leading-or-trailing.html
Here's the example so you can see how it works:
http://jsfiddle.net/CkMPH/
For the only first space to be removed you need that code
var pane = $('span');
pane.text(pane.text().replace(/^\s/, ''));
http://jsfiddle.net/P9jSL/

Dynamically add anchor tags around text WHITHOUT re-writing the HTML

I'm using javascript, jQuery and regex to add anchors (#hashtag) around all hashtags on the page. The regex detects things that are hashtags, and then I use jQuery to re-write the HTML and a javascript .replace() to add in the anchor tags. I also do a javascript if statement so it doesn't replace things inside of script and style tags.
var regExp = /(\W)#([a-zA-Z_]+)(\W)/gm;
var boxLink = "$1<a class='tagLink' onClick=\"doServer('#$2')\">#$2</a>$3"
$('body').children().each(function(){
if (($(this).get(0).tagName.toLowerCase() != 'style')
&& ($(this).get(0).tagName.toLowerCase() != 'script')
) {
$(this).html($(this).html().replace(regExp, boxLink));
}
});
});
Simple enough... right?
The problem is that I'm making a plugin, so developers will deploy this on their websites. The html rewrite ($(this).html($(this).html().replace(regExp, boxLink));) breaks seemingly random areas of javascript on websites. It also messes up some HTML structure sometimes. It's just a really messy thing to be doing on lots of different sites.
So rather then fix the re-write, I'd like to just find another way to do this. Is there any way I can accomplish the same thing (adding anchor tags around all hashtags on the page) without re-writing the entire HTML on the page each load?
If not, how can I tweak the javascript I have so it isn't so conflicting with javascript on people's sites.
This replaces every textnode with a hash tag on this page with:
<span>texts without hash <a name = "myplugin">#</a></span>
You can substitute the regex to match yours :)
var getTextNodesIn = function(el) {
$(el).find("*").andSelf().contents().each(function() {
var parentNode = this.parentNode.nodeName,
data = this.data;
if(this.nodeType == 3 && parentNode !== "SCRIPT" && parentNode !== "STYLE" && data.indexOf("#") > -1){
var anch = data.replace(/#/g,"#".anchor("myplugin"));
$(this).replaceWith("<span>"+anch+"<span/>");
}
});
};
getTextNodesIn(document.body);
P.S getTextNodesIn function was taken from this post :
https://stackoverflow.com/a/4399718/776575
I think part of the problem is that you need to isolate the text nodes and operate on those, not chunks of html. Your example only iterates across the direct children of body, but then tries to apply replacements to whatever html is within those children. This could easily cause existing markup and javascript to break.
Answers to question might be helpful: How do I select text nodes with jQuery?

Replace a empty space with " " using Jquery

I am looking around on the web but I am not finding anything useful. :(
I am having a problem that I don't understand. I am sure that I am doing something wrong, but I don't know well the syntax of jQuery to understand what is that I am not doing right.
I am using animations with JS and CSS 3, and I am having troubles with empty spaces between the words, and to solve this problems I have to find a way to substitute chars inside a string of text with something else. Like an empty space with a , or as a test that I was trying to do a "n" with a "xxxxx".
What I think that I am doing is:
when the page is loaded
Modify the string of any paragraph with the class .fancy-title that contains "n" with a text "xxxxx"
So:
$(document).ready(function(){
for(i=0; i< myLength+1; i++){
var charCheck = $(".fancy-title").text()[i];
if(charCheck == "n"){
charCheck.replace("n", "xxxxxxxx");
}
}
});
But I receive an error that it said:
charCheck.replace("n", "xxxxxxxx"); it is not a function
I am using jquery
and other scripts that are based on jquery to make animations, rotation and scaling... and they are all in the HEAD with jquery first to load.
What am I doing wrong? Manipulation in jQuery does it need a specific .js extension? I understood that was in the basic capability of jQuery, and looking at other examples all creates me the same kind of error.
I even tried
if(charCheck == "n"){
$(".fancy-title").text()[i] == " "
}
But simply the modification it is not applied on the page. I tried with innerHTML as well :(
I feel so incompetent...
Thank you in advance for any help.
$(document).ready(function(){
$(".fancy-title").each(function(i){
var text = $(this).html();
$(this).html(text.replace(/ /g, " "));
})
});
You have no problem with the replace part :).
$(document).ready(function(){
$(".fancy-title").each(function () { //for all the elements with class 'fancy-title'
var s=$(this).text(); //get text
$(this).text(s.replace(/n/g, 'xxxxxxxx')); //set text to the replaced version
});
});
Just a quick example, hope it works.
Have you tried the css style white-space:pre instead of replacing ' ' with ' '?
http://de.selfhtml.org/css/eigenschaften/ausrichtung.htm#white_space
It seems you are trying to replace a single character with a new string.
You might be able to get the right result by dropping the iteration and simply call .replace on the jQuery-object.

Categories

Resources