From 2faf5e8e4842db257227da26fb017dfaf15d9711 Mon Sep 17 00:00:00 2001
From: Bas Brands <bas@moodle.com>
Date: Mon, 20 Dec 2021 14:40:20 +0100
Subject: [PATCH] MDL-72737 theme_boost: update for section header styles

---
 admin/tests/behat/purge_caches.feature        |   4 +-
 .../behat/activities_edit_completion.feature  |   1 +
 .../behat/course_collapse_sections.feature    |   2 +-
 lib/editor/atto/plugins/h5p/lib.php           |   3 +-
 .../moodle-atto_h5p-button-debug.js           |  36 ++++--
 .../moodle-atto_h5p-button-min.js             |   4 +-
 .../moodle-atto_h5p-button.js                 |  36 ++++--
 .../plugins/h5p/yui/src/button/js/button.js   |  36 ++++--
 lib/editor/atto/plugins/media/lib.php         |   1 +
 .../moodle-atto_media-button-debug.js         |  46 +++++--
 .../moodle-atto_media-button-min.js           |   8 +-
 .../moodle-atto_media-button.js               |  46 +++++--
 .../plugins/media/yui/src/button/js/button.js |  46 +++++--
 lib/form/amd/build/collapsesections.min.js    |   2 +
 .../amd/build/collapsesections.min.js.map     |   1 +
 lib/form/amd/src/collapsesections.js          |  80 ++++++++++++
 lib/form/header.php                           |   3 +-
 lib/form/templates/collapsesections.mustache  |  36 ++++++
 lib/form/templates/element-header.mustache    |  59 +++++++++
 .../moodle-form-shortforms-debug.js           | 118 +-----------------
 .../moodle-form-shortforms-min.js             |   2 +-
 .../moodle-form-shortforms.js                 | 118 +-----------------
 lib/form/yui/src/shortforms/js/shortforms.js  | 118 +-----------------
 lib/formslib.php                              |  34 ++---
 lib/tests/behat/behat_forms.php               |   9 +-
 .../behat/wiki_activity_completion.feature    |   1 +
 report/outline/tests/behat/filter.feature     |   4 +-
 search/tests/behat/behat_search.php           |   3 +-
 theme/boost/scss/moodle/core.scss             |  13 --
 theme/boost/scss/moodle/forms.scss            |  44 ++++---
 theme/boost/style/moodle.css                  |  44 +++----
 theme/classic/style/moodle.css                |  44 +++----
 32 files changed, 467 insertions(+), 535 deletions(-)
 create mode 100644 lib/form/amd/build/collapsesections.min.js
 create mode 100644 lib/form/amd/build/collapsesections.min.js.map
 create mode 100644 lib/form/amd/src/collapsesections.js
 create mode 100644 lib/form/templates/collapsesections.mustache
 create mode 100644 lib/form/templates/element-header.mustache

diff --git a/admin/tests/behat/purge_caches.feature b/admin/tests/behat/purge_caches.feature
index 7f1e80560c4..15d522bb4cd 100644
--- a/admin/tests/behat/purge_caches.feature
+++ b/admin/tests/behat/purge_caches.feature
@@ -16,12 +16,12 @@ Feature: Purge caches
   Scenario: Purge selected caches
     Given I should not see "Selected caches were purged"
     When I set the field "Themes" to "1"
-    And I press "Purge selected caches"
+    And I click on "Purge selected caches" "button" in the "#fitem_id_purgeselectedcaches" "css_element"
     Then I should see "The selected caches were purged"
 
   Scenario: Purge selected caches without selecting any caches
     Given I should not see "Select one or more caches to purge"
-    When I press "Purge selected caches"
+    And I click on "Purge selected caches" "button" in the "#fitem_id_purgeselectedcaches" "css_element"
     Then I should not see "The selected caches were purged"
     And I should see "Select one or more caches to purge"
 
diff --git a/course/tests/behat/activities_edit_completion.feature b/course/tests/behat/activities_edit_completion.feature
index c601abf9768..993c68df477 100644
--- a/course/tests/behat/activities_edit_completion.feature
+++ b/course/tests/behat/activities_edit_completion.feature
@@ -30,6 +30,7 @@ Feature: Edit completion settings of an activity
     When I am on the TestPage "Page Activity editing" page
     And I expand all fieldsets
     And I press "Unlock completion options"
+    And I expand all fieldsets
     Then I should see "Completion options unlocked"
     And I set the field "Completion tracking" to "Students can manually mark the activity as completed"
     And I press "Save and display"
diff --git a/course/tests/behat/course_collapse_sections.feature b/course/tests/behat/course_collapse_sections.feature
index 96ac0f5980e..ec81055a521 100644
--- a/course/tests/behat/course_collapse_sections.feature
+++ b/course/tests/behat/course_collapse_sections.feature
@@ -172,8 +172,8 @@ Feature: Collapse course sections
     When I navigate to "Settings" in current page administration
     And I expand all fieldsets
     And I set the following fields to these values:
-      | Format      | Weekly format     |
       | Course layout | Show one section per page |
+      | Format        | Weekly format             |
     And I press "Save and display"
     And "[data-toggle=collapse]" "css_element" should not exist in the "region-main" "region"
     And I click on "8 May - 14 May" "link" in the "region-main" "region"
diff --git a/lib/editor/atto/plugins/h5p/lib.php b/lib/editor/atto/plugins/h5p/lib.php
index 5aa345781e7..6b9da45f324 100644
--- a/lib/editor/atto/plugins/h5p/lib.php
+++ b/lib/editor/atto/plugins/h5p/lib.php
@@ -80,7 +80,6 @@ function atto_h5p_strings_for_js() {
     );
 
     $PAGE->requires->strings_for_js($strings, 'atto_h5p');
+    $PAGE->requires->strings_for_js(['expand', 'collapse'], 'moodle');
     $PAGE->requires->js(autoloader::get_h5p_core_library_url('js/h5p-resizer.js'));
 }
