Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #26768 > unrolled thread

Parse CSS styles and swap background position value

Started byCezary Tomczyk <cezary.tomczyk@gmail.com>
First post2015-01-31 10:39 -0800
Last post2015-02-03 12:44 +0100
Articles 12 — 5 participants

Back to article view | Back to comp.lang.javascript


Contents

  Parse CSS styles and swap background position value Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2015-01-31 10:39 -0800
    Re: Parse CSS styles and swap background position value Erwin Moller <erwinmollerusenet@xs4all.nl> - 2015-02-02 13:09 +0100
      Re: Parse CSS styles and swap background position value Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-02-02 14:01 +0100
        Re: Parse CSS styles and swap background position value Erwin Moller <erwinmollerusenet@xs4all.nl> - 2015-02-02 14:39 +0100
          Re: Parse CSS styles and swap background position value Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-02-02 18:17 +0100
            Re: Parse CSS styles and swap background position value Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2015-02-03 01:59 -0800
              Re: Parse CSS styles and swap background position value "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-02-03 11:39 +0100
              Re: Parse CSS styles and swap background position value Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-02-03 15:37 +0100
                Re: Parse CSS styles and swap background position value Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2015-02-04 08:55 +0100
                Re: Parse CSS styles and swap background position value John Harris <niam@jghnorth.org.uk.invalid> - 2015-02-04 15:09 +0000
                  Re: Parse CSS styles and swap background position value Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-02-04 16:19 +0100
            Re: Parse CSS styles and swap background position value Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-02-03 12:44 +0100

#26768 — Parse CSS styles and swap background position value

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2015-01-31 10:39 -0800
SubjectParse CSS styles and swap background position value
Message-ID<8be9bcae-a221-46e1-8e0f-ec41632517a4@googlegroups.com>
Here is a sample of CSS (the properties are repeated, but this is just for example to test regular expression):

h1 { float: left; }

