Problem/Motivation

Forms that are displayed in the Layout Builder form are submittable.

This can

  1. Take you away from the layout builder
  2. Create changes to your site.

For example in the node layout override form the comments form is displayed. You can actually create a comment from here. It also may be confusing if you are scrolling up and down the page and you see Save and Preview buttons you might not see the comment for it is attached and then click "Save" and see the message "Comment field is required." field is required(not speaking from personal experience or anything 😜).

The search form could also be placed which will take you away from the page.

With contrib modules you would have any more fields that might expose forms. Inline Entity Form and Webform for example.

Additionally but related are there could be other blocks/field that expose links that take you away from the page. Or certain links like for example links from the Flag module might actually save data("Bookmark this") from the rendered blocks.

Submitting these forms and clicking the links could be accidental click or the user might get confused and think they are looking at the entity view page.

Proposed resolution

Similar to Settings Tray Edit mode forms and links on Layout Builder preview blocks should be inoperable. This effects both the default and override layout forms.

Possible ways to do this:
Via Javascript see: core/modules/settings_tray/js/settings_tray.es6.js
When rendering a block preview we could set #disabled on all form elements and links.

Remaining tasks

  1. Confirm we want to disable forms and links
  2. write failing tests
  3. Write fix
  4. review
  5. 🎉

User interface changes

All links and forms in layout builder form will be disabled.

API changes

None

Data model changes

None

CommentFileSizeAuthor
#90 2973921-90.patch18.69 KBbnjmnm
#90 interdiff_84-90.txt4.32 KBbnjmnm
#84 2973921-84.patch18.93 KBbnjmnm
#84 interdiff_81-84.txt2.59 KBbnjmnm
#81 2973921-81.patch16.34 KBbnjmnm
#81 interdiff_77-81.txt10.03 KBbnjmnm
#81 2973921-81-x25.patch18.26 KBbnjmnm
#81 2973921-81-x25-test-only-FAIL.patch18.03 KBbnjmnm
#77 2973921-77.patch10.99 KBbnjmnm
#77 interdiff_72-77.txt2.44 KBbnjmnm
#74 Screen Shot 2019-02-07 at 7.10.06 PM.png777.62 KBKristen Pol
#72 2973921-72-reroll.patch10.39 KBbnjmnm
#69 2973921-69.patch11.18 KBbnjmnm
#69 interdiff_67-69.txt1.06 KBbnjmnm
#67 2973921-67.patch11.37 KBbnjmnm
#67 interdiff_61-67.txt1012 bytesbnjmnm
#63 2973921-61-x30.patch13.33 KBtedbow
#62 Screen Shot 2019-02-03 at 11.32.36 PM.png538.5 KBKristen Pol
#61 2973921-61.patch11.41 KBbnjmnm
#61 interdiff_56-61.txt2.74 KBbnjmnm
#60 Screen Shot 2019-01-27 at 10.19.34 PM.png152.71 KBKristen Pol
#60 Screen Shot 2019-01-27 at 10.19.26 PM.png808.7 KBKristen Pol
#58 2973921-58.patch10.01 KBbnjmnm
#58 interdiff_56-58.txt1.24 KBbnjmnm
#56 2973921-56.patch9.99 KBbnjmnm
#56 interdiff_53-56.txt4.92 KBbnjmnm
#53 2973921-53.patch11.81 KBbnjmnm
#53 interdiff_46-53.txt4.78 KBbnjmnm
#52 Screen Shot 2019-01-18 at 8.26.19 PM.png662.12 KBKristen Pol
#52 Screen Shot 2019-01-18 at 8.30.57 PM.png639.45 KBKristen Pol
#52 Screen Shot 2019-01-18 at 8.25.49 PM.png753.62 KBKristen Pol
#46 2973921-46.patch11.75 KBbnjmnm
#46 2973921-46-test-only.patch6.76 KBbnjmnm
#46 interdiff_43-46.txt957 bytesbnjmnm
#43 2973921-43.patch11.61 KBbnjmnm
#43 interdiff_41-43.txt7.97 KBbnjmnm
#41 2973921-41.patch11.4 KBbnjmnm
#41 2973921-41-test-only.patch10.16 KBbnjmnm
#41 interdiff-37-41.txt8.5 KBbnjmnm
#37 2973921-37.patch9.38 KBtedbow
#37 interdiff-35-37.txt2.21 KBtedbow
#35 2973921-35.patch9.61 KBtedbow
#35 interdiff-33-35.txt4.87 KBtedbow
#33 2973921-33.patch9.41 KBtedbow
#33 interdiff-32-33.txt2.25 KBtedbow
#32 2973921-32.patch8.11 KBtedbow
#32 interdiff-31-32.txt3.71 KBtedbow
#31 x20-2973921-31.patch10.17 KBtedbow
#31 interdiff-30-31.txt2.41 KBtedbow
#30 interdiff-28-30.txt950 bytestedbow
#30 2973921-30.patch10.88 KBtedbow
#28 2973921-28.patch10.75 KBtedbow
#28 interdiff-26-28.txt1.6 KBtedbow
#26 2973921-26.patch9.9 KBtedbow
#26 interdiff-24-26.txt828 bytestedbow
#24 2973921-24.patch10.04 KBtedbow
#24 interdiff-22-24.txt3.25 KBtedbow
#22 2973921-22.patch10.69 KBtedbow
#22 interdiff-20-22.txt3.02 KBtedbow
#20 2973921-20.patch8.47 KBtedbow
#20 interdiff-17-20.txt0 bytestedbow
#17 interdiff-14-17.txt1.55 KBtedbow
#17 2973921-17.patch7.65 KBtedbow
#14 2973921-14.patch7.54 KBtedbow
#14 interdiff-9-13.txt638 bytestedbow
#9 2973921-9.patch6.91 KBtedbow
#9 interdiff-7-9.txt1.45 KBtedbow
#7 interdiff-2973921-4-7.txt618 bytesyogeshmpawar
#7 2973921-7.patch6.9 KByogeshmpawar
#4 2973921-4.patch7.01 KBtedbow
#4 2973921-4-test-only.patch5.58 KBtedbow
#3 2973921-3.patch1.43 KBtedbow
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tedbow created an issue. See original summary.

tim.plunkett’s picture

Title: Forms and Links inside preview block in the Layout Builder form should not be disabled. » Forms and Links inside preview block in the Layout Builder form should be disabled.

Title change?

tedbow’s picture

Issue tags: +Needs tests
FileSize
1.43 KB

Here is patch that prevents clicks and mousedown events for any blocks rendered in the layout builder.

tedbow’s picture

Status: Active » Needs review
Issue tags: -Needs tests
FileSize
5.58 KB
7.01 KB

Here is the same patch with a test and a test-only patch to prove it fails without the fix.

GrandmaGlassesRopeMan’s picture

Status: Needs review » Needs work
+++ b/core/modules/layout_builder/js/layout-builder.js
@@ -11,7 +11,11 @@
+      $(context).find('.layout-builder--lay     out__region').sortable({

What's going on with this additional space in the selector?

yogeshmpawar’s picture

Assigned: Unassigned » yogeshmpawar
yogeshmpawar’s picture

Assigned: yogeshmpawar » Unassigned
Status: Needs work » Needs review
FileSize
6.9 KB
618 bytes

@drpal - I think it's a miss from @tedbow so doing changes to previous patch because there is no update on this issue from last 4 days. also added an interdiff to highlight changes.

johnwebdev’s picture

I think the patch looks, just a quick thought:

Can't we add context to the event listeners for slightly better performance when LB is re-rendered through AJAX?

tedbow’s picture

Doing @johndevman's suggestion in #8

GrandmaGlassesRopeMan’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +JavaScript
+++ b/core/modules/layout_builder/js/layout-builder.es6.js
@@ -1,6 +1,10 @@
+      $('[data-layout-block-uuid]', context).children().on('click mousedown', (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+      });
       $(context).find('.layout-builder--layout__region').sortable({

Somewhat interesting that we do this two different ways. Maybe a followup to figure out which one is more 🎉

The last submitted patch, 3: 2973921-3.patch, failed testing. View results

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

I tested this and it works well even if you tab around the form and use the return key. One thing I'm wondering is accessibility. Do we need to announce that the action is disabled in some way? Or would that as annoying as a javascript alert message that informs the users the click has been ignored. Maybe what we should do is add something to the help to tell the user that links and forms in the blocks will be disabled in the preview - i.e. add something to layout_builder_help().

tedbow’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
638 bytes
7.54 KB

Add a message to help on the layout builder pages.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 14: 2973921-14.patch, failed testing. View results

tim.plunkett’s picture

Issue tags: +sprint
tedbow’s picture

Status: Needs work » Needs review
FileSize
7.65 KB
1.55 KB

Rerolled #14 and fixed test.

Status: Needs review » Needs work

The last submitted patch, 17: 2973921-17.patch, failed testing. View results

tim.plunkett’s picture

tedbow’s picture

Status: Needs work » Needs review
FileSize
0 bytes
8.47 KB

Just test changes, adding waits to try to get it to pass. Passes locally.

Status: Needs review » Needs work

The last submitted patch, 20: 2973921-20.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
3.02 KB
10.69 KB

I think the problem

+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,197 @@
+    $this->addBlock('Search form', '#layout-builder .search-block-form');

This where the test fails.

I think it is because the previous dialog is still open or is closing.

So I changed to wait till "Add block" is visible not exists.

Changed core/drupalci.yml to only run this test

Status: Needs review » Needs work

The last submitted patch, 22: 2973921-22.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
3.25 KB
10.04 KB
+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,197 @@
+    $this->addBlock('Block with link', '#layout-builder .block-block-content');
+    $this->addBlock('Search form', '#layout-builder .search-block-form');

Trying to figure out what makes this test different and realized this is the only that adds to blocks in 1 page load. Testing the dialogs is tricky.

Going to save the layout in between adding the blocks.

Status: Needs review » Needs work

The last submitted patch, 24: 2973921-24.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
828 bytes
9.9 KB

Failed at a different point.
Removing the check until after the layout is saved.

Status: Needs review » Needs work

The last submitted patch, 26: 2973921-26.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
1.6 KB
10.75 KB
+++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
@@ -0,0 +1,167 @@
+    // Wait for block form to be rendered in the Layout Builder.
+    $this->assertNotEmpty($assert_session->waitForElement('css', $rendered_locator));

Maybe we also need to check the dialog is closed?

Status: Needs review » Needs work

The last submitted patch, 28: 2973921-28.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
10.88 KB
950 bytes

Having weird problem using "Save layout" without reloading page in testing. Also in #2919795: Add visual hints that Layout Builder work is in tempstore and will not be lost, or take effect until saved

tedbow’s picture

So now #31 is passing. I don't think #28 was necessary.
Also adding back check removed in #26

tedbow’s picture

Now that this is passing.

  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,172 @@
    +  public static $modules = [
    

    Should be protected

  2. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,172 @@
    +    // Add a block with a link and one with a form.
    

    s/one with/a block with/

  3. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderTest.php
    @@ -0,0 +1,172 @@
    +class LayoutBuilderTest extends WebDriverTestBase {
    

    Change to a more specific class name for this test

tedbow’s picture

I realized that in keyboard navigation you can still tab to these from elements and input or submit. Generally I think for keyboard navigation it would better for these elements not to be in the tab order at all.

This patch adds removing elements beside contextual links from the tab order.

andrewmacpherson’s picture

Title: Forms and Links inside preview block in the Layout Builder form should be disabled. » Interactive controls inside preview block in the Layout Builder form should be disabled.
Status: Needs review » Needs work
Issue tags: +Accessibility

I think it would be best to disable all interactive controls, not just forms and links. Videos, embedded Prezi slideshows, social share widgets, could all have the potential to take you away from the layout builder.

+      $('[data-layout-block-uuid]', context)
+        .children()
+        .on('click mousedown', e => {
+          e.preventDefault();
+          e.stopPropagation();
+        });

Is "click mousedown" going to be enough? Especially given that we have a "mouseup" in our ajax.js and third-party embeds have who-knows-what. I don't know how robust we can be, but I think we should consider all the mouse*, pointer*, and touch* events here.

Aside: we'll need to replace "mousedown" in core with "mouseup" in lots of places for #2958654: Assess JavaScript behaviours for WCAG 2.1 Pointer Cancellation

+       * Remmove from the tabbing order all input elements and elements

Nit: "remove".

+      containingElements
+        .find(
+          'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"]):not(.focusable)',
+        )
+        .attr('tabindex', -1);

The .focusable selector is from jQueryUI, right? There's also .tabbable which might be more readable here.

Will these approaches be effective at disabling controls inside an iframe?

tedbow’s picture

Status: Needs work » Needs review
FileSize
4.87 KB
9.61 KB

@andrewmacpherson thanks for the review

  1. change to mouseup and added touchstart. Put a todo to make sure when add all events needed.
  2. Nit: "remove". fixed
  3. Changed to use .tabbable
  4. I change to use the disabled property for all items except links. This means we don't have JS events here and I think is more robust as far it gaining focus.

    also has the bonus of making CKEditor be disabled which seems to be very hard otherwise: see: https://ckeditor.com/docs/ckeditor4/latest/guide/dev_readonly.html

  5. I added logic to excluded disabled links from being used as a selection for the jquery sortable. The link seems to act funky I think because are messing with there listener. You can still sort these by drag and drop just by clicking other parts of the block just not the link itself
  6. Will these approaches be effective at disabling controls inside an iframe?

    Pretty sure it will not work if the iframe src is from another domain but I think this impossible to get around and is by design.
    I am not sure about if it is the same domain. it wasn't working for me when I just tried to by making an inline block with an iframe point to /node/1/edit for the same site. but it might be possible

GrandmaGlassesRopeMan’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,37 @@
    +      $blocks.find('a').on('click mouseup touchstart', e => {
    

    What specifically are you trying to capture? All interaction events?

  2. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,37 @@
    +        typeof context.closest === 'function' &&
    

    You should be careful here. If `context.closest` is somehow a `String`, `Date` or `Object`, `typeof` will tell you they are functions.

  3. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,37 @@
    +        context.closest('[data-layout-block-uuid]')
    

    There's a warning about `context.closest` needed to be destructured.

tedbow’s picture

Status: Needs work » Needs review
FileSize
2.21 KB
9.38 KB

@drpal thanks for the review.

  1. See @andrewmacpherson's comment in #34. I am not sure here. Basically we don't want users to be able to click, touch, or otherwise use these links.
  2. I realize we can simplify this and get rid of the if by just using
    $(context)
              .closest('[data-layout-block-uuid]')
              .children()
              .not('[data-contextual-id]'),
  3. 2) removed this
tedbow’s picture

tedbow’s picture

GrandmaGlassesRopeMan’s picture

@tedbow - The changes look good. I would just want to make sure we are capturing all the input events we need to from @andrewmacpherson's comment in #34.

bnjmnm’s picture

Added JS to make iframes non-interactive
Added pointer-events: none; to preview CSS so cursor/hover behavior does not act as if items are clickable.

Refactored tests to account for this CSS change - now we check for non-clickability vs. the previous check for default-click behavior being suppressed.

Checked video & audio elements and concluded no changes were necessary - while its possible play those media items, none of the controls take the user away from Layout Builder or alter anything on the site.

tedbow’s picture

Status: Needs review » Needs work

@bnjmnm I like these changes. Nice solution for iframes.

  1. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,50 @@
    +      * Set Tabindex = -1 on iframes so no child elements are tabbable.
    +      * Mask iframe with trasparent div to prevent clicking.
    

    The tab index on iframes is actually being set above. I would say move the comment above or just rely on the existing comment about tab index without specifically mentioning iframes.

  2. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,50 @@
    +          .wrap('<div style="position:relative;"></div>')
    +          .before(
    +            '<div style="height:100%;width:100%;position:absolute;"></div>',
    

    Is there any chance that a theme would add margin or padding to all divs that would alter this admin view when compared to the regular output?

    If so should put margin and padding of 0 in here also?

    I am assuming this done inline as opposed to in a style sheet because we want to not overwritten anything? Could we do it in style sheet with !important. I know we don't usually want to use this but would this be a case? not sure.

    Also instead of html string maybe we should use createElement?

  3. +++ b/core/modules/layout_builder/layout_builder.module
    --- /dev/null
    +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    
    +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,193 @@
    +   * Confirm element is not clickable by checking for exception message stating "not clickable".
    

    Line should be under 80 chars. Method should have 1 line description and then blank link before further comment(if needed)

  4. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,193 @@
    +   * @throws \Behat\Mink\Exception\ElementNotFoundException
    +   * @throws \Behat\Mink\Exception\ExpectationException
    

    We don't include the @throws unless the method directly throws the exception

    /tedbow wishes we did

  5. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,193 @@
    +  protected function isElementUnclickable($element) {
    

    Missing @param for $element. Also should be type hinted to \Behat\Mink\Element\NodeElement

    You could also just change this method to an assert like assertElementUnclickable(). You would have to assert the string and replace the return FALSE with a $this->fail() call.

bnjmnm’s picture

Patch addresses feedback from @tedbow in #42 (including refactoring assertElementUnclickable() - much nicer.

Went with the important! approach for the mask + container. I'm inclined to think this is one of those legitimate uses of !important despite it being one of the most commonly discouraged anythings in web development.

bnjmnm’s picture

Status: Needs work » Needs review
tedbow’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -157,37 +151,34 @@ protected function addBlock($block_link_text, $rendered_locator) {
           $element->click();
    +      $this->fail();
         }
         catch (UnknownError $e) {
    -      return strpos($e->getMessage(), 'is not clickable at point') !== FALSE;
    ...
         }
    -    return FALSE;
    

    Sorry what I meant here is don't change $element->click()

    but after your new
    $this->assertContains('is not clickable at point', $e->getMessage());
    return; because assertion would have passed.

    But after the catch block call something like

    $this->fail('Element was clickable but should not have been');

    Because if it made it there then the click() call did not throw the exception.

    I am not sure why the testing now with the direct call to fail.
    I read the interdiff wrong 😬

  2. Since I haven't seen this method of asserting that an element is clickable which should have have test only patch to prove this new assert method fails.
bnjmnm’s picture

Re: #45 (2): I provided a test-only patch.

Also a small change to the #43 patch - added fail message to click test.

tedbow’s picture

Status: Needs work » Needs review

setting to Needs Review to trigger test

tedbow’s picture

@bnjmnm thanks for providing the failing test.

I think this looks good if the tests come back as expected.

I probably can't RTBC since I worked on it.

The last submitted patch, 46: 2973921-46-test-only.patch, failed testing. View results

tim.plunkett’s picture

Issue tags: +Usability
Kristen Pol’s picture

Thanks for the patch. I have reviewed and found only very minor things including one typo (see below). I will try to test this.

  1. +++ b/core/modules/layout_builder/css/layout-builder.css
    @@ -56,6 +56,22 @@
    +.layout-section .layout-builder--layout__region .preview-mask-container {
    +  position: relative!important;
    

    Nitpick: Other parts of core have a space before !important.

  2. +++ b/core/modules/layout_builder/css/layout-builder.css
    @@ -56,6 +56,22 @@
    +  position: absolute!important;
    +  width: 100%!important;
    +  height: 100%!important;
    +  margin: 0!important;
    +  padding: 0!important;
    

    Same as above.

  3. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,52 @@
    +      /*
    +       * Disable interactive elements in Layout Builder Preview
    

    Nitpick: No period at end of sentence.

  4. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,52 @@
    +      /*
    +      * Remove from the tabbing order all input elements and elements
    +      * specifically assigned a tab index.
    +      */
    

    Nitpick: Alignment of * is off.

  5. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -49,6 +49,52 @@
    +      /*
    +      * Mask iframe with trasparent div to prevent clicking.
    +      */
    

    "trasparent" is a typo.

    Nitpick: Same as above.

  6. +++ b/core/modules/layout_builder/js/layout-builder.js
    @@ -30,6 +30,30 @@
    +
    +      containingElements = containingElements.add($(context).closest('[data-layout-block-uuid]').children().not('[data-contextual-id]'));
    

    Nitpick: Consider formatting so it's easier to read.

  7. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,185 @@
    +use Behat\Mink\Element\NodeElement;
    

    Nitpick: Should be first in the list.

  8. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,185 @@
    +    'layout_builder',
    +    'block',
    +    'node',
    +    'search',
    +    'filter',
    +    'filter_test',
    +    'block_content',
    

    Nitpick: Make alphabetical?

  9. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,185 @@
    +    //   https://www.drupal.org/project/drupal/issues/2917777.
    

    Nitpick: Remove extra space before https?

  10. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,185 @@
    +    // Add a block with a link, another with a form, and one with an iframe.
    +    $this->addBlock('Search form', '#layout-builder .search-block-form');
    +    $this->drupalGet("$field_ui_prefix/display-layout/default");
    +    $this->addBlock('Block with link', '#link-that-should-be-disabled');
    +    $this->drupalGet("$field_ui_prefix/display-layout/default");
    +    $this->addBlock('Block with iframe', '#iframe-that-should-be-disabled');
    

    Nitpick: The order in the comments is not the same as the code. Comment has link, form, and then iframe. Code has form, link, and then iframe. Would be good if they matched.

  11. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,185 @@
    +      $this->fail(format_string('@tag_name was clickable when it shouldn\'t have been', ['@tag_name' => $tag_name]));
    

    Nitpick: Consider double quotes around string to avoid escaping quote since double quotes aren't used in the string.

  12. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php
    @@ -0,0 +1,185 @@
    +   * Asserts that forms, links and iframes in preview are non-interactive.
    

    Nitpick: Use Oxford comma.

Kristen Pol’s picture

I have tested the patch from #46 by:

  1. Enabled layout builder modules
  2. Configured layout builder on page content type
  3. Added link and iframe to body text of node 1
  4. Go to layout page
  5. Both link and iframe controls are disabled

Marking back to "Needs work" in case any changes from previous comment should be done.

bnjmnm’s picture

Thank you for the thorough review & testing @kristen-pol
Items in #51 are addressed other than ones commented on below
6) core/modules/layout_builder/js/layout-builder.js is automatically generated from core/modules/layout_builder/js/layout-builder.es6.js so it's not a change that can be made. The .es6.js file is fair game though and should be formatted with readability in mind.

9) There isn't (afaik) a firm coding standard for inline comments using tags, but I prefer using the indentation so IDEs format the additional lines as part of the @todo statement.

bnjmnm’s picture

Status: Needs work » Needs review
GrandmaGlassesRopeMan’s picture

+++ b/core/modules/layout_builder/js/layout-builder.es6.js
@@ -49,6 +49,52 @@
+      containingElements = containingElements.add(

I wonder if this makes sense. Could we possibly update the previous selector to provide an equivalent result?

Additionally, from #53, formatting is not fair game. We have a pipeline which includes Prettier for a reason. Having a wild-west environment where every file is formatted differently makes it quite difficult to parse unfamiliar files.

bnjmnm’s picture

Summary of changes in this patch

  1. #53 By adding context to the creation of $blocks, I was able to remove everything related to containingElements and just work with $blocks. Despite the tests passing, I was still concerned that I overlooked the use case that promoted containingElements to be distinct from $blocks, so I did some manual sanity-checking as well. This included taking into account pre and post Ajax requests, using quickedit, mouse & tab navigation, and making sure LB contextual links continue to work. All seems fine?
  2. Removed everything related to masking the iframe with a transparent div in JS and CSS. I realized it was unnecessary once pointer-events: none;was added. This successfully prevents mouse interactions, and the setting of tabindex to -1 prevents keyboard interactions.
  3. Rephrased a few comments in the JS.
bnjmnm’s picture

Status: Needs review » Needs work

Discussed #56 with @tedbow and we agreed it needed a few more changes. A revised patch will arrive shortly.

bnjmnm’s picture

@tedbow explained the use case I was wondering if I overlooked in #56.1
containingElements was added to catch any AJAX changes applied directly to a block's content from other modules.
We realized that the same could be achieved by removing context from the creation of $block.
To mitigate the performance hit of removing context, the Layout builder ID was added to the selector
const $blocks = $('#layout-builder [data-layout-block-uuid]');

tedbow’s picture

Status: Needs work » Needs review

@bnjmnm thanks for the updated patch. Setting to Needs Review for tests

Kristen Pol’s picture

I tested #58 using the search form, links, and an iframe. Interactivity for all of these was disabled.

I reviewed the interdiff and, while I don't see anything obviously wrong, it would be good if @tedbow could confirm the changes are as expected. If so, this looks RTBC to me.

bnjmnm’s picture

Split JS into multiple behaviors & added JS Documentation.

Kristen Pol’s picture

Issue tags: -Accessibility +accessibility
FileSize
538.5 KB

Checked that #61 still works and it does. Someone with more js chops will need to verify the interdiff is ok.

tedbow’s picture

Since this is JS patch just uploading patch to run #61 30x.

To test for random drupalci failures that might happen. I think it should be fine though

tedbow’s picture

Status: Needs review » Reviewed & tested by the community

This looks good to me. Good test coverage, straight forward JS and updated help text.

xjm’s picture

+++ b/core/modules/layout_builder/js/layout-builder.es6.js
@@ -1,5 +1,19 @@
+(($, Drupal) => {
+  const { ajax, behaviors, announce } = Drupal;
+  /**
+   * Provides the ability to drag blocks to new positions in the layout.

There's a missing blank line before the docblock. Was this eslinted? (It could be that the blank line just isn't in the AirBnB standards, but I've not seen this before in our JS.)

tedbow’s picture

Status: Reviewed & tested by the community » Needs work

Was this eslinted? (It could be that the blank line just isn't in the AirBnB standards, but I've not seen this before in our JS.)

I ran just ran
yarn lint:core-js-passing
This had no errors.

I then ran
node ./node_modules/eslint/bin/eslint.js modules/layout_builder/js/layout-builder.es6.js
which is the higher standard but not guaranteed to pass on our js code.

The blank line is not in our standards but I did find 1 other minor problem

   7:28  warning  'announce' is assigned a value but never used  no-unused-vars
  77:12  warning  'context' is defined but never used            no-unused-vars

Which corresponds to

  1. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -1,5 +1,19 @@
    +(($, Drupal) => {
    +  const { ajax, behaviors, announce } = Drupal;
    

    announce is never used. Probably we needed earlier in the patch or just c/p error.

    It should be removed

  2. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -51,4 +65,36 @@
    +    attach(context) {
    

    context here is also not used but our convention is to leave it in since this variable is always sent via Drupal behaviors API.

Setting to needs work for 1)

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
1012 bytes
11.37 KB

Addressed #66.1

tedbow’s picture

Status: Needs review » Needs work

#67 looks good

+++ b/core/modules/layout_builder/js/layout-builder.es6.js
@@ -1,5 +1,19 @@
-(($, { ajax, behaviors }) => {
...
+(($, Drupal) => {
+  const { ajax, behaviors } = Drupal;

Sorry I didn't catch this before. No I am not sure why we changing this first line here at all.

The only reason I know to not destructure Drupal here is if we need to use Drupal.t because we can't use the t function in a destructure way.

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
1.06 KB
11.18 KB

Patch addresses the goof spotted in #68.

tedbow’s picture

Status: Needs review » Reviewed & tested by the community

LOoks good!

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll
bnjmnm’s picture

Status: Needs work » Needs review
FileSize
10.39 KB

Reroll 🥖

Kristen Pol’s picture

Does this need another round of manual testing?

Kristen Pol’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
777.62 KB

Just in case, I did and it is working. Marking RTBC.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs reroll
  1. +++ b/core/modules/layout_builder/css/layout-builder.css
    @@ -56,6 +56,10 @@
    +.layout-section .layout-builder--layout__region .block [tabindex="-1"] {
    

    This selector only works with themes that extend Classy. We should add class to blocks that are rendered inside the layout builder editor.

  2. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -160,4 +160,37 @@
    +      // Don't allow links to be used as a sortable selection.
    +      $('.layout-builder--layout__region').sortable({ cancel: 'a' });
    

    Why is this needed?

tedbow’s picture

Re #75.2
I think I added this. The idea was to stop links from being used to drag and dropped. But I test taking this out and it act the same. You can click anywhere inside a block to drag it, even on the disabled links. Which seem to work fine.

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
2.44 KB
10.99 KB
  1. #75.1 Very good catch, added new class to these blocks.
  2. #75.2 Removed this after confirmation from @tedbow that it is no longer required.

Status: Needs review » Needs work

The last submitted patch, 77: 2973921-77.patch, failed testing. View results

tedbow’s picture

the changes in #77 look good to me but I manually tested the patch and it seems that it is stopping the contextual links to configure block from working. Not sure why. I have tried a few test themes.

+++ b/core/modules/layout_builder/css/layout-builder.css
@@ -56,6 +56,10 @@
+.layout-section .layout-builder--layout__region .layout-builder--block [tabindex="-1"] {
+  pointer-events: none;
+}

The problem is here. This also stops contextual links form working not sure why it doesn't fail in tests so @bnjmnm if you could confirm you are seeing this behavior.

I tested and adding :not([data-contextual-id] a) to the end of the selector work.

This issue doesn't deal with contextual links but #3002608: Remove contextual links not related to layout administration inside layout builder blocks will remove all non layout builder contextual links so we should be good.

GrandmaGlassesRopeMan’s picture

+++ b/core/modules/layout_builder/js/layout-builder.es6.js
@@ -160,4 +160,34 @@
+    attach(context) {

You're passing `context` here but you never use it inside the function.

bnjmnm’s picture

#80 addressed by removing `context`

For #79 I had to address the nonfuncitoning contextual links differently than suggested - this solution would make the contextual links clickable, but they would still not be tabbable. This problem was probably not notices sooner as it requires a specific order events. Very pleased @tedbow discovered it. The easiest way to reproduce is go to the layout builder UI and refresh the page. On a refresh, it looks like contextual links init and behaviors.layoutBuilderDisableInteractiveElements happen in a different sequence and the contextual links are disabled.

Reproducing this in tests was not as simple as refreshing the page, but I think I found steps to reliably reproduce the issue. I attached x25 and x25-FAIL versions of the patch to confirm this.

The last submitted patch, 81: 2973921-81-x25-test-only-FAIL.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 81: 2973921-81.patch, failed testing. View results

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
2.59 KB
18.93 KB

Adding the new block class required updating some unit tests.

tedbow’s picture

Status: Needs review » Reviewed & tested by the community
  1. I have manually tested and the changes since #77 look good.

    I used the "Test Wild West" which is not based on stable.
    with the patch in #77 the contextual links do not work
    with the patch in #84 the contextual links do work

    In both cases the other links which should be disabled are disabled.

    Test with bartik too. It works in both cases.

    The test coverage looks good the fail patch proves we have a fix.

  2. #80 has been fixed
  3. The change in #84 looks good to fix the unit test failure.

    I ran all unit and kernel tests locally to be sure
    I

RTBC! if test fail in #84 for some reason this will push it back to Needs Work.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work

It seems like #75.2 is now relevant because contextual links can be used and shouldn't start sorting.

tedbow’s picture

Status: Needs work » Reviewed & tested by the community

I think the solution in #75.2 is actually a problem that is out of scope of the current issue.

Currently in 8.7.x you can use the contextual links to drag and drop. Though you have to actually think to do this.
1. Open up the contextual links
2. drag the link instead of clicking it

So this problem has really nothing to do with disabling other links and other items inside the form area.
I just happen to have added the code to this issue for some reason, sorry.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/layout_builder/css/layout-builder.css
@@ -56,6 +56,10 @@
+.layout-section .layout-builder--layout__region .layout-builder--block [tabindex="-1"] {

+++ b/core/modules/layout_builder/src/EventSubscriber/BlockComponentRenderArray.php
@@ -106,6 +106,7 @@ public function onBuildRender(SectionComponentBuildRenderArrayEvent $event) {
+        '#attributes' => ['class' => ['layout-builder--block']],

We shouldn't use the modifier pattern here.

lauriii’s picture

Issue tags: +Needs followup

Let's also make sure that follow-up gets opened for #75.2.

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
4.32 KB
18.69 KB
  1. #88 Modifier pattern removed
  2. #89 Created #3033153: Contextual links can be used to drag and drop Layout Blocks. for the symptoms discussed in #75.2
tedbow’s picture

Status: Needs review » Reviewed & tested by the community

Looks good!

lauriii’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/layout_builder/css/layout-builder.css
@@ -55,6 +55,10 @@
+.layout-section .layout-builder--layout__region .layout-builder-block [tabindex="-1"] {

Do we still need .layout-section and .layout-builder--layout__region in the selector?

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
960 bytes
18.94 KB

Re #92

Do we still need .layout-section and .layout-builder--layout__region in the selector?

Good call. These are no longer necessary and they've been removed.

These became unnecessary in the rule above it as well

.layout-section .layout-builder--layout__region .block {
  padding: 1.5em;
}

was changed to

.layout-builder-block {
  padding: 1.5em;
}

And these were moved in the file as to not interrupt the grouping of .layout-section .layout-builder--layout__region rules.

bnjmnm’s picture

Status: Needs review » Needs work

@tedbow spotted an issue with the patch - will upload a corrected one

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
960 bytes
18.94 KB

This is identical to the patch actually uploaded in #93, so the interdiff is from #90

Them being identical is only apparent if you view the patch with a cache busting query. Visiting the URL directly gets a cached version that was removed before saving #93. Re-uploading the patch and interdiff with new filenames.

tedbow’s picture

Status: Needs review » Reviewed & tested by the community

ok #92 is now addressed.

RTBC!

  • lauriii committed ef68ad6 on 8.7.x
    Issue #2973921 by tedbow, bnjmnm, yogeshmpawar, Kristen Pol, lauriii,...
lauriii’s picture

Status: Reviewed & tested by the community » Fixed

Looks good! Thank you everyone!

Committed ef68ad6 and pushed to 8.7.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

andrewmacpherson’s picture

Issue tags: -accessibility (duplicate tag) +Accessibility

fixing accessibility tag