thaolt / phpquery

Automatically exported from code.google.com/p/phpquery
0 stars 0 forks source link

table DOM doesn't match browser? #100

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
On a page which contains a table, Firefox will add a TBODY element, but
phpQuery does not. This can cause issues when using direct child selectors,
because a selector which works in jQuery may not work in phpQuery, and vice
versa.

For example:
  <table>
    <tr>
      <td>Foo</td>
    </tr>
  </table>

Selector: table>tr>td

Works in phpQuery, but not in jQuery (in Firefox for sure, haven't tested
other browsers yet). With jQuery/Firefox, you must explicitly include the
TBODY element:

Selector: table>tbody>tr>td

This was with phpQuery 0.9.5 beta4

Original issue reported on code.google.com by dougal.c...@gmail.com on 10 Feb 2009 at 8:33

GoogleCodeExporter commented 9 years ago

Original comment by tobiasz....@gmail.com on 11 Feb 2009 at 12:11

GoogleCodeExporter commented 9 years ago
I'm not sure that's the true way to do it... phpQuery is working on a giving DOM
which have a DOC TYPE, in this DOC TYPE it's explicitely say if we need a TBODY 
in
the table... or not.
Firefox modify the DOM to get it working well according to it DOC TYPE... but 
isn't
to the author to do his DOM on the good way first ?

I don't agree with the idea that phpQuery will modify the DOM it self... jQuery 
don't.

Firefox is to jQuery what PHP is to phpQuery... PHP doesn't modify the DOM...

That's just my opinion about that.

Original comment by nicolas....@gmail.com on 11 Feb 2009 at 9:15

GoogleCodeExporter commented 9 years ago
The document in question did not explicitly declare a DOCTYPE (and should 
probably be
considered "tag soup"). My searches seemed to give conflicting info about 
whether
TBODY is required or not, and I haven't had a chance to double-check the DOM 
spec
itself. So, I'm not sure what the "correct" behavior should be, or if we just 
have to
chalk this up as a "browser incompatibility".

But I can say that it made it difficult for me to track down why my selectors 
weren't
working :)

Original comment by dougal.c...@gmail.com on 11 Feb 2009 at 4:05

GoogleCodeExporter commented 9 years ago
Hmmm, I found this discussion:

  http://www.codingforums.com/archive/index.php/t-38596.html

In particular, the last few comments, starting with liorean and lorax1284 both 
state
that in HTML4.01, the TBODY element is required, and browsers should explicitly
insert it into the DOM model, even if not present in the source.

Original comment by dougal.c...@gmail.com on 11 Feb 2009 at 4:21

GoogleCodeExporter commented 9 years ago
Thanks dougal for your source.
You're right, the browser should insert tbody.

But phpQuery should to insert it too ?
I keep thinking no.

But am I true ? Not sure...

Original comment by nicolas....@gmail.com on 12 Feb 2009 at 8:23

GoogleCodeExporter commented 9 years ago
Okay, it's not completely straightforward, but I'm thinking that
DOMDocumentWrapper.php is our browser in this case, and it should do what the 
specs say.

Now, what do the specs say? For HTML4 DOM, they say that TBODY is required in 
the DOM
model, even though it's optional in the content model (an SGML feature). For 
XHTML,
they say to follow HTML conventions for content served as 'text/html', and to 
follow
XML conventions for content served with an XML content-type (i.e., the DOM 
mirrors
the content model, so don't add a missing tbody):

  http://www.w3.org/TR/2002/REC-xhtml1-20020801/#C_11

So, it's all clear as mud, right? :)

In my test case, it should be defaulting to HTML4.01 anyways, so the HTML vs 
XHTML
(vs Content-type) question wouldn't be an issue.

Original comment by dougal.c...@gmail.com on 12 Feb 2009 at 2:52

GoogleCodeExporter commented 9 years ago
I think such functionality should be implemented in a way it has to be 
explicitly
turned on to work. At least at the beginning. 

I see best place for this in plugin called such as BrowserCompatibility, which 
would
be set of rules imitating specific browser. For tbody code would be as follows:

$doc->bind('DOMNodeInserted', 'everyTableHaveTbody');
function everyTableHaveTbody($e) {  
  pq($e->target->ownerDocument)  
    ->find('table')  
      // nested closure should be here  
      ->each('everyTableHaveTbodyCallback');
}
function everyTableHaveTbodyCallback($table) {  
  if (pq('> tbody', $table)->length == 0)  
    pq($table)->contents()->wrapAll('<tbody>');  
}

To get it working you need branches/dev version of phpQuery with support for 
Mutation
Events (0.9.5 RC wont work).

Original comment by tobiasz....@gmail.com on 16 Feb 2009 at 5:18

GoogleCodeExporter commented 9 years ago
I forgot about content loaded with document ;) This would be:

->bind('load', 'everyTableHaveTbody')->trigger('load');

Original comment by tobiasz....@gmail.com on 19 Feb 2009 at 11:13