Refactor slide methods in utils and use them for toolbar menus
This commit is contained in:
parent
ce2548c838
commit
b2a118ca9e
2
Makefile
2
Makefile
|
@ -148,7 +148,7 @@ css/mobile.min.css:: stamp-npm sass/*
|
|||
|
||||
.PHONY: watch
|
||||
watch: stamp-bundler
|
||||
$(SASS) --watch -I ./node_modules/bourbon/app/assets/stylesheets/ sass/converse/converse.scss:css/converse.css sass/_muc_embedded.scss:css/converse-muc-embedded.css
|
||||
$(SASS) --watch -I ./node_modules/bourbon/app/assets/stylesheets/ sass/converse/converse.scss:css/converse.css sass/_muc_embedded.scss:css/converse-muc-embedded.css sass/inverse/inverse.scss:css/inverse.css
|
||||
|
||||
.PHONY: watchjs
|
||||
watchjs: stamp-npm
|
||||
|
|
149
css/converse.css
149
css/converse.css
|
@ -1201,9 +1201,6 @@
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
#converse-embedded-chat .emoticon,
|
||||
#conversejs .emoticon {
|
||||
font-size: 14px; }
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0; }
|
||||
|
@ -1234,6 +1231,10 @@
|
|||
#conversejs .hidden {
|
||||
opacity: 0;
|
||||
display: none; }
|
||||
#converse-embedded-chat .collapsed,
|
||||
#conversejs .collapsed {
|
||||
height: 0;
|
||||
overflow: hidden; }
|
||||
#converse-embedded-chat .locked,
|
||||
#conversejs .locked {
|
||||
padding-right: 22px; }
|
||||
|
@ -1697,12 +1698,6 @@
|
|||
color: #818479;
|
||||
text-decoration: none;
|
||||
text-shadow: none; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .emoji-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .emoji-picker {
|
||||
margin-bottom: 30px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toolbar-picker-panel a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toolbar-picker-panel a {
|
||||
color: #578EA9; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .chat-toolbar-text,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .chat-toolbar-text {
|
||||
font-size: 12px;
|
||||
|
@ -1712,10 +1707,10 @@
|
|||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted {
|
||||
color: #818479; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-picker-panel a,
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-picker-panel a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-picker-panel a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-picker-panel a {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-menu a,
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-menu a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-menu a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-menu a {
|
||||
color: #578EA9; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unverified a,
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unverified,
|
||||
|
@ -1736,79 +1731,75 @@
|
|||
float: right; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: 0 3px 0 3px;
|
||||
cursor: pointer;
|
||||
margin-top: 1px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li:hover {
|
||||
cursor: pointer; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul {
|
||||
background: #fff;
|
||||
bottom: 100%;
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
position: relative; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar ul li a:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li a:hover {
|
||||
color: #8f2831; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li {
|
||||
margin-left: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley {
|
||||
color: #818479;
|
||||
padding-left: 5px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul {
|
||||
left: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker {
|
||||
margin-top: 1px;
|
||||
padding: 0 3px 0 3px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li:hover {
|
||||
cursor: pointer; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
|
||||
background-color: #fff;
|
||||
bottom: 100%;
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu a {
|
||||
color: #578EA9; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker {
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
z-index: 100; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker .picked,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker .picked {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker .picked,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker .picked {
|
||||
background-color: #DCF9F6; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-picker {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
|
||||
height: 250px;
|
||||
overflow: scroll; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li {
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
z-index: 98; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li.emoji a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li.emoji a {
|
||||
font-size: 20px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li:hover {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
|
||||
margin-left: 0;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
position: relative; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li a:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li a:hover {
|
||||
color: #8f2831; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu {
|
||||
color: #818479; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu ul li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu ul li:hover {
|
||||
background-color: #DCF9F6; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li {
|
||||
padding: 7px;
|
||||
background-color: white;
|
||||
display: block;
|
||||
z-index: 99; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li a {
|
||||
-moz-transition: background-color 0.2s ease-in-out;
|
||||
-webkit-transition: background-color 0.2s ease-in-out;
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
display: block;
|
||||
padding: 1px;
|
||||
text-decoration: none; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li:hover {
|
||||
background-color: #DCF9F6; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley {
|
||||
padding-left: 5px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul {
|
||||
left: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li {
|
||||
padding: 5px;
|
||||
z-index: 98; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li.emoji a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li.emoji a {
|
||||
font-size: 20px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul {
|
||||
z-index: 99; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li {
|
||||
display: block;
|
||||
padding: 7px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li a {
|
||||
display: block; }
|
||||
#converse-embedded-chat .chatbox .dragresize,
|
||||
#conversejs .chatbox .dragresize {
|
||||
background: transparent;
|
||||
|
|
149
css/inverse.css
149
css/inverse.css
|
@ -1201,9 +1201,6 @@
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
#converse-embedded-chat .emoticon,
|
||||
#conversejs .emoticon {
|
||||
font-size: 16px; }
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0; }
|
||||
|
@ -1234,6 +1231,10 @@
|
|||
#conversejs .hidden {
|
||||
opacity: 0;
|
||||
display: none; }
|
||||
#converse-embedded-chat .collapsed,
|
||||
#conversejs .collapsed {
|
||||
height: 0;
|
||||
overflow: hidden; }
|
||||
#converse-embedded-chat .locked,
|
||||
#conversejs .locked {
|
||||
padding-right: 22px; }
|
||||
|
@ -1743,12 +1744,6 @@ body {
|
|||
color: #818479;
|
||||
text-decoration: none;
|
||||
text-shadow: none; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .emoji-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .emoji-picker {
|
||||
margin-bottom: 34px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toolbar-picker-panel a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toolbar-picker-panel a {
|
||||
color: #578EA9; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .chat-toolbar-text,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .chat-toolbar-text {
|
||||
font-size: 12px;
|
||||
|
@ -1758,10 +1753,10 @@ body {
|
|||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted {
|
||||
color: #818479; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-picker-panel a,
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-picker-panel a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-picker-panel a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-picker-panel a {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-menu a,
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-menu a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-menu a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted .toolbar-menu a {
|
||||
color: #578EA9; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unverified a,
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .unverified,
|
||||
|
@ -1782,79 +1777,75 @@ body {
|
|||
float: right; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: 0 3px 0 3px;
|
||||
cursor: pointer;
|
||||
margin-top: 1px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li:hover {
|
||||
cursor: pointer; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul {
|
||||
background: #fff;
|
||||
bottom: 100%;
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
position: relative; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar ul li a:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li a:hover {
|
||||
color: #8f2831; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li {
|
||||
margin-left: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley {
|
||||
color: #818479;
|
||||
padding-left: 5px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul {
|
||||
left: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker {
|
||||
margin-top: 1px;
|
||||
padding: 0 3px 0 3px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li:hover {
|
||||
cursor: pointer; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
|
||||
background-color: #fff;
|
||||
bottom: 100%;
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu a {
|
||||
color: #578EA9; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker {
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
z-index: 100; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker .picked,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-category-picker .picked {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker .picked,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-category-picker .picked {
|
||||
background-color: #DCF9F6; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul.emoji-picker {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
|
||||
height: 250px;
|
||||
overflow: scroll; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li {
|
||||
font-size: 16px;
|
||||
padding: 5px;
|
||||
z-index: 98; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li.emoji a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li.emoji a {
|
||||
font-size: 26px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li:hover {
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
|
||||
margin-left: 0;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
position: relative; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li a:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul li a:hover {
|
||||
color: #8f2831; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu {
|
||||
color: #818479; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu ul li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu ul li:hover {
|
||||
background-color: #DCF9F6; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li {
|
||||
padding: 7px;
|
||||
background-color: white;
|
||||
display: block;
|
||||
z-index: 99; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li a {
|
||||
-moz-transition: background-color 0.2s ease-in-out;
|
||||
-webkit-transition: background-color 0.2s ease-in-out;
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
display: block;
|
||||
padding: 1px;
|
||||
text-decoration: none; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li:hover,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li:hover {
|
||||
background-color: #DCF9F6; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley {
|
||||
padding-left: 5px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul {
|
||||
left: 0; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li {
|
||||
padding: 5px;
|
||||
z-index: 98; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li.emoji a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-smiley ul li.emoji a {
|
||||
font-size: 26px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul {
|
||||
z-index: 99; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li {
|
||||
display: block;
|
||||
padding: 7px; }
|
||||
#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li a,
|
||||
#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li.toggle-otr ul li a {
|
||||
display: block; }
|
||||
#converse-embedded-chat .chatbox .dragresize,
|
||||
#conversejs .chatbox .dragresize {
|
||||
background: transparent;
|
||||
|
|
|
@ -272,14 +272,6 @@
|
|||
text-decoration: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
.emoji-picker {
|
||||
margin-bottom: $toolbar-height + 5px;
|
||||
}
|
||||
.toolbar-picker-panel {
|
||||
a {
|
||||
color: $link-color;
|
||||
}
|
||||
}
|
||||
.chat-toolbar-text {
|
||||
font-size: 12px;
|
||||
padding-right: 3px;
|
||||
|
@ -287,7 +279,7 @@
|
|||
.unencrypted a,
|
||||
.unencrypted {
|
||||
color: $text-color;
|
||||
.toolbar-picker-panel {
|
||||
.toolbar-menu {
|
||||
a {
|
||||
color: $link-color;
|
||||
}
|
||||
|
@ -307,83 +299,83 @@
|
|||
float: right;
|
||||
}
|
||||
li {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: 0 3px 0 3px;
|
||||
cursor: pointer;
|
||||
margin-top: 1px;
|
||||
}
|
||||
li:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
ul {
|
||||
background: #fff;
|
||||
bottom: 100%;
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
li {
|
||||
padding: 0 3px 0 3px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
position: relative;
|
||||
a:hover {
|
||||
color: #8f2831;
|
||||
}
|
||||
}
|
||||
}
|
||||
li {
|
||||
margin-left: 0;
|
||||
}
|
||||
.toggle-smiley {
|
||||
color: $text-color;
|
||||
padding-left: 5px;
|
||||
ul {
|
||||
&.emoji-category-picker {
|
||||
z-index: 100;
|
||||
.picked {
|
||||
background-color: $highlight-color;
|
||||
.toolbar-menu {
|
||||
background-color: #fff;
|
||||
bottom: 100%;
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
a {
|
||||
color: $link-color;
|
||||
}
|
||||
ul {
|
||||
&.emoji-category-picker {
|
||||
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
.picked {
|
||||
background-color: $highlight-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.emoji-picker {
|
||||
height: 250px;
|
||||
overflow: scroll;
|
||||
}
|
||||
left: 0;
|
||||
li {
|
||||
font-size: $font-size;
|
||||
padding: 5px;
|
||||
z-index: 98;
|
||||
&.emoji {
|
||||
a {
|
||||
font-size: $font-size-huge;
|
||||
&.emoji-picker {
|
||||
height: 250px;
|
||||
overflow: scroll;
|
||||
}
|
||||
li {
|
||||
margin-left: 0;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
position: relative;
|
||||
a:hover {
|
||||
color: #8f2831;
|
||||
}
|
||||
}
|
||||
}
|
||||
li:hover {
|
||||
background-color: $highlight-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.toggle-otr {
|
||||
ul {
|
||||
li {
|
||||
padding: 7px;
|
||||
background-color: white;
|
||||
display: block;
|
||||
z-index: 99;
|
||||
a {
|
||||
-moz-transition: background-color 0.2s ease-in-out;
|
||||
-webkit-transition: background-color 0.2s ease-in-out;
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
display: block;
|
||||
padding: 1px;
|
||||
text-decoration: none;
|
||||
&.toggle-toolbar-menu {
|
||||
color: $text-color;
|
||||
ul {
|
||||
li {
|
||||
&:hover {
|
||||
background-color: $highlight-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
li:hover {
|
||||
background-color: $highlight-color;
|
||||
}
|
||||
&.toggle-smiley {
|
||||
padding-left: 5px;
|
||||
ul {
|
||||
left: 0;
|
||||
li {
|
||||
padding: 5px;
|
||||
z-index: 98;
|
||||
&.emoji {
|
||||
a {
|
||||
font-size: $font-size-huge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.toggle-otr {
|
||||
ul {
|
||||
z-index: 99;
|
||||
li {
|
||||
display: block;
|
||||
padding: 7px;
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
opacity: 0;
|
||||
display: none;
|
||||
}
|
||||
.collapsed {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.locked {
|
||||
padding-right: 22px;
|
||||
|
|
|
@ -54,14 +54,13 @@
|
|||
//
|
||||
registerGlobalEventHandlers: function () {
|
||||
this.__super__.registerGlobalEventHandlers();
|
||||
document.addEventListener('click', function () {
|
||||
if ($('.toggle-smiley ul').is(':visible')) {
|
||||
_.each(
|
||||
document.querySelectorAll('.toggle-smiley .emoji-picker-container'),
|
||||
utils.hideElement
|
||||
);
|
||||
document.addEventListener(
|
||||
'click', function () {
|
||||
utils.slideInAllElements(
|
||||
document.querySelectorAll('.toolbar-menu')
|
||||
)
|
||||
}
|
||||
});
|
||||
);
|
||||
},
|
||||
|
||||
ChatBoxViews: {
|
||||
|
@ -114,7 +113,7 @@
|
|||
});
|
||||
|
||||
_converse.EmojiPickerView = Backbone.View.extend({
|
||||
className: 'emoji-picker-container hidden',
|
||||
className: 'emoji-picker-container toolbar-menu collapsed',
|
||||
events: {
|
||||
'click .emoji-category-picker li a': 'chooseCategory',
|
||||
},
|
||||
|
@ -710,7 +709,16 @@
|
|||
return;
|
||||
}
|
||||
}
|
||||
utils.toggleElement(this.emoji_picker_view.el);
|
||||
const elements = _.difference(
|
||||
document.querySelectorAll('.toolbar-menu'),
|
||||
[this.emoji_picker_view.el]
|
||||
);
|
||||
utils.slideInAllElements(elements).then(
|
||||
_.partial(
|
||||
utils.slideToggleElement,
|
||||
this.emoji_picker_view.el
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
toggleCall (ev) {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
OTR_CLASS_MAPPING[VERIFIED] = 'verified';
|
||||
OTR_CLASS_MAPPING[FINISHED] = 'finished';
|
||||
|
||||
|
||||
converse.plugins.add('converse-otr', {
|
||||
|
||||
overrides: {
|
||||
|
@ -51,15 +52,6 @@
|
|||
//
|
||||
// New functions which don't exist yet can also be added.
|
||||
|
||||
registerGlobalEventHandlers () {
|
||||
this.__super__.registerGlobalEventHandlers();
|
||||
document.addEventListener('click', function () {
|
||||
if ($('.toggle-otr ul').is(':visible')) {
|
||||
_.each($('.toggle-otr ul', this), utils.hideElement);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
ChatBox: {
|
||||
initialize () {
|
||||
this.__super__.initialize.apply(this, arguments);
|
||||
|
@ -347,7 +339,6 @@
|
|||
},
|
||||
|
||||
startOTRFromToolbar (ev) {
|
||||
$(ev.target).parent().parent().slideUp();
|
||||
ev.stopPropagation();
|
||||
this.model.initiateOTR();
|
||||
},
|
||||
|
@ -392,7 +383,17 @@
|
|||
|
||||
toggleOTRMenu (ev) {
|
||||
ev.stopPropagation();
|
||||
utils.toggleElement(this.el.querySelector('.toggle-otr ul'));
|
||||
const menu = this.el.querySelector('.toggle-otr ul');
|
||||
const elements = _.difference(
|
||||
document.querySelectorAll('.toolbar-menu'),
|
||||
[menu]
|
||||
);
|
||||
utils.slideInAllElements(elements).then(
|
||||
_.partial(
|
||||
utils.slideToggleElement,
|
||||
menu
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
getOTRTooltip () {
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
});
|
||||
this.hide();
|
||||
if (this.list_model.get('toggle-state') !== _converse.OPENED) {
|
||||
this.el.querySelector('.open-rooms-list').classList.add('hidden');
|
||||
this.el.querySelector('.open-rooms-list').classList.add('collapsed');
|
||||
}
|
||||
this.model.each(this.renderRoomsListElement.bind(this));
|
||||
const controlboxview = _converse.chatboxviews.get('controlbox');
|
||||
|
@ -142,13 +142,13 @@
|
|||
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
||||
const el = ev.target;
|
||||
if (el.classList.contains("icon-opened")) {
|
||||
utils.slideUp(this.el.querySelector('.open-rooms-list')).then(() => {
|
||||
utils.slideIn(this.el.querySelector('.open-rooms-list')).then(() => {
|
||||
this.list_model.save({'toggle-state': _converse.CLOSED});
|
||||
el.classList.remove("icon-opened");
|
||||
el.classList.add("icon-closed");
|
||||
});
|
||||
} else {
|
||||
utils.slideDown(this.el.querySelector('.open-rooms-list')).then(() => {
|
||||
utils.slideOut(this.el.querySelector('.open-rooms-list')).then(() => {
|
||||
this.list_model.save({'toggle-state': _converse.OPENED});
|
||||
el.classList.remove("icon-closed");
|
||||
el.classList.add("icon-opened");
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
<ul class="emoji-category-picker">
|
||||
{[ _.forEach(emojis_by_category, function (obj, category) { ]}
|
||||
<li data-category="{{{category}}}" class="emoji-category {[ if (current_category === category) { ]} picked {[ } ]}">
|
||||
<a href="#" data-category="{{{category}}}"> {{ emojione.shortnameToUnicode(emojis_by_category[category][0]._shortname) }} </a>
|
||||
</li>
|
||||
{[ }); ]}
|
||||
</ul>
|
||||
{[ _.forEach(emojis_by_category, function (obj, category) { ]}
|
||||
<ul class="emoji-picker emoji-picker-{{{category}}} {[ if (current_category !== category) { ]} hidden {[ } ]}">
|
||||
{[ _.forEach(emojis_by_category[category], function (emoji) { ]}
|
||||
|
@ -14,3 +7,10 @@
|
|||
{[ }); ]}
|
||||
</ul>
|
||||
{[ }); ]}
|
||||
<ul class="emoji-category-picker">
|
||||
{[ _.forEach(emojis_by_category, function (obj, category) { ]}
|
||||
<li data-category="{{{category}}}" class="emoji-category {[ if (current_category === category) { ]} picked {[ } ]}">
|
||||
<a href="#" data-category="{{{category}}}"> {{ emojione.shortnameToUnicode(emojis_by_category[category][0]._shortname) }} </a>
|
||||
</li>
|
||||
{[ }); ]}
|
||||
</ul>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{[ if (use_emoji) { ]}
|
||||
<li class="toggle-smiley icon-happy" title="{{{label_insert_smiley}}}">
|
||||
<li class="toggle-toolbar-menu toggle-smiley icon-happy" title="{{{label_insert_smiley}}}">
|
||||
<ul class="emoji-picker"></ul>
|
||||
</li>
|
||||
{[ } ]}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{[ if (allow_otr) { ]}
|
||||
<li class="toggle-otr {{{otr_status_class}}}" title="{{{otr_tooltip}}}">
|
||||
<li class="toggle-toolbar-menu toggle-otr {{{otr_status_class}}}" title="{{{otr_tooltip}}}">
|
||||
<span class="chat-toolbar-text">{{{otr_translated_status}}}</span>
|
||||
{[ if (otr_status == UNENCRYPTED) { ]}
|
||||
<span class="icon-unlocked"></span>
|
||||
|
@ -13,7 +13,7 @@
|
|||
{[ if (otr_status == FINISHED) { ]}
|
||||
<span class="icon-unlocked"></span>
|
||||
{[ } ]}
|
||||
<ul class="toolbar-picker-panel">
|
||||
<ul class="toolbar-menu collapsed">
|
||||
{[ if (otr_status == UNENCRYPTED) { ]}
|
||||
<li><a class="start-otr" href="#">{{{label_start_encrypted_conversation}}}</a></li>
|
||||
{[ } ]}
|
||||
|
|
713
src/utils.js
713
src/utils.js
|
@ -129,356 +129,385 @@
|
|||
return this;
|
||||
};
|
||||
|
||||
var utils = {
|
||||
// Translation machinery
|
||||
// ---------------------
|
||||
__: function (str) {
|
||||
if (!utils.isConverseLocale(this.locale) || this.locale === 'en') {
|
||||
return Jed.sprintf.apply(Jed, arguments);
|
||||
}
|
||||
if (typeof this.jed === "undefined") {
|
||||
this.jed = new Jed(window.JSON.parse(locales[this.locale]));
|
||||
}
|
||||
var t = this.jed.translate(str);
|
||||
if (arguments.length>1) {
|
||||
return t.fetch.apply(t, [].slice.call(arguments,1));
|
||||
} else {
|
||||
return t.fetch();
|
||||
}
|
||||
},
|
||||
function calculateSlideStep (height) {
|
||||
if (height > 100) {
|
||||
return 10;
|
||||
} else if (height > 50) {
|
||||
return 5;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
___: function (str) {
|
||||
/* XXX: This is part of a hack to get gettext to scan strings to be
|
||||
* translated. Strings we cannot send to the function above because
|
||||
* they require variable interpolation and we don't yet have the
|
||||
* variables at scan time.
|
||||
*
|
||||
* See actionInfoMessages in src/converse-muc.js
|
||||
*/
|
||||
return str;
|
||||
},
|
||||
var utils = {};
|
||||
|
||||
isLocaleAvailable: function (locale, available) {
|
||||
/* Check whether the locale or sub locale (e.g. en-US, en) is supported.
|
||||
*
|
||||
* Parameters:
|
||||
* (Function) available - returns a boolean indicating whether the locale is supported
|
||||
*/
|
||||
if (available(locale)) {
|
||||
return locale;
|
||||
} else {
|
||||
var sublocale = locale.split("-")[0];
|
||||
if (sublocale !== locale && available(sublocale)) {
|
||||
return sublocale;
|
||||
}
|
||||
}
|
||||
},
|
||||
// Translation machinery
|
||||
// ---------------------
|
||||
utils.__ = function (str) {
|
||||
if (!utils.isConverseLocale(this.locale) || this.locale === 'en') {
|
||||
return Jed.sprintf.apply(Jed, arguments);
|
||||
}
|
||||
if (typeof this.jed === "undefined") {
|
||||
this.jed = new Jed(window.JSON.parse(locales[this.locale]));
|
||||
}
|
||||
var t = this.jed.translate(str);
|
||||
if (arguments.length>1) {
|
||||
return t.fetch.apply(t, [].slice.call(arguments,1));
|
||||
} else {
|
||||
return t.fetch();
|
||||
}
|
||||
};
|
||||
|
||||
hideElement: function (el) {
|
||||
el.classList.add('hidden');
|
||||
},
|
||||
utils.___ = function (str) {
|
||||
/* XXX: This is part of a hack to get gettext to scan strings to be
|
||||
* translated. Strings we cannot send to the function above because
|
||||
* they require variable interpolation and we don't yet have the
|
||||
* variables at scan time.
|
||||
*
|
||||
* See actionInfoMessages in src/converse-muc.js
|
||||
*/
|
||||
return str;
|
||||
};
|
||||
|
||||
toggleElement: function (el) {
|
||||
if (_.includes(el.classList, 'hidden')) {
|
||||
// XXX: use fadeIn?
|
||||
el.classList.remove('hidden');
|
||||
} else {
|
||||
this.hideElement (el);
|
||||
}
|
||||
},
|
||||
|
||||
slideDown: function (el, interval=0.6) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (_.isNil(el)) {
|
||||
const err = "Undefined or null element passed into slideDown"
|
||||
console.warn(err);
|
||||
reject(new Error(err));
|
||||
}
|
||||
let intval = el.getAttribute('data-slider-intval');
|
||||
if (intval) {
|
||||
window.clearInterval(intval);
|
||||
}
|
||||
let h = 0;
|
||||
const end_height = el.getAttribute('data-slider-height');
|
||||
intval = window.setInterval(function () {
|
||||
h++;
|
||||
el.style.height = h + 'px';
|
||||
if (h >= end_height) {
|
||||
window.clearInterval(intval);
|
||||
el.style.height = '';
|
||||
el.style.overflow = '';
|
||||
el.removeAttribute('data-slider-intval');
|
||||
el.removeAttribute('data-slider-height');
|
||||
resolve();
|
||||
}
|
||||
}, interval);
|
||||
el.setAttribute('data-slider-intval', intval);
|
||||
});
|
||||
},
|
||||
|
||||
slideUp: function (el, interval=0.6) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (_.isNil(el)) {
|
||||
const err = "Undefined or null element passed into slideUp";
|
||||
console.warn(err);
|
||||
reject(new Error(err));
|
||||
}
|
||||
let intval = el.getAttribute('data-slider-intval');
|
||||
if (intval) {
|
||||
window.clearInterval(intval);
|
||||
}
|
||||
let h = el.offsetHeight;
|
||||
el.setAttribute('data-slider-height', h);
|
||||
el.style.overflow = 'hidden';
|
||||
intval = window.setInterval(function () {
|
||||
el.style.height = h + 'px';
|
||||
h--;
|
||||
if (h < 0) {
|
||||
window.clearInterval(intval);
|
||||
el.removeAttribute('data-slider-intval');
|
||||
resolve();
|
||||
}
|
||||
}, interval);
|
||||
el.setAttribute('data-slider-intval', intval);
|
||||
});
|
||||
},
|
||||
|
||||
fadeIn: function (el, callback) {
|
||||
if (_.isNil(el)) {
|
||||
console.warn("Undefined or null element passed into fadeIn");
|
||||
}
|
||||
if ($.fx.off) {
|
||||
el.classList.remove('hidden');
|
||||
if (_.isFunction(callback)) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_.includes(el.classList, 'hidden')) {
|
||||
/* XXX: This doesn't appear to be working...
|
||||
el.addEventListener("webkitAnimationEnd", _.partial(afterAnimationEnd, el, callback), false);
|
||||
el.addEventListener("animationend", _.partial(afterAnimationEnd, el, callback), false);
|
||||
*/
|
||||
setTimeout(_.partial(afterAnimationEnd, el, callback), 351);
|
||||
el.classList.add('visible');
|
||||
el.classList.remove('hidden');
|
||||
} else {
|
||||
afterAnimationEnd(el, callback);
|
||||
}
|
||||
},
|
||||
|
||||
isSameBareJID: function (jid1, jid2) {
|
||||
return Strophe.getBareJidFromJid(jid1).toLowerCase() ===
|
||||
Strophe.getBareJidFromJid(jid2).toLowerCase();
|
||||
},
|
||||
|
||||
isNewMessage: function (message) {
|
||||
/* Given a stanza, determine whether it's a new
|
||||
* message, i.e. not a MAM archived one.
|
||||
*/
|
||||
if (message instanceof Element) {
|
||||
return !(sizzle('result[xmlns="'+Strophe.NS.MAM+'"]', message).length);
|
||||
} else {
|
||||
return !message.get('archive_id');
|
||||
}
|
||||
},
|
||||
|
||||
isOTRMessage: function (message) {
|
||||
var body = message.querySelector('body'),
|
||||
text = (!_.isNull(body) ? body.textContent: undefined);
|
||||
return text && !!text.match(/^\?OTR/);
|
||||
},
|
||||
|
||||
isHeadlineMessage: function (message) {
|
||||
var from_jid = message.getAttribute('from');
|
||||
if (message.getAttribute('type') === 'headline') {
|
||||
return true;
|
||||
}
|
||||
if (message.getAttribute('type') !== 'error' &&
|
||||
!_.isNil(from_jid) &&
|
||||
!_.includes(from_jid, '@')) {
|
||||
// Some servers (I'm looking at you Prosody) don't set the message
|
||||
// type to "headline" when sending server messages. For now we
|
||||
// check if an @ signal is included, and if not, we assume it's
|
||||
// a headline message.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
merge: function merge (first, second) {
|
||||
/* Merge the second object into the first one.
|
||||
*/
|
||||
for (var k in second) {
|
||||
if (_.isObject(first[k])) {
|
||||
merge(first[k], second[k]);
|
||||
} else {
|
||||
first[k] = second[k];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
applyUserSettings: function applyUserSettings (context, settings, user_settings) {
|
||||
/* Configuration settings might be nested objects. We only want to
|
||||
* add settings which are whitelisted.
|
||||
*/
|
||||
for (var k in settings) {
|
||||
if (_.isUndefined(user_settings[k])) {
|
||||
continue;
|
||||
}
|
||||
if (_.isObject(settings[k]) && !_.isArray(settings[k])) {
|
||||
applyUserSettings(context[k], settings[k], user_settings[k]);
|
||||
} else {
|
||||
context[k] = user_settings[k];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
refreshWebkit: function () {
|
||||
/* This works around a webkit bug. Refreshes the browser's viewport,
|
||||
* otherwise chatboxes are not moved along when one is closed.
|
||||
*/
|
||||
if ($.browser.webkit && window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame(function () {
|
||||
var conversejs = document.getElementById('conversejs');
|
||||
conversejs.style.display = 'none';
|
||||
var tmp = conversejs.offsetHeight; // jshint ignore:line
|
||||
conversejs.style.display = 'block';
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
webForm2xForm: function (field) {
|
||||
/* Takes an HTML DOM and turns it into an XForm field.
|
||||
*
|
||||
* Parameters:
|
||||
* (DOMElement) field - the field to convert
|
||||
*/
|
||||
var $input = $(field), value;
|
||||
if ($input.is('[type=checkbox]')) {
|
||||
value = $input.is(':checked') && 1 || 0;
|
||||
} else if ($input.is('textarea')) {
|
||||
value = [];
|
||||
var lines = $input.val().split('\n');
|
||||
for( var vk=0; vk<lines.length; vk++) {
|
||||
var val = $.trim(lines[vk]);
|
||||
if (val === '')
|
||||
continue;
|
||||
value.push(val);
|
||||
}
|
||||
} else {
|
||||
value = $input.val();
|
||||
}
|
||||
return $(tpl_field({
|
||||
name: $input.attr('name'),
|
||||
value: value
|
||||
}))[0];
|
||||
},
|
||||
|
||||
contains: function (attr, query) {
|
||||
return function (item) {
|
||||
if (typeof attr === 'object') {
|
||||
var value = false;
|
||||
_.forEach(attr, function (a) {
|
||||
value = value || _.includes(item.get(a).toLowerCase(), query.toLowerCase());
|
||||
});
|
||||
return value;
|
||||
} else if (typeof attr === 'string') {
|
||||
return _.includes(item.get(attr).toLowerCase(), query.toLowerCase());
|
||||
} else {
|
||||
throw new TypeError('contains: wrong attribute type. Must be string or array.');
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
xForm2webForm: function ($field, $stanza) {
|
||||
/* Takes a field in XMPP XForm (XEP-004: Data Forms) format
|
||||
* and turns it into a HTML DOM field.
|
||||
*
|
||||
* Parameters:
|
||||
* (XMLElement) field - the field to convert
|
||||
*/
|
||||
|
||||
// FIXME: take <required> into consideration
|
||||
var options = [], j, $options, $values, value, values;
|
||||
|
||||
if ($field.attr('type') === 'list-single' || $field.attr('type') === 'list-multi') {
|
||||
values = [];
|
||||
$values = $field.children('value');
|
||||
for (j=0; j<$values.length; j++) {
|
||||
values.push($($values[j]).text());
|
||||
}
|
||||
$options = $field.children('option');
|
||||
for (j=0; j<$options.length; j++) {
|
||||
value = $($options[j]).find('value').text();
|
||||
options.push(tpl_select_option({
|
||||
value: value,
|
||||
label: $($options[j]).attr('label'),
|
||||
selected: _.startsWith(values, value),
|
||||
required: $field.find('required').length
|
||||
}));
|
||||
}
|
||||
return tpl_form_select({
|
||||
name: $field.attr('var'),
|
||||
label: $field.attr('label'),
|
||||
options: options.join(''),
|
||||
multiple: ($field.attr('type') === 'list-multi'),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type') === 'fixed') {
|
||||
return $('<p class="form-help">').text($field.find('value').text());
|
||||
} else if ($field.attr('type') === 'jid-multi') {
|
||||
return tpl_form_textarea({
|
||||
name: $field.attr('var'),
|
||||
label: $field.attr('label') || '',
|
||||
value: $field.find('value').text(),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type') === 'boolean') {
|
||||
return tpl_form_checkbox({
|
||||
name: $field.attr('var'),
|
||||
type: XFORM_TYPE_MAP[$field.attr('type')],
|
||||
label: $field.attr('label') || '',
|
||||
checked: $field.find('value').text() === "1" && 'checked="1"' || '',
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type') && $field.attr('var') === 'username') {
|
||||
return tpl_form_username({
|
||||
domain: ' @'+this.domain,
|
||||
name: $field.attr('var'),
|
||||
type: XFORM_TYPE_MAP[$field.attr('type')],
|
||||
label: $field.attr('label') || '',
|
||||
value: $field.find('value').text(),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type')) {
|
||||
return tpl_form_input({
|
||||
name: $field.attr('var'),
|
||||
type: XFORM_TYPE_MAP[$field.attr('type')],
|
||||
label: $field.attr('label') || '',
|
||||
value: $field.find('value').text(),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else {
|
||||
if ($field.attr('var') === 'ocr') { // Captcha
|
||||
return _.reduce(_.map($field.find('uri'),
|
||||
$.proxy(function (uri) {
|
||||
return tpl_form_captcha({
|
||||
label: this.$field.attr('label'),
|
||||
name: this.$field.attr('var'),
|
||||
data: this.$stanza.find('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]').text(),
|
||||
type: uri.getAttribute('type'),
|
||||
required: this.$field.find('required').length
|
||||
});
|
||||
}, {'$stanza': $stanza, '$field': $field})
|
||||
),
|
||||
function (memo, num) { return memo + num; }, ''
|
||||
);
|
||||
}
|
||||
utils.isLocaleAvailable = function (locale, available) {
|
||||
/* Check whether the locale or sub locale (e.g. en-US, en) is supported.
|
||||
*
|
||||
* Parameters:
|
||||
* (Function) available - returns a boolean indicating whether the locale is supported
|
||||
*/
|
||||
if (available(locale)) {
|
||||
return locale;
|
||||
} else {
|
||||
var sublocale = locale.split("-")[0];
|
||||
if (sublocale !== locale && available(sublocale)) {
|
||||
return sublocale;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
utils.slideInAllElements = function (elements) {
|
||||
return Promise.all(
|
||||
_.map(
|
||||
elements,
|
||||
_.partial(utils.slideIn, _, 600)
|
||||
));
|
||||
};
|
||||
|
||||
utils.slideToggleElement = function (el) {
|
||||
if (!el.offsetHeight) {
|
||||
return utils.slideOut(el);
|
||||
} else {
|
||||
return utils.slideIn(el);
|
||||
}
|
||||
};
|
||||
|
||||
utils.slideOut = function (el, duration=600) {
|
||||
/* Shows/expands an element by sliding it out of itself. */
|
||||
return new Promise((resolve, reject) => {
|
||||
if (_.isNil(el)) {
|
||||
const err = "Undefined or null element passed into slideOut"
|
||||
console.warn(err);
|
||||
reject(new Error(err));
|
||||
}
|
||||
let interval_marker = el.getAttribute('data-slider-marker');
|
||||
if (interval_marker) {
|
||||
window.clearInterval(interval_marker);
|
||||
}
|
||||
const end_height = _.reduce(el.children, function (result, child) {
|
||||
return result + child.offsetHeight;
|
||||
}, 0);
|
||||
const step = calculateSlideStep(end_height),
|
||||
interval = end_height/duration*step;
|
||||
|
||||
let h = 0;
|
||||
interval_marker = window.setInterval(function () {
|
||||
h += step;
|
||||
if (h < end_height) {
|
||||
el.style.height = h + 'px';
|
||||
} else {
|
||||
el.style.height = end_height + 'px';
|
||||
window.clearInterval(interval_marker);
|
||||
el.style.overflow = '';
|
||||
el.removeAttribute('data-slider-marker');
|
||||
resolve();
|
||||
}
|
||||
}, interval);
|
||||
el.setAttribute('data-slider-marker', interval_marker);
|
||||
});
|
||||
};
|
||||
|
||||
utils.slideIn = function (el, duration=600) {
|
||||
/* Hides/collapses an element by sliding it into itself. */
|
||||
return new Promise((resolve, reject) => {
|
||||
if (_.isNil(el)) {
|
||||
const err = "Undefined or null element passed into slideIn";
|
||||
console.warn(err);
|
||||
reject(new Error(err));
|
||||
}
|
||||
if (!el.offsetHeight) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
let interval_marker = el.getAttribute('data-slider-marker');
|
||||
if (interval_marker) {
|
||||
window.clearInterval(interval_marker);
|
||||
}
|
||||
let h = el.offsetHeight;
|
||||
const step = calculateSlideStep(h),
|
||||
interval = h/duration*step;
|
||||
|
||||
el.style.overflow = 'hidden';
|
||||
|
||||
interval_marker = window.setInterval(function () {
|
||||
h -= step;
|
||||
if (h > 0) {
|
||||
el.style.height = h + 'px';
|
||||
} else {
|
||||
el.style.height = 0 + 'px';
|
||||
window.clearInterval(interval_marker);
|
||||
el.removeAttribute('data-slider-marker');
|
||||
resolve();
|
||||
}
|
||||
}, interval);
|
||||
el.setAttribute('data-slider-marker', interval_marker);
|
||||
});
|
||||
};
|
||||
|
||||
utils.fadeIn = function (el, callback) {
|
||||
if (_.isNil(el)) {
|
||||
console.warn("Undefined or null element passed into fadeIn");
|
||||
}
|
||||
if ($.fx.off) {
|
||||
el.classList.remove('hidden');
|
||||
if (_.isFunction(callback)) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_.includes(el.classList, 'hidden')) {
|
||||
/* XXX: This doesn't appear to be working...
|
||||
el.addEventListener("webkitAnimationEnd", _.partial(afterAnimationEnd, el, callback), false);
|
||||
el.addEventListener("animationend", _.partial(afterAnimationEnd, el, callback), false);
|
||||
*/
|
||||
setTimeout(_.partial(afterAnimationEnd, el, callback), 351);
|
||||
el.classList.add('visible');
|
||||
el.classList.remove('hidden');
|
||||
} else {
|
||||
afterAnimationEnd(el, callback);
|
||||
}
|
||||
};
|
||||
|
||||
utils.isSameBareJID = function (jid1, jid2) {
|
||||
return Strophe.getBareJidFromJid(jid1).toLowerCase() ===
|
||||
Strophe.getBareJidFromJid(jid2).toLowerCase();
|
||||
};
|
||||
|
||||
utils.isNewMessage = function (message) {
|
||||
/* Given a stanza, determine whether it's a new
|
||||
* message, i.e. not a MAM archived one.
|
||||
*/
|
||||
if (message instanceof Element) {
|
||||
return !(sizzle('result[xmlns="'+Strophe.NS.MAM+'"]', message).length);
|
||||
} else {
|
||||
return !message.get('archive_id');
|
||||
}
|
||||
};
|
||||
|
||||
utils.isOTRMessage = function (message) {
|
||||
var body = message.querySelector('body'),
|
||||
text = (!_.isNull(body) ? body.textContent: undefined);
|
||||
return text && !!text.match(/^\?OTR/);
|
||||
};
|
||||
|
||||
utils.isHeadlineMessage = function (message) {
|
||||
var from_jid = message.getAttribute('from');
|
||||
if (message.getAttribute('type') === 'headline') {
|
||||
return true;
|
||||
}
|
||||
if (message.getAttribute('type') !== 'error' &&
|
||||
!_.isNil(from_jid) &&
|
||||
!_.includes(from_jid, '@')) {
|
||||
// Some servers (I'm looking at you Prosody) don't set the message
|
||||
// type to "headline" when sending server messages. For now we
|
||||
// check if an @ signal is included, and if not, we assume it's
|
||||
// a headline message.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
utils.merge = function merge (first, second) {
|
||||
/* Merge the second object into the first one.
|
||||
*/
|
||||
for (var k in second) {
|
||||
if (_.isObject(first[k])) {
|
||||
merge(first[k], second[k]);
|
||||
} else {
|
||||
first[k] = second[k];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
utils.applyUserSettings = function applyUserSettings (context, settings, user_settings) {
|
||||
/* Configuration settings might be nested objects. We only want to
|
||||
* add settings which are whitelisted.
|
||||
*/
|
||||
for (var k in settings) {
|
||||
if (_.isUndefined(user_settings[k])) {
|
||||
continue;
|
||||
}
|
||||
if (_.isObject(settings[k]) && !_.isArray(settings[k])) {
|
||||
applyUserSettings(context[k], settings[k], user_settings[k]);
|
||||
} else {
|
||||
context[k] = user_settings[k];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
utils.refreshWebkit = function () {
|
||||
/* This works around a webkit bug. Refreshes the browser's viewport,
|
||||
* otherwise chatboxes are not moved along when one is closed.
|
||||
*/
|
||||
if ($.browser.webkit && window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame(function () {
|
||||
var conversejs = document.getElementById('conversejs');
|
||||
conversejs.style.display = 'none';
|
||||
var tmp = conversejs.offsetHeight; // jshint ignore:line
|
||||
conversejs.style.display = 'block';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
utils.webForm2xForm = function (field) {
|
||||
/* Takes an HTML DOM and turns it into an XForm field.
|
||||
*
|
||||
* Parameters:
|
||||
* (DOMElement) field - the field to convert
|
||||
*/
|
||||
var $input = $(field), value;
|
||||
if ($input.is('[type=checkbox]')) {
|
||||
value = $input.is(':checked') && 1 || 0;
|
||||
} else if ($input.is('textarea')) {
|
||||
value = [];
|
||||
var lines = $input.val().split('\n');
|
||||
for( var vk=0; vk<lines.length; vk++) {
|
||||
var val = $.trim(lines[vk]);
|
||||
if (val === '')
|
||||
continue;
|
||||
value.push(val);
|
||||
}
|
||||
} else {
|
||||
value = $input.val();
|
||||
}
|
||||
return $(tpl_field({
|
||||
name: $input.attr('name'),
|
||||
value: value
|
||||
}))[0];
|
||||
};
|
||||
|
||||
utils.contains = function (attr, query) {
|
||||
return function (item) {
|
||||
if (typeof attr === 'object') {
|
||||
var value = false;
|
||||
_.forEach(attr, function (a) {
|
||||
value = value || _.includes(item.get(a).toLowerCase(), query.toLowerCase());
|
||||
});
|
||||
return value;
|
||||
} else if (typeof attr === 'string') {
|
||||
return _.includes(item.get(attr).toLowerCase(), query.toLowerCase());
|
||||
} else {
|
||||
throw new TypeError('contains: wrong attribute type. Must be string or array.');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
utils.xForm2webForm = function ($field, $stanza) {
|
||||
/* Takes a field in XMPP XForm (XEP-004: Data Forms) format
|
||||
* and turns it into a HTML DOM field.
|
||||
*
|
||||
* Parameters:
|
||||
* (XMLElement) field - the field to convert
|
||||
*/
|
||||
|
||||
// FIXME: take <required> into consideration
|
||||
var options = [], j, $options, $values, value, values;
|
||||
|
||||
if ($field.attr('type') === 'list-single' || $field.attr('type') === 'list-multi') {
|
||||
values = [];
|
||||
$values = $field.children('value');
|
||||
for (j=0; j<$values.length; j++) {
|
||||
values.push($($values[j]).text());
|
||||
}
|
||||
$options = $field.children('option');
|
||||
for (j=0; j<$options.length; j++) {
|
||||
value = $($options[j]).find('value').text();
|
||||
options.push(tpl_select_option({
|
||||
value: value,
|
||||
label: $($options[j]).attr('label'),
|
||||
selected: _.startsWith(values, value),
|
||||
required: $field.find('required').length
|
||||
}));
|
||||
}
|
||||
return tpl_form_select({
|
||||
name: $field.attr('var'),
|
||||
label: $field.attr('label'),
|
||||
options: options.join(''),
|
||||
multiple: ($field.attr('type') === 'list-multi'),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type') === 'fixed') {
|
||||
return $('<p class="form-help">').text($field.find('value').text());
|
||||
} else if ($field.attr('type') === 'jid-multi') {
|
||||
return tpl_form_textarea({
|
||||
name: $field.attr('var'),
|
||||
label: $field.attr('label') || '',
|
||||
value: $field.find('value').text(),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type') === 'boolean') {
|
||||
return tpl_form_checkbox({
|
||||
name: $field.attr('var'),
|
||||
type: XFORM_TYPE_MAP[$field.attr('type')],
|
||||
label: $field.attr('label') || '',
|
||||
checked: $field.find('value').text() === "1" && 'checked="1"' || '',
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type') && $field.attr('var') === 'username') {
|
||||
return tpl_form_username({
|
||||
domain: ' @'+this.domain,
|
||||
name: $field.attr('var'),
|
||||
type: XFORM_TYPE_MAP[$field.attr('type')],
|
||||
label: $field.attr('label') || '',
|
||||
value: $field.find('value').text(),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else if ($field.attr('type')) {
|
||||
return tpl_form_input({
|
||||
name: $field.attr('var'),
|
||||
type: XFORM_TYPE_MAP[$field.attr('type')],
|
||||
label: $field.attr('label') || '',
|
||||
value: $field.find('value').text(),
|
||||
required: $field.find('required').length
|
||||
});
|
||||
} else {
|
||||
if ($field.attr('var') === 'ocr') { // Captcha
|
||||
return _.reduce(_.map($field.find('uri'),
|
||||
$.proxy(function (uri) {
|
||||
return tpl_form_captcha({
|
||||
label: this.$field.attr('label'),
|
||||
name: this.$field.attr('var'),
|
||||
data: this.$stanza.find('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]').text(),
|
||||
type: uri.getAttribute('type'),
|
||||
required: this.$field.find('required').length
|
||||
});
|
||||
}, {'$stanza': $stanza, '$field': $field})
|
||||
),
|
||||
function (memo, num) { return memo + num; }, ''
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
utils.detectLocale = function (library_check) {
|
||||
/* Determine which locale is supported by the user's system as well
|
||||
* as by the relevant library (e.g. converse.js or moment.js).
|
||||
|
|
Loading…
Reference in New Issue
Block a user