DocumentServer/OfficeWeb/apps/common/main/lib/component/Button.js
2015-04-28 17:59:00 +03:00

315 lines
14 KiB
JavaScript

/*
* (c) Copyright Ascensio System SIA 2010-2015
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
if (Common === undefined) {
var Common = {};
}
define(["common/main/lib/component/BaseView", "common/main/lib/component/ToggleManager"], function () {
Common.UI.Button = Common.UI.BaseView.extend({
options: {
id: null,
hint: false,
enableToggle: false,
allowDepress: true,
toggleGroup: null,
cls: "",
iconCls: "",
caption: "",
menu: null,
disabled: false,
pressed: false,
split: false
},
template: _.template(["<% if (menu == null) { %>", '<button type="button" class="btn <%= cls %>" id="<%= id %>" style="<%= style %>">', '<span class="caption"><%= caption %></span>', '<% if (iconCls != "") { %>', '<span class="btn-icon <%= iconCls %>">&nbsp;</span>', "<% } %>", "</button>", "<% } else if (split == false) {%>", '<div class="btn-group" id="<%= id %>" style="<%= style %>">', '<button type="button" class="btn dropdown-toggle <%= cls %>" data-toggle="dropdown">', '<span class="caption"><%= caption %></span>', '<% if (iconCls != "") { %>', '<span class="btn-icon <%= iconCls %>">&nbsp;</span>', "<% } %>", '<span class="caret"></span>', "</button>", "</div>", "<% } else { %>", '<div class="btn-group split" id="<%= id %>" style="<%= style %>">', '<button type="button" class="btn <%= cls %>">', '<span class="caption"><%= caption %></span>', '<% if (iconCls != "") { %>', '<span class="btn-icon <%= iconCls %>">&nbsp;</span>', "<% } %>", "</button>", '<button type="button" class="btn <%= cls %> dropdown-toggle" data-toggle="dropdown">', '<span class="caret"></span>', '<span class="sr-only"></span>', "</button>", "</div>", "<% } %>"].join("")),
initialize: function (options) {
Common.UI.BaseView.prototype.initialize.call(this, options);
var me = this;
me.id = me.options.id || Common.UI.getId();
me.hint = me.options.hint;
me.enableToggle = me.options.enableToggle;
me.allowDepress = me.options.allowDepress;
me.cls = me.options.cls;
me.iconCls = me.options.iconCls;
me.menu = me.options.menu;
me.split = me.options.split;
me.toggleGroup = me.options.toggleGroup;
me.disabled = me.options.disabled;
me.pressed = me.options.pressed;
me.caption = me.options.caption;
me.template = me.options.template || me.template;
me.style = me.options.style;
me.rendered = false;
if (me.options.el) {
me.render();
}
},
render: function (parentEl) {
var me = this;
me.trigger("render:before", me);
me.cmpEl = $(me.el);
if (parentEl) {
me.setElement(parentEl, false);
if (!me.rendered) {
me.cmpEl = $(this.template({
id: me.id,
cls: me.cls,
iconCls: me.iconCls,
menu: me.menu,
split: me.split,
disabled: me.disabled,
pressed: me.pressed,
caption: me.caption,
style: me.style
}));
if (me.menu && _.isFunction(me.menu.render)) {
me.menu.render(me.cmpEl);
}
parentEl.html(me.cmpEl);
}
}
if (!me.rendered) {
var el = me.cmpEl,
isGroup = el.hasClass("btn-group"),
isSplit = el.hasClass("split");
if (me.options.hint) {
var modalParents = me.cmpEl.closest(".asc-window");
me.cmpEl.attr("data-toggle", "tooltip");
me.cmpEl.tooltip({
title: me.options.hint,
placement: me.options.hintAnchor || "cursor"
});
if (modalParents.length > 0) {
me.cmpEl.data("bs.tooltip").tip().css("z-index", parseInt(modalParents.css("z-index")) + 10);
}
}
if (_.isString(me.toggleGroup)) {
me.enableToggle = true;
}
var buttonHandler = function (e) {
if (!me.disabled && e.which == 1) {
me.doToggle();
if (me.options.hint) {
var tip = me.cmpEl.data("bs.tooltip");
if (tip) {
if (tip.dontShow === undefined) {
tip.dontShow = true;
}
tip.hide();
}
}
me.trigger("click", me, e);
}
};
var doSplitSelect = function (select, e) {
if (!select) {
var isUnderMouse = false;
_.each($("button", el), function (el) {
if ($(el).is(":hover")) {
isUnderMouse = true;
return false;
}
});
if (!isUnderMouse) {
el.removeClass("over");
$("button", el).removeClass("over");
}
}
if (!select && (me.enableToggle && me.allowDepress && me.pressed)) {
return;
}
if (select && !isSplit && (me.enableToggle && me.allowDepress && !me.pressed)) {
e.preventDefault();
return;
}
$("button:first", el).toggleClass("active", select);
$("[data-toggle^=dropdown]", el).toggleClass("active", select);
el.toggleClass("active", select);
};
var menuHandler = function (e) {
if (!me.disabled && e.which == 1) {
if (isSplit) {
if (me.options.hint) {
var tip = me.cmpEl.data("bs.tooltip");
if (tip) {
if (tip.dontShow === undefined) {
tip.dontShow = true;
}
tip.hide();
}
}
var isOpen = el.hasClass("open");
doSplitSelect(!isOpen, e);
}
}
};
var doSetActiveState = function (e, state) {
if (isSplit) {
doSplitSelect(state, e);
} else {
el.toggleClass("active", state);
$("button", el).toggleClass("active", state);
}
};
var onMouseDown = function (e) {
doSplitSelect(true, e);
$(document).on("mouseup", onMouseUp);
};
var onMouseUp = function (e) {
doSplitSelect(false, e);
$(document).off("mouseup", onMouseUp);
};
var onAfterHideMenu = function (e) {
me.cmpEl.find(".dropdown-toggle").blur();
};
if (isGroup) {
if (isSplit) {
$("[data-toggle^=dropdown]", el).on("mousedown", _.bind(menuHandler, this));
$("button", el).on("mousedown", _.bind(onMouseDown, this));
}
el.on("hide.bs.dropdown", _.bind(doSplitSelect, me, false));
el.on("show.bs.dropdown", _.bind(doSplitSelect, me, true));
el.on("hidden.bs.dropdown", _.bind(onAfterHideMenu, me));
$("button:first", el).on("click", buttonHandler);
} else {
el.on("click", buttonHandler);
}
el.on("button.internal.active", _.bind(doSetActiveState, me));
el.on("mouseover", function (e) {
if (!me.disabled) {
me.cmpEl.addClass("over");
me.trigger("mouseover", me, e);
}
});
el.on("mouseout", function (e) {
if (!me.disabled) {
me.cmpEl.removeClass("over");
me.trigger("mouseout", me, e);
}
});
Common.UI.ToggleManager.register(me);
}
me.rendered = true;
if (me.pressed) {
me.toggle(me.pressed, true);
}
if (me.disabled) {
me.setDisabled(me.disabled);
}
me.trigger("render:after", me);
return this;
},
doToggle: function () {
var me = this;
if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) {
me.toggle();
}
},
toggle: function (toggle, suppressEvent) {
var state = toggle === undefined ? !this.pressed : !!toggle;
this.pressed = state;
if (this.cmpEl) {
this.cmpEl.trigger("button.internal.active", [state]);
}
if (!suppressEvent) {
this.trigger("toggle", this, state);
}
},
isActive: function () {
if (this.enableToggle) {
return this.pressed;
}
return this.cmpEl.hasClass("active");
},
setDisabled: function (disabled) {
if (this.rendered) {
var el = this.cmpEl,
isGroup = el.hasClass("btn-group");
disabled = (disabled === true);
if (disabled !== el.hasClass("disabled")) {
var decorateBtn = function (button) {
button.toggleClass("disabled", disabled);
(disabled) ? button.attr({
disabled: disabled
}) : button.removeAttr("disabled");
};
decorateBtn(el);
isGroup && decorateBtn(el.children("button"));
}
if (disabled) {
var tip = this.cmpEl.data("bs.tooltip");
if (tip) {
tip.hide();
}
}
}
this.disabled = disabled;
},
isDisabled: function () {
return this.disabled;
},
setIconCls: function (cls) {
var btnIconEl = $(this.el).find("span.btn-icon"),
oldCls = this.iconCls;
this.iconCls = cls;
btnIconEl.removeClass(oldCls);
btnIconEl.addClass(cls || "");
},
setVisible: function (visible) {
this.cmpEl.toggleClass("hidden", !visible);
},
updateHint: function (hint) {
this.options.hint = hint;
var cmpEl = this.cmpEl,
modalParents = cmpEl.closest(".asc-window");
cmpEl.attr("data-toggle", "tooltip");
cmpEl.tooltip("destroy").tooltip({
title: hint,
placement: this.options.hintAnchor || "cursor"
});
if (modalParents.length > 0) {
cmpEl.data("bs.tooltip").tip().css("z-index", parseInt(modalParents.css("z-index")) + 10);
}
},
setCaption: function (caption) {
if (this.caption != caption) {
this.caption = caption;
if (this.rendered) {
var captionNode = this.cmpEl.find("button:first > .caption").andSelf().filter("button > .caption");
if (captionNode.length > 0) {
captionNode.text(caption);
} else {
this.cmpEl.find("button:first").andSelf().filter("button").text(caption);
}
}
}
}
});
});