.example1 { background: #fff url(p.png) no-repeat right top; cursor: ne-resize; border-left: 10px; border-right: 5px; float: right; height: 100%; margin: 0 50px 0 0; padding: 0px  20px 0 0; padding-left: 15px; width: 50%; padding-right: 5px; margin-left: 15px; width: 50%; margin-right: 5px; }

.example2 {
  padding: 1px 2px 3px 4px;
  margin-right: 3em;
  background-position: 5% 80%;
  background: url(test.gif);
  cursor: ne-resize;
  border-left: 1px;
  background: url(example1.png) repeat-x right 50%;
  background: #ffffff url("example2.png") no-repeat fixed 0% top;
  background: white url("example3.png") repeat fixed left;
  background: #333 url("example4.png") 0 50%;
}

My goal is to find all "background" properties and then swap horizontal position value from left to right or right to left or value% to (100% - value%).

I've started from (background\s*:\s*)(.*); regular expression. However, background property might have a very different values here. I know that it does not matter if one of the property values is missing, as long as the ones that are present are in this order:

* background-color
* background-image
* background-repeat
* background-attachment
* background-position

I've been thinking maybe I'll end up with overcomplicated regular expression here.

Any suggestions how it can be done in simpler way?

Here is the site where I play with regular expressions: https://www.regex101.com/r/sJ2uL5/1

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [next] | [standalone]


#26775

FromErwin Moller <erwinmollerusenet@xs4all.nl>
Date2015-02-02 13:09 +0100
Message-ID<54cf68f5$0$2870$e4fe514c@news2.news.xs4all.nl>
In reply to#26768
On 1/31/2015 7:39 PM, Cezary Tomczyk wrote:
> Here is a sample of CSS (the properties are repeated, but this is just for example to test regular expression):
>
> h1 { float: left; }
>
> .example1 { background: #fff url(p.png) no-repeat right top; cursor: ne-resize; border-left: 10px; border-right: 5px; float: right; height: 100%; margin: 0 50px 0 0; padding: 0px  20px 0 0; padding-left: 15px; width: 50%; padding-right: 5px; margin-left: 15px; width: 50%; margin-right: 5px; }
>
> .example2 {
>    padding: 1px 2px 3px 4px;
>    margin-right: 3em;
>    background-position: 5% 80%;
>    background: url(test.gif);
>    cursor: ne-resize;
>    border-left: 1px;
>    background: url(example1.png) repeat-x right 50%;
>    background: #ffffff url("example2.png") no-repeat fixed 0% top;
>    background: white url("example3.png") repeat fixed left;
>    background: #333 url("example4.png") 0 50%;
> }
>
> My goal is to find all "background" properties and then swap horizontal position value from left to right or right to left or value% to (100% - value%).
>
> I've started from (background\s*:\s*)(.*); regular expression. However, background property might have a very different values here. I know that it does not matter if one of the property values is missing, as long as the ones that are present are in this order:
>
> * background-color
> * background-image
> * background-repeat
> * background-attachment
> * background-position
>
> I've been thinking maybe I'll end up with overcomplicated regular expression here.
>
> Any suggestions how it can be done in simpler way?
>
> Here is the site where I play with regular expressions: https://www.regex101.com/r/sJ2uL5/1
>

Sounds pretty difficult with regex only.
I would load the file into a programming language of your choice (eg 
PHP, Phyton, etc) and fix the CSS from there.

For example:
- Make a single item of each separate declaration. (they end with ";")
  Maybe use split on ";" but also make sure you take the opening "{" 
into account.
- trim any spaces/tabs on the left side.
- Check if that item starts with "background" or "background-*:" where 
"*" can be anything up to the next ":". (You can use a regex for this 
part of course)
- if so: do something with the rest (eg replacing "left" with "right").
- reassemble all the parts into your new css.

I think that covers all appearances.

Regards,
Erwin Moller

-- 
"That which can be asserted without evidence, can be dismissed without 
evidence."
-- Christopher Hitchens

[toc] | [prev] | [next] | [standalone]


#26776

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-02-02 14:01 +0100
Message-ID<1609092.d9bYY2oEu8@PointedEars.de>
In reply to#26775
Erwin Moller wrote:

> On 1/31/2015 7:39 PM, Cezary Tomczyk wrote:
>> Here is a sample of CSS (the properties are repeated, but this is just
>> for example to test regular expression):
>> […]
>> My goal is to find all "background" properties and then swap horizontal
>> position value from left to right or right to left or value% to (100% -
>> value%).
>> […]
>> Here is the site where I play with regular expressions:
>> https://www.regex101.com/r/sJ2uL5/1
> 
> Sounds pretty difficult with regex only.

It is provably *impossible* to parse (a) CSS(-like language) with only one 
application of one *regular* expression.  As most languages to be parsed,
this one, too, is _not_ regular.  (See: Chomsky hierarchy, pumping lemma for 
regular languages.)

It is provably possible with several regular expressions as part of an 
implementation of a push-down automaton.  In the simplest case:

  var
    match,
    rx = /…|…/g;

  while ((match = rx.exec(code))
  {
    /* … */
  }

(This does not suffice here because the first, *longest* match must win, and 
with alternation the first matching alternative always wins.  I have been 
working on a general parser implementation that is capable, but it is not 
production-ready yet.)

> I would load the file into a programming language of your choice (eg
> PHP, Phyton, etc) and fix the CSS from there.

It’s _Python_.  But I do not see what difference that would make, unless 
there is a CSS library in either language that I am not aware of.  Recursive 
regular expressions which are supported by Python and PCRE as supported by 
PHP can only get you that far.

This appears to me to be a use-case for LESS or another CSS generator.  Use 
them to have variables and more functions in your stylesheet, then use 
client-side script only to switch the class of a context element.

Or do not parse the stylesheet at all, but find the selectors that apply in 
the document.styleSheets NodeList and modify the property values there.

> For example:
> - Make a single item of each separate declaration. (they end with ";")
>   Maybe use split on ";" but also make sure you take the opening "{"
> into account.

  @media only screen and (max-width: 474px) {
    .foo:after {
      display: block;
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      content: "BTDT; and you?";
    }
  }

> - trim any spaces/tabs on the left side.
> - Check if that item starts with "background" or "background-*:" where
> "*" can be anything up to the next ":". (You can use a regex for this
> part of course)
> - if so: do something with the rest (eg replacing "left" with "right").
>  - reassemble all the parts into your new css.

You can do that, but again it will not work with a single expression, 
because parantheses can be nested in the property value, namely

  background-image: linear-gradient(rgb(0, 0, 0), rgb(255, 255, 255));
  background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));

(a linear gradient with either top black to bottom white or top opaque black 
to bottom transparent black, depending on which is supported last) is Valid 
CSS3 (and think about prefixes).

> I think that covers all appearances.

It does not, of course.  See the CSS 2.1 grammar to begin with.

The used parser would have to recognize, in top-down order: media queries, 
rulesets, declarations, property names, and property values, in order to do 
something useful with property values.  (And probably I have forgotten 
something else.)  It is not logical to rebuild a CSS parser when simpler 
measures would suffice.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#26777

FromErwin Moller <erwinmollerusenet@xs4all.nl>
Date2015-02-02 14:39 +0100
Message-ID<54cf7dfa$0$2962$e4fe514c@news2.news.xs4all.nl>
In reply to#26776
On 2/2/2015 2:01 PM, Thomas 'PointedEars' Lahn wrote:
> Erwin Moller wrote:
>
>> On 1/31/2015 7:39 PM, Cezary Tomczyk wrote:
>>> Here is a sample of CSS (the properties are repeated, but this is just
>>> for example to test regular expression):
>>> […]
>>> My goal is to find all "background" properties and then swap horizontal
>>> position value from left to right or right to left or value% to (100% -
>>> value%).
>>> […]
>>> Here is the site where I play with regular expressions:
>>> https://www.regex101.com/r/sJ2uL5/1
>>
>> Sounds pretty difficult with regex only.
>
> It is provably *impossible* to parse (a) CSS(-like language) with only one
> application of one *regular* expression.  As most languages to be parsed,
> this one, too, is _not_ regular.  (See: Chomsky hierarchy, pumping lemma for
> regular languages.)
>
> It is provably possible with several regular expressions as part of an
> implementation of a push-down automaton.  In the simplest case:
>
>    var
>      match,
>      rx = /…|…/g;
>
>    while ((match = rx.exec(code))
>    {
>      /* … */
>    }
>
> (This does not suffice here because the first, *longest* match must win, and
> with alternation the first matching alternative always wins.  I have been
> working on a general parser implementation that is capable, but it is not
> production-ready yet.)

OK.


>
>> I would load the file into a programming language of your choice (eg
>> PHP, Phyton, etc) and fix the CSS from there.
>
> It’s _Python_.

What's wrong with Fyton? :-)
Sorry, that was a typo (a typo I cannot get out of fingers/system, much 
to my embarrassment.).


   But I do not see what difference that would make, unless
> there is a CSS library in either language that I am not aware of.  Recursive
> regular expressions which are supported by Python and PCRE as supported by
> PHP can only get you that far.

I wasn't suggesting a helper-CCS library at all.
My suggestion was to just find the declarations which mention 
"background" or "background-*".


>
> This appears to me to be a use-case for LESS or another CSS generator.  Use
> them to have variables and more functions in your stylesheet, then use
> client-side script only to switch the class of a context element.

OK.

>
> Or do not parse the stylesheet at all, but find the selectors that apply in
> the document.styleSheets NodeList and modify the property values there.

That would be a fix at client-side of the CSS then. I am not sure I like 
that idea (load on the client while the right CSS would suffice.).


>
>> For example:
>> - Make a single item of each separate declaration. (they end with ";")
>>    Maybe use split on ";" but also make sure you take the opening "{"
>> into account.
>
>    @media only screen and (max-width: 474px) {
>      .foo:after {
>        display: block;
>        position: absolute;
>        left: 0;
>        top: 0;
>        right: 0;
>        bottom: 0;
>        content: "BTDT; and you?";

(Not as often as you, I expect.)

>      }
>    }
>


I see where you are heading: using ; in the content.

Yes, that would make my (not posted) algorithm fail horribly.
I stand corrected.


>> - trim any spaces/tabs on the left side.
>> - Check if that item starts with "background" or "background-*:" where
>> "*" can be anything up to the next ":". (You can use a regex for this
>> part of course)
>> - if so: do something with the rest (eg replacing "left" with "right").
>>   - reassemble all the parts into your new css.
>
> You can do that, but again it will not work with a single expression,
> because parantheses can be nested in the property value, namely
>
>    background-image: linear-gradient(rgb(0, 0, 0), rgb(255, 255, 255));
>    background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
>
> (a linear gradient with either top black to bottom white or top opaque black
> to bottom transparent black, depending on which is supported last) is Valid
> CSS3 (and think about prefixes).
>
>> I think that covers all appearances.
>
> It does not, of course.  See the CSS 2.1 grammar to begin with.
>
> The used parser would have to recognize, in top-down order: media queries,
> rulesets, declarations, property names, and property values, in order to do
> something useful with property values.  (And probably I have forgotten
> something else.)

AAARGH, please stop!

You convinced me completely.


   It is not logical to rebuild a CSS parser when simpler
> measures would suffice.
>


I am not familiar with Chomsky hierarchy, but after reading your post I 
think I should. I have the feeling I wouldn't have posted my first 
suggestion if I did know about Chomsky hierarchy.

Thanks for the explanation.
And good luck to OP fixing the CSS in another way.


Regards,
Erwin Moller


-- 
"That which can be asserted without evidence, can be dismissed without 
evidence."
-- Christopher Hitchens

[toc] | [prev] | [next] | [standalone]


#26778

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-02-02 18:17 +0100
Message-ID<7622963.yZKU775dzf@PointedEars.de>
In reply to#26777
Erwin Moller wrote:

> On 2/2/2015 2:01 PM, Thomas 'PointedEars' Lahn wrote:
>> Erwin Moller wrote:
>>> On 1/31/2015 7:39 PM, Cezary Tomczyk wrote:
>>>> Here is a sample of CSS (the properties are repeated, but this is just
>>>> for example to test regular expression):
>>>> […]
>>>> My goal is to find all "background" properties and then swap horizontal
>>>> position value from left to right or right to left or value% to (100% -
>>>> value%).
>>>> […]
>>>> Here is the site where I play with regular expressions:
>>>> https://www.regex101.com/r/sJ2uL5/1
>>> […]
>>> I would load the file into a programming language of your choice (eg 
>>> PHP, Phyton, etc) and fix the CSS from there.
>> […]
>>    But I do not see what difference that would make, unless
>> there is a CSS library in either language that I am not aware of. 
>> Recursive regular expressions which are supported by Python and PCRE as
>> supported by PHP can only get you that far.
> 
> I wasn't suggesting a helper-CCS library at all.
> My suggestion was to just find the declarations which mention
> "background" or "background-*".

What exactly did you have in mind, then?

>> Or do not parse the stylesheet at all, but find the selectors that apply
>> in the document.styleSheets NodeList and modify the property values
>> there.
> 
> That would be a fix at client-side of the CSS then. I am not sure I like
> that idea (load on the client while the right CSS would suffice.).

It is not my preferred approach either, although I have written ECMAScript-
conforming code that allows one to access rules in the CSSOM by selector to 
make that easy.  I find the OP’s problem description sufficiently imprecise 
to give a good recommendation as to the best approach.

> I see where you are heading: using ; in the content.
> 
> Yes, that would make my (not posted) algorithm fail horribly.
> I stand corrected.
> 
>>> I think that covers all appearances.
>>
>> It does not, of course.  See the CSS 2.1 grammar to begin with.
>>
>> The used parser would have to recognize, in top-down order: media
>> queries, rulesets, declarations, property names, and property values, in
>> order to do
>> something useful with property values.  (And probably I have forgotten
>> something else.)
> 
> AAARGH, please stop!
> 
> You convinced me completely.

Now that I have given sufficient warning for the *general* case ;-), 
I should point out that, because of the restrictions in the CSS3 module 
specifications for background property values *so far*, this is a *special* 
case where you could find the pertinent declarations, and tell apart the 
property names and value *without* a full-blown CSS parser, under the 
following conditions:

- Every background property declaration (even the last one in a ruleset,
  where it is optional) is terminated with a semicolon (otherwise, newlines
  complicate everything);

- Property values do not contain semicolons (there is the syntactical   
  possibility for semicolons in “data” URIs for the “background-image”
  property value or “background” property value component, for example);

- Property values do not contain substrings that match a “background”
  or “background-position” property declaration.

And then I am rather certain (also tested positive on the example code) that 
you can use

  /\bbackground(-position)?\s*:\s*([^;]+)\s*;/gi

for matching.

Still, the difficulty here is to tell apart the parts of the property value 
for exchanging their value ("$2").  Again, *iff* you can make sure that 
*all* percentages in the matched property values relate to horizontal 
background-position (which usually is _not_ the case: they can also be 
something that precedes a URI-encoded value for the background image; a 
radius, position or color stop of a gradient; the background size, or an 
RGB[A]/HSL[A] background color component, or the vertical background-
position – did I miss anything?), then you could use

  … = value.replace(/\b(?:(left)|(right)|(\d+)%)\b/gi,
    function (match, left, right, percentage) {
      return (left
        ? "right"
        : (right ? "left" : (100 - percentage) + "%")));
    });

