
It currently isn't possible to have multiple position:fixed elements (like toolbar, from now on read displaced elements) on a page.
I've tried to come up with a generic approach for displaced elements.
Advantages of this generic approach:
- It prevents multiple displaced elements from overlapping each other and it automaticly sets the padding-top on document.body.
- It also removes the requirement of Drupal.settings.tableHeaderOffset (which also was badly implemented; only one callback was possible).
- Calculated displacement height can be reused (currently by tableheader.js and overlay-parent.js)
Comment | File | Size | Author |
---|---|---|---|
#90 | snapshot1.png | 87.11 KB | mgifford |
#90 | snapshot2.png | 93.59 KB | mgifford |
#88 | drupal.displace.88.patch | 30.36 KB | sun |
#80 | 787940-80-displace.patch | 16.51 KB | mgifford |
#74 | displace-qunit.zip | 54.05 KB | kiphaas7 |
Comments
Comment #1
kiphaas7 CreditAttribution: kiphaas7 commentedsub, and postponing #787670: Clean up tableheader.js untill this lands (or not).
Comment #2
sunSee also #428844: Use JS to adjust layout (a fix for all margin/absolute/background problems)
Comment #3
casey CreditAttribution: casey commentedImproved displace.js
Comment #4
casey CreditAttribution: casey commentedOops some whitespace and an undefined var.
Comment #5
casey CreditAttribution: casey commentedComment #6
casey CreditAttribution: casey commented- Replaced IE6 CSS hack for a JS support test for position:fixed.
- Added file comment to displace.js
Comment #7
casey CreditAttribution: casey commentedComment #8
dries CreditAttribution: dries commentedHas this been tested on all browsers?
Comment #9
kiphaas7 CreditAttribution: kiphaas7 commentedEither the comment is wrong, or the triggerHandler should be namespaced again...
Comment #10
casey CreditAttribution: casey commentedMost of what is available for windows (IE6-IE8, FF2, FF3, FF3.6, Opera10, Safari4, Chrome4)
Comment #11
casey CreditAttribution: casey commentedChanged comment:
Comment #12
aspilicious CreditAttribution: aspilicious commentedYes Dries I used this patch together with #668640: Overlay shouldn't be based on jQuery UI Dialog to test them together.
I tested in a lot of browsers.
Comment #13
dries CreditAttribution: dries commentedOK, committed this to CVS HEAD. Thanks. Hopefully that will allow us to make progress on some other bugs.
Comment #14
kiphaas7 CreditAttribution: kiphaas7 commentedYay! That should indeed make things easier, thanks casey!
Found some minor typos:
Fixed positioning (CSS declaration position:fixed) is done relatively to the
Should be relative?
// Test for position:fixed support as IE6 does not.
In the doc above, there was already a section about position fixed support and how IE6 does not support it properly. Also, "as IE6 does not" comes off a bit weird to me. I'd change it to:
// Test for position:fixed support.
var el = $('<div style="position:fixed;top:10px"/>').appendTo(document.body);
Needs spacing to enhance readability and coding standards?
var el = $('<div style="position:fixed; top:10px" />').appendTo(document.body);
Attached patch changes the above mentioned issues.
Comment #15
kiphaas7 CreditAttribution: kiphaas7 commentedFound another typo (overriden -> overridden) and moved the fixed support test to the main drupal.js file. This way the test is available for all scripts (like tableheader.js, which is duplicating the test found here).
The code doc needs some review, not entirely sure if I used the right syntax. Also, I used a rather verbose syntax for the variable positionFixedSupported, but that is because it is namespaced under the main drupal object, and I want to avoid conflicts.
Comment #16
casey CreditAttribution: casey commentedI agree on #15 if you replace function name to positionFixedSupported() and the variable to _positionFixedSupported.
Comment #17
kiphaas7 CreditAttribution: kiphaas7 commentedAgreed, it is an internal variable.
Comment #18
kiphaas7 CreditAttribution: kiphaas7 commentedDoc changes as discussed with casey on irc.
Comment #19
casey CreditAttribution: casey commentedRTBC when green.
Comment #20
jbrown CreditAttribution: jbrown commentedToggling the shortcut bar on the modules page now takes several seconds and jumps back to the top of the page.
Comment #21
casey CreditAttribution: casey commented@jbrown which browser/OS are you using?
Comment #22
jbrown CreditAttribution: jbrown commentedActually, it is reloading the page when I toggle on the modules page - it doesn't do this on other pages.
Behaves like this with Firefox 3.6.3 & Chrome
Comment #23
kiphaas7 CreditAttribution: kiphaas7 commentedDo you have firebug installed for firefox? If so, please open firebug, reload the page, and watch for any errors in the console.
I can't reproduce this on windows /firefox 3.6.3.
Comment #24
jbrown CreditAttribution: jbrown commentedYes - on the modules page I get
but it doesn't provide any further information.
Comment #25
casey CreditAttribution: casey commented#20
Ahh. Well, before toolbar module added a fixed padding-top to body in toolbar.css (which wasn't always correct, and also didn't allow other position:fixed elements. Now the padding-top is calculated by Javascript. This calculation is done in a Drupal.behaviour which are called when $(document).ready(). For large pages like the module page it might take some time before their DOM is fully loaded (may differ per PC/browser/etc).
We could put the fixed padding back into toolbar.css, because it is overriden by displace.js anyway. But then again, what to do when there are other position:fixed elements?
#24
The error is caused by a wrong patch in #535966: add ":target" to selector for removing "collapsed" class. issue contains a new patch.
@Dries/webchick: patch in #18 is still RTBC
Comment #26
dries CreditAttribution: dries commentedCommitted to CVS HEAD. Thanks.
Comment #27
sunum, I'm a bit baffled that this patch went in without any in-depth code review...
I kindly ask to roll back the already committed patch, so we can redo a proper and solid patch here.
The first patch contained some questionable lines. This (second) one at minimum:
should pre-check + conditonally initialize jQuery.support.positionFixed -- this is jQuery 1.4, friends :)
80 critical left. Go review some!
Comment #28
casey CreditAttribution: casey commented@sun,
I actually like to add some more code to displace.js: #800270: Anchor/focus hidden beneath toolbar/tableheader (CKEditor full screen menu).
Besides that I also found out that admin_menu allows configuring the positioning of its toolbar (fixed or absolute). To make displace.js useable for modules like admin_menu (see #801526: Use misc/displace.js to position admin_menu), I'd like to add support for both absolute and fixed positioned elements. Attached patch does this.
There are other usecases for displace.js like the theming-bar of drupalgardens or toolbars provided by modules like devel. Displace.js is useful because it makes that other modules don't need to include this code and instead just have to add the class "displace-top" or "displace-bottom". It also provides an api to find out these displacements and use them consistently in those modules but also scripts like tableheader.js and overlay.
I included code of #800270: Anchor/focus hidden beneath toolbar/tableheader (CKEditor full screen menu) into this patch because it needed to be rearranged.
I like your suggestion of replacing Drupal.positionFixedSupported with $.support.positionFixed (it is even be suggested at jquery.com http://api.jquery.com/jQuery.support/#comment-44249686) and included it in attached patch also.
Comment #29
sunI understand. But still. This code went into Drupal core without ANY technical review. That's totally not acceptable at this stage of the cycle.
I'm not saying that it cannot be done and committed for D7. But look: We have no target for reviewing now (3 separate patches), and any change request we're doing now is going to be treated like an API change, since this code was already committed. I do not have the time nor energy to review and clean-up all patches next to the already committed code, while constantly having to inter-diff all these targets.
Therefore, let's roll back this entire thing first. Then, roll a new + complete patch, and properly review that to get this done, please.
What follows is a review of the latest patch, but in reality, I have much more to criticize on the first original code, which has been partially changed in the meantime.
Description in @return can be moved into docblock summary.
@see can be removed.
$.support.X are properties, not functions. Please have a look at jQuery's source code to see how $.support implementations are done.
Additionally, we should move this code to the bottom of drupal.js, but before any procedural code starts in the file. It is very likely that we will add further $.support properties in the future.
We do not need to repeat the -top and -bottom classes from the preceding paragraph.
I had to look up the actual code to understand what this paragraph is trying to tell me.
"mixed" is a very poor property name.
It's weird that absolute and fixed are applied in parallel. Makes no sense for me.
So what's the difference between absolute and unsupported?
80 critical left. Go review some!
Comment #30
casey CreditAttribution: casey commentedI understand your objections and even agree it shouldn't really went in without any technical review. But as it did and it is functional code (second patch only adds functionality) and don't agree on the rollback. There is currently only one patch to be reviewed; attached here.
Anyway, I changed jQuery.support.positionFixed, updated the comments and replaced "mixed" with "mixedDisplacement".
I added the following documentation:
The class diplace-unsupported is used as fallback. I also tried to improve the documentation on this class a bit.
Comment #31
casey CreditAttribution: casey commentedWhoops, I should've checked that patch;
- Prefixed internal Drupal.displace variables with a "_" (replacing "mixed" with "mixedDisplacement" collided with function mixedDisplacement)
- Moved jQuery.support.positionFixed into $(function () { ... }); as it need document to be ready.
Comment #32
sunNow you're doing exactly what I explained: Defending the already committed code and pointing me to this last follow-up patch instead. While my focus starts reversed; instead of doing countless of follow-up patches and inter-diff reviews, we want to ensure a properly reviewed and agreed on technical implementation in the first place.
Attached patch reverts the first and second patch.
Afterwards, we can apply this patch reversed, plus the patch from #30, and, review the entire implementation.
Comment #33
casey CreditAttribution: casey commentedOk.
Comment #34
dries CreditAttribution: dries commentedI don't understand why we wouldn't be able to improve the already committed code with follow-up patches? I don't mind rolling back the patch but I'm puzzled by the 'why'.
Comment #35
casey CreditAttribution: casey commentedAs I think this code is useful to make things like toolbars and tableheaders work together properly, I like the quickest way to result. If rolling the patch back and reviewing it as one patch is easier/quicker I am okay with it.
Comment #36
casey CreditAttribution: casey commentedJust so I don't lose this change; add paddingTop/paddingBottom to HTML element instead of BODY so background-image of body moves along correctly (thanks to SteveK in #801752: change padding to margin and apply to html instead of body).
Feel free to do the rollback-first-review-later first.
Comment #37
casey CreditAttribution: casey commentedComment #38
casey CreditAttribution: casey commentedI think it covers it all now. It is however 300 lines of code... worth it?
Pro
Cons
Comment #39
sunThat's what we need to discuss and review in detail, but in total. Therefore, rollback first, proper reviews afterwards.
Again, the committed code had _zero_ technical reviews. Not even an agreement on the overall approach to begin with.
The status went from "needs review" to "fixed". We obviously missed some stages here.
Comment #40
casey CreditAttribution: casey commented@Dries, could you commit rollback patch of #32? I mean, if that's the way to get this issue somewhere, I am happy to reroll a full patch afterward.
Comment #41
dries CreditAttribution: dries commentedRolled back from CVS HEAD using the patch in #32.
Comment #42
casey CreditAttribution: casey commenteddisplace.js needs to be removed too.
Comment #43
casey CreditAttribution: casey commentedComment #44
dries CreditAttribution: dries commentedRolled back displace.js too.
Comment #45
casey CreditAttribution: casey commentedFull reroll + a page to test the script.
Comment #46
aspilicious CreditAttribution: aspilicious commentedFocussing
trailing white space
77 critical left. Go review some!
Comment #47
casey CreditAttribution: casey commentedFocussing? If you mean instead of Focusin, then see http://api.jquery.com/focusin/
Comment #48
aspilicious CreditAttribution: aspilicious commentedThnx for the link...
I was wrong
Comment #49
casey CreditAttribution: casey commentedRemoved trailing whitespace and added some more comments.
Comment #50
seutje CreditAttribution: seutje commentedinteresting approach, seems a lot more workable than all those 1-off solutions
will try to play around with this some more
Comment #51
aspilicious CreditAttribution: aspilicious commentedWe need sun's blessing before this can get commited
Comment #52
dries CreditAttribution: dries commentedWould love to get sun's take too.
Comment #53
casey CreditAttribution: casey commentedI found out that adjusting the HTML element (which makes that BODY element's top position is not equal to window's top position) won't work when using jQuery UI draggables; they get positioned according to BODY's top position, but that's not where the mouse is.
I believe this is actually a jQuery UI (probably jquery.ui.position.js or jquery.ui.draggable.js) bug. I don't think this is fixable (cross-browser) in displace.js.
Another solution for adjusting the background-image might be something like is suggested in #428844: Use JS to adjust layout (a fix for all margin/absolute/background problems), but that is no solution for absolute positioned elements (with offsetParent body; see my test of #45) so they will fall beneath any toolbars.
Anyway, I don't have much time for the next two weeks.
Comment #54
casey CreditAttribution: casey commentedAdded a dialog to the test page to show what is going wrong; try dragging it.
Comment #55
casey CreditAttribution: casey commentedjQuery UI #4438: Helper is in the wrong position when body has position: relative and an offset relative to the document. That ticket unfortunately has a won't fix. So adjusting BODY's position is not an option.
Using a wrapper as suggested in that ticket's comments might be a solution, although I am not sure if this has side-effects for other scripts.
Comment #56
sunDid I understand the most recent follow-ups correctly, in that this entire, current displace.js approach and patch did not work out like it should have? (due to an issue in jQuery UI?)
Comment #57
casey CreditAttribution: casey commentedNah I still think we need a generic approach. Displace.js does the job.
It doesn't however adjust the position of any background-image of the body element and any absolutely positioned elements (with body as offsetParent). I tried to fix this by positioning body relative and preventing document/body collapsing. This doesn't work in combination with Jquery UI however (jQuery UI ignores any offset set to the body element).
I think we can fix this adjustment of background-image and absolutely positioned elements using the approach suggested in #428844: Use JS to adjust layout (a fix for all margin/absolute/background problems). In attached patch I skipped this however.
I did include a solution for jQuery UI's draggables (dialogs too).
I included the patch of #787670: Clean up tableheader.js. It would be nice if that one is being reviewed/committed first so the size of this patch decreases a bit.
Screen capture to show what this is all about:
http://www.screencast.com/users/caseyn/folders/Jing/media/c4e9c2b4-c3db-...
Comment #58
casey CreditAttribution: casey commentedComment #59
aspilicious CreditAttribution: aspilicious commentedI need this patch If I wonna use media module in overlay...
Seriously...
Comment #60
sunSorry, just a useless follow-up for now -- webchick bumped #655416: "Demonstrate block regions" bugs with regions, navigation, overlay to critical, so this is a major bug at the very least.
Will try to do a in-depth review ASAP.
Comment #61
casey CreditAttribution: casey commentedBugfix + code cleanups.
Comment #62
james.elliott CreditAttribution: james.elliott commentedThe patch looks really good. One minor quibble. With JS turned off I lose the box shadow on the toolbar. The box shadow attributes shouldn't be part of .displace-processed #toolbar, they need to stay with #toolbar so they show with or without JS turned on.
Comment #63
casey CreditAttribution: casey commented- Chasing HEAD.
- Split focus movement detection into a separate object (displace.js).
- Some code improvements.
- Dropped "overlay-displace-$region" classes in favor of "displace-$region" classes.
@james.elliott, thats not really possible. Currently we just positioned toolbar fixed and altered the body margin accordingly. When all displaced elements would do so they all would overlap each other.
This patch keeps all those elements on their original location (position:relative) until Javascript kicks in. I think this is the only way to get a nice gracefully degrading solution.
To get box-shadow over the full width of the toolbar we set a padding. Using a negative margin the width is corrected so we don't get a vertical scrollbar. This however only works with position:absolute/fixed.
We could remove the padding/margin, but In FF (and <Safari4) box-shadow on a full-width element with position:relative also causes an vertical scrollbar.
http://css.2040035.n2.nabble.com/moz-box-shadow-td4450208.html
http://placenamehere.com/article/372/CSS3TrialsBoxShadowAndMore (header: Creating a full width drop shadow)
We could use an toolbar-wrapper with overflow:hidden, but I don't like this for just some shadow and only in case Javascript is disabled. A degrading solution seems nicer to me.
Any other ideas?
Comment #64
jacineThe CSS that is currently in system.css belongs in system-behavior.css. Also, it would be helpful to document (briefly) why and where this code is being used, rather than just having " To be used with displace.js."
Comment #65
tim.plunkettRerolled against HEAD, moving the CSS to system-behavior.css. I replaced "To be used with displace.js." with "Displace position: fixed elements.", which isn't much better. Eek.
Getting this in will allow #888412: Make footer stick to the bottom of the page to work, which would be awesome.
Comment #66
kiphaas7 CreditAttribution: kiphaas7 commentedhttp://stackoverflow.com/questions/1702399/how-can-i-force-reflow-after-...
http://stackoverflow.com/questions/510213/when-does-reflow-happen-in-a-d...
I'd prefer to call .className instead of calling the jQuery wrapper functions addClass and removeClass, since this is a bugfix for IE7, and we know exactly what we want to do (force a reflow, nothing fancy with adding a class or removing a class). I haven't tested this myself, but according to the first link it should work.
Yes it should be fast(er), and yes, it is a micro optimization. But also, it's a bit cleaner code-wise since there is no extra redundant class necessary.
http://stackoverflow.com/questions/693719/javascript-performance-of-clas...
lastly, the doc line doesn't really tell why you're adding/removing a class. Something along the lines of:
Would be more descriptive, regardless of my proposed micro change.
Comment #67
aspilicious CreditAttribution: aspilicious commentedTo help things moving, rerolled with suggestions.
Comment #68
kiphaas7 CreditAttribution: kiphaas7 commentedI didn't roll because I didn't test it. I still haven't tested it (no time for it), so it still needs a review. Or did you test it aspilicious?
Thanks for rolling!
Comment #69
aspilicious CreditAttribution: aspilicious commentedNop I didn't I just rerolled :)
Comment #70
casey CreditAttribution: casey commentedI still think we need this, especially for #800270: Anchor/focus hidden beneath toolbar/tableheader (CKEditor full screen menu) (usability/accessibility). I have been working on a even more abstract/generic jquery plugin but it's far from ready and D7 release is closing fast, so I think we should stick to this patch.
We need testers...
Comment #71
seutje CreditAttribution: seutje commentedsmall testcase for Kiphaas7's micro-optimization -> http://jsperf.com/reflow-trigger
Comment #72
kiphaas7 CreditAttribution: kiphaas7 commentedBikeshedding probably, but I got excited when I saw jsperf.com. (Thanks for the link seutje! :) ).
The entire modified code should be included, since jQuery does benefit from chaining.
http://jsperf.com/reflow-trigger/4
Comment #73
kiphaas7 CreditAttribution: kiphaas7 commentedI've started writing some tests in qUnit for displace.js. Will try to post a .zip file with a first working draft tomorrow.
Comment #74
kiphaas7 CreditAttribution: kiphaas7 commentedJust a beginning, first few functions have limited test coverage. If anyone else has time to add tests, please do! I probably won't have enough time to finish it by myself. If you see faults in my tests, please improve them, it's my first time writing tests for jQuery code :).
Comment #75
carlos8f CreditAttribution: carlos8f commentedCan anyone summarize, in non-js-ninja language, what this patch accomplishes?
And secondly, should we mark any of these duplicates or postponed on this issue:
#546126: Toolbar interferes with anchor links
#567754: Wrong anchor adjustment in tableheader.js
#800270: Anchor/focus hidden beneath toolbar/tableheader (CKEditor full screen menu)
Comment #76
james.elliott CreditAttribution: james.elliott commentedThe patch adds a generic (read reusable) solution to placing fixed positioned elements on the page without having them overlap each other or the content on the page.
This means that if I develop an awesome banner module that keeps a banner docked on the top of the screen, I can use this displacement behavior to guarantee that it won't overlap the content at the top of the page. I also don't have to worry about special cases like the presence of the admin toolbar or the shortcut bar while I'm developing my module.
This needs a reroll as the patch no longer applies cleanly.
Comment #77
mgifford#67: 787940-67-displace.patch queued for re-testing.
Comment #79
webchickGiven that this was already committed in some form already, and given that the lack of a fix here exposes several pretty nasty user-facing bugs, I'd still like to get this into D7, assuming it's done by RC1.
Comment #80
mgiffordWell, this patch applies, but it really messes up the Skip to Main stuff.
Can we get someone to review the patch, fix the Skip to Main problem & then document how to thoroughly test it so we can get this RTBC before RC1?
Comment #82
mgiffordI can't really take this any further. I wanted the patch to be able to apply to core, but this needs a CSS/JS guy and that's not me..
@james.elliott - do you have some test code for this?
@aspilicious - can you look over my patch which is based on yours and see what I may have missed. So much has changed.
@tim.plunkett - your patch did get by the bots. Can you look to find ways to get this patch through the bots now?
@casey - how do we make this work, particularly with the skip to main? How close is this patch to what you see as needed now?
I can apply patches to my sandbox and do some testing, particularly against accessibility issues.
Comment #83
aspilicious CreditAttribution: aspilicious commentedI only rerolled it :).
Can't fix this, I'm srry.
Comment #84
tim.plunkettI only rerolled as well, but I'll take a look at it this week.
Comment #85
sunGoing to put this into my list. However, not sure whether I'll be able to work on it before the weekend, so feel free to beat me to it (assign to yourself first).
Comment #86
sunok, tried to move forward here, but serious problem:
All of the re-rolled patches in #63, #65, #67, #80 are entirely different. Some are missing displace* files, some are missing changes to Overlay, and some missing changes to tableHeader and/or Toolbar. The corresponding comments do not mention whether the changes were intentionally left out or whether there was a problem in re-rolling. Therefore, we have at least 4 different targets in this issue, from which every single one seems to be incomplete.
What we need is a clear, single, and up-to-date target. Looks like all of the 4 patches need to be extracted into the files they are changing in order to figure out what changes the current patch should actually contain, and merge them back into a single patch afterwards. The existing patches cannot be applied, since HEAD has changed in the meantime. That's going to take some time.
Comment #87
tim.plunkettLooking at the diffstat and innerdiff of each patch, there doesn't seem to be too many missed changes between #63, #65 and #67, but those are the oldest and are definitely behind HEAD in a big way (two of the files don't even exist anymore).
sun, is this assigned to you because you still intend to undertake the task you outlined in your last comment? If not, I might be able to spend some time on it.
Comment #88
sunStraight re-roll against HEAD.
- Moved displace styles into dedicated /misc/displace.css. (but didn't adjust asset/library loading yet)
Comment #89
mgiffordGo bot go! Thanks @sun!
Comment #90
mgiffordsadly, this patch needs more than a re-roll.
It's adding about 1cm of blank to the top of the themes I tested it on.
Comment #91
sunYes, already mentioned in #88. Additionally, the implementation is a bit over-engineered, IMHO. Hope to be able to revisit this patch today/tomorrow, but it's not too high on my todo/priority list.
Comment #92
sunComment #93
klonosI see this got postponed for D8. Any chance we'll have a working solution for D7? I don't mean start chasing d7/d8 dev changes and re-rolling/re-coding, just a patch that'll simply do magic in D7.0 final (ideally without the issue in #90 above). I am seeking a solution for admin_menu and 'sticky' table headers to play nice together.
Comment #94
pillarsdotnet CreditAttribution: pillarsdotnet commentedbump.
Comment #95
sunComment #96
nod_#1417378: Remove eval() from tableHeader JavaScript is somehow related in that it allow multiple module/script to declare an offset function for
tableheader
placement. It's very simple and very effective so it might make this issue simpler to solve.Comment #97
nod_#1440628: [Meta] javascript toolbar/tableheader with url fragment mess
Comment #99
mgifford#88: drupal.displace.88.patch queued for re-testing.
Comment #101
shyamala CreditAttribution: shyamala commented+toolbar-followup
Comment #102
sunI won't have time to work on this.
Comment #103
jessebeach CreditAttribution: jessebeach commentedIt may not be exactly the same behavior described in this issue, but we're working on a generic way to measure elements that displace (like the toolbar) other components (like the overlay and sticky table headers) as well as an event-based update system redraw elements that have been displaced when the displacing elements change. It draws on some of the ideas in this issue, but puts the onus of measuring the displacement on the modules that own the views of the displacing elements.
#1847084-48: Measure/track displacing elements better + provide change events for them (fix overlay + toolbar)
Comment #104
jessebeach CreditAttribution: jessebeach commentedI'm marking this fixed based on the the commit of #1847084: Measure/track displacing elements better + provide change events for them (fix overlay + toolbar).
Comment #105
tim.plunkett