-
-
diff --git a/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-debug.js b/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-debug.js
index 98d1d42fbac..9e892bc5abe 100644
--- a/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-debug.js
+++ b/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-debug.js
@@ -93,9 +93,29 @@ var CSS = {
                         '{{/if}}' +
                     '</div>' +
                     '{{#if canUpload}}' +
-                        '<fieldset class="collapsible {{#if collapseOptions}}collapsed{{/if}}" id="{{elementid}}_h5poptions">' +
-                            '<legend class="ftoggler">{{get_string "h5poptions" component}}</legend>' +
-                            '<div class="fcontainer">' +
+                        '<fieldset class="mt-2 collapsible" id="{{elementid}}_h5poptions">' +
+                            '<legend class="d-flex align-items-center px-1">' +
+                                '<div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">' +
+                                    '<a role="button" data-toggle="collapse" href="#h5poptions"' +
+                                    'aria-expanded="{{#if showOptions}}true{{/if}}{{^if showOptions}}false{{/if}}"' +
+                                        'aria-controls="h5poptions"' +
+                                        'class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed">' +
+                                        '<span class="expanded-icon icon-no-margin p-2"' +
+                                            'title="{{get_string "collapse" "moodle"}}">' +
+                                            '<i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i>' +
+                                        '</span>' +
+                                        '<span class="collapsed-icon icon-no-margin p-2"' +
+                                            'title="{{get_string "expand" "moodle"}}">' +
+                                            '<i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i>' +
+                                        '</span>' +
+                                        '<span class="sr-only">{{get_string "h5poptions" component}}</span>' +
+                                    '</a>' +
+                                    '<h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">' +
+                                        '{{get_string "h5poptions" component}}' +
+                                    '</h3>' +
+                                '</div>' +
+                            '</legend>' +
+                            '<div id="h5poptions" class="fcontainer collapseable collapse px-1 {{#if showOptions}}show{{/if}}">' +
                                 '<div class="form-check">' +
                                     '<input type="checkbox" {{optionDownloadButton}} ' +
                                     'class="form-check-input {{CSS.OPTION_DOWNLOAD_BUTTON}}"' +
@@ -311,7 +331,7 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
             optionDownloadButton,
             optionEmbedButton,
             optionCopyrightButton,
-            collapseOptions = true;
+            showOptions = false;
 
         if (this._H5PDiv) {
             var H5PURL = this._H5PDiv.get('innerHTML');
@@ -323,17 +343,17 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
                 if (parameters) {
                     if (parameters.match(/export=1/)) {
                         optionDownloadButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
 
                     if (parameters.match(/embed=1/)) {
                         optionEmbedButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
 
                     if (parameters.match(/copyright=1/)) {
                         optionCopyrightButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
                 }
             } else {
@@ -349,7 +369,7 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
                 canUpload: permissions.canUpload,
                 canEmbed: permissions.canEmbed,
                 canUploadAndEmbed: permissions.canUploadAndEmbed,
-                collapseOptions: collapseOptions,
+                showOptions: showOptions,
                 fileURL: fileURL,
                 optionDownloadButton: optionDownloadButton,
                 optionEmbedButton: optionEmbedButton,
diff --git a/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-min.js b/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-min.js
index d1ba31a78cf..8d5962dcae8 100644
--- a/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-min.js
+++ b/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button-min.js
@@ -1,2 +1,2 @@
-YUI.add("moodle-atto_h5p-button",function(c,t){var d={CONTENTWARNING:"att_h5p_contentwarning",H5PBROWSER:"openh5pbrowser",INPUTALT:"atto_h5p_altentry",INPUTH5PFILE:"atto_h5p_file",INPUTSUBMIT:"atto_h5p_urlentrysubmit",OPTION_DOWNLOAD_BUTTON:"atto_h5p_option_download_button",OPTION_COPYRIGHT_BUTTON:"atto_h5p_option_copyright_button",OPTION_EMBED_BUTTON:"atto_h5p_option_embed_button",URLWARNING:"atto_h5p_warning"},r={CONTENTWARNING:"."+d.CONTENTWARNING,H5PBROWSER:"."+d.H5PBROWSER,INPUTH5PFILE:"."+d.INPUTH5PFILE,INPUTSUBMIT:"."+d.INPUTSUBMIT,OPTION_DOWNLOAD_BUTTON:"."+d.OPTION_DOWNLOAD_BUTTON,OPTION_COPYRIGHT_BUTTON:"."+d.OPTION_COPYRIGHT_BUTTON,OPTION_EMBED_BUTTON:"."+d.OPTION_EMBED_BUTTON,URLWARNING:"."+d.URLWARNING},p="atto_h5p",h='{{#if addParagraphs}}<p><br></p>{{/if}}<div class="h5p-placeholder" contenteditable="false">{{{url}}}</div>{{#if addParagraphs}}<p><br></p>{{/if}}';c.namespace("M.atto_h5p").Button=c.Base.create("button",c.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_form:null,_H5PDiv:null,_allowedmethods:"none",initializer:function(){this._allowedmethods=this.get("allowedmethods"),"none"!==this._allowedmethods&&(this.addButton({icon:"icon",iconComponent:"atto_h5p",callback:this._displayDialogue,tags:".h5p-placeholder",tagMatchRequiresAll:!1}),this.editor.all(".h5p-placeholder").setAttribute("contenteditable","false"),this.editor.delegate("dblclick",this._handleDblClick,".h5p-placeholder",this),this.editor.delegate("click",this._handleClick,".h5p-placeholder",this))},_handleDblClick:function(){this._displayDialogue()},_handleClick:function(t){t=this.get("host").getSelectionFromNode(t.target);this.get("host").getSelection()!==t&&this.get("host").setSelection(t)},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection(),!1!==this._currentSelection&&(this._getH5PDiv(),this.getDialogue({headerContent:M.util.get_string("pluginname",p),width:"auto",focusAfterHide:!0}).set("bodyContent",this._getDialogueContent()).show(),M.form.shortforms({formid:this.get("host").get("elementid")+"_atto_h5p_form"}))},_getH5PDiv:function(){var t=this.get("host").getSelectedNodes(),e=null;t.each(function(t){t.hasClass("h5p-placeholder")&&(e=t)}),this._H5PDiv=e},_getPermissions:function(){var t={canEmbed:!1,canUpload:!1,canUploadAndEmbed:!1};return this.get("host").canShowFilepicker("h5p")&&("both"===this._allowedmethods?(t.canUploadAndEmbed=!0,t.canUpload=!0):"upload"===this._allowedmethods&&(t.canUpload=!0)),"both"!==this._allowedmethods&&"embed"!==this._allowedmethods||(t.canEmbed=!0),t},_getDialogueContent:function(){var t,e,o,n,i,l,a=this._getPermissions(),s=!0;return this._H5PDiv&&(l=this._H5PDiv.get("innerHTML"),(i=M.cfg.wwwroot+"/draftfile.php")==l.substring(0,i.length)?(t=l.split("?")[0],(i=l.split("?")[1])&&(i.match(/export=1/)&&(s=!(e="checked")),i.match(/embed=1/)&&(s=!(o="checked")),i.match(/copyright=1/)&&(s=!(n="checked")))):t=l),i=c.Handlebars.compile('<form class="atto_form mform" id="{{elementid}}_atto_h5p_form"><div style="display:none" role="alert" class="alert alert-warning mb-1 {{CSS.CONTENTWARNING}}">{{get_string "noh5pcontent" component}}</div><div style="display:none" role="alert" class="alert alert-warning mb-1 {{CSS.URLWARNING}}">{{get_string "invalidh5purl" component}}</div>{{#if canUploadAndEmbed}}<div class="mt-2 mb-4 attoh5pinstructions">{{{get_string "instructions" component}}}</div>{{/if}}<div class="mb-4"><label for="{{elementid}}_{{CSS.H5PBROWSER}}">{{#if canUploadAndEmbed}}{{get_string "h5pfileorurl" component}}{{/if}}{{^if canUploadAndEmbed}}{{#if canUpload}}{{get_string "h5pfile" component}}{{/if}}{{#if canEmbed}}{{get_string "h5purl" component}}{{/if}}{{/if}}</label><div class="input-group input-append w-100"><input class="form-control {{CSS.INPUTH5PFILE}}" type="url" value="{{fileURL}}" id="{{elementid}}_{{CSS.INPUTH5PFILE}}" data-region="h5pfile" size="32"/>{{#if canUpload}}<span class="input-group-append"><button class="btn btn-secondary {{CSS.H5PBROWSER}}" type="button">{{get_string "browserepositories" component}}</button></span>{{/if}}</div>{{#if canUpload}}<fieldset class="collapsible {{#if collapseOptions}}collapsed{{/if}}" id="{{elementid}}_h5poptions"><legend class="ftoggler">{{get_string "h5poptions" component}}</legend><div class="fcontainer"><div class="form-check"><input type="checkbox" {{optionDownloadButton}} class="form-check-input {{CSS.OPTION_DOWNLOAD_BUTTON}}"aria-label="{{get_string "downloadbutton" component}}" id="{{elementid}}_h5p-option-allow-download"/><label class="form-check-label" for="{{elementid}}_h5p-option-allow-download">{{get_string "downloadbutton" component}}</label></div><div class="form-check"><input type="checkbox" {{optionEmbedButton}} class="form-check-input {{CSS.OPTION_EMBED_BUTTON}}" aria-label="{{get_string "embedbutton" component}}" id="{{elementid}}_h5p-option-embed-button"/><label class="form-check-label" for="{{elementid}}_h5p-option-embed-button">{{get_string "embedbutton" component}}</label></div><div class="form-check mb-2"><input type="checkbox" {{optionCopyrightButton}} class="form-check-input {{CSS.OPTION_COPYRIGHT_BUTTON}}" aria-label="{{get_string "copyrightbutton" component}}" id="{{elementid}}_h5p-option-copyright-button"/><label class="form-check-label" for="{{elementid}}_h5p-option-copyright-button">{{get_string "copyrightbutton" component}}</label></div></div></fieldset>{{/if}}</div><div class="text-center"><button class="btn btn-secondary {{CSS.INPUTSUBMIT}}" type="submit">{{get_string "pluginname" component}}</button></div></form>'),l=c.Node.create(i({elementid:this.get("host").get("elementid"),CSS:d,component:p,canUpload:a.canUpload,canEmbed:a.canEmbed,canUploadAndEmbed:a.canUploadAndEmbed,collapseOptions:s,fileURL:t,optionDownloadButton:e,optionEmbedButton:o,optionCopyrightButton:n})),this._form=l,this._setEventListeners(),l},_filepickerCallback:function(t){""!==t.url&&(this._form.one(r.INPUTH5PFILE).set("value",t.url),this._removeWarnings())},
-_setEventListeners:function(){var t=this._form,e=this._getPermissions();t.one(r.INPUTSUBMIT).on("click",this._setH5P,this),e.canUpload&&t.one(r.H5PBROWSER).on("click",function(){this.get("host").showFilepicker("h5p",this._filepickerCallback,this)},this),e.canUploadAndEmbed&&t.one(r.INPUTH5PFILE).on("change",function(){this._removeWarnings()},this)},_removeWarnings:function(){var t=this._form;t.one(r.URLWARNING).setStyle("display","none"),t.one(r.CONTENTWARNING).setStyle("display","none")},_setH5P:function(t){var e,o,n,i,l=this._form,a=this.get("host"),s=l.one(r.INPUTH5PFILE).get("value"),d=this._getPermissions();if(t.preventDefault(),!this._updateWarning()){if(a.focus(),t=!0,this._H5PDiv&&(this._H5PDiv.remove(),t=!1),""!==s){if(a.setSelection(this._currentSelection),s.startsWith(M.cfg.wwwroot)){if(o="",d.canUpload)for(i in n={},l.one(r.OPTION_DOWNLOAD_BUTTON).get("checked")&&(n["export"]="1"),l.one(r.OPTION_EMBED_BUTTON).get("checked")&&(n.embed="1"),l.one(r.OPTION_COPYRIGHT_BUTTON).get("checked")&&(n.copyright="1"),n)""===o&&-1===s.indexOf("?")?o+="?":o+="&amp;",o+=i+"="+n[i];e=c.Handlebars.compile(h)({url:s+o,addParagraphs:t})}else e=c.Handlebars.compile(h)({url:s});a.insertContentAtFocusPoint(e),this.markUpdated()}this.getDialogue({focusAfterHide:null}).hide()}},_validEmbed:function(t){return!!new RegExp("^(<iframe).*(<\\/iframe>)").test(t)},_validURL:function(t){return!!new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*").test(t)},_updateWarning:function(){var t=this._form,e=!0,o=this._getPermissions();return e=o.canUpload||o.canEmbed?""!==(o=t.one(r.INPUTH5PFILE).get("value"))?(t.one(r.CONTENTWARNING).setStyle("display","none"),o.startsWith(M.cfg.wwwroot)||this._validURL(o)?(t.one(r.URLWARNING).setStyle("display","none"),!1):(t.one(r.URLWARNING).setStyle("display","block"),!0)):(t.one(r.CONTENTWARNING).setStyle("display","block"),!0):e}},{ATTRS:{allowedmethods:{value:null}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
\ No newline at end of file
+YUI.add("moodle-atto_h5p-button",function(c,t){var d={CONTENTWARNING:"att_h5p_contentwarning",H5PBROWSER:"openh5pbrowser",INPUTALT:"atto_h5p_altentry",INPUTH5PFILE:"atto_h5p_file",INPUTSUBMIT:"atto_h5p_urlentrysubmit",OPTION_DOWNLOAD_BUTTON:"atto_h5p_option_download_button",OPTION_COPYRIGHT_BUTTON:"atto_h5p_option_copyright_button",OPTION_EMBED_BUTTON:"atto_h5p_option_embed_button",URLWARNING:"atto_h5p_warning"},r={CONTENTWARNING:"."+d.CONTENTWARNING,H5PBROWSER:"."+d.H5PBROWSER,INPUTH5PFILE:"."+d.INPUTH5PFILE,INPUTSUBMIT:"."+d.INPUTSUBMIT,OPTION_DOWNLOAD_BUTTON:"."+d.OPTION_DOWNLOAD_BUTTON,OPTION_COPYRIGHT_BUTTON:"."+d.OPTION_COPYRIGHT_BUTTON,OPTION_EMBED_BUTTON:"."+d.OPTION_EMBED_BUTTON,URLWARNING:"."+d.URLWARNING},p="atto_h5p",h='{{#if addParagraphs}}<p><br></p>{{/if}}<div class="h5p-placeholder" contenteditable="false">{{{url}}}</div>{{#if addParagraphs}}<p><br></p>{{/if}}';c.namespace("M.atto_h5p").Button=c.Base.create("button",c.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_form:null,_H5PDiv:null,_allowedmethods:"none",initializer:function(){this._allowedmethods=this.get("allowedmethods"),"none"!==this._allowedmethods&&(this.addButton({icon:"icon",iconComponent:"atto_h5p",callback:this._displayDialogue,tags:".h5p-placeholder",tagMatchRequiresAll:!1}),this.editor.all(".h5p-placeholder").setAttribute("contenteditable","false"),this.editor.delegate("dblclick",this._handleDblClick,".h5p-placeholder",this),this.editor.delegate("click",this._handleClick,".h5p-placeholder",this))},_handleDblClick:function(){this._displayDialogue()},_handleClick:function(t){t=this.get("host").getSelectionFromNode(t.target);this.get("host").getSelection()!==t&&this.get("host").setSelection(t)},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection(),!1!==this._currentSelection&&(this._getH5PDiv(),this.getDialogue({headerContent:M.util.get_string("pluginname",p),width:"auto",focusAfterHide:!0}).set("bodyContent",this._getDialogueContent()).show(),M.form.shortforms({formid:this.get("host").get("elementid")+"_atto_h5p_form"}))},_getH5PDiv:function(){var t=this.get("host").getSelectedNodes(),e=null;t.each(function(t){t.hasClass("h5p-placeholder")&&(e=t)}),this._H5PDiv=e},_getPermissions:function(){var t={canEmbed:!1,canUpload:!1,canUploadAndEmbed:!1};return this.get("host").canShowFilepicker("h5p")&&("both"===this._allowedmethods?(t.canUploadAndEmbed=!0,t.canUpload=!0):"upload"===this._allowedmethods&&(t.canUpload=!0)),"both"!==this._allowedmethods&&"embed"!==this._allowedmethods||(t.canEmbed=!0),t},_getDialogueContent:function(){var t,e,o,n,i,a,l=this._getPermissions(),s=!1;return this._H5PDiv&&(a=this._H5PDiv.get("innerHTML"),(i=M.cfg.wwwroot+"/draftfile.php")==a.substring(0,i.length)?(t=a.split("?")[0],(i=a.split("?")[1])&&(i.match(/export=1/)&&(e="checked",s=!0),i.match(/embed=1/)&&(o="checked",s=!0),i.match(/copyright=1/)&&(n="checked",s=!0))):t=a),i=c.Handlebars.compile(
+'<form class="atto_form mform" id="{{elementid}}_atto_h5p_form"><div style="display:none" role="alert" class="alert alert-warning mb-1 {{CSS.CONTENTWARNING}}">{{get_string "noh5pcontent" component}}</div><div style="display:none" role="alert" class="alert alert-warning mb-1 {{CSS.URLWARNING}}">{{get_string "invalidh5purl" component}}</div>{{#if canUploadAndEmbed}}<div class="mt-2 mb-4 attoh5pinstructions">{{{get_string "instructions" component}}}</div>{{/if}}<div class="mb-4"><label for="{{elementid}}_{{CSS.H5PBROWSER}}">{{#if canUploadAndEmbed}}{{get_string "h5pfileorurl" component}}{{/if}}{{^if canUploadAndEmbed}}{{#if canUpload}}{{get_string "h5pfile" component}}{{/if}}{{#if canEmbed}}{{get_string "h5purl" component}}{{/if}}{{/if}}</label><div class="input-group input-append w-100"><input class="form-control {{CSS.INPUTH5PFILE}}" type="url" value="{{fileURL}}" id="{{elementid}}_{{CSS.INPUTH5PFILE}}" data-region="h5pfile" size="32"/>{{#if canUpload}}<span class="input-group-append"><button class="btn btn-secondary {{CSS.H5PBROWSER}}" type="button">{{get_string "browserepositories" component}}</button></span>{{/if}}</div>{{#if canUpload}}<fieldset class="mt-2 collapsible" id="{{elementid}}_h5poptions"><legend class="d-flex align-items-center px-1"><div class="position-relative d-flex ftoggler align-items-center position-relative mr-1"><a role="button" data-toggle="collapse" href="#h5poptions"aria-expanded="{{#if showOptions}}true{{/if}}{{^if showOptions}}false{{/if}}"aria-controls="h5poptions"class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed"><span class="expanded-icon icon-no-margin p-2"title="{{get_string "collapse" "moodle"}}"><i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i></span><span class="collapsed-icon icon-no-margin p-2"title="{{get_string "expand" "moodle"}}"><i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i></span><span class="sr-only">{{get_string "h5poptions" component}}</span></a><h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">{{get_string "h5poptions" component}}</h3></div></legend><div id="h5poptions" class="fcontainer collapseable collapse px-1 {{#if showOptions}}show{{/if}}"><div class="form-check"><input type="checkbox" {{optionDownloadButton}} class="form-check-input {{CSS.OPTION_DOWNLOAD_BUTTON}}"aria-label="{{get_string "downloadbutton" component}}" id="{{elementid}}_h5p-option-allow-download"/><label class="form-check-label" for="{{elementid}}_h5p-option-allow-download">{{get_string "downloadbutton" component}}</label></div><div class="form-check"><input type="checkbox" {{optionEmbedButton}} class="form-check-input {{CSS.OPTION_EMBED_BUTTON}}" aria-label="{{get_string "embedbutton" component}}" id="{{elementid}}_h5p-option-embed-button"/><label class="form-check-label" for="{{elementid}}_h5p-option-embed-button">{{get_string "embedbutton" component}}</label></div><div class="form-check mb-2"><input type="checkbox" {{optionCopyrightButton}} class="form-check-input {{CSS.OPTION_COPYRIGHT_BUTTON}}" aria-label="{{get_string "copyrightbutton" component}}" id="{{elementid}}_h5p-option-copyright-button"/><label class="form-check-label" for="{{elementid}}_h5p-option-copyright-button">{{get_string "copyrightbutton" component}}</label></div></div></fieldset>{{/if}}</div><div class="text-center"><button class="btn btn-secondary {{CSS.INPUTSUBMIT}}" type="submit">{{get_string "pluginname" component}}</button></div></form>'),a=c.Node.create(i({elementid:this.get("host").get("elementid"),CSS:d,component:p,canUpload:l.canUpload,canEmbed:l.canEmbed,canUploadAndEmbed:l.canUploadAndEmbed,showOptions:s,fileURL:t,optionDownloadButton:e,optionEmbedButton:o,optionCopyrightButton:n})),this._form=a,this._setEventListeners(),a},_filepickerCallback:function(t){""!==t.url&&(this._form.one(r.INPUTH5PFILE).set("value",t.url),this._removeWarnings())},_setEventListeners:function(){var t=this._form,e=this._getPermissions();t.one(r.INPUTSUBMIT).on("click",this._setH5P,this),e.canUpload&&t.one(r.H5PBROWSER).on("click",function(){this.get("host").showFilepicker("h5p",this._filepickerCallback,this)},this),e.canUploadAndEmbed&&t.one(r.INPUTH5PFILE).on("change",function(){this._removeWarnings()},this)},_removeWarnings:function(){var t=this._form;t.one(r.URLWARNING).setStyle("display","none"),t.one(r.CONTENTWARNING).setStyle("display","none")},_setH5P:function(t){var e,o,n,i,a=this._form,l=this.get("host"),s=a.one(r.INPUTH5PFILE).get("value"),d=this._getPermissions();if(t.preventDefault(),!this._updateWarning()){if(l.focus(),t=!0,this._H5PDiv&&(this._H5PDiv.remove(),t=!1),""!==s){if(l.setSelection(this._currentSelection),s.startsWith(M.cfg.wwwroot)){if(o="",d.canUpload)for(i in n={},a.one(r.OPTION_DOWNLOAD_BUTTON).get("checked")&&(n["export"]="1"),a.one(r.OPTION_EMBED_BUTTON).get("checked")&&(n.embed="1"),a.one(r.OPTION_COPYRIGHT_BUTTON).get("checked")&&(n.copyright="1"),n)""===o&&-1===s.indexOf("?")?o+="?":o+="&amp;",o+=i+"="+n[i];e=c.Handlebars.compile(h)({url:s+o,addParagraphs:t})}else e=c.Handlebars.compile(h)({url:s});l.insertContentAtFocusPoint(e),this.markUpdated()}this.getDialogue({focusAfterHide:null}).hide()}},_validEmbed:function(t){return!!new RegExp("^(<iframe).*(<\\/iframe>)").test(t)},_validURL:function(t){return!!new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*").test(t)},_updateWarning:function(){var t=this._form,e=!0,o=this._getPermissions();return e=o.canUpload||o.canEmbed?""!==(o=t.one(r.INPUTH5PFILE).get("value"))?(t.one(r.CONTENTWARNING).setStyle("display","none"),o.startsWith(M.cfg.wwwroot)||this._validURL(o)?(t.one(r.URLWARNING).setStyle("display","none"),!1):(t.one(r.URLWARNING).setStyle("display","block"),!0)):(t.one(r.CONTENTWARNING).setStyle("display","block"),!0):e}},{ATTRS:{allowedmethods:{value:null}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
\ No newline at end of file
diff --git a/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button.js b/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button.js
index 98d1d42fbac..9e892bc5abe 100644
--- a/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button.js
+++ b/lib/editor/atto/plugins/h5p/yui/build/moodle-atto_h5p-button/moodle-atto_h5p-button.js
@@ -93,9 +93,29 @@ var CSS = {
                         '{{/if}}' +
                     '</div>' +
                     '{{#if canUpload}}' +
-                        '<fieldset class="collapsible {{#if collapseOptions}}collapsed{{/if}}" id="{{elementid}}_h5poptions">' +
-                            '<legend class="ftoggler">{{get_string "h5poptions" component}}</legend>' +
-                            '<div class="fcontainer">' +
+                        '<fieldset class="mt-2 collapsible" id="{{elementid}}_h5poptions">' +
+                            '<legend class="d-flex align-items-center px-1">' +
+                                '<div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">' +
+                                    '<a role="button" data-toggle="collapse" href="#h5poptions"' +
+                                    'aria-expanded="{{#if showOptions}}true{{/if}}{{^if showOptions}}false{{/if}}"' +
+                                        'aria-controls="h5poptions"' +
+                                        'class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed">' +
+                                        '<span class="expanded-icon icon-no-margin p-2"' +
+                                            'title="{{get_string "collapse" "moodle"}}">' +
+                                            '<i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i>' +
+                                        '</span>' +
+                                        '<span class="collapsed-icon icon-no-margin p-2"' +
+                                            'title="{{get_string "expand" "moodle"}}">' +
+                                            '<i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i>' +
+                                        '</span>' +
+                                        '<span class="sr-only">{{get_string "h5poptions" component}}</span>' +
+                                    '</a>' +
+                                    '<h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">' +
+                                        '{{get_string "h5poptions" component}}' +
+                                    '</h3>' +
+                                '</div>' +
+                            '</legend>' +
+                            '<div id="h5poptions" class="fcontainer collapseable collapse px-1 {{#if showOptions}}show{{/if}}">' +
                                 '<div class="form-check">' +
                                     '<input type="checkbox" {{optionDownloadButton}} ' +
                                     'class="form-check-input {{CSS.OPTION_DOWNLOAD_BUTTON}}"' +
@@ -311,7 +331,7 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
             optionDownloadButton,
             optionEmbedButton,
             optionCopyrightButton,
-            collapseOptions = true;
+            showOptions = false;
 
         if (this._H5PDiv) {
             var H5PURL = this._H5PDiv.get('innerHTML');
@@ -323,17 +343,17 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
                 if (parameters) {
                     if (parameters.match(/export=1/)) {
                         optionDownloadButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
 
                     if (parameters.match(/embed=1/)) {
                         optionEmbedButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
 
                     if (parameters.match(/copyright=1/)) {
                         optionCopyrightButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
                 }
             } else {
@@ -349,7 +369,7 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
                 canUpload: permissions.canUpload,
                 canEmbed: permissions.canEmbed,
                 canUploadAndEmbed: permissions.canUploadAndEmbed,
-                collapseOptions: collapseOptions,
+                showOptions: showOptions,
                 fileURL: fileURL,
                 optionDownloadButton: optionDownloadButton,
                 optionEmbedButton: optionEmbedButton,
diff --git a/lib/editor/atto/plugins/h5p/yui/src/button/js/button.js b/lib/editor/atto/plugins/h5p/yui/src/button/js/button.js
index 2906734e42a..eacf0f5d8ed 100644
--- a/lib/editor/atto/plugins/h5p/yui/src/button/js/button.js
+++ b/lib/editor/atto/plugins/h5p/yui/src/button/js/button.js
@@ -91,9 +91,29 @@ var CSS = {
                         '{{/if}}' +
                     '</div>' +
                     '{{#if canUpload}}' +
-                        '<fieldset class="collapsible {{#if collapseOptions}}collapsed{{/if}}" id="{{elementid}}_h5poptions">' +
-                            '<legend class="ftoggler">{{get_string "h5poptions" component}}</legend>' +
-                            '<div class="fcontainer">' +
+                        '<fieldset class="mt-2 collapsible" id="{{elementid}}_h5poptions">' +
+                            '<legend class="d-flex align-items-center px-1">' +
+                                '<div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">' +
+                                    '<a role="button" data-toggle="collapse" href="#h5poptions"' +
+                                    'aria-expanded="{{#if showOptions}}true{{/if}}{{^if showOptions}}false{{/if}}"' +
+                                        'aria-controls="h5poptions"' +
+                                        'class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed">' +
+                                        '<span class="expanded-icon icon-no-margin p-2"' +
+                                            'title="{{get_string "collapse" "moodle"}}">' +
+                                            '<i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i>' +
+                                        '</span>' +
+                                        '<span class="collapsed-icon icon-no-margin p-2"' +
+                                            'title="{{get_string "expand" "moodle"}}">' +
+                                            '<i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i>' +
+                                        '</span>' +
+                                        '<span class="sr-only">{{get_string "h5poptions" component}}</span>' +
+                                    '</a>' +
+                                    '<h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">' +
+                                        '{{get_string "h5poptions" component}}' +
+                                    '</h3>' +
+                                '</div>' +
+                            '</legend>' +
+                            '<div id="h5poptions" class="fcontainer collapseable collapse px-1 {{#if showOptions}}show{{/if}}">' +
                                 '<div class="form-check">' +
                                     '<input type="checkbox" {{optionDownloadButton}} ' +
                                     'class="form-check-input {{CSS.OPTION_DOWNLOAD_BUTTON}}"' +
@@ -309,7 +329,7 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
             optionDownloadButton,
             optionEmbedButton,
             optionCopyrightButton,
-            collapseOptions = true;
+            showOptions = false;
 
         if (this._H5PDiv) {
             var H5PURL = this._H5PDiv.get('innerHTML');
@@ -321,17 +341,17 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
                 if (parameters) {
                     if (parameters.match(/export=1/)) {
                         optionDownloadButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
 
                     if (parameters.match(/embed=1/)) {
                         optionEmbedButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
 
                     if (parameters.match(/copyright=1/)) {
                         optionCopyrightButton = 'checked';
-                        collapseOptions = false;
+                        showOptions = true;
                     }
                 }
             } else {
@@ -347,7 +367,7 @@ Y.namespace('M.atto_h5p').Button = Y.Base.create('button', Y.M.editor_atto.Edito
                 canUpload: permissions.canUpload,
                 canEmbed: permissions.canEmbed,
                 canUploadAndEmbed: permissions.canUploadAndEmbed,
-                collapseOptions: collapseOptions,
+                showOptions: showOptions,
                 fileURL: fileURL,
                 optionDownloadButton: optionDownloadButton,
                 optionEmbedButton: optionEmbedButton,
diff --git a/lib/editor/atto/plugins/media/lib.php b/lib/editor/atto/plugins/media/lib.php
index 3e4b19dc947..88ee7177c3a 100644
--- a/lib/editor/atto/plugins/media/lib.php
+++ b/lib/editor/atto/plugins/media/lib.php
@@ -80,6 +80,7 @@ function atto_media_strings_for_js() {
                                           'videowidth',
                                           'width'),
                                           'atto_media');
+    $PAGE->requires->strings_for_js(array('expand', 'collapse'), 'moodle');
 }
 
 /**
diff --git a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js
index 5ffa2201561..f80eee7c5d5 100644
--- a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js
+++ b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js
@@ -162,22 +162,22 @@ var COMPONENTNAME = 'atto_media',
                     ' addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-display-options">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-display-options" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "displayoptions" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vdisplayoptions" name="displayoptions"}}' +
+                    '<div id="vdisplayoptions" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.display_options" context=this id=CSS.VIDEO mediatype_video=true}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-advanced-settings">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-advanced-settings" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "advancedsettings" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vadvancedsettings" name="advancedsettings"}}' +
+                    '<div id="vadvancedsettings" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.advanced_settings" context=this id=CSS.VIDEO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-tracks">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-tracks" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vtracks" name="tracks" help=helpStrings.tracks}}' +
+                    '<div id="vtracks" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.track_tabs" context=this id=CSS.VIDEO}}' +
                     '</div>' +
                 '</fieldset>',
@@ -186,22 +186,22 @@ var COMPONENTNAME = 'atto_media',
                     ' addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-display-options">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-display-options" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "displayoptions" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="adisplayoptions" name="displayoptions"}}' +
+                    '<div id="adisplayoptions" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.display_options" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-advanced-settings">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-advanced-settings" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "advancedsettings" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="aadvancedsettings" name="advancedsettings"}}' +
+                    '<div id="aadvancedsettings" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.advanced_settings" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-tracks">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-tracks" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="atracks" name="tracks" help=helpStrings.tracks}}' +
+                    '<div id="atracks" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.track_tabs" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>'
@@ -383,7 +383,27 @@ var COMPONENTNAME = 'atto_media',
                         '<label class="form-check-label">{{get_string "default" component}}</label>' +
                     '</div>' +
                     '{{renderPartial "form_components.add_component" context=this label=addcomponentlabel}}' +
-                '</div>'
+                '</div>',
+            SECTION: '' +
+                '<legend class="d-flex align-items-center px-1">' +
+                    '<div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">' +
+                        '<a role="button" data-toggle="collapse" href="#{{id}}" aria-expanded="false"' +
+                            'aria-controls="{{id}}"' +
+                            'class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed">' +
+                            '<span class="expanded-icon icon-no-margin p-2" title="{{get_string "collapse" "moodle"}}">' +
+                                '<i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i>' +
+                            '</span>' +
+                            '<span class="collapsed-icon icon-no-margin p-2" title="{{get_string "expand" "moodle"}}">' +
+                                '<i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i>' +
+                            '</span>' +
+                            '<span class="sr-only">{{get_string name component}}</span>' +
+                        '</a>' +
+                        '<h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">' +
+                            '{{get_string name component}}' +
+                        '</h3>' +
+                        '</div>' +
+                    '{{#help}}{{{../help}}}{{/help}}' +
+                '</legend>'
         },
         HTML_MEDIA: {
             VIDEO: '' +
diff --git a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js
index 2c3f9b0de7f..93ab0dd7915 100644
--- a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js
+++ b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js
@@ -1,5 +1,5 @@
 YUI.add("moodle-atto_media-button",function(l,e){var t="atto_media",i={LINK:"LINK",VIDEO:"VIDEO",AUDIO:"AUDIO"},a={SUBTITLES:"SUBTITLES",CAPTIONS:"CAPTIONS",DESCRIPTIONS:"DESCRIPTIONS",CHAPTERS:"CHAPTERS",METADATA:"METADATA"},o={SOURCE:"atto_media_source",TRACK:"atto_media_track",MEDIA_SOURCE:"atto_media_media_source",LINK_SOURCE:"atto_media_link_source",POSTER_SOURCE:"atto_media_poster_source",TRACK_SOURCE:"atto_media_track_source",DISPLAY_OPTIONS:"atto_media_display_options",NAME_INPUT:"atto_media_name_entry",TITLE_INPUT:"atto_media_title_entry",URL_INPUT:"atto_media_url_entry",POSTER_SIZE:"atto_media_poster_size",LINK_SIZE:"atto_media_link_size",WIDTH_INPUT:"atto_media_width_entry",HEIGHT_INPUT:"atto_media_height_entry",TRACK_KIND_INPUT:"atto_media_track_kind_entry",TRACK_LABEL_INPUT:"atto_media_track_label_entry",TRACK_LANG_INPUT:"atto_media_track_lang_entry",TRACK_DEFAULT_SELECT:"atto_media_track_default",MEDIA_CONTROLS_TOGGLE:"atto_media_controls",MEDIA_AUTOPLAY_TOGGLE:"atto_media_autoplay",MEDIA_MUTE_TOGGLE:"atto_media_mute",MEDIA_LOOP_TOGGLE:"atto_media_loop",ADVANCED_SETTINGS:"atto_media_advancedsettings",LINK:i.LINK.toLowerCase(),VIDEO:i.VIDEO.toLowerCase(),AUDIO:i.AUDIO.toLowerCase(),TRACK_SUBTITLES:a.SUBTITLES.toLowerCase(),TRACK_CAPTIONS:a.CAPTIONS.toLowerCase(),TRACK_DESCRIPTIONS:a.DESCRIPTIONS.toLowerCase(),TRACK_CHAPTERS:a.CHAPTERS.toLowerCase(),TRACK_METADATA:a.METADATA.toLowerCase()},s={SOURCE:"."+o.SOURCE,TRACK:"."+o.TRACK,MEDIA_SOURCE:"."+o.MEDIA_SOURCE,POSTER_SOURCE:"."+o.POSTER_SOURCE,TRACK_SOURCE:"."+o.TRACK_SOURCE,DISPLAY_OPTIONS:"."+o.DISPLAY_OPTIONS,NAME_INPUT:"."+o.NAME_INPUT,TITLE_INPUT:"."+o.TITLE_INPUT,URL_INPUT:"."+o.URL_INPUT,POSTER_SIZE:"."+o.POSTER_SIZE,LINK_SIZE:"."+o.LINK_SIZE,WIDTH_INPUT:"."+o.WIDTH_INPUT,HEIGHT_INPUT:"."+o.HEIGHT_INPUT,TRACK_KIND_INPUT:"."+o.TRACK_KIND_INPUT,TRACK_LABEL_INPUT:"."+o.TRACK_LABEL_INPUT,TRACK_LANG_INPUT:"."+o.TRACK_LANG_INPUT,TRACK_DEFAULT_SELECT:"."+o.TRACK_DEFAULT_SELECT,MEDIA_CONTROLS_TOGGLE:"."+o.MEDIA_CONTROLS_TOGGLE,MEDIA_AUTOPLAY_TOGGLE:"."+o.MEDIA_AUTOPLAY_TOGGLE,MEDIA_MUTE_TOGGLE:"."+o.MEDIA_MUTE_TOGGLE,MEDIA_LOOP_TOGGLE:"."+o.MEDIA_LOOP_TOGGLE,ADVANCED_SETTINGS:"."+o.ADVANCED_SETTINGS,LINK_TAB:'li[data-medium-type="'+o.LINK+'"]',LINK_PANE:'.tab-pane[data-medium-type="'+o.LINK+'"]',VIDEO_TAB:'li[data-medium-type="'+o.VIDEO+'"]',VIDEO_PANE:'.tab-pane[data-medium-type="'+o.VIDEO+'"]',AUDIO_TAB:'li[data-medium-type="'+o.AUDIO+'"]',AUDIO_PANE:'.tab-pane[data-medium-type="'+o.AUDIO+'"]',TRACK_SUBTITLES_TAB:'li[data-track-kind="'+o.TRACK_SUBTITLES+'"]',TRACK_SUBTITLES_PANE:'.tab-pane[data-track-kind="'+o.TRACK_SUBTITLES+'"]',TRACK_CAPTIONS_TAB:'li[data-track-kind="'+o.TRACK_CAPTIONS+'"]',TRACK_CAPTIONS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_CAPTIONS+'"]',TRACK_DESCRIPTIONS_TAB:'li[data-track-kind="'+o.TRACK_DESCRIPTIONS+'"]',TRACK_DESCRIPTIONS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_DESCRIPTIONS+'"]',TRACK_CHAPTERS_TAB:'li[data-track-kind="'+o.TRACK_CHAPTERS+'"]',TRACK_CHAPTERS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_CHAPTERS+'"]',TRACK_METADATA_TAB:'li[data-track-kind="'+o.TRACK_METADATA+'"]',TRACK_METADATA_PANE:'.tab-pane[data-track-kind="'+o.TRACK_METADATA+'"]'},r={ROOT:'<form class="mform atto_form atto_media" id="{{elementid}}_atto_media_form"><ul class="root nav nav-tabs mb-1" role="tablist"><li data-medium-type="{{CSS.LINK}}" class="nav-item"><a class="nav-link active" href="#{{elementid}}_{{CSS.LINK}}" role="tab" data-toggle="tab">{{get_string "link" component}}</a></li><li data-medium-type="{{CSS.VIDEO}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{CSS.VIDEO}}" role="tab" data-toggle="tab">{{get_string "video" component}}</a></li><li data-medium-type="{{CSS.AUDIO}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{CSS.AUDIO}}" role="tab" data-toggle="tab">{{get_string "audio" component}}</a></li></ul><div class="root tab-content"><div data-medium-type="{{CSS.LINK}}" class="tab-pane active" id="{{elementid}}_{{CSS.LINK}}">{{> tab_panes.link}}</div><div data-medium-type="{{CSS.VIDEO}}" class="tab-pane" id="{{elementid}}_{{CSS.VIDEO}}">{{> tab_panes.video}}</div><div data-medium-type="{{CSS.AUDIO}}" class="tab-pane" id="{{elementid}}_{{CSS.AUDIO}}">{{> tab_panes.audio}}</div></div><div class="mdl-align"><br/><button class="btn btn-secondary submit" type="submit">{{get_string "createmedia" component}}</button></div></form>',TAB_PANES:{LINK:'{{renderPartial "form_components.source" context=this id=CSS.LINK_SOURCE}}<label for="{{elementid}}_link_nameentry">{{get_string "entername" component}}</label><input class="form-control fullwidth {{CSS.NAME_INPUT}}" type="text" id="{{elementid}}_link_nameentry"size="32" required="true"/>',
-VIDEO:'{{renderPartial "form_components.source" context=this id=CSS.MEDIA_SOURCE entersourcelabel="videosourcelabel" addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}<fieldset class="collapsible collapsed" id="{{elementid}}_video-display-options"><input name="mform_isexpanded_{{elementid}}_video-display-options" type="hidden"><legend class="ftoggler">{{get_string "displayoptions" component}}</legend><div class="fcontainer">{{renderPartial "form_components.display_options" context=this id=CSS.VIDEO mediatype_video=true}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_video-advanced-settings"><input name="mform_isexpanded_{{elementid}}_video-advanced-settings" type="hidden"><legend class="ftoggler">{{get_string "advancedsettings" component}}</legend><div class="fcontainer">{{renderPartial "form_components.advanced_settings" context=this id=CSS.VIDEO}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_video-tracks"><input name="mform_isexpanded_{{elementid}}_video-tracks" type="hidden"><legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend><div class="fcontainer">{{renderPartial "form_components.track_tabs" context=this id=CSS.VIDEO}}</div></fieldset>',AUDIO:'{{renderPartial "form_components.source" context=this id=CSS.MEDIA_SOURCE entersourcelabel="audiosourcelabel" addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}<fieldset class="collapsible collapsed" id="{{elementid}}_audio-display-options"><input name="mform_isexpanded_{{elementid}}_audio-display-options" type="hidden"><legend class="ftoggler">{{get_string "displayoptions" component}}</legend><div class="fcontainer">{{renderPartial "form_components.display_options" context=this id=CSS.AUDIO}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_audio-advanced-settings"><input name="mform_isexpanded_{{elementid}}_audio-advanced-settings" type="hidden"><legend class="ftoggler">{{get_string "advancedsettings" component}}</legend><div class="fcontainer">{{renderPartial "form_components.advanced_settings" context=this id=CSS.AUDIO}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_audio-tracks"><input name="mform_isexpanded_{{elementid}}_audio-tracks" type="hidden"><legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend><div class="fcontainer">{{renderPartial "form_components.track_tabs" context=this id=CSS.AUDIO}}</div></fieldset>'},FORM_COMPONENTS:{SOURCE:'<div class="{{CSS.SOURCE}} {{id}}"><div class="mb-1"><label for="url-input">{{#entersourcelabel}}{{get_string ../entersourcelabel ../component}}{{/entersourcelabel}}{{^entersourcelabel}}{{get_string "entersource" ../component}}{{/entersourcelabel}}</label><div class="input-group input-append w-100"><input id="url-input" class="form-control {{CSS.URL_INPUT}}" type="url" size="32"/><span class="input-group-append"><button class="btn btn-secondary openmediabrowser" type="button">{{get_string "browserepositories" component}}</button></span></div></div>{{#multisource}}{{renderPartial "form_components.add_component" context=../this label=../addcomponentlabel  help=../addsourcehelp}}{{/multisource}}</div>',ADD_COMPONENT:'<div><a href="#" class="addcomponent">{{#label}}{{get_string ../label ../component}}{{/label}}{{^label}}{{get_string "add" ../component}}{{/label}}</a>{{#help}}{{{../help}}}{{/help}}</div>',REMOVE_COMPONENT:'<div><a href="#" class="removecomponent">{{#label}}{{get_string ../label ../component}}{{/label}}{{^label}}{{get_string "remove" ../component}}{{/label}}</a></div>',DISPLAY_OPTIONS:'<div class="{{CSS.DISPLAY_OPTIONS}}"><div class="mb-1"><label for="{{id}}_media-title-entry">{{get_string "entertitle" component}}</label><input class="form-control fullwidth {{CSS.TITLE_INPUT}}" type="text" id="{{id}}_media-title-entry"size="32"/></div><div class="clearfix"></div>{{#mediatype_video}}<div class="mb-1"><label>{{get_string "size" component}}</label><div class="form-inline {{CSS.POSTER_SIZE}}"><label class="accesshide">{{get_string "videowidth" component}}</label><input type="text" class="form-control mr-1 {{CSS.WIDTH_INPUT}} input-mini" size="4"/> x <label class="accesshide">{{get_string "videoheight" component}}</label><input type="text" class="form-control ml-1 {{CSS.HEIGHT_INPUT}} input-mini" size="4"/></div></div><div class="clearfix"></div>{{renderPartial "form_components.source" context=this id=CSS.POSTER_SOURCE entersourcelabel="poster"}}{{/mediatype_video}}<div>',ADVANCED_SETTINGS:'<div class="{{CSS.ADVANCED_SETTINGS}}"><div class="form-check"><input type="checkbox" checked="true" class="form-check-input {{CSS.MEDIA_CONTROLS_TOGGLE}}"id="{{id}}_media-controls-toggle"/><label class="form-check-label" for="{{id}}_media-controls-toggle">{{get_string "controls" component}}</label></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.MEDIA_AUTOPLAY_TOGGLE}}"id="{{id}}_media-autoplay-toggle"/><label class="form-check-label" for="{{id}}_media-autoplay-toggle">{{get_string "autoplay" component}}</label></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.MEDIA_MUTE_TOGGLE}}" id="{{id}}_media-mute-toggle"/><label class="form-check-label" for="{{id}}_media-mute-toggle">{{get_string "mute" component}}</label></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.MEDIA_LOOP_TOGGLE}}" id="{{id}}_media-loop-toggle"/><label class="form-check-label" for="{{id}}_media-loop-toggle">{{get_string "loop" component}}</label></div></div>',
-TRACK_TABS:'<ul class="nav nav-tabs mb-3"><li data-track-kind="{{CSS.TRACK_SUBTITLES}}" class="nav-item"><a class="nav-link active" href="#{{elementid}}_{{id}}_{{CSS.TRACK_SUBTITLES}}" role="tab" data-toggle="tab">{{get_string "subtitles" component}}</a></li><li data-track-kind="{{CSS.TRACK_CAPTIONS}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_CAPTIONS}}" role="tab" data-toggle="tab">{{get_string "captions" component}}</a></li><li data-track-kind="{{CSS.TRACK_DESCRIPTIONS}}"  class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_DESCRIPTIONS}}" role="tab" data-toggle="tab">{{get_string "descriptions" component}}</a></li><li data-track-kind="{{CSS.TRACK_CHAPTERS}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_CHAPTERS}}" role="tab" data-toggle="tab">{{get_string "chapters" component}}</a></li><li data-track-kind="{{CSS.TRACK_METADATA}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_METADATA}}" role="tab" data-toggle="tab">{{get_string "metadata" component}}</a></li></ul><div class="tab-content"><div data-track-kind="{{CSS.TRACK_SUBTITLES}}" class="tab-pane active" id="{{elementid}}_{{id}}_{{CSS.TRACK_SUBTITLES}}"><div class="trackhelp">{{{helpStrings.subtitles}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="subtitlessourcelabel" addcomponentlabel="addsubtitlestrack"}}</div><div data-track-kind="{{CSS.TRACK_CAPTIONS}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_CAPTIONS}}"><div class="trackhelp">{{{helpStrings.captions}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="captionssourcelabel" addcomponentlabel="addcaptionstrack"}}</div><div data-track-kind="{{CSS.TRACK_DESCRIPTIONS}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_DESCRIPTIONS}}"><div class="trackhelp">{{{helpStrings.descriptions}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="descriptionssourcelabel" addcomponentlabel="adddescriptionstrack"}}</div><div data-track-kind="{{CSS.TRACK_CHAPTERS}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_CHAPTERS}}"><div class="trackhelp">{{{helpStrings.chapters}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="chapterssourcelabel" addcomponentlabel="addchapterstrack"}}</div><div data-track-kind="{{CSS.TRACK_METADATA}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_METADATA}}"><div class="trackhelp">{{{helpStrings.metadata}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="metadatasourcelabel" addcomponentlabel="addmetadatatrack"}}</div></div>',TRACK:'<div class="mb-1 {{CSS.TRACK}}">{{renderPartial "form_components.source" context=this id=CSS.TRACK_SOURCE entersourcelabel=sourcelabel}}<div class="form-group"><label class="w-100" for="lang-input">{{get_string "srclang" component}}</label><select id="lang-input" class="custom-select {{CSS.TRACK_LANG_INPUT}}"><optgroup label="{{get_string "languagesinstalled" component}}">{{#langsinstalled}}<option value="{{code}}" {{#default}}selected="selected"{{/default}}>{{lang}}</option>{{/langsinstalled}}</optgroup><optgroup label="{{get_string "languagesavailable" component}} ">{{#langsavailable}}<option value="{{code}}">{{lang}}</option>{{/langsavailable}}</optgroup></select></div><div class="form-group"><label class="w-100" for="track-input">{{get_string "label" component}}</label><input id="track-input" class="form-control {{CSS.TRACK_LABEL_INPUT}}" type="text"/></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.TRACK_DEFAULT_SELECT}}"/><label class="form-check-label">{{get_string "default" component}}</label></div>{{renderPartial "form_components.add_component" context=this label=addcomponentlabel}}</div>'},HTML_MEDIA:{VIDEO:'&nbsp;<video {{#width}}width="{{../width}}" {{/width}}{{#height}}height="{{../height}}" {{/height}}{{#poster}}poster="{{../poster}}" {{/poster}}{{#showControls}}controls="true" {{/showControls}}{{#loop}}loop="true" {{/loop}}{{#muted}}muted="true" {{/muted}}{{#autoplay}}autoplay="true" {{/autoplay}}{{#title}}title="{{../title}}" {{/title}}>{{#sources}}<source src="{{source}}">{{/sources}}{{#tracks}}<track src="{{track}}" kind="{{kind}}" srclang="{{srclang}}" label="{{label}}" {{#defaultTrack}}default="true"{{/defaultTrack}}>{{/tracks}}{{#description}}{{../description}}{{/description}}</video>&nbsp',AUDIO:'&nbsp;<audio {{#showControls}}controls="true" {{/showControls}}{{#loop}}loop="true" {{/loop}}{{#muted}}muted="true" {{/muted}}{{#autoplay}}autoplay="true" {{/autoplay}}{{#title}}title="{{../title}}" {{/title}}>{{#sources}}<source src="{{source}}">{{/sources}}{{#tracks}}<track src="{{track}}" kind="{{kind}}" srclang="{{srclang}}" label="{{label}}" {{#defaultTrack}}default="true"{{/defaultTrack}}>{{/tracks}}{{#description}}{{../description}}{{/description}}</audio>&nbsp',LINK:'<a href="{{url}}" {{#width}}data-width="{{../width}}" {{/width}}{{#height}}data-height="{{../height}}"{{/height}}>{{#name}}{{../name}}{{/name}}{{^name}}{{../url}}{{/name}}</a>'}};l.namespace("M.atto_media").Button=l.Base.create("button",l.M.editor_atto.EditorPlugin,[],{initializer:function(){this.get("host").canShowFilepicker("media")&&(this.editor.delegate("dblclick",this._displayDialogue,"video",this),this.editor.delegate("click",this._handleClick,"video",this),this.addButton({icon:"e/insert_edit_video",callback:this._displayDialogue,tags:"video, audio",tagMatchRequiresAll:!1}))},_getContext:function(e){return l.merge({elementid:this.get("host").get("elementid"),component:t,langsinstalled:this.get("langs").installed,langsavailable:this.get("langs").available,helpStrings:this.get("help"),CSS:o},e)},_handleClick:function(e){e=e.target,e=this.get("host").getSelectionFromNode(e);this.get("host").getSelection()!==e&&this.get("host").setSelection(e)},_displayDialogue:function(){!1!==this.get("host").getSelection()&&("renderPartial"in l.Handlebars.helpers||(
-function i(a,e){l.each(e,function(e,t){a.push(t),"object"!=typeof e?l.Handlebars.registerPartial(a.join(".").toLowerCase(),e):i(a,e),a.pop()})}([],r),l.Handlebars.registerHelper("renderPartial",function(e,t){var a;return e?(e=l.Handlebars.partials[e],a=t.hash.context?l.clone(t.hash.context):{},delete(a=l.merge(a,t.hash)).context,e?new l.Handlebars.SafeString(l.Handlebars.compile(e)(a)):""):""})),this.getDialogue({headerContent:M.util.get_string("createmedia",t),focusAfterHide:!0,width:660,focusOnShowSelector:s.URL_INPUT}).set("bodyContent",this._getDialogueContent(this.get("host").getSelection())).show(),M.form.shortforms({formid:this.get("host").get("elementid")+"_atto_media_form"}))},_getDialogueContent:function(e){var t=l.Node.create(l.Handlebars.compile(r.ROOT)(this._getContext())),a=this.get("host").getSelectedNodes().filter("video,audio").shift(),a=!!a&&this._getMediumProperties(a);return this._attachEvents(this._applyMediumProperties(t,a),e)},_attachEvents:function(e,a){return e.delegate("click",function(e){e.preventDefault(),this._addMediaSourceComponent(e.currentTarget)},s.MEDIA_SOURCE+" .addcomponent",this),e.delegate("click",function(e){e.preventDefault(),this._addTrackComponent(e.currentTarget)},s.TRACK+" .addcomponent",this),e.delegate("click",function(e){var t,a=e.currentTarget;a.get("checked")&&(t=function(e){return this._getTrackTypeFromTabPane(e.ancestor(".tab-pane"))}.bind(this),a.ancestor(".root.tab-content").all(s.TRACK_DEFAULT_SELECT).each(function(e){e!==a&&t(a)===t(e)&&e.set("checked",!1)}))},s.TRACK_DEFAULT_SELECT,this),e.delegate("click",function(e){var t=e.currentTarget,a=(t.ancestor(s.POSTER_SOURCE)?"image":t.ancestor(s.TRACK_SOURCE)&&"subtitle")||"media";e.preventDefault(),this.get("host").showFilepicker(a,this._getFilepickerCallback(t,a),this)},".openmediabrowser",this),e.all(".nav-item").on("click",function(e){e.currentTarget.get("parentNode").all(".active").removeClass("active")}),e.one(".submit").on("click",function(e){e.preventDefault();var e=this._getMediaHTML(e.currentTarget.ancestor(".atto_form")),t=this.get("host");this.getDialogue({focusAfterHide:null}).hide(),e&&(t.setSelection(a),t.insertContentAtFocusPoint(e),this.markUpdated())},this),e},_applyMediumProperties:function(e,t){var i,n,a;return t&&(i=function(e,t){e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).set("value",t.src),e.one(s.TRACK_LANG_INPUT).set("value",t.srclang),e.one(s.TRACK_LABEL_INPUT).set("value",t.label),e.one(s.TRACK_DEFAULT_SELECT).set("checked",t.defaultTrack)},(n=e.one(".root.tab-content > .tab-pane#"+this.get("host").get("elementid")+"_"+t.type.toLowerCase())).one(s.MEDIA_SOURCE+" "+s.URL_INPUT).set("value",t.sources[0]),l.Array.each(t.sources.slice(1),function(t){this._addMediaSourceComponent(n.one(s.MEDIA_SOURCE+" .addcomponent"),function(e){e.one(s.URL_INPUT).set("value",t)})},this),l.Object.each(t.tracks,function(e,t){var e=e.length?e:[{src:"",srclang:"",label:"",defaultTrack:!1}],a=s["TRACK_"+t.toUpperCase()+"_PANE"];i(n.one(a+" "+s.TRACK),e[0]),l.Array.each(e.slice(1),function(t){this._addTrackComponent(n.one(a+" "+s.TRACK+" .addcomponent"),function(e){i(e,t)})},this)},this),n.one(s.TITLE_INPUT).set("value",t.title),n.one(s.MEDIA_CONTROLS_TOGGLE).set("checked",t.controls),n.one(s.MEDIA_AUTOPLAY_TOGGLE).set("checked",t.autoplay),n.one(s.MEDIA_MUTE_TOGGLE).set("checked",t.muted),n.one(s.MEDIA_LOOP_TOGGLE).set("checked",t.loop),"video"===(a=this._getMediumTypeFromTabPane(n))&&(n.one(s.POSTER_SOURCE+" "+s.URL_INPUT).setAttribute("value",t.poster),n.one(s.WIDTH_INPUT).set("value",t.width),n.one(s.HEIGHT_INPUT).set("value",t.height)),n.siblings(".active").removeClass("active"),e.all(".root.nav-tabs .nav-item a").removeClass("active"),n.addClass("active"),e.one(s[a.toUpperCase()+"_TAB"]+" a").addClass("active")),e},_getMediumProperties:function(e){var t=function(e,t){return e.hasAttribute(t)&&(e.getAttribute(t)||""===e.getAttribute(t))},a={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]};return e.all("track").each(function(e){a[e.getAttribute("kind")].push({src:e.getAttribute("src"),srclang:e.getAttribute("srclang"),label:e.getAttribute("label"),defaultTrack:t(e,"default")})}),{type:e.test("video")?i.VIDEO:i.AUDIO,sources:e.all("source").get("src"),poster:e.getAttribute("poster"),title:e.getAttribute("title"),width:e.getAttribute("width"),height:e.getAttribute("height"),autoplay:t(e,"autoplay"),loop:t(e,"loop"),muted:t(e,"muted"),controls:t(e,"controls"),tracks:a}},_addTrackComponent:function(e,t){var a=this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({sourcelabel:a+"sourcelabel",addcomponentlabel:"add"+a+"track"});this._addComponent(e,r.FORM_COMPONENTS.TRACK,s.TRACK,a,t)},_addMediaSourceComponent:function(e,t){var a=this._getMediumTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({multisource:!0,id:o.MEDIA_SOURCE,entersourcelabel:a+"sourcelabel",addcomponentlabel:"addsource",addsourcehelp:this.get("help").addsource});this._addComponent(e,r.FORM_COMPONENTS.SOURCE,s.MEDIA_SOURCE,a,t)},_addComponent:function(e,t,a,i,n){var o=e.ancestor(a),a=l.Node.create(l.Handlebars.compile(t)(i)),t=this._getContext(i);t.label="remove",(i=l.Node.create(l.Handlebars.compile(r.FORM_COMPONENTS.REMOVE_COMPONENT)(t))).one(".removecomponent").on("click",function(e){e.preventDefault(),o.remove(!0)}),o.insert(a,"after"),e.ancestor().insert(i,"after"),e.ancestor().remove(!0),n&&n.call(this,a)},_getFilepickerCallback:function(i,n){return function(e){var a,t;""!==e.url&&(t=i.ancestor(".tab-pane"),i.ancestor(s.SOURCE).one(s.URL_INPUT).set("value",e.url),t.get("id")===this.get("host").get("elementid")+"_"+o.LINK&&t.one(s.NAME_INPUT).set("value",e.file),"subtitle"===n&&(a=e.file.split(".vtt")[0].split("-").slice(-1)[0],(t=this.get("langs").available.reduce(function(e,t){return t.code===a?t:e},!1))&&(i.ancestor(s.TRACK).one(s.TRACK_LABEL_INPUT).set("value",t.lang.substr(0,t.lang.lastIndexOf(" "))),i.ancestor(s.TRACK).one(s.TRACK_LANG_INPUT).set("value",t.code))))}},
-_getMediumTypeFromTabPane:function(e){return e.getAttribute("data-medium-type")},_getTrackTypeFromTabPane:function(e){return e.getAttribute("data-track-kind")},_getMediaHTML:function(e){var t=this._getMediumTypeFromTabPane(e.one(".root.tab-content > .tab-pane.active")),e=e.one(s[t.toUpperCase()+"_PANE"]);return this["_getMediaHTML"+t[0].toUpperCase()+t.substr(1)](e)},_getMediaHTMLLink:function(e){e={url:e.one(s.URL_INPUT).get("value"),name:e.one(s.NAME_INPUT).get("value")||!1};return e.url?l.Handlebars.compile(r.HTML_MEDIA.LINK)(e):""},_getMediaHTMLVideo:function(e){var t=this._getContextForMediaHTML(e);return t.width=e.one(s.WIDTH_INPUT).get("value")||!1,t.height=e.one(s.HEIGHT_INPUT).get("value")||!1,t.poster=e.one(s.POSTER_SOURCE+" "+s.URL_INPUT).get("value")||!1,t.sources.length?l.Handlebars.compile(r.HTML_MEDIA.VIDEO)(t):""},_getMediaHTMLAudio:function(e){e=this._getContextForMediaHTML(e);return e.sources.length?l.Handlebars.compile(r.HTML_MEDIA.AUDIO)(e):""},_getContextForMediaHTML:function(e){var t=[];return e.all(s.TRACK).each(function(e){t.push({track:e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).get("value"),kind:this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),label:e.one(s.TRACK_LABEL_INPUT).get("value")||e.one(s.TRACK_LANG_INPUT).get("value"),srclang:e.one(s.TRACK_LANG_INPUT).get("value"),defaultTrack:e.one(s.TRACK_DEFAULT_SELECT).get("checked")?"true":null})},this),{sources:e.all(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value").filter(function(e){return!!e}).map(function(e){return{source:e}}),description:e.one(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value")||!1,tracks:t.filter(function(e){return!!e.track}),showControls:e.one(s.MEDIA_CONTROLS_TOGGLE).get("checked"),autoplay:e.one(s.MEDIA_AUTOPLAY_TOGGLE).get("checked"),muted:e.one(s.MEDIA_MUTE_TOGGLE).get("checked"),loop:e.one(s.MEDIA_LOOP_TOGGLE).get("checked"),title:e.one(s.TITLE_INPUT).get("value")||!1}}},{ATTRS:{langs:{},help:{}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-form-shortforms"]});
\ No newline at end of file
+VIDEO:'{{renderPartial "form_components.source" context=this id=CSS.MEDIA_SOURCE entersourcelabel="videosourcelabel" addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}<fieldset class="collapsible collapsed" id="{{elementid}}_video-display-options"><input name="mform_isexpanded_{{elementid}}_video-display-options" type="hidden">{{renderPartial "form_components.section" context=this id="vdisplayoptions" name="displayoptions"}}<div id="vdisplayoptions" class="fcontainer collapseable collapse px-1">{{renderPartial "form_components.display_options" context=this id=CSS.VIDEO mediatype_video=true}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_video-advanced-settings"><input name="mform_isexpanded_{{elementid}}_video-advanced-settings" type="hidden">{{renderPartial "form_components.section" context=this id="vadvancedsettings" name="advancedsettings"}}<div id="vadvancedsettings" class="fcontainer collapseable collapse px-1">{{renderPartial "form_components.advanced_settings" context=this id=CSS.VIDEO}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_video-tracks"><input name="mform_isexpanded_{{elementid}}_video-tracks" type="hidden">{{renderPartial "form_components.section" context=this id="vtracks" name="tracks" help=helpStrings.tracks}}<div id="vtracks" class="fcontainer collapseable collapse px-1">{{renderPartial "form_components.track_tabs" context=this id=CSS.VIDEO}}</div></fieldset>',AUDIO:'{{renderPartial "form_components.source" context=this id=CSS.MEDIA_SOURCE entersourcelabel="audiosourcelabel" addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}<fieldset class="collapsible collapsed" id="{{elementid}}_audio-display-options"><input name="mform_isexpanded_{{elementid}}_audio-display-options" type="hidden">{{renderPartial "form_components.section" context=this id="adisplayoptions" name="displayoptions"}}<div id="adisplayoptions" class="fcontainer collapseable collapse px-1">{{renderPartial "form_components.display_options" context=this id=CSS.AUDIO}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_audio-advanced-settings"><input name="mform_isexpanded_{{elementid}}_audio-advanced-settings" type="hidden">{{renderPartial "form_components.section" context=this id="aadvancedsettings" name="advancedsettings"}}<div id="aadvancedsettings" class="fcontainer collapseable collapse px-1">{{renderPartial "form_components.advanced_settings" context=this id=CSS.AUDIO}}</div></fieldset><fieldset class="collapsible collapsed" id="{{elementid}}_audio-tracks"><input name="mform_isexpanded_{{elementid}}_audio-tracks" type="hidden">{{renderPartial "form_components.section" context=this id="atracks" name="tracks" help=helpStrings.tracks}}<div id="atracks" class="fcontainer collapseable collapse px-1">{{renderPartial "form_components.track_tabs" context=this id=CSS.AUDIO}}</div></fieldset>'},FORM_COMPONENTS:{SOURCE:'<div class="{{CSS.SOURCE}} {{id}}"><div class="mb-1"><label for="url-input">{{#entersourcelabel}}{{get_string ../entersourcelabel ../component}}{{/entersourcelabel}}{{^entersourcelabel}}{{get_string "entersource" ../component}}{{/entersourcelabel}}</label><div class="input-group input-append w-100"><input id="url-input" class="form-control {{CSS.URL_INPUT}}" type="url" size="32"/><span class="input-group-append"><button class="btn btn-secondary openmediabrowser" type="button">{{get_string "browserepositories" component}}</button></span></div></div>{{#multisource}}{{renderPartial "form_components.add_component" context=../this label=../addcomponentlabel  help=../addsourcehelp}}{{/multisource}}</div>',ADD_COMPONENT:'<div><a href="#" class="addcomponent">{{#label}}{{get_string ../label ../component}}{{/label}}{{^label}}{{get_string "add" ../component}}{{/label}}</a>{{#help}}{{{../help}}}{{/help}}</div>',REMOVE_COMPONENT:'<div><a href="#" class="removecomponent">{{#label}}{{get_string ../label ../component}}{{/label}}{{^label}}{{get_string "remove" ../component}}{{/label}}</a></div>',DISPLAY_OPTIONS:'<div class="{{CSS.DISPLAY_OPTIONS}}"><div class="mb-1"><label for="{{id}}_media-title-entry">{{get_string "entertitle" component}}</label><input class="form-control fullwidth {{CSS.TITLE_INPUT}}" type="text" id="{{id}}_media-title-entry"size="32"/></div><div class="clearfix"></div>{{#mediatype_video}}<div class="mb-1"><label>{{get_string "size" component}}</label><div class="form-inline {{CSS.POSTER_SIZE}}"><label class="accesshide">{{get_string "videowidth" component}}</label><input type="text" class="form-control mr-1 {{CSS.WIDTH_INPUT}} input-mini" size="4"/> x <label class="accesshide">{{get_string "videoheight" component}}</label><input type="text" class="form-control ml-1 {{CSS.HEIGHT_INPUT}} input-mini" size="4"/></div></div><div class="clearfix"></div>{{renderPartial "form_components.source" context=this id=CSS.POSTER_SOURCE entersourcelabel="poster"}}{{/mediatype_video}}<div>',
+ADVANCED_SETTINGS:'<div class="{{CSS.ADVANCED_SETTINGS}}"><div class="form-check"><input type="checkbox" checked="true" class="form-check-input {{CSS.MEDIA_CONTROLS_TOGGLE}}"id="{{id}}_media-controls-toggle"/><label class="form-check-label" for="{{id}}_media-controls-toggle">{{get_string "controls" component}}</label></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.MEDIA_AUTOPLAY_TOGGLE}}"id="{{id}}_media-autoplay-toggle"/><label class="form-check-label" for="{{id}}_media-autoplay-toggle">{{get_string "autoplay" component}}</label></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.MEDIA_MUTE_TOGGLE}}" id="{{id}}_media-mute-toggle"/><label class="form-check-label" for="{{id}}_media-mute-toggle">{{get_string "mute" component}}</label></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.MEDIA_LOOP_TOGGLE}}" id="{{id}}_media-loop-toggle"/><label class="form-check-label" for="{{id}}_media-loop-toggle">{{get_string "loop" component}}</label></div></div>',TRACK_TABS:'<ul class="nav nav-tabs mb-3"><li data-track-kind="{{CSS.TRACK_SUBTITLES}}" class="nav-item"><a class="nav-link active" href="#{{elementid}}_{{id}}_{{CSS.TRACK_SUBTITLES}}" role="tab" data-toggle="tab">{{get_string "subtitles" component}}</a></li><li data-track-kind="{{CSS.TRACK_CAPTIONS}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_CAPTIONS}}" role="tab" data-toggle="tab">{{get_string "captions" component}}</a></li><li data-track-kind="{{CSS.TRACK_DESCRIPTIONS}}"  class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_DESCRIPTIONS}}" role="tab" data-toggle="tab">{{get_string "descriptions" component}}</a></li><li data-track-kind="{{CSS.TRACK_CHAPTERS}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_CHAPTERS}}" role="tab" data-toggle="tab">{{get_string "chapters" component}}</a></li><li data-track-kind="{{CSS.TRACK_METADATA}}" class="nav-item"><a class="nav-link" href="#{{elementid}}_{{id}}_{{CSS.TRACK_METADATA}}" role="tab" data-toggle="tab">{{get_string "metadata" component}}</a></li></ul><div class="tab-content"><div data-track-kind="{{CSS.TRACK_SUBTITLES}}" class="tab-pane active" id="{{elementid}}_{{id}}_{{CSS.TRACK_SUBTITLES}}"><div class="trackhelp">{{{helpStrings.subtitles}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="subtitlessourcelabel" addcomponentlabel="addsubtitlestrack"}}</div><div data-track-kind="{{CSS.TRACK_CAPTIONS}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_CAPTIONS}}"><div class="trackhelp">{{{helpStrings.captions}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="captionssourcelabel" addcomponentlabel="addcaptionstrack"}}</div><div data-track-kind="{{CSS.TRACK_DESCRIPTIONS}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_DESCRIPTIONS}}"><div class="trackhelp">{{{helpStrings.descriptions}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="descriptionssourcelabel" addcomponentlabel="adddescriptionstrack"}}</div><div data-track-kind="{{CSS.TRACK_CHAPTERS}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_CHAPTERS}}"><div class="trackhelp">{{{helpStrings.chapters}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="chapterssourcelabel" addcomponentlabel="addchapterstrack"}}</div><div data-track-kind="{{CSS.TRACK_METADATA}}" class="tab-pane" id="{{elementid}}_{{id}}_{{CSS.TRACK_METADATA}}"><div class="trackhelp">{{{helpStrings.metadata}}}</div>{{renderPartial "form_components.track" context=this sourcelabel="metadatasourcelabel" addcomponentlabel="addmetadatatrack"}}</div></div>',TRACK:'<div class="mb-1 {{CSS.TRACK}}">{{renderPartial "form_components.source" context=this id=CSS.TRACK_SOURCE entersourcelabel=sourcelabel}}<div class="form-group"><label class="w-100" for="lang-input">{{get_string "srclang" component}}</label><select id="lang-input" class="custom-select {{CSS.TRACK_LANG_INPUT}}"><optgroup label="{{get_string "languagesinstalled" component}}">{{#langsinstalled}}<option value="{{code}}" {{#default}}selected="selected"{{/default}}>{{lang}}</option>{{/langsinstalled}}</optgroup><optgroup label="{{get_string "languagesavailable" component}} ">{{#langsavailable}}<option value="{{code}}">{{lang}}</option>{{/langsavailable}}</optgroup></select></div><div class="form-group"><label class="w-100" for="track-input">{{get_string "label" component}}</label><input id="track-input" class="form-control {{CSS.TRACK_LABEL_INPUT}}" type="text"/></div><div class="form-check"><input type="checkbox" class="form-check-input {{CSS.TRACK_DEFAULT_SELECT}}"/><label class="form-check-label">{{get_string "default" component}}</label></div>{{renderPartial "form_components.add_component" context=this label=addcomponentlabel}}</div>',SECTION:'<legend class="d-flex align-items-center px-1"><div class="position-relative d-flex ftoggler align-items-center position-relative mr-1"><a role="button" data-toggle="collapse" href="#{{id}}" aria-expanded="false"aria-controls="{{id}}"class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed"><span class="expanded-icon icon-no-margin p-2" title="{{get_string "collapse" "moodle"}}"><i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i></span><span class="collapsed-icon icon-no-margin p-2" title="{{get_string "expand" "moodle"}}"><i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i></span><span class="sr-only">{{get_string name component}}</span></a><h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">{{get_string name component}}</h3></div>{{#help}}{{{../help}}}{{/help}}</legend>'},HTML_MEDIA:{
+VIDEO:'&nbsp;<video {{#width}}width="{{../width}}" {{/width}}{{#height}}height="{{../height}}" {{/height}}{{#poster}}poster="{{../poster}}" {{/poster}}{{#showControls}}controls="true" {{/showControls}}{{#loop}}loop="true" {{/loop}}{{#muted}}muted="true" {{/muted}}{{#autoplay}}autoplay="true" {{/autoplay}}{{#title}}title="{{../title}}" {{/title}}>{{#sources}}<source src="{{source}}">{{/sources}}{{#tracks}}<track src="{{track}}" kind="{{kind}}" srclang="{{srclang}}" label="{{label}}" {{#defaultTrack}}default="true"{{/defaultTrack}}>{{/tracks}}{{#description}}{{../description}}{{/description}}</video>&nbsp',AUDIO:'&nbsp;<audio {{#showControls}}controls="true" {{/showControls}}{{#loop}}loop="true" {{/loop}}{{#muted}}muted="true" {{/muted}}{{#autoplay}}autoplay="true" {{/autoplay}}{{#title}}title="{{../title}}" {{/title}}>{{#sources}}<source src="{{source}}">{{/sources}}{{#tracks}}<track src="{{track}}" kind="{{kind}}" srclang="{{srclang}}" label="{{label}}" {{#defaultTrack}}default="true"{{/defaultTrack}}>{{/tracks}}{{#description}}{{../description}}{{/description}}</audio>&nbsp',LINK:'<a href="{{url}}" {{#width}}data-width="{{../width}}" {{/width}}{{#height}}data-height="{{../height}}"{{/height}}>{{#name}}{{../name}}{{/name}}{{^name}}{{../url}}{{/name}}</a>'}};l.namespace("M.atto_media").Button=l.Base.create("button",l.M.editor_atto.EditorPlugin,[],{initializer:function(){this.get("host").canShowFilepicker("media")&&(this.editor.delegate("dblclick",this._displayDialogue,"video",this),this.editor.delegate("click",this._handleClick,"video",this),this.addButton({icon:"e/insert_edit_video",callback:this._displayDialogue,tags:"video, audio",tagMatchRequiresAll:!1}))},_getContext:function(e){return l.merge({elementid:this.get("host").get("elementid"),component:t,langsinstalled:this.get("langs").installed,langsavailable:this.get("langs").available,helpStrings:this.get("help"),CSS:o},e)},_handleClick:function(e){e=e.target,e=this.get("host").getSelectionFromNode(e);this.get("host").getSelection()!==e&&this.get("host").setSelection(e)},_displayDialogue:function(){!1!==this.get("host").getSelection()&&("renderPartial"in l.Handlebars.helpers||(function i(a,e){l.each(e,function(e,t){a.push(t),"object"!=typeof e?l.Handlebars.registerPartial(a.join(".").toLowerCase(),e):i(a,e),a.pop()})}([],r),l.Handlebars.registerHelper("renderPartial",function(e,t){var a;return e?(e=l.Handlebars.partials[e],a=t.hash.context?l.clone(t.hash.context):{},delete(a=l.merge(a,t.hash)).context,e?new l.Handlebars.SafeString(l.Handlebars.compile(e)(a)):""):""})),this.getDialogue({headerContent:M.util.get_string("createmedia",t),focusAfterHide:!0,width:660,focusOnShowSelector:s.URL_INPUT}).set("bodyContent",this._getDialogueContent(this.get("host").getSelection())).show(),M.form.shortforms({formid:this.get("host").get("elementid")+"_atto_media_form"}))},_getDialogueContent:function(e){var t=l.Node.create(l.Handlebars.compile(r.ROOT)(this._getContext())),a=this.get("host").getSelectedNodes().filter("video,audio").shift(),a=!!a&&this._getMediumProperties(a);return this._attachEvents(this._applyMediumProperties(t,a),e)},_attachEvents:function(e,a){return e.delegate("click",function(e){e.preventDefault(),this._addMediaSourceComponent(e.currentTarget)},s.MEDIA_SOURCE+" .addcomponent",this),e.delegate("click",function(e){e.preventDefault(),this._addTrackComponent(e.currentTarget)},s.TRACK+" .addcomponent",this),e.delegate("click",function(e){var t,a=e.currentTarget;a.get("checked")&&(t=function(e){return this._getTrackTypeFromTabPane(e.ancestor(".tab-pane"))}.bind(this),a.ancestor(".root.tab-content").all(s.TRACK_DEFAULT_SELECT).each(function(e){e!==a&&t(a)===t(e)&&e.set("checked",!1)}))},s.TRACK_DEFAULT_SELECT,this),e.delegate("click",function(e){var t=e.currentTarget,a=(t.ancestor(s.POSTER_SOURCE)?"image":t.ancestor(s.TRACK_SOURCE)&&"subtitle")||"media";e.preventDefault(),this.get("host").showFilepicker(a,this._getFilepickerCallback(t,a),this)},".openmediabrowser",this),e.all(".nav-item").on("click",function(e){e.currentTarget.get("parentNode").all(".active").removeClass("active")}),e.one(".submit").on("click",function(e){e.preventDefault();var e=this._getMediaHTML(e.currentTarget.ancestor(".atto_form")),t=this.get("host");this.getDialogue({focusAfterHide:null}).hide(),e&&(t.setSelection(a),t.insertContentAtFocusPoint(e),this.markUpdated())},this),e},_applyMediumProperties:function(e,t){var i,n,a;return t&&(i=function(e,t){e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).set("value",t.src),e.one(s.TRACK_LANG_INPUT).set("value",t.srclang),e.one(s.TRACK_LABEL_INPUT).set("value",t.label),e.one(s.TRACK_DEFAULT_SELECT).set("checked",t.defaultTrack)},(n=e.one(".root.tab-content > .tab-pane#"+this.get("host").get("elementid")+"_"+t.type.toLowerCase())).one(s.MEDIA_SOURCE+" "+s.URL_INPUT).set("value",t.sources[0]),l.Array.each(t.sources.slice(1),function(t){this._addMediaSourceComponent(n.one(s.MEDIA_SOURCE+" .addcomponent"),function(e){e.one(s.URL_INPUT).set("value",t)})},this),l.Object.each(t.tracks,function(e,t){var e=e.length?e:[{src:"",srclang:"",label:"",defaultTrack:!1}],a=s["TRACK_"+t.toUpperCase()+"_PANE"];i(n.one(a+" "+s.TRACK),e[0]),l.Array.each(e.slice(1),function(t){this._addTrackComponent(n.one(a+" "+s.TRACK+" .addcomponent"),function(e){i(e,t)})},this)},this),n.one(s.TITLE_INPUT).set("value",t.title),n.one(s.MEDIA_CONTROLS_TOGGLE).set("checked",t.controls),n.one(s.MEDIA_AUTOPLAY_TOGGLE).set("checked",t.autoplay),n.one(s.MEDIA_MUTE_TOGGLE).set("checked",t.muted),n.one(s.MEDIA_LOOP_TOGGLE).set("checked",t.loop),"video"===(a=this._getMediumTypeFromTabPane(n))&&(n.one(s.POSTER_SOURCE+" "+s.URL_INPUT).setAttribute("value",t.poster),n.one(s.WIDTH_INPUT).set("value",t.width),n.one(s.HEIGHT_INPUT).set("value",t.height)),n.siblings(".active").removeClass("active"),e.all(".root.nav-tabs .nav-item a").removeClass("active"),n.addClass("active"),e.one(s[a.toUpperCase()+"_TAB"]+" a").addClass("active")),e},_getMediumProperties:function(e){
+var t=function(e,t){return e.hasAttribute(t)&&(e.getAttribute(t)||""===e.getAttribute(t))},a={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]};return e.all("track").each(function(e){a[e.getAttribute("kind")].push({src:e.getAttribute("src"),srclang:e.getAttribute("srclang"),label:e.getAttribute("label"),defaultTrack:t(e,"default")})}),{type:e.test("video")?i.VIDEO:i.AUDIO,sources:e.all("source").get("src"),poster:e.getAttribute("poster"),title:e.getAttribute("title"),width:e.getAttribute("width"),height:e.getAttribute("height"),autoplay:t(e,"autoplay"),loop:t(e,"loop"),muted:t(e,"muted"),controls:t(e,"controls"),tracks:a}},_addTrackComponent:function(e,t){var a=this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({sourcelabel:a+"sourcelabel",addcomponentlabel:"add"+a+"track"});this._addComponent(e,r.FORM_COMPONENTS.TRACK,s.TRACK,a,t)},_addMediaSourceComponent:function(e,t){var a=this._getMediumTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({multisource:!0,id:o.MEDIA_SOURCE,entersourcelabel:a+"sourcelabel",addcomponentlabel:"addsource",addsourcehelp:this.get("help").addsource});this._addComponent(e,r.FORM_COMPONENTS.SOURCE,s.MEDIA_SOURCE,a,t)},_addComponent:function(e,t,a,i,n){var o=e.ancestor(a),a=l.Node.create(l.Handlebars.compile(t)(i)),t=this._getContext(i);t.label="remove",(i=l.Node.create(l.Handlebars.compile(r.FORM_COMPONENTS.REMOVE_COMPONENT)(t))).one(".removecomponent").on("click",function(e){e.preventDefault(),o.remove(!0)}),o.insert(a,"after"),e.ancestor().insert(i,"after"),e.ancestor().remove(!0),n&&n.call(this,a)},_getFilepickerCallback:function(i,n){return function(e){var a,t;""!==e.url&&(t=i.ancestor(".tab-pane"),i.ancestor(s.SOURCE).one(s.URL_INPUT).set("value",e.url),t.get("id")===this.get("host").get("elementid")+"_"+o.LINK&&t.one(s.NAME_INPUT).set("value",e.file),"subtitle"===n&&(a=e.file.split(".vtt")[0].split("-").slice(-1)[0],(t=this.get("langs").available.reduce(function(e,t){return t.code===a?t:e},!1))&&(i.ancestor(s.TRACK).one(s.TRACK_LABEL_INPUT).set("value",t.lang.substr(0,t.lang.lastIndexOf(" "))),i.ancestor(s.TRACK).one(s.TRACK_LANG_INPUT).set("value",t.code))))}},_getMediumTypeFromTabPane:function(e){return e.getAttribute("data-medium-type")},_getTrackTypeFromTabPane:function(e){return e.getAttribute("data-track-kind")},_getMediaHTML:function(e){var t=this._getMediumTypeFromTabPane(e.one(".root.tab-content > .tab-pane.active")),e=e.one(s[t.toUpperCase()+"_PANE"]);return this["_getMediaHTML"+t[0].toUpperCase()+t.substr(1)](e)},_getMediaHTMLLink:function(e){e={url:e.one(s.URL_INPUT).get("value"),name:e.one(s.NAME_INPUT).get("value")||!1};return e.url?l.Handlebars.compile(r.HTML_MEDIA.LINK)(e):""},_getMediaHTMLVideo:function(e){var t=this._getContextForMediaHTML(e);return t.width=e.one(s.WIDTH_INPUT).get("value")||!1,t.height=e.one(s.HEIGHT_INPUT).get("value")||!1,t.poster=e.one(s.POSTER_SOURCE+" "+s.URL_INPUT).get("value")||!1,t.sources.length?l.Handlebars.compile(r.HTML_MEDIA.VIDEO)(t):""},_getMediaHTMLAudio:function(e){e=this._getContextForMediaHTML(e);return e.sources.length?l.Handlebars.compile(r.HTML_MEDIA.AUDIO)(e):""},_getContextForMediaHTML:function(e){var t=[];return e.all(s.TRACK).each(function(e){t.push({track:e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).get("value"),kind:this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),label:e.one(s.TRACK_LABEL_INPUT).get("value")||e.one(s.TRACK_LANG_INPUT).get("value"),srclang:e.one(s.TRACK_LANG_INPUT).get("value"),defaultTrack:e.one(s.TRACK_DEFAULT_SELECT).get("checked")?"true":null})},this),{sources:e.all(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value").filter(function(e){return!!e}).map(function(e){return{source:e}}),description:e.one(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value")||!1,tracks:t.filter(function(e){return!!e.track}),showControls:e.one(s.MEDIA_CONTROLS_TOGGLE).get("checked"),autoplay:e.one(s.MEDIA_AUTOPLAY_TOGGLE).get("checked"),muted:e.one(s.MEDIA_MUTE_TOGGLE).get("checked"),loop:e.one(s.MEDIA_LOOP_TOGGLE).get("checked"),title:e.one(s.TITLE_INPUT).get("value")||!1}}},{ATTRS:{langs:{},help:{}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-form-shortforms"]});
\ No newline at end of file
diff --git a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js
index 5ffa2201561..f80eee7c5d5 100644
--- a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js
+++ b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js
@@ -162,22 +162,22 @@ var COMPONENTNAME = 'atto_media',
                     ' addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-display-options">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-display-options" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "displayoptions" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vdisplayoptions" name="displayoptions"}}' +
+                    '<div id="vdisplayoptions" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.display_options" context=this id=CSS.VIDEO mediatype_video=true}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-advanced-settings">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-advanced-settings" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "advancedsettings" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vadvancedsettings" name="advancedsettings"}}' +
+                    '<div id="vadvancedsettings" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.advanced_settings" context=this id=CSS.VIDEO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-tracks">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-tracks" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vtracks" name="tracks" help=helpStrings.tracks}}' +
+                    '<div id="vtracks" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.track_tabs" context=this id=CSS.VIDEO}}' +
                     '</div>' +
                 '</fieldset>',
@@ -186,22 +186,22 @@ var COMPONENTNAME = 'atto_media',
                     ' addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-display-options">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-display-options" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "displayoptions" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="adisplayoptions" name="displayoptions"}}' +
+                    '<div id="adisplayoptions" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.display_options" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-advanced-settings">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-advanced-settings" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "advancedsettings" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="aadvancedsettings" name="advancedsettings"}}' +
+                    '<div id="aadvancedsettings" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.advanced_settings" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-tracks">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-tracks" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="atracks" name="tracks" help=helpStrings.tracks}}' +
+                    '<div id="atracks" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.track_tabs" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>'
@@ -383,7 +383,27 @@ var COMPONENTNAME = 'atto_media',
                         '<label class="form-check-label">{{get_string "default" component}}</label>' +
                     '</div>' +
                     '{{renderPartial "form_components.add_component" context=this label=addcomponentlabel}}' +
-                '</div>'
+                '</div>',
+            SECTION: '' +
+                '<legend class="d-flex align-items-center px-1">' +
+                    '<div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">' +
+                        '<a role="button" data-toggle="collapse" href="#{{id}}" aria-expanded="false"' +
+                            'aria-controls="{{id}}"' +
+                            'class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed">' +
+                            '<span class="expanded-icon icon-no-margin p-2" title="{{get_string "collapse" "moodle"}}">' +
+                                '<i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i>' +
+                            '</span>' +
+                            '<span class="collapsed-icon icon-no-margin p-2" title="{{get_string "expand" "moodle"}}">' +
+                                '<i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i>' +
+                            '</span>' +
+                            '<span class="sr-only">{{get_string name component}}</span>' +
+                        '</a>' +
+                        '<h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">' +
+                            '{{get_string name component}}' +
+                        '</h3>' +
+                        '</div>' +
+                    '{{#help}}{{{../help}}}{{/help}}' +
+                '</legend>'
         },
         HTML_MEDIA: {
             VIDEO: '' +
diff --git a/lib/editor/atto/plugins/media/yui/src/button/js/button.js b/lib/editor/atto/plugins/media/yui/src/button/js/button.js
index 39e20cb8c31..91e7758faf2 100644
--- a/lib/editor/atto/plugins/media/yui/src/button/js/button.js
+++ b/lib/editor/atto/plugins/media/yui/src/button/js/button.js
@@ -160,22 +160,22 @@ var COMPONENTNAME = 'atto_media',
                     ' addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-display-options">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-display-options" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "displayoptions" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vdisplayoptions" name="displayoptions"}}' +
+                    '<div id="vdisplayoptions" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.display_options" context=this id=CSS.VIDEO mediatype_video=true}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-advanced-settings">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-advanced-settings" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "advancedsettings" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vadvancedsettings" name="advancedsettings"}}' +
+                    '<div id="vadvancedsettings" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.advanced_settings" context=this id=CSS.VIDEO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_video-tracks">' +
                     '<input name="mform_isexpanded_{{elementid}}_video-tracks" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="vtracks" name="tracks" help=helpStrings.tracks}}' +
+                    '<div id="vtracks" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.track_tabs" context=this id=CSS.VIDEO}}' +
                     '</div>' +
                 '</fieldset>',
@@ -184,22 +184,22 @@ var COMPONENTNAME = 'atto_media',
                     ' addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-display-options">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-display-options" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "displayoptions" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="adisplayoptions" name="displayoptions"}}' +
+                    '<div id="adisplayoptions" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.display_options" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-advanced-settings">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-advanced-settings" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "advancedsettings" component}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="aadvancedsettings" name="advancedsettings"}}' +
+                    '<div id="aadvancedsettings" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.advanced_settings" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>' +
                 '<fieldset class="collapsible collapsed" id="{{elementid}}_audio-tracks">' +
                     '<input name="mform_isexpanded_{{elementid}}_audio-tracks" type="hidden">' +
-                    '<legend class="ftoggler">{{get_string "tracks" component}} {{{helpStrings.tracks}}}</legend>' +
-                    '<div class="fcontainer">' +
+                    '{{renderPartial "form_components.section" context=this id="atracks" name="tracks" help=helpStrings.tracks}}' +
+                    '<div id="atracks" class="fcontainer collapseable collapse px-1">' +
                         '{{renderPartial "form_components.track_tabs" context=this id=CSS.AUDIO}}' +
                     '</div>' +
                 '</fieldset>'
@@ -381,7 +381,27 @@ var COMPONENTNAME = 'atto_media',
                         '<label class="form-check-label">{{get_string "default" component}}</label>' +
                     '</div>' +
                     '{{renderPartial "form_components.add_component" context=this label=addcomponentlabel}}' +
-                '</div>'
+                '</div>',
+            SECTION: '' +
+                '<legend class="d-flex align-items-center px-1">' +
+                    '<div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">' +
+                        '<a role="button" data-toggle="collapse" href="#{{id}}" aria-expanded="false"' +
+                            'aria-controls="{{id}}"' +
+                            'class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader collapsed">' +
+                            '<span class="expanded-icon icon-no-margin p-2" title="{{get_string "collapse" "moodle"}}">' +
+                                '<i class="icon fa fa-chevron-down fa-fw " aria-hidden="true"></i>' +
+                            '</span>' +
+                            '<span class="collapsed-icon icon-no-margin p-2" title="{{get_string "expand" "moodle"}}">' +
+                                '<i class="icon fa fa-chevron-right fa-fw " aria-hidden="true"></i>' +
+                            '</span>' +
+                            '<span class="sr-only">{{get_string name component}}</span>' +
+                        '</a>' +
+                        '<h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">' +
+                            '{{get_string name component}}' +
+                        '</h3>' +
+                        '</div>' +
+                    '{{#help}}{{{../help}}}{{/help}}' +
+                '</legend>'
         },
         HTML_MEDIA: {
             VIDEO: '' +
diff --git a/lib/form/amd/build/collapsesections.min.js b/lib/form/amd/build/collapsesections.min.js
new file mode 100644
index 00000000000..ef0d26732e5
--- /dev/null
+++ b/lib/form/amd/build/collapsesections.min.js
@@ -0,0 +1,2 @@
+define ("core_form/collapsesections",["exports","jquery","core/pending"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=d(b);c=d(c);function d(a){return a&&a.__esModule?a:{default:a}}var e={FORMCONTAINER:".fcontainer"},f={SHOW:"show",COLLAPSED:"collapsed"},g=function(a){var d=new c.default("core_form/collapsesections"),g=document.querySelector(a);g.addEventListener("click",function(){var a="hide";if(g.classList.contains(f.COLLAPSED)){a="show"}document.querySelectorAll(e.FORMCONTAINER).forEach(function(c){(0,b.default)(c).collapse(a)})});(0,b.default)(e.FORMCONTAINER).on("hidden.bs.collapse",function(){var a=!0;(0,b.default)(e.FORMCONTAINER).each(function(b,c){if(c.classList.contains(f.SHOW)){a=!1}});if(a){g.classList.add(f.COLLAPSED)}});(0,b.default)(e.FORMCONTAINER).on("shown.bs.collapse",function(){var a=!0;(0,b.default)(e.FORMCONTAINER).each(function(b,c){if(!c.classList.contains(f.SHOW)){a=!1}});if(a){g.classList.remove(f.COLLAPSED)}});d.resolve()};a.init=g});
+//# sourceMappingURL=collapsesections.min.js.map
diff --git a/lib/form/amd/build/collapsesections.min.js.map b/lib/form/amd/build/collapsesections.min.js.map
new file mode 100644
index 00000000000..24067e88572
--- /dev/null
+++ b/lib/form/amd/build/collapsesections.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/collapsesections.js"],"names":["SELECTORS","FORMCONTAINER","CLASSES","SHOW","COLLAPSED","init","collapsesections","pendingPromise","Pending","collapsemenu","document","querySelector","addEventListener","action","classList","contains","querySelectorAll","forEach","collapsecontainer","collapse","on","allcollapsed","each","_","add","allexpanded","remove","resolve"],"mappings":"qKAwBA,OACA,O,sDAEMA,CAAAA,CAAS,CAAG,CACdC,aAAa,CAAE,aADD,C,CAIZC,CAAO,CAAG,CACZC,IAAI,CAAE,MADM,CAEZC,SAAS,CAAE,WAFC,C,CAUHC,CAAI,CAAG,SAAAC,CAAgB,CAAI,IAE9BC,CAAAA,CAAc,CAAG,GAAIC,UAAJ,CAAY,4BAAZ,CAFa,CAG9BC,CAAY,CAAGC,QAAQ,CAACC,aAAT,CAAuBL,CAAvB,CAHe,CAIpCG,CAAY,CAACG,gBAAb,CAA8B,OAA9B,CAAuC,UAAM,CACzC,GAAIC,CAAAA,CAAM,CAAG,MAAb,CACA,GAAIJ,CAAY,CAACK,SAAb,CAAuBC,QAAvB,CAAgCb,CAAO,CAACE,SAAxC,CAAJ,CAAwD,CACpDS,CAAM,CAAG,MACZ,CAEDH,QAAQ,CAACM,gBAAT,CAA0BhB,CAAS,CAACC,aAApC,EAAmDgB,OAAnD,CAA2D,SAACC,CAAD,CAAuB,CAC9E,cAAEA,CAAF,EAAqBC,QAArB,CAA8BN,CAA9B,CACH,CAFD,CAGH,CATD,EAUA,cAAEb,CAAS,CAACC,aAAZ,EAA2BmB,EAA3B,CAA8B,oBAA9B,CAAoD,UAAM,CACtD,GAAIC,CAAAA,CAAY,GAAhB,CACA,cAAErB,CAAS,CAACC,aAAZ,EAA2BqB,IAA3B,CAAgC,SAACC,CAAD,CAAIL,CAAJ,CAA0B,CACtD,GAAIA,CAAiB,CAACJ,SAAlB,CAA4BC,QAA5B,CAAqCb,CAAO,CAACC,IAA7C,CAAJ,CAAwD,CACpDkB,CAAY,GACf,CACJ,CAJD,EAKA,GAAIA,CAAJ,CAAkB,CACdZ,CAAY,CAACK,SAAb,CAAuBU,GAAvB,CAA2BtB,CAAO,CAACE,SAAnC,CACH,CACJ,CAVD,EAWA,cAAEJ,CAAS,CAACC,aAAZ,EAA2BmB,EAA3B,CAA8B,mBAA9B,CAAmD,UAAM,CACrD,GAAIK,CAAAA,CAAW,GAAf,CACA,cAAEzB,CAAS,CAACC,aAAZ,EAA2BqB,IAA3B,CAAgC,SAACC,CAAD,CAAIL,CAAJ,CAA0B,CACtD,GAAI,CAACA,CAAiB,CAACJ,SAAlB,CAA4BC,QAA5B,CAAqCb,CAAO,CAACC,IAA7C,CAAL,CAAyD,CACrDsB,CAAW,GACd,CACJ,CAJD,EAMA,GAAIA,CAAJ,CAAiB,CACbhB,CAAY,CAACK,SAAb,CAAuBY,MAAvB,CAA8BxB,CAAO,CAACE,SAAtC,CACH,CACJ,CAXD,EAYAG,CAAc,CAACoB,OAAf,EACH,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Collapse or expand all form sections on clicking the expand all / collapse al link.\n *\n * @module core_form/collapsesections\n * @copyright 2021 Bas Brands\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport $ from 'jquery';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n    FORMCONTAINER: '.fcontainer',\n};\n\nconst CLASSES = {\n    SHOW: 'show',\n    COLLAPSED: 'collapsed'\n};\n\n/**\n * Initialises the form section collapse / expand action.\n *\n * @param {string} collapsesections the collapse/expand link id.\n */\nexport const init = collapsesections => {\n    // All jQuery in this code can be replaced when MDL-79179 is integrated.\n    const pendingPromise = new Pending('core_form/collapsesections');\n    const collapsemenu = document.querySelector(collapsesections);\n    collapsemenu.addEventListener('click', () => {\n        let action = 'hide';\n        if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n            action = 'show';\n        }\n\n        document.querySelectorAll(SELECTORS.FORMCONTAINER).forEach((collapsecontainer) => {\n            $(collapsecontainer).collapse(action);\n        });\n    });\n    $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n        let allcollapsed = true;\n        $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n            if (collapsecontainer.classList.contains(CLASSES.SHOW)) {\n                allcollapsed = false;\n            }\n        });\n        if (allcollapsed) {\n            collapsemenu.classList.add(CLASSES.COLLAPSED);\n        }\n    });\n    $(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {\n        var allexpanded = true;\n        $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n            if (!collapsecontainer.classList.contains(CLASSES.SHOW)) {\n                allexpanded = false;\n            }\n        });\n\n        if (allexpanded) {\n            collapsemenu.classList.remove(CLASSES.COLLAPSED);\n        }\n    });\n    pendingPromise.resolve();\n};\n"],"file":"collapsesections.min.js"}
\ No newline at end of file
diff --git a/lib/form/amd/src/collapsesections.js b/lib/form/amd/src/collapsesections.js
new file mode 100644
index 00000000000..d8e37da5b14
--- /dev/null
+++ b/lib/form/amd/src/collapsesections.js
@@ -0,0 +1,80 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Collapse or expand all form sections on clicking the expand all / collapse al link.
+ *
+ * @module core_form/collapsesections
+ * @copyright 2021 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since 4.0
+ */
+
+import $ from 'jquery';
+import Pending from 'core/pending';
+
+const SELECTORS = {
+    FORMCONTAINER: '.fcontainer',
+};
+
+const CLASSES = {
+    SHOW: 'show',
+    COLLAPSED: 'collapsed'
+};
+
+/**
+ * Initialises the form section collapse / expand action.
+ *
+ * @param {string} collapsesections the collapse/expand link id.
+ */
+export const init = collapsesections => {
+    // All jQuery in this code can be replaced when MDL-79179 is integrated.
+    const pendingPromise = new Pending('core_form/collapsesections');
+    const collapsemenu = document.querySelector(collapsesections);
+    collapsemenu.addEventListener('click', () => {
+        let action = 'hide';
+        if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {
+            action = 'show';
+        }
+
+        document.querySelectorAll(SELECTORS.FORMCONTAINER).forEach((collapsecontainer) => {
+            $(collapsecontainer).collapse(action);
+        });
+    });
+    $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {
+        let allcollapsed = true;
+        $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {
+            if (collapsecontainer.classList.contains(CLASSES.SHOW)) {
+                allcollapsed = false;
+            }
+        });
+        if (allcollapsed) {
+            collapsemenu.classList.add(CLASSES.COLLAPSED);
+        }
+    });
+    $(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {
+        var allexpanded = true;
+        $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {
+            if (!collapsecontainer.classList.contains(CLASSES.SHOW)) {
+                allexpanded = false;
+            }
+        });
+
+        if (allexpanded) {
+            collapsemenu.classList.remove(CLASSES.COLLAPSED);
+        }
+    });
+    pendingPromise.resolve();
+};
diff --git a/lib/form/header.php b/lib/form/header.php
index f5f1ed57722..da80feba789 100644
--- a/lib/form/header.php
+++ b/lib/form/header.php
@@ -69,7 +69,6 @@ class MoodleQuickForm_header extends HTML_QuickForm_header
     */
     function accept(&$renderer, $required=false, $error=null)
     {
-        $this->_text .= $this->getHelpButton();
         $renderer->renderHeader($this);
     }
 
@@ -81,4 +80,4 @@ class MoodleQuickForm_header extends HTML_QuickForm_header
     function getHelpButton(){
         return $this->_helpbutton;
     }
-}
\ No newline at end of file
+}
diff --git a/lib/form/templates/collapsesections.mustache b/lib/form/templates/collapsesections.mustache
new file mode 100644
index 00000000000..fb4bd5fca7d
--- /dev/null
+++ b/lib/form/templates/collapsesections.mustache
@@ -0,0 +1,36 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template core_form/collapsesections
+
+    Renders a form section header
+
+    Example context (json):
+    {
+    }
+}}
+<div class="collapsible-actions">
+    <a id="collapsesections{{uniqid}}" href="#" aria-expanded="true" class="collapseexpand collapsemenu collapsed">
+        <span class="collapseall">{{#str}}collapseall{{/str}}</span>
+        <span class="expandall">{{#str}}expandall{{/str}}</span>
+    </a>
+</div>
+{{#js}}
+require(['core_form/collapsesections'], function(Collapsesections) {
+    Collapsesections.init('#collapsesections{{uniqid}}');
+});
+{{/js}}
diff --git a/lib/form/templates/element-header.mustache b/lib/form/templates/element-header.mustache
new file mode 100644
index 00000000000..5b952c79d40
--- /dev/null
+++ b/lib/form/templates/element-header.mustache
@@ -0,0 +1,59 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template core_form/element-header
+
+    Renders a form section header
+
+    Example context (json):
+    {
+        "id": "id_general",
+        "header": "General",
+        "collapsed": 0,
+        "collapseable": 1,
+        "helpbutton": "Help"
+    }
+}}
+{{#collapseable}}
+    <legend class="d-flex align-items-center">
+        <div class="position-relative d-flex ftoggler align-items-center position-relative mr-1">
+            <a data-toggle="collapse"
+                href="#{{id}}container"
+                role="button"
+                aria-expanded="{{#collapsed}}false{{/collapsed}}{{^collapsed}}true{{/collapsed}}"
+                aria-controls="{{id}}container"
+                class="btn btn-icon mr-1 icons-collapse-expand stretched-link fheader {{#collapsed}}collapsed{{/collapsed}}"
+                >
+                <span class="expanded-icon icon-no-margin p-2" title="{{#str}} collapse, core {{/str}}">
+                    {{#pix}} t/expandedchevron, core {{/pix}}
+                </span>
+                <span class="collapsed-icon icon-no-margin p-2" title="{{#str}} expand, core {{/str}}">
+                    {{#pix}} t/collapsedchevron, core {{/pix}}
+                </span>
+                <span class="sr-only">{{{header}}}</span>
+            </a>
+            <h3 class="d-flex align-self-stretch align-items-center mb-0" aria-hidden="true">
+                {{{header}}}
+            </h3>
+        </div>
+        {{{helpbutton}}}
+    </legend>
+{{/collapseable}}
+{{^collapseable}}
+    <legend>{{{header}}}</legend>
+{{/collapseable}}
+<div id="{{id}}container" class="fcontainer {{#collapseable}}collapseable collapse {{/collapseable}} {{^collapsed}}show{{/collapsed}}">
diff --git a/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-debug.js b/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-debug.js
index 8bc8b847089..86476b2688b 100644
--- a/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-debug.js
+++ b/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-debug.js
@@ -18,7 +18,6 @@ function SHORTFORMS() {
 }
 
 var SELECTORS = {
-        COLLAPSEEXPAND: '.collapsible-actions .collapseexpand',
         COLLAPSED: '.collapsed',
         FIELDSETCOLLAPSIBLE: 'fieldset.collapsible',
         FIELDSETLEGENDLINK: 'fieldset.collapsible .fheader',
@@ -62,77 +61,19 @@ Y.extend(SHORTFORMS, Y.Base, {
      * @protected
      */
     initializer: function() {
-        var form = Y.one('#' + this.get('formid')),
-            fieldlist,
-            btn,
-            link,
-            idlist;
+        var form = Y.one('#' + this.get('formid'));
         if (!form) {
             Y.log('Could not locate the form', 'warn', 'moodle-form-shortforms');
             return;
         }
         // Stores the form in the object.
         this.form = form;
-        // Look through collapsible fieldset divs.
-        fieldlist = form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(this.process_fieldset, this);
 
         // Subscribe collapsible fieldsets and buttons to click events.
         form.delegate('click', this.switch_state, SELECTORS.FIELDSETLEGENDLINK, this);
-        form.delegate('key', this.switch_state, 'down:enter,32', SELECTORS.FIELDSETLEGENDLINK, this);
 
         // Handle event, when there's an error in collapsed section.
         Y.Global.on(M.core.globalEvents.FORM_ERROR, this.expand_fieldset, this);
-
-        // Make the collapse/expand a link.
-        btn = form.one(SELECTORS.COLLAPSEEXPAND);
-        if (btn) {
-            link = Y.Node.create('<a href="#"></a>');
-            link.setHTML(btn.getHTML());
-            link.setAttribute('class', btn.getAttribute('class'));
-            link.setAttribute('role', 'button');
-
-            // Get list of IDs controlled by this button to set the aria-controls attribute.
-            idlist = [];
-            form.all(SELECTORS.FIELDSETLEGENDLINK).each(function(node) {
-                idlist[idlist.length] = node.generateID();
-            });
-            link.setAttribute('aria-controls', idlist.join(' '));
-
-            // Placing the button and binding the event.
-            link.on('click', this.set_state_all, this, true);
-            link.on('key', this.set_state_all, 'down:enter,32', this, true);
-            btn.replace(link);
-            this.update_btns(form);
-        }
-    },
-
-    /**
-     * Process the supplied fieldset to add appropriate links, and ARIA
-     * roles.
-     *
-     * @method process_fieldset
-     * @param {Node} fieldset The Node relating to the fieldset to add collapsing to.
-     * @chainable
-     */
-    process_fieldset: function(fieldset) {
-        // Get legend element.
-        var legendelement = fieldset.one(SELECTORS.LEGENDFTOGGLER);
-
-        // Turn headers to links for accessibility.
-        var headerlink = Y.Node.create('<a href="#"></a>');
-        headerlink.addClass(CSS.FHEADER);
-        headerlink.appendChild(legendelement.get('firstChild'));
-        headerlink.setAttribute('role', 'button');
-        headerlink.setAttribute('aria-controls', fieldset.generateID());
-        if (legendelement.ancestor(SELECTORS.COLLAPSED)) {
-            headerlink.setAttribute('aria-expanded', 'false');
-        } else {
-            headerlink.setAttribute('aria-expanded', 'true');
-        }
-        legendelement.prepend(headerlink);
-
-        return this;
     },
 
     /**
@@ -167,22 +108,6 @@ Y.extend(SHORTFORMS, Y.Base, {
         return this;
     },
 
-    /**
-     * Set the state for all fieldsets in the form.
-     *
-     * @method set_state_all
-     * @param {EventFacade} e
-     */
-    set_state_all: function(e) {
-        e.preventDefault();
-        var collapsed = e.target.hasClass(CSS.COLLAPSEALL),
-            fieldlist = this.form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(function(node) {
-            this.set_state(node, collapsed);
-        }, this);
-        this.update_btns();
-    },
-
     /**
      * Toggle the state for the fieldset that was clicked.
      *
@@ -193,49 +118,8 @@ Y.extend(SHORTFORMS, Y.Base, {
         e.preventDefault();
         var fieldset = e.target.ancestor(SELECTORS.FIELDSETCOLLAPSIBLE);
         this.set_state(fieldset, !fieldset.hasClass(CSS.COLLAPSED));
-        this.update_btns();
     },
 
-    /**
-     * Update the Expand/Collapse all buttons as required.
-     *
-     * @method update_btns
-     * @chainable
-     */
-    update_btns: function() {
-        var btn,
-            collapsed = 0,
-            expandbtn = false,
-            fieldlist;
-
-        btn = this.form.one(SELECTORS.COLLAPSEEXPAND);
-        if (!btn) {
-            return this;
-        }
-
-        // Counting the number of collapsed sections.
-        fieldlist = this.form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(function(node) {
-            if (node.hasClass(CSS.COLLAPSED)) {
-                collapsed++;
-            }
-        });
-
-        if (collapsed !== 0) {
-            expandbtn = true;
-        }
-
-        // Updating the button.
-        if (expandbtn) {
-            btn.removeClass(CSS.COLLAPSEALL);
-            btn.setHTML(M.util.get_string('expandall', 'moodle'));
-        } else {
-            btn.addClass(CSS.COLLAPSEALL);
-            btn.setHTML(M.util.get_string('collapseall', 'moodle'));
-        }
-
-        return this;
-    },
     /**
      * Expand the fieldset, which contains an error.
      *
diff --git a/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-min.js b/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-min.js
index 7d5ac195d06..8d7a6615134 100644
--- a/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-min.js
+++ b/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms-min.js
@@ -1 +1 @@
-YUI.add("moodle-form-shortforms",function(r,e){function t(){t.superclass.constructor.apply(this,arguments)}var o=".collapsible-actions .collapseexpand",a=".collapsed",i="fieldset.collapsible",l="fieldset.collapsible .fheader",n=".fheader",d="legend.ftoggler",c="collapse-all",f="collapsed",h="fheader",s={formid:{value:null}};r.extend(t,r.Base,{form:null,initializer:function(){var e,t,s,a=r.one("#"+this.get("formid"));a&&((this.form=a).all(i).each(this.process_fieldset,this),a.delegate("click",this.switch_state,l,this),a.delegate("key",this.switch_state,"down:enter,32",l,this),r.Global.on(M.core.globalEvents.FORM_ERROR,this.expand_fieldset,this),(e=a.one(o))&&((t=r.Node.create('<a href="#"></a>')).setHTML(e.getHTML()),t.setAttribute("class",e.getAttribute("class")),t.setAttribute("role","button"),s=[],a.all(l).each(function(e){s[s.length]=e.generateID()}),t.setAttribute("aria-controls",s.join(" ")),t.on("click",this.set_state_all,this,!0),t.on("key",this.set_state_all,"down:enter,32",this,!0),e.replace(t),this.update_btns(a)))},process_fieldset:function(e){var t=e.one(d),s=r.Node.create('<a href="#"></a>');return s.addClass(h),s.appendChild(t.get("firstChild")),s.setAttribute("role","button"),s.setAttribute("aria-controls",e.generateID()),t.ancestor(a)?s.setAttribute("aria-expanded","false"):s.setAttribute("aria-expanded","true"),t.prepend(s),this},set_state:function(e,t){var s=e.one(n);return t?(e.addClass(f),s&&s.setAttribute("aria-expanded","false")):(e.removeClass(f),s&&s.setAttribute("aria-expanded","true")),(s=this.form.one("input[name=mform_isexpanded_"+e.get("id")+"]"))&&s.set("value",t?0:1),this},set_state_all:function(e){e.preventDefault();var t=e.target.hasClass(c);this.form.all(i).each(function(e){this.set_state(e,t)},this),this.update_btns()},switch_state:function(e){e.preventDefault();e=e.target.ancestor(i);this.set_state(e,!e.hasClass(f)),this.update_btns()},update_btns:function(){var t=0,e=!1,s=this.form.one(o);return s&&(this.form.all(i).each(function(e){e.hasClass(f)&&t++}),(e=0!==t?!0:e)?(s.removeClass(c),s.setHTML(M.util.get_string("expandall","moodle"))):(s.addClass(c),s.setHTML(M.util.get_string("collapseall","moodle")))),this},expand_fieldset:function(e){var t;e.stopPropagation(),e.formid===this.form.getAttribute("id")&&(t=r.one("#"+e.elementid).ancestor("fieldset"))&&this.set_state(t,!1)}},{NAME:"moodle-form-shortforms",ATTRS:s}),M.form=M.form||{},M.form.shortforms=M.form.shortforms||function(e){return new t(e)}},"@VERSION@",{requires:["node","base","selector-css3","moodle-core-event"]});
\ No newline at end of file
+YUI.add("moodle-form-shortforms",function(t,e){function s(){s.superclass.constructor.apply(this,arguments)}var o="fieldset.collapsible",r="fieldset.collapsible .fheader",i=".fheader",a="collapsed",n={formid:{value:null}};t.extend(s,t.Base,{form:null,initializer:function(){var e=t.one("#"+this.get("formid"));e&&((this.form=e).delegate("click",this.switch_state,r,this),t.Global.on(M.core.globalEvents.FORM_ERROR,this.expand_fieldset,this))},set_state:function(e,t){var s=e.one(i);return t?(e.addClass(a),s&&s.setAttribute("aria-expanded","false")):(e.removeClass(a),s&&s.setAttribute("aria-expanded","true")),(s=this.form.one("input[name=mform_isexpanded_"+e.get("id")+"]"))&&s.set("value",t?0:1),this},switch_state:function(e){e.preventDefault();e=e.target.ancestor(o);this.set_state(e,!e.hasClass(a))},expand_fieldset:function(e){e.stopPropagation(),e.formid===this.form.getAttribute("id")&&(e=t.one("#"+e.elementid).ancestor("fieldset"))&&this.set_state(e,!1)}},{NAME:"moodle-form-shortforms",ATTRS:n}),M.form=M.form||{},M.form.shortforms=M.form.shortforms||function(e){return new s(e)}},"@VERSION@",{requires:["node","base","selector-css3","moodle-core-event"]});
\ No newline at end of file
diff --git a/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms.js b/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms.js
index 29292a33efa..b581418d2c2 100644
--- a/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms.js
+++ b/lib/form/yui/build/moodle-form-shortforms/moodle-form-shortforms.js
@@ -18,7 +18,6 @@ function SHORTFORMS() {
 }
 
 var SELECTORS = {
-        COLLAPSEEXPAND: '.collapsible-actions .collapseexpand',
         COLLAPSED: '.collapsed',
         FIELDSETCOLLAPSIBLE: 'fieldset.collapsible',
         FIELDSETLEGENDLINK: 'fieldset.collapsible .fheader',
@@ -62,76 +61,18 @@ Y.extend(SHORTFORMS, Y.Base, {
      * @protected
      */
     initializer: function() {
-        var form = Y.one('#' + this.get('formid')),
-            fieldlist,
-            btn,
-            link,
-            idlist;
+        var form = Y.one('#' + this.get('formid'));
         if (!form) {
             return;
         }
         // Stores the form in the object.
         this.form = form;
-        // Look through collapsible fieldset divs.
-        fieldlist = form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(this.process_fieldset, this);
 
         // Subscribe collapsible fieldsets and buttons to click events.
         form.delegate('click', this.switch_state, SELECTORS.FIELDSETLEGENDLINK, this);
-        form.delegate('key', this.switch_state, 'down:enter,32', SELECTORS.FIELDSETLEGENDLINK, this);
 
         // Handle event, when there's an error in collapsed section.
         Y.Global.on(M.core.globalEvents.FORM_ERROR, this.expand_fieldset, this);
-
-        // Make the collapse/expand a link.
-        btn = form.one(SELECTORS.COLLAPSEEXPAND);
-        if (btn) {
-            link = Y.Node.create('<a href="#"></a>');
-            link.setHTML(btn.getHTML());
-            link.setAttribute('class', btn.getAttribute('class'));
-            link.setAttribute('role', 'button');
-
-            // Get list of IDs controlled by this button to set the aria-controls attribute.
-            idlist = [];
-            form.all(SELECTORS.FIELDSETLEGENDLINK).each(function(node) {
-                idlist[idlist.length] = node.generateID();
-            });
-            link.setAttribute('aria-controls', idlist.join(' '));
-
-            // Placing the button and binding the event.
-            link.on('click', this.set_state_all, this, true);
-            link.on('key', this.set_state_all, 'down:enter,32', this, true);
-            btn.replace(link);
-            this.update_btns(form);
-        }
-    },
-
-    /**
-     * Process the supplied fieldset to add appropriate links, and ARIA
-     * roles.
-     *
-     * @method process_fieldset
-     * @param {Node} fieldset The Node relating to the fieldset to add collapsing to.
-     * @chainable
-     */
-    process_fieldset: function(fieldset) {
-        // Get legend element.
-        var legendelement = fieldset.one(SELECTORS.LEGENDFTOGGLER);
-
-        // Turn headers to links for accessibility.
-        var headerlink = Y.Node.create('<a href="#"></a>');
-        headerlink.addClass(CSS.FHEADER);
-        headerlink.appendChild(legendelement.get('firstChild'));
-        headerlink.setAttribute('role', 'button');
-        headerlink.setAttribute('aria-controls', fieldset.generateID());
-        if (legendelement.ancestor(SELECTORS.COLLAPSED)) {
-            headerlink.setAttribute('aria-expanded', 'false');
-        } else {
-            headerlink.setAttribute('aria-expanded', 'true');
-        }
-        legendelement.prepend(headerlink);
-
-        return this;
     },
 
     /**
@@ -164,22 +105,6 @@ Y.extend(SHORTFORMS, Y.Base, {
         return this;
     },
 
-    /**
-     * Set the state for all fieldsets in the form.
-     *
-     * @method set_state_all
-     * @param {EventFacade} e
-     */
-    set_state_all: function(e) {
-        e.preventDefault();
-        var collapsed = e.target.hasClass(CSS.COLLAPSEALL),
-            fieldlist = this.form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(function(node) {
-            this.set_state(node, collapsed);
-        }, this);
-        this.update_btns();
-    },
-
     /**
      * Toggle the state for the fieldset that was clicked.
      *
@@ -190,49 +115,8 @@ Y.extend(SHORTFORMS, Y.Base, {
         e.preventDefault();
         var fieldset = e.target.ancestor(SELECTORS.FIELDSETCOLLAPSIBLE);
         this.set_state(fieldset, !fieldset.hasClass(CSS.COLLAPSED));
-        this.update_btns();
     },
 
-    /**
-     * Update the Expand/Collapse all buttons as required.
-     *
-     * @method update_btns
-     * @chainable
-     */
-    update_btns: function() {
-        var btn,
-            collapsed = 0,
-            expandbtn = false,
-            fieldlist;
-
-        btn = this.form.one(SELECTORS.COLLAPSEEXPAND);
-        if (!btn) {
-            return this;
-        }
-
-        // Counting the number of collapsed sections.
-        fieldlist = this.form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(function(node) {
-            if (node.hasClass(CSS.COLLAPSED)) {
-                collapsed++;
-            }
-        });
-
-        if (collapsed !== 0) {
-            expandbtn = true;
-        }
-
-        // Updating the button.
-        if (expandbtn) {
-            btn.removeClass(CSS.COLLAPSEALL);
-            btn.setHTML(M.util.get_string('expandall', 'moodle'));
-        } else {
-            btn.addClass(CSS.COLLAPSEALL);
-            btn.setHTML(M.util.get_string('collapseall', 'moodle'));
-        }
-
-        return this;
-    },
     /**
      * Expand the fieldset, which contains an error.
      *
diff --git a/lib/form/yui/src/shortforms/js/shortforms.js b/lib/form/yui/src/shortforms/js/shortforms.js
index 032b1d2a482..08916b81ca4 100644
--- a/lib/form/yui/src/shortforms/js/shortforms.js
+++ b/lib/form/yui/src/shortforms/js/shortforms.js
@@ -16,7 +16,6 @@ function SHORTFORMS() {
 }
 
 var SELECTORS = {
-        COLLAPSEEXPAND: '.collapsible-actions .collapseexpand',
         COLLAPSED: '.collapsed',
         FIELDSETCOLLAPSIBLE: 'fieldset.collapsible',
         FIELDSETLEGENDLINK: 'fieldset.collapsible .fheader',
@@ -60,77 +59,19 @@ Y.extend(SHORTFORMS, Y.Base, {
      * @protected
      */
     initializer: function() {
-        var form = Y.one('#' + this.get('formid')),
-            fieldlist,
-            btn,
-            link,
-            idlist;
+        var form = Y.one('#' + this.get('formid'));
         if (!form) {
             Y.log('Could not locate the form', 'warn', 'moodle-form-shortforms');
             return;
         }
         // Stores the form in the object.
         this.form = form;
-        // Look through collapsible fieldset divs.
-        fieldlist = form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(this.process_fieldset, this);
 
         // Subscribe collapsible fieldsets and buttons to click events.
         form.delegate('click', this.switch_state, SELECTORS.FIELDSETLEGENDLINK, this);
-        form.delegate('key', this.switch_state, 'down:enter,32', SELECTORS.FIELDSETLEGENDLINK, this);
 
         // Handle event, when there's an error in collapsed section.
         Y.Global.on(M.core.globalEvents.FORM_ERROR, this.expand_fieldset, this);
-
-        // Make the collapse/expand a link.
-        btn = form.one(SELECTORS.COLLAPSEEXPAND);
-        if (btn) {
-            link = Y.Node.create('<a href="#"></a>');
-            link.setHTML(btn.getHTML());
-            link.setAttribute('class', btn.getAttribute('class'));
-            link.setAttribute('role', 'button');
-
-            // Get list of IDs controlled by this button to set the aria-controls attribute.
-            idlist = [];
-            form.all(SELECTORS.FIELDSETLEGENDLINK).each(function(node) {
-                idlist[idlist.length] = node.generateID();
-            });
-            link.setAttribute('aria-controls', idlist.join(' '));
-
-            // Placing the button and binding the event.
-            link.on('click', this.set_state_all, this, true);
-            link.on('key', this.set_state_all, 'down:enter,32', this, true);
-            btn.replace(link);
-            this.update_btns(form);
-        }
-    },
-
-    /**
-     * Process the supplied fieldset to add appropriate links, and ARIA
-     * roles.
-     *
-     * @method process_fieldset
-     * @param {Node} fieldset The Node relating to the fieldset to add collapsing to.
-     * @chainable
-     */
-    process_fieldset: function(fieldset) {
-        // Get legend element.
-        var legendelement = fieldset.one(SELECTORS.LEGENDFTOGGLER);
-
-        // Turn headers to links for accessibility.
-        var headerlink = Y.Node.create('<a href="#"></a>');
-        headerlink.addClass(CSS.FHEADER);
-        headerlink.appendChild(legendelement.get('firstChild'));
-        headerlink.setAttribute('role', 'button');
-        headerlink.setAttribute('aria-controls', fieldset.generateID());
-        if (legendelement.ancestor(SELECTORS.COLLAPSED)) {
-            headerlink.setAttribute('aria-expanded', 'false');
-        } else {
-            headerlink.setAttribute('aria-expanded', 'true');
-        }
-        legendelement.prepend(headerlink);
-
-        return this;
     },
 
     /**
@@ -165,22 +106,6 @@ Y.extend(SHORTFORMS, Y.Base, {
         return this;
     },
 
-    /**
-     * Set the state for all fieldsets in the form.
-     *
-     * @method set_state_all
-     * @param {EventFacade} e
-     */
-    set_state_all: function(e) {
-        e.preventDefault();
-        var collapsed = e.target.hasClass(CSS.COLLAPSEALL),
-            fieldlist = this.form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(function(node) {
-            this.set_state(node, collapsed);
-        }, this);
-        this.update_btns();
-    },
-
     /**
      * Toggle the state for the fieldset that was clicked.
      *
@@ -191,49 +116,8 @@ Y.extend(SHORTFORMS, Y.Base, {
         e.preventDefault();
         var fieldset = e.target.ancestor(SELECTORS.FIELDSETCOLLAPSIBLE);
         this.set_state(fieldset, !fieldset.hasClass(CSS.COLLAPSED));
-        this.update_btns();
     },
 
-    /**
-     * Update the Expand/Collapse all buttons as required.
-     *
-     * @method update_btns
-     * @chainable
-     */
-    update_btns: function() {
-        var btn,
-            collapsed = 0,
-            expandbtn = false,
-            fieldlist;
-
-        btn = this.form.one(SELECTORS.COLLAPSEEXPAND);
-        if (!btn) {
-            return this;
-        }
-
-        // Counting the number of collapsed sections.
-        fieldlist = this.form.all(SELECTORS.FIELDSETCOLLAPSIBLE);
-        fieldlist.each(function(node) {
-            if (node.hasClass(CSS.COLLAPSED)) {
-                collapsed++;
-            }
-        });
-
-        if (collapsed !== 0) {
-            expandbtn = true;
-        }
-
-        // Updating the button.
-        if (expandbtn) {
-            btn.removeClass(CSS.COLLAPSEALL);
-            btn.setHTML(M.util.get_string('expandall', 'moodle'));
-        } else {
-            btn.addClass(CSS.COLLAPSEALL);
-            btn.setHTML(M.util.get_string('collapseall', 'moodle'));
-        }
-
-        return this;
-    },
     /**
      * Expand the fieldset, which contains an error.
      *
diff --git a/lib/formslib.php b/lib/formslib.php
index 3467779d0c4..7f5228987af 100644
--- a/lib/formslib.php
+++ b/lib/formslib.php
@@ -3022,10 +3022,6 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
      */
     var $_openHiddenFieldsetTemplate = "\n\t<fieldset class=\"hidden\"><div>";
 
-    /** @var string Header Template string */
-    var $_headerTemplate =
-       "\n\t\t<legend class=\"ftoggler\">{header}</legend>\n\t\t<div class=\"fcontainer clearfix\">\n\t\t";
-
     /** @var string Template used when opening a fieldset */
     var $_openFieldsetTemplate = "\n\t<fieldset class=\"{classes}\" {id}>";
 
@@ -3122,7 +3118,7 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
      * @param MoodleQuickForm $form reference of the form
      */
     function startForm(&$form){
-        global $PAGE;
+        global $PAGE, $OUTPUT;
         $this->_reqHTML = $form->getReqHTML();
         $this->_elementTemplates = str_replace('{req}', $this->_reqHTML, $this->_elementTemplates);
         $this->_advancedHTML = $form->getAdvancedHTML();
@@ -3144,8 +3140,7 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
         }
         if (!empty($this->_collapsibleElements)) {
             if (count($this->_collapsibleElements) > 1) {
-                $this->_collapseButtons = $this->_collapseButtonsTemplate;
-                $this->_collapseButtons = str_replace('{strexpandall}', get_string('expandall'), $this->_collapseButtons);
+                $this->_collapseButtons = $OUTPUT->render_from_template('core_form/collapsesections', (object)[]);
             }
             $PAGE->requires->yui_module('moodle-form-shortforms', 'M.form.shortforms', array(array('formid' => $formid)));
         }
@@ -3327,18 +3322,29 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
     * @global moodle_page $PAGE
     */
     function renderHeader(&$header) {
-        global $PAGE;
+        global $PAGE, $OUTPUT;
 
         $header->_generateId();
         $name = $header->getName();
 
+        $collapsed = $collapseable = '';
+        if (isset($this->_collapsibleElements[$header->getName()])) {
+            $collapseable = true;
+            $collapsed = $this->_collapsibleElements[$header->getName()];
+        }
+
         $id = empty($name) ? '' : ' id="' . $header->getAttribute('id') . '"';
-        if (is_null($header->_text)) {
-            $header_html = '';
-        } elseif (!empty($name) && isset($this->_templates[$name])) {
-            $header_html = str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
+        if (!empty($name) && isset($this->_templates[$name])) {
+            $headerhtml = str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
         } else {
-            $header_html = str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
+            $headerhtml = $OUTPUT->render_from_template('core_form/element-header',
+                (object)[
+                    'header' => $header->toHtml(),
+                    'id' => $header->getAttribute('id'),
+                    'collapseable' => $collapseable,
+                    'collapsed' => $collapsed,
+                    'helpbutton' => $header->getHelpButton(),
+                ]);
         }
 
         if ($this->_fieldsetsOpen > 0) {
@@ -3363,7 +3369,7 @@ class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{
         $openFieldsetTemplate = str_replace('{id}', $id, $this->_openFieldsetTemplate);
         $openFieldsetTemplate = str_replace('{classes}', join(' ', $fieldsetclasses), $openFieldsetTemplate);
 
-        $this->_html .= $openFieldsetTemplate . $header_html;
+        $this->_html .= $openFieldsetTemplate . $headerhtml;
         $this->_fieldsetsOpen++;
     }
 
diff --git a/lib/tests/behat/behat_forms.php b/lib/tests/behat/behat_forms.php
index 2a3689819fb..915088d022f 100644
--- a/lib/tests/behat/behat_forms.php
+++ b/lib/tests/behat/behat_forms.php
@@ -143,18 +143,19 @@ class behat_forms extends behat_base {
         // We already know that we waited for the DOM and the JS to be loaded, even the editor
         // so, we will use the reduced timeout as it is a common task and we should save time.
         try {
-
+            $this->wait_for_pending_js();
             // Expand all fieldsets link - which will only be there if there is more than one collapsible section.
             $expandallxpath = "//div[@class='collapsible-actions']" .
-                "//a[contains(concat(' ', @class, ' '), ' collapseexpand ')]" .
-                "[not(contains(concat(' ', @class, ' '), ' collapse-all '))]";
+                "//a[contains(concat(' ', @class, ' '), ' collapsed ')]" .
+                "//span[contains(concat(' ', @class, ' '), ' expandall ')]";
             // Else, look for the first expand fieldset link.
             $expandonlysection = "//legend[@class='ftoggler']" .
-                    "//a[contains(concat(' ', @class, ' '), ' fheader ') and @aria-expanded = 'false']";
+                    "//a[contains(concat(' ', @class, ' '), ' icons-collapse-expand ') and @aria-expanded = 'false']";
 
             $collapseexpandlink = $this->find('xpath', $expandallxpath . '|' . $expandonlysection,
                     false, false, behat_base::get_reduced_timeout());
             $collapseexpandlink->click();
+            $this->wait_for_pending_js();
 
         } catch (ElementNotFoundException $e) {
             // The behat_base::find() method throws an exception if there are no elements,
diff --git a/mod/wiki/tests/behat/wiki_activity_completion.feature b/mod/wiki/tests/behat/wiki_activity_completion.feature
index 4a48dc9452a..07f6fcc2142 100644
--- a/mod/wiki/tests/behat/wiki_activity_completion.feature
+++ b/mod/wiki/tests/behat/wiki_activity_completion.feature
@@ -52,6 +52,7 @@ Feature: View activity completion information in the Wiki activity
     And I am on the "Music history" "wiki activity editing" page
     And I expand all fieldsets
     And I press "Unlock completion options"
+    And I expand all fieldsets
     And I set the field "Completion tracking" to "Students can manually mark the activity as completed"
     And I press "Save and display"
     # Teacher view.
diff --git a/report/outline/tests/behat/filter.feature b/report/outline/tests/behat/filter.feature
index 5cde5088c38..62acb65e051 100644
--- a/report/outline/tests/behat/filter.feature
+++ b/report/outline/tests/behat/filter.feature
@@ -54,7 +54,7 @@ Feature: Filter an outline report
       | filterstartdate[day]     | 12   |
       | filterstartdate[month]   | June |
       | filterstartdate[year]    | 2017 |
-    And I press "Filter"
+    And I click on "Filter" "button" in the "#fgroup_id_buttonar" "css_element"
     Then I should see "1 views by 1 users" in the "Book name" "table_row"
     And I should see "1 views by 1 users" in the "Forum name" "table_row"
 
@@ -87,6 +87,6 @@ Feature: Filter an outline report
       | filterenddate[day]     | 11   |
       | filterenddate[month]   | June |
       | filterenddate[year]    | 2017 |
-    And I press "Filter"
+    And I click on "Filter" "button" in the "#fgroup_id_buttonar" "css_element"
     Then I should see "1 views by 1 users" in the "Book name" "table_row"
     And I should not see "views by" in the "Forum name" "table_row"
diff --git a/search/tests/behat/behat_search.php b/search/tests/behat/behat_search.php
index a96536ac1a3..7699408069c 100644
--- a/search/tests/behat/behat_search.php
+++ b/search/tests/behat/behat_search.php
@@ -51,7 +51,8 @@ class behat_search extends behat_base {
         $this->execute('behat_forms::i_set_the_field_to', ['q', $query]);
 
         // Submit the form.
-        $this->execute_script('return document.querySelector(".searchform-navbar").submit();');
+        $this->execute("behat_general::i_click_on_in_the",
+            [get_string('search', 'core'), 'button', '#usernavigation', 'css_element']);
     }
 
     /**
diff --git a/theme/boost/scss/moodle/core.scss b/theme/boost/scss/moodle/core.scss
index 9ae4d4cff94..3f081d84476 100644
--- a/theme/boost/scss/moodle/core.scss
+++ b/theme/boost/scss/moodle/core.scss
@@ -319,19 +319,6 @@ a.autolink.glossary:hover {
     display: block;
 }
 
-.collapsible-actions .collapseexpand {
-    padding-left: 20px;
-    background: url([[pix:t/collapsed]]) 2px center no-repeat;
-}
-/*rtl:raw:
-.collapsible-actions .collapseexpand {
-    background: url([[pix:t/collapsed_rtl]]) right center no-repeat;
-}
-*/
-.collapsible-actions .collapse-all {
-    background-image: url([[pix:t/expanded]]);
-}
-
 .yui-overlay .yui-widget-bd {
     background-color: #ffee69;
     border: 1px solid #a6982b;
diff --git a/theme/boost/scss/moodle/forms.scss b/theme/boost/scss/moodle/forms.scss
index bca4d68d48a..857c558ff07 100644
--- a/theme/boost/scss/moodle/forms.scss
+++ b/theme/boost/scss/moodle/forms.scss
@@ -58,10 +58,6 @@
     width: auto;
 }
 
-.jsenabled .mform .collapsed .fcontainer {
-    display: none;
-}
-
 #adminsettings .error {
     color: $danger;
 }
@@ -290,7 +286,7 @@ fieldset.coursesearchbox label {
     overflow: auto;
     margin: $dropdown-spacer 0 0;
     padding: $dropdown-padding-y 0;
-    z-index: 1;
+    z-index: 2;
 }
 
 .form-autocomplete-suggestions li {
@@ -441,23 +437,13 @@ textarea[data-auto-rows] {
     flex-grow: 1;
 }
 
-@include media-breakpoint-up(sm) {
-    .mform fieldset.collapsible legend a.fheader {
-        padding: 0 5px 0 ($spacer * 1.5);
-        background: url([[pix:t/expanded]]) 0 center no-repeat;
-    }
-
-    .mform fieldset.collapsed legend a.fheader {
-        /*rtl:raw:
-        background-image: url([[pix:t/collapsed_rtl]]);
-        */
-        /*rtl:remove*/
-        background-image: url([[pix:t/collapsed]]);
-    }
-    .mform fieldset.collapsible .col-form-label {
+@include media-breakpoint-up(md) {
+    .mform fieldset .fcontainer.collapseable .col-form-label {
         padding-left: ($spacer * 2.5);
     }
+}
 
+@include media-breakpoint-up(sm) {
     .mform {
         .form-inline {
             .fdefaultcustom {
@@ -469,6 +455,26 @@ textarea[data-auto-rows] {
     }
 }
 
+.collapsemenu {
+    .collapseall {
+        display: block;
+    }
+
+    .expandall {
+        display: none;
+    }
+
+    &.collapsed {
+        .collapseall {
+            display: none;
+        }
+
+        .expandall {
+            display: block;
+        }
+    }
+}
+
 // Form inset on the left/right.
 // Used to display an icon/button within the form control.
 .input-group {
diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css
index b9ffcd2abda..e96824292d0 100644
--- a/theme/boost/style/moodle.css
+++ b/theme/boost/style/moodle.css
@@ -10133,18 +10133,6 @@ a.autolink.glossary:hover {
 .jsenabled .collapsible-actions {
   display: block; }
 
-.collapsible-actions .collapseexpand {
-  padding-left: 20px;
-  background: url([[pix:t/collapsed]]) 2px center no-repeat; }
-
-/*rtl:raw:
-.collapsible-actions .collapseexpand {
-    background: url([[pix:t/collapsed_rtl]]) right center no-repeat;
-}
-*/
-.collapsible-actions .collapse-all {
-  background-image: url([[pix:t/expanded]]); }
-
 .yui-overlay .yui-widget-bd {
   background-color: #ffee69;
   border: 1px solid #a6982b;
@@ -17282,9 +17270,6 @@ body.path-question-type .mform fieldset.hidden {
 #adminsettings .form-control[size] {
   width: auto; }
 
-.jsenabled .mform .collapsed .fcontainer {
-  display: none; }
-
 #adminsettings .error {
   color: #ca3120; }
 
@@ -17467,7 +17452,7 @@ fieldset.coursesearchbox label {
   overflow: auto;
   margin: 0.125rem 0 0;
   padding: 0.5rem 0;
-  z-index: 1; }
+  z-index: 2; }
 
 .form-autocomplete-suggestions li {
   list-style-type: none;
@@ -17576,21 +17561,26 @@ textarea[data-auto-rows] {
 [data-fieldtype="editor"] > div {
   flex-grow: 1; }
 
+@media (min-width: 768px) {
+  .mform fieldset .fcontainer.collapseable .col-form-label {
+    padding-left: 2.5rem; } }
+
 @media (min-width: 576px) {
-  .mform fieldset.collapsible legend a.fheader {
-    padding: 0 5px 0 1.5rem;
-    background: url([[pix:t/expanded]]) 0 center no-repeat; }
-  .mform fieldset.collapsed legend a.fheader {
-    /*rtl:raw:
-        background-image: url([[pix:t/collapsed_rtl]]);
-        */
-    /*rtl:remove*/
-    background-image: url([[pix:t/collapsed]]); }
-  .mform fieldset.collapsible .col-form-label {
-    padding-left: 2.5rem; }
   .mform .form-inline .fdefaultcustom label {
     justify-content: initial; } }
 
+.collapsemenu .collapseall {
+  display: block; }
+
+.collapsemenu .expandall {
+  display: none; }
+
+.collapsemenu.collapsed .collapseall {
+  display: none; }
+
+.collapsemenu.collapsed .expandall {
+  display: block; }
+
 .input-group.form-inset .form-inset-item {
   position: absolute;
   padding-top: calc(0.375rem + 1px);
diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css
index 0b074281110..d956b1ec87f 100644
--- a/theme/classic/style/moodle.css
+++ b/theme/classic/style/moodle.css
@@ -10133,18 +10133,6 @@ a.autolink.glossary:hover {
 .jsenabled .collapsible-actions {
   display: block; }
 
-.collapsible-actions .collapseexpand {
-  padding-left: 20px;
-  background: url([[pix:t/collapsed]]) 2px center no-repeat; }
-
-/*rtl:raw:
-.collapsible-actions .collapseexpand {
-    background: url([[pix:t/collapsed_rtl]]) right center no-repeat;
-}
-*/
-.collapsible-actions .collapse-all {
-  background-image: url([[pix:t/expanded]]); }
-
 .yui-overlay .yui-widget-bd {
   background-color: #ffee69;
   border: 1px solid #a6982b;
@@ -17282,9 +17270,6 @@ body.path-question-type .mform fieldset.hidden {
 #adminsettings .form-control[size] {
   width: auto; }
 
-.jsenabled .mform .collapsed .fcontainer {
-  display: none; }
-
 #adminsettings .error {
   color: #ca3120; }
 
@@ -17467,7 +17452,7 @@ fieldset.coursesearchbox label {
   overflow: auto;
   margin: 0.125rem 0 0;
   padding: 0.5rem 0;
-  z-index: 1; }
+  z-index: 2; }
 
 .form-autocomplete-suggestions li {
   list-style-type: none;
@@ -17576,21 +17561,26 @@ textarea[data-auto-rows] {
 [data-fieldtype="editor"] > div {
   flex-grow: 1; }
 
+@media (min-width: 768px) {
+  .mform fieldset .fcontainer.collapseable .col-form-label {
+    padding-left: 2.5rem; } }
+
 @media (min-width: 576px) {
-  .mform fieldset.collapsible legend a.fheader {
-    padding: 0 5px 0 1.5rem;
-    background: url([[pix:t/expanded]]) 0 center no-repeat; }
-  .mform fieldset.collapsed legend a.fheader {
-    /*rtl:raw:
-        background-image: url([[pix:t/collapsed_rtl]]);
-        */
-    /*rtl:remove*/
-    background-image: url([[pix:t/collapsed]]); }
-  .mform fieldset.collapsible .col-form-label {
-    padding-left: 2.5rem; }
   .mform .form-inline .fdefaultcustom label {
     justify-content: initial; } }
 
+.collapsemenu .collapseall {
+  display: block; }
+
+.collapsemenu .expandall {
+  display: none; }
+
+.collapsemenu.collapsed .collapseall {
+  display: none; }
+
+.collapsemenu.collapsed .expandall {
+  display: block; }
+
 .input-group.form-inset .form-inset-item {
   position: absolute;
   padding-top: calc(0.375rem + 1px);