Skip to content

Commit 8e404e4

Browse files
fix: prevent <button>'s from becoming form submit when they shouldn't (#4221)
* fix: prevent <button>'s from becoming form submit when they shouldn't Adds `type=button` to most `<button>` usage (except the AdminPage#submitButton). The first button of type submit (which is the default in HTML if undeclared) becomes what the enter keybind presses in a form. This makes the behavior with these components make more sense. * Prettier on framework
1 parent 4e95d06 commit 8e404e4

File tree

14 files changed

+21
-7
lines changed

14 files changed

+21
-7
lines changed

extensions/emoji/js/src/forum/addComposerAutocomplete.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export default function addComposerAutocomplete() {
7070
return (
7171
<Tooltip text={name}>
7272
<button
73+
type="button"
7374
key={emoji}
7475
onclick={() => applySuggestion(emoji)}
7576
onmouseenter={function () {

extensions/mentions/js/src/forum/components/MentionsDropdownItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default class MentionsDropdownItem<CustomAttrs extends IMentionsDropdownI
1717
const className = classList('MentionsDropdownItem', 'PostPreview', `MentionsDropdown-${mentionable.type()}`);
1818

1919
return (
20-
<button className={className} {...attrs}>
20+
<button className={className} type="button" {...attrs}>
2121
<span className="PostPreview-content">{vnode.children}</span>
2222
</button>
2323
);

extensions/mentions/js/src/forum/fragments/PostQuoteButton.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default class PostQuoteButton extends Fragment {
1515
return (
1616
<button
1717
className="Button PostQuoteButton"
18+
type="button"
1819
onclick={() => {
1920
reply(this.post, this.content);
2021
}}

extensions/statistics/js/src/admin/components/StatisticsWidget.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ export default class StatisticsWidget extends DashboardWidget {
279279
return (
280280
<button
281281
className={classList('Button--ua-reset StatisticsWidget-entity', { active: this.selectedEntity === entity })}
282+
type="button"
282283
onclick={this.changeEntity.bind(this, entity)}
283284
>
284285
<h3 className="StatisticsWidget-heading">{app.translator.trans('flarum-statistics.admin.statistics.' + entity + '_heading')}</h3>

framework/core/js/src/admin/components/AdminPage.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,13 @@ export default abstract class AdminPage<CustomAttrs extends IPageAttrs = IPageAt
6767
*/
6868
submitButton(): Mithril.Children {
6969
return (
70-
<Button onclick={this.saveSettings.bind(this)} className="Button Button--primary" loading={this.loading} disabled={!this.isChanged()}>
70+
<Button
71+
type="submit"
72+
onclick={this.saveSettings.bind(this)}
73+
className="Button Button--primary"
74+
loading={this.loading}
75+
disabled={!this.isChanged()}
76+
>
7177
{app.translator.trans('core.admin.settings.submit_button')}
7278
</Button>
7379
);

framework/core/js/src/admin/components/PermissionsPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ export default class PermissionsPage extends AdminPage {
2525
.all<Group>('groups')
2626
.filter((group) => [Group.GUEST_ID, Group.MEMBER_ID].indexOf(group.id()!) === -1)
2727
.map((group) => (
28-
<button className="Button Group" onclick={() => app.modal.show(EditGroupModal, { group })}>
28+
<button className="Button Group" type="button" onclick={() => app.modal.show(EditGroupModal, { group })}>
2929
<GroupBadge group={group} className="Group-icon" label={null} />
3030
<span className="Group-name">{group.namePlural()}</span>
3131
</button>
3232
))}
33-
<button className="Button Group Group--add" onclick={() => app.modal.show(EditGroupModal)}>
33+
<button className="Button Group Group--add" type="button" onclick={() => app.modal.show(EditGroupModal)}>
3434
<Icon name="fas fa-plus" className="Group-icon" />
3535
<span className="Group-name">{app.translator.trans('core.admin.permissions.new_group_button')}</span>
3636
</button>

framework/core/js/src/admin/components/UserListPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ export default class UserListPage extends AdminPage {
352352
<button
353353
onclick={toggleEmailVisibility}
354354
className="Button Button--text UserList-emailIconBtn"
355+
type="button"
355356
title={app.translator.trans('core.admin.users.grid.columns.email.visibility_show')}
356357
>
357358
<Icon name="far fa-eye-slash fa-fw" className="icon" />

framework/core/js/src/common/components/DetailedDropdownItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default class DetailedDropdownItem<
2121
> extends Component<CustomAttrs> {
2222
view() {
2323
return (
24-
<button className="DetailedDropdownItem hasIcon" onclick={this.attrs.onclick}>
24+
<button type="button" className="DetailedDropdownItem hasIcon" onclick={this.attrs.onclick}>
2525
<Icon name={this.attrs.active ? 'fas fa-check' : 'fas'} className="Button-icon" />
2626
<span className="DetailedDropdownItem-content">
2727
<Icon name={this.attrs.icon} className="Button-icon" />

framework/core/js/src/common/components/Dropdown.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export default class Dropdown<CustomAttrs extends IDropdownAttrs = IDropdownAttr
139139
getButton(children: Mithril.ChildArray): Mithril.Vnode<any, any> {
140140
let button = (
141141
<button
142+
type="button"
142143
className={'Dropdown-toggle ' + this.attrs.buttonClassName}
143144
aria-haspopup="menu"
144145
aria-label={this.attrs.accessibleToggleLabel}

framework/core/js/src/common/components/SplitDropdown.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export default class SplitDropdown<CustomAttrs extends ISplitDropdownAttrs = ISp
4545
<>
4646
{button}
4747
<button
48+
type="button"
4849
className={'Dropdown-toggle Button Button--icon ' + this.attrs.buttonClassName}
4950
aria-haspopup="menu"
5051
aria-label={this.attrs.accessibleToggleLabel}

framework/core/js/src/forum/components/AvatarEditor.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default class AvatarEditor extends Component {
4343
<div className={classList(['AvatarEditor', 'Dropdown', this.attrs.className, this.loading && 'loading', this.isDraggedOver && 'dragover'])}>
4444
<Avatar user={user} loading="eager" />
4545
<button
46+
type="button"
4647
className={user.avatarUrl() ? 'Dropdown-toggle' : 'Dropdown-toggle AvatarEditor--noAvatar'}
4748
title={app.translator.trans('core.forum.user.avatar_upload_tooltip')}
4849
ariaLabel={app.translator.trans('core.forum.user.avatar_upload_tooltip')}

framework/core/js/src/forum/components/PostMeta.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default class PostMeta<CustomAttrs extends IPostMetaAttrs = IPostMetaAttr
4040
items.add(
4141
'time',
4242
<button
43+
type="button"
4344
className={classList({
4445
'Button Button--text': true,
4546
'Dropdown-toggle Button--link': !!permalink,

framework/core/js/src/forum/components/PostStreamScrubber.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default class PostStreamScrubber extends Component {
5858

5959
return (
6060
<div className={classNames.join(' ')}>
61-
<button className="Button Dropdown-toggle" data-toggle="dropdown">
61+
<button type="button" className="Button Dropdown-toggle" data-toggle="dropdown">
6262
{viewing} <Icon name={'fas fa-sort'} />
6363
</button>
6464

framework/core/js/src/forum/components/ReplyPlaceholder.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default class ReplyPlaceholder<CustomAttrs extends IReplyPlaceholderAttrs
5454
});
5555

5656
return (
57-
<button className="Post ReplyPlaceholder" onclick={reply}>
57+
<button type="button" className="Post ReplyPlaceholder" onclick={reply}>
5858
<div className="Post-container">
5959
<div className="Post-side">
6060
<Avatar user={app.session.user} className="Post-avatar" />

0 commit comments

Comments
 (0)