You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/02/12 10:33:48 UTC

[openmeetings] branch csp updated: [OPENMEETINGS-2165] more code clean-up

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch csp
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/csp by this push:
     new 78f4894  [OPENMEETINGS-2165] more code clean-up
78f4894 is described below

commit 78f489464080b8aaf9cd9c37d773944a01ef1070
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Wed Feb 12 17:33:32 2020 +0700

    [OPENMEETINGS-2165] more code clean-up
---
 .../web/admin/users/PasswordDialog.java            |  3 +-
 .../apache/openmeetings/web/app/Application.java   |  4 +
 .../openmeetings/web/common/InvitationDialog.java  | 11 +--
 .../apache/openmeetings/web/common/NameDialog.java |  3 +-
 .../web/common/UploadableImagePanel.html           |  2 +-
 .../web/common/UploadableImagePanel.java           | 16 ++--
 .../common/confirmation/ConfirmationDialog.java    | 55 ++++++++++++++
 .../openmeetings/web/pages/AccessDeniedPage.html   |  8 +-
 .../openmeetings/web/pages/AccessDeniedPage.java   |  8 +-
 .../web/pages/InvitationPasswordDialog.java        | 88 ++++++++--------------
 .../web/pages/auth/ForgetPasswordDialog.java       | 10 +--
 .../web/pages/auth/RegisterDialog.java             | 10 +--
 .../openmeetings/web/room/NicknameDialog.java      | 85 ++++++++-------------
 .../web/user/InviteUserMessageDialog.java          | 10 +--
 .../web/user/InviteUserToRoomDialog.java           | 11 +--
 .../openmeetings/web/user/MessageDialog.java       | 13 +---
 .../openmeetings/web/user/OmWysiwygToolbar.html    | 85 +++++++++++++++++++++
 .../OmWysiwygToolbar.java}                         | 20 ++---
 .../openmeetings/web/user/UserInfoDialog.java      |  9 +--
 .../web/user/calendar/AppointmentDialog.java       |  4 +-
 .../web/user/profile/ChangePasswordDialog.html     |  4 +-
 .../web/user/profile/ChangePasswordDialog.java     | 72 +++++++-----------
 .../web/user/profile/EditProfileForm.html          |  2 +-
 .../web/user/profile/EditProfileForm.java          | 14 ++--
 .../web/user/profile/MessagesContactsPanel.html    |  5 +-
 .../web/user/profile/MessagesContactsPanel.java    | 36 +++++----
 .../web/user/profile/UserSearchPanel.html          |  2 +-
 .../web/user/profile/UserSearchPanel.java          |  6 +-
 openmeetings-web/src/main/webapp/css/raw-chat.css  | 14 ++--
 29 files changed, 321 insertions(+), 289 deletions(-)

diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/users/PasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/users/PasswordDialog.java
index f3876c2..a6fa5a8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/users/PasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/users/PasswordDialog.java
@@ -34,6 +34,7 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButt
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class PasswordDialog extends Modal<String> {
 	private static final long serialVersionUID = 1L;
@@ -82,7 +83,7 @@ public class PasswordDialog extends Modal<String> {
 				}
 			}
 		}); // OK
-		addCloseButton(new ResourceModel("lbl.cancel"));
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		add(form.add(feedback.setOutputMarkupId(true), pass.setRequired(false).setLabel(new ResourceModel("110")).setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true)));
 		super.onInitialize();
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 4a3a1b7..a39e104 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -105,6 +105,7 @@ import org.apache.wicket.core.request.handler.BookmarkableListenerRequestHandler
 import org.apache.wicket.core.request.handler.ListenerRequestHandler;
 import org.apache.wicket.core.request.mapper.MountedMapper;
 import org.apache.wicket.csp.CSPDirective;
+import org.apache.wicket.csp.CSPDirectiveSrcValue;
 import org.apache.wicket.csp.CSPHeaderConfiguration;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.filter.FilteringHeaderResponse;
@@ -341,6 +342,9 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 					cspConfig.add(CSPDirective.IMG_SRC, oauth.getIconUrl());
 				}
 			});
