Created
October 20, 2010 19:01
-
-
Save allboyshatebras/637070 to your computer and use it in GitHub Desktop.
Useful for manipulating CSS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
var rules = [], stylesheets = [], createCount = 0; | |
/** | |
* Given a scope (typically $(document)) all sheets are scanned until requested rule is found | |
* | |
* @author Adam Yanalunas | |
* @since 2010-01-24 | |
* | |
* @param string|array Rules to be returned | |
* @return CSSStyleRule|null | |
*/ | |
$.fn.CSSelection = function(action) { | |
if (0 == stylesheets.length) { | |
stylesheets = retrieveStylesheets($(document)[0]); | |
//What if there aren't any stylesheets on the page? | |
if(0 == stylesheets.length) { | |
stylesheets.push(createStylesheet()); | |
} | |
} | |
if (typeof action === 'object') { | |
var rule = retrieveRule(this.selector); | |
//Only add if this rule doesn't already exist | |
if (null === rule) { | |
var addResult = addRule(this.selector, arguments[0]); | |
return this; | |
} else { | |
//Turn the CSS rule name into a JavaScript rule name (i.e.: border-color = borderColor) | |
for (ruleName in arguments[0].rules) { | |
var nameParts = ruleName.split('-'); | |
for (var i = 1, len = nameParts.length; i < len; i++) { | |
nameParts[i] = nameParts[i].substring(0, 1).toUpperCase() + nameParts[i].substring(1, nameParts[i].length); | |
} | |
var cssName = nameParts.join(''); | |
rule.style[cssName] = arguments[0].rules[ruleName]; | |
} | |
return this; | |
} | |
} else if ('remove' === action) { | |
return removeRule(retrieveRule(this.selector)); | |
} else { | |
return retrieveRule(this.selector); | |
return this; | |
} | |
} | |
/** | |
* Create a new stylesheet in the DOM | |
* | |
* @author Adam Yanalunas | |
* @since 2010-08-16 | |
* | |
* @return HTMLStyle Reference to the newly-created, blank stylesheet | |
*/ | |
var createStylesheet = function() { | |
var cssNode = document.createElement('style'); | |
cssNode.type = 'text/css'; | |
cssNode.rel = 'stylesheet'; | |
//cssNode.media = 'screen'; | |
cssNode.title = 'dynamicSheet' + createCount; | |
document.getElementsByTagName("head")[0].appendChild(cssNode); | |
return cssNode.sheet; | |
} | |
/** | |
* Go through all style sheets. Sheets using @import are iterated over and added to flat list | |
* Interesting note: IE does not resolve .href to absolute path with protocol and host prefix. | |
* Therefore, if there's a protocol in .href using IE you know it's not a local styleSheet | |
* | |
* @author Adam Yanalunas | |
* @since 2010-01-25 | |
* | |
* @param scope Typically $(document) but can be any given scope | |
* @return array One-dimensional list of all stylesheets loaded in scope | |
*/ | |
var retrieveStylesheets = function(scope) { | |
var collection = scope.styleSheets; | |
var sheets = []; | |
var localDomain = document.location.host; | |
for (var i = 0, len = collection.length; i < len; i++) { | |
var sheetHref = collection[i].href || ''; | |
var sheetHost = sheetHref.substring(sheetHref.indexOf('://')+3,sheetHref.length); | |
if(localDomain != sheetHost.substring(0,sheetHost.indexOf('/')) && 'http' == sheetHref.substring(0, 4)) continue; | |
var entries = getEntries(collection[i]); | |
if (0 < entries.length && 3 == entries[0].type) { | |
for (var j = 0; j < entries.length; j++) { | |
sheets.push(entries[j].styleSheet); | |
} | |
} else { | |
sheets.push(collection[i]); | |
} | |
} | |
return sheets; | |
} | |
/** | |
* Based on browser support return an array of CSS rules for a provided stylesheet | |
* | |
* @author Adam Yanalunas | |
* @since 2010-01-24 | |
* | |
* @param sheet StyleSheet A style sheet object | |
* @return array List of rules, if any, in provided stylesheet | |
*/ | |
var getEntries = function(sheet) { | |
if(typeof sheet == 'undefined') return []; | |
//if(0 == sheet.media.length) return []; | |
var rules = []; | |
if (sheet.rules) { | |
rules = sheet.rules; | |
} else if (sheet.cssRules) { | |
rules = sheet.cssRules; | |
} | |
return rules; | |
} | |
/** | |
* With local-global stylesheet list, searches for requested rule | |
* | |
* @author Adam Yanalunas | |
* @since 2010-01-24 | |
* | |
* @param string ruleName Full scope name of rule | |
* @return CSSStyleRule|null | |
*/ | |
var retrieveRule = function(ruleName) { | |
var rule = null; | |
for (var i = 0, slen = stylesheets.length; i < slen && rule == null; i++) { | |
var entries = getEntries(stylesheets[i]); | |
for (var j = 0, elen = entries.length; j < elen && rule == null; j++) { | |
if (entries[j].selectorText == ruleName) { | |
rule = entries[j]; | |
/*rule.position = j;*/ | |
} | |
} | |
} | |
return rule; | |
} | |
var makeRuleText = function(ruleSet) { | |
var rules = []; | |
for (var ruleName in ruleSet) { | |
rules.push([ruleName, ': ', ruleSet[ruleName], ';'].join('')); | |
} | |
return rules.join(' '); | |
} | |
/** | |
* Given a selector from jQuery, add a CSS rule with options for stylesheet and position | |
* | |
* @author Adam Yanalunas | |
* @since 2010-02-05 | |
* | |
* @param jQuery selector CSS selector to have rule added | |
* @param settings Object literal with rule, stylesheet and poisition entry | |
* @return boolean | |
*/ | |
var addRule = function(selector, settings) { | |
var styleSheet = settings.styleSheet || stylesheets[stylesheets.length - 1]; | |
var position = settings.position || getEntries(styleSheet).length; | |
var rules = makeRuleText(settings.rules); | |
//IE | |
if (styleSheet.addRule) { | |
return styleSheet.addRule(selector, rules); | |
} | |
//Mozilla | |
else if (styleSheet.insertRule) { | |
return styleSheet.insertRule(selector + '{' + rules + '}', position); | |
} | |
return false; | |
} | |
/** | |
* Given a rule object, finds the parent stylesheet and uses supplied position to remove from list | |
* | |
* @author Adam Yanalunas | |
* @since 2010-02-05 | |
* | |
* @param CSSelection rule Rule already selected from stylesheet | |
* @return boolean | |
*/ | |
var removeRule = function(rule) { | |
if (rule) { | |
var styleSheet = rule.parentStyleSheet; | |
//Mozilla selector | |
if (styleSheet.cssRules) { | |
return styleSheet.deleteRule(rule.position); | |
//Others | |
} else { | |
return styleSheet.removeRule(rule.position); | |
} | |
} | |
return false; | |
} | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment