464 lines
14 KiB
JavaScript
464 lines
14 KiB
JavaScript
goog.loadJs('common', () => {
|
|
|
|
goog.require('layui');
|
|
goog.require('$.select2');
|
|
goog.require('Mixly.Env');
|
|
goog.require('Mixly.XML');
|
|
goog.require('Mixly.Msg');
|
|
goog.require('Mixly.HTMLTemplate');
|
|
goog.require('Mixly.Component');
|
|
goog.require('Mixly.DropdownMenuGroup');
|
|
goog.provide('Mixly.Nav');
|
|
|
|
const {
|
|
Env,
|
|
XML,
|
|
Msg,
|
|
HTMLTemplate,
|
|
Component,
|
|
DropdownMenuGroup
|
|
} = Mixly;
|
|
|
|
const { element } = layui;
|
|
|
|
|
|
class Nav extends Component {
|
|
static {
|
|
/**
|
|
* nav容器html片段
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/nav.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/nav.html')))
|
|
);
|
|
|
|
/**
|
|
* nav按钮html片段
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/nav-btn.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/nav-btn.html')))
|
|
);
|
|
|
|
/**
|
|
* nav子元素容器html片段
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/nav-item-container.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/nav-item-container.html')))
|
|
);
|
|
|
|
/**
|
|
* nav子元素html片段
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/nav-item.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/nav-item.html')))
|
|
);
|
|
|
|
/**
|
|
* 板卡选择器html片段
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/board-selector-div.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/board-selector-div.html')))
|
|
);
|
|
|
|
/**
|
|
* 端口选择器html片段
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/port-selector-div.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/port-selector-div.html')))
|
|
);
|
|
|
|
/**
|
|
* 下拉菜单遮罩
|
|
* @type {String}
|
|
*/
|
|
HTMLTemplate.add(
|
|
'html/nav/shadow.html',
|
|
new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/nav/shadow.html')))
|
|
);
|
|
|
|
Nav.Scope = {
|
|
'LEFT': -1,
|
|
'CENTER': 0,
|
|
'RIGHT': 1,
|
|
'-1': 'LEFT',
|
|
'0': 'CENTER',
|
|
'1': 'RIGHT'
|
|
};
|
|
|
|
this.navs = [];
|
|
|
|
this.getAll = () => {
|
|
return this.navs;
|
|
}
|
|
|
|
this.add = (nav) => {
|
|
this.remove(nav);
|
|
this.navs.push(nav);
|
|
}
|
|
|
|
this.remove = (nav) => {
|
|
for (let i in this.workspaces) {
|
|
if (this.navs[i].id !== nav.id) {
|
|
continue;
|
|
}
|
|
this.navs.slice(i, 1);
|
|
}
|
|
}
|
|
|
|
this.getMain = () => {
|
|
if (this.navs.length) {
|
|
return this.navs[0];
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#$container_ = null;
|
|
#$leftBtnContainer_ = null;
|
|
#$leftBtnExtContainer_ = null;
|
|
#$rightBtnContainer_ = null;
|
|
#$dropdownContainer_ = null;
|
|
#$rightMenuContainer_ = null;
|
|
#$rightArea_ = null;
|
|
#$editorBtnsContainer_ = null;
|
|
#$boardSelect_ = null;
|
|
#$portSelect_ = null;
|
|
#$shadow_ = $(HTMLTemplate.get('html/nav/shadow.html').render());
|
|
#btns_ = [];
|
|
#rightDropdownMenuGroup_ = null;
|
|
|
|
constructor() {
|
|
super();
|
|
const navTemplate = HTMLTemplate.get('html/nav/nav.html');
|
|
this.setId(navTemplate.getId());
|
|
this.#$container_ = $(navTemplate.render({
|
|
more: Msg.Lang['nav.more']
|
|
}));
|
|
this.setContent(this.#$container_);
|
|
this.#$leftBtnContainer_ = this.#$container_.find('.left-btn-container');
|
|
this.#$leftBtnExtContainer_ = this.#$container_.find('.left-btn-ext-container');
|
|
this.#$rightBtnContainer_ = this.#$container_.find('.right-btn-container');
|
|
this.#$dropdownContainer_ = this.#$container_.find('.dropdown-container');
|
|
this.#$rightMenuContainer_ = this.#$container_.find('.right-menu-container');
|
|
this.#$rightArea_ = this.#$container_.find('.right-area');
|
|
this.#$editorBtnsContainer_ = this.#$container_.find('.editor-btn-container');
|
|
const boardSelectTemplate = HTMLTemplate.get('html/nav/board-selector-div.html');
|
|
this.#$boardSelect_ = $(boardSelectTemplate.render());
|
|
this.#$dropdownContainer_.append(this.#$boardSelect_);
|
|
this.#$boardSelect_.select2({
|
|
width: '150px',
|
|
minimumResultsForSearch: 10,
|
|
dropdownCssClass: `mixly-scrollbar mixly-${boardSelectTemplate.getId()}`,
|
|
dropdownAutoWidth: true,
|
|
placeholder: Msg.Lang['nav.selectBoard'],
|
|
language: Msg.nowLang
|
|
});
|
|
const portSelectTemplate = HTMLTemplate.get('html/nav/port-selector-div.html');
|
|
this.#$portSelect_ = $(portSelectTemplate.render());
|
|
this.#$dropdownContainer_.append(this.#$portSelect_);
|
|
this.#$portSelect_.select2({
|
|
width: '100px',
|
|
minimumResultsForSearch: Infinity,
|
|
dropdownCssClass: `mixly-scrollbar mixly-${portSelectTemplate.getId()}`,
|
|
dropdownAutoWidth: true,
|
|
placeholder: Msg.Lang['nav.selectPort']
|
|
});
|
|
const $merge = this.#$boardSelect_.add(this.#$portSelect_);
|
|
let count = 0;
|
|
$merge.on('select2:opening', (event) => {
|
|
count += 1;
|
|
$(document.body).append(this.#$shadow_);
|
|
});
|
|
$merge.on('select2:closing', () => {
|
|
count -= 1;
|
|
!count && this.#$shadow_.detach();
|
|
});
|
|
this.#$shadow_.click(() => $merge.select2('close'));
|
|
this.addEventsType(['changeBoard', 'changePort']);
|
|
this.#addEventsListener_();
|
|
this.#rightDropdownMenuGroup_ = new DropdownMenuGroup(this.#$rightMenuContainer_[0]);
|
|
Nav.add(this);
|
|
this.list = [];
|
|
}
|
|
|
|
onMounted() {
|
|
super.onMounted();
|
|
element.render('nav', 'nav-filter');
|
|
}
|
|
|
|
getEditorBtnsContainer() {
|
|
return this.#$editorBtnsContainer_;
|
|
}
|
|
|
|
getBoardSelector() {
|
|
return this.#$boardSelect_;
|
|
}
|
|
|
|
getPortSelector() {
|
|
return this.#$portSelect_;
|
|
}
|
|
|
|
getBoardName() {
|
|
return this.#$boardSelect_.find(':selected').text();
|
|
}
|
|
|
|
getBoardKey() {
|
|
return this.#$boardSelect_.val();
|
|
}
|
|
|
|
getPortName() {
|
|
return this.#$portSelect_.find(':selected').text();
|
|
}
|
|
|
|
getPortKey() {
|
|
return this.#$portSelect_.val();
|
|
}
|
|
|
|
/**
|
|
* @function 注册函数
|
|
* @param config 选项
|
|
* {
|
|
* icon: String,
|
|
* title: String,
|
|
* id: String | Array,
|
|
* displayText: String,
|
|
* preconditionFn: Function,
|
|
* callback: Function,
|
|
* scopeType: Nav.SCOPE_TYPE,
|
|
* weight: Number
|
|
* }
|
|
* @return {void}
|
|
**/
|
|
register(config) {
|
|
const { scopeType = Nav.ScopeType.LEFT } = config;
|
|
config = {
|
|
preconditionFn: () => true,
|
|
...config
|
|
};
|
|
const {
|
|
id = '',
|
|
title = '',
|
|
icon = '',
|
|
displayText = ''
|
|
} = config;
|
|
switch (scopeType) {
|
|
case Nav.Scope.LEFT:
|
|
config.$moreBtn = $(HTMLTemplate.get('html/nav/nav-item.html').render({
|
|
mId: id,
|
|
icon,
|
|
text: displayText
|
|
}));
|
|
case Nav.Scope.CENTER:
|
|
config.$btn = $(HTMLTemplate.get('html/nav/nav-btn.html').render({
|
|
title,
|
|
mId: id,
|
|
icon,
|
|
text: displayText
|
|
}));
|
|
break;
|
|
}
|
|
this.#add_(config);
|
|
return config;
|
|
}
|
|
|
|
#add_(config) {
|
|
const {
|
|
scopeType = Nav.ScopeType.LEFT,
|
|
id = ''
|
|
} = config;
|
|
switch (scopeType) {
|
|
case Nav.Scope.LEFT:
|
|
if (id === 'home-btn') {
|
|
this.#btns_[config.id] = config;
|
|
} else {
|
|
this.#addLeftBtn_(config);
|
|
}
|
|
break;
|
|
case Nav.Scope.CENTER:
|
|
this.#addCenterBtn_(config);
|
|
break;
|
|
case Nav.Scope.RIGHT:
|
|
this.#addRightBtn_(config);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @function 取消注册函数
|
|
* @param config 选项
|
|
* {
|
|
* id: String | Array,
|
|
* scopeType: Nav.SCOPE_TYPE
|
|
* }
|
|
* @return {void}
|
|
**/
|
|
unregister(config) {
|
|
|
|
}
|
|
|
|
#getElemWidth_(elem) {
|
|
const display = elem.css('display');
|
|
if (display !== 'none') {
|
|
return elem.outerWidth(true);
|
|
}
|
|
const visibility = elem.css('visibility');
|
|
const position = elem.css('position');
|
|
elem.css({
|
|
display: 'block',
|
|
visibility: 'hidden',
|
|
position: 'absolute'
|
|
});
|
|
const width = elem.outerWidth(true);
|
|
elem.css({ display, visibility, position });
|
|
return width;
|
|
}
|
|
|
|
#addEventsListener_() {
|
|
$(document).off('click', '.mixly-nav')
|
|
.on('click', '.mixly-nav', (event) => {
|
|
const mId = $(event.currentTarget).attr('m-id');
|
|
if (this.#btns_[mId]
|
|
&& typeof this.#btns_[mId].callback === 'function') {
|
|
this.#btns_[mId].callback(this);
|
|
}
|
|
});
|
|
|
|
this.#$boardSelect_.on('select2:select', (event) => {
|
|
const { data } = event.params;
|
|
this.runEvent('changeBoard', data);
|
|
});
|
|
|
|
this.#$portSelect_.on('select2:select', (event) => {
|
|
const { data } = event.params;
|
|
this.runEvent('changePort', data);
|
|
$('#mixly-footer-port-div').css('display', 'inline-flex');
|
|
$('#mixly-footer-port').html(data.id);
|
|
});
|
|
}
|
|
|
|
#addLeftBtn_(config) {
|
|
const { id = '', weight = 0 } = config;
|
|
if (Object.keys(this.#btns_).includes(id)) {
|
|
this.#btns_[id].$btn.remove();
|
|
this.#btns_[id].$moreBtn.remove();
|
|
delete this.#btns_[id];
|
|
}
|
|
let $btn = null;
|
|
let $moreBtn = null;
|
|
const $btns = this.#$leftBtnContainer_.children('button');
|
|
for (let i = 0; $btns[i]; i++) {
|
|
const mId = $($btns[i]).attr('m-id');
|
|
if (!this.#btns_[mId]) {
|
|
continue;
|
|
}
|
|
if (weight < this.#btns_[mId].weight) {
|
|
$btn = this.#btns_[mId].$btn;
|
|
$moreBtn = this.#btns_[mId].$moreBtn;
|
|
break;
|
|
}
|
|
}
|
|
if ($btn) {
|
|
$btn.before(config.$btn);
|
|
$moreBtn.before(config.$moreBtn);
|
|
} else {
|
|
this.#$leftBtnContainer_.append(config.$btn);
|
|
this.#$leftBtnExtContainer_.append(config.$moreBtn);
|
|
}
|
|
config.width = this.#getElemWidth_(config.$btn);
|
|
this.#btns_[id] = config;
|
|
this.resize();
|
|
}
|
|
|
|
#addCenterBtn_(config) {
|
|
const { id = '', weight = 0 } = config;
|
|
let $btn = null;
|
|
const $btns = this.#$rightBtnContainer_.children('button');
|
|
for (let i = 0; $btns[i]; i++) {
|
|
const mId = $($btns[i]).attr('m-id');
|
|
if (!this.#btns_[mId]) {
|
|
continue;
|
|
}
|
|
if (weight < this.#btns_[mId].weight) {
|
|
$btn = this.#btns_[mId].$btn;
|
|
break;
|
|
}
|
|
}
|
|
if ($btn) {
|
|
$btn.before(config.$btn);
|
|
} else {
|
|
this.#$rightBtnContainer_.append(config.$btn);
|
|
}
|
|
config.width = this.#getElemWidth_(config.$btn);
|
|
this.#btns_[id] = config;
|
|
this.resize();
|
|
}
|
|
|
|
#addRightBtn_(config) {
|
|
const { preconditionFn } = config;
|
|
if (!preconditionFn()) {
|
|
return;
|
|
}
|
|
this.#rightDropdownMenuGroup_.add(config);
|
|
this.resize();
|
|
}
|
|
|
|
resize() {
|
|
super.resize();
|
|
this.#$boardSelect_.select2('close');
|
|
this.#$portSelect_.select2('close');
|
|
const navRightWidth = this.#getElemWidth_(this.#$rightArea_);
|
|
const navWidth = this.#getElemWidth_(this.#$container_);
|
|
const $btns = this.#$leftBtnContainer_.children('button');
|
|
let nowWidth = navRightWidth;
|
|
let showMoreBtnContainer = false;
|
|
for (let i = 0; $btns[i]; i++) {
|
|
const mId = $($btns[i]).attr('m-id');
|
|
if (mId === 'home-btn') {
|
|
continue;
|
|
}
|
|
const config = this.#btns_[mId];
|
|
let newWidth = nowWidth;
|
|
if (config) {
|
|
const { preconditionFn } = config;
|
|
if (!preconditionFn()) {
|
|
config.$btn.css('display', 'none');
|
|
config.$moreBtn.css('display', 'none');
|
|
continue;
|
|
}
|
|
newWidth += config.width;
|
|
} else {
|
|
newWidth += this.#getElemWidth_($($btns[i]));
|
|
continue;
|
|
}
|
|
if (navWidth < newWidth + this.#$editorBtnsContainer_.outerWidth(true) + 130) {
|
|
config.$btn.css('display', 'none');
|
|
config.$moreBtn.css('display', 'block');
|
|
showMoreBtnContainer = true;
|
|
} else {
|
|
config.$btn.css('display', 'block');
|
|
config.$moreBtn.css('display', 'none');
|
|
nowWidth = newWidth;
|
|
}
|
|
}
|
|
if (navWidth < nowWidth + this.#$editorBtnsContainer_.outerWidth(true) + 130) {
|
|
showMoreBtnContainer = false;
|
|
}
|
|
const parent = this.#$leftBtnExtContainer_.parent();
|
|
parent.css('display', showMoreBtnContainer? 'block' : 'none');
|
|
}
|
|
}
|
|
|
|
Mixly.Nav = Nav;
|
|
|
|
}); |