But this does not work already in the case of

  background: url(example1.png) repeat-x right 50%;

And the “right” value can be anywhere in the property value:

<http://www.w3.org/TR/css3-background/#ltbg-layergt>

Specifically, you have to exclude the cases where you found a percentage and 
either “left” or “right” (in any order) because that percentage, in the 
aforementioned context, refers to the *vertical* position instead.

As is obvious now, even though it is generally possible to use regular 
expressions in this case, many conditions have to be met in order to make it 
possible.

It is a lot easier to use the CSSOM instead (document.styleSheets, the 
return value of document.defaultView.getComputedStyle(…), or the “style” 
property): there you have the rulesets and declarations already parsed, and 
can access the “backgroundPosition” or “backgroundPositionX” property value 
directly where it should always be retrievable in percentages.

>>    It is not logical to rebuild a CSS parser when simpler
>> measures would suffice.
> 
> I am not familiar with Chomsky hierarchy, but after reading your post
> I think I should. I have the feeling I wouldn't have posted my first
> suggestion if I did know about Chomsky hierarchy.

At least not in *that* way, for sure.
 
> Thanks for the explanation.

You’re welcome.

> And good luck to OP fixing the CSS in another way.

ACK.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#26779

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2015-02-03 01:59 -0800
Message-ID<d2124cae-9d2a-4132-a42f-87f0bd8f6316@googlegroups.com>
In reply to#26778
On Monday, February 2, 2015 at 6:18:05 PM UTC+1, Thomas 'PointedEars' Lahn wrote:
[...]

> Now that I have given sufficient warning for the *general* case ;-), 
> I should point out that, because of the restrictions in the CSS3 module 
> specifications for background property values *so far*, this is a *special* 
> case where you could find the pertinent declarations, and tell apart the 
> property names and value *without* a full-blown CSS parser, under the 
> following conditions:
> 
> - Every background property declaration (even the last one in a ruleset,
>   where it is optional) is terminated with a semicolon (otherwise, newlines
>   complicate everything);
> 
> - Property values do not contain semicolons (there is the syntactical   
>   possibility for semicolons in "data" URIs for the "background-image"
>   property value or "background" property value component, for example);
> 
> - Property values do not contain substrings that match a "background"
>   or "background-position" property declaration.
> 
> And then I am rather certain (also tested positive on the example code) that 
> you can use
> 
>   /\bbackground(-position)?\s*:\s*([^;]+)\s*;/gi
> 
> for matching.

I was very close to that regular expression :-) Anyway, that one helped me. Thanks.

> Still, the difficulty here is to tell apart the parts of the property value 
> for exchanging their value ("$2").  Again, *iff* you can make sure that 
> *all* percentages in the matched property values relate to horizontal 
> background-position (which usually is _not_ the case: they can also be 
> something that precedes a URI-encoded value for the background image; a 
> radius, position or color stop of a gradient; the background size, or an 
> RGB[A]/HSL[A] background color component, or the vertical background-
> position - did I miss anything?), then you could use
> 
>   ... = value.replace(/\b(?:(left)|(right)|(\d+)%)\b/gi,
>     function (match, left, right, percentage) {
>       return (left
>         ? "right"
>         : (right ? "left" : (100 - percentage) + "%")));
>     });
> 
> But this does not work already in the case of
> 
>   background: url(example1.png) repeat-x right 50%;
> 
> And the "right" value can be anywhere in the property value:
> 
> <http://www.w3.org/TR/css3-background/#ltbg-layergt>
> 
> Specifically, you have to exclude the cases where you found a percentage and 
> either "left" or "right" (in any order) because that percentage, in the 
> aforementioned context, refers to the *vertical* position instead.

