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


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

Clean up HTML content

Started byCezary Tomczyk <cezary.tomczyk@gmail.com>
First post2013-03-05 08:48 +0100
Last post2013-03-09 11:44 -0800
Articles 14 — 6 participants

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


Contents

  Clean up HTML content Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2013-03-05 08:48 +0100
    Re: Clean up HTML content Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-05 17:55 +0100
      Re: Clean up HTML content Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2013-03-05 20:25 +0100
        Re: Clean up HTML content Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-06 00:03 +0100
          Re: Clean up HTML content Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-06 00:08 +0100
            Re: Clean up HTML content Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-03-06 22:06 +0000
              Re: Clean up HTML content Eric Bednarz <bednarz@fahr-zur-hoelle.org> - 2013-03-10 01:14 +0100
          Re: Clean up HTML content Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2013-03-06 22:02 +0100
            Re: Clean up HTML content Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-06 23:45 +0100
              Re: Clean up HTML content Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2013-03-09 11:29 +0100
                Re: Clean up HTML content Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-09 16:11 +0100
    Re: Clean up HTML content Danny <dann90038@gmail.com> - 2013-03-07 14:28 -0800
      Re: Clean up HTML content Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2013-03-09 11:37 +0100
        Re: Clean up HTML content dann90038@gmail.com - 2013-03-09 11:44 -0800

#18718 — Clean up HTML content

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2013-03-05 08:48 +0100
SubjectClean up HTML content
Message-ID<kh4813$lkv$1@speranza.aioe.org>
I wrote some method to clean up HTML content inside <div> (could by any 
element) with attribute "contenteditable='true'". My idea is to remove 
all HTML nodes except text nodes and specific images.

Live example: http://jsfiddle.net/rFRwp/

Unfortunately, doesn't work yet. Am I going into right way? Or there is 
better methods to clean up HTML?

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

[toc] | [next] | [standalone]


#18722

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-05 17:55 +0100
Message-ID<2342178.BYbISWzQ9U@PointedEars.de>
In reply to#18718
Cezary Tomczyk wrote:

> I wrote some method to clean up HTML content inside <div> (could by any
> element) with attribute "contenteditable='true'". My idea is to remove
> all HTML nodes except text nodes and specific images.
> 
> Live example: http://jsfiddle.net/rFRwp/

This is Usenet, not the Web.  An URI to a test case can be helpful, but it 
does not suffice.
 
> Unfortunately, doesn't work yet. Am I going into right way? Or there is
> better methods to clean up HTML?

Perhaps.  I cannot know for sure because I cannot scroll your script code on 
the Web, and you have not posted any code here.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

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


#18724

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2013-03-05 20:25 +0100
Message-ID<kh5grn$bm0$1@speranza.aioe.org>
In reply to#18722
W dniu 2013-03-05 17:55, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
[...]

>> Live example: http://jsfiddle.net/rFRwp/
>
> This is Usenet, not the Web.  An URI to a test case can be helpful, but it
> does not suffice.

I know that this is Usenet, not the Web. I thought that code is too big 
and instead of posting code here it would be better to prepare a working 
example.

>> Unfortunately, doesn't work yet. Am I going into right way? Or there is
>> better methods to clean up HTML?
>
> Perhaps.  I cannot know for sure because I cannot scroll your script code on
> the Web, and you have not posted any code here.

Here's the code:

var is_block_style = function (el) {
     var el_style;
     if (window.getComputedStyle) {
         el_style = window.getComputedStyle(el, 
null).getPropertyValue('display');
     } else {
         el_style = el.currentStyle.display;
     }
     return el_style;
};

var imgClassName = 'testimg';

var tidyHTML = function (node) {
     var elms = node.childNodes,
         i = elms.length,
         text = '',
         elm;

     if (!node.hasChildNodes() && (node.nodeName.toLowerCase() === 'img' 
&& !(new RegExp('(^|\\s)' + imgClassName + 
'(\\s|$)')).test(node.className))) {
         node.parentNode.removeChild(node);
         return text;
     }

     while (i--) {
         elm = elms[i];

         if (elm.nodeType === 1) {
             text += tidyHTML(elm);
         } else if (elm.nodeType === 3) {
             text += elm.data;
         } else if (elm.nodeType !== 3 && elm.nodeType !== 1) {
             elm.parentNode.removeChild(elm);
         }
     }

     if (typeof text !== 'undefined') {
         if (is_block_style(node) === 'block') {
             node.parentNode.insertBefore(document.createElement('br'), 
node.nextSibling);
         }
         //node.parentNode.replaceChild(document.createTextNode(text), 
node);
     }
     return text;
};

Above version also on the web: http://jsfiddle.net/rFRwp/2/

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

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


#18725

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-06 00:03 +0100
Message-ID<1699591.rPLLIT5s0r@PointedEars.de>
In reply to#18724
Cezary Tomczyk wrote:

> W dniu 2013-03-05 17:55, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
>>> Live example: http://jsfiddle.net/rFRwp/
>>
>> This is Usenet, not the Web.  An URI to a test case can be helpful, but
>> it does not suffice.
> 
> I know that this is Usenet, not the Web. I thought that code is too big
> and instead of posting code here it would be better to prepare a working
> example.

You have posted 75 lines now.  Of those, unless I miscounted or 
miscalculated, 48 of them are source code.  I do not think that is “too big” 
for source code on this newsgroup.

Consider that there have been discussions here with very valuable postings 
of 200 lines and more.  Although few if any of those postings contained 
source code in all or even the majority of lines, what is to discuss *here* 
if we adopt a rule that, say, posting code was inappropriate when it 
exceeded 40 lines?

There is an individual limit as to the acceptable length of a posting, but I 
doubt it starts below 100 lines for anyone.  The same is true for source 
code in postings.  This posting is likely to have more than 100 lines, 
including source code.

What is usually frowned upon is posting uncommented source code that is not 
self-explanatory, and maybe even badly formatted, because the poster did not 
take care to understand it in the first place.  Your code is neither.
 
>>> Unfortunately, doesn't work yet. Am I going into right way? Or there is
>>> better methods to clean up HTML?
>>
>> Perhaps.  I cannot know for sure because I cannot scroll your script code
>> on the Web, and you have not posted any code here.
> 
> Here's the code:
> 
> var is_block_style = function (el) {
>      var el_style;
>      if (window.getComputedStyle) {

You should feature-test this method in a way that does not primarily use 
implicit type conversion.  There is one DOM implementation, MSHTML, that is 
notorious for throwing strange exceptions on properties of type "unknown" 
otherwise.  See also, e.g., jsx.object.isHostMethod().

>          el_style = window.getComputedStyle(el,
> null).getPropertyValue('display');
>      } else {
>          el_style = el.currentStyle.display;
>      }
>      return el_style;
> };

