@nod_ suggested in IRC that we may be able to get the same UX experience that we achieving now with existing dialog system.
This might eliminate the need for most of offcanvas.js
Hopefully links could use this system by doing something like:
$element['attributes'] = [
'class' => ['use-ajax'],
'data-dialog-type' => 'dialog',
'data-side-tray'=> 'true'
];
'data-side-tray' would have to trigger positioning the dialog and adjusting the body to achieve current UX experience.
This issue is to explore that possibility.
A prerequisite for any method that would replace the current offcanvas is that would easy for developer of other modules to easy be able to use the tray in way that would very similar to Outside In usage. This would provide a consistent UX experience across Outside In, other parts of core and contrib modules(such as Panels IPE).
Relating this other JS issue that this would likely affect if we switched to this method.
Comment | File | Size | Author |
---|---|---|---|
#59 | interdiff-2786459-56-59.txt | 2.52 KB | tedbow |
#59 | 2786459-59.patch | 33.22 KB | tedbow |
#58 | Screen Shot 2016-08-25 at 1.43.51 PM.png | 124.31 KB | tkoleary |
#58 | Screen Shot 2016-08-25 at 1.47.25 PM.png | 389.71 KB | tkoleary |
#56 | interdiff-2786459-53-56.txt | 1018 bytes | tedbow |
Comments
Comment #2
nod_Attached a very rough patch that uses core dialogs. Bonus is the ability to resize the sidebar.
Using dialogs is good because it'll help with a11y and once we figure out what todo with them on mobile, this will benefit.
Comment #3
nod_Comment #4
nod_fix some stuff in dialog.ajax.js
Comment #5
nod_Make use of the (renamed) OpenOutsideinDialogCommand ajax command to clean up dialog settings.
Comment #6
nod_Reroll and removing of #2784463: Convert outside_in_page_(top|bottom)() to a #theme_wrappers altogether since we don't need any extra wrapping.
Comment #7
martin107 CreditAttribution: martin107 as a volunteer commentedI like this issue ... less code, by using an existing pattern is a good thing.
Two comments :-
1)
From #6
Good I hope we can remove it ....
(A) There are still references to #main-canvas in the css.
In one case I can use (A) to explain a visual regression - namely
(B) In edit mode all blocks should have "dotted-line box styling". that toggles with the edit button
There are lots of other outside_in issues waiting in the wings to style the tray and add throbbers etc
#2784513: Off-canvas tray requires feedback on load
#2784437: Clean up CSS in outside_in module
So I want to be limited in the restoring all the visual function of the tray --- but I think we should fix (B)
Let me describe what is going wrong with an example
#block-bartik-branding - the div that says by default "Site-Install"
it is a "contextual region" that has the dotted-line border because this css selector is matched.
"#main-canvas.js-outside-in-edit-mode .ourside-in-editable"
#main-canvas has gone away so we need to refactor the js.
2)
I like the injection of Drupal.debounce and Drupal.displace. that is good news for flexibility.
BUT there is still a call in outside_in.js bodyPadding() to Drupal.displace() which needs to be converted into a displace() call for consistency.
Comment #8
tedbowI was trying to get the patch in #6 to work I couldn't. It seems to be working for @nod_ and @martin107 so I thought it might be caching issue for me. After some testing, reinstalling, using an anonymous browser session, and clearing all caches I think it might be caching issue for them(I hope ;) ).
No matter what I did it load like regular dialog in the middle of the screen. I did some debugging and found that \Drupal\outside_in\Render\MainContent\OffCanvasRender was never being called. Instead the requests were handled by \Drupal\Core\Render\MainContent\DialogRenderer
This was because in outside_in.services.yml:
note the "format".
But in outside_in_contextual_links_view_alter it was using
'data-dialog-type' => 'dialog',
I updated this to use
'data-dialog-type' => 'offcanvas',
again and now \Drupal\outside_in\Render\MainContent\OffCanvasRender . My guess of why it was working for @nod_ and @martin107 is that contextual links are cached on the client side so that their browsers still had'data-dialog-type' => 'offcanvas',
even though the php code had been updated to use'data-dialog-type' => 'dialog',
.I like that fact that even though we are using core dialog system we can still use
'data-dialog-type' => 'offcanvas',
(not sure if this is bug). That way it will be easier for others, core or contrib to use the tray. I still think we should spin this part off into core.services.yml including OffCanvasRender and OpenOutsideinDialogCommand(removing "OutsideIn" from the name.I still think #2784443: Move off-canvas functionality from Settings tray module into drupal.dialog.ajax library so that other modules can use it is important even it is using the regular core dialog system like this patch provides.
Comment #9
martin107 CreditAttribution: martin107 as a volunteer commented@tedbow
I agree with you --- I see lots of the problems you describe
I was taking the line the patch was a good start but there are lots problems
I was focusing on the issues I could isolate and just building up information.
Thanks for the tip about caching ... I am well aware .. I was working around those.
I will have more time tomorrow to contribute and will try and work in away that takes into account your perspective and prefered order of doing things.
coordinating things remotely is tricky...
Comment #10
tedbow@nod_ I see the problem with patch I posted in #8. I forgotten the point you made on IRC about not using
'data-dialog-type' => 'offcanvas'
because it doesn't adhere to html5 spec(I think)There was still a problem with #6 though I think you weren't seeing because of client-side caching. Basically if you use
'data-dialog-type' => 'dialog'
OpenOutsideinDialogCommand won't be used because offormat: drupal_offcanvas
in outside_in.services.yml. We could change outside_in.services.yml to useformat: drupal_dialog
for OpenOutsideinDialogCommand. But then we would have both OpenOutsideinDialogCommand and DialogRenderer usingformat: drupal_dialog
.Because the $main_content_renderers are keyed by format in \Drupal\Core\Render\MainContent\MainContentRenderersPass::process then we can only have 1 main rendered for a "format". I tested changing outside_in.services.yml to use
format: drupal_dialog
. This does fix that Outside in module but would change the current behaviour of any request that was expecting DialogRenderer to be used, though I am not sure there are any in core(contrib could be using it).Comment #11
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer commentedAre we talking about modal or non-modal dialogs here?
Comment #12
tedbowOk this patch addresses the problem I mentioned in #10
I added the attribute data-dialog-renderer. data-dialog-renderer(if available) and data-dialog-type will be combined to make the "format" for the service. It does require 2 small changes to ajax.js
Setting to needs review. It should cause any tests to fail that aren't in "outside_in" module if I am right.
Comment #14
webchickThis is starting to block various other issues, so escalating to major.
Comment #15
tedbow@webchick thanks for bumping to major
This patch does several things. Alot of these are still in hopes that we can do #2784443: Move off-canvas functionality from Settings tray module into drupal.dialog.ajax library so that other modules can use it but with this new patch
OutsideInBlockFormTest is probably going to still fail. I am getting weird results locally such as
This seems to happen randomly.
Comment #16
tedbowUpdating for tests
Comment #23
GrandmaGlassesRopeMan@nod_
Do you think this negates the need to transition the state management of the off canvas tray to Backbone? #2784935
Comment #24
tedbowThere is an issue where the dialog with flash in the center of the screen before it moves to the right.
I added some code to position off screen in 'dialog:beforecreate'. This stops the flash.
Also fixed a case issue that I introduced for the file OpenOffCanvasDialogCommand
Comment #26
martin107 CreditAttribution: martin107 as a volunteer commentedGreat, that now functions much better.
it is now appropriate to fold in the stuff from #7
1) I have made a start on #7.1 -- fixing references in the css to #main-canvas etc.
When edit mode is toggled the dashed borders now return.
2) #7.2 fixed
3) like ajax.js, block.js I want "window" to be injected into the js library.
Comment #28
tedbow#page-wrapper is specific to bartik so we can't rely on it.
Comment #29
tedbowOk this patch does a couple things
Comment #30
tkoleary CreditAttribution: tkoleary at Acquia commented@tedbow
Looks good, but of course with the refactor there are a bunch of UX regressions. Here's what I can see at first look.
Visual and interaction regressions
And new issues introduced
When used with Place Block
When used with Quickedit
Comment #31
tedbowok this patch
If I am correct we should be down to 1 failing test, OutsideInBlockFormTest
Comment #32
webchickSorry, just being the tag fairy.
Comment #33
nod_Few adjustments:
* Drupal.attachBehaviors expects a DOM object as first argument, not a jQuery object.
* we don't use $.each for iterating over an array, it's not safe. Refactored to use array functions.
* we don't inject window in the closure. If someone tries to run this in a non browser env, they'll have other problems. and window is not used in that closure. We shouldn't be using it that much anyway, so not much value into adding that to a closure.
Comment #34
tedbow@nod_ thanks for the adjustments.
Here is patch that applies a class,'ui-dialog-offcanvas', to our dialog wrapper. Then attempt to update the previous css to use the new dialog classes instead of the classes from our old custom tray.
Comment #36
tedbowre: @tkoleary in #30
I tested this with 8.2.x and it works the same way. Since Place Block reloads the page I would expect the tray to close.
I think this issue is related. #2784481: The off-canvas tray does not respect the state last set by the user in a session.. Don't think we should hold issue up because it is not related.
This also happens in 8.2.x. Unrelated to this issue.
Comment #39
tedbowok this
Comment #41
nod_getEdge doesn't need to be a function, if the rtl attribute changes on
<html>
it means the language changed and the page was reloaded.Is enough. document.documentElement exists wherever the JS is, header or footer, no need to put that in behavior or delay the evaluation.
Comment #42
tedbow@nod_ re #41 this removes the function getEdge() and just adds
var edge = (document.documentElement.dir === 'rtl') ? 'left' : 'right';
I think the variable name should still be "edge". It's not the direction.
This also updates fixes problems with OffCanvasTest.
Offcanvas links now need the outside_in library to work because it takes care of the _wrapper_format.
OutsideInBlockFormTest still fails. It looks like it is gaston.js bug. Seems we have run into a similar problem before. #2773791: Clicking elements with children in Javascript tests throws a GastonJS exception.
I found this same problem when I was writing the original OutSide In JS tests and was able to write around it. If I can figure out the issue I will file an issue.
Comment #44
droplet CreditAttribution: droplet commentedPersonally, I disagree this idea.
From concept side,
`Offcanvas` has its own pattern, and different to Modal & Dialog. #2672344: [UX] Open as Modal should not able to interact with other elements. For example, we called DROPDOWN as DROPDOWN, not Dialog. (It's also opening dialog-like element but different styling)
From code side,
We can see the patch doesn't reuse much of the code from Drupal.dialog but make it bloated.
All these events should not be global. Because when we make it to standalone lib, we able to open multiple dialogs inside and do whatever crazy actions.
Comment #45
nod_We use everything from Drupal.dialog, except
dialog.position.js
. The code in 8.2 is trying to do many things already done by Drupal.dialog such as a title bar, a close button and in the queue there is an issue to close the "offcanvas" with ESC key or another one to improve a11y.The dialog is not opened as a modal, we can open several on top of each others so #2672344: [UX] Open as Modal should not able to interact with other elements doesn't apply.
We can open many modals but not many offcanvas modals (at least that is what I understood). We need to bind stuff to window since
resize
,dialog:*
events are triggered on this. And document is needed fordrupalViewportOffsetChange
.And look at the resulting code, it's much simpler after the patch. The only big piece of code is the positioning and it can't reuse what core does because it's just not the same.
Comment #46
tedbowThe last failing test I think is problem with Javascript tests and submitting a form inside an ajax dialog.
I have created an issue to separate this from the outside_in module #2789381: Submitting an ajax dialog form in Javascript test throws a GastonJS error
That issue contains a test should prove it is a testing issue.
re @droplet in #44
and @nod_ in #45
I agree with @nod_ the intention of the offcanvas tray is there should only ever be 1 open at a time.
Comment #47
tkoleary CreditAttribution: tkoleary at Acquia commented@tedbow
I don't think so. I believe the standard jquery dialog close icon is a png. For retina we want the svg from core/misc/icons.
Comment #48
tkoleary CreditAttribution: tkoleary at Acquia commented@tedbow
I think you can safely remove all the media queries from the offcanvas css files eg. @media (max-width: 700px) etc. since that's all handled by breakpoint module and drupal displace.
Comment #49
tedbow@tkoleary
Done! I didn't touch motion.css because we are going to rework totally when(if?) this gets in.
This patch also comments out the ends of both test functions in OutsideInBlockFormTest. This because it seems to be caused by #2789381: Submitting an ajax dialog form in Javascript test throws a GastonJS error. The tests still prove you can click edit in the toolbar and then open the offcanvas block form by clicking on a block. I would rather not do this but think it is okay because this an experimental module.
Also locally I am having random failures on 2 lines in that test.
$page->find('css', '#block-powered')->click();
and
$page->find('css', '#block-branding')->click();
This have been happening on my local but have never seen it happen on DrupalCI. But it is also a GastonJS error.
@droplet has chimed in against this issue. Besides that I think this issue ready.
UPDATE: we need to document the JS functions.
I talk with @tkoleary and he agreed we can follow up on CSS issues. We already have #2781577: Properly style outside-in off canvas tray and #2784437: Clean up CSS in outside_in module
Comment #50
tedbowOk. great so tests are passing.
This patch add comments to the functions in offcanvas.js
Comment #51
droplet CreditAttribution: droplet commentedI'm lost on these outside_in issues. I could catch a bug within 10 sec after enabling the module. But we kicked it in. :s It must be some reason for that, I don't try to block its unusual workflow anyway :)
Same as outside_in, it's easy to find a wired bug:
But you able to open a dialog inside, the dialog close will trigger above listeners.
We have to think about: "Offcanvas" vs "Offcanvas for outside_in"
As standalone Offcanvas, you won't put title bar & bottom bar there. Almost all sites I've seen, they don't. And now we're adopting the CSS from dialog, you will write a lot of custom CSS to revert these inherited rules. (Remembering that its loading jQuery UI also)
Also, we can see current refactor doesn't provide same rendering behavior ( the anime ). And this complicated logic from JS side will be another headache for themers.
standalone `Offcanvas` should only take the main API to render the content inside the canvas. And let outside_in define its pattern: title & bottom bar.
Comment #52
tedbow@droplet, thanks for the feedback.
This is totally expected! Since outside_in is an experimental module there will might be bugs. The handbook page on experimental modules notes that outside_in is an alpha stage experimental module and:
(emphasis mine). Before #2753941: [Experimental] Create Outside In module MVP to provide block configuration in Off-Canvas tray and expand site edit mode was committed we an effort to file an issue for every bug and task that came up during the reviews. There are now 43 issues filed against outside_in and most were created before that issue was committed.
Whether experimental modules and the process around them is good idea(I think so!) is separate from this issue.
re:
Nice catch!
This was caused by
$element.css({overflow: 'visible', height: 'auto'});
changed to
$element.css({height: 'auto'});
Which works.
I think this is problem. I have update the offcanvas_test module to display a modal link and another offcanvas link inside the modal. I have not written a test for this yet but I filed #2790073: Ensure other modal links work from within the off-canvas tray. which we really should do whether or not this issue gets in.
This cause
21 strange errors.If you open a modal inside a offcanvas when you close the modal then the body is readjusted and part of the body goes under the offcanvas.Figured this out. Our 'dialog:beforeclose' function need to check that the element was #drupal-offcanvas.
Comment #53
tedbowSorry I had uncommitted changes that didn't make it into that patch.
Meanwhile though I figured out problem in the strange behavior 2 from 52.
This was throwing an error because when open a dialog with ajax links and then close that dialog then the Drupal.ajax.instances array has null elements. Seems like maybe this should be cleaned up by core?
I fixed by changing to
var hasElement = instance && !!instance.element;
So this fixes the 2 problems I found with dialog links inside of an offcanvas dialog.
@droplet re:
obviously this is not extensive testing. What are the concerns do you have about this?
I am going to do my interdiff against #50 because #52 was not complete.
Comment #54
GrandmaGlassesRopeMan@tedbow
Just a few minor things.
The initial condition doesn't need to be wrapped in parenthesis.
Maybe some documentation around this confusing positioning format?
Comment #55
GrandmaGlassesRopeMan[duplicate comment]
Comment #56
tedbowA couple other points I realized I forgot to address from @droplet's review in #51
From my reading of Drupal.behaviors.dialog.prepareDialogButtons the bottom bar will only be there for forms that have a .form-actions element. From my reading of the comments in that function this is example why we should be using the standard dialog system.
How long would have taken use to solve this problem if we weren't using the standard dialogs? Also if Drupal.behaviors.dialog.prepareDialogButtons has problems it should be fixed for both offcanvas and modals/standard dialogs.
I see your point about the title bar. In the latest changes I added a class to the dialog to specify if it has a empty title. I updated the test to check for this. Right now the CSS is not using that class but we can determine what it should look like with no title. Also it would be pretty easy for us to add an option to not have a title bar. Or to not have a close button and then if there is not a title and no close button remove the title bar.
Also if you try the current version of offcanvas you actually see the string "null" in the tray if the response doesn't have a title. For me this another example of a bug that we likely would not find because our use case always has a title. By using the standard dialog it just works because a bug that like would have been found long ago.
@drpal thanks the review.
1. fixed
2. Add
// @see http://api.jqueryui.com/position/
before both uses. Yeah not a big fan of this format. That link is where I figured it out. It has better explanation then I think we could provide.Comment #57
tkoleary CreditAttribution: tkoleary at Acquia commented@tedbow
The z-index and position of the button pane are working great now but when there is overflow, for instance when tools menu has both details panes open, there are three scrollbars.
Since #drupal-offcanvas has overflow scroll, I think we can safely set div.dialog-offcanvas to overflow: hidden, since the dialog javascript will always calculate the width of the three children. That way most of the time there will be only one scrollbar, and at most two, when there is overflow.
Comment #58
tkoleary CreditAttribution: tkoleary at Acquia commented@tedbow
Also this is exposing some core technical debt in quickedit where z-indexes are all off with contextual links above entity toolbar and entity toolbar below offcanvas tray:
Making quickedit toolbar container z-index:502 (or higher) fixes it.
The good news is that now that it's using Drupal displace the edge detection is "pushing" the entity (quickedit) toolbar away from the offcanvas tray.
Comment #59
tedbow@kevin this patch changes overflow css as you mentioned in #57. Not addressing #58 as that is another issue.
I also looked through the patch and update comments and spacing where needed.
Needs review for RTBC.
Comment #60
GrandmaGlassesRopeManWe have a follow up for #58, we should be good to go.
#2790285: Contextual link triggers displayed above the Quick Edit's toolbar
Comment #62
nod_I agree this is RTBC, but I do want to reply to droplet and make sure we're on the same page before it gets in though so I'll let him RTBC.
On the CSS bloat from the jquery ui dialog that's a fair complaint and I kinda agree. We'll see how bad this in #2781577: Properly style outside-in off canvas tray if it's too bad we can always go back or find a different solution, it's experimental after all.
On the rendering behavior, the ajax framework has everything needed to let us replicate it. It's not great DX and not really documented but it's there. Might get some work to get working but it's doable.
My main concern is the creation of a new API while exploring the UX of the feature. we have tools that can do most of the job and I really want us to use what already exists and see where the limitations are. If a new API is needed we'll have a better idea of what it should do and how if we start by using dialogs.
I was surprised at the state this was committed too, but it does mean we can do pretty much whatever we want from here.
( edit ) for example, I was pretty sure we'll need to add identifiers to modals (or some sort of tags) to avoid too many $element.is('#whatever'); from what we do in this patch it's pretty clear we need a way to handle that properly.
Comment #63
droplet CreditAttribution: droplet commentedThe basic feature is fine now. Let's move forward. :)
But I still aginst the change to jQuery UI Dialog.
Note that: Mainly, I'm talking about `Offcanvas pattern` rather than `Offcanvas for outside_in`
The problem with this changes:
- (Although we don't have a plan, I think we have the intention to remove Drupal.dialog [jQuery UI] in the future versions and keep Drupal.dialog close to HTML5 Dialog as possible.)
- Bloated CSS, extra JS loading.
- Default style in dialog (`ui-dialog ui-widget ui-widget-content ui-corner-all ui-front`) shared across all Dialog instances.
- debounced positions from JS provided bad experiences on windows resizing.
- Themers got mad! It seems almost impossible to implement nice CSS anime (even from JS side). (It's pretty important for Offcanvas pattern, and it's why we called it Offcanvas. With current change, this is Side PopUp).
Just take a record, my Offcanvas idea ( Similiar to unpatched ):
- It able to borrow some layout hacks from Toolbar vertical mode.
- Allowed multiple instances (eg. main menu + Offcanvas for setting is a common pattern). Reducing DOM manipulation.
Comment #64
nod_I see what you mean, it makes sense for the standalone offcanvas feature. For now I don't want to add another api to maintain so let's go with it for now.
Can you repost this in #2784443: Move off-canvas functionality from Settings tray module into drupal.dialog.ajax library so that other modules can use it? If it goes badly in the CSS issues and the others we can always go with your version.
Comment #65
droplet CreditAttribution: droplet commentedCool. In general, I can predict it won't fulfill most themers needs or my needs above. ServerSide Rendering & CSS Anime are headaches. We hit the same issue in the current patch right? it dropped the CSS anime.
One more note:
Scandalized the APIs, considering to adopt the Dialog pattern now:
(Sorry I can't provide a patch to demo it due to my personal schedule)
- Very similar concept to Drupal.dialog but I think hacking the Drupal.dialog would be harder. It's shared with 3 types.
- Less messed with Dialog event system and not limited by HTML5 Dialog SPEC.
- It allowed internal refactoring even after leaving experiment I think.
- No extra maintenance than Drupal.dialog but better API design.
I always see developers overridden Drupal.dialog.show & Drupal.dialog.close. They won't trigger events properly. Less or more, I also saw it in quickedit / edit modules. Our dialog is messed up before this patch. It made us very busy to test all 3 components with simple changes.
Comment #66
nod_Makes sense. Agreed. Lets open a follow-up.
Don't need a patch in the other issue, just the comment and pseudo code is enough.
Comment #68
webchickWhile my JavaScript level is approximately -1000, since this is a patch towards an experimental module in core, and it has sign-off (even if begrudging sign-off ;)) from both JavaScript maintainers, I think I'm comfortable committing this. This unblocks important other work going on in terms of accessibility and bug fixes, and its absence is making small improvement patches really hard to review.
I played around with the interaction and can't seem to break it. I know Kevin was very concerned that the animation is not as smooth as it used to be, but I wasn't able to immediately perceive that myself (as a non-designer). That also seems like something we can either try and get in before RC1 (though time is ticking) and/or a nice thing we can mention in the release notes of 8.2.1+ if we can't make it in time.
Committed and pushed to 8.2.x and 8.3.x. Thanks!
The idea of having a wrapping API is a good one, and I think the more things that get converted to this pattern, the more we'll be able to see the need for it. We still need a follow-up for that, so tagging.
Comment #71
tedbowChanging to new settings_tray.module component. @drpal thanks for script help! :)