That's true. Having values anywhere in property brings complexity for parsing.

> As is obvious now, even though it is generally possible to use regular 
> expressions in this case, many conditions have to be met in order to make it 
> possible.

That's all true what You wrote.

However, I am going to do it starting from basic level. I mean, I will assume that position values will be always at the end of the background property. This indicates some discipline in CSS, but it will work. As a basic step it should be sufficient. Later I will extend parsing to be more flexible.

> It is a lot easier to use the CSSOM instead (document.styleSheets, the 
> return value of document.defaultView.getComputedStyle(...), or the "style" 
> property): there you have the rulesets and declarations already parsed, and 
> can access the "backgroundPosition" or "backgroundPositionX" property value 
> directly where it should always be retrievable in percentages.
[...]

I agree, it's a lot of easier to use the CSSOM instead, but there are several reasons that doesn't allow me to do that in that way.

1. Processing of the CSS file will be done in NodeJS. This means that there is no way to use CSSOM there in the way as browser is using it.

2. I want to keep processed version in the same format as original version for better debugging purpose.

3. I've used PhantomJS to get all CSS properties/values from CSSOM and it works. However, I can get all necessary details but then again I need to build new CSS so that it will look as original file. I think the solution here might become too complex.

Because of all these reasons I think that at basic level I can just parse CSS and use regular expressions to do the changes. Later the solution could be improved, I think.

