简体   繁体   中英

Adding Parent Selectors To CSS block using jQuery

So we have an email builder that allows the client to create their own custom color schemes. In additon to pre-defined fields we allow them to enter their own custom CSS block to modify their color schemes.

The problem is we NEED to put a parent selector before each rule. So for instance:

 p {font-size:12px;}

will need to become

 .parent_selector p {font-size:12px;}

Is there anyway to programmatically add these parent selectors to EACH CSS rule? As an example use case let's say this is the custom css provided by the client:

 p {font-size:12px; font-weight:bold}
 .description {color:#cccccc; line-height:1.2em;}
 #header {padding:bottom:12px}
 .buttons .button {padding:12px; background:#112233;}
 .buttons a {text-decoration:none;}

I would need a parent selector before each rule. I've considered searching for brackets and adding text accordingly but it got too complicated. Another option (which I don't like) is creating a dummy selector and doing a string replace. Here is an example:

 .placeholder p {font-size:12px;}

will need to become

 .parent_selector p {font-size:12px;}

Thanks in advance!

You could try to inject their code into something like the less preprocessor and compile before sending to the server. or create your own parser to prepend the parent selector to the classes provided. This would probably need work for the different formats that could be input by your users.

edit: on second thought don't leave it to chance. remove all double whitespace characters and you will get a consistent formatting and minification for free.

 function addParentSelector( parentSelector, styles ){ return styles.replace(/((?:\\s|\\n|\\t)+)/gm, ' ').replace(/([^{]+)({[^}]+})/gm, function(_, selectors, styles ){ return selectors.split(',').map(function( selector ){ return parentSelector + ' ' + selector; }).join(',') + styles; }); } function compile(){ var res = addParentSelector('.some-parent-selector', document.querySelector('#styles').value ); document.querySelector('#output').innerHTML = res; } 
 /* ignore the css here */ textarea { width: 100%; height: 6em; } pre { white-space:pre-wrap; word-wrap:break-word; } button { cursor: pointer; display: inline-block; text-align: center; color: #fff; line-height: 1; padding: .6em .8em; background: #009afd; -webkit-transition: background 0.15s ease, color 0.15s ease; -moz-transition: background 0.15s ease, color 0.15s ease; -ms-transition: background 0.15s ease, color 0.15s ease; -o-transition: background 0.15s ease, color 0.15s ease; border: 1px solid #1777b7; box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset,0 1px 1px rgba(100,100,100,0.3); border-radius: 3px; } button:hover { color: #fff; background: #0087de; } 
 <textarea id='styles'> .profile { line-height: 2; padding: 1em; font-family: sans-serif; } .profile__header { background: red; } .profile__header-heading { font-size: 2em; padding: 0; margin: 0; } .profile__header-heading small { color: rgba(43,44,43,.7); } .profile__header-edit { padding: .5em 2em; border: .2em solid #3cf; color: #fff; background: #3cf; text-decoration: none; transition: .2s; } .profile__header-edit:hover { color: #3cf; background: #fff; } .profile__content p { color: rgba(34,35,34,.7); line-height: 2; } </textarea> <button onclick="compile()">click me!</button> <pre id="output"></pre> 

edit: there was an issue in the Regex. I was using a [\\s|\\n|\\t] group for space|newline|tab but it should have been a non capture group (?:\\s|\\n|\\t).

This should be more complete. Also please be aware that Array.prototype.map() will fail in IE < 9.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM