Skip to content

Instantly share code, notes, and snippets.

@afeld
Created November 17, 2011 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afeld/1374035 to your computer and use it in GitHub Desktop.
Save afeld/1374035 to your computer and use it in GitHub Desktop.
code to encapsulate CSS with a class name
/**
* Encapsulates the css for a given bit. Prepends the bit name as an ancestor selector,
* as well as a "self" selector for each element and class selector found in a sheet.<br><br>
*
* For example, given a bit with name "myBit", the sheet:
* <pre><code>
.myClass { color: blue; }
.myOtherClass { color: red; }
* </pre></code>
* would be converted to:
* <pre><code>
.myBit.myClass, .myBit .myClass { color: blue; }
.myBit.myOtherClass, .myBit .myOtherClass { color: red; }
* </pre></code><br>
*
*
* @method encapsulate
* @param {String} css The input css.
* @param {Object} options
* {Jux.Bits.Bit} bit The bit whose name to use as the "prefix" selector. Uses the bit's folder name, not its display name.
* {String} location The location to prefix image urls with. Defaults to the bit's {@link Jux.Bits.Bit#location location}.
* {String} prefix An override for the prefix that will be placed before the selectors. The prefix normally defaults to the bit's folder name.
* @return {String} The processed (encapsulated) css.
*/
encapsulate : function(css, options) {
options = options || {};
var bName = options.prefix || '';
if( options.bit && !bName ) {
bName = options.bit.getBitFolderName();
}
// Unless the bName starts with a '#', add the prefixed '.' (which is the default, for encapsulating with css classes)
if( bName && bName.charAt( 0 ) !== '#' ) {
bName = '.' + bName;
}
var location = options.location || '';
if( options.bit && !location ) {
location = options.bit.getLocation();
}
if (location.charAt(location.length - 1) !== '/') {
location += '/';
}
// first, strip out the comments
css = css.replace(new RegExp("/\\*[\\S\\s]*?\\*/","gim"), '');
var selectorRegex = new RegExp('([\\S\\s]*?)({[\\S\\s]*?})', 'gim');
var newCss = css.replace(selectorRegex, function(a, b, c, d) {
var imports = b.match(/@import[^;]+;/gim) || [];
/* Prefix the selectors */
// first strip out imports, newlines and then get all selectors
var selectors = b.replace(/@import[^;]+;/gim, '').replace(/[\r\n]/gim, '').split(',');
for (var i = 0; i < selectors.length; i++) {
selectors[ i ] = Jux.Util.lang.trim(selectors[ i ]); // in case there are spaces around the selector.
if (selectors[i].indexOf('.Bit') > -1) {
selectors[i] = bName; // bit level styles
} else {
if (selectors[i].indexOf('.canvas') === 0) { // do nothing for canvas selector
continue;
} else {
if( selectors[i].indexOf( '.noEncapsulate' ) === 0 ) {
// if the selector starts with the special ".noEncapsulate", just remove the ".noEncapsulate " (with its trailing space).
// Do not encapsulate these selectors.
selectors[i] = selectors[i].slice( ".noEncapsulate".length + 1 );
} else if( selectors[i].indexOf( '.' ) === 0 ) {
// this is a class, add "children"
selectors[i] = bName + ' ' + selectors[i];
} else if( selectors[i].indexOf( '@' ) === 0 ) {
// ignore these
continue;
} else { // this is not a class, dont add "self" rule
selectors[i] = bName + ' ' + selectors[i];
}
}
}
}
// Prefix the image urls
var properties = c;
var urlRegex = new RegExp('(url\\([\'\"]?)([\\S\\s]*?)([\'\"]?\\))', 'gim');
properties = properties.replace(urlRegex, function(a, b, c, d){
if (!c.match(/http:\/\/|https:\/\/|www\.|\/!lime\/root/)) {
c = location + c;
}
return b + c + d;
});
return imports.join('\n') + '\n' + selectors.join(',') + properties;
});
return newCss;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment