From 0c2b79acedc08fa0702b52d612aa0b92f67f1573 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Wed, 7 Feb 2018 15:16:01 +0900
Subject: [PATCH] wip

---
 src/web/app/auth/tags/form.tag                |   4 +-
 src/web/app/ch/tags/channel.tag               |  14 +-
 src/web/app/ch/tags/index.tag                 |   2 +-
 src/web/app/common/tags/error.tag             |   4 +-
 src/web/app/common/tags/messaging/form.tag    |   2 +-
 src/web/app/common/tags/messaging/index.tag   |   4 +-
 src/web/app/common/tags/messaging/room.tag    |   2 +-
 src/web/app/common/tags/poll-editor.tag       |   6 +-
 src/web/app/common/tags/poll.tag              |   4 +-
 src/web/app/common/tags/post-menu.tag         |   6 +-
 src/web/app/common/tags/reaction-picker.tag   | 184 ----------------
 src/web/app/common/tags/reaction-picker.vue   | 202 ++++++++++++++++++
 src/web/app/common/tags/signin-history.tag    |   2 +-
 src/web/app/common/tags/signup.tag            |   2 +-
 src/web/app/common/tags/stream-indicator.tag  |  78 -------
 src/web/app/common/tags/stream-indicator.vue  |  74 +++++++
 src/web/app/common/tags/twitter-setting.tag   |   4 +-
 .../desktop/tags/autocomplete-suggestion.tag  |   2 +-
 .../app/desktop/tags/big-follow-button.tag    |   2 +-
 src/web/app/desktop/tags/crop-window.tag      |   6 +-
 .../app/desktop/tags/detailed-post-window.tag |   2 +-
 src/web/app/desktop/tags/dialog.tag           |   4 +-
 src/web/app/desktop/tags/donation.tag         |   2 +-
 .../desktop/tags/drive/base-contextmenu.tag   |   6 +-
 src/web/app/desktop/tags/drive/browser.tag    |   2 +-
 .../desktop/tags/drive/file-contextmenu.tag   |  14 +-
 src/web/app/desktop/tags/drive/file.tag       |   2 +-
 .../desktop/tags/drive/folder-contextmenu.tag |   8 +-
 src/web/app/desktop/tags/drive/folder.tag     |   2 +-
 src/web/app/desktop/tags/drive/nav-folder.tag |   2 +-
 src/web/app/desktop/tags/follow-button.tag    |   2 +-
 .../app/desktop/tags/following-setuper.tag    |   4 +-
 .../desktop/tags/home-widgets/broadcast.tag   |   2 +-
 .../app/desktop/tags/home-widgets/channel.tag |   4 +-
 .../desktop/tags/home-widgets/mentions.tag    |   2 +-
 .../tags/home-widgets/notifications.tag       |   2 +-
 .../desktop/tags/home-widgets/post-form.tag   |   2 +-
 .../app/desktop/tags/home-widgets/profile.tag |   4 +-
 .../tags/home-widgets/recommended-polls.tag   |   2 +-
 .../desktop/tags/home-widgets/rss-reader.tag  |   2 +-
 .../app/desktop/tags/home-widgets/server.tag  |   2 +-
 .../desktop/tags/home-widgets/slideshow.tag   |   4 +-
 .../app/desktop/tags/home-widgets/trends.tag  |   2 +-
 .../tags/home-widgets/user-recommendation.tag |   2 +-
 src/web/app/desktop/tags/home.tag             |   2 +-
 src/web/app/desktop/tags/images.tag           |   4 +-
 src/web/app/desktop/tags/input-dialog.tag     |   4 +-
 src/web/app/desktop/tags/notifications.tag    |   2 +-
 src/web/app/desktop/tags/pages/entrance.tag   |   6 +-
 .../app/desktop/tags/pages/selectdrive.tag    |   6 +-
 src/web/app/desktop/tags/post-detail.tag      |  10 +-
 src/web/app/desktop/tags/post-form.tag        |  12 +-
 src/web/app/desktop/tags/repost-form.tag      |   6 +-
 .../tags/select-file-from-drive-window.tag    |   6 +-
 .../tags/select-folder-from-drive-window.tag  |   4 +-
 .../desktop/tags/set-avatar-suggestion.tag    |   4 +-
 .../desktop/tags/set-banner-suggestion.tag    |   4 +-
 src/web/app/desktop/tags/settings.tag         |  14 +-
 src/web/app/desktop/tags/timeline.tag         |  10 +-
 src/web/app/desktop/tags/ui.tag               |  14 +-
 src/web/app/desktop/tags/user-timeline.tag    |   2 +-
 src/web/app/desktop/tags/user.tag             |  10 +-
 src/web/app/desktop/tags/users-list.tag       |   6 +-
 src/web/app/desktop/tags/widgets/activity.tag |   2 +-
 src/web/app/desktop/tags/widgets/calendar.tag |   6 +-
 src/web/app/desktop/tags/window.tag           |   6 +-
 src/web/app/dev/tags/new-app-form.tag         |   2 +-
 .../app/mobile/tags/drive-folder-selector.tag |   4 +-
 src/web/app/mobile/tags/drive-selector.tag    |   4 +-
 src/web/app/mobile/tags/drive.tag             |   6 +-
 src/web/app/mobile/tags/drive/file-viewer.tag |   6 +-
 src/web/app/mobile/tags/drive/file.tag        |   2 +-
 src/web/app/mobile/tags/drive/folder.tag      |   2 +-
 src/web/app/mobile/tags/follow-button.tag     |   2 +-
 src/web/app/mobile/tags/init-following.tag    |   4 +-
 src/web/app/mobile/tags/notifications.tag     |   2 +-
 src/web/app/mobile/tags/page/entrance.tag     |   2 +-
 .../app/mobile/tags/page/entrance/signin.tag  |   2 +-
 .../app/mobile/tags/page/entrance/signup.tag  |   2 +-
 src/web/app/mobile/tags/page/selectdrive.tag  |   4 +-
 src/web/app/mobile/tags/page/settings.tag     |   2 +-
 .../app/mobile/tags/page/settings/profile.tag |  10 +-
 src/web/app/mobile/tags/post-detail.tag       |  10 +-
 src/web/app/mobile/tags/post-form.tag         |  14 +-
 src/web/app/mobile/tags/timeline.tag          |  10 +-
 src/web/app/mobile/tags/ui.tag                |   8 +-
 src/web/app/mobile/tags/user.tag              |   6 +-
 src/web/app/mobile/tags/users-list.tag        |   6 +-
 88 files changed, 474 insertions(+), 460 deletions(-)
 delete mode 100644 src/web/app/common/tags/reaction-picker.tag
 create mode 100644 src/web/app/common/tags/reaction-picker.vue
 delete mode 100644 src/web/app/common/tags/stream-indicator.tag
 create mode 100644 src/web/app/common/tags/stream-indicator.vue

diff --git a/src/web/app/auth/tags/form.tag b/src/web/app/auth/tags/form.tag
index 4a236f7594..5bb27c269e 100644
--- a/src/web/app/auth/tags/form.tag
+++ b/src/web/app/auth/tags/form.tag
@@ -26,8 +26,8 @@
 		</section>
 	</div>
 	<div class="action">
-		<button onclick={ cancel }>キャンセル</button>
-		<button onclick={ accept }>アクセスを許可</button>
+		<button @click="cancel">キャンセル</button>
+		<button @click="accept">アクセスを許可</button>
 	</div>
 	<style>
 		:scope
diff --git a/src/web/app/ch/tags/channel.tag b/src/web/app/ch/tags/channel.tag
index cc8ce1ed9e..7e76778f9a 100644
--- a/src/web/app/ch/tags/channel.tag
+++ b/src/web/app/ch/tags/channel.tag
@@ -5,8 +5,8 @@
 		<h1>{ channel.title }</h1>
 
 		<div if={ SIGNIN }>
-			<p if={ channel.is_watching }>このチャンネルをウォッチしています <a onclick={ unwatch }>ウォッチ解除</a></p>
-			<p if={ !channel.is_watching }><a onclick={ watch }>このチャンネルをウォッチする</a></p>
+			<p if={ channel.is_watching }>このチャンネルをウォッチしています <a @click="unwatch">ウォッチ解除</a></p>
+			<p if={ !channel.is_watching }><a @click="watch">このチャンネルをウォッチする</a></p>
 		</div>
 
 		<div class="share">
@@ -164,7 +164,7 @@
 
 <mk-channel-post>
 	<header>
-		<a class="index" onclick={ reply }>{ post.index }:</a>
+		<a class="index" @click="reply">{ post.index }:</a>
 		<a class="name" href={ _URL_ + '/' + post.user.username }><b>{ post.user.name }</b></a>
 		<mk-time time={ post.created_at }/>
 		<mk-time time={ post.created_at } mode="detail"/>
@@ -241,12 +241,12 @@
 </mk-channel-post>
 
 <mk-channel-form>
-	<p if={ reply }><b>&gt;&gt;{ reply.index }</b> ({ reply.user.name }): <a onclick={ clearReply }>[x]</a></p>
+	<p if={ reply }><b>&gt;&gt;{ reply.index }</b> ({ reply.user.name }): <a @click="clearReply">[x]</a></p>
 	<textarea ref="text" disabled={ wait } oninput={ update } onkeydown={ onkeydown } onpaste={ onpaste } placeholder="%i18n:ch.tags.mk-channel-form.textarea%"></textarea>
 	<div class="actions">
-		<button onclick={ selectFile }>%fa:upload%%i18n:ch.tags.mk-channel-form.upload%</button>
-		<button onclick={ drive }>%fa:cloud%%i18n:ch.tags.mk-channel-form.drive%</button>
-		<button class={ wait: wait } ref="submit" disabled={ wait || (refs.text.value.length == 0) } onclick={ post }>
+		<button @click="selectFile">%fa:upload%%i18n:ch.tags.mk-channel-form.upload%</button>
+		<button @click="drive">%fa:cloud%%i18n:ch.tags.mk-channel-form.drive%</button>
+		<button class={ wait: wait } ref="submit" disabled={ wait || (refs.text.value.length == 0) } @click="post">
 			<virtual if={ !wait }>%fa:paper-plane%</virtual>{ wait ? '%i18n:ch.tags.mk-channel-form.posting%' : '%i18n:ch.tags.mk-channel-form.post%' }<mk-ellipsis if={ wait }/>
 		</button>
 	</div>
diff --git a/src/web/app/ch/tags/index.tag b/src/web/app/ch/tags/index.tag
index 5f3871802a..489f21148f 100644
--- a/src/web/app/ch/tags/index.tag
+++ b/src/web/app/ch/tags/index.tag
@@ -1,7 +1,7 @@
 <mk-index>
 	<mk-header/>
 	<hr>
-	<button onclick={ n }>%i18n:ch.tags.mk-index.new%</button>
+	<button @click="n">%i18n:ch.tags.mk-index.new%</button>
 	<hr>
 	<ul if={ channels }>
 		<li each={ channels }><a href={ '/' + this.id }>{ this.title }</a></li>
diff --git a/src/web/app/common/tags/error.tag b/src/web/app/common/tags/error.tag
index a5b8d14898..07ba611615 100644
--- a/src/web/app/common/tags/error.tag
+++ b/src/web/app/common/tags/error.tag
@@ -3,12 +3,12 @@
 	<h1>%i18n:common.tags.mk-error.title%</h1>
 	<p class="text">{
 		'%i18n:common.tags.mk-error.description%'.substr(0, '%i18n:common.tags.mk-error.description%'.indexOf('{'))
-	}<a onclick={ reload }>{
+	}<a @click="reload">{
 		'%i18n:common.tags.mk-error.description%'.match(/\{(.+?)\}/)[1]
 	}</a>{
 		'%i18n:common.tags.mk-error.description%'.substr('%i18n:common.tags.mk-error.description%'.indexOf('}') + 1)
 	}</p>
-	<button if={ !troubleshooting } onclick={ troubleshoot }>%i18n:common.tags.mk-error.troubleshoot%</button>
+	<button if={ !troubleshooting } @click="troubleshoot">%i18n:common.tags.mk-error.troubleshoot%</button>
 	<mk-troubleshooter if={ troubleshooting }/>
 	<p class="thanks">%i18n:common.tags.mk-error.thanks%</p>
 	<style>
diff --git a/src/web/app/common/tags/messaging/form.tag b/src/web/app/common/tags/messaging/form.tag
index 7b133a71c4..a5de32e3fd 100644
--- a/src/web/app/common/tags/messaging/form.tag
+++ b/src/web/app/common/tags/messaging/form.tag
@@ -2,7 +2,7 @@
 	<textarea ref="text" onkeypress={ onkeypress } onpaste={ onpaste } placeholder="%i18n:common.input-message-here%"></textarea>
 	<div class="files"></div>
 	<mk-uploader ref="uploader"/>
-	<button class="send" onclick={ send } disabled={ sending } title="%i18n:common.send%">
+	<button class="send" @click="send" disabled={ sending } title="%i18n:common.send%">
 		<virtual if={ !sending }>%fa:paper-plane%</virtual><virtual if={ sending }>%fa:spinner .spin%</virtual>
 	</button>
 	<button class="attach-from-local" type="button" title="%i18n:common.tags.mk-messaging-form.attach-from-local%">
diff --git a/src/web/app/common/tags/messaging/index.tag b/src/web/app/common/tags/messaging/index.tag
index d26cec6cdf..547727da27 100644
--- a/src/web/app/common/tags/messaging/index.tag
+++ b/src/web/app/common/tags/messaging/index.tag
@@ -6,7 +6,7 @@
 		</div>
 		<div class="result">
 			<ol class="users" if={ searchResult.length > 0 } ref="searchResult">
-				<li each={ user, i in searchResult } onkeydown={ parent.onSearchResultKeydown.bind(null, i) } onclick={ user._click } tabindex="-1">
+				<li each={ user, i in searchResult } onkeydown={ parent.onSearchResultKeydown.bind(null, i) } @click="user._click" tabindex="-1">
 					<img class="avatar" src={ user.avatar_url + '?thumbnail&size=32' } alt=""/>
 					<span class="name">{ user.name }</span>
 					<span class="username">@{ user.username }</span>
@@ -16,7 +16,7 @@
 	</div>
 	<div class="history" if={ history.length > 0 }>
 		<virtual each={ history }>
-			<a class="user" data-is-me={ is_me } data-is-read={ is_read } onclick={ _click }>
+			<a class="user" data-is-me={ is_me } data-is-read={ is_read } @click="_click">
 				<div>
 					<img class="avatar" src={ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' } alt=""/>
 					<header>
diff --git a/src/web/app/common/tags/messaging/room.tag b/src/web/app/common/tags/messaging/room.tag
index 7b4d1be569..a42e0ea949 100644
--- a/src/web/app/common/tags/messaging/room.tag
+++ b/src/web/app/common/tags/messaging/room.tag
@@ -3,7 +3,7 @@
 		<p class="init" if={ init }>%fa:spinner .spin%%i18n:common.loading%</p>
 		<p class="empty" if={ !init && messages.length == 0 }>%fa:info-circle%%i18n:common.tags.mk-messaging-room.empty%</p>
 		<p class="no-history" if={ !init && messages.length > 0 && !moreMessagesIsInStock }>%fa:flag%%i18n:common.tags.mk-messaging-room.no-history%</p>
-		<button class="more { fetching: fetchingMoreMessages }" if={ moreMessagesIsInStock } onclick={ fetchMoreMessages } disabled={ fetchingMoreMessages }>
+		<button class="more { fetching: fetchingMoreMessages }" if={ moreMessagesIsInStock } @click="fetchMoreMessages" disabled={ fetchingMoreMessages }>
 			<virtual if={ fetchingMoreMessages }>%fa:spinner .pulse .fw%</virtual>{ fetchingMoreMessages ? '%i18n:common.loading%' : '%i18n:common.tags.mk-messaging-room.more%' }
 		</button>
 		<virtual each={ message, i in messages }>
diff --git a/src/web/app/common/tags/poll-editor.tag b/src/web/app/common/tags/poll-editor.tag
index e79209e9b4..73e783ddbd 100644
--- a/src/web/app/common/tags/poll-editor.tag
+++ b/src/web/app/common/tags/poll-editor.tag
@@ -5,13 +5,13 @@
 	<ul ref="choices">
 		<li each={ choice, i in choices }>
 			<input value={ choice } oninput={ oninput.bind(null, i) } placeholder={ '%i18n:common.tags.mk-poll-editor.choice-n%'.replace('{}', i + 1) }>
-			<button onclick={ remove.bind(null, i) } title="%i18n:common.tags.mk-poll-editor.remove%">
+			<button @click="remove.bind(null, i)" title="%i18n:common.tags.mk-poll-editor.remove%">
 				%fa:times%
 			</button>
 		</li>
 	</ul>
-	<button class="add" if={ choices.length < 10 } onclick={ add }>%i18n:common.tags.mk-poll-editor.add%</button>
-	<button class="destroy" onclick={ destroy } title="%i18n:common.tags.mk-poll-editor.destroy%">
+	<button class="add" if={ choices.length < 10 } @click="add">%i18n:common.tags.mk-poll-editor.add%</button>
+	<button class="destroy" @click="destroy" title="%i18n:common.tags.mk-poll-editor.destroy%">
 		%fa:times%
 	</button>
 	<style>
diff --git a/src/web/app/common/tags/poll.tag b/src/web/app/common/tags/poll.tag
index 32542418aa..3d0a559d0f 100644
--- a/src/web/app/common/tags/poll.tag
+++ b/src/web/app/common/tags/poll.tag
@@ -1,6 +1,6 @@
 <mk-poll data-is-voted={ isVoted }>
 	<ul>
-		<li each={ poll.choices } onclick={ vote.bind(null, id) } class={ voted: voted } title={ !parent.isVoted ? '%i18n:common.tags.mk-poll.vote-to%'.replace('{}', text) : '' }>
+		<li each={ poll.choices } @click="vote.bind(null, id)" class={ voted: voted } title={ !parent.isVoted ? '%i18n:common.tags.mk-poll.vote-to%'.replace('{}', text) : '' }>
 			<div class="backdrop" style={ 'width:' + (parent.result ? (votes / parent.total * 100) : 0) + '%' }></div>
 			<span>
 				<virtual if={ is_voted }>%fa:check%</virtual>
@@ -12,7 +12,7 @@
 	<p if={ total > 0 }>
 		<span>{ '%i18n:common.tags.mk-poll.total-users%'.replace('{}', total) }</span>
 		・
-		<a if={ !isVoted } onclick={ toggleResult }>{ result ? '%i18n:common.tags.mk-poll.vote%' : '%i18n:common.tags.mk-poll.show-result%' }</a>
+		<a if={ !isVoted } @click="toggleResult">{ result ? '%i18n:common.tags.mk-poll.vote%' : '%i18n:common.tags.mk-poll.show-result%' }</a>
 		<span if={ isVoted }>%i18n:common.tags.mk-poll.voted%</span>
 	</p>
 	<style>
diff --git a/src/web/app/common/tags/post-menu.tag b/src/web/app/common/tags/post-menu.tag
index be4468a214..dd2a273d4e 100644
--- a/src/web/app/common/tags/post-menu.tag
+++ b/src/web/app/common/tags/post-menu.tag
@@ -1,7 +1,7 @@
 <mk-post-menu>
-	<div class="backdrop" ref="backdrop" onclick={ close }></div>
+	<div class="backdrop" ref="backdrop" @click="close"></div>
 	<div class="popover { compact: opts.compact }" ref="popover">
-		<button if={ post.user_id === I.id } onclick={ pin }>%i18n:common.tags.mk-post-menu.pin%</button>
+		<button if={ post.user_id === I.id } @click="pin">%i18n:common.tags.mk-post-menu.pin%</button>
 		<div if={ I.is_pro && !post.is_category_verified }>
 			<select ref="categorySelect">
 				<option value="">%i18n:common.tags.mk-post-menu.select%</option>
@@ -12,7 +12,7 @@
 				<option value="gadgets">%i18n:common.post_categories.gadgets%</option>
 				<option value="photography">%i18n:common.post_categories.photography%</option>
 			</select>
-			<button onclick={ categorize }>%i18n:common.tags.mk-post-menu.categorize%</button>
+			<button @click="categorize">%i18n:common.tags.mk-post-menu.categorize%</button>
 		</div>
 	</div>
 	<style>
diff --git a/src/web/app/common/tags/reaction-picker.tag b/src/web/app/common/tags/reaction-picker.tag
deleted file mode 100644
index 458d16ec71..0000000000
--- a/src/web/app/common/tags/reaction-picker.tag
+++ /dev/null
@@ -1,184 +0,0 @@
-<mk-reaction-picker>
-	<div class="backdrop" ref="backdrop" onclick={ close }></div>
-	<div class="popover { compact: opts.compact }" ref="popover">
-		<p if={ !opts.compact }>{ title }</p>
-		<div>
-			<button onclick={ react.bind(null, 'like') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="1" title="%i18n:common.reactions.like%"><mk-reaction-icon reaction='like'/></button>
-			<button onclick={ react.bind(null, 'love') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="2" title="%i18n:common.reactions.love%"><mk-reaction-icon reaction='love'/></button>
-			<button onclick={ react.bind(null, 'laugh') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="3" title="%i18n:common.reactions.laugh%"><mk-reaction-icon reaction='laugh'/></button>
-			<button onclick={ react.bind(null, 'hmm') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="4" title="%i18n:common.reactions.hmm%"><mk-reaction-icon reaction='hmm'/></button>
-			<button onclick={ react.bind(null, 'surprise') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="5" title="%i18n:common.reactions.surprise%"><mk-reaction-icon reaction='surprise'/></button>
-			<button onclick={ react.bind(null, 'congrats') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="6" title="%i18n:common.reactions.congrats%"><mk-reaction-icon reaction='congrats'/></button>
-			<button onclick={ react.bind(null, 'angry') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="4" title="%i18n:common.reactions.angry%"><mk-reaction-icon reaction='angry'/></button>
-			<button onclick={ react.bind(null, 'confused') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="5" title="%i18n:common.reactions.confused%"><mk-reaction-icon reaction='confused'/></button>
-			<button onclick={ react.bind(null, 'pudding') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="6" title="%i18n:common.reactions.pudding%"><mk-reaction-icon reaction='pudding'/></button>
-		</div>
-	</div>
-	<style>
-		$border-color = rgba(27, 31, 35, 0.15)
-
-		:scope
-			display block
-			position initial
-
-			> .backdrop
-				position fixed
-				top 0
-				left 0
-				z-index 10000
-				width 100%
-				height 100%
-				background rgba(0, 0, 0, 0.1)
-				opacity 0
-
-			> .popover
-				position absolute
-				z-index 10001
-				background #fff
-				border 1px solid $border-color
-				border-radius 4px
-				box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
-				transform scale(0.5)
-				opacity 0
-
-				$balloon-size = 16px
-
-				&:not(.compact)
-					margin-top $balloon-size
-					transform-origin center -($balloon-size)
-
-					&:before
-						content ""
-						display block
-						position absolute
-						top -($balloon-size * 2)
-						left s('calc(50% - %s)', $balloon-size)
-						border-top solid $balloon-size transparent
-						border-left solid $balloon-size transparent
-						border-right solid $balloon-size transparent
-						border-bottom solid $balloon-size $border-color
-
-					&:after
-						content ""
-						display block
-						position absolute
-						top -($balloon-size * 2) + 1.5px
-						left s('calc(50% - %s)', $balloon-size)
-						border-top solid $balloon-size transparent
-						border-left solid $balloon-size transparent
-						border-right solid $balloon-size transparent
-						border-bottom solid $balloon-size #fff
-
-				> p
-					display block
-					margin 0
-					padding 8px 10px
-					font-size 14px
-					color #586069
-					border-bottom solid 1px #e1e4e8
-
-				> div
-					padding 4px
-					width 240px
-					text-align center
-
-					> button
-						width 40px
-						height 40px
-						font-size 24px
-						border-radius 2px
-
-						&:hover
-							background #eee
-
-						&:active
-							background $theme-color
-							box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
-
-	</style>
-	<script>
-		import anime from 'animejs';
-
-		this.mixin('api');
-
-		this.post = this.opts.post;
-		this.source = this.opts.source;
-
-		const placeholder = '%i18n:common.tags.mk-reaction-picker.choose-reaction%';
-
-		this.title = placeholder;
-
-		this.onmouseover = e => {
-			this.update({
-				title: e.target.title
-			});
-		};
-
-		this.onmouseout = () => {
-			this.update({
-				title: placeholder
-			});
-		};
-
-		this.on('mount', () => {
-			const rect = this.source.getBoundingClientRect();
-			const width = this.refs.popover.offsetWidth;
-			const height = this.refs.popover.offsetHeight;
-			if (this.opts.compact) {
-				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
-				const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
-				this.refs.popover.style.left = (x - (width / 2)) + 'px';
-				this.refs.popover.style.top = (y - (height / 2)) + 'px';
-			} else {
-				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
-				const y = rect.top + window.pageYOffset + this.source.offsetHeight;
-				this.refs.popover.style.left = (x - (width / 2)) + 'px';
-				this.refs.popover.style.top = y + 'px';
-			}
-
-			anime({
-				targets: this.refs.backdrop,
-				opacity: 1,
-				duration: 100,
-				easing: 'linear'
-			});
-
-			anime({
-				targets: this.refs.popover,
-				opacity: 1,
-				scale: [0.5, 1],
-				duration: 500
-			});
-		});
-
-		this.react = reaction => {
-			this.api('posts/reactions/create', {
-				post_id: this.post.id,
-				reaction: reaction
-			}).then(() => {
-				if (this.opts.cb) this.opts.cb();
-				this.unmount();
-			});
-		};
-
-		this.close = () => {
-			this.refs.backdrop.style.pointerEvents = 'none';
-			anime({
-				targets: this.refs.backdrop,
-				opacity: 0,
-				duration: 200,
-				easing: 'linear'
-			});
-
-			this.refs.popover.style.pointerEvents = 'none';
-			anime({
-				targets: this.refs.popover,
-				opacity: 0,
-				scale: 0.5,
-				duration: 200,
-				easing: 'easeInBack',
-				complete: () => this.unmount()
-			});
-		};
-	</script>
-</mk-reaction-picker>
diff --git a/src/web/app/common/tags/reaction-picker.vue b/src/web/app/common/tags/reaction-picker.vue
new file mode 100644
index 0000000000..2430390301
--- /dev/null
+++ b/src/web/app/common/tags/reaction-picker.vue
@@ -0,0 +1,202 @@
+<template>
+<div>
+	<div class="backdrop" ref="backdrop" @click="close"></div>
+	<div class="popover" :data-compact="compact" ref="popover">
+		<p if={ !opts.compact }>{ title }</p>
+		<div>
+			<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" title="%i18n:common.reactions.like%"><mk-reaction-icon reaction='like'/></button>
+			<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" title="%i18n:common.reactions.love%"><mk-reaction-icon reaction='love'/></button>
+			<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" title="%i18n:common.reactions.laugh%"><mk-reaction-icon reaction='laugh'/></button>
+			<button @click="react('hmm')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" title="%i18n:common.reactions.hmm%"><mk-reaction-icon reaction='hmm'/></button>
+			<button @click="react('surprise')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" title="%i18n:common.reactions.surprise%"><mk-reaction-icon reaction='surprise'/></button>
+			<button @click="react('congrats')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" title="%i18n:common.reactions.congrats%"><mk-reaction-icon reaction='congrats'/></button>
+			<button @click="react('angry')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" title="%i18n:common.reactions.angry%"><mk-reaction-icon reaction='angry'/></button>
+			<button @click="react('confused')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" title="%i18n:common.reactions.confused%"><mk-reaction-icon reaction='confused'/></button>
+			<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" title="%i18n:common.reactions.pudding%"><mk-reaction-icon reaction='pudding'/></button>
+		</div>
+	</div>
+</div>
+</template>
+
+<script>
+	import anime from 'animejs';
+	import api from '../scripts/api';
+
+	export default {
+		props: ['post', 'cb'],
+		methods: {
+			react: function (reaction) {
+				api('posts/reactions/create', {
+					post_id: this.post.id,
+					reaction: reaction
+				}).then(() => {
+					if (this.cb) this.cb();
+					this.$destroy();
+				});
+			}
+		}
+	};
+
+	this.mixin('api');
+
+	this.post = this.opts.post;
+	this.source = this.opts.source;
+
+	const placeholder = '%i18n:common.tags.mk-reaction-picker.choose-reaction%';
+
+	this.title = placeholder;
+
+	this.onmouseover = e => {
+		this.update({
+			title: e.target.title
+		});
+	};
+
+	this.onmouseout = () => {
+		this.update({
+			title: placeholder
+		});
+	};
+
+	this.on('mount', () => {
+		const rect = this.source.getBoundingClientRect();
+		const width = this.refs.popover.offsetWidth;
+		const height = this.refs.popover.offsetHeight;
+		if (this.opts.compact) {
+			const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
+			const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
+			this.refs.popover.style.left = (x - (width / 2)) + 'px';
+			this.refs.popover.style.top = (y - (height / 2)) + 'px';
+		} else {
+			const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
+			const y = rect.top + window.pageYOffset + this.source.offsetHeight;
+			this.refs.popover.style.left = (x - (width / 2)) + 'px';
+			this.refs.popover.style.top = y + 'px';
+		}
+
+		anime({
+			targets: this.refs.backdrop,
+			opacity: 1,
+			duration: 100,
+			easing: 'linear'
+		});
+
+		anime({
+			targets: this.refs.popover,
+			opacity: 1,
+			scale: [0.5, 1],
+			duration: 500
+		});
+	});
+
+	this.react = reaction => {
+
+	};
+
+	this.close = () => {
+		this.refs.backdrop.style.pointerEvents = 'none';
+		anime({
+			targets: this.refs.backdrop,
+			opacity: 0,
+			duration: 200,
+			easing: 'linear'
+		});
+
+		this.refs.popover.style.pointerEvents = 'none';
+		anime({
+			targets: this.refs.popover,
+			opacity: 0,
+			scale: 0.5,
+			duration: 200,
+			easing: 'easeInBack',
+			complete: () => this.unmount()
+		});
+	};
+</script>
+
+<mk-reaction-picker>
+
+	<style>
+		$border-color = rgba(27, 31, 35, 0.15)
+
+		:scope
+			display block
+			position initial
+
+			> .backdrop
+				position fixed
+				top 0
+				left 0
+				z-index 10000
+				width 100%
+				height 100%
+				background rgba(0, 0, 0, 0.1)
+				opacity 0
+
+			> .popover
+				position absolute
+				z-index 10001
+				background #fff
+				border 1px solid $border-color
+				border-radius 4px
+				box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
+				transform scale(0.5)
+				opacity 0
+
+				$balloon-size = 16px
+
+				&:not(.compact)
+					margin-top $balloon-size
+					transform-origin center -($balloon-size)
+
+					&:before
+						content ""
+						display block
+						position absolute
+						top -($balloon-size * 2)
+						left s('calc(50% - %s)', $balloon-size)
+						border-top solid $balloon-size transparent
+						border-left solid $balloon-size transparent
+						border-right solid $balloon-size transparent
+						border-bottom solid $balloon-size $border-color
+
+					&:after
+						content ""
+						display block
+						position absolute
+						top -($balloon-size * 2) + 1.5px
+						left s('calc(50% - %s)', $balloon-size)
+						border-top solid $balloon-size transparent
+						border-left solid $balloon-size transparent
+						border-right solid $balloon-size transparent
+						border-bottom solid $balloon-size #fff
+
+				> p
+					display block
+					margin 0
+					padding 8px 10px
+					font-size 14px
+					color #586069
+					border-bottom solid 1px #e1e4e8
+
+				> div
+					padding 4px
+					width 240px
+					text-align center
+
+					> button
+						width 40px
+						height 40px
+						font-size 24px
+						border-radius 2px
+
+						&:hover
+							background #eee
+
+						&:active
+							background $theme-color
+							box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
+
+	</style>
+
+</mk-reaction-picker>
diff --git a/src/web/app/common/tags/signin-history.tag b/src/web/app/common/tags/signin-history.tag
index cdd58c4c67..10729789c6 100644
--- a/src/web/app/common/tags/signin-history.tag
+++ b/src/web/app/common/tags/signin-history.tag
@@ -42,7 +42,7 @@
 </mk-signin-history>
 
 <mk-signin-record>
-	<header onclick={ toggle }>
+	<header @click="toggle">
 		<virtual if={ rec.success }>%fa:check%</virtual>
 		<virtual if={ !rec.success }>%fa:times%</virtual>
 		<span class="ip">{ rec.ip }</span>
diff --git a/src/web/app/common/tags/signup.tag b/src/web/app/common/tags/signup.tag
index b488efb927..d0bd769074 100644
--- a/src/web/app/common/tags/signup.tag
+++ b/src/web/app/common/tags/signup.tag
@@ -36,7 +36,7 @@
 			<input name="agree-tou" type="checkbox" autocomplete="off" required="required"/>
 			<p><a href={ touUrl } target="_blank">利用規約</a>に同意する</p>
 		</label>
-		<button onclick={ onsubmit }>%i18n:common.tags.mk-signup.create%</button>
+		<button @click="onsubmit">%i18n:common.tags.mk-signup.create%</button>
 	</form>
 	<style>
 		:scope
diff --git a/src/web/app/common/tags/stream-indicator.tag b/src/web/app/common/tags/stream-indicator.tag
deleted file mode 100644
index 0eb6196b6d..0000000000
--- a/src/web/app/common/tags/stream-indicator.tag
+++ /dev/null
@@ -1,78 +0,0 @@
-<mk-stream-indicator>
-	<p if={ connection.state == 'initializing' }>
-		%fa:spinner .pulse%
-		<span>%i18n:common.tags.mk-stream-indicator.connecting%<mk-ellipsis/></span>
-	</p>
-	<p if={ connection.state == 'reconnecting' }>
-		%fa:spinner .pulse%
-		<span>%i18n:common.tags.mk-stream-indicator.reconnecting%<mk-ellipsis/></span>
-	</p>
-	<p if={ connection.state == 'connected' }>
-		%fa:check%
-		<span>%i18n:common.tags.mk-stream-indicator.connected%</span>
-	</p>
-	<style>
-		:scope
-			display block
-			pointer-events none
-			position fixed
-			z-index 16384
-			bottom 8px
-			right 8px
-			margin 0
-			padding 6px 12px
-			font-size 0.9em
-			color #fff
-			background rgba(0, 0, 0, 0.8)
-			border-radius 4px
-
-			> p
-				display block
-				margin 0
-
-				> [data-fa]
-					margin-right 0.25em
-
-	</style>
-	<script>
-		import anime from 'animejs';
-
-		this.mixin('i');
-
-		this.mixin('stream');
-		this.connection = this.stream.getConnection();
-		this.connectionId = this.stream.use();
-
-		this.on('before-mount', () => {
-			if (this.connection.state == 'connected') {
-				this.root.style.opacity = 0;
-			}
-
-			this.connection.on('_connected_', () => {
-				this.update();
-				setTimeout(() => {
-					anime({
-						targets: this.root,
-						opacity: 0,
-						easing: 'linear',
-						duration: 200
-					});
-				}, 1000);
-			});
-
-			this.connection.on('_closed_', () => {
-				this.update();
-				anime({
-					targets: this.root,
-					opacity: 1,
-					easing: 'linear',
-					duration: 100
-				});
-			});
-		});
-
-		this.on('unmount', () => {
-			this.stream.dispose(this.connectionId);
-		});
-	</script>
-</mk-stream-indicator>
diff --git a/src/web/app/common/tags/stream-indicator.vue b/src/web/app/common/tags/stream-indicator.vue
new file mode 100644
index 0000000000..619237193a
--- /dev/null
+++ b/src/web/app/common/tags/stream-indicator.vue
@@ -0,0 +1,74 @@
+<template>
+	<div>
+		<p v-if=" stream.state == 'initializing' ">
+			%fa:spinner .pulse%
+			<span>%i18n:common.tags.mk-stream-indicator.connecting%<mk-ellipsis/></span>
+		</p>
+		<p v-if=" stream.state == 'reconnecting' ">
+			%fa:spinner .pulse%
+			<span>%i18n:common.tags.mk-stream-indicator.reconnecting%<mk-ellipsis/></span>
+		</p>
+		<p v-if=" stream.state == 'connected' ">
+			%fa:check%
+			<span>%i18n:common.tags.mk-stream-indicator.connected%</span>
+		</p>
+	</div>
+</template>
+
+<script>
+	import anime from 'animejs';
+	import Ellipsis from './ellipsis.vue';
+
+	export default {
+		props: ['stream'],
+		created: function() {
+			if (this.stream.state == 'connected') {
+				this.root.style.opacity = 0;
+			}
+
+			this.stream.on('_connected_', () => {
+				setTimeout(() => {
+					anime({
+						targets: this.root,
+						opacity: 0,
+						easing: 'linear',
+						duration: 200
+					});
+				}, 1000);
+			});
+
+			this.stream.on('_closed_', () => {
+				anime({
+					targets: this.root,
+					opacity: 1,
+					easing: 'linear',
+					duration: 100
+				});
+			});
+		}
+	};
+</script>
+
+<style lang="stylus">
+	> div
+		display block
+		pointer-events none
+		position fixed
+		z-index 16384
+		bottom 8px
+		right 8px
+		margin 0
+		padding 6px 12px
+		font-size 0.9em
+		color #fff
+		background rgba(0, 0, 0, 0.8)
+		border-radius 4px
+
+		> p
+			display block
+			margin 0
+
+			> [data-fa]
+				margin-right 0.25em
+
+</style>
diff --git a/src/web/app/common/tags/twitter-setting.tag b/src/web/app/common/tags/twitter-setting.tag
index 4d57cfa55a..8419f8b62a 100644
--- a/src/web/app/common/tags/twitter-setting.tag
+++ b/src/web/app/common/tags/twitter-setting.tag
@@ -2,9 +2,9 @@
 	<p>%i18n:common.tags.mk-twitter-setting.description%<a href={ _DOCS_URL_ + '/link-to-twitter' } target="_blank">%i18n:common.tags.mk-twitter-setting.detail%</a></p>
 	<p class="account" if={ I.twitter } title={ 'Twitter ID: ' + I.twitter.user_id }>%i18n:common.tags.mk-twitter-setting.connected-to%: <a href={ 'https://twitter.com/' + I.twitter.screen_name } target="_blank">@{ I.twitter.screen_name }</a></p>
 	<p>
-		<a href={ _API_URL_ + '/connect/twitter' } target="_blank" onclick={ connect }>{ I.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }</a>
+		<a href={ _API_URL_ + '/connect/twitter' } target="_blank" @click="connect">{ I.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }</a>
 		<span if={ I.twitter }> or </span>
-		<a href={ _API_URL_ + '/disconnect/twitter' } target="_blank" if={ I.twitter } onclick={ disconnect }>%i18n:common.tags.mk-twitter-setting.disconnect%</a>
+		<a href={ _API_URL_ + '/disconnect/twitter' } target="_blank" if={ I.twitter } @click="disconnect">%i18n:common.tags.mk-twitter-setting.disconnect%</a>
 	</p>
 	<p class="id" if={ I.twitter }>Twitter ID: { I.twitter.user_id }</p>
 	<style>
diff --git a/src/web/app/desktop/tags/autocomplete-suggestion.tag b/src/web/app/desktop/tags/autocomplete-suggestion.tag
index 7311606694..5304875c17 100644
--- a/src/web/app/desktop/tags/autocomplete-suggestion.tag
+++ b/src/web/app/desktop/tags/autocomplete-suggestion.tag
@@ -1,6 +1,6 @@
 <mk-autocomplete-suggestion>
 	<ol class="users" ref="users" if={ users.length > 0 }>
-		<li each={ users } onclick={ parent.onClick } onkeydown={ parent.onKeydown } tabindex="-1">
+		<li each={ users } @click="parent.onClick" onkeydown={ parent.onKeydown } tabindex="-1">
 			<img class="avatar" src={ avatar_url + '?thumbnail&size=32' } alt=""/>
 			<span class="name">{ name }</span>
 			<span class="username">@{ username }</span>
diff --git a/src/web/app/desktop/tags/big-follow-button.tag b/src/web/app/desktop/tags/big-follow-button.tag
index 7634043b20..476f958401 100644
--- a/src/web/app/desktop/tags/big-follow-button.tag
+++ b/src/web/app/desktop/tags/big-follow-button.tag
@@ -1,5 +1,5 @@
 <mk-big-follow-button>
-	<button class={ wait: wait, follow: !user.is_following, unfollow: user.is_following } if={ !init } onclick={ onclick } disabled={ wait } title={ user.is_following ? 'フォロー解除' : 'フォローする' }>
+	<button class={ wait: wait, follow: !user.is_following, unfollow: user.is_following } if={ !init } @click="onclick" disabled={ wait } title={ user.is_following ? 'フォロー解除' : 'フォローする' }>
 		<span if={ !wait && user.is_following }>%fa:minus%フォロー解除</span>
 		<span if={ !wait && !user.is_following }>%fa:plus%フォロー</span>
 		<virtual if={ wait }>%fa:spinner .pulse .fw%</virtual>
diff --git a/src/web/app/desktop/tags/crop-window.tag b/src/web/app/desktop/tags/crop-window.tag
index 4845b669d2..b74b46b77e 100644
--- a/src/web/app/desktop/tags/crop-window.tag
+++ b/src/web/app/desktop/tags/crop-window.tag
@@ -4,9 +4,9 @@
 		<yield to="content">
 			<div class="body"><img ref="img" src={ parent.image.url + '?thumbnail&quality=80' } alt=""/></div>
 			<div class="action">
-				<button class="skip" onclick={ parent.skip }>クロップをスキップ</button>
-				<button class="cancel" onclick={ parent.cancel }>キャンセル</button>
-				<button class="ok" onclick={ parent.ok }>決定</button>
+				<button class="skip" @click="parent.skip">クロップをスキップ</button>
+				<button class="cancel" @click="parent.cancel">キャンセル</button>
+				<button class="ok" @click="parent.ok">決定</button>
 			</div>
 		</yield>
 	</mk-window>
diff --git a/src/web/app/desktop/tags/detailed-post-window.tag b/src/web/app/desktop/tags/detailed-post-window.tag
index 04f9acf974..a0bcdc79ac 100644
--- a/src/web/app/desktop/tags/detailed-post-window.tag
+++ b/src/web/app/desktop/tags/detailed-post-window.tag
@@ -1,5 +1,5 @@
 <mk-detailed-post-window>
-	<div class="bg" ref="bg" onclick={ bgClick }></div>
+	<div class="bg" ref="bg" @click="bgClick"></div>
 	<div class="main" ref="main" if={ !fetching }>
 		<mk-post-detail ref="detail" post={ post }/>
 	</div>
diff --git a/src/web/app/desktop/tags/dialog.tag b/src/web/app/desktop/tags/dialog.tag
index 743fd63942..f213211730 100644
--- a/src/web/app/desktop/tags/dialog.tag
+++ b/src/web/app/desktop/tags/dialog.tag
@@ -1,11 +1,11 @@
 <mk-dialog>
-	<div class="bg" ref="bg" onclick={ bgClick }></div>
+	<div class="bg" ref="bg" @click="bgClick"></div>
 	<div class="main" ref="main">
 		<header ref="header"></header>
 		<div class="body" ref="body"></div>
 		<div class="buttons">
 			<virtual each={ opts.buttons }>
-				<button onclick={ _onclick }>{ text }</button>
+				<button @click="_onclick">{ text }</button>
 			</virtual>
 		</div>
 	</div>
diff --git a/src/web/app/desktop/tags/donation.tag b/src/web/app/desktop/tags/donation.tag
index 1c19fac1f5..b2d18d4450 100644
--- a/src/web/app/desktop/tags/donation.tag
+++ b/src/web/app/desktop/tags/donation.tag
@@ -1,5 +1,5 @@
 <mk-donation>
-	<button class="close" onclick={ close }>閉じる x</button>
+	<button class="close" @click="close">閉じる x</button>
 	<div class="message">
 		<p>利用者の皆さま、</p>
 		<p>
diff --git a/src/web/app/desktop/tags/drive/base-contextmenu.tag b/src/web/app/desktop/tags/drive/base-contextmenu.tag
index b16dbf55d6..2d7796c682 100644
--- a/src/web/app/desktop/tags/drive/base-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/base-contextmenu.tag
@@ -1,13 +1,13 @@
 <mk-drive-browser-base-contextmenu>
 	<mk-contextmenu ref="ctx">
 		<ul>
-			<li onclick={ parent.createFolder }>
+			<li @click="parent.createFolder">
 				<p>%fa:R folder%%i18n:desktop.tags.mk-drive-browser-base-contextmenu.create-folder%</p>
 			</li>
-			<li onclick={ parent.upload }>
+			<li @click="parent.upload">
 				<p>%fa:upload%%i18n:desktop.tags.mk-drive-browser-base-contextmenu.upload%</p>
 			</li>
-			<li onclick={ parent.urlUpload }>
+			<li @click="parent.urlUpload">
 				<p>%fa:cloud-upload-alt%%i18n:desktop.tags.mk-drive-browser-base-contextmenu.url-upload%</p>
 			</li>
 		</ul>
diff --git a/src/web/app/desktop/tags/drive/browser.tag b/src/web/app/desktop/tags/drive/browser.tag
index a60a46b790..f9dea51271 100644
--- a/src/web/app/desktop/tags/drive/browser.tag
+++ b/src/web/app/desktop/tags/drive/browser.tag
@@ -28,7 +28,7 @@
 				</virtual>
 				<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
 				<div class="padding" each={ Array(10).fill(16) }></div>
-				<button if={ moreFiles } onclick={ fetchMoreFiles }>%i18n:desktop.tags.mk-drive-browser.load-more%</button>
+				<button if={ moreFiles } @click="fetchMoreFiles">%i18n:desktop.tags.mk-drive-browser.load-more%</button>
 			</div>
 			<div class="empty" if={ files.length == 0 && folders.length == 0 && !fetching }>
 				<p if={ draghover }>%i18n:desktop.tags.mk-drive-browser.empty-draghover%</p>
diff --git a/src/web/app/desktop/tags/drive/file-contextmenu.tag b/src/web/app/desktop/tags/drive/file-contextmenu.tag
index 532417c757..31ab05c23b 100644
--- a/src/web/app/desktop/tags/drive/file-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/file-contextmenu.tag
@@ -1,25 +1,25 @@
 <mk-drive-browser-file-contextmenu>
 	<mk-contextmenu ref="ctx">
 		<ul>
-			<li onclick={ parent.rename }>
+			<li @click="parent.rename">
 				<p>%fa:i-cursor%%i18n:desktop.tags.mk-drive-browser-file-contextmenu.rename%</p>
 			</li>
-			<li onclick={ parent.copyUrl }>
+			<li @click="parent.copyUrl">
 				<p>%fa:link%%i18n:desktop.tags.mk-drive-browser-file-contextmenu.copy-url%</p>
 			</li>
-			<li><a href={ parent.file.url + '?download' } download={ parent.file.name } onclick={ parent.download }>%fa:download%%i18n:desktop.tags.mk-drive-browser-file-contextmenu.download%</a></li>
+			<li><a href={ parent.file.url + '?download' } download={ parent.file.name } @click="parent.download">%fa:download%%i18n:desktop.tags.mk-drive-browser-file-contextmenu.download%</a></li>
 			<li class="separator"></li>
-			<li onclick={ parent.delete }>
+			<li @click="parent.delete">
 				<p>%fa:R trash-alt%%i18n:common.delete%</p>
 			</li>
 			<li class="separator"></li>
 			<li class="has-child">
 				<p>%i18n:desktop.tags.mk-drive-browser-file-contextmenu.else-files%%fa:caret-right%</p>
 				<ul>
-					<li onclick={ parent.setAvatar }>
+					<li @click="parent.setAvatar">
 						<p>%i18n:desktop.tags.mk-drive-browser-file-contextmenu.set-as-avatar%</p>
 					</li>
-					<li onclick={ parent.setBanner }>
+					<li @click="parent.setBanner">
 						<p>%i18n:desktop.tags.mk-drive-browser-file-contextmenu.set-as-banner%</p>
 					</li>
 				</ul>
@@ -27,7 +27,7 @@
 			<li class="has-child">
 				<p>%i18n:desktop.tags.mk-drive-browser-file-contextmenu.open-in-app%...%fa:caret-right%</p>
 				<ul>
-					<li onclick={ parent.addApp }>
+					<li @click="parent.addApp">
 						<p>%i18n:desktop.tags.mk-drive-browser-file-contextmenu.add-app%...</p>
 					</li>
 				</ul>
diff --git a/src/web/app/desktop/tags/drive/file.tag b/src/web/app/desktop/tags/drive/file.tag
index 8b3d36b3f3..2a1519dc7e 100644
--- a/src/web/app/desktop/tags/drive/file.tag
+++ b/src/web/app/desktop/tags/drive/file.tag
@@ -1,4 +1,4 @@
-<mk-drive-browser-file data-is-selected={ isSelected } data-is-contextmenu-showing={ isContextmenuShowing.toString() } onclick={ onclick } oncontextmenu={ oncontextmenu } draggable="true" ondragstart={ ondragstart } ondragend={ ondragend } title={ title }>
+<mk-drive-browser-file data-is-selected={ isSelected } data-is-contextmenu-showing={ isContextmenuShowing.toString() } @click="onclick" oncontextmenu={ oncontextmenu } draggable="true" ondragstart={ ondragstart } ondragend={ ondragend } title={ title }>
 	<div class="label" if={ I.avatar_id == file.id }><img src="/assets/label.svg"/>
 		<p>%i18n:desktop.tags.mk-drive-browser-file.avatar%</p>
 	</div>
diff --git a/src/web/app/desktop/tags/drive/folder-contextmenu.tag b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
index c6a1ea3b84..eb8cad52a7 100644
--- a/src/web/app/desktop/tags/drive/folder-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
@@ -1,18 +1,18 @@
 <mk-drive-browser-folder-contextmenu>
 	<mk-contextmenu ref="ctx">
 		<ul>
-			<li onclick={ parent.move }>
+			<li @click="parent.move">
 				<p>%fa:arrow-right%%i18n:desktop.tags.mk-drive-browser-folder-contextmenu.move-to-this-folder%</p>
 			</li>
-			<li onclick={ parent.newWindow }>
+			<li @click="parent.newWindow">
 				<p>%fa:R window-restore%%i18n:desktop.tags.mk-drive-browser-folder-contextmenu.show-in-new-window%</p>
 			</li>
 			<li class="separator"></li>
-			<li onclick={ parent.rename }>
+			<li @click="parent.rename">
 				<p>%fa:i-cursor%%i18n:desktop.tags.mk-drive-browser-folder-contextmenu.rename%</p>
 			</li>
 			<li class="separator"></li>
-			<li onclick={ parent.delete }>
+			<li @click="parent.delete">
 				<p>%fa:R trash-alt%%i18n:common.delete%</p>
 			</li>
 		</ul>
diff --git a/src/web/app/desktop/tags/drive/folder.tag b/src/web/app/desktop/tags/drive/folder.tag
index 0b7ee6e2d1..2fae55e503 100644
--- a/src/web/app/desktop/tags/drive/folder.tag
+++ b/src/web/app/desktop/tags/drive/folder.tag
@@ -1,4 +1,4 @@
-<mk-drive-browser-folder data-is-contextmenu-showing={ isContextmenuShowing.toString() } data-draghover={ draghover.toString() } onclick={ onclick } onmouseover={ onmouseover } onmouseout={ onmouseout } ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop } oncontextmenu={ oncontextmenu } draggable="true" ondragstart={ ondragstart } ondragend={ ondragend } title={ title }>
+<mk-drive-browser-folder data-is-contextmenu-showing={ isContextmenuShowing.toString() } data-draghover={ draghover.toString() } @click="onclick" onmouseover={ onmouseover } onmouseout={ onmouseout } ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop } oncontextmenu={ oncontextmenu } draggable="true" ondragstart={ ondragstart } ondragend={ ondragend } title={ title }>
 	<p class="name"><virtual if={ hover }>%fa:R folder-open .fw%</virtual><virtual if={ !hover }>%fa:R folder .fw%</virtual>{ folder.name }</p>
 	<style>
 		:scope
diff --git a/src/web/app/desktop/tags/drive/nav-folder.tag b/src/web/app/desktop/tags/drive/nav-folder.tag
index 43a648b52b..d688d2e084 100644
--- a/src/web/app/desktop/tags/drive/nav-folder.tag
+++ b/src/web/app/desktop/tags/drive/nav-folder.tag
@@ -1,4 +1,4 @@
-<mk-drive-browser-nav-folder data-draghover={ draghover } onclick={ onclick } ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop }>
+<mk-drive-browser-nav-folder data-draghover={ draghover } @click="onclick" ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop }>
 	<virtual if={ folder == null }>%fa:cloud%</virtual><span>{ folder == null ? '%i18n:desktop.tags.mk-drive-browser-nav-folder.drive%' : folder.name }</span>
 	<style>
 		:scope
diff --git a/src/web/app/desktop/tags/follow-button.tag b/src/web/app/desktop/tags/follow-button.tag
index ce6de3ac69..8a1f7b2c14 100644
--- a/src/web/app/desktop/tags/follow-button.tag
+++ b/src/web/app/desktop/tags/follow-button.tag
@@ -1,5 +1,5 @@
 <mk-follow-button>
-	<button class={ wait: wait, follow: !user.is_following, unfollow: user.is_following } if={ !init } onclick={ onclick } disabled={ wait } title={ user.is_following ? 'フォロー解除' : 'フォローする' }>
+	<button class={ wait: wait, follow: !user.is_following, unfollow: user.is_following } if={ !init } @click="onclick" disabled={ wait } title={ user.is_following ? 'フォロー解除' : 'フォローする' }>
 		<virtual if={ !wait && user.is_following }>%fa:minus%</virtual>
 		<virtual if={ !wait && !user.is_following }>%fa:plus%</virtual>
 		<virtual if={ wait }>%fa:spinner .pulse .fw%</virtual>
diff --git a/src/web/app/desktop/tags/following-setuper.tag b/src/web/app/desktop/tags/following-setuper.tag
index a51a38ccd5..8280986298 100644
--- a/src/web/app/desktop/tags/following-setuper.tag
+++ b/src/web/app/desktop/tags/following-setuper.tag
@@ -10,8 +10,8 @@
 	</div>
 	<p class="empty" if={ !fetching && users.length == 0 }>おすすめのユーザーは見つかりませんでした。</p>
 	<p class="fetching" if={ fetching }>%fa:spinner .pulse .fw%読み込んでいます<mk-ellipsis/></p>
-	<a class="refresh" onclick={ refresh }>もっと見る</a>
-	<button class="close" onclick={ close } title="閉じる">%fa:times%</button>
+	<a class="refresh" @click="refresh">もっと見る</a>
+	<button class="close" @click="close" title="閉じる">%fa:times%</button>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/desktop/tags/home-widgets/broadcast.tag b/src/web/app/desktop/tags/home-widgets/broadcast.tag
index 6f4bb0756d..157c429634 100644
--- a/src/web/app/desktop/tags/home-widgets/broadcast.tag
+++ b/src/web/app/desktop/tags/home-widgets/broadcast.tag
@@ -13,7 +13,7 @@
 		broadcasts.length == 0 ? '%i18n:desktop.tags.mk-broadcast-home-widget.no-broadcasts%' : broadcasts[i].title
 	}</h1>
 	<p if={ !fetching }><mk-raw if={ broadcasts.length != 0 } content={ broadcasts[i].text }/><virtual if={ broadcasts.length == 0 }>%i18n:desktop.tags.mk-broadcast-home-widget.have-a-nice-day%</virtual></p>
-	<a if={ broadcasts.length > 1 } onclick={ next }>%i18n:desktop.tags.mk-broadcast-home-widget.next% &gt;&gt;</a>
+	<a if={ broadcasts.length > 1 } @click="next">%i18n:desktop.tags.mk-broadcast-home-widget.next% &gt;&gt;</a>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/desktop/tags/home-widgets/channel.tag b/src/web/app/desktop/tags/home-widgets/channel.tag
index 545bc38acf..0e40caa1e2 100644
--- a/src/web/app/desktop/tags/home-widgets/channel.tag
+++ b/src/web/app/desktop/tags/home-widgets/channel.tag
@@ -3,7 +3,7 @@
 		<p class="title">%fa:tv%{
 			channel ? channel.title : '%i18n:desktop.tags.mk-channel-home-widget.title%'
 		}</p>
-		<button onclick={ settings } title="%i18n:desktop.tags.mk-channel-home-widget.settings%">%fa:cog%</button>
+		<button @click="settings" title="%i18n:desktop.tags.mk-channel-home-widget.settings%">%fa:cog%</button>
 	</virtual>
 	<p class="get-started" if={ this.data.channel == null }>%i18n:desktop.tags.mk-channel-home-widget.get-started%</p>
 	<mk-channel ref="channel" show={ this.data.channel }/>
@@ -192,7 +192,7 @@
 
 <mk-channel-post>
 	<header>
-		<a class="index" onclick={ reply }>{ post.index }:</a>
+		<a class="index" @click="reply">{ post.index }:</a>
 		<a class="name" href={ _URL_ + '/' + post.user.username }><b>{ post.user.name }</b></a>
 		<span>ID:<i>{ post.user.username }</i></span>
 	</header>
diff --git a/src/web/app/desktop/tags/home-widgets/mentions.tag b/src/web/app/desktop/tags/home-widgets/mentions.tag
index 2687283079..94329f0304 100644
--- a/src/web/app/desktop/tags/home-widgets/mentions.tag
+++ b/src/web/app/desktop/tags/home-widgets/mentions.tag
@@ -1,5 +1,5 @@
 <mk-mentions-home-widget>
-	<header><span data-is-active={ mode == 'all' } onclick={ setMode.bind(this, 'all') }>すべて</span><span data-is-active={ mode == 'following' } onclick={ setMode.bind(this, 'following') }>フォロー中</span></header>
+	<header><span data-is-active={ mode == 'all' } @click="setMode.bind(this, 'all')">すべて</span><span data-is-active={ mode == 'following' } @click="setMode.bind(this, 'following')">フォロー中</span></header>
 	<div class="loading" if={ isLoading }>
 		<mk-ellipsis-icon/>
 	</div>
diff --git a/src/web/app/desktop/tags/home-widgets/notifications.tag b/src/web/app/desktop/tags/home-widgets/notifications.tag
index 0ccd832d71..051714eab0 100644
--- a/src/web/app/desktop/tags/home-widgets/notifications.tag
+++ b/src/web/app/desktop/tags/home-widgets/notifications.tag
@@ -1,7 +1,7 @@
 <mk-notifications-home-widget>
 	<virtual if={ !data.compact }>
 		<p class="title">%fa:R bell%%i18n:desktop.tags.mk-notifications-home-widget.title%</p>
-		<button onclick={ settings } title="%i18n:desktop.tags.mk-notifications-home-widget.settings%">%fa:cog%</button>
+		<button @click="settings" title="%i18n:desktop.tags.mk-notifications-home-widget.settings%">%fa:cog%</button>
 	</virtual>
 	<mk-notifications/>
 	<style>
diff --git a/src/web/app/desktop/tags/home-widgets/post-form.tag b/src/web/app/desktop/tags/home-widgets/post-form.tag
index c8ccc5a30e..b6310d6aa3 100644
--- a/src/web/app/desktop/tags/home-widgets/post-form.tag
+++ b/src/web/app/desktop/tags/home-widgets/post-form.tag
@@ -5,7 +5,7 @@
 			<p class="title">%fa:pencil-alt%%i18n:desktop.tags.mk-post-form-home-widget.title%</p>
 		</virtual>
 		<textarea disabled={ posting } ref="text" onkeydown={ onkeydown } placeholder="%i18n:desktop.tags.mk-post-form-home-widget.placeholder%"></textarea>
-		<button onclick={ post } disabled={ posting }>%i18n:desktop.tags.mk-post-form-home-widget.post%</button>
+		<button @click="post" disabled={ posting }>%i18n:desktop.tags.mk-post-form-home-widget.post%</button>
 	</virtual>
 	<style>
 		:scope
diff --git a/src/web/app/desktop/tags/home-widgets/profile.tag b/src/web/app/desktop/tags/home-widgets/profile.tag
index eb8ba52e84..bba5b0c478 100644
--- a/src/web/app/desktop/tags/home-widgets/profile.tag
+++ b/src/web/app/desktop/tags/home-widgets/profile.tag
@@ -1,6 +1,6 @@
 <mk-profile-home-widget data-compact={ data.design == 1 || data.design == 2 } data-melt={ data.design == 2 }>
-	<div class="banner" style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' } title="クリックでバナー編集" onclick={ setBanner }></div>
-	<img class="avatar" src={ I.avatar_url + '?thumbnail&size=96' } onclick={ setAvatar } alt="avatar" title="クリックでアバター編集" data-user-preview={ I.id }/>
+	<div class="banner" style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' } title="クリックでバナー編集" @click="setBanner"></div>
+	<img class="avatar" src={ I.avatar_url + '?thumbnail&size=96' } @click="setAvatar" alt="avatar" title="クリックでアバター編集" data-user-preview={ I.id }/>
 	<a class="name" href={ '/' + I.username }>{ I.name }</a>
 	<p class="username">@{ I.username }</p>
 	<style>
diff --git a/src/web/app/desktop/tags/home-widgets/recommended-polls.tag b/src/web/app/desktop/tags/home-widgets/recommended-polls.tag
index 776f666015..5489edf5f8 100644
--- a/src/web/app/desktop/tags/home-widgets/recommended-polls.tag
+++ b/src/web/app/desktop/tags/home-widgets/recommended-polls.tag
@@ -1,7 +1,7 @@
 <mk-recommended-polls-home-widget>
 	<virtual if={ !data.compact }>
 		<p class="title">%fa:chart-pie%%i18n:desktop.tags.mk-recommended-polls-home-widget.title%</p>
-		<button onclick={ fetch } title="%i18n:desktop.tags.mk-recommended-polls-home-widget.refresh%">%fa:sync%</button>
+		<button @click="fetch" title="%i18n:desktop.tags.mk-recommended-polls-home-widget.refresh%">%fa:sync%</button>
 	</virtual>
 	<div class="poll" if={ !loading && poll != null }>
 		<p if={ poll.text }><a href="/{ poll.user.username }/{ poll.id }">{ poll.text }</a></p>
diff --git a/src/web/app/desktop/tags/home-widgets/rss-reader.tag b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
index a927693ce8..45cc62a51a 100644
--- a/src/web/app/desktop/tags/home-widgets/rss-reader.tag
+++ b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
@@ -1,7 +1,7 @@
 <mk-rss-reader-home-widget>
 	<virtual if={ !data.compact }>
 		<p class="title">%fa:rss-square%RSS</p>
-		<button onclick={ settings } title="設定">%fa:cog%</button>
+		<button @click="settings" title="設定">%fa:cog%</button>
 	</virtual>
 	<div class="feed" if={ !initializing }>
 		<virtual each={ item in items }><a href={ item.link } target="_blank">{ item.title }</a></virtual>
diff --git a/src/web/app/desktop/tags/home-widgets/server.tag b/src/web/app/desktop/tags/home-widgets/server.tag
index b9b191c181..6eb4ce15b7 100644
--- a/src/web/app/desktop/tags/home-widgets/server.tag
+++ b/src/web/app/desktop/tags/home-widgets/server.tag
@@ -1,7 +1,7 @@
 <mk-server-home-widget data-melt={ data.design == 2 }>
 	<virtual if={ data.design == 0 }>
 		<p class="title">%fa:server%%i18n:desktop.tags.mk-server-home-widget.title%</p>
-		<button onclick={ toggle } title="%i18n:desktop.tags.mk-server-home-widget.toggle%">%fa:sort%</button>
+		<button @click="toggle" title="%i18n:desktop.tags.mk-server-home-widget.toggle%">%fa:sort%</button>
 	</virtual>
 	<p class="initializing" if={ initializing }>%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
 	<mk-server-home-widget-cpu-and-memory-usage if={ !initializing } show={ data.view == 0 } connection={ connection }/>
diff --git a/src/web/app/desktop/tags/home-widgets/slideshow.tag b/src/web/app/desktop/tags/home-widgets/slideshow.tag
index 53fe047000..af54fd893d 100644
--- a/src/web/app/desktop/tags/home-widgets/slideshow.tag
+++ b/src/web/app/desktop/tags/home-widgets/slideshow.tag
@@ -1,11 +1,11 @@
 <mk-slideshow-home-widget>
-	<div onclick={ choose }>
+	<div @click="choose">
 		<p if={ data.folder === undefined }>クリックしてフォルダを指定してください</p>
 		<p if={ data.folder !== undefined && images.length == 0 && !fetching }>このフォルダには画像がありません</p>
 		<div ref="slideA" class="slide a"></div>
 		<div ref="slideB" class="slide b"></div>
 	</div>
-	<button onclick={ resize }>%fa:expand%</button>
+	<button @click="resize">%fa:expand%</button>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/desktop/tags/home-widgets/trends.tag b/src/web/app/desktop/tags/home-widgets/trends.tag
index 3a2304111b..637f53a606 100644
--- a/src/web/app/desktop/tags/home-widgets/trends.tag
+++ b/src/web/app/desktop/tags/home-widgets/trends.tag
@@ -1,7 +1,7 @@
 <mk-trends-home-widget>
 	<virtual if={ !data.compact }>
 		<p class="title">%fa:fire%%i18n:desktop.tags.mk-trends-home-widget.title%</p>
-		<button onclick={ fetch } title="%i18n:desktop.tags.mk-trends-home-widget.refresh%">%fa:sync%</button>
+		<button @click="fetch" title="%i18n:desktop.tags.mk-trends-home-widget.refresh%">%fa:sync%</button>
 	</virtual>
 	<div class="post" if={ !loading && post != null }>
 		<p class="text"><a href="/{ post.user.username }/{ post.id }">{ post.text }</a></p>
diff --git a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
index a1af7a5c49..881373f8d0 100644
--- a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
+++ b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
@@ -1,7 +1,7 @@
 <mk-user-recommendation-home-widget>
 	<virtual if={ !data.compact }>
 		<p class="title">%fa:users%%i18n:desktop.tags.mk-user-recommendation-home-widget.title%</p>
-		<button onclick={ refresh } title="%i18n:desktop.tags.mk-user-recommendation-home-widget.refresh%">%fa:sync%</button>
+		<button @click="refresh" title="%i18n:desktop.tags.mk-user-recommendation-home-widget.refresh%">%fa:sync%</button>
 	</virtual>
 	<div class="user" if={ !loading && users.length != 0 } each={ _user in users }>
 		<a class="avatar-anchor" href={ '/' + _user.username }>
diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag
index 50f6c84604..90486f7d2b 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -27,7 +27,7 @@
 					<option value="nav">ナビゲーション</option>
 					<option value="tips">ヒント</option>
 				</select>
-				<button onclick={ addWidget }>追加</button>
+				<button @click="addWidget">追加</button>
 			</div>
 			<div class="trash">
 				<div ref="trash"></div>
diff --git a/src/web/app/desktop/tags/images.tag b/src/web/app/desktop/tags/images.tag
index 0cd408576f..1c81af3d08 100644
--- a/src/web/app/desktop/tags/images.tag
+++ b/src/web/app/desktop/tags/images.tag
@@ -58,7 +58,7 @@
 		onmousemove={ mousemove }
 		onmouseleave={ mouseleave }
 		style={ styles }
-		onclick={ click }
+		@click="click"
 		title={ image.name }></a>
 	<style>
 		:scope
@@ -110,7 +110,7 @@
 </mk-images-image>
 
 <mk-image-dialog>
-	<div class="bg" ref="bg" onclick={ close }></div><img ref="img" src={ image.url } alt={ image.name } title={ image.name } onclick={ close }/>
+	<div class="bg" ref="bg" @click="close"></div><img ref="img" src={ image.url } alt={ image.name } title={ image.name } @click="close"/>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/desktop/tags/input-dialog.tag b/src/web/app/desktop/tags/input-dialog.tag
index f175277547..84dcedf935 100644
--- a/src/web/app/desktop/tags/input-dialog.tag
+++ b/src/web/app/desktop/tags/input-dialog.tag
@@ -8,8 +8,8 @@
 				<input ref="text" type={ parent.type } oninput={ parent.onInput } onkeydown={ parent.onKeydown } placeholder={ parent.placeholder }/>
 			</div>
 			<div class="action">
-				<button class="cancel" onclick={ parent.cancel }>キャンセル</button>
-				<button class="ok" disabled={ !parent.allowEmpty && refs.text.value.length == 0 } onclick={ parent.ok }>決定</button>
+				<button class="cancel" @click="parent.cancel">キャンセル</button>
+				<button class="ok" disabled={ !parent.allowEmpty && refs.text.value.length == 0 } @click="parent.ok">決定</button>
 			</div>
 		</yield>
 	</mk-window>
diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag
index 39862487e9..91876c24f3 100644
--- a/src/web/app/desktop/tags/notifications.tag
+++ b/src/web/app/desktop/tags/notifications.tag
@@ -78,7 +78,7 @@
 			</p>
 		</virtual>
 	</div>
-	<button class="more { fetching: fetchingMoreNotifications }" if={ moreNotifications } onclick={ fetchMoreNotifications } disabled={ fetchingMoreNotifications }>
+	<button class="more { fetching: fetchingMoreNotifications }" if={ moreNotifications } @click="fetchMoreNotifications" disabled={ fetchingMoreNotifications }>
 		<virtual if={ fetchingMoreNotifications }>%fa:spinner .pulse .fw%</virtual>{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:desktop.tags.mk-notifications.more%' }
 	</button>
 	<p class="empty" if={ notifications.length == 0 && !loading }>ありません!</p>
diff --git a/src/web/app/desktop/tags/pages/entrance.tag b/src/web/app/desktop/tags/pages/entrance.tag
index 974f49a4fe..d3807a1e7f 100644
--- a/src/web/app/desktop/tags/pages/entrance.tag
+++ b/src/web/app/desktop/tags/pages/entrance.tag
@@ -10,7 +10,7 @@
 			<mk-entrance-signup if={ mode == 'signup' }/>
 			<div class="introduction" if={ mode == 'introduction' }>
 				<mk-introduction/>
-				<button onclick={ signin }>わかった</button>
+				<button @click="signin">わかった</button>
 			</div>
 		</div>
 	</main>
@@ -159,7 +159,7 @@
 	</div>
 	<a href={ _API_URL_ + '/signin/twitter' }>Twitterでサインイン</a>
 	<div class="divider"><span>or</span></div>
-	<button class="signup" onclick={ parent.signup }>新規登録</button><a class="introduction" onclick={ introduction }>Misskeyについて</a>
+	<button class="signup" @click="parent.signup">新規登録</button><a class="introduction" @click="introduction">Misskeyについて</a>
 	<style>
 		:scope
 			display block
@@ -295,7 +295,7 @@
 
 <mk-entrance-signup>
 	<mk-signup/>
-	<button class="cancel" type="button" onclick={ parent.signin } title="キャンセル">%fa:times%</button>
+	<button class="cancel" type="button" @click="parent.signin" title="キャンセル">%fa:times%</button>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/desktop/tags/pages/selectdrive.tag b/src/web/app/desktop/tags/pages/selectdrive.tag
index 123977e905..993df680f5 100644
--- a/src/web/app/desktop/tags/pages/selectdrive.tag
+++ b/src/web/app/desktop/tags/pages/selectdrive.tag
@@ -1,9 +1,9 @@
 <mk-selectdrive-page>
 	<mk-drive-browser ref="browser" multiple={ multiple }/>
 	<div>
-		<button class="upload" title="%i18n:desktop.tags.mk-selectdrive-page.upload%" onclick={ upload }>%fa:upload%</button>
-		<button class="cancel" onclick={ close }>%i18n:desktop.tags.mk-selectdrive-page.cancel%</button>
-		<button class="ok" onclick={ ok }>%i18n:desktop.tags.mk-selectdrive-page.ok%</button>
+		<button class="upload" title="%i18n:desktop.tags.mk-selectdrive-page.upload%" @click="upload">%fa:upload%</button>
+		<button class="cancel" @click="close">%i18n:desktop.tags.mk-selectdrive-page.cancel%</button>
+		<button class="ok" @click="ok">%i18n:desktop.tags.mk-selectdrive-page.ok%</button>
 	</div>
 
 	<style>
diff --git a/src/web/app/desktop/tags/post-detail.tag b/src/web/app/desktop/tags/post-detail.tag
index 47c71a6c12..6177f24eee 100644
--- a/src/web/app/desktop/tags/post-detail.tag
+++ b/src/web/app/desktop/tags/post-detail.tag
@@ -1,6 +1,6 @@
 <mk-post-detail title={ title }>
 	<div class="main">
-		<button class="read-more" if={ p.reply && p.reply.reply_id && context == null } title="会話をもっと読み込む" onclick={ loadContext } disabled={ contextFetching }>
+		<button class="read-more" if={ p.reply && p.reply.reply_id && context == null } title="会話をもっと読み込む" @click="loadContext" disabled={ contextFetching }>
 			<virtual if={ !contextFetching }>%fa:ellipsis-v%</virtual>
 			<virtual if={ contextFetching }>%fa:spinner .pulse%</virtual>
 		</button>
@@ -43,16 +43,16 @@
 			</div>
 			<footer>
 				<mk-reactions-viewer post={ p }/>
-				<button onclick={ reply } title="返信">
+				<button @click="reply" title="返信">
 					%fa:reply%<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p>
 				</button>
-				<button onclick={ repost } title="Repost">
+				<button @click="repost" title="Repost">
 					%fa:retweet%<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p>
 				</button>
-				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="リアクション">
+				<button class={ reacted: p.my_reaction != null } @click="react" ref="reactButton" title="リアクション">
 					%fa:plus%<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p>
 				</button>
-				<button onclick={ menu } ref="menuButton">
+				<button @click="menu" ref="menuButton">
 					%fa:ellipsis-h%
 				</button>
 			</footer>
diff --git a/src/web/app/desktop/tags/post-form.tag b/src/web/app/desktop/tags/post-form.tag
index 0b4c07906a..23434a8241 100644
--- a/src/web/app/desktop/tags/post-form.tag
+++ b/src/web/app/desktop/tags/post-form.tag
@@ -5,7 +5,7 @@
 			<ul ref="media">
 				<li each={ files } data-id={ id }>
 					<div class="img" style="background-image: url({ url + '?thumbnail&size=64' })" title={ name }></div>
-					<img class="remove" onclick={ removeFile } src="/assets/desktop/remove.png" title="%i18n:desktop.tags.mk-post-form.attach-cancel%" alt=""/>
+					<img class="remove" @click="removeFile" src="/assets/desktop/remove.png" title="%i18n:desktop.tags.mk-post-form.attach-cancel%" alt=""/>
 				</li>
 			</ul>
 			<p class="remain">{ 4 - files.length }/4</p>
@@ -13,12 +13,12 @@
 		<mk-poll-editor if={ poll } ref="poll" ondestroy={ onPollDestroyed }/>
 	</div>
 	<mk-uploader ref="uploader"/>
-	<button ref="upload" title="%i18n:desktop.tags.mk-post-form.attach-media-from-local%" onclick={ selectFile }>%fa:upload%</button>
-	<button ref="drive" title="%i18n:desktop.tags.mk-post-form.attach-media-from-drive%" onclick={ selectFileFromDrive }>%fa:cloud%</button>
-	<button class="kao" title="%i18n:desktop.tags.mk-post-form.insert-a-kao%" onclick={ kao }>%fa:R smile%</button>
-	<button class="poll" title="%i18n:desktop.tags.mk-post-form.create-poll%" onclick={ addPoll }>%fa:chart-pie%</button>
+	<button ref="upload" title="%i18n:desktop.tags.mk-post-form.attach-media-from-local%" @click="selectFile">%fa:upload%</button>
+	<button ref="drive" title="%i18n:desktop.tags.mk-post-form.attach-media-from-drive%" @click="selectFileFromDrive">%fa:cloud%</button>
+	<button class="kao" title="%i18n:desktop.tags.mk-post-form.insert-a-kao%" @click="kao">%fa:R smile%</button>
+	<button class="poll" title="%i18n:desktop.tags.mk-post-form.create-poll%" @click="addPoll">%fa:chart-pie%</button>
 	<p class="text-count { over: refs.text.value.length > 1000 }">{ '%i18n:desktop.tags.mk-post-form.text-remain%'.replace('{}', 1000 - refs.text.value.length) }</p>
-	<button class={ wait: wait } ref="submit" disabled={ wait || (refs.text.value.length == 0 && files.length == 0 && !poll && !repost) } onclick={ post }>
+	<button class={ wait: wait } ref="submit" disabled={ wait || (refs.text.value.length == 0 && files.length == 0 && !poll && !repost) } @click="post">
 		{ wait ? '%i18n:desktop.tags.mk-post-form.posting%' : submitText }<mk-ellipsis if={ wait }/>
 	</button>
 	<input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" onchange={ changeFile }/>
diff --git a/src/web/app/desktop/tags/repost-form.tag b/src/web/app/desktop/tags/repost-form.tag
index c3cf6c1fb3..946871765b 100644
--- a/src/web/app/desktop/tags/repost-form.tag
+++ b/src/web/app/desktop/tags/repost-form.tag
@@ -2,9 +2,9 @@
 	<mk-post-preview post={ opts.post }/>
 	<virtual if={ !quote }>
 		<footer>
-			<a class="quote" if={ !quote } onclick={ onquote }>%i18n:desktop.tags.mk-repost-form.quote%</a>
-			<button class="cancel" onclick={ cancel }>%i18n:desktop.tags.mk-repost-form.cancel%</button>
-			<button class="ok" onclick={ ok } disabled={ wait }>{ wait ? '%i18n:desktop.tags.mk-repost-form.reposting%' : '%i18n:desktop.tags.mk-repost-form.repost%' }</button>
+			<a class="quote" if={ !quote } @click="onquote">%i18n:desktop.tags.mk-repost-form.quote%</a>
+			<button class="cancel" @click="cancel">%i18n:desktop.tags.mk-repost-form.cancel%</button>
+			<button class="ok" @click="ok" disabled={ wait }>{ wait ? '%i18n:desktop.tags.mk-repost-form.reposting%' : '%i18n:desktop.tags.mk-repost-form.repost%' }</button>
 		</footer>
 	</virtual>
 	<virtual if={ quote }>
diff --git a/src/web/app/desktop/tags/select-file-from-drive-window.tag b/src/web/app/desktop/tags/select-file-from-drive-window.tag
index c660a2fe90..6225145589 100644
--- a/src/web/app/desktop/tags/select-file-from-drive-window.tag
+++ b/src/web/app/desktop/tags/select-file-from-drive-window.tag
@@ -7,9 +7,9 @@
 		<yield to="content">
 			<mk-drive-browser ref="browser" multiple={ parent.multiple }/>
 			<div>
-				<button class="upload" title="PCからドライブにファイルをアップロード" onclick={ parent.upload }>%fa:upload%</button>
-				<button class="cancel" onclick={ parent.close }>キャンセル</button>
-				<button class="ok" disabled={ parent.multiple && parent.files.length == 0 } onclick={ parent.ok }>決定</button>
+				<button class="upload" title="PCからドライブにファイルをアップロード" @click="parent.upload">%fa:upload%</button>
+				<button class="cancel" @click="parent.close">キャンセル</button>
+				<button class="ok" disabled={ parent.multiple && parent.files.length == 0 } @click="parent.ok">決定</button>
 			</div>
 		</yield>
 	</mk-window>
diff --git a/src/web/app/desktop/tags/select-folder-from-drive-window.tag b/src/web/app/desktop/tags/select-folder-from-drive-window.tag
index 3c66a4e6da..45700420cc 100644
--- a/src/web/app/desktop/tags/select-folder-from-drive-window.tag
+++ b/src/web/app/desktop/tags/select-folder-from-drive-window.tag
@@ -6,8 +6,8 @@
 		<yield to="content">
 			<mk-drive-browser ref="browser"/>
 			<div>
-				<button class="cancel" onclick={ parent.close }>キャンセル</button>
-				<button class="ok" onclick={ parent.ok }>決定</button>
+				<button class="cancel" @click="parent.close">キャンセル</button>
+				<button class="ok" @click="parent.ok">決定</button>
 			</div>
 		</yield>
 	</mk-window>
diff --git a/src/web/app/desktop/tags/set-avatar-suggestion.tag b/src/web/app/desktop/tags/set-avatar-suggestion.tag
index 7e871129fc..faf4cdd8a4 100644
--- a/src/web/app/desktop/tags/set-avatar-suggestion.tag
+++ b/src/web/app/desktop/tags/set-avatar-suggestion.tag
@@ -1,6 +1,6 @@
-<mk-set-avatar-suggestion onclick={ set }>
+<mk-set-avatar-suggestion @click="set">
 	<p><b>アバターを設定</b>してみませんか?
-		<button onclick={ close }>%fa:times%</button>
+		<button @click="close">%fa:times%</button>
 	</p>
 	<style>
 		:scope
diff --git a/src/web/app/desktop/tags/set-banner-suggestion.tag b/src/web/app/desktop/tags/set-banner-suggestion.tag
index 4cd364ca3e..cbf0f1b68f 100644
--- a/src/web/app/desktop/tags/set-banner-suggestion.tag
+++ b/src/web/app/desktop/tags/set-banner-suggestion.tag
@@ -1,6 +1,6 @@
-<mk-set-banner-suggestion onclick={ set }>
+<mk-set-banner-suggestion @click="set">
 	<p><b>バナーを設定</b>してみませんか?
-		<button onclick={ close }>%fa:times%</button>
+		<button @click="close">%fa:times%</button>
 	</p>
 	<style>
 		:scope
diff --git a/src/web/app/desktop/tags/settings.tag b/src/web/app/desktop/tags/settings.tag
index 457b7e2276..efc5da83f1 100644
--- a/src/web/app/desktop/tags/settings.tag
+++ b/src/web/app/desktop/tags/settings.tag
@@ -131,7 +131,7 @@
 <mk-profile-setting>
 	<label class="avatar ui from group">
 		<p>%i18n:desktop.tags.mk-profile-setting.avatar%</p><img class="avatar" src={ I.avatar_url + '?thumbnail&size=64' } alt="avatar"/>
-		<button class="ui" onclick={ avatar }>%i18n:desktop.tags.mk-profile-setting.choice-avatar%</button>
+		<button class="ui" @click="avatar">%i18n:desktop.tags.mk-profile-setting.choice-avatar%</button>
 	</label>
 	<label class="ui from group">
 		<p>%i18n:desktop.tags.mk-profile-setting.name%</p>
@@ -149,7 +149,7 @@
 		<p>%i18n:desktop.tags.mk-profile-setting.birthday%</p>
 		<input ref="accountBirthday" type="date" value={ I.profile.birthday } class="ui"/>
 	</label>
-	<button class="ui primary" onclick={ updateAccount }>%i18n:desktop.tags.mk-profile-setting.save%</button>
+	<button class="ui primary" @click="updateAccount">%i18n:desktop.tags.mk-profile-setting.save%</button>
 	<style>
 		:scope
 			display block
@@ -195,7 +195,7 @@
 	<p>%i18n:desktop.tags.mk-api-info.intro%</p>
 	<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:desktop.tags.mk-api-info.caution%</p></div>
 	<p>%i18n:desktop.tags.mk-api-info.regeneration-of-token%</p>
-	<button class="ui" onclick={ regenerateToken }>%i18n:desktop.tags.mk-api-info.regenerate-token%</button>
+	<button class="ui" @click="regenerateToken">%i18n:desktop.tags.mk-api-info.regenerate-token%</button>
 	<style>
 		:scope
 			display block
@@ -225,7 +225,7 @@
 </mk-api-info>
 
 <mk-password-setting>
-	<button onclick={ reset } class="ui primary">%i18n:desktop.tags.mk-password-setting.reset%</button>
+	<button @click="reset" class="ui primary">%i18n:desktop.tags.mk-password-setting.reset%</button>
 	<style>
 		:scope
 			display block
@@ -265,10 +265,10 @@
 <mk-2fa-setting>
 	<p>%i18n:desktop.tags.mk-2fa-setting.intro%<a href="%i18n:desktop.tags.mk-2fa-setting.url%" target="_blank">%i18n:desktop.tags.mk-2fa-setting.detail%</a></p>
 	<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:desktop.tags.mk-2fa-setting.caution%</p></div>
-	<p if={ !data && !I.two_factor_enabled }><button onclick={ register } class="ui primary">%i18n:desktop.tags.mk-2fa-setting.register%</button></p>
+	<p if={ !data && !I.two_factor_enabled }><button @click="register" class="ui primary">%i18n:desktop.tags.mk-2fa-setting.register%</button></p>
 	<virtual if={ I.two_factor_enabled }>
 		<p>%i18n:desktop.tags.mk-2fa-setting.already-registered%</p>
-		<button onclick={ unregister } class="ui">%i18n:desktop.tags.mk-2fa-setting.unregister%</button>
+		<button @click="unregister" class="ui">%i18n:desktop.tags.mk-2fa-setting.unregister%</button>
 	</virtual>
 	<div if={ data }>
 		<ol>
@@ -276,7 +276,7 @@
 			<li>%i18n:desktop.tags.mk-2fa-setting.scan%<br><img src={ data.qr }></li>
 			<li>%i18n:desktop.tags.mk-2fa-setting.done%<br>
 				<input type="number" ref="token" class="ui">
-				<button onclick={ submit } class="ui primary">%i18n:desktop.tags.mk-2fa-setting.submit%</button>
+				<button @click="submit" class="ui primary">%i18n:desktop.tags.mk-2fa-setting.submit%</button>
 			</li>
 		</ol>
 		<div class="ui info"><p>%fa:info-circle%%i18n:desktop.tags.mk-2fa-setting.info%</p></div>
diff --git a/src/web/app/desktop/tags/timeline.tag b/src/web/app/desktop/tags/timeline.tag
index ed77a9e608..0616a95f99 100644
--- a/src/web/app/desktop/tags/timeline.tag
+++ b/src/web/app/desktop/tags/timeline.tag
@@ -129,19 +129,19 @@
 			</div>
 			<footer>
 				<mk-reactions-viewer post={ p } ref="reactionsViewer"/>
-				<button onclick={ reply } title="%i18n:desktop.tags.mk-timeline-post.reply%">
+				<button @click="reply" title="%i18n:desktop.tags.mk-timeline-post.reply%">
 					%fa:reply%<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p>
 				</button>
-				<button onclick={ repost } title="%i18n:desktop.tags.mk-timeline-post.repost%">
+				<button @click="repost" title="%i18n:desktop.tags.mk-timeline-post.repost%">
 					%fa:retweet%<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p>
 				</button>
-				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%">
+				<button class={ reacted: p.my_reaction != null } @click="react" ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%">
 					%fa:plus%<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p>
 				</button>
-				<button onclick={ menu } ref="menuButton">
+				<button @click="menu" ref="menuButton">
 					%fa:ellipsis-h%
 				</button>
-				<button onclick={ toggleDetail } title="%i18n:desktop.tags.mk-timeline-post.detail">
+				<button @click="toggleDetail" title="%i18n:desktop.tags.mk-timeline-post.detail">
 					<virtual if={ !isDetailOpened }>%fa:caret-down%</virtual>
 					<virtual if={ isDetailOpened }>%fa:caret-up%</virtual>
 				</button>
diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag
index 3dfdeec01c..3e7b5c2eca 100644
--- a/src/web/app/desktop/tags/ui.tag
+++ b/src/web/app/desktop/tags/ui.tag
@@ -186,7 +186,7 @@
 </mk-ui-header-search>
 
 <mk-ui-header-post-button>
-	<button onclick={ post } title="%i18n:desktop.tags.mk-ui-header-post-button.post%">%fa:pencil-alt%</button>
+	<button @click="post" title="%i18n:desktop.tags.mk-ui-header-post-button.post%">%fa:pencil-alt%</button>
 	<style>
 		:scope
 			display inline-block
@@ -229,7 +229,7 @@
 </mk-ui-header-post-button>
 
 <mk-ui-header-notifications>
-	<button data-active={ isOpen } onclick={ toggle } title="%i18n:desktop.tags.mk-ui-header-notifications.title%">
+	<button data-active={ isOpen } @click="toggle" title="%i18n:desktop.tags.mk-ui-header-notifications.title%">
 		%fa:R bell%<virtual if={ hasUnreadNotifications }>%fa:circle%</virtual>
 	</button>
 	<div class="notifications" if={ isOpen }>
@@ -400,7 +400,7 @@
 				</a>
 			</li>
 			<li class="messaging">
-				<a onclick={ messaging }>
+				<a @click="messaging">
 					%fa:comments%
 					<p>%i18n:desktop.tags.mk-ui-header-nav.messaging%</p>
 					<virtual if={ hasUnreadMessagingMessages }>%fa:circle%</virtual>
@@ -629,7 +629,7 @@
 </mk-ui-header-clock>
 
 <mk-ui-header-account>
-	<button class="header" data-active={ isOpen.toString() } onclick={ toggle }>
+	<button class="header" data-active={ isOpen.toString() } @click="toggle">
 		<span class="username">{ I.username }<virtual if={ !isOpen }>%fa:angle-down%</virtual><virtual if={ isOpen }>%fa:angle-up%</virtual></span>
 		<img class="avatar" src={ I.avatar_url + '?thumbnail&size=64' } alt="avatar"/>
 	</button>
@@ -638,7 +638,7 @@
 			<li>
 				<a href={ '/' + I.username }>%fa:user%%i18n:desktop.tags.mk-ui-header-account.profile%%fa:angle-right%</a>
 			</li>
-			<li onclick={ drive }>
+			<li @click="drive">
 				<p>%fa:cloud%%i18n:desktop.tags.mk-ui-header-account.drive%%fa:angle-right%</p>
 			</li>
 			<li>
@@ -646,12 +646,12 @@
 			</li>
 		</ul>
 		<ul>
-			<li onclick={ settings }>
+			<li @click="settings">
 				<p>%fa:cog%%i18n:desktop.tags.mk-ui-header-account.settings%%fa:angle-right%</p>
 			</li>
 		</ul>
 		<ul>
-			<li onclick={ signout }>
+			<li @click="signout">
 				<p>%fa:power-off%%i18n:desktop.tags.mk-ui-header-account.signout%%fa:angle-right%</p>
 			</li>
 		</ul>
diff --git a/src/web/app/desktop/tags/user-timeline.tag b/src/web/app/desktop/tags/user-timeline.tag
index 134aeee28c..19ee2f3284 100644
--- a/src/web/app/desktop/tags/user-timeline.tag
+++ b/src/web/app/desktop/tags/user-timeline.tag
@@ -1,6 +1,6 @@
 <mk-user-timeline>
 	<header>
-		<span data-is-active={ mode == 'default' } onclick={ setMode.bind(this, 'default') }>投稿</span><span data-is-active={ mode == 'with-replies' } onclick={ setMode.bind(this, 'with-replies') }>投稿と返信</span>
+		<span data-is-active={ mode == 'default' } @click="setMode.bind(this, 'default')">投稿</span><span data-is-active={ mode == 'with-replies' } @click="setMode.bind(this, 'with-replies')">投稿と返信</span>
 	</header>
 	<div class="loading" if={ isLoading }>
 		<mk-ellipsis-icon/>
diff --git a/src/web/app/desktop/tags/user.tag b/src/web/app/desktop/tags/user.tag
index b29d1eaebc..5dc4175cf9 100644
--- a/src/web/app/desktop/tags/user.tag
+++ b/src/web/app/desktop/tags/user.tag
@@ -40,7 +40,7 @@
 
 <mk-user-header data-is-dark-background={ user.banner_url != null }>
 	<div class="banner-container" style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=2048)' : '' }>
-		<div class="banner" ref="banner" style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=2048)' : '' } onclick={ onUpdateBanner }></div>
+		<div class="banner" ref="banner" style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=2048)' : '' } @click="onUpdateBanner"></div>
 	</div>
 	<div class="fade"></div>
 	<div class="container">
@@ -227,8 +227,8 @@
 	<div class="friend-form" if={ SIGNIN && I.id != user.id }>
 		<mk-big-follow-button user={ user }/>
 		<p class="followed" if={ user.is_followed }>%i18n:desktop.tags.mk-user.follows-you%</p>
-		<p if={ user.is_muted }>%i18n:desktop.tags.mk-user.muted% <a onclick={ unmute }>%i18n:desktop.tags.mk-user.unmute%</a></p>
-		<p if={ !user.is_muted }><a onclick={ mute }>%i18n:desktop.tags.mk-user.mute%</a></p>
+		<p if={ user.is_muted }>%i18n:desktop.tags.mk-user.muted% <a @click="unmute">%i18n:desktop.tags.mk-user.unmute%</a></p>
+		<p if={ !user.is_muted }><a @click="mute">%i18n:desktop.tags.mk-user.mute%</a></p>
 	</div>
 	<div class="description" if={ user.description }>{ user.description }</div>
 	<div class="birthday" if={ user.profile.birthday }>
@@ -239,8 +239,8 @@
 	</div>
 	<div class="status">
 	  <p class="posts-count">%fa:angle-right%<a>{ user.posts_count }</a><b>ポスト</b></p>
-		<p class="following">%fa:angle-right%<a onclick={ showFollowing }>{ user.following_count }</a>人を<b>フォロー</b></p>
-		<p class="followers">%fa:angle-right%<a onclick={ showFollowers }>{ user.followers_count }</a>人の<b>フォロワー</b></p>
+		<p class="following">%fa:angle-right%<a @click="showFollowing">{ user.following_count }</a>人を<b>フォロー</b></p>
+		<p class="followers">%fa:angle-right%<a @click="showFollowers">{ user.followers_count }</a>人の<b>フォロワー</b></p>
 	</div>
 	<style>
 		:scope
diff --git a/src/web/app/desktop/tags/users-list.tag b/src/web/app/desktop/tags/users-list.tag
index ec9c7d8c7b..3e993a40ec 100644
--- a/src/web/app/desktop/tags/users-list.tag
+++ b/src/web/app/desktop/tags/users-list.tag
@@ -1,8 +1,8 @@
 <mk-users-list>
 	<nav>
 		<div>
-			<span data-is-active={ mode == 'all' } onclick={ setMode.bind(this, 'all') }>すべて<span>{ opts.count }</span></span>
-			<span if={ SIGNIN && opts.youKnowCount } data-is-active={ mode == 'iknow' } onclick={ setMode.bind(this, 'iknow') }>知り合い<span>{ opts.youKnowCount }</span></span>
+			<span data-is-active={ mode == 'all' } @click="setMode.bind(this, 'all')">すべて<span>{ opts.count }</span></span>
+			<span if={ SIGNIN && opts.youKnowCount } data-is-active={ mode == 'iknow' } @click="setMode.bind(this, 'iknow')">知り合い<span>{ opts.youKnowCount }</span></span>
 		</div>
 	</nav>
 	<div class="users" if={ !fetching && users.length != 0 }>
@@ -10,7 +10,7 @@
 			<mk-list-user user={ this }/>
 		</div>
 	</div>
-	<button class="more" if={ !fetching && next != null } onclick={ more } disabled={ moreFetching }>
+	<button class="more" if={ !fetching && next != null } @click="more" disabled={ moreFetching }>
 		<span if={ !moreFetching }>もっと</span>
 		<span if={ moreFetching }>読み込み中<mk-ellipsis/></span>
 	</button>
diff --git a/src/web/app/desktop/tags/widgets/activity.tag b/src/web/app/desktop/tags/widgets/activity.tag
index e8c8a47632..9b547b95f3 100644
--- a/src/web/app/desktop/tags/widgets/activity.tag
+++ b/src/web/app/desktop/tags/widgets/activity.tag
@@ -1,7 +1,7 @@
 <mk-activity-widget data-melt={ design == 2 }>
 	<virtual if={ design == 0 }>
 		<p class="title">%fa:chart-bar%%i18n:desktop.tags.mk-activity-widget.title%</p>
-		<button onclick={ toggle } title="%i18n:desktop.tags.mk-activity-widget.toggle%">%fa:sort%</button>
+		<button @click="toggle" title="%i18n:desktop.tags.mk-activity-widget.toggle%">%fa:sort%</button>
 	</virtual>
 	<p class="initializing" if={ initializing }>%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
 	<mk-activity-widget-calender if={ !initializing && view == 0 } data={ [].concat(activity) }/>
diff --git a/src/web/app/desktop/tags/widgets/calendar.tag b/src/web/app/desktop/tags/widgets/calendar.tag
index abe9981873..00205a90a4 100644
--- a/src/web/app/desktop/tags/widgets/calendar.tag
+++ b/src/web/app/desktop/tags/widgets/calendar.tag
@@ -1,8 +1,8 @@
 <mk-calendar-widget data-melt={ opts.design == 4 || opts.design == 5 }>
 	<virtual if={ opts.design == 0 || opts.design == 1 }>
-		<button onclick={ prev } title="%i18n:desktop.tags.mk-calendar-widget.prev%">%fa:chevron-circle-left%</button>
+		<button @click="prev" title="%i18n:desktop.tags.mk-calendar-widget.prev%">%fa:chevron-circle-left%</button>
 		<p class="title">{ '%i18n:desktop.tags.mk-calendar-widget.title%'.replace('{1}', year).replace('{2}', month) }</p>
-		<button onclick={ next } title="%i18n:desktop.tags.mk-calendar-widget.next%">%fa:chevron-circle-right%</button>
+		<button @click="next" title="%i18n:desktop.tags.mk-calendar-widget.next%">%fa:chevron-circle-right%</button>
 	</virtual>
 
 	<div class="calendar">
@@ -15,7 +15,7 @@
 				data-selected={ isSelected(i + 1) }
 				data-is-out-of-range={ isOutOfRange(i + 1) }
 				data-is-donichi={ isDonichi(i + 1) }
-				onclick={ go.bind(null, i + 1) }
+				@click="go.bind(null, i + 1)"
 				title={ isOutOfRange(i + 1) ? null : '%i18n:desktop.tags.mk-calendar-widget.go%' }><div>{ i + 1 }</div></div>
 	</div>
 	<style>
diff --git a/src/web/app/desktop/tags/window.tag b/src/web/app/desktop/tags/window.tag
index 5b4b3c83e4..ebc7382d5a 100644
--- a/src/web/app/desktop/tags/window.tag
+++ b/src/web/app/desktop/tags/window.tag
@@ -1,12 +1,12 @@
 <mk-window data-flexible={ isFlexible } ondragover={ ondragover }>
-	<div class="bg" ref="bg" show={ isModal } onclick={ bgClick }></div>
+	<div class="bg" ref="bg" show={ isModal } @click="bgClick"></div>
 	<div class="main" ref="main" tabindex="-1" data-is-modal={ isModal } onmousedown={ onBodyMousedown } onkeydown={ onKeydown }>
 		<div class="body">
 			<header ref="header" onmousedown={ onHeaderMousedown }>
 				<h1 data-yield="header"><yield from="header"/></h1>
 				<div>
-					<button class="popout" if={ popoutUrl } onmousedown={ repelMove } onclick={ popout } title="ポップアウト">%fa:R window-restore%</button>
-					<button class="close" if={ canClose } onmousedown={ repelMove } onclick={ close } title="閉じる">%fa:times%</button>
+					<button class="popout" if={ popoutUrl } onmousedown={ repelMove } @click="popout" title="ポップアウト">%fa:R window-restore%</button>
+					<button class="close" if={ canClose } onmousedown={ repelMove } @click="close" title="閉じる">%fa:times%</button>
 				</div>
 			</header>
 			<div class="content" data-yield="content"><yield from="content"/></div>
diff --git a/src/web/app/dev/tags/new-app-form.tag b/src/web/app/dev/tags/new-app-form.tag
index fdd442a836..c9518d8deb 100644
--- a/src/web/app/dev/tags/new-app-form.tag
+++ b/src/web/app/dev/tags/new-app-form.tag
@@ -73,7 +73,7 @@
 			</div>
 			<p>%fa:exclamation-triangle%アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。</p>
 		</section>
-		<button onclick={ onsubmit }>アプリ作成</button>
+		<button @click="onsubmit">アプリ作成</button>
 	</form>
 	<style>
 		:scope
diff --git a/src/web/app/mobile/tags/drive-folder-selector.tag b/src/web/app/mobile/tags/drive-folder-selector.tag
index 35d0208a07..82e22fed29 100644
--- a/src/web/app/mobile/tags/drive-folder-selector.tag
+++ b/src/web/app/mobile/tags/drive-folder-selector.tag
@@ -2,8 +2,8 @@
 	<div class="body">
 		<header>
 			<h1>%i18n:mobile.tags.mk-drive-folder-selector.select-folder%</h1>
-			<button class="close" onclick={ cancel }>%fa:times%</button>
-			<button class="ok" onclick={ ok }>%fa:check%</button>
+			<button class="close" @click="cancel">%fa:times%</button>
+			<button class="ok" @click="ok">%fa:check%</button>
 		</header>
 		<mk-drive ref="browser" select-folder={ true }/>
 	</div>
diff --git a/src/web/app/mobile/tags/drive-selector.tag b/src/web/app/mobile/tags/drive-selector.tag
index f8bc49dab0..36fed8c327 100644
--- a/src/web/app/mobile/tags/drive-selector.tag
+++ b/src/web/app/mobile/tags/drive-selector.tag
@@ -2,8 +2,8 @@
 	<div class="body">
 		<header>
 			<h1>%i18n:mobile.tags.mk-drive-selector.select-file%<span class="count" if={ files.length > 0 }>({ files.length })</span></h1>
-			<button class="close" onclick={ cancel }>%fa:times%</button>
-			<button if={ opts.multiple } class="ok" onclick={ ok }>%fa:check%</button>
+			<button class="close" @click="cancel">%fa:times%</button>
+			<button if={ opts.multiple } class="ok" @click="ok">%fa:check%</button>
 		</header>
 		<mk-drive ref="browser" select-file={ true } multiple={ opts.multiple }/>
 	</div>
diff --git a/src/web/app/mobile/tags/drive.tag b/src/web/app/mobile/tags/drive.tag
index 2a3ff23bfa..d3ca1aff90 100644
--- a/src/web/app/mobile/tags/drive.tag
+++ b/src/web/app/mobile/tags/drive.tag
@@ -1,9 +1,9 @@
 <mk-drive>
 	<nav ref="nav">
-		<a onclick={ goRoot } href="/i/drive">%fa:cloud%%i18n:mobile.tags.mk-drive.drive%</a>
+		<a @click="goRoot" href="/i/drive">%fa:cloud%%i18n:mobile.tags.mk-drive.drive%</a>
 		<virtual each={ folder in hierarchyFolders }>
 			<span>%fa:angle-right%</span>
-			<a onclick={ move } href="/i/drive/folder/{ folder.id }">{ folder.name }</a>
+			<a @click="move" href="/i/drive/folder/{ folder.id }">{ folder.name }</a>
 		</virtual>
 		<virtual if={ folder != null }>
 			<span>%fa:angle-right%</span>
@@ -34,7 +34,7 @@
 			<virtual each={ file in files }>
 				<mk-drive-file file={ file }/>
 			</virtual>
-			<button class="more" if={ moreFiles } onclick={ fetchMoreFiles }>
+			<button class="more" if={ moreFiles } @click="fetchMoreFiles">
 				{ fetchingMoreFiles ? '%i18n:common.loading%' : '%i18n:mobile.tags.mk-drive.load-more%' }
 			</button>
 		</div>
diff --git a/src/web/app/mobile/tags/drive/file-viewer.tag b/src/web/app/mobile/tags/drive/file-viewer.tag
index 259873d95c..2d9338fd35 100644
--- a/src/web/app/mobile/tags/drive/file-viewer.tag
+++ b/src/web/app/mobile/tags/drive/file-viewer.tag
@@ -28,7 +28,7 @@
 			<span class="separator"></span>
 			<span class="data-size">{ bytesToSize(file.datasize) }</span>
 			<span class="separator"></span>
-			<span class="created-at" onclick={ showCreatedAt }>%fa:R clock%<mk-time time={ file.created_at }/></span>
+			<span class="created-at" @click="showCreatedAt">%fa:R clock%<mk-time time={ file.created_at }/></span>
 		</div>
 	</div>
 	<div class="menu">
@@ -36,10 +36,10 @@
 			<a href={ file.url + '?download' } download={ file.name }>
 				%fa:download%%i18n:mobile.tags.mk-drive-file-viewer.download%
 			</a>
-			<button onclick={ rename }>
+			<button @click="rename">
 				%fa:pencil-alt%%i18n:mobile.tags.mk-drive-file-viewer.rename%
 			</button>
-			<button onclick={ move }>
+			<button @click="move">
 				%fa:R folder-open%%i18n:mobile.tags.mk-drive-file-viewer.move%
 			</button>
 		</div>
diff --git a/src/web/app/mobile/tags/drive/file.tag b/src/web/app/mobile/tags/drive/file.tag
index 684df7dd08..a04528ce7e 100644
--- a/src/web/app/mobile/tags/drive/file.tag
+++ b/src/web/app/mobile/tags/drive/file.tag
@@ -1,5 +1,5 @@
 <mk-drive-file data-is-selected={ isSelected }>
-	<a onclick={ onclick } href="/i/drive/file/{ file.id }">
+	<a @click="onclick" href="/i/drive/file/{ file.id }">
 		<div class="container">
 			<div class="thumbnail" style={ thumbnail }></div>
 			<div class="body">
diff --git a/src/web/app/mobile/tags/drive/folder.tag b/src/web/app/mobile/tags/drive/folder.tag
index 6125e0b254..c0ccee6a55 100644
--- a/src/web/app/mobile/tags/drive/folder.tag
+++ b/src/web/app/mobile/tags/drive/folder.tag
@@ -1,5 +1,5 @@
 <mk-drive-folder>
-	<a onclick={ onclick } href="/i/drive/folder/{ folder.id }">
+	<a @click="onclick" href="/i/drive/folder/{ folder.id }">
 		<div class="container">
 			<p class="name">%fa:folder%{ folder.name }</p>%fa:angle-right%
 		</div>
diff --git a/src/web/app/mobile/tags/follow-button.tag b/src/web/app/mobile/tags/follow-button.tag
index 5b710bfa9d..805d5e6599 100644
--- a/src/web/app/mobile/tags/follow-button.tag
+++ b/src/web/app/mobile/tags/follow-button.tag
@@ -1,5 +1,5 @@
 <mk-follow-button>
-	<button class={ wait: wait, follow: !user.is_following, unfollow: user.is_following } if={ !init } onclick={ onclick } disabled={ wait }>
+	<button class={ wait: wait, follow: !user.is_following, unfollow: user.is_following } if={ !init } @click="onclick" disabled={ wait }>
 		<virtual if={ !wait && user.is_following }>%fa:minus%</virtual>
 		<virtual if={ !wait && !user.is_following }>%fa:plus%</virtual>
 		<virtual if={ wait }>%fa:spinner .pulse .fw%</virtual>{ user.is_following ? '%i18n:mobile.tags.mk-follow-button.unfollow%' : '%i18n:mobile.tags.mk-follow-button.follow%' }
diff --git a/src/web/app/mobile/tags/init-following.tag b/src/web/app/mobile/tags/init-following.tag
index 105a1f70d3..d2d19a8876 100644
--- a/src/web/app/mobile/tags/init-following.tag
+++ b/src/web/app/mobile/tags/init-following.tag
@@ -7,8 +7,8 @@
 	</div>
 	<p class="empty" if={ !fetching && users.length == 0 }>おすすめのユーザーは見つかりませんでした。</p>
 	<p class="fetching" if={ fetching }>%fa:spinner .pulse .fw%読み込んでいます<mk-ellipsis/></p>
-	<a class="refresh" onclick={ refresh }>もっと見る</a>
-	<button class="close" onclick={ close } title="閉じる">%fa:times%</button>
+	<a class="refresh" @click="refresh">もっと見る</a>
+	<button class="close" @click="close" title="閉じる">%fa:times%</button>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/mobile/tags/notifications.tag b/src/web/app/mobile/tags/notifications.tag
index 742cc45145..520a336b0a 100644
--- a/src/web/app/mobile/tags/notifications.tag
+++ b/src/web/app/mobile/tags/notifications.tag
@@ -5,7 +5,7 @@
 			<p class="date" if={ i != notifications.length - 1 && notification._date != notifications[i + 1]._date }><span>%fa:angle-up%{ notification._datetext }</span><span>%fa:angle-down%{ notifications[i + 1]._datetext }</span></p>
 		</virtual>
 	</div>
-	<button class="more" if={ moreNotifications } onclick={ fetchMoreNotifications } disabled={ fetchingMoreNotifications }>
+	<button class="more" if={ moreNotifications } @click="fetchMoreNotifications" disabled={ fetchingMoreNotifications }>
 		<virtual if={ fetchingMoreNotifications }>%fa:spinner .pulse .fw%</virtual>{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:mobile.tags.mk-notifications.more%' }
 	</button>
 	<p class="empty" if={ notifications.length == 0 && !loading }>%i18n:mobile.tags.mk-notifications.empty%</p>
diff --git a/src/web/app/mobile/tags/page/entrance.tag b/src/web/app/mobile/tags/page/entrance.tag
index 191874caf9..b5da3c947b 100644
--- a/src/web/app/mobile/tags/page/entrance.tag
+++ b/src/web/app/mobile/tags/page/entrance.tag
@@ -4,7 +4,7 @@
 		<mk-entrance-signup if={ mode == 'signup' }/>
 		<div class="introduction" if={ mode == 'introduction' }>
 			<mk-introduction/>
-			<button onclick={ signin }>%i18n:common.ok%</button>
+			<button @click="signin">%i18n:common.ok%</button>
 		</div>
 	</main>
 	<footer>
diff --git a/src/web/app/mobile/tags/page/entrance/signin.tag b/src/web/app/mobile/tags/page/entrance/signin.tag
index 6f473feb9d..81d0a48a7b 100644
--- a/src/web/app/mobile/tags/page/entrance/signin.tag
+++ b/src/web/app/mobile/tags/page/entrance/signin.tag
@@ -2,7 +2,7 @@
 	<mk-signin/>
 	<a href={ _API_URL_ + '/signin/twitter' }>Twitterでサインイン</a>
 	<div class="divider"><span>or</span></div>
-	<button class="signup" onclick={ parent.signup }>%i18n:mobile.tags.mk-entrance-signin.signup%</button><a class="introduction" onclick={ parent.introduction }>%i18n:mobile.tags.mk-entrance-signin.about%</a>
+	<button class="signup" @click="parent.signup">%i18n:mobile.tags.mk-entrance-signin.signup%</button><a class="introduction" @click="parent.introduction">%i18n:mobile.tags.mk-entrance-signin.about%</a>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/mobile/tags/page/entrance/signup.tag b/src/web/app/mobile/tags/page/entrance/signup.tag
index 7b11bcad4d..6634593d31 100644
--- a/src/web/app/mobile/tags/page/entrance/signup.tag
+++ b/src/web/app/mobile/tags/page/entrance/signup.tag
@@ -1,6 +1,6 @@
 <mk-entrance-signup>
 	<mk-signup/>
-	<button class="cancel" type="button" onclick={ parent.signin } title="%i18n:mobile.tags.mk-entrance-signup.cancel%">%fa:times%</button>
+	<button class="cancel" type="button" @click="parent.signin" title="%i18n:mobile.tags.mk-entrance-signup.cancel%">%fa:times%</button>
 	<style>
 		:scope
 			display block
diff --git a/src/web/app/mobile/tags/page/selectdrive.tag b/src/web/app/mobile/tags/page/selectdrive.tag
index 1a790d806c..42a624a7aa 100644
--- a/src/web/app/mobile/tags/page/selectdrive.tag
+++ b/src/web/app/mobile/tags/page/selectdrive.tag
@@ -1,8 +1,8 @@
 <mk-selectdrive-page>
 	<header>
 		<h1>%i18n:mobile.tags.mk-selectdrive-page.select-file%<span class="count" if={ files.length > 0 }>({ files.length })</span></h1>
-		<button class="upload" onclick={ upload }>%fa:upload%</button>
-		<button if={ multiple } class="ok" onclick={ ok }>%fa:check%</button>
+		<button class="upload" @click="upload">%fa:upload%</button>
+		<button if={ multiple } class="ok" @click="ok">%fa:check%</button>
 	</header>
 	<mk-drive ref="browser" select-file={ true } multiple={ multiple } is-naked={ true } top={ 42 }/>
 
diff --git a/src/web/app/mobile/tags/page/settings.tag b/src/web/app/mobile/tags/page/settings.tag
index 9a73b0af3c..b388121cbb 100644
--- a/src/web/app/mobile/tags/page/settings.tag
+++ b/src/web/app/mobile/tags/page/settings.tag
@@ -26,7 +26,7 @@
 		<li><a href="./settings/signin-history">%fa:sign-in-alt%%i18n:mobile.tags.mk-settings-page.signin-history%%fa:angle-right%</a></li>
 	</ul>
 	<ul>
-		<li><a onclick={ signout }>%fa:power-off%%i18n:mobile.tags.mk-settings-page.signout%</a></li>
+		<li><a @click="signout">%fa:power-off%%i18n:mobile.tags.mk-settings-page.signout%</a></li>
 	</ul>
 	<p><small>ver { _VERSION_ } (葵 aoi)</small></p>
 	<style>
diff --git a/src/web/app/mobile/tags/page/settings/profile.tag b/src/web/app/mobile/tags/page/settings/profile.tag
index 8881e95190..cf62c3eb55 100644
--- a/src/web/app/mobile/tags/page/settings/profile.tag
+++ b/src/web/app/mobile/tags/page/settings/profile.tag
@@ -21,8 +21,8 @@
 	<div>
 		<p>%fa:info-circle%%i18n:mobile.tags.mk-profile-setting.will-be-published%</p>
 		<div class="form">
-			<div style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=1024)' : '' } onclick={ clickBanner }>
-				<img src={ I.avatar_url + '?thumbnail&size=200' } alt="avatar" onclick={ clickAvatar }/>
+			<div style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=1024)' : '' } @click="clickBanner">
+				<img src={ I.avatar_url + '?thumbnail&size=200' } alt="avatar" @click="clickAvatar"/>
 			</div>
 			<label>
 				<p>%i18n:mobile.tags.mk-profile-setting.name%</p>
@@ -42,14 +42,14 @@
 			</label>
 			<label>
 				<p>%i18n:mobile.tags.mk-profile-setting.avatar%</p>
-				<button onclick={ setAvatar } disabled={ avatarSaving }>%i18n:mobile.tags.mk-profile-setting.set-avatar%</button>
+				<button @click="setAvatar" disabled={ avatarSaving }>%i18n:mobile.tags.mk-profile-setting.set-avatar%</button>
 			</label>
 			<label>
 				<p>%i18n:mobile.tags.mk-profile-setting.banner%</p>
-				<button onclick={ setBanner } disabled={ bannerSaving }>%i18n:mobile.tags.mk-profile-setting.set-banner%</button>
+				<button @click="setBanner" disabled={ bannerSaving }>%i18n:mobile.tags.mk-profile-setting.set-banner%</button>
 			</label>
 		</div>
-		<button class="save" onclick={ save } disabled={ saving }>%fa:check%%i18n:mobile.tags.mk-profile-setting.save%</button>
+		<button class="save" @click="save" disabled={ saving }>%fa:check%%i18n:mobile.tags.mk-profile-setting.save%</button>
 	</div>
 	<style>
 		:scope
diff --git a/src/web/app/mobile/tags/post-detail.tag b/src/web/app/mobile/tags/post-detail.tag
index 1816d1bf93..131ea3aa3a 100644
--- a/src/web/app/mobile/tags/post-detail.tag
+++ b/src/web/app/mobile/tags/post-detail.tag
@@ -1,5 +1,5 @@
 <mk-post-detail>
-	<button class="read-more" if={ p.reply && p.reply.reply_id && context == null } onclick={ loadContext } disabled={ loadingContext }>
+	<button class="read-more" if={ p.reply && p.reply.reply_id && context == null } @click="loadContext" disabled={ loadingContext }>
 		<virtual if={ !contextFetching }>%fa:ellipsis-v%</virtual>
 		<virtual if={ contextFetching }>%fa:spinner .pulse%</virtual>
 	</button>
@@ -43,16 +43,16 @@
 		</a>
 		<footer>
 			<mk-reactions-viewer post={ p }/>
-			<button onclick={ reply } title="%i18n:mobile.tags.mk-post-detail.reply%">
+			<button @click="reply" title="%i18n:mobile.tags.mk-post-detail.reply%">
 				%fa:reply%<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p>
 			</button>
-			<button onclick={ repost } title="Repost">
+			<button @click="repost" title="Repost">
 				%fa:retweet%<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p>
 			</button>
-			<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%">
+			<button class={ reacted: p.my_reaction != null } @click="react" ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%">
 				%fa:plus%<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p>
 			</button>
-			<button onclick={ menu } ref="menuButton">
+			<button @click="menu" ref="menuButton">
 				%fa:ellipsis-h%
 			</button>
 		</footer>
diff --git a/src/web/app/mobile/tags/post-form.tag b/src/web/app/mobile/tags/post-form.tag
index 05466a6ec2..f0aa102d65 100644
--- a/src/web/app/mobile/tags/post-form.tag
+++ b/src/web/app/mobile/tags/post-form.tag
@@ -1,9 +1,9 @@
 <mk-post-form>
 	<header>
-		<button class="cancel" onclick={ cancel }>%fa:times%</button>
+		<button class="cancel" @click="cancel">%fa:times%</button>
 		<div>
 			<span if={ refs.text } class="text-count { over: refs.text.value.length > 1000 }">{ 1000 - refs.text.value.length }</span>
-			<button class="submit" onclick={ post }>%i18n:mobile.tags.mk-post-form.submit%</button>
+			<button class="submit" @click="post">%i18n:mobile.tags.mk-post-form.submit%</button>
 		</div>
 	</header>
 	<div class="form">
@@ -12,16 +12,16 @@
 		<div class="attaches" show={ files.length != 0 }>
 			<ul class="files" ref="attaches">
 				<li class="file" each={ files } data-id={ id }>
-					<div class="img" style="background-image: url({ url + '?thumbnail&size=128' })" onclick={ removeFile }></div>
+					<div class="img" style="background-image: url({ url + '?thumbnail&size=128' })" @click="removeFile"></div>
 				</li>
 			</ul>
 		</div>
 		<mk-poll-editor if={ poll } ref="poll" ondestroy={ onPollDestroyed }/>
 		<mk-uploader ref="uploader"/>
-		<button ref="upload" onclick={ selectFile }>%fa:upload%</button>
-		<button ref="drive" onclick={ selectFileFromDrive }>%fa:cloud%</button>
-		<button class="kao" onclick={ kao }>%fa:R smile%</button>
-		<button class="poll" onclick={ addPoll }>%fa:chart-pie%</button>
+		<button ref="upload" @click="selectFile">%fa:upload%</button>
+		<button ref="drive" @click="selectFileFromDrive">%fa:cloud%</button>
+		<button class="kao" @click="kao">%fa:R smile%</button>
+		<button class="poll" @click="addPoll">%fa:chart-pie%</button>
 		<input ref="file" type="file" accept="image/*" multiple="multiple" onchange={ changeFile }/>
 	</div>
 	<style>
diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag
index 9e85f97da3..400fa5d85f 100644
--- a/src/web/app/mobile/tags/timeline.tag
+++ b/src/web/app/mobile/tags/timeline.tag
@@ -13,7 +13,7 @@
 		</p>
 	</virtual>
 	<footer if={ !init }>
-		<button if={ canFetchMore } onclick={ more } disabled={ fetching }>
+		<button if={ canFetchMore } @click="more" disabled={ fetching }>
 			<span if={ !fetching }>%i18n:mobile.tags.mk-timeline.load-more%</span>
 			<span if={ fetching }>%i18n:common.loading%<mk-ellipsis/></span>
 		</button>
@@ -182,16 +182,16 @@
 			</div>
 			<footer>
 				<mk-reactions-viewer post={ p } ref="reactionsViewer"/>
-				<button onclick={ reply }>
+				<button @click="reply">
 					%fa:reply%<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p>
 				</button>
-				<button onclick={ repost } title="Repost">
+				<button @click="repost" title="Repost">
 					%fa:retweet%<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p>
 				</button>
-				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton">
+				<button class={ reacted: p.my_reaction != null } @click="react" ref="reactButton">
 					%fa:plus%<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p>
 				</button>
-				<button class="menu" onclick={ menu } ref="menuButton">
+				<button class="menu" @click="menu" ref="menuButton">
 					%fa:ellipsis-h%
 				</button>
 			</footer>
diff --git a/src/web/app/mobile/tags/ui.tag b/src/web/app/mobile/tags/ui.tag
index 77ad14530d..b03534f925 100644
--- a/src/web/app/mobile/tags/ui.tag
+++ b/src/web/app/mobile/tags/ui.tag
@@ -52,10 +52,10 @@
 	<div class="main">
 		<div class="backdrop"></div>
 		<div class="content">
-			<button class="nav" onclick={ parent.toggleDrawer }>%fa:bars%</button>
+			<button class="nav" @click="parent.toggleDrawer">%fa:bars%</button>
 			<virtual if={ hasUnreadNotifications || hasUnreadMessagingMessages }>%fa:circle%</virtual>
 			<h1 ref="title">Misskey</h1>
-			<button if={ func } onclick={ func }><mk-raw content={ funcIcon }/></button>
+			<button if={ func } @click="func"><mk-raw content={ funcIcon }/></button>
 		</div>
 	</div>
 	<style>
@@ -225,7 +225,7 @@
 </mk-ui-header>
 
 <mk-ui-nav>
-	<div class="backdrop" onclick={ parent.toggleDrawer }></div>
+	<div class="backdrop" @click="parent.toggleDrawer"></div>
 	<div class="body">
 		<a class="me" if={ SIGNIN } href={ '/' + I.username }>
 			<img class="avatar" src={ I.avatar_url + '?thumbnail&size=128' } alt="avatar"/>
@@ -242,7 +242,7 @@
 				<li><a href="/i/drive">%fa:cloud%%i18n:mobile.tags.mk-ui-nav.drive%%fa:angle-right%</a></li>
 			</ul>
 			<ul>
-				<li><a onclick={ search }>%fa:search%%i18n:mobile.tags.mk-ui-nav.search%%fa:angle-right%</a></li>
+				<li><a @click="search">%fa:search%%i18n:mobile.tags.mk-ui-nav.search%%fa:angle-right%</a></li>
 			</ul>
 			<ul>
 				<li><a href="/i/settings">%fa:cog%%i18n:mobile.tags.mk-ui-nav.settings%%fa:angle-right%</a></li>
diff --git a/src/web/app/mobile/tags/user.tag b/src/web/app/mobile/tags/user.tag
index b3a2f1a147..eb6d9ffbe1 100644
--- a/src/web/app/mobile/tags/user.tag
+++ b/src/web/app/mobile/tags/user.tag
@@ -39,9 +39,9 @@
 				</div>
 			</div>
 			<nav>
-				<a data-is-active={ page == 'overview' } onclick={ go.bind(null, 'overview') }>%i18n:mobile.tags.mk-user.overview%</a>
-				<a data-is-active={ page == 'posts' } onclick={ go.bind(null, 'posts') }>%i18n:mobile.tags.mk-user.timeline%</a>
-				<a data-is-active={ page == 'media' } onclick={ go.bind(null, 'media') }>%i18n:mobile.tags.mk-user.media%</a>
+				<a data-is-active={ page == 'overview' } @click="go.bind(null, 'overview')">%i18n:mobile.tags.mk-user.overview%</a>
+				<a data-is-active={ page == 'posts' } @click="go.bind(null, 'posts')">%i18n:mobile.tags.mk-user.timeline%</a>
+				<a data-is-active={ page == 'media' } @click="go.bind(null, 'media')">%i18n:mobile.tags.mk-user.media%</a>
 			</nav>
 		</header>
 		<div class="body">
diff --git a/src/web/app/mobile/tags/users-list.tag b/src/web/app/mobile/tags/users-list.tag
index 1dec33dddc..8e18bdea3c 100644
--- a/src/web/app/mobile/tags/users-list.tag
+++ b/src/web/app/mobile/tags/users-list.tag
@@ -1,12 +1,12 @@
 <mk-users-list>
 	<nav>
-		<span data-is-active={ mode == 'all' } onclick={ setMode.bind(this, 'all') }>%i18n:mobile.tags.mk-users-list.all%<span>{ opts.count }</span></span>
-		<span if={ SIGNIN && opts.youKnowCount } data-is-active={ mode == 'iknow' } onclick={ setMode.bind(this, 'iknow') }>%i18n:mobile.tags.mk-users-list.known%<span>{ opts.youKnowCount }</span></span>
+		<span data-is-active={ mode == 'all' } @click="setMode.bind(this, 'all')">%i18n:mobile.tags.mk-users-list.all%<span>{ opts.count }</span></span>
+		<span if={ SIGNIN && opts.youKnowCount } data-is-active={ mode == 'iknow' } @click="setMode.bind(this, 'iknow')">%i18n:mobile.tags.mk-users-list.known%<span>{ opts.youKnowCount }</span></span>
 	</nav>
 	<div class="users" if={ !fetching && users.length != 0 }>
 		<mk-user-preview each={ users } user={ this }/>
 	</div>
-	<button class="more" if={ !fetching && next != null } onclick={ more } disabled={ moreFetching }>
+	<button class="more" if={ !fetching && next != null } @click="more" disabled={ moreFetching }>
 		<span if={ !moreFetching }>%i18n:mobile.tags.mk-users-list.load-more%</span>
 		<span if={ moreFetching }>%i18n:common.loading%<mk-ellipsis/></span></button>
 	<p class="no" if={ !fetching && users.length == 0 }>{ opts.noUsers }</p>