+			cspConfig.add(CSPDirective.STYLE_SRC, "https://fonts.googleapis.com/css"); //Roboto font FIXME TODO should this be moved to configs???
+			cspConfig.add(CSPDirective.FONT_SRC, "https://fonts.gstatic.com"); //Roboto font FIXME TODO should this be moved to configs???
+			cspConfig.add(CSPDirective.MEDIA_SRC, CSPDirectiveSrcValue.SELF);
 			setInitComplete(true);
 		} catch (Exception err) {
 			log.error("[appStart]", err);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationDialog.java
index f31ccc9..4eeebcf 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationDialog.java
@@ -20,13 +20,12 @@ package org.apache.openmeetings.web.common;
 
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.model.Model;
 import org.apache.wicket.model.ResourceModel;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class InvitationDialog extends Modal<Invitation> {
 	private static final long serialVersionUID = 1L;
@@ -71,13 +70,7 @@ public class InvitationDialog extends Modal<Invitation> {
 				InvitationDialog.this.onClick(target, InvitationForm.Action.SEND);
 			}
 		});
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				InvitationDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		super.onInitialize();
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
index 6ed3271..a5092ab 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
@@ -32,6 +32,7 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButt
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public abstract class NameDialog extends Modal<String> {
 	private static final long serialVersionUID = 1L;
@@ -56,7 +57,7 @@ public abstract class NameDialog extends Modal<String> {
 		setCloseOnEscapeKey(true);
 		setBackdrop(Backdrop.STATIC);
 
-		addCloseButton(new ResourceModel("lbl.cancel"));
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		addButton(new BootstrapAjaxButton("button", getAddBtnLabel(), form, Buttons.Type.Outline_Primary) {
 			private static final long serialVersionUID = 1L;
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.html
index 5caf8ce..454c5e8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.html
@@ -21,7 +21,7 @@
 <!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org">
 <wicket:extend>
-	<button type="button" class="btn btn-xs btn-secondary remove" wicket:id="remove">
+	<button type="button" class="btn btn-xs btn-outline-secondary remove" wicket:id="remove">
 		<span aria-hidden="true">×</span>
 	</button>
 	<form wicket:id="form" class="img-upload">
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
index ff2f174..f2d4f82 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
@@ -26,10 +26,11 @@ import java.util.Optional;
 
 import org.apache.openmeetings.util.StoredFile;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
 import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
@@ -68,10 +69,7 @@ public abstract class UploadableImagePanel extends ImagePanel {
 		form.add(fileUploadField);
 		form.add(new UploadProgressBar("progress", form, fileUploadField));
 		form.addOrReplace(getImage());
-		if (delayed) {
-			add(new WebMarkupContainer("remove").add(AttributeModifier.append("onclick"
-					, "$(this).parent().find('.fileinput').fileinput('clear');")));
-		} else {
+		if (!delayed) {
 			BootstrapAjaxLink<String> remove = new BootstrapAjaxLink<>("remove", Buttons.Type.Outline_Secondary) {
 				private static final long serialVersionUID = 1L;
 
@@ -102,6 +100,14 @@ public abstract class UploadableImagePanel extends ImagePanel {
 	}
 
 	@Override
+	public void renderHead(IHeaderResponse response) {
+		super.renderHead(response);
+		if (delayed) {
+			response.render(OnDomReadyHeaderItem.forScript("$('#" + form.getOutputMarkupId() + " .remove').click(function() {$(this).parent().find('.fileinput').fileinput('clear');})"));
+		}
+	}
+
+	@Override
 	public void update() {
 		profile.addOrReplace(new WebMarkupContainer("img").setVisible(false));
 		form.addOrReplace(getImage());
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmationDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmationDialog.java
new file mode 100644
index 0000000..979a360
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmationDialog.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.common.confirmation;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.TextContentModal;
+
+public abstract class ConfirmationDialog extends TextContentModal {
+	private static final long serialVersionUID = 1L;
+
+	public ConfirmationDialog(String id, IModel<String> title, IModel<String> model) {
+		super(id, model);
+		header(title);
+		setBackdrop(Backdrop.STATIC);
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+		addButton(new BootstrapAjaxLink<>("button", null, Buttons.Type.Outline_Primary, new ResourceModel("54")) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClick(AjaxRequestTarget target) {
+				close(target);
+				onConfirm(target);
+			}
+		}); //send
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
+	}
+
+	protected abstract void onConfirm(AjaxRequestTarget target);
+}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.html
index 3fb13ca..da3806d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.html
@@ -20,15 +20,15 @@
 <!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org" wicket:id="html">
 <wicket:extend>
-	<div class="ui-widget ui-corner-all ui-widget-shadow access-denied outer">
-		<div class="ui-widget-content ui-corner-all ui-state-error inner">
+	<div class="access-denied outer">
+		<div class="border text-danger inner">
 			<div>
 				<h2><wicket:message key="access.denied.header"/></h2>
 			</div>
 			<div class="centered">
 				<form wicket:id="form">
-					<button class="ui-state-error" wicket:id="home"><wicket:message key="124"/></button>
-					<button class="ui-state-error" wicket:id="logout"><wicket:message key="310"/></button>
+					<button wicket:id="home"></button>
+					<button wicket:id="logout"></button>
 				</form>
 			</div>
 		</div>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.java
index 1b15ba5..4f7a888 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/AccessDeniedPage.java
@@ -22,9 +22,11 @@ import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.IRequestParameters;
 
-import com.googlecode.wicket.jquery.ui.form.button.Button;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 
 public class AccessDeniedPage extends BaseInitedPage {
 	private static final long serialVersionUID = 1L;
@@ -33,7 +35,7 @@ public class AccessDeniedPage extends BaseInitedPage {
 	protected void onInitialize() {
 		super.onInitialize();
 		add(new Form<Void>("form").add(
-				new Button("home") {
+				new BootstrapButton("home", new ResourceModel("124"), Buttons.Type.Outline_Primary) {
 					private static final long serialVersionUID = 1L;
 
 					@Override
@@ -41,7 +43,7 @@ public class AccessDeniedPage extends BaseInitedPage {
 						setResponsePage(Application.get().getHomePage());
 					}
 				}
-				, new Button("logout") {
+				, new BootstrapButton("logout", new ResourceModel("310"), Buttons.Type.Outline_Danger) {
 					private static final long serialVersionUID = 1L;
 
 					@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
index b0112fd..12b67ba 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
@@ -18,14 +18,10 @@
  */
 package org.apache.openmeetings.web.pages;
 
-import java.util.Arrays;
-import java.util.List;
-
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.util.crypt.CryptProvider;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.IUpdatable;
-import org.apache.openmeetings.web.util.NonClosableDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
@@ -37,22 +33,28 @@ import org.apache.wicket.validation.IValidatable;
 import org.apache.wicket.validation.IValidator;
 import org.apache.wicket.validation.ValidationError;
 
-import com.googlecode.wicket.jquery.core.JQueryBehavior;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 
-public class InvitationPasswordDialog extends NonClosableDialog<Invitation> {
+public class InvitationPasswordDialog extends Modal<Invitation> {
 	private static final long serialVersionUID = 1L;
 	private final NotificationPanel feedback = new NotificationPanel("feedback");
-	private DialogButton check;
 	private final Form<Void> form = new Form<>("form");
 	private final PasswordTextField password = new PasswordTextField("password", Model.of((String)null));
 	private final IUpdatable comp;
 
 	public InvitationPasswordDialog(String id, IUpdatable comp) {
-		super(id, "");
+		super(id);
 		this.comp = comp;
+	}
+
+	@Override
+	protected void onInitialize() {
+		header(new ResourceModel("230"));
+		setBackdrop(Backdrop.STATIC);
+
 		password.add(new IValidator<String>(){
 			private static final long serialVersionUID = 1L;
 
@@ -69,71 +71,47 @@ public class InvitationPasswordDialog extends NonClosableDialog<Invitation> {
 
 			@Override
 			protected void onSubmit(AjaxRequestTarget target) {
-				InvitationPasswordDialog.this.onSubmit(target, check);
-				InvitationPasswordDialog.this.close(target, null);
+				InvitationPasswordDialog.this.onSubmit(target);
 			}
 
 			@Override
 			protected void onError(AjaxRequestTarget target) {
-				InvitationPasswordDialog.this.onError(target, check);
+				InvitationPasswordDialog.this.onError(target);
 			}
 		};
 		form.add(ab);
 		form.setDefaultButton(ab);
-	}
-
-	@Override
-	protected void onInitialize() {
-		getTitle().setObject(getString("230"));
 		password.setLabel(new ResourceModel("110"));
-		check = new DialogButton("check", getString("537"));
-		super.onInitialize();
-	}
-
-	@Override
-	public void onConfigure(JQueryBehavior behavior) {
-		super.onConfigure(behavior);
-		Invitation i = WebSession.get().getInvitation();
-		behavior.setOption("autoOpen", i != null && i.isPasswordProtected());
-	}
+		addButton(new BootstrapAjaxButton("button", new ResourceModel("537"), form, Buttons.Type.Outline_Primary) {
+			private static final long serialVersionUID = 1L;
 
-	@Override
-	public boolean isResizable() {
-		return false;
-	}
+			@Override
+			protected void onError(AjaxRequestTarget target) {
+				InvitationPasswordDialog.this.onError(target);
+			}
 
-	@Override
-	public boolean isDefaultCloseEventEnabled() {
-		return false;
+			@Override
+			protected void onSubmit(AjaxRequestTarget target) {
+				InvitationPasswordDialog.this.onSubmit(target);
+			}
+		}); //check
+		super.onInitialize();
+		Invitation i = WebSession.get().getInvitation();
+		show(i != null && i.isPasswordProtected());
 	}
 
 	@Override
-	protected void onOpen(IPartialPageRequestHandler handler) {
+	public Modal<Invitation> show(IPartialPageRequestHandler handler) {
 		password.setModelObject(null);
+		return super.show(handler);
 	}
 
-	@Override
-	public DialogButton getSubmitButton() {
-		return check;
-	}
-
-	@Override
-	protected List<DialogButton> getButtons() {
-		return Arrays.asList(check);
-	}
-
-	@Override
-	public Form<Void> getForm() {
-		return form;
-	}
-
-	@Override
-	protected void onError(AjaxRequestTarget target, DialogButton btn) {
+	protected void onError(AjaxRequestTarget target) {
 		target.add(feedback);
 	}
 
-	@Override
-	protected void onSubmit(AjaxRequestTarget target, DialogButton btn) {
+	protected void onSubmit(AjaxRequestTarget target) {
 		comp.update(target);
+		close(target);
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
index 8d33aea..6f9a539 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
@@ -56,10 +56,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class ForgetPasswordDialog extends Modal<String> {
 	private static final Logger log = LoggerFactory.getLogger(ForgetPasswordDialog.class);
@@ -100,13 +100,7 @@ public class ForgetPasswordDialog extends Modal<String> {
 		addButton(new BootstrapAjaxButton("button", new ResourceModel("317"), form, Buttons.Type.Outline_Primary) {
 			private static final long serialVersionUID = 1L;
 		}); // Send
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				ForgetPasswordDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 
 		add(form);
 		super.onInitialize();
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
index 3b22aba..8d34a3f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
@@ -52,10 +52,10 @@ import org.apache.wicket.validation.IValidatable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.spinner.SpinnerAjaxButton;
 
 public class RegisterDialog extends Modal<String> {
@@ -96,13 +96,7 @@ public class RegisterDialog extends Modal<String> {
 		setBackdrop(Backdrop.STATIC);
 
 		addButton(new SpinnerAjaxButton("button", new ResourceModel("121"), form, Buttons.Type.Outline_Primary)); // register
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				RegisterDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		add(form);
 		add(new Label("register", getString("121")).setRenderBodyOnly(true), new BookmarkablePageLink<>("link", PrivacyPage.class));
 		reset(null);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
index e099cea..a606d87 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
@@ -22,15 +22,12 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.getMinFnameLeng
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getMinLnameLength;
 import static org.apache.wicket.validation.validator.StringValidator.minimumLength;
 
-import java.util.Arrays;
 import java.util.Date;
-import java.util.List;
 
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.ClientManager;
-import org.apache.openmeetings.web.util.NonClosableDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.validation.validator.RfcCompliantEmailAddressValidator;
 import org.apache.wicket.markup.html.form.Form;
@@ -40,85 +37,65 @@ import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.string.Strings;
 
-import com.googlecode.wicket.jquery.core.JQueryBehavior;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 
-public class NicknameDialog extends NonClosableDialog<User> {
+public class NicknameDialog extends Modal<User> {
 	private static final long serialVersionUID = 1L;
 	private static final FastDateFormat TIME_DF = FastDateFormat.getInstance("HH:mm:ss");
 	private final NotificationPanel feedback = new NotificationPanel("feedback");
-	private DialogButton ok;
 	private final RoomPanel room;
-	private final Form<User> form;
+	private Form<User> form;
 	@SpringBean
 	private ClientManager cm;
 
 	public NicknameDialog(String id, final RoomPanel room) {
-		super(id, "");
+		super(id);
 		this.room = room;
-		add(form = new Form<>("form", new CompoundPropertyModel<>(room.getClient().getUser())));
 	}
 
 	@Override
 	protected void onInitialize() {
-		getTitle().setObject(getString("1287"));
-		ok = new DialogButton("ok", getString("54"));
+		header(new ResourceModel("1287"));
+		setBackdrop(Backdrop.STATIC);
+
+		add(form = new Form<>("form", new CompoundPropertyModel<>(room.getClient().getUser())));
+		addButton(new BootstrapAjaxButton("button", new ResourceModel("54"), form, Buttons.Type.Outline_Primary) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void onError(AjaxRequestTarget target) {
+				target.add(feedback);
+			}
+
+			@Override
+			protected void onSubmit(AjaxRequestTarget target) {
+				final User u = form.getModelObject();
+				final Client c = room.getClient();
+				c.getUser().setFirstname(u.getFirstname()).setLastname(u.getLastname());
+				room.broadcast(cm.update(c));
+				NicknameDialog.this.close(target);
+			}
+		}); //set nickname
 		form.add(feedback.setOutputMarkupId(true));
 		form.add(new RequiredTextField<String>("firstname").setLabel(new ResourceModel("135")).add(minimumLength(getMinFnameLength())));
 		form.add(new RequiredTextField<String>("lastname").setLabel(new ResourceModel("136")).add(minimumLength(getMinLnameLength())));
 		form.add(new RequiredTextField<String>("address.email").setLabel(new ResourceModel("119")).add(RfcCompliantEmailAddressValidator.getInstance()));
 		super.onInitialize();
-	}
 
-	private static boolean isVisible(User u) {
-		return (User.Type.contact == u.getType() || User.Type.external == u.getType())
-				&& Strings.isEmpty(u.getFirstname()) && Strings.isEmpty(u.getLastname());
-	}
-
-	@Override
-	public void onConfigure(JQueryBehavior behavior) {
-		super.onConfigure(behavior);
 		User u = form.getModelObject();
 		boolean visible = isVisible(u);
 		if (visible) {
 			u.setFirstname(getString("433"));
 			u.setLastname(String.format("%s %s", u.getFirstname(), TIME_DF.format(new Date())));
 		}
-		behavior.setOption("autoOpen", visible);
-	}
-
-	@Override
-	public boolean isResizable() {
-		return false;
-	}
-
-	@Override
-	protected List<DialogButton> getButtons() {
-		return Arrays.asList(ok);
-	}
-
-	@Override
-	public DialogButton getSubmitButton() {
-		return ok;
-	}
-
-	@Override
-	public Form<?> getForm() {
-		return form;
+		show(visible);
 	}
 
-	@Override
-	protected void onError(AjaxRequestTarget target, DialogButton btn) {
-		target.add(feedback);
-	}
-
-	@Override
-	protected void onSubmit(AjaxRequestTarget target, DialogButton btn) {
-		final User u = form.getModelObject();
-		final Client c = room.getClient();
-		c.getUser().setFirstname(u.getFirstname()).setLastname(u.getLastname());
-		room.broadcast(cm.update(c));
+	private static boolean isVisible(User u) {
+		return (User.Type.contact == u.getType() || User.Type.external == u.getType())
+				&& Strings.isEmpty(u.getFirstname()) && Strings.isEmpty(u.getLastname());
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserMessageDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserMessageDialog.java
index f211460..cd71431 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserMessageDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserMessageDialog.java
@@ -32,9 +32,9 @@ import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class InviteUserMessageDialog extends Modal<String> {
 	private static final long serialVersionUID = 1L;
@@ -69,13 +69,7 @@ public class InviteUserMessageDialog extends Modal<String> {
 				InviteUserMessageDialog.this.close(target);
 			}
 		}); //send
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				InviteUserMessageDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		super.onInitialize();
 		add(form.add(message.setRequired(true), enterRoom.setOutputMarkupId(true)).setOutputMarkupId(true));
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserToRoomDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserToRoomDialog.java
index 4aab3ff..2d27d6c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserToRoomDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/InviteUserToRoomDialog.java
@@ -30,13 +30,12 @@ import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.web.user.rooms.RoomListPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
-import org.apache.wicket.model.Model;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class InviteUserToRoomDialog extends Modal<String> {
 	private static final long serialVersionUID = 1L;
@@ -72,13 +71,7 @@ public class InviteUserToRoomDialog extends Modal<String> {
 		setCloseOnEscapeKey(true);
 		setBackdrop(Backdrop.STATIC);
 
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				InviteUserToRoomDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		add(publicRooms = new InviteRoomListPanel("publicRooms", new ArrayList<Room>(), getString("1135")));
 		add(privateRooms = new InviteRoomListPanel("privateRooms", new ArrayList<Room>(), getString("1135")));
 		add(inviteMsg);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
index 0aab9d7..79f3cb8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
@@ -73,13 +73,12 @@ import org.apache.wicket.model.util.CollectionModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
 import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.WysiwygEditor;
-import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.toolbar.DefaultWysiwygToolbar;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class MessageDialog extends Modal<PrivateMessage> {
 	private static final long serialVersionUID = 1L;
@@ -210,18 +209,12 @@ public class MessageDialog extends Modal<PrivateMessage> {
 				onSend(target);
 			}
 		}); // send
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				MessageDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 
 		form.add(feedback.setOutputMarkupId(true));
 		form.add(new UserMultiChoice("to", modelTo).setRequired(true));
 		form.add(new TextField<String>("subject"));
-		DefaultWysiwygToolbar toolbar = new DefaultWysiwygToolbar("toolbarContainer");
+		OmWysiwygToolbar toolbar = new OmWysiwygToolbar("toolbarContainer");
 		form.add(toolbar);
 		form.add(new WysiwygEditor("message", toolbar));
 		form.add(roomParamsBlock.setOutputMarkupId(true));
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/OmWysiwygToolbar.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/OmWysiwygToolbar.html
new file mode 100644
index 0000000..1f450de
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/OmWysiwygToolbar.html
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+	<div wicket:id="toolbar" class="btn-toolbar wysiwyg-toolbar" data-role="editor-toolbar">
+		<div class="btn-group">
+			<a wicket:id="fontSize" id="fontSize" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" role="button" title="Font Size"> A </a>
+			<ul class="dropdown-menu">
+				<li><a wicket:id="huge" class="font-huge text-center clickable" data-edit="fontSize 5"></a></li>
+				<li><a wicket:id="medium" class="font-small text-center clickable" data-edit="fontSize 3"></a></li>
+				<li><a wicket:id="small" class="font-tiny text-center clickable" data-edit="fontSize 1"></a></li>
+			</ul>
+		</div>
+		<div class="btn-group">
+			<a wicket:id="bold" class="btn btn-outline-secondary tool-btn bold" data-edit="bold" title=""> B </a>
+			<a wicket:id="italic" class="btn btn-outline-secondary tool-btn italic" data-edit="italic" title=""> I </a>
+			<a wicket:id="strikethrough" class="btn btn-outline-secondary tool-btn strike" data-edit="strikethrough" title=""> S </a>
+			<a wicket:id="underline" class="btn btn-outline-secondary tool-btn under" data-edit="underline" title=""> U </a>
+		</div>
+		<div class="btn-group">
+			<a wicket:id="bullets" class="btn btn-outline-secondary" data-edit="insertunorderedlist" title="">
+				<i class="fas fa-list-ul"></i>
+			</a>
+			<a wicket:id="numbers" class="btn btn-outline-secondary" data-edit="insertorderedlist" title="">
+				<i class="fas fa-list-ol"></i>
+			</a>
+			<a wicket:id="reduceIndent" class="btn btn-outline-secondary" data-edit="outdent" title="">
+				<i class="fas fa-indent"></i>
+			</a>
+			<a wicket:id="indent" class="btn btn-outline-secondary" data-edit="indent" title="">
+				<i class="fas fa-outdent"></i>
+			</a>
+		</div>
+		<div class="btn-group">
+			<a wicket:id="justifyLeft" class="btn btn-outline-secondary" data-edit="justifyleft" title="">
+				<i class="fas fa-align-left"></i>
+			</a>
+			<a wicket:id="justifyCenter" class="btn btn-outline-secondary" data-edit="justifycenter" title="">
+				<i class="fas fa-align-center"></i>
+			</a>
+			<a wicket:id="justifyRight" class="btn btn-outline-secondary" data-edit="justifyright" title="">
+				<i class="fas fa-align-right"></i>
+			</a>
+			<a wicket:id="justifyFull" class="btn btn-outline-secondary" data-edit="justifyfull" title="">
+				<i class="fas fa-align-justify"></i>
+			</a>
+		</div>
+		<div class="btn-group">
+			<a wicket:id="hyperlink" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" title="">
+				<i class="fas fa-link"></i>
+			</a>
+			<div class="dropdown-menu input-append">
+				<input class="span2" placeholder="URL" type="text" data-edit="createLink"/>
+				<button class="btn btn-outline-secondary" type="button"><wicket:message key="1261"/></button>
+			</div>
+			<a wicket:id="removeHyperlink" class="btn btn-outline-secondary" data-edit="unlink" title="">
+				<i class="fas fa-unlink"></i>
+			</a>
+		</div>
+		<div class="btn-group">
+			<a wicket:id="undo" class="btn btn-outline-secondary" data-edit="undo" title="">
+				<i class="fas fa-undo-alt"></i>
+			</a>
+			<a wicket:id="redo" class="btn btn-outline-secondary" data-edit="redo" title="">
+				<i class="fas fa-redo-alt"></i>
+			</a>
+		</div>
+	</div>
+</wicket:panel>
+</html>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/OmWysiwygToolbar.java
similarity index 59%
rename from openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java
rename to openmeetings-web/src/main/java/org/apache/openmeetings/web/user/OmWysiwygToolbar.java
index 8f8a5ec..ce310bc 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/OmWysiwygToolbar.java
@@ -16,24 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.openmeetings.web.util;
+package org.apache.openmeetings.web.user;
 
-import java.io.Serializable;
+import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.toolbar.DefaultWysiwygToolbar;
 
-import com.googlecode.wicket.jquery.core.JQueryBehavior;
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
-
-public abstract class NonClosableDialog<T extends Serializable> extends AbstractFormDialog<T> {
+public class OmWysiwygToolbar extends DefaultWysiwygToolbar {
 	private static final long serialVersionUID = 1L;
 
-	public NonClosableDialog(String id, String title) {
-		super(id, title);
-	}
-
-	@Override
-	public void onConfigure(JQueryBehavior behavior) {
-		super.onConfigure(behavior);
-		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("classes", "{'ui-dialog-titlebar': 'ui-corner-all no-close'}");
+	public OmWysiwygToolbar(String id) {
+		super(id);
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/UserInfoDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/UserInfoDialog.java
index 9787758..7d96cf0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/UserInfoDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/UserInfoDialog.java
@@ -33,6 +33,7 @@ import org.apache.wicket.spring.injection.annot.SpringBean;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
 
 public class UserInfoDialog extends Modal<String> {
 	private static final long serialVersionUID = 1L;
@@ -70,13 +71,7 @@ public class UserInfoDialog extends Modal<String> {
 				UserInfoDialog.this.close(target);
 			}
 		});
-		addButton(new BootstrapAjaxLink<>("button", Model.of(""), Buttons.Type.Outline_Secondary, new ResourceModel("lbl.cancel")) {
-			private static final long serialVersionUID = 1L;
-
-			public void onClick(AjaxRequestTarget target) {
-				UserInfoDialog.this.close(target);
-			}
-		});
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		add(container.add(new WebMarkupContainer("body")).setOutputMarkupId(true));
 		super.onInitialize();
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
index 75d0979..d1459d2 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
@@ -53,6 +53,7 @@ import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.GroupChoiceProvider;
 import org.apache.openmeetings.web.common.OmDateTimePicker;
 import org.apache.openmeetings.web.pages.MainPage;
+import org.apache.openmeetings.web.user.OmWysiwygToolbar;
 import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
 import org.apache.openmeetings.web.util.RoomTypeDropDown;
 import org.apache.openmeetings.web.util.UserMultiChoice;
@@ -88,7 +89,6 @@ import org.wicketstuff.select2.Select2MultiChoice;
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.ui.JQueryUIBehavior;
 import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.WysiwygEditor;
-import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.toolbar.DefaultWysiwygToolbar;
 import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
@@ -385,7 +385,7 @@ public class AppointmentDialog extends AbstractFormDialog<Appointment> {
 			rdi.add(new Radio<>("user", Model.of(InviteeType.user)));
 
 			add(new TextField<String>("location"));
-			DefaultWysiwygToolbar toolbar = new DefaultWysiwygToolbar("toolbarContainer");
+			OmWysiwygToolbar toolbar = new OmWysiwygToolbar("toolbarContainer");
 			add(toolbar);
 			add(new WysiwygEditor("description", toolbar));
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.html
index 1e157f9..c22f103 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.html
@@ -20,7 +20,7 @@
 -->
 <!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org">
-<wicket:panel>
+<wicket:extend>
 	<form wicket:id="form">
 		<div wicket:id="feedback" class="error"></div>
 		<table>
@@ -38,5 +38,5 @@
 			</tr>
 		</table>
 	</form>
-</wicket:panel>
+</wicket:extend>
 </html>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.java
index 73a0f28..db82206 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/ChangePasswordDialog.java
@@ -20,9 +20,6 @@ package org.apache.openmeetings.web.user.profile;
 
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
-import java.util.Arrays;
-import java.util.List;
-
 import org.apache.openmeetings.core.util.StrongPasswordValidator;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -35,16 +32,15 @@ import org.apache.wicket.util.string.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.spinner.SpinnerAjaxButton;
 
-public class ChangePasswordDialog extends AbstractFormDialog<String> {
+public class ChangePasswordDialog extends Modal<String> {
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = LoggerFactory.getLogger(ChangePasswordDialog.class);
-	private DialogButton update;
-	private DialogButton cancel;
 	private final PasswordTextField current = new PasswordTextField("current", Model.of((String)null));
 	private final PasswordTextField pass = new PasswordTextField("pass", Model.of((String)null));
 	private final PasswordTextField pass2 = new PasswordTextField("pass2", Model.of((String)null));
@@ -76,21 +72,35 @@ public class ChangePasswordDialog extends AbstractFormDialog<String> {
 	private UserDao userDao;
 
 	public ChangePasswordDialog(String id) {
-		super(id, "");
+		super(id);
 	}
 
 	@Override
 	protected void onInitialize() {
-		getTitle().setObject(getString("327"));
-		update = new DialogButton("update", new ResourceModel("327")) {
+		header(new ResourceModel("327"));
+		setCloseOnEscapeKey(true);
+		setBackdrop(Backdrop.STATIC);
+
+		addButton(new SpinnerAjaxButton("button", new ResourceModel("327"), form, Buttons.Type.Outline_Primary) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			public boolean isIndicating() {
-				return true;
+			protected void onError(AjaxRequestTarget target) {
+				target.add(feedback);
+			}
+
+			@Override
+			protected void onSubmit(AjaxRequestTarget target) {
+				try {
+					userDao.update(userDao.get(getUserId()), pass.getModelObject(), getUserId());
+					ChangePasswordDialog.this.close(target);
+				} catch (Exception e) {
+					error(e.getMessage());
+					target.add(feedback);
+				}
 			}
-		};
-		cancel = new DialogButton("cancel", new ResourceModel("lbl.cancel"));
+		}); //send
+		addButton(new ModalCloseButton(new ResourceModel("lbl.cancel")).type(Buttons.Type.Outline_Secondary));
 		passValidator = new StrongPasswordValidator(userDao.get(getUserId()));
 		add(form.add(
 				current.setLabel(new ResourceModel("current.password")).setRequired(true)
@@ -100,34 +110,4 @@ public class ChangePasswordDialog extends AbstractFormDialog<String> {
 				));
 		super.onInitialize();
 	}
-
-	@Override
-	protected List<DialogButton> getButtons() {
-		return Arrays.asList(update, cancel);
-	}
-
-	@Override
-	public DialogButton getSubmitButton() {
-		return update;
-	}
-
-	@Override
-	public Form<?> getForm() {
-		return form;
-	}
-
-	@Override
-	protected void onError(AjaxRequestTarget target, DialogButton btn) {
-		target.add(feedback);
-	}
-
-	@Override
-	protected void onSubmit(AjaxRequestTarget target, DialogButton btn) {
-		try {
-			userDao.update(userDao.get(getUserId()), pass.getModelObject(), getUserId());
-		} catch (Exception e) {
-			error(e.getMessage());
-			target.add(feedback);
-		}
-	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.html
index 4781bc5..9485f56 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.html
@@ -29,7 +29,7 @@
 					<legend class="">
 						<wicket:message key="143" />
 					</legend>
-					<button type="button" wicket:id="changePwd" id="changePwd"><wicket:message key="327"/></button>
+					<button type="button" wicket:id="changePwd" id="changePwd"></button>
 					<div class="formelement" wicket:enclosure="passwd">
 						<label class="col-3 text-right" wicket:for="passwd"><wicket:message key="current.password" /></label>
 						<input type="password" wicket:id="passwd" class="col-8"/>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.java
index 7493ecd..fcac50e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/EditProfileForm.java
@@ -19,7 +19,6 @@
 package org.apache.openmeetings.web.user.profile;
 
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
-import static org.apache.openmeetings.web.common.BasePanel.EVT_CLICK;
 
 import java.time.Duration;
 
@@ -32,10 +31,8 @@ import org.apache.openmeetings.web.common.FormActionsPanel;
 import org.apache.openmeetings.web.common.GeneralUserForm;
 import org.apache.openmeetings.web.common.UploadableProfileImagePanel;
 import org.apache.openmeetings.web.pages.PrivacyPage;
-import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormValidatingBehavior;
-import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.PasswordTextField;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
@@ -49,7 +46,8 @@ import org.apache.wicket.util.string.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.googlecode.wicket.jquery.ui.form.button.ButtonBehavior;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 
 public class EditProfileForm extends Form<User> {
 	private static final long serialVersionUID = 1L;
@@ -113,14 +111,14 @@ public class EditProfileForm extends Form<User> {
 				setResponsePage(Application.get().getSignInPageClass());
 			}
 		});
-		add(new WebMarkupContainer("changePwd").add(new ButtonBehavior("#changePwd"), new AjaxEventBehavior(EVT_CLICK) {
+		add(new BootstrapAjaxLink<>("changePwd", Model.of(""), Buttons.Type.Outline_Danger, new ResourceModel("327")) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			protected void onEvent(AjaxRequestTarget target) {
-				chPwdDlg.open(target);
+			public void onClick(AjaxRequestTarget target) {
+				chPwdDlg.show(target);
 			}
-		}).setVisible(checkPassword));
+		}.setVisible(checkPassword));
 		add(userForm);
 		add(new UploadableProfileImagePanel("img", getUserId()));
 		add(new ComunityUserForm("comunity", getModel()));
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html
index 3b5e1d9..4b7ee28 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html
@@ -34,7 +34,7 @@
 						<div class="email newdir clickable" wicket:id="newdir" wicket:message="title:1259"><wicket:message key="703"/></div>
 						<div wicket:id="folder">
 							<div wicket:id="name"></div>
-							<div class="delete" wicket:id="delete" wicket:message="title:1262"></div>
+							<a class="delete" wicket:id="delete" wicket:message="title:1262"></a>
 						</div>
 					</div>
 				</td>
@@ -115,8 +115,7 @@
 								></div><div wicket:id="decline" class="cross om-icon clickable" wicket:message="title:1191"
 								></div><div wicket:id="view" class="user om-icon clickable" wicket:message="title:1236"
 								></div><div wicket:id="message" class="new-email om-icon clickable" wicket:message="title:1253"
-								></div><div wicket:id="delete" class="cross om-icon clickable" wicket:message="title:1234"
-								></div></td>
+								></div><a wicket:id="delete" wicket:message="title:1234"></a></td>
 						</tr>
 					</table>
 				</td>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
index d181996..5bf1975 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
@@ -48,20 +48,18 @@ import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.PagedEntityListPanel;
 import org.apache.openmeetings.web.common.UserBasePanel;
-import org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.data.DataViewContainer;
 import org.apache.openmeetings.web.data.OmOrderByBorder;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
 import org.apache.openmeetings.web.user.MessageDialog;
 import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
+import org.apache.openmeetings.web.util.CallbackFunctionHelper;
 import org.apache.openmeetings.web.util.ContactsHelper;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
-import org.apache.wicket.ajax.attributes.AjaxRequestAttributes.EventPropagation;
 import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.head.IHeaderResponse;
@@ -83,6 +81,10 @@ import org.apache.wicket.spring.injection.annot.SpringBean;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType;
+
 public class MessagesContactsPanel extends UserBasePanel {
 	private static final long serialVersionUID = 1L;
 	private static final Long MOVE_CHOOSE = Long.valueOf(-1);
@@ -218,22 +220,20 @@ public class MessagesContactsPanel extends UserBasePanel {
 			@Override
 			protected void populateItem(final ListItem<PrivateMessageFolder> item) {
 				item.add(new Label("name", item.getModelObject().getFolderName()));
-				item.add(new ConfirmableAjaxBorder("delete", getString("80"), getString("833")) {
+				BootstrapAjaxLink<String> del = new BootstrapAjaxLink<>("delete", Buttons.Type.Outline_Danger) {
 					private static final long serialVersionUID = 1L;
 
 					@Override
-					protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
-						attributes.setEventPropagation(EventPropagation.STOP_IMMEDIATE);
-					}
-
-					@Override
-					protected void onSubmit(AjaxRequestTarget target) {
+					public void onClick(AjaxRequestTarget target) {
 						folderDao.delete(item.getModelObject(), getUserId());
 						foldersModel.setObject(folderDao.get(0, Integer.MAX_VALUE));
 						updateMoveModel();
 						target.add(folders, moveDropDown);
 					}
-				});
+				};
+				del.setIconType(FontAwesome5IconType.times_s)
+						.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+				item.add(del);
 				item.add(new AjaxEventBehavior(EVT_CLICK) {
 					private static final long serialVersionUID = 1L;
 
@@ -489,20 +489,18 @@ public class MessagesContactsPanel extends UserBasePanel {
 				}).setVisible(uc.isPending()));
 				item.add(new WebMarkupContainer("view").add(addOnClick(String.format("showUserInfo(%s);", userId))));
 				item.add(new WebMarkupContainer("message").add(addOnClick(String.format("privateMessage(%s);", userId))).setVisible(!uc.isPending()));
-				item.add(new ConfirmableAjaxBorder("delete", getString("80"), getString("833")) {
+				BootstrapAjaxLink<String> del = new BootstrapAjaxLink<>("delete", Buttons.Type.Outline_Danger) {
 					private static final long serialVersionUID = 1L;
 
 					@Override
-					protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
-						attributes.setEventPropagation(EventPropagation.STOP_IMMEDIATE);
-					}
-
-					@Override
-					protected void onSubmit(AjaxRequestTarget target) {
+					public void onClick(AjaxRequestTarget target) {
 						contactDao.delete(contactId);
 						updateContacts(target);
 					}
-				}.setVisible(!uc.isPending()));
+				};
+				del.setIconType(FontAwesome5IconType.times_s)
+						.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+				item.add(del.setVisible(!uc.isPending()));
 			}
 		};
 		updateContacts(null);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.html
index d69301e..da602ff 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.html
@@ -32,7 +32,7 @@
 				<div><wicket:message key="1178"/></div>
 				<input type="text" wicket:id="search"/><br/>
 				<br/>
-				<button wicket:id="submit" type="button"><wicket:message key="714"/></button>
+				<button wicket:id="submit" type="button"></button>
 			</form>
 		</div>
 		<div wicket:id="container" class="pl-3 h-100">
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
index 1e1f1d2..558af70 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
@@ -47,9 +47,11 @@ import org.apache.wicket.markup.repeater.data.IDataProvider;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
-import com.googlecode.wicket.jquery.ui.form.button.AjaxButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 
 public class UserSearchPanel extends UserBasePanel {
 	private static final long serialVersionUID = 1L;
@@ -78,7 +80,7 @@ public class UserSearchPanel extends UserBasePanel {
 			protected void onInitialize() {
 				super.onInitialize();
 				add(text, offer, search);
-				add(new AjaxButton("submit") {
+				add(new BootstrapAjaxButton("submit", new ResourceModel("714"), Buttons.Type.Outline_Primary) {
 					private static final long serialVersionUID = 1L;
 
 					@Override
diff --git a/openmeetings-web/src/main/webapp/css/raw-chat.css b/openmeetings-web/src/main/webapp/css/raw-chat.css
index 124d246..5507d0d 100644
--- a/openmeetings-web/src/main/webapp/css/raw-chat.css
+++ b/openmeetings-web/src/main/webapp/css/raw-chat.css
@@ -165,24 +165,24 @@ html[dir="rtl"] .main.room #chatPanel {
 .chat-msg-container {
 	position: relative;
 }
-.chat-toolbar .font-huge {
+.chat-toolbar .font-huge, .wysiwyg-toolbar .font-huge {
 	font-size: x-large;
 }
-.chat-toolbar .font-small {
+.chat-toolbar .font-small, .wysiwyg-toolbar .font-small {
 	font-size: small;
 }
-.chat-toolbar .font-tiny {
+.chat-toolbar .font-tiny, .wysiwyg-toolbar .font-tiny {
 	font-size: small;
 }
-.chat-toolbar .chat-btn.bold {
+.chat-toolbar .chat-btn.bold, .wysiwyg-toolbar .tool-btn.bold {
 	font-weight: bold;
 }
-.chat-toolbar .chat-btn.bold {
+.chat-toolbar .chat-btn.italic, .wysiwyg-toolbar .tool-btn.italic {
 	font-style: italic;
 }
-.chat-toolbar .chat-btn.strike {
+.chat-toolbar .chat-btn.strike, .wysiwyg-toolbar .tool-btn.strike {
 	text-decoration: line-through;
 }
-.chat-toolbar .chat-btn.under {
+.chat-toolbar .chat-btn.under, .wysiwyg-toolbar .tool-btn.under {
 	text-decoration: underline;
 }