Not sure if this is a views bug or a core bug, but since I currently can't replicate it outside of views, I'm posting this in the views issue queue.
The problem is that when making multiple AJAX requests on a view page (paging, sorting, filtering), two things happen:
- Duplicate CSS imports are added, invalidly wrapped in divs (see https://skitch.com/duellj/rj63c/duplicate-css)
- View output gets deeply nested in blank divs (see https://skitch.com/duellj/rj64u/nested-divs). This could get insane if the user interacts with the ajax requests for some time
The offending code seems to be in core misc/ajax.js:
// We don't know what response.data contains: it might be a string of text
// without HTML, so don't rely on jQuery correctly iterpreting
// $(response.data) as new HTML rather than a CSS selector. Also, if
// response.data contains top-level text nodes, they get lost with either
// $(response.data) or $('<div></div>').replaceWith(response.data).
var new_content_wrapped = $('<div></div>').html(response.data);
var new_content = new_content_wrapped.contents();
// For legacy reasons, the effects processing code assumes that new_content
// consists of a single top-level element. Also, it has not been
// sufficiently tested whether attachBehaviors() can be successfully called
// with a context object that includes top-level text nodes. However, to
// give developers full control of the HTML appearing in the page, and to
// enable AJAX content to be inserted in places where DIV elements are not
// allowed (e.g., within TABLE, TR, and SPAN parents), we check if the new
// content satisfies the requirement of a single top-level element, and
// only use the container DIV created above when it doesn't. For more
// information, please see http://drupal.org/node/736066.
if (new_content.length != 1 || new_content.get(0).nodeType != 1) {
new_content = new_content_wrapped;
}
But I'm not sure if it's a core issue or if views is returning invalid response data.
Comments
Comment #1
merlinofchaos commentedUltimately, this is a core issue.
The problem is that it's still too aggressive about that div wrapper, and it causes problems with the methods I tend to use for javascript.
IMO we need at least 1 of 3 things:
1) The wrapping is simply never appropriate with replaceWith. For 'replace' method operations, we should automatically remove the wrapper.
2) We could send an optional 'wrap' command which defaults to true. This is a worst case solution that is the least invasive but IMO not the right solution.
3) We could consider unconditionally removing the wrapper. I don't see why it needs to be there; it's there initially to prevent Safari bugs, but once it's there, we should be able to safely and unconditionally remove it so that the HTML being inserted/replaced/added/whatevered is the HTML that was sent.
In fact, philosophically, #3 matters to me. It bugs me that this system is modifying the HTML. This is causing lots more than just this problem for me.
Comment #2
Michsk commented@#1: +1 #3
Comment #3
duellj commentedChanging title, since this issue isn't specifically with views.
I agree with merlinofchaos that #3 seems like the ideal solution. It's creating more problems then it's solving by modifying the HTML that is being sent via AJAX requests.
Comment #4
rfaySubscribe
Comment #5
droplet commentedSubscribe
Comment #6
gbelot2003 commentedSubscribe
Comment #7
theusualsuspect commentedIs there any solution-proposal or a patch available. Could I just hack core and remove it
thank you.
Comment #8
merlinofchaos commentedPeople who've commented like my solution #3 from comment #1; but no patch has been written.
Comment #9
nod_#1430688: Drupal.ajax appends additional stylesheet resources wrapped in div elements to the <head> element same issue.
Comment #10
nod_I think we should stop babysitting users. If they are using the insert command they should be inserting HTML, not textnodes or whatever. as for attachbehaviors if there are multiple top-level elements just pass the parent as context and that'll do it.
Comment #11
Jorrit commentedThe problem is that the following HTML is inserted:
<style type="text/css" media="all">@import url("http://../../...css");</style>\nThese are two DOM nodes: The style element and the
\ntext node. Theif (new_content.length != 1 || new_content.get(0).nodeType != 1) {check in ajax.js (line 502) fails to unwrap the wrapped content because of this. If the HTML were stripped of the last \n before being wrapped, the<div>would never be inserted in the<head>, I think.Comment #12
nod_