thingsinjars / jQuery-Scoped-CSS-plugin

DEPRECATED: A jQuery plugin to enable the scoped attribute on style blocks
http://thingsinjars.com/post/359/css-scoped/
MIT License
168 stars 36 forks source link

fails in jQuery 1.9+ - missing $.browser #1

Closed himdel closed 11 years ago

himdel commented 11 years ago

jQuery 1.9 removed the .browser property, so this plugin fails.

This quick and dirty hack solves it but it would be nice if it could use Modernizr or something ..proper (I have no idea what features to detect though.)

// for jquery 1.9+
if (!jQuery.browser) {
    jQuery.browser = {};
    jQuery.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase());
    jQuery.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
    jQuery.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
    jQuery.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());
}

Anyway, do you have any plans of continuing this project? I would really love to see support for nested scopes.

thingsinjars commented 11 years ago

Hi

Thanks for pointing it out. I've got a version that doesn't use $.browser anymore but it's acting a bit oddly with Firefox on externally imported files. I'm going to see if I can straighten that out before pushing.

Nested scopes should already work (at least, they used to) so I'll see if there's a problem with them.

himdel commented 11 years ago

Hi, great to hear that, thanks.

As for nested scopes, I do have a reproducible problem with them in firefox, using import. I'm using scoped imports to untangle a 50kB ad-hoc written CSS file, it works fine in chrome (with style scoped enabled), it actually works fine in firefox without your plugin (the style is global but it works) but when I enable $.scoped(), something is wrong...

Now, I'm not really sure, it would really help debugging if it'd just set the css properties that are actually defined in the style instead of all of them, BUT .. the problem could be related to dynamically adding classes.

Basically, if I use the same html and css (without having called $.scoped() first), add a class (to a div within that scope) and then call $.scoped(), it works fine. But when I call $.scoped() first, then add the class, it's broken and calling $.scoped() again aftewards doesn't help.

The scoped version is the one from master, so 0.5, I guess.

(If you want I can give you the link but be warned that it's rather unpleasant to use and only partially translated to English, so, only if you really feel like cursing :).)

EDIT: just to clarify, in the middle of writing the text, I realised it may not actually be related to nesting at all, I'm not sure though.

thingsinjars commented 11 years ago

I've pushed a version that works with jQuery 1.9 and also has a few performance improvements.

I don't think it'll work in your case, however as it can only really be run once. Multiple runs created unexpected behaviour as, by the time of the second run, every element has inline styles that represent the intended scoped styles.

I've updated so that it can only be run once per page load to prevent the unexpected behaviour but that may mean that your code may not work with it. It's probably possible to work around it by looping over the page and removing all inline styles immediately before calling the plugin for the second time but I haven't had a chance to look into that yet.

thingsinjars commented 11 years ago

The latest version now allows multiple runs and means you can add styles to the page after load. You just need to rerun $.scoped() to get it to update the styles.

himdel commented 11 years ago

Big thanks for all that effort, I can confirm it works quite well. Even :hover is supported provided I call $.scoped() in onmouseover and onmouseout of all the elements with :hover in their scoped style.

But, actually, I've been thinking, is it possible to programatically modify the selectors? As in, do $(scoped.parent()).uniqueId(); and then just prepend '#'+scoped.parent().id+' ' to all the selectors. That would eliminate both the need to set inline styles and to call $.scoped() repeatedly.

thingsinjars commented 11 years ago

The initial version of the plugin actually did exactly that but it proved to be a nightmare of specificity rules. There wasn't an easy way to create a generic solution that used unique IDs.

There's a demo of it here: http://thingsinjars.com/lab/scoped/index_guid.html

and the write-up of it here: http://thingsinjars.com/post/359/css-scoped/