You should generalize this code, see also jsx.dom.getComputedStyle().  In 
this case, because the base object always is the same, you can even safely 
perform the branching for the window.getComputedStyle() DOM method – which 
should be document.defaultView.getComputedStyle() to be compatible – only 
once.  You cannot assume, however, that if the getComputedStyle() method is 
absent, the “currentStyle“ property must be present; that is an inductive 
fallacy (hasty generalization).

A method whose name starts with “is” should not return a string value, but a 
boolean value.  In this case, it should return the result of the comparison 
against any of those property values which should be considered indicative 
of a “block element” (see CSS 2.1, also CSS3 Box Model for details).

> var imgClassName = 'testimg';
> 
> var tidyHTML = function (node) {
>      var elms = node.childNodes,
>          i = elms.length,
>          text = '',
>          elm;
> 
>      if (!node.hasChildNodes()

I have never used that method before.  Unless you are sure about its 
backwards-compatibility, you should replace the call with

  if (!node.childNodes.length > 0

If you do not insist on an explicit condition, use

  if (!node.childNodes.length

or

  if (!node.firstChild

whereas the latter is probably the more efficient variant of the two.
I think it is safe to assume that those values can be type-converted if 
necessary, because otherwise a lot of simple client-side scripts would fail.  
But if necessary and appropriate for your use-case, use

  if (null != node.firstChild

or 

  if (node.firstChild !== null

In theory,

  if (null !== node.firstChild

should have the best runtime efficiency, returning in step 3 of the “Strict 
Equality Comparison Algorithm” (ES 5.1, 11.9.6) if node.firstChild is null, 
and returning in step 1 if it is not, already.  (I have not applied this 
knowledge yet.  Profiling will show if I should.)

>      && (node.nodeName.toLowerCase() === 'img'
> && !(new RegExp('(^|\\s)' + imgClassName +
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> '(\\s|$)')).test(node.className))) {
  ^^^^^^^^^^^
You should move or even generalize this code in order to leverage caching.  
You can do that because the RegExp does not have the “global” flag set 
(i.e.,  its boolean ”global” property has the value “false”).

>          node.parentNode.removeChild(node);
>          return text;
>      }
> 
>      while (i--) {
>          elm = elms[i];

So AIUI you iterate backwards through the child nodes …

>          if (elm.nodeType === 1) {

A strict comparison does not appear to be necessary or prudent here.  You 
cannot know that the types match since you are dealing with a host object.  
What you can know (from the ECMAScript Specification) is that *if* the types 
match, it does not matter for the result or efficiency if you use a strict 
comparison or not.  And you gain a little bit more backwards-compatibility 
that way.

>              text += tidyHTML(elm);

… but why do you *append* to the “text” variable as if you had iterated 
forwards, thereby reversing the order of the content?

Equivalent code:

  var a = ["foo", "bar", "baz"];
  var i = a.length;
  var a2 = [];
  while (i--)
  {
    if (a[i] != "bar")
    {
      a2.push(a[i]);
    }
  }

  /* ["baz", "foo"] */
  console.log(a2);

You are looking for something more like

  for (var i = 0, len = elms.length; i < len; ++i)
  {
    text += tidyHTML(elms[i]);
  }

>          } else if (elm.nodeType === 3) {
>              text += elm.data;
>          } else if (elm.nodeType !== 3 && elm.nodeType !== 1) {
>              elm.parentNode.removeChild(elm);
>          }

ISTM that at least one of those should happen before the loop, and before 
the function returns, in the trivial case.  Pseudo-code:

  function recurse (target)
  {
    if (isTrivial(target)) { return trivialValue; }

    for (var property in target)
    {
      recurse(target[property]);
    }

    return nonTrivialValue;
  }

>      }
> 
>      if (typeof text !== 'undefined') {

Again an unnecessary strict comparison.

>          if (is_block_style(node) === 'block') {
>              node.parentNode.insertBefore(document.createElement('br'),
> node.nextSibling);
>          }

Why?  Usually it is misuse of the “br” element to use it as replacement for 
a block delimiter.  Also, “display: block” does not necessarily mean that 
there is a paragraph.  Consider, for example, positioned or floating block 
elements.

>          //node.parentNode.replaceChild(document.createTextNode(text),
> node);
>      }
>      return text;
> };

And BTW, “doesn't work (yet)” is not a problem description.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

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


#18726

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-06 00:08 +0100
Message-ID<3701606.ZRzbRc1aAO@PointedEars.de>
In reply to#18725
Thomas 'PointedEars' Lahn wrote:

> Cezary Tomczyk wrote:
>>      if (!node.hasChildNodes()
> 
> I have never used that method before.  Unless you are sure about its
> backwards-compatibility, you should replace the call with
> 
>   if (!node.childNodes.length > 0
> […]

I meant

  if (node.childNodes.length < 1

or 

  if (node.childNodes.length == 0

-- 
PointedEars

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


#18741

FromDr J R Stockton <reply1300@merlyn.demon.co.uk.invalid>
Date2013-03-06 22:06 +0000
Message-ID<IIxkZSKA47NRFwmm@invalid.uk.co.demon.merlyn.invalid>
In reply to#18726
In comp.lang.javascript message <3701606.ZRzbRc1aAO@PointedEars.de>,
Wed, 6 Mar 2013 00:08:25, Thomas 'PointedEars' Lahn <PointedEars@web.de>
posted:

>Thomas 'PointedEars' Lahn wrote:
>
>> Cezary Tomczyk wrote:
>>>      if (!node.hasChildNodes()
>>
>> I have never used that method before.  Unless you are sure about its
>> backwards-compatibility, you should replace the call with
>>
>>   if (!node.childNodes.length > 0
>> […]
>
>I meant
>
>  if (node.childNodes.length < 1
>
>or
>
>  if (node.childNodes.length == 0

If you spent less time writing drivel, you would have more time to check
your code before posting.


-- 
(c) John Stockton, nr London UK.  ???@merlyn.demon.co.uk  Turnpike v6.05  MIME.
 Web  <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
     Check boilerplate spelling -- error is a public sign of incompetence.
    Never fully trust an article from a poster who gives no full real name.

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


#18796

FromEric Bednarz <bednarz@fahr-zur-hoelle.org>
Date2013-03-10 01:14 +0100
Message-ID<m2obesru08.fsf@nntp.bednarz.nl>
In reply to#18741
Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> writes:

> Thomas 'PointedEars' Lahn <PointedEars@web.de> posted:

[...]

> If you spent less time writing drivel, you would have more time to check
> your code before posting.

If you spent less time writing drivel, oh well, you'd probably be
dead. Never mind,  I'm sure the politically correct course of action is
to encourage you to go on.

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


#18739

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2013-03-06 22:02 +0100
Message-ID<kh8ata$am8$1@speranza.aioe.org>
In reply to#18725
W dniu 2013-03-06 00:03, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2013-03-05 17:55, Thomas 'PointedEars' Lahn pisze:
[...]
>> I know that this is Usenet, not the Web. I thought that code is too big
>> and instead of posting code here it would be better to prepare a working
>> example.
>
> You have posted 75 lines now.  Of those, unless I miscounted or
> miscalculated, 48 of them are source code.  I do not think that is “too big”
> for source code on this newsgroup.
>
> Consider that there have been discussions here with very valuable postings
> of 200 lines and more.  Although few if any of those postings contained
> source code in all or even the majority of lines, what is to discuss *here*
> if we adopt a rule that, say, posting code was inappropriate when it
> exceeded 40 lines?
>
> There is an individual limit as to the acceptable length of a posting, but I
> doubt it starts below 100 lines for anyone.  The same is true for source
> code in postings.  This posting is likely to have more than 100 lines,
> including source code.
>
> What is usually frowned upon is posting uncommented source code that is not
> self-explanatory, and maybe even badly formatted, because the poster did not
> take care to understand it in the first place.  Your code is neither.

I'll try to consider it while will be posting code next time. As for 
formatting, code was formatted, but for some reason do not know why here 
is unformatted.

[...]

>> Here's the code:
>>
>> var is_block_style = function (el) {
>>       var el_style;
>>       if (window.getComputedStyle) {
>
> You should feature-test this method in a way that does not primarily use
> implicit type conversion.  There is one DOM implementation, MSHTML, that is
> notorious for throwing strange exceptions on properties of type "unknown"
> otherwise.  See also, e.g., jsx.object.isHostMethod().

Yes, I know that IE return sometimes "object", sometimes "function". 
However, I had never any problems with implicit type conversion like above.

One request: if you refer to some methods of your code, eg. e.g., 
jsx.object.isHostMethod, then please also add link to source code. I 
guess it's coming from JSX project 
http://pointedears.de/websvn/listing.php?repname=JSX.

And you thought about that, right?

jsx.object.isMethodType = function (s) {
   return /^\s*(function|object|unknown)\s*$/i.test(s);
};

>>           el_style = window.getComputedStyle(el,
>> null).getPropertyValue('display');
>>       } else {
>>           el_style = el.currentStyle.display;
>>       }
>>       return el_style;
>> };
>
> You should generalize this code, see also jsx.dom.getComputedStyle().  In

I do not see here 
http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom.js 
method getComputedStyle.

> this case, because the base object always is the same, you can even safely
> perform the branching for the window.getComputedStyle() DOM method – which
> should be document.defaultView.getComputedStyle() to be compatible – only
> once.  You cannot assume, however, that if the getComputedStyle() method is
> absent, the “currentStyle“ property must be present; that is an inductive
> fallacy (hasty generalization).

Hm, both sources:

* https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
* http://msdn.microsoft.com/en-us/library/ie/ff975168%28v=vs.85%29.aspx

says about window.getComputedStyle. That's why I used this method.

However, when I look at David Mark method getKomputedStyle seems it's 
quite complicated :-(

> A method whose name starts with “is” should not return a string value, but a
> boolean value.  In this case, it should return the result of the comparison
> against any of those property values which should be considered indicative
> of a “block element” (see CSS 2.1, also CSS3 Box Model for details).

Makes sense. Thanks.

>> var imgClassName = 'testimg';
>>
>> var tidyHTML = function (node) {
>>       var elms = node.childNodes,
>>           i = elms.length,
>>           text = '',
>>           elm;
>>
>>       if (!node.hasChildNodes()
>
> I have never used that method before.  Unless you are sure about its
> backwards-compatibility, you should replace the call with

I use https://developer.mozilla.org/en-US/docs/DOM/Node.hasChildNodes 
from long time. Sesms it's implemented long time ago. See: 
http://www.quirksmode.org/dom/w3c_core.html

>    if (!node.childNodes.length > 0
>
> If you do not insist on an explicit condition, use
>
>    if (!node.childNodes.length
>
> or
>
>    if (!node.firstChild
>
> whereas the latter is probably the more efficient variant of the two.
> I think it is safe to assume that those values can be type-converted if
> necessary, because otherwise a lot of simple client-side scripts would fail.
> But if necessary and appropriate for your use-case, use
>
>    if (null != node.firstChild
>
> or
>
>    if (node.firstChild !== null
>
> In theory,
>
>    if (null !== node.firstChild
>
> should have the best runtime efficiency, returning in step 3 of the “Strict
> Equality Comparison Algorithm” (ES 5.1, 11.9.6) if node.firstChild is null,
> and returning in step 1 if it is not, already.  (I have not applied this
> knowledge yet.  Profiling will show if I should.)

This one:
if (!node.firstChild
is nice. However, as I wrote, I have never had problems with 
hasChildNodes method.

>>       && (node.nodeName.toLowerCase() === 'img'
>> && !(new RegExp('(^|\\s)' + imgClassName +
>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> '(\\s|$)')).test(node.className))) {
>    ^^^^^^^^^^^
> You should move or even generalize this code in order to leverage caching.

Move new RegExp outside of method to do not creating new objects RegExp 
everytime?

> You can do that because the RegExp does not have the “global” flag set
> (i.e.,  its boolean ”global” property has the value “false”).

Right. I should set "global" as "true".

>>           node.parentNode.removeChild(node);
>>           return text;
>>       }
>>
>>       while (i--) {
>>           elm = elms[i];
>
> So AIUI you iterate backwards through the child nodes …

Yes.

>>           if (elm.nodeType === 1) {
>
> A strict comparison does not appear to be necessary or prudent here.  You
> cannot know that the types match since you are dealing with a host object.
> What you can know (from the ECMAScript Specification) is that *if* the types
> match, it does not matter for the result or efficiency if you use a strict
> comparison or not.  And you gain a little bit more backwards-compatibility
> that way.

Yes, I remember your explanation from the past. But it's about JSLint 
which I do not remember now why JSLint require "===" all the time.

>>               text += tidyHTML(elm);
>
> … but why do you *append* to the “text” variable as if you had iterated
> forwards, thereby reversing the order of the content?

Because sometimes I removing node.

> Equivalent code:
>
>    var a = ["foo", "bar", "baz"];
>    var i = a.length;
>    var a2 = [];
>    while (i--)
>    {
>      if (a[i] != "bar")
>      {
>        a2.push(a[i]);
>      }
>    }
>
>    /* ["baz", "foo"] */
>    console.log(a2);
>
> You are looking for something more like
>
>    for (var i = 0, len = elms.length; i < len; ++i)
>    {
>      text += tidyHTML(elms[i]);
>    }

Not really. In short: I want to remove all html nodes, except img with 
specified class name + I need to care about formatting, eg. if text is 
in block element then I apply <br/> after plain text.

>>           } else if (elm.nodeType === 3) {
>>               text += elm.data;
>>           } else if (elm.nodeType !== 3 && elm.nodeType !== 1) {
>>               elm.parentNode.removeChild(elm);
>>           }
>
> ISTM that at least one of those should happen before the loop, and before
> the function returns, in the trivial case.  Pseudo-code:
>
>    function recurse (target)
>    {
>      if (isTrivial(target)) { return trivialValue; }
>
>      for (var property in target)
>      {
>        recurse(target[property]);
>      }
>
>      return nonTrivialValue;
>    }

I'll try to make a changes as you suggested above.

>>       }
>>
>>       if (typeof text !== 'undefined') {
>
> Again an unnecessary strict comparison.

JSLint case.

>>           if (is_block_style(node) === 'block') {
>>               node.parentNode.insertBefore(document.createElement('br'),
>> node.nextSibling);
>>           }
>
> Why?  Usually it is misuse of the “br” element to use it as replacement for
> a block delimiter.  Also, “display: block” does not necessarily mean that
> there is a paragraph.  Consider, for example, positioned or floating block
> elements.

Yes, I now saw the method getKomputedStyle from MyLibrary. 
Unfortunately, it's quite complicated :/ I do not know about JSX similar 
method.

>>           //node.parentNode.replaceChild(document.createTextNode(text),
>> node);
>>       }
>>       return text;
>> };
>
> And BTW, “doesn't work (yet)” is not a problem description.

I'll try to be more strictly next time.

Will apply now some changes, as you mentioned.

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

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


#18740

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-06 23:45 +0100
Message-ID<2295376.vs5DUIPqoH@PointedEars.de>
In reply to#18739
Cezary Tomczyk wrote:

> W dniu 2013-03-06 00:03, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
>>> W dniu 2013-03-05 17:55, Thomas 'PointedEars' Lahn pisze:
> [...]
>> What is usually frowned upon is posting uncommented source code that is
>> not self-explanatory, and maybe even badly formatted, because the poster
>> did not take care to understand it in the first place.  Your code is
>> neither.
> 
> I'll try to consider it while will be posting code next time. As for
> formatting, code was formatted, but for some reason do not know why here
> is unformatted.

I said: The code that you posted (IMHO) *is* self-explanatory, and _not_ 
badly formatted.  IOW, (IMHO) it is *OK* for posting even *without* 
additional comments.
 
> [...]
>>> Here's the code:
>>>
>>> var is_block_style = function (el) {
>>>       var el_style;
>>>       if (window.getComputedStyle) {
>>
>> You should feature-test this method in a way that does not primarily use
>> implicit type conversion.  There is one DOM implementation, MSHTML, that
>> is notorious for throwing strange exceptions on properties of type
>> "unknown" otherwise.  See also, e.g., jsx.object.isHostMethod().
   ^^^^^^^^^                             ^^^^^^^^^^^^^^^^^^^^^^^^^
> Yes, I know that IE return sometimes "object", sometimes "function".

More importantly, sometimes the result of the “typeof” operation is 
“"unknown"” there (I hope the additional quotes make it clear now).  And 
then a type-converting test throws an exception.  So a type-converting test 
cannot be considered appropriate for feature-testing host object's methods.  
It is insufficient for testing native object's methods already.

> However, I had never any problems with implicit type conversion like
> above.

Lucky you.

> One request: if you refer to some methods of your code, eg. e.g.,
> jsx.object.isHostMethod, then please also add link to source code. I
> guess it's coming from JSX project
> http://pointedears.de/websvn/listing.php?repname=JSX.
> 
> And you thought about that, right?

Yes …
 
> jsx.object.isMethodType = function (s) {
  ^^^^^^^^^^^^^^^^^^^^^^^
>    return /^\s*(function|object|unknown)\s*$/i.test(s);
> };

… and no; evidently the name of the method I mentioned is different.  The 
actual method *actually* is too long to be posted here.  It can be found in

<http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fobject.js>

which in turn can be easily found with a Web search.
 
>>>           el_style = window.getComputedStyle(el,
>>> null).getPropertyValue('display');
>>>       } else {
>>>           el_style = el.currentStyle.display;
>>>       }
>>>       return el_style;
>>> };
>>
>> You should generalize this code, see also jsx.dom.getComputedStyle().  In
> 
> I do not see here
> 
http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom.js
> method getComputedStyle.

Because it requires *CSS* (D)OM capabilities.  For historical reasons it is 
not available as jsx.dom.css.getComputedStyle(), though.

<http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom%2Fcss.js>

That, too, can be easily found with a Web search.

Try to be more careful in all respects, please.

>> this case, because the base object always is the same, you can even
>> safely perform the branching for the window.getComputedStyle() DOM method
>> – which should be document.defaultView.getComputedStyle() to be
>> compatible – only once.  You cannot assume, however, that if the
>> getComputedStyle() method is absent, the “currentStyle“ property must be
>> present; that is an inductive fallacy (hasty generalization).
> 
> Hm, both sources:
> 
> * https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle

Keep in mind that this is a wiki.  Anyone logged in can write any nonsense 
there.  And anyone logged in can correct it.  If they learn about it.

> * http://msdn.microsoft.com/en-us/library/ie/ff975168%28v=vs.85%29.aspx
> 
> says about window.getComputedStyle. That's why I used this method.
> 
> However, when I look at David Mark method getKomputedStyle seems it's
> quite complicated :-(

So there *actually* *is* *more* than Firefox and Internet Explorer? ;-)

Seriously though, I remember to have observed several versions of Safari 4 
not having window.getComputedStyle() but 
document.defaultView.getComputedStyle().  The Gecko DOM, and the MSHTML 9 
DOM in Standards Mode, have both.

So far, document.defaultView.getComputedStyle() is the more standards-
compliant approach because:

1. “document” implements the “DocumentView” interface of W3C DOM Level 2
   Views [DOM2Views].

2. “document.defaultView” implements the “ViewCSS” interface of
   W3C DOM Level 2 Style CSS [DOM2CSS], which inherits from the
   “AbstractView” interface of [DOM2Views].

3. “getComputedStyle” is a method provided by “ViewCSS” interface. (ibid.)

(The reference to [HTML5] in [DOM2Views] appears to be a dead end here; the 
“Window” interface of [HTML5] does not provide a “getComputedStyle” method.)

______________
[DOM2Views] <http://www.w3.org/TR/DOM-Level-2-Views/> p.
[DOM2CSS]   <http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-ViewCSS>
[HTML5]     <http://www.w3.org/TR/html5/dom.html#the-document-object> pp.

>>> var imgClassName = 'testimg';
>>>
>>> var tidyHTML = function (node) {
>>>       var elms = node.childNodes,
>>>           i = elms.length,
>>>           text = '',
>>>           elm;
>>>
>>>       if (!node.hasChildNodes()
>>
>> I have never used that method before.  Unless you are sure about its
>> backwards-compatibility, you should replace the call with
> 
> I use https://developer.mozilla.org/en-US/docs/DOM/Node.hasChildNodes
> from long time. Sesms it's implemented long time ago. See:
> http://www.quirksmode.org/dom/w3c_core.html

It was *specified* a long time ago.  I rather do my own tests instead of 
relying on MDN or Quirks Mode.

>>>       && (node.nodeName.toLowerCase() === 'img'
>>> && !(new RegExp('(^|\\s)' + imgClassName +
>>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> '(\\s|$)')).test(node.className))) {
>>    ^^^^^^^^^^^
>> You should move or even generalize this code in order to leverage
>> caching.
> 
> Move new RegExp outside of method to do not creating new objects RegExp
> everytime?

Yes.

My next idea is that you can globally cache references to RegExp instances 
that do not have the “global” flag set.  But it is perhaps not applicable 
here.

>> You can do that because the RegExp does not have the “global” flag set
   ^^^^^^^^^^^^^^^
Meaning: “You can create the RegExp instance only once because …”

>> (i.e.,  its boolean ”global” property has the value “false”).
> 
> Right. I should set "global" as "true".

No, I did _not_ suggest that you should make that mistake:

  var rx = /foo/g;
  var s = "foo";

  /* true */
  rx.test(s)

  /* false */
  rx.test(s)

  /* true */
  rx.test(s)

  .
  .
  .
 
>>>           node.parentNode.removeChild(node);
>>>           return text;
>>>       }
>>>
>>>       while (i--) {
>>>           elm = elms[i];
>>
>> So AIUI you iterate backwards through the child nodes …
> 
> Yes.
> 
>>>           if (elm.nodeType === 1) {
>>
>> A strict comparison does not appear to be necessary or prudent here.  You
>> cannot know that the types match since you are dealing with a host
>> object. What you can know (from the ECMAScript Specification) is that
>> *if* the types match, it does not matter for the result or efficiency if
>> you use a strict comparison or not.  And you gain a little bit more
>> backwards-compatibility that way.
> 
> Yes, I remember your explanation from the past. But it's about JSLint
> which I do not remember now why JSLint require "===" all the time.
> 
>>>               text += tidyHTML(elm);
>>
>> … but why do you *append* to the “text” variable as if you had iterated
>> forwards, thereby reversing the order of the content?
> 
> Because sometimes I removing node.

How does that explain the opposite direction of the concatenation?

>> Equivalent code:
>>
>>    var a = ["foo", "bar", "baz"];
>>    var i = a.length;
>>    var a2 = [];
>>    while (i--)
>>    {
>>      if (a[i] != "bar")
>>      {
>>        a2.push(a[i]);
>>      }
>>    }
>>
>>    /* ["baz", "foo"] */
>>    console.log(a2);
>>
>> You are looking for something more like
>>
>>    for (var i = 0, len = elms.length; i < len; ++i)
>>    {
>>      text += tidyHTML(elms[i]);
>>    }
> 
> Not really. In short: I want to remove all html nodes, except img with
> specified class name + I need to care about formatting, eg. if text is
> in block element then I apply <br/> after plain text.

I am aware of that, but ISTM that you will still have to append/concatenate 
in the direction of the iteration or you will have the original content 
reduced *and* backwards.
 
>>>       }
>>>
>>>       if (typeof text !== 'undefined') {
>>
>> Again an unnecessary strict comparison.
> 
> JSLint case.

Learn how to configure it, or use a better tool.
 
>>>           if (is_block_style(node) === 'block') {
>>>               node.parentNode.insertBefore(document.createElement('br'),
>>> node.nextSibling);
>>>           }
>>
>> Why?  Usually it is misuse of the “br” element to use it as replacement
>> for a block delimiter.  Also, “display: block” does not necessarily mean
>> that there is a paragraph.  Consider, for example, positioned or floating
>> block elements.
> 
> Yes, I now saw the method getKomputedStyle from MyLibrary.

JFTR: You are not posting the URI of code you are referring to either.

> Unfortunately, it's quite complicated :/ I do not know about JSX similar
> method.

I seriously hope there is none.  What a bloat:

<https://github.com/cinsoft/My-Library/blob/master/mylib.asp#L2329>
 
-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

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


#18783

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2013-03-09 11:29 +0100
Message-ID<khf2uc$9o0$1@speranza.aioe.org>
In reply to#18740
W dniu 2013-03-06 23:45, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2013-03-06 00:03, Thomas 'PointedEars' Lahn pisze:
[...]

> I said: The code that you posted (IMHO) *is* self-explanatory, and _not_
> badly formatted.  IOW, (IMHO) it is *OK* for posting even *without*
> additional comments.

Ok.

>> [...]
>>>> Here's the code:
>>>>
>>>> var is_block_style = function (el) {
>>>>        var el_style;
>>>>        if (window.getComputedStyle) {
>>>
>>> You should feature-test this method in a way that does not primarily use
>>> implicit type conversion.  There is one DOM implementation, MSHTML, that
>>> is notorious for throwing strange exceptions on properties of type
>>> "unknown" otherwise.  See also, e.g., jsx.object.isHostMethod().
>     ^^^^^^^^^                             ^^^^^^^^^^^^^^^^^^^^^^^^^
>> Yes, I know that IE return sometimes "object", sometimes "function".
>
> More importantly, sometimes the result of the “typeof” operation is
> “"unknown"” there (I hope the additional quotes make it clear now).  And
> then a type-converting test throws an exception.  So a type-converting test
> cannot be considered appropriate for feature-testing host object's methods.
> It is insufficient for testing native object's methods already.

That's surprising me, I mean about "unknown". I never saw it before.

>> However, I had never any problems with implicit type conversion like
>> above.
>
> Lucky you.

Probably.

[...]

>> jsx.object.isMethodType = function (s) {
>    ^^^^^^^^^^^^^^^^^^^^^^^
>>     return /^\s*(function|object|unknown)\s*$/i.test(s);
>> };
>
> … and no; evidently the name of the method I mentioned is different.  The
> actual method *actually* is too long to be posted here.  It can be found in
>
> <http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fobject.js>
>
> which in turn can be easily found with a Web search.

isHostMethod is the same as isMethod, as I see:

jsx.object.isHostMethod = jsx.object.areHostMethods = jsx.object.isMethod;

>>>>            el_style = window.getComputedStyle(el,
>>>> null).getPropertyValue('display');
>>>>        } else {
>>>>            el_style = el.currentStyle.display;
>>>>        }
>>>>        return el_style;
>>>> };
>>>
>>> You should generalize this code, see also jsx.dom.getComputedStyle().  In
>>
>> I do not see here
>>
> http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom.js
>> method getComputedStyle.
>
> Because it requires *CSS* (D)OM capabilities.  For historical reasons it is
> not available as jsx.dom.css.getComputedStyle(), though.
>
> <http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom%2Fcss.js>
>
> That, too, can be easily found with a Web search.

Would be nice to have same input search field to search through SVN files.

I found jsx.dom.getComputedStyle and seems it's code looks not so big.

> Try to be more careful in all respects, please.

I'll try.

>>> this case, because the base object always is the same, you can even
>>> safely perform the branching for the window.getComputedStyle() DOM method
>>> – which should be document.defaultView.getComputedStyle() to be
>>> compatible – only once.  You cannot assume, however, that if the
>>> getComputedStyle() method is absent, the “currentStyle“ property must be
>>> present; that is an inductive fallacy (hasty generalization).
>>
>> Hm, both sources:
>>
>> * https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
>
> Keep in mind that this is a wiki.  Anyone logged in can write any nonsense
> there.  And anyone logged in can correct it.  If they learn about it.

"Anyone can write nonsense, anyone can correct it." - how to trust in 
that sources then? Hm...

>> * http://msdn.microsoft.com/en-us/library/ie/ff975168%28v=vs.85%29.aspx
>>
>> says about window.getComputedStyle. That's why I used this method.
>>
>> However, when I look at David Mark method getKomputedStyle seems it's
>> quite complicated :-(
>
> So there *actually* *is* *more* than Firefox and Internet Explorer? ;-)

Ou, yes :-)

> Seriously though, I remember to have observed several versions of Safari 4
> not having window.getComputedStyle() but
> document.defaultView.getComputedStyle().  The Gecko DOM, and the MSHTML 9
> DOM in Standards Mode, have both.
>
> So far, document.defaultView.getComputedStyle() is the more standards-
> compliant approach because:
>
> 1. “document” implements the “DocumentView” interface of W3C DOM Level 2
>     Views [DOM2Views].
>
> 2. “document.defaultView” implements the “ViewCSS” interface of
>     W3C DOM Level 2 Style CSS [DOM2CSS], which inherits from the
>     “AbstractView” interface of [DOM2Views].
>
> 3. “getComputedStyle” is a method provided by “ViewCSS” interface. (ibid.)
>
> (The reference to [HTML5] in [DOM2Views] appears to be a dead end here; the
> “Window” interface of [HTML5] does not provide a “getComputedStyle” method.)
>
> ______________
> [DOM2Views] <http://www.w3.org/TR/DOM-Level-2-Views/> p.
> [DOM2CSS]   <http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-ViewCSS>
> [HTML5]     <http://www.w3.org/TR/html5/dom.html#the-document-object> pp.

Thank you for nice explanation. Also, method jsx.dom.getComputedStyle 
looks good.

>>>> var imgClassName = 'testimg';
>>>>
>>>> var tidyHTML = function (node) {
>>>>        var elms = node.childNodes,
>>>>            i = elms.length,
>>>>            text = '',
>>>>            elm;
>>>>
>>>>        if (!node.hasChildNodes()
>>>
>>> I have never used that method before.  Unless you are sure about its
>>> backwards-compatibility, you should replace the call with
>>
>> I use https://developer.mozilla.org/en-US/docs/DOM/Node.hasChildNodes
>> from long time. Sesms it's implemented long time ago. See:
>> http://www.quirksmode.org/dom/w3c_core.html
>
> It was *specified* a long time ago.  I rather do my own tests instead of
> relying on MDN or Quirks Mode.

Yes, many things can be specified, but not implemented. However, 
theoretically, we should check if there are exists all methods before 
using them. More over, they can work with a very different way that that 
is expected. Is not it already fall into an paranoid? I do not know.

>>>>        && (node.nodeName.toLowerCase() === 'img'
>>>> && !(new RegExp('(^|\\s)' + imgClassName +
>>>          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> '(\\s|$)')).test(node.className))) {
>>>     ^^^^^^^^^^^
>>> You should move or even generalize this code in order to leverage
>>> caching.
>>
>> Move new RegExp outside of method to do not creating new objects RegExp
>> everytime?
>
> Yes.

Sure. Will do this.

> My next idea is that you can globally cache references to RegExp instances
> that do not have the “global” flag set.  But it is perhaps not applicable
> here.
>
>>> You can do that because the RegExp does not have the “global” flag set
>     ^^^^^^^^^^^^^^^
> Meaning: “You can create the RegExp instance only once because …”

Yes. I thought about only once instance to save memory and more 
efficient running code.

>>> (i.e.,  its boolean ”global” property has the value “false”).
>>
>> Right. I should set "global" as "true".
>
> No, I did _not_ suggest that you should make that mistake:

>    var rx = /foo/g;
>    var s = "foo";
>
>    /* true */
>    rx.test(s)
>
>    /* false */
>    rx.test(s)
>
>    /* true */
>    rx.test(s)

Correct me if I am wrong: in fact boolean "global" should be false 
because I need to find at least one "class name". No need to find all of 
them. Except when I want to remove them.

[...]

>> Because sometimes I removing node.
>
> How does that explain the opposite direction of the concatenation?

I suppose it doesn't have to be opposite direction.

>>> Equivalent code:
>>>
>>>     var a = ["foo", "bar", "baz"];
>>>     var i = a.length;
>>>     var a2 = [];
>>>     while (i--)
>>>     {
>>>       if (a[i] != "bar")
>>>       {
>>>         a2.push(a[i]);
>>>       }
>>>     }
>>>
>>>     /* ["baz", "foo"] */
>>>     console.log(a2);
>>>
>>> You are looking for something more like
>>>
>>>     for (var i = 0, len = elms.length; i < len; ++i)
>>>     {
>>>       text += tidyHTML(elms[i]);
>>>     }
>>
>> Not really. In short: I want to remove all html nodes, except img with
>> specified class name + I need to care about formatting, eg. if text is
>> in block element then I apply <br/> after plain text.
>
> I am aware of that, but ISTM that you will still have to append/concatenate
> in the direction of the iteration or you will have the original content
> reduced *and* backwards.

Possible. Will try other ways also.

>>>>        }
>>>>
>>>>        if (typeof text !== 'undefined') {
>>>
>>> Again an unnecessary strict comparison.
>>
>> JSLint case.
>
> Learn how to configure it, or use a better tool.

I know that JSLint have an options, but sometimes you can not just turn 
it off, eg. when you working with group that accepted some rules.

>>>>            if (is_block_style(node) === 'block') {
>>>>                node.parentNode.insertBefore(document.createElement('br'),
>>>> node.nextSibling);
>>>>            }
>>>
>>> Why?  Usually it is misuse of the “br” element to use it as replacement
>>> for a block delimiter.  Also, “display: block” does not necessarily mean
>>> that there is a paragraph.  Consider, for example, positioned or floating
>>> block elements.
>>
>> Yes, I now saw the method getKomputedStyle from MyLibrary.
>
> JFTR: You are not posting the URI of code you are referring to either.

I run into my own trap. I asked about the same before you :-)

>> Unfortunately, it's quite complicated :/ I do not know about JSX similar
>> method.
>
> I seriously hope there is none.  What a bloat:
>
> <https://github.com/cinsoft/My-Library/blob/master/mylib.asp#L2329>

Yes. I also found it :-)

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

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


#18786

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-09 16:11 +0100
Message-ID<104841153.13fF9WP0Kf@PointedEars.de>
In reply to#18783
Cezary Tomczyk wrote:

> W dniu 2013-03-06 23:45, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
>>> W dniu 2013-03-06 00:03, Thomas 'PointedEars' Lahn pisze:
>>>> Cezary Tomczyk wrote:
>>>>> Here's the code:
>>>>>
>>>>> var is_block_style = function (el) {
>>>>>        var el_style;
>>>>>        if (window.getComputedStyle) {
>>>>
>>>> You should feature-test this method in a way that does not primarily
>>>> use implicit type conversion.  There is one DOM implementation, MSHTML,
>>>> that is notorious for throwing strange exceptions on properties of type
>>>> "unknown" otherwise.  See also, e.g., jsx.object.isHostMethod().
>>   ^^^^^^^^^                             ^^^^^^^^^^^^^^^^^^^^^^^^^
>>> Yes, I know that IE return sometimes "object", sometimes "function".
>>
>> More importantly, sometimes the result of the “typeof” operation is
>> “"unknown"” there (I hope the additional quotes make it clear now).  And
>> then a type-converting test throws an exception.  So a type-converting
>> test cannot be considered appropriate for feature-testing host object's
>> methods. It is insufficient for testing native object's methods already.
> 
> That's surprising me, I mean about "unknown". I never saw it before.

It has been common knowledge here and in de.comp.lang.javascript for about a 
decade now.  IIRC, I had first suggested using a “typeof” operation to tell 
callable and non-callable properties apart, isMethodType(), in 2003 CE.
[1, 2]  After I presented my suggestion on Usenet it turned out that certain 
host objects in MSHTML exhibited the aforementioned behavior with “typeof”, 
which led to the extension of isMethod().  Eventually, IIRC as suggested 
first by David Mark in what you could call a “library battle” (reference 
anyone?), it led to the use of a second string argument and the bracket 
property accessor syntax to prevent type conversion on "unknown" properties.  
From that point forward, isMethodType() was marked deprecated in favor of 
isMethod(). [3]

However, it became apparent that considering both host object properties and 
native methods in the same feature-test was rather inefficient and 
unnecessary, because when you want to feature-test a method you almost 
always know what kind of method you are testing for.  So, IIRC, again it was 
David who suggested using two methods for either case, isHostMethod() and 
isNativeMethod().  I had my doubts about that at first.

In parallel I had been continuing to improve isMethod() so that it could 
feature-test along a MemberExpression (for lack of a better term) [4], and
accepting a reference to an Array instance, several methods at once, 
eliminating the need for several calls with related features; the latter was 
suggested by kangax [5].  Eventually recognizing David's suggestion as 
necessary to be implemented in some cases (most notably event handling), the 
method now being properly namespaced as jsx.object.isMethod() was redesigned 
so that it could distinguish between those two cases, and a minimum 
jsx.object.isNativeMethod() was added to call it, reusing most of the 
existing code.  jsx.object.isHostMethod() and jsx.object.areHostMethods() 
became aliases for jsx.object.isMethod() then.

Curiously enough, I am now at a point where I see calling 
jsx.object.isNativeMethod() as computationally wasteful if the base object 
is known and there is only one property of it to test, and have begun to 
replace those calls with a simple “typeof” operation again.  This design 
decision was also supported by ECMAScript Edition 5 specifying in section  
11.4.3 that host objects MUST NOT yield any of the string values for native 
objects with “typeof”, except "function" if they are callable.

____________
[1] Earliest mention on Usenet available on Google Groups:
    <news:3FF99790.4060001@PointedEars.de>
    <https://groups.google.com/group/de.comp.lang.javascript/msg/9fa70f6407c8d3fc?dmode=source>    
[2] Earliest version on Usenet available on Google Groups:
    <news:40584264.6070500@PointedEars.de>    
    <https://groups.google.com/group/comp.lang.javascript/msg/6c1f50d6e339b802?dmode=source>
[3] <news:490EE64E.5000307@PointedEars.de>
    <https://groups.google.com/group/comp.lang.javascript/msg/40ce845814b9933c?dmode=source>
[4] <news:4A49E20B.3040608@PointedEars.de>
    <https://groups.google.com/group/comp.lang.javascript/msg/b56b53e651bf007f?dmode=source>
[5] <news:4A4BE96C.1020801@PointedEars.de>
    <https://groups.google.com/group/comp.lang.javascript/msg/b24a396bcaf24e75?dmode=source>
 
>>> jsx.object.isMethodType = function (s) {
>>    ^^^^^^^^^^^^^^^^^^^^^^^
>>>     return /^\s*(function|object|unknown)\s*$/i.test(s);
>>> };
>>
>> … and no; evidently the name of the method I mentioned is different.  The
>> actual method *actually* is too long to be posted here.  It can be found
>> in
>>
>> 
<http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fobject.js>
>>
>> which in turn can be easily found with a Web search.
> 
> isHostMethod is the same as isMethod, as I see:
> 
> jsx.object.isHostMethod = jsx.object.areHostMethods = jsx.object.isMethod;

Yes, see above.

>>> I do not see here
>>>
>> 
http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom.js
>>> method getComputedStyle.
>>
>> Because it requires *CSS* (D)OM capabilities.  For historical reasons it
>> is not available as jsx.dom.css.getComputedStyle(), though.
>>
>> 
<http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom%2Fcss.js>
>>
>> That, too, can be easily found with a Web search.
> 
> Would be nice to have same input search field to search through SVN files.

<http://lmgtfy.com/?q=getComputedStyle+site%3Apointedears.de>
 
> I found jsx.dom.getComputedStyle and seems it's code looks not so big.

Note the dependencies.
 
>>> * https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
>>
>> Keep in mind that this is a wiki.  Anyone logged in can write any
>> nonsense there.  And anyone logged in can correct it.  If they learn
>> about it.
> 
> "Anyone can write nonsense, anyone can correct it." - how to trust in
> that sources then? Hm...

Exactly.  However, you might be interested to know that I have recently 
migrated my MDN account to Mozilla Persona, so there is a chance that things 
are not as bad.

>> [why document.defaultView.getComputedStyle is to be preferred]
> 
> Thank you for nice explanation. Also, method jsx.dom.getComputedStyle 
> looks good.

You are welcome.  The trunk version might need to be updated, though, so 
that makes use of getPropertyValue() if available; it may also fix some 
bugs.  It appears to better to accept only CSS-style property names as 
arguments, and convert them to script-style ones only when necessary.
But I have to check use-cases and dependencies first.

BTW, the first version of that method appears to be available at 

<https://groups.google.com/group/comp.lang.javascript/msg/5e095a9d3a86353c?dmode=source&output=gplain> 

(which I found during isMethod() research; ironically that version already 
used getPropertyValue().)	

>>>>> var imgClassName = 'testimg';
>>>>>
>>>>> var tidyHTML = function (node) {
>>>>>        var elms = node.childNodes,
>>>>>            i = elms.length,
>>>>>            text = '',
>>>>>            elm;
>>>>>
>>>>>        if (!node.hasChildNodes()
>>>>
>>>> I have never used that method before.  Unless you are sure about its
>>>> backwards-compatibility, you should replace the call with
>>>
>>> I use https://developer.mozilla.org/en-US/docs/DOM/Node.hasChildNodes
>>> from long time. Sesms it's implemented long time ago. See:
>>> http://www.quirksmode.org/dom/w3c_core.html
>> It was *specified* a long time ago.  I rather do my own tests instead of
>> relying on MDN or Quirks Mode.
> 
> Yes, many things can be specified, but not implemented. However,
> theoretically, we should check if there are exists all methods before
> using them. More over, they can work with a very different way that that
> is expected.

You are preaching to the choir here.

> Is not it already fall into an paranoid? I do not know.

Parse error.

>>>> (i.e.,  its boolean ”global” property has the value “false”).
>>>
>>> Right. I should set "global" as "true".
>>
>> No, I did _not_ suggest that you should make that mistake:
> 
>>    var rx = /foo/g;
>>    var s = "foo";
>>
>>    /* true */
>>    rx.test(s)
>>
>>    /* false */
>>    rx.test(s)
>>
>>    /* true */
>>    rx.test(s)
> 
> Correct me if I am wrong: in fact boolean "global" should be false
> because I need to find at least one "class name". No need to find all of
> them. Except when I want to remove them.

Correct.  But more importantly, RegExp.protoype.test() should *never* be 
called on RegExp instances with the “global” flag set, because it wraps 
RegExp.prototype.exec().

> [...]
> 
>>> Because sometimes I removing node.
>>
>> How does that explain the opposite direction of the concatenation?
> 
> I suppose it doesn't have to be opposite direction.

It *must not* be in your case (unless you want the result to be backwards).  
“Opposite“ does not just mean “i--” here; it means ”i--” *and* “… += x[i]”, 
or “++i” *and* “… = x[i] + …”.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

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


#18751

FromDanny <dann90038@gmail.com>
Date2013-03-07 14:28 -0800
Message-ID<1986e356-3a1a-4fa8-b6a2-b358b3a2d6f2@googlegroups.com>
In reply to#18718
To Cezary Tomczyk

After checking in firebug/inspector(google chrome) with a few breakpoints and steps-into, it turns out that in the end you're hosing the IMGs on line 65, since createTextNode() only returns a text/plain string.  The 'undefined' string came out in the end, after a removeChild() [line 57], I didn't give much tracking to that, but I think it was just some inserted object in the iterated node.

Anyhow, I rewrote it some -> http://www.webdevout.net/test?02N&raw
using a DocumentFragment, prepending text and images, in case it helps

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


#18784

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2013-03-09 11:37 +0100
Message-ID<khf3dr$aro$2@speranza.aioe.org>
In reply to#18751
W dniu 2013-03-07 23:28, Danny pisze:
> To Cezary Tomczyk
>
> After checking in firebug/inspector(google chrome) with a few
> breakpoints and steps-into, it turns out that in the end you're
> hosing the IMGs on line 65, since createTextNode() only returns a
> text/plain string.  The 'undefined' string came out in the end, after
> a removeChild() [line 57], I didn't give much tracking to that, but I
> think it was just some inserted object in the iterated node.
>
> Anyhow, I rewrote it some -> http://www.webdevout.net/test?02N&raw
> using a DocumentFragment, prepending text and images, in case it
> helps

Looks not bad, thanks, but there is still empty nodes there. I will look 
more deeply in your code now.

By the way. Do test like this: try to create some simple text with MS 
Word, apply some formatting like bold, italic and underline. Copy it and 
paste into "div" element. Make a tidy up and look after all into source 
code. There is still empty nodes which I wanted to also remove. :/

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

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


#18788

Fromdann90038@gmail.com
Date2013-03-09 11:44 -0800
Message-ID<5003173b-d346-4beb-9bdf-ab0cb9e10efe@googlegroups.com>
In reply to#18784
To Cezary Tomczyk

well, the loop is supposed to remove all nodes that do not have any childNodes, which it does.  Bear in mind that, "\n       " or "    \n		" ARE childNodes of #text type, which in the loop when picked up as .nodeType === 3, will be prepended, so
--------------------------------------------
<p>Some test <span>paragraph</span></p>
        <!-- This is just an example of comment line -->
    </div>
</div>
--------------------------------------------

gives you a childNode after the </p>, then the #comment childNode, and then the "\n     " childNode.

Not sure what you're checking with, but give a shot to google-chrome Inspector or FF Firebug, set a breakpoint right after the variables assignment, then Step-Into from there for line-by-line execution, set a "Watch" on "text" and "elm.data", and you'll notice.  I'm assuming those might be the ones you're referring.

[toc] | [prev] | [standalone]


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


csiph-web