Thank You for above suggestions described in Your response.

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#26780

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-02-03 11:39 +0100
Message-ID<XnsA436768B71CD1eejj99@194.109.133.133>
In reply to#26779
Cezary Tomczyk <cezary.tomczyk@gmail.com> wrote on 03 feb 2015 in 
comp.lang.javascript:

>  was very close to that regular expression :-)

alert( ':-);-):-);-)'.replace(/((:|;)-\))/g,'$1$1$1') );

-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#26782

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-02-03 15:37 +0100
Message-ID<2677580.U53eFOF1Mr@PointedEars.de>
In reply to#26779
Cezary Tomczyk wrote:

> On Monday, February 2, 2015 at 6:18:05 PM UTC+1, Thomas 'PointedEars' Lahn
> wrote:
> [...]
> However, I am going to do it starting from basic level. I mean, I will
> assume that position values will be always at the end of the background
> property.

Even if so, which coordinate, if any, comes first, is determined by the 
components of the value.

  background: … right 50%;

is equivalent to

  background-: … 100% 50%;

and

  background: … 50% top;

is equivalent to

  background: … 50% 0%;

which is equivalent to

  background: … center top;

and 

  background: … top;

Finally, the initial value is “0% 0%” which is equivalent to “left top”.  
That is, in order to exchange left-aligned for right-aligned background-
position, you have to set “100% 0%” if you find background-image but not any 
“background-position” values in the ruleset *or* rulesets that match the 
same elements.  For that you need a ruleset parser (to consider only the 
last valid declaration), and to find the rulesets to pass to that parser you 
need a full CSS parser (so as not to mistake media queries for them).

<http://www.w3.org/TR/css3-background/#background-position>

