loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make "cancel" buttons have proper type in modal forms (#25618)

Replace #25446, fix #25438

All "cancel" buttons which do not have "type" should not submit the
form, should not be triggered by "Enter".

This is a complete fix for all modal dialogs.

The major change is "modules/aria/modal.js", "devtest" related code is
for demo/test purpose.

authored by

wxiaoguang and committed by
GitHub
45bc180a 2aa6a785

+52 -1
+11 -1
routers/web/devtest/devtest.go
··· 34 34 35 35 func FetchActionTest(ctx *context.Context) { 36 36 _ = ctx.Req.ParseForm() 37 - ctx.Flash.Info(ctx.Req.Method + " " + ctx.Req.RequestURI + "<br>" + 37 + ctx.Flash.Info("fetch-action: " + ctx.Req.Method + " " + ctx.Req.RequestURI + "<br>" + 38 38 "Form: " + ctx.Req.Form.Encode() + "<br>" + 39 39 "PostForm: " + ctx.Req.PostForm.Encode(), 40 40 ) ··· 51 51 ctx.Data["TimeFuture2m"] = now.Add(2 * time.Minute) 52 52 ctx.Data["TimePast1y"] = now.Add(-1 * 366 * 86400 * time.Second) 53 53 ctx.Data["TimeFuture1y"] = now.Add(1 * 366 * 86400 * time.Second) 54 + 55 + if ctx.Req.Method == "POST" { 56 + _ = ctx.Req.ParseForm() 57 + ctx.Flash.Info("form: "+ctx.Req.Method+" "+ctx.Req.RequestURI+"<br>"+ 58 + "Form: "+ctx.Req.Form.Encode()+"<br>"+ 59 + "PostForm: "+ctx.Req.PostForm.Encode(), 60 + true, 61 + ) 62 + time.Sleep(2 * time.Second) 63 + } 54 64 55 65 ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.Params("sub")))) 56 66 }
+13
templates/devtest/fomantic-modal.tmpl
··· 1 1 {{template "base/head" .}} 2 2 <div class="page-content devtest ui container"> 3 + {{template "base/alert" .}} 4 + 5 + <button class="show-modal" data-modal="#test-modal-form">show modal form</button> 6 + <div id="test-modal-form" class="ui mini modal"> 7 + <div class="header">Form dialog</div> 8 + <form class="content" method="post"> 9 + <div class="ui input"><input name="user_input"></div> 10 + {{template "base/modal_actions_confirm" (dict "locale" $.locale "ModalButtonTypes" "confirm")}} 11 + </form> 12 + </div> 13 + 14 + <div class="divider"></div> 15 + 3 16 <div class="ui g-modal-confirm modal" id="test-modal-default"> 4 17 <div class="header">{{svg "octicon-file"}} Default dialog <span>title</span></div> 5 18 <div class="content">
+26
web_src/js/modules/aria/modal.js
··· 1 + import $ from 'jquery'; 2 + 3 + const fomanticModalFn = $.fn.modal; 4 + 5 + // use our own `$.fn.modal` to patch Fomantic's modal module 6 + export function initAriaModalPatch() { 7 + if ($.fn.modal === ariaModalFn) throw new Error('initAriaModalPatch could only be called once'); 8 + $.fn.modal = ariaModalFn; 9 + ariaModalFn.settings = fomanticModalFn.settings; 10 + } 11 + 12 + // the patched `$.fn.modal` modal function 13 + // * it does the one-time attaching on the first call 14 + function ariaModalFn(...args) { 15 + const ret = fomanticModalFn.apply(this, args); 16 + if (args[0] === 'show' || args[0]?.autoShow) { 17 + for (const el of this) { 18 + // If there is a form in the modal, there might be a "cancel" button before "ok" button (all buttons are "type=submit" by default). 19 + // In such case, the "Enter" key will trigger the "cancel" button instead of "ok" button, then the dialog will be closed. 20 + // It breaks the user experience - the "Enter" key should confirm the dialog and submit the form. 21 + // So, all "cancel" buttons without "[type]" must be marked as "type=button". 22 + $(el).find('form button.cancel:not([type])').attr('type', 'button'); 23 + } 24 + } 25 + return ret; 26 + }
+2
web_src/js/modules/fomantic.js
··· 1 1 import $ from 'jquery'; 2 2 import {initAriaCheckboxPatch} from './aria/checkbox.js'; 3 3 import {initAriaDropdownPatch} from './aria/dropdown.js'; 4 + import {initAriaModalPatch} from './aria/modal.js'; 4 5 import {svg} from '../svg.js'; 5 6 6 7 export const fomanticMobileScreen = window.matchMedia('only screen and (max-width: 767.98px)'); ··· 26 27 // Use the patches to improve accessibility, these patches are designed to be as independent as possible, make it easy to modify or remove in the future. 27 28 initAriaCheckboxPatch(); 28 29 initAriaDropdownPatch(); 30 + initAriaModalPatch(); 29 31 } 30 32 31 33 function initFomanticApiPatch() {