-
Re: suffixes, I forgot to say...
I want to do a rewrite because the current implementation is a bit flawed (in at least an edge case.)
My main goal with the rewrite would be to allow for comma-separated lists of suffixes in any file.
index.ie6,ie7,ie9,member1.css would thus target member #1 if he uses ie except ie8.
To achieve this, I suspect that doing a glob() call would be enough. Then for each file -- explode the suffixes, and check whether they're in our list.
Only thing I'm not sure about -- performance. Is glob() optimized enough, does the folder list stay in memory as much as possible..? I suspect so, but I don't know for now.
-
I don't believe glob is cached as thoroughly as you're hoping - but it should be cached by the OS through the statcache if possible. IOW, it is cached but not up in PHP and I think you're going to end up doing one per theme folder (in the hierarchy) per page.
-
I'm not actually bothered by it, it is a link after all ;)
file_exists definitely uses the stat cache, glob I'm not so sure about but I can't see any reason it wouldn't be cached at the OS level. Benchmarking is useful - but benching it on Windows is less meaningful than benching it on a Linux server. Windows will give you the worst-case scenario for things like that.
-
It's not cached by stat...
http://www.php.net/manual/en/function.clearstatcache.php
There's a list of functions affected -- glob is not among them.
What we could do is add a link to the Admin menu where we would delete the cache. And then we could store the current (complete) skin file list in a regular Wedge cache file, with a relatively short latency (a couple of minutes?). What do you think...?
Posted: May 15th, 2012, 03:50 PM
As for the main menu, the system may be a bit too complex to be usable in a "simple" mini-menu.
It's done pretty much this way: store parent items into a special span (not a big fan but...), and apply on hover a .hove class. And then create my menu inside the span (or div), this way the parent item still has the 'hove' class even though it's no longer actually hovered.
What I liked about the mini-menu thing is that by being a direct child of the anchor, it would automatically adapt to its position, as well as keep the :hover state on the parent link. But I'm not ready either to have some browsers apply :hover to every single child item, even when not hovered... Meh!
I'll look into the span, then...
-
What we could do is add a link to the Admin menu where we would delete the cache. And then we could store the current (complete) skin file list in a regular Wedge cache file, with a relatively short latency (a couple of minutes?). What do you think...?
We could certainly do that, we could also push it into the main cache and make clearing that more prominent (which would clear everything)?
-
Can you reformulate?
-
Well, you're talking about caching it and having a button in order to clear that cache. I wasn't sure whether you were putting into the main data cache or somewhere else, especially as you were talking about having a separate way to clear that cache.
I figured we could use the main cache and then make it more prominent to clear the main cache (though that has other consequences on, say, accelerator-based caches)
-
Yup, I did mean using the 'regular' cache, and that the admin button for clearing the cache could possibly clear it all (the .php files, at the very least.)
-
Yup, as far as I know it was patched in their Git repo, along with the fact that the cache level and type are now globals and not in $settings. (So that the settings table can actually be cached and read properly from cache, regardless of which cache we're talking about)
-
Well, here's the thing, and it's actually the source of some of the 'SMF 2 is slower than SMF 1' theory. It's also incredibly complicated, but bear with me and hopefully I'll explain how it all works.
SMF 1 has no file cache. Thus no queries get cached to files but it can use proper caches like memcache. That means until such times as you're on a grown up cache, you're swallowing the extra load attached to all the uncached queries.
The difference as compared to SMF 2 is though, when you're starting out, the cache miss frequency will be much higher due to low traffic, so in starting out (and, unsurprisingly, prime shared hosting territory) you're not only not benefitting much from the cache because it expires too quickly for the low traffic, you're also paying the overhead attached to it too.
So at the very earliest stages, you carry out extra work compared to SMF 1, and see little benefit - but as soon as you start getting anywhere serious (and by that I mean you start getting any real volume of traffic), the cache soon starts to kick in and benefit, and I suspect the reality is that you'd be able to run SMF 2 on shared hosting longer than you would for SMF 1 because of the caching taking the edge off the DB, and especially that most hosts target CPU as the prime measure of load and don't focus on I/O, so the cache definitely helps there.
I think the file cache is worth doing. The problems with the cache subsystem as they stand are:
1. It's totally I/O bound. As nend's experiments show, there's little you can do to optimise that. So the speed benefit is finite. There are advantages to using the SQLite system as nend suggested, though.
2. Things are not best using the cache, but that's not systemic to the cache itself; the fact $settings is not cached by things other than the file cache is not the fault of the file cache, it is the fault of the housekeeping that drives all of the caching system. Transferring the cache settings to be in Settings.php means it's possible to cache $settings, something not possible in Wedge currently except through the file cache (which is better than nothing)
3. Clearing the non-file caches is difficult and unreliable. Clearing the file cache or even parts of the file cache is trivial by comparison.
Re the menu, the big problem there is the fact that changing the rest of the layout screws other things up too, which is a big con in my book. I know only too well that resizing the browser or other layout causes a lot of hassle when positioning is important (especially if the size of menu panels is dependent on the layout of the screen!) but to me that seems a deal breaker, especially as the complexity of fixing it by binding to the viewport's resize is going to add a fair bit more code.
-
I'll deal with the OT later, but menus -- I don't understand what you're trying to say. Any real-life cases of a layout change that happens often enough for absolutely-positioned menus to be a big con for you...?
-
(Which is why I switched to SMF 2 in the first place... and, because it was in private beta, how I got into the SMF community after a couple of years of just using SMF1 and posting on my own forums. Anyway -- the file cache never really helped performance on my old server and moving it to a new server helped. I've always been worried about performance in general, and it shows in Wedge...)
The difference as compared to SMF 2 is though, when you're starting out, the cache miss frequency will be much higher due to low traffic, so in starting out (and, unsurprisingly, prime shared hosting territory) you're not only not benefitting much from the cache because it expires too quickly for the low traffic, you're also paying the overhead attached to it too.
Yeah, that would explain a lot... (Although my forum already had 200k+ posts when I tried making the switch.)I think the file cache is worth doing. The problems with the cache subsystem as they stand are:
1. It's totally I/O bound. As nend's experiments show, there's little you can do to optimise that.
It's pretty much up to PHP to keep things in memory for other simultaneous sessions, yeah.So the speed benefit is finite. There are advantages to using the SQLite system as nend suggested, though.
But again, it's mostly I/O bound... (i.e. whether SQLite can deal with the disk access faster than a pure PHP call is up to the machine and setup, I guess...?)
Relying on SQLite, to me, is a bit like creating temp tables in MySQL that bear the names of the cache keys :) Eh, that could be an idea... :lol:2. Things are not best using the cache, but that's not systemic to the cache itself; the fact $settings is not cached by things other than the file cache is not the fault of the file cache, it is the fault of the housekeeping that drives all of the caching system. Transferring the cache settings to be in Settings.php means it's possible to cache $settings, something not possible in Wedge currently except through the file cache (which is better than nothing)
You mean it's not possible without a similar rewrite, right..?3. Clearing the non-file caches is difficult and unreliable. Clearing the file cache or even parts of the file cache is trivial by comparison.
Isn't it possible to send a global timeout notice or something to the cache handlers...?
-
Yeah, that would explain a lot... (Although my forum already had 200k+ posts when I tried making the switch.)
Yup, it starts out with less efficiency and will outpace SMF 1 after a while, but it's never clear exactly when the switch will occur.It's pretty much up to PHP to keep things in memory for other simultaneous sessions, yeah.
Well... there's part of the problem. Especially on Apache, each PHP request is theoretically meant to be threadsafe and thus independent, so any request made can only use stuff that is outside PHP itself for persistence, whatever form that persistence takes. For big persistence obviously something like MySQL is going to be used, but for short term caching, you'd likely be using memcache or whatever.
Really, it's just about what is available to service the lower end hosting; anyone running Wedge etc. on any really large platform is going to be on a VPS and able to drop memcache or APC into place anyway.But again, it's mostly I/O bound... (i.e. whether SQLite can deal with the disk access faster than a pure PHP call is up to the machine and setup, I guess...?)
Actually it's mostly a toss-up between pure CPU overhead at that point. Either way it's still I/O bound but the scale of writing means whether you write 1KB or 8KB is almost irrelevant, so it comes down to the file_put_contents overhead or the overhead of SQLite which is effectively also a native method. That was the thing nend's experiments came up with, that at times one was faster than the other but it was variable - and from what I can see the variation is going to ultimately be down to CPU and file overhead between the two. (The fact that the SQLite implementation was slower to start with is no surprise to me, any system with any kind of caching performs less efficiently from cold.)You mean it's not possible without a similar rewrite, right..?
Something like that. If you want $settings cacheable with a proper cache, the underlying settings have to be moved out of $settings and available globally. We're only talking 2 variables IIRC, so it's not a massive deal.
But the question of expiry is a bit more tricky to resolve.Isn't it possible to send a global timeout notice or something to the cache handlers...?
It sort of is, and that's sort of what the patches do, but if you have a site like that you may not wish to clear the entire cache, just parts of it.
-
It's not cached by stat...
http://[url]http://www.php.net/manual/en/function.clearstatcache.php[/url]
There's a list of functions affected -- glob is not among them.
So... Been doing my tests...
It's a local thing, so it's based on Windows 7 + i7 CPU (quad core, 3+Ghz...) + 8GB Ram, and would probably be slower on a 'regular' server (even if running Linux).
By calling the entire CSS caching, it takes about 0.4ms in the current SVN, and about 0.7ms in the glob() version. That's about 50% slower, and the file searching code itself is probably even twice slower (because the entire function has more code than just the file search...), but still -- it's less than a millisecond. We're talking about web pages that always take at least 120 milliseconds to generate on my PC. It seems to be acceptable -- and if anything, it can be sped up by caching the file list...
I think I'll keep it this way. It still needs some (a lot of?) work to make it work across fallback folders, but other than that, it seems to be working.
Only issue, maybe: I'm using GLOB_BRACE to avoid using multiple glob() calls, but the php.net documentation says that it's not supported everywhere, giving Solaris as an example... I suspect that isn't that big of a deal, but still...
Posted: May 20th, 2012, 12:59 PM
Doing some quick tests between one version and the other...
Old version: 0.4 to 0.7ms (average: 0.5-0.6ms)
New version: 0.5 to 0.8ms (average: 0.7-0.8ms)
So, it's not even 50% slower actually... :^^;:
-
That's the thing, I'd be interested in testing it on a Linux server because IIRC Windows doesn't have the same concepts of caching at the OS level that Linux does.
-
Either way I'm sure it's always fast.
And there's always our own caching. :)
-
Tested here...
file_exists method: 0.15 to 0.35ms, average: 0.2ms.
glob method: 0.4 to 0.7ms, average: 0.5ms
It's still twice slower, but still under a millisecond...
What really scared me, though, is that right after I uploaded my file and refreshed, it sent me a benchmark 1.65 SECOND for that code block...! Then I refreshed, and it went under a millisecond.
I don't know what it means, but to me it means only one thing -- glob() is indeed cached by Apache across all page requests :P
Posted: May 20th, 2012, 06:03 PM
Hmm... The current version here is the file_exists one, and I *just* had a 1.15 second benchmark time for it. So I guess it's not limited to glob()... It's just that glob() is a bit slower in every task.
-
Okay, I'm having a logic problem here...
Let's say I have this main skin:
/skins/index.css
/skins/editor.css
/skins/editor.firefox.css
And a replace-type skin:
/skins/Foobar/index.css
Now, let's say that I don't have an editor.css file in the sub-skin, because I want to re-use the default one.
This was possible (and supported) in Wedge up until now.
Now, with the glob() rewrite, I have to make some adjustments, but I'm not even SURE I can remember how I dealt with it...
Basically: should I use the top-level editor.css? Yes. Should I use the top-level editor.firefox.css if I'm on Firefox? I have no idea... How do I determine that it's a generic fix file and not something related to the default skin...? What if I have an editor.css in my sub-skin, but not editor.firefox.css --- should I use the top-level's editor.firefox.css file? It's a lot of fun...
-
It should use the top-level's file. The child editor.css should only replace editor.css from the parent. That way if someone wants to replace both, they should state both (and likely will need both anyway)
-
"State both"?
Posted: May 20th, 2012, 07:09 PM
But if my sub-skin's editor.css has no need for Firefox hacks, why should I add an empty editor.firefox.css file then...?
Posted: May 20th, 2012, 07:10 PM
As a reminder, I'm talking about a replace-type skin, not an inherit-type (add-type) skin.
Which means that the only reason we should look into the default skin is if we can't find a *main* file such as editor.css or index.css...
But then it gets funny when you specify an editor.firefox.css file in your sub-skin, but no editor.css file... Probably meaning you want to include the top-level's editor.css, but modify it for Firefox in your sub-skin.
Lots of fun :)
-
Oh, if you're talking about replace, then editor.firefox.css should not be included. The idea then is that the child should replace the parent unless the parent doesn't have it.
If the child has no editor.css at all, then go to the parent (and use the parent's editor.firefox.css if appropriate). But if the child has editor.css and no editor.firefox.css, load the child's editor.css and ignore the parent's editor.firefox.css.
-
Agreed.
But:
/editor.css
/Foobar/editor.firefox.css
If only these files are there -- I can see the intent as "use the top-level editor.css, and modify it with my custom firefox file..."
Hmm, the change to glob() unfortunately makes it a tad harder to sort these files correctly.
-
Well... replace skins implies replacing everything, no?
Whatever the behaviour is, as long as it's documented and allows people to replace things as necessary, I don't really see it as a big problem.
-
I really only want for this all to just... make sense ;)
Intuition is what you rely on when you're too lazy to read a documentation. So everything I do, I try to make intuitive :P
-
Just wanted to say — going to bed with a half done function. CSS may fail here and there.
Heck. The new function adds something like 60 lines.... Adding support for comma separated suffixes is definitely more complicated than I originally thought ;)
-
Just wanted to say — going to bed with a half done function. CSS may fail here and there.
Wasn't failed.... Just forgot to empty the cache ;)
Posted: May 21st, 2012, 09:13 AM
Agreed.
But:
/editor.css
/Foobar/editor.firefox.css
If only these files are there -- I can see the intent as "use the top-level editor.css, and modify it with my custom firefox file..."
Haven't found a solution for this, btw...
Also:
/editor.css
/editor.firefox.css
/Foobar/(nothing)
Should firefox* be loaded in Foobar...?
-
Foobar doesn't provide editor.css so the root editor.css will be required, and I would assume you'd have to load editor.firefox.css for that too, regardless of replace or inherit.
-
I have this terrible feeling that I'm going to have to add even more lines of code...
I usually make my rewrites shorter than any earlier code. It would be a first ;)
-
Hmm... Tried replacing the glob() call with scandir() and opendir(), hoping to get better performance...
Unfortunately, it's not any faster, maybe even a bit slower, although at least the performance is more stable across multiple refreshes.
I'll probably switch to scandir() because at the very least it's supported everywhere...
-
Phew... Finally done rewriting the logic for replace-type skins.
I added a dummy skin with just two files (index.member.css and sections.css), and here's how it was included:
Array
(
- => /Themes/default/skins/index.css
[1] => /Themes/default/skins/index.opera.css
[2] => /Themes/default/skins/index.member.css
[3] => /Themes/default/skins/Wutherings/index.member.css
[4] => /Themes/default/skins/Wutherings/sections.css
[5] => /Themes/default/skins/custom.css
[6] => /Themes/default/skins/custom.admin.css
)
The absolute perfect order.
Meaning you can easily manipulate ordering just by removing files in your replace skin or adding empty files, or choosing adequate suffixes.
Meanwhile, I've switched to makinge use of scandir(), and caching the results in a static array, although I'm disappointed by the lack of performance improvements with the caching... (Well, it probably works better on external files like editor.css, so I won't be removing it.)
-
Nicely done!!
-
It's not working 100% for now, works fine when not using comma-separated lists but I did that on ie6+ie7 and they fail to load correctly... Will test later...
Oh god, I have so many leftover features to finish... Grmpf...
-
Seems to be working, now :)
-
Oh, the Wireless skin was broken because of a test file I'd uploaded to stress-test the inheritance mechanism and forgot to remove when I was done... Sorry about that.
Will no one report that kind of issue when it's been going on for at least a few hours? :P
-
I guess no-one used Wireless in that time?
-
I did... Although I thought it was another parser bug, which turned out to be working fine...
(Except that Wine is seriously broken right now. Hmm, when did that start...? I'll have to fix it again. Maybe I'll use the opportunity to rewrite the sidebar to behave like in Weaving, because I've really grown tired of that nice little animation -- it doesn't work on touch devices, for starters...)
Posted: May 23rd, 2012, 08:34 PM
I think I've fixed everything...
Changed a lot of things internally, really.
I have no idea whether it's for the better. It's certainly a bit slower, whether it be the per-page file check, or the actual parsing (I now do some extra sorting on selector lists), but I did notice a minor improvement in CSS file size reduction, plus there's the added flexibility of using multiple suffixes...
Now I shouldn't forget about implementing per-member suffixes, and maybe other things... What about per-board and per-category suffixes, for instance? (A different skin can be chosen for another board, but this would allow having custom CSS in a single board across *all* possible skins for it...)
One thing I don't know about, though, is the 'admin' suffix (i.e. custom CSS for admins). That's because there's also an 'admin' radix (base?), which is used in the admin area... (the classic admin.css file.)
I'd like to change that, but I don't know what to, and I don't know if I should rename the radix or the suffix.
-
I'd rename admin.css to adminarea.css so that the base doesn't conflict with the suffix.
-
I think it's a bit too long for my taste...
What about mana.css? :P
It's like 'manage', but it pleases my RPG-addicted mischievous mind :lol:
Oh, also... Today I added support for:
- *.b1.css -> custom css for board #1
- *.c1.css -> category #1
- *.m1.css -> member #1 (no more annoying you with my tests :P)
- *.replace.css -> a new idea of mine... It basically acts like a local replace-type skin, for one radix type.
e.g. Wine was broken because it included custom.css from its parent skin, which was geared towards modifying Weaving, not Wine. So I added an empty custom.replace.css file in the Wine folder and voilà -- all custom.*.css files from Weaving are subsequently ignored.
What I like about my skin system is that I actually use it. Thus, when I meet a new problem, I try to find an innovative solution to it.
Heck, I could even get away with removing skin types entirely, and relying on the 'replace' keyword everytime it's needed... What do you think? I can't think of a situation where a global replace type would be better.
-
mana.css is absolutely fine, and I love the idea of board and category CSS - not quite so keen on m1.css, but I'm sure it'll have use.
I really like the idea of using the replace.css and I can see the benefits of it simplifying add vs replace skins. Would it be faster to drop add/replace skin types and rely on the keyword?
-
mana.css is absolutely fine,
Except for the idea that it's still called the Admin area, but whatever... :lol:and I love the idea of board and category CSS - not quite so keen on m1.css, but I'm sure it'll have use.
If anything, it has a use for me :) (Of course I can always use the admin suffix if you prefer to see what I'm doing.)I really like the idea of using the replace.css and I can see the benefits of it simplifying add vs replace skins. Would it be faster to drop add/replace skin types and rely on the keyword?
That's the problem... Which would feel the most 'natural' to people?
skin.xml has many options, but the skin type is the option regarding CSS files and their ordering. It feels more natural to have this put into the file names themselves.
However, people may get confused with where to put the replace suffix... And even I don't know to which extent they should be applied. For instance, should they put it into every available file? index.replace.css + index.replace,ie6.css -- currently, Wedge doesn't need that because it will delete any index.*.css file if a replace suffix is found on any index.*.css file. But what if they only provide an index.replace,ie6.css file into their skin folder? Now that's an issue... It'd logically mean, "keep the parent index.css and everything, but replace the index.ie6.css with mine". I guess if I had to implement this, I'd need to add even more extra code to Wedge so that it goes through the parent list and removes only those files with suffixes found in our list (in this case, ie6). Meh. OTOH it also gives more flexibility than replace-type skins. But it also introduces a potential complexity that could scare themers away.
All in all, for now I'll be keeping the replace type, but I'd like more opinions on this.
-
Bump?
Posted: May 25th, 2012, 01:09 PM
Ah well, so no one cares about that... :(
I assume no one cares either about the philosophical matter of having the Thoughts table serve as recipient for our future 'user streams'? (i.e. FB wall, to put it bluntly. Before they went for their horrible timeline thingy...)
-
Hey, I've been busy, out yesterday fighting viruses, out today to London and back for a 15 minute interview >_>
I'm not sure which would be more natural, that's half the problem. I suspect ditching the separate skin types would make more sense, though. As long as it's documented, it'll be OK.
-
Let's say you have these files:
/index.css
/index.ie6.css
/index.ie6,ie7.css
/index.ie8.css
/Sub/index.css
/Sub/index.replace.ie6.css
The question is: what files *should* be included as logic implies here, and in our current SVN, what files will end up being included in the Sub skin...?
You have one hour.
Or, in other words: should we allow for the replace keyword to be used alongside any other suffix...?
-
Yes, yes we should. That implies to me that we should load these as standard:
index.css
Sub/index.css (to extend index.css)
If IE6 is present, also load
index.ie6,ie7.css
Sub/index.replace.ie6.css
The replace keyword replaces the equivalent suffix earlier up, so Sub/index.replace.ie6.css replaces index.ie6.css but leaves index.ie6,ie7.css alone, as it's a different suffix.
-
So, if I put a index.ie7,replace,ie6.css file into the folder, that would assume I want the parent folder's index.ie6,ie7.css and index.ie7,ie6.css files to be removed...? But not, say, index.ie6.css or index.ie6,ie7,ie8.css?
-
The commas instead of dots confuse me. I'd argue that ie7,replace,ie6 is a combination that isn't really necessary... what purpose would it (practically) solve?
-
Well, that's the reason I asked. (I could use 'index.replace.ie6,ie7.css' but I'm not sure people would follow.)
I'm already getting the list of suffixes for a file -- I could just as well remove 'replace' from the array, and then do a search on all parent folders, get all files with the same radix, explode the suffix list and compare the arrays. (Perhaps doing a sort() before maybe? I don't think array(1, 2) == array(2, 1)...)
There also is the point of replacing non-suffixed files in the same skin. Like, 'custom.replace,ie6.css' could be a request to entire remove 'custom.css' when IE6 is used, and replace it with 'custom.replace,ie6.css'...
-
You're right, array(1, 2) != array(2, 1) but that's sort of the point.
I'd keep it simple: if you indicate replace, and there's a suffix after that, that's all that's replaced. Bear in mind that we'll have to explain this to other people!
-
Lulz yeah...
But there's hardly any reason to account for the replace keyword's position when already I'm getting the suffixes as an array...
Could simply test for implode(',', array_diff($suffix_list_from_this_file_that_has_a_replace_suffix, (array) 'replace'))...
-
Putting aside the position of the replace keyword, just consider the remainder of the terms - index.replace.some,thing.css should replace index.some,thing.css but not index.thing,some.css.
While I can see the logic of arguing either way, I'd strongly be in favour of keeping it simple.
-
Nao, I think your rewrite is broken somewhat. My custom board icons don't show (full path instead of URI). Also, my custom menu is completely broken. Does the reset keyword still work?
-
I don't think anything's broken in here...?
Even the reset keyword seems to work.
Can you look into it further, please? You know I'm as careful as possible when touching my skin code, but maybe I missed something, given the number of possibilities wetem and wecss offer...
-
It was a misplaced parenthesis!
-
Offending line:
.menu:not(#main_menu2, #context_menus)
The comma confuses the parser, it seems.
-
Not surprised. WeCSS has trouble with any complex css2/3 that uses commas or quotes. I think one of my comments warns against that.
What shall we do? Protect all code at parse time? In what order? etc.... Headaches ahead.
-
Thing is, my entire skin worked just as expected before the rewrite.
-
Can you help determine what revision broke it?
-
Yep. Latter on today after I finish this small plugin. I reverted to r1595 yesterday to see if something after that broke it, still broken. :(
-
Can you revert to an even older copy then? Just check the log for Class-CSS.php to see the relevant revs... Thanks!
-
OMG so many changes... so fucking lost.
Posted: June 10th, 2012, 06:14 AM
it works in r1584
Posted: June 10th, 2012, 06:20 AM
also in 1590
Posted: June 10th, 2012, 06:24 AM
and not in 1593
Posted: June 10th, 2012, 06:26 AM
* Sort selector lists before generating the CSS files. This helps a bit with overall gzip compression rates. (Class-CSS.php)
I'd assume that has something to do with it.
-
Okay, thanks... Then I guess it's due to this: your selector is split into two different selectors ("something:(firstpart" and "secondpart)"), and then sorted to gain a few bytes at gzipping time, but this also moves "secondpart)" further up the chain instead of directly following it. Hence the broken part.
So, there are two ways of avoiding this...
1/ Just reverting my sort() call and calling it quits on the optimization.
2/ Protection quotes, double quotes, brackets and parenthesis before doing the parsing. That is, anything between these items would be base64-encoded or something (right before building the pseudo-XML CSS tree), and then decoded again once the actual CSS file is generated.
I have a neat preference for solution 2 because it's "cleaner" in my opinion, and would also be likely to fix other potential issues I haven't found yet.
However, I'm not 100% sure it's going to work flawlessly. I can't think of anything right now, but there may be occasions where Wedge will want to access stuff between protected bytes at tree parsing time... What do you think?
-
1/ Just reverting my sort() call and calling it quits on the optimization
Is that all it is? A dinky little optimization? What all does it do?
-
Yes. It's only a gzip optimization. Nothing more. Plus when you have multiple versions of a gzipped CSS file, it's way easier to compare them when the selectors are stored. Otherwise Wedge tends to mix them up...
-
Offending line:
.menu:not(#main_menu2, #context_menus)
The comma confuses the parser, it seems.
Instead of removing the sorting, I implemented the protection code.
It will search for any (..., ...) "..., ..." and '..., ...' in the selectors.
I tested with this:
.something, .menu:not(#main_menu2, #context_menus)
.hello
color: #fff
It got properly parsed. Is that good enough? :)
Now to fix the other error I'm getting... (Well, not so much an error as, ahem, a repetition of some selectors...)
-
I'm in the process of rewriting the css selector parser... Well, it had some obvious flaws to me (notably, it was, uh, building the final selector directly as a comma-separated string instead of just manipulating an array of selectors?!). Still has. But at least now Wedge will properly delete any duplicates. After gzipping, the current main CSS file is now 70 bytes smaller without any other change than removing dupes (most of the savings) and reordering selectors properly. :)
Hey Pete! Gotta go, will read your post tomorrow ;)
-
Fixed!
-
Phew :)
-
Putting aside the position of the replace keyword, just consider the remainder of the terms - index.replace.some,thing.css should replace index.some,thing.css but not index.thing,some.css.
While I can see the logic of arguing either way, I'd strongly be in favour of keeping it simple.
I need a briefing on this. I still don't know what's best -- deleting replace-type skins or not.
-
Bumping this...... If anyone feels inspired by the moment or something ;)
Posted: February 17th, 2013, 08:01 PM
Or, rewording... Does it feel more natural to use a skin.xml override to make a skin forget its parents, or to use a filename keyword..?
-
I would argue it should be in skin.xml rather than indicating it in the filename.