Summary: | Javascript popups at www.ensembl.org show up at wrong positions | ||
---|---|---|---|
Product: | [Applications] konqueror | Reporter: | Harm van Bakel <hvbakel> |
Component: | khtml ecma | Assignee: | Konqueror Developers <konq-bugs> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | maksim |
Priority: | NOR | ||
Version: | 3.5 | ||
Target Milestone: | --- | ||
Platform: | Ubuntu | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
patch
patch #2 |
Description
Harm van Bakel
2005-11-27 21:21:18 UTC
Hmm, the reason this happens is that scrollTop is always(?) 0 in gecko in strict mode. Gonna need to test IE, though. quirksmode.org as a quite thorough analysis on those viewport properties along with nice test pages strict/loose. Very scary. It seems we'd need to turn some on/off and from a place to another according to doctype to keep scripts such as this one happy ;( I have a reasonably simple patch for this, which is imperfect, though. Will attach, along with summary of my testing. To make things worse, IE and Mozilla are inconsistent here. Created attachment 15043 [details]
patch
Basically, this removes special body path for scroll*, and instead makes the
generic path in quirks mode forward body to root.
Ugh. And now I notice that somehow scrollTop not longer works as I wished it to do in quirks. Double-checking Created attachment 15044 [details]
patch #2
A bit better, but still sucks. This also fixes #86794, by the way.
Here are my test results, with patch: quirks mode: scrollTop: IE: position on body, 0 on documentElement Mozilla: position on body, 0 on documentElement Konqueror: position on both scrollHeight: IE: document height on body, viewport height on documentElement! Mozilla: document height on both Konqueror: document height on both clientHeight: IE: viewport height (minus something) on body, 0 on documentElement! Mozilla: viewport height on body, 0 on documentElement! Konqueror: viewport height on body, document height on documentElement offsetHeight: Mozilla: height of element on both! IE: viewport height on both! Konqueror: viewport height on body, document height on documentElement strict mode: scrollTop: IE: 0 on body, position on documentElement Mozilla: 0 on body, position on documentElement Konqueror: 0 on body, position on documentElement scrollHeight: IE, Mozilla, Konq: scrollHeight of the appropriate element clientHeight: IE, Mozilla: body: height of the body element documentElement: viewport height!!! Konq: height of the element on both! (BUG?) offsetHeight: IE: on body: height of the body element documentElement: viewport height! Mozilla: height of the appropriate element Konq: height of the appropriate element hmm, it may be cleanest to make offsetHeight and clientHeight on root to return viewport height (just like scrollHeight does in quirks mode), and to always forward body to root in quirks. This will make us match IE, modulo not returning 0 for some things in quirks. re #8: agreed... and I think it's even a sane behavior, as the dom spec failed to provide real means of accessing the viewport. If not asking the root, then who else? Otherwise, how would that affect our Mozilla compatibility? SVN commit 561392 by orlovich: Improve the compatibility of our scrollTop/Left/Height/Width, offsetWidth/offsetHeight,clientWidth/clientHeight on body and the root element. These aren't quite perfectly compatible, but should be clearly better... This fixes core of #86794, #117163, and #130577 (amazon.com book reader --- though error reporting popups seem to mess that up a bit(!?)) CCBUG:86794 BUG:117163 BUG:130577 M +46 -0 kjs_dom.cpp M +0 -33 kjs_html.cpp M +1 -2 kjs_html.h --- branches/KDE/3.5/kdelibs/khtml/ecma/kjs_dom.cpp #561391:561392 @@ -182,6 +182,46 @@ return DOMObjectLookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this); } +static khtml::RenderObject* handleBodyRootQuirk(const DOM::Node& node, khtml::RenderObject* rend, int token) +{ + //This emulates the quirks of various height/width properties on the viewport and root. Note that it + //is (mostly) IE-compatible in quirks, and mozilla-compatible in strict. + if (!rend) return 0; + + bool quirksMode = rend->style() && rend->style()->htmlHacks(); + + //There are a couple quirks here. One is that in quirks mode body is always forwarded to root... + //This is relevant for even the scrollTop/scrollLeft type properties. + if (quirksMode && node.handle()->id() == ID_BODY) { + while (rend->parent() && !rend->isRoot()) + rend = rend->parent(); + } + + //Also, some properties of the root are really done in terms of the viewport. + //These are {offset/client}{Height/Width}. The offset versions do it only in + //quirks mode, the client always. + if (!rend->isRoot()) return rend; //Don't care about non-root things here! + bool needViewport = false; + + switch (token) { + case DOMNode::OffsetHeight: + case DOMNode::OffsetWidth: + needViewport = quirksMode; + break; + case DOMNode::ClientHeight: + case DOMNode::ClientWidth: + needViewport = true; + break; + } + + if (needViewport) { + //Scan up to find the new target + while (rend->parent()) + rend = rend->parent(); + } + return rend; +} + Value DOMNode::getValueProperty(ExecState *exec, int token) const { switch (token) { @@ -287,6 +327,9 @@ khtml::RenderObject *rend = node.handle()->renderer(); + //In quirks mode, may need to forward if to body. + rend = handleBodyRootQuirk(node, rend, token); + switch (token) { case OffsetLeft: return rend ? static_cast<Value>( Number( rend->offsetLeft() ) ) : Undefined(); @@ -427,6 +470,9 @@ khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L; + //In quirks mode, may need to forward. + rend = handleBodyRootQuirk(node, rend, token); + switch (token) { case ScrollLeft: if (rend && rend->layer()) { --- branches/KDE/3.5/kdelibs/khtml/ecma/kjs_html.cpp #561391:561392 @@ -676,10 +676,6 @@ text KJS::HTMLElement::BodyText DontDelete vLink KJS::HTMLElement::BodyVLink DontDelete # IE extension - scrollLeft KJS::HTMLElement::BodyScrollLeft DontDelete - scrollTop KJS::HTMLElement::BodyScrollTop DontDelete - scrollWidth KJS::HTMLElement::BodyScrollWidth DontDelete|ReadOnly - scrollHeight KJS::HTMLElement::BodyScrollHeight DontDelete|ReadOnly onload KJS::HTMLElement::BodyOnLoad DontDelete @end @begin HTMLFormElementTable 11 @@ -1257,20 +1253,6 @@ Value nodeValue(kjsDocNode); return kjsDocNode->getListener( DOM::EventImpl::LOAD_EVENT ); } - default: - // Update the document's layout before we compute these attributes. - DOM::DocumentImpl* docimpl = node.handle()->getDocument(); - if (docimpl) - docimpl->updateLayout(); - - switch( token ) { - case BodyScrollLeft: - return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsX() : 0); - case BodyScrollTop: - return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsY() : 0); - case BodyScrollHeight: return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsHeight() : 0); - case BodyScrollWidth: return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsWidth() : 0); - } } } break; @@ -2487,21 +2469,6 @@ case BodyLink: { body.setLink(str); return; } case BodyText: { body.setText(str); return; } case BodyVLink: { body.setVLink(str); return; } - case BodyScrollLeft: - case BodyScrollTop: { - QScrollView* sview = body.ownerDocument().view(); - if (sview) { - // Update the document's layout before we compute these attributes. - DOM::DocumentImpl* docimpl = body.handle()->getDocument(); - if (docimpl) - docimpl->updateLayout(); - if (token == BodyScrollLeft) - sview->setContentsPos(value.toInteger(exec), sview->contentsY()); - else - sview->setContentsPos(sview->contentsX(), value.toInteger(exec)); - } - return; - } case BodyOnLoad: DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(node.ownerDocument().handle()); if (doc && checkNodeSecurity(exec, node)) --- branches/KDE/3.5/kdelibs/khtml/ecma/kjs_html.h #561391:561392 @@ -84,8 +84,7 @@ LinkSheet, TitleText, MetaName, MetaHttpEquiv, MetaContent, MetaScheme, BaseHref, BaseTarget, IsIndexForm, IsIndexPrompt, StyleDisabled, StyleSheet, StyleType, StyleMedia, BodyBackground, BodyVLink, BodyText, - BodyLink, BodyALink, BodyBgColor, BodyScrollLeft, BodyScrollTop, - BodyScrollHeight, BodyScrollWidth, BodyOnLoad, + BodyLink, BodyALink, BodyBgColor, BodyOnLoad, FormAction, FormEncType, FormElements, FormLength, FormAcceptCharset, FormReset, FormTarget, FormName, FormMethod, FormSubmit, SelectAdd, SelectTabIndex, SelectValue, SelectSelectedIndex, SelectLength, |