>> It is a lot easier to use the CSSOM instead (document.styleSheets, the
>> return value of document.defaultView.getComputedStyle(...), or the
>> "style" property): there you have the rulesets and declarations already
>> parsed, and can access the "backgroundPosition" or "backgroundPositionX"
>> property value directly where it should always be retrievable in
>> percentages.
> [...]
> 
> I agree, it's a lot of easier to use the CSSOM instead, but there are
> several reasons that doesn't allow me to do that in that way.
> 
> 1. Processing of the CSS file will be done in NodeJS. This means that
> there is no way to use CSSOM there in the way as browser is using it.

Doubtful given PhantomJS.

> 2. I want to keep processed version in the same format as original version
> for better debugging purpose.
> 
> 3. I've used PhantomJS to get all CSS properties/values from CSSOM and it
> works. However, I can get all necessary details but then again I need to
> build new CSS so that it will look as original file. I think the solution
> here might become too complex.

While it is rather simple to retrieve the CSS code from a CSS stylesheet 
object in the CSSOM –

  [].map.call(
    document.styleSheets[0].cssRules,
    function (rule) {
      return rule.cssText;
    }).join("\n")

– the result does not need to look like the original stylesheet indeed.
In particular, the retrieved values are the computed ones.

But why would that matter?  What is your use-case?

> Because of all these reasons I think that at basic level I can just parse
> CSS and use regular expressions to do the changes. 

If you have a CSS parser.  Otherwise the probability is greater than zero 
that you break the code this way or that the result is inconsistent.

> Later the solution could be improved, I think.

Improved solutions will become increasingly similar to a CSS parser.  BTDT.

> Thank You for above suggestions described in Your response.

You are welcome.

(Even the polite form of „you“ – which I suppose is what you wanted to 
convey – is not written with a “Y” in modern English, except at the start of 
a sentence.  See also
<http://english.stackexchange.com/questions/30185/you-versus-you-as-polite-form-of-writing>.  Contrast that with “I” which is always written with a 
capital letter.)

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#26788

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2015-02-04 08:55 +0100
Message-ID<7b84c$54d1d079$6def49cc$21120@nntpswitch.blueworldhosting.com>
In reply to#26782
On 2015-02-03 15:37, Thomas 'PointedEars' Lahn wrote:
> Cezary Tomczyk wrote:
>
>> On Monday, February 2, 2015 at 6:18:05 PM UTC+1, Thomas
>> 'PointedEars' Lahn wrote: [...] However, I am going to do it
>> starting from basic level. I mean, I will assume that position
>> values will be always at the end of the background property.
>
> Even if so, which coordinate, if any, comes first, is determined by
> the components of the value.
>
> background: … right 50%;
>
> is equivalent to
>
> background-: … 100% 50%;
>
> and
>
> background: … 50% top;
>
> is equivalent to
>
> background: … 50% 0%;
>
> which is equivalent to
>
> background: … center top;
>
> and
>
> background: … top;
>
> Finally, the initial value is “0% 0%” which is equivalent to “left
> top”. That is, in order to exchange left-aligned for right-aligned
> background- position, you have to set “100% 0%” if you find
> background-image but not any “background-position” values in the
> ruleset *or* rulesets that match the same elements.  For that you
> need a ruleset parser (to consider only the last valid declaration),
> and to find the rulesets to pass to that parser you need a full CSS
> parser (so as not to mistake media queries for them).
>
> <http://www.w3.org/TR/css3-background/#background-position>

I see. More explanation below.

>>> It is a lot easier to use the CSSOM instead
>>> (document.styleSheets, the return value of
>>> document.defaultView.getComputedStyle(...), or the "style"
>>> property): there you have the rulesets and declarations already
>>> parsed, and can access the "backgroundPosition" or
>>> "backgroundPositionX" property value directly where it should
>>> always be retrievable in percentages.
>> [...]
>>
>> I agree, it's a lot of easier to use the CSSOM instead, but there
>> are several reasons that doesn't allow me to do that in that way.
>>
>> 1. Processing of the CSS file will be done in NodeJS. This means
>> that there is no way to use CSSOM there in the way as browser is
>> using it.
>
> Doubtful given PhantomJS.

I've tested yesterday and it works. PhantomJS is fine and I can get all
necessary data using
https://developer.mozilla.org/en-US/docs/Web/API/document.styleSheets.

>> 2. I want to keep processed version in the same format as original
>> version for better debugging purpose.
>>
>> 3. I've used PhantomJS to get all CSS properties/values from CSSOM
>> and it works. However, I can get all necessary details but then
>> again I need to build new CSS so that it will look as original
>> file. I think the solution here might become too complex.
>
> While it is rather simple to retrieve the CSS code from a CSS
> stylesheet object in the CSSOM –
>
> [].map.call( document.styleSheets[0].cssRules, function (rule) {
> return rule.cssText; }).join("\n")
>
> – the result does not need to look like the original stylesheet
> indeed. In particular, the retrieved values are the computed ones.
>
> But why would that matter?  What is your use-case?

Well, I was thinking about debugging later. Same style sheets might help
me to debugging bugs later. But... after all I think this is over
thinking from my side.

I think better idea is to use PhantomJS to retrieve the CSS code from a
CSS stylesheet object in the CSSOM and then before every changed
selector add simple html[dir='rtl'].

Example: LTR version will look

.sidebar {
     float: left;
}

and after processing RTL will look:

html[dir='rtl']
.sidebar {
     float: left;
}

The <html> HTML element need to have set "dir" attribute to proper value.

Yes, leaving parsing for the browser and get all details from browser is
much easier and safer than using regular expressions. Plus, there will
be less maintenance of code.

>> Because of all these reasons I think that at basic level I can just
>> parse CSS and use regular expressions to do the changes.
>
> If you have a CSS parser.  Otherwise the probability is greater than
> zero that you break the code this way or that the result is
> inconsistent.
>
>> Later the solution could be improved, I think.
>
> Improved solutions will become increasingly similar to a CSS parser.
> BTDT.

It's so true. I was afraid about that. This would probably lead me into
very complex direction.

After all considerations I decided to use PhantomJS to do the job.

> (Even the polite form of „you“ – which I suppose is what you wanted
> to convey – is not written with a “Y” in modern English, except at
> the start of a sentence.  See also
> <http://english.stackexchange.com/questions/30185/you-versus-you-as-polite-form-of-writing>.
> Contrast that with “I” which is always written with a capital
> letter.)

Thanks for that note. However, some software just automatically convert
"you" to "You" ;-)

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#26793

FromJohn Harris <niam@jghnorth.org.uk.invalid>
Date2015-02-04 15:09 +0000
Message-ID<rfd4dalahtkidfk0854evpk65o5dr55lvl@4ax.com>
In reply to#26782
On Tue, 03 Feb 2015 15:37:31 +0100, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:


  <snip>
>(Even the polite form of „you“ – which I suppose is what you wanted to 
  <snip>

English does not use upside down quote symbols.

  John

[toc] | [prev] | [next] | [standalone]


#26794

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-02-04 16:19 +0100
Message-ID<3546401.Vs2I2MNLQO@PointedEars.de>
In reply to#26793
John Harris wrote:

> […] Thomas 'PointedEars' Lahn […] wrote:
>> (Even the polite form of „you“ – which I suppose is what you wanted to
>> [convey …]
> 
> English does not use upside down quote symbols.

s/quote symbols/quotation marks/, otherwise you are correct.  German does, 
however, and out of habit I used those here (with this keyboard layout it is 
actually easier for me to use the “English” ones than the “German” ones).

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#26781

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-02-03 12:44 +0100
Message-ID<2049578.4vjSuc16jt@PointedEars.de>
In reply to#26778
Thomas 'PointedEars' Lahn wrote:

> […] Again, *iff* you can make sure that *all* percentages in the matched 
> property values relate to horizontal background-position (which usually is 
> _not_ the case: […]), then you could use
> 
>   … = value.replace(/\b(?:(left)|(right)|(\d+)%)\b/gi,
>     function (match, left, right, percentage) {
>       return (left
>         ? "right"
>         : (right ? "left" : (100 - percentage) + "%")));
                                                        ^
>     });
> 
> But this does not work already in the case of
> 
>   background: url(example1.png) repeat-x right 50%;

Bad example :)  It would work here (after the extra parenthesis was 
removed), but only because of 100 − 50 = 50.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web