merge: 合并master到develop
This commit is contained in:
@@ -41,10 +41,11 @@ class ContextMenu {
|
||||
}
|
||||
}
|
||||
|
||||
#selector_ = null;
|
||||
#menus_ = new Registry();
|
||||
#events_ = new Events(['getMenu']);
|
||||
constructor(selector, config = {}) {
|
||||
this.selector = selector;
|
||||
this.#selector_ = selector;
|
||||
this.menu = $.contextMenu({
|
||||
selector,
|
||||
build: ($trigger) => {
|
||||
@@ -67,20 +68,20 @@ class ContextMenu {
|
||||
return ContextMenu.generate(menu, $trigger, e);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
$.contextMenu('destroy', this.selector);
|
||||
this.#events_.reset();
|
||||
this.#menus_.reset();
|
||||
this.menu = null;
|
||||
this.selector = null;
|
||||
}
|
||||
|
||||
show() {
|
||||
$(this.selector).contextMenu();
|
||||
$(this.#selector_).contextMenu();
|
||||
}
|
||||
|
||||
hide() {
|
||||
$(this.selector).contextMenu('hide');
|
||||
$(this.#selector_).contextMenu('hide');
|
||||
}
|
||||
|
||||
dispose() {
|
||||
$.contextMenu('destroy', this.#selector_);
|
||||
this.#events_.reset();
|
||||
this.#menus_.reset();
|
||||
this.menu = null;
|
||||
this.#selector_ = null;
|
||||
}
|
||||
|
||||
bind(type, func) {
|
||||
|
||||
@@ -1,35 +1,66 @@
|
||||
goog.loadJs('common', () => {
|
||||
|
||||
goog.require('tippy');
|
||||
goog.require('Mixly.IdGenerator');
|
||||
goog.require('Mixly.ContextMenu');
|
||||
goog.provide('Mixly.DropdownMenu');
|
||||
|
||||
const { ContextMenu } = Mixly;
|
||||
const {
|
||||
IdGenerator,
|
||||
ContextMenu
|
||||
} = Mixly;
|
||||
|
||||
|
||||
class DropdownMenu extends ContextMenu {
|
||||
#contextMenu_ = null;
|
||||
#layer_ = null;
|
||||
static {
|
||||
this.$container = $('<div class="mixly-dropdown-menus"></div>');
|
||||
$(document.body).append(this.$container);
|
||||
}
|
||||
|
||||
#shown_ = false;
|
||||
constructor(selector) {
|
||||
#layer_ = null;
|
||||
#contextMenuId_ = '';
|
||||
#$contextMenuElem_ = null;
|
||||
constructor(elem) {
|
||||
const layer = tippy(elem, {
|
||||
allowHTML: true,
|
||||
content: '',
|
||||
trigger: 'click',
|
||||
interactive: true,
|
||||
maxWidth: 'none',
|
||||
offset: [0, 0],
|
||||
appendTo: document.body,
|
||||
arrow: false,
|
||||
placement: 'bottom-start',
|
||||
delay: 0,
|
||||
duration: [0, 0],
|
||||
onCreate: (instance) => {
|
||||
$(instance.popper).addClass('mixly-drapdown-menu');
|
||||
},
|
||||
onMount: () => {
|
||||
this.show();
|
||||
},
|
||||
onHide: () => {
|
||||
this.#shown_ && this.hide();
|
||||
}
|
||||
});
|
||||
|
||||
const contextMenuId = IdGenerator.generate();
|
||||
const selector = `body > .mixly-dropdown-menus > div[m-id="${contextMenuId}"]`;
|
||||
|
||||
super(selector, {
|
||||
trigger: 'none',
|
||||
appendTo: $(layer.popper).children().children(),
|
||||
zIndex: 1001,
|
||||
position: (opt) => {
|
||||
opt.$menu.css({
|
||||
top: 0,
|
||||
left: 0,
|
||||
position: 'relative',
|
||||
margin: 0
|
||||
});
|
||||
opt.$menu.css('margin', 0);
|
||||
},
|
||||
events: {
|
||||
show: (opt) => {
|
||||
opt.$menu.detach();
|
||||
$('body > .mixly-drapdown-menu > .tippy-box > .tippy-content').empty().append(opt.$menu);
|
||||
this.#layer_.setProps({});
|
||||
show: () => {
|
||||
this.#shown_ = true;
|
||||
this.#layer_.setProps({});
|
||||
},
|
||||
hide: (opt) => {
|
||||
hide: () => {
|
||||
this.#shown_ = false;
|
||||
if (this.#layer_.state.isShown) {
|
||||
this.#layer_.hide();
|
||||
@@ -38,33 +69,26 @@ class DropdownMenu extends ContextMenu {
|
||||
}
|
||||
});
|
||||
|
||||
this.#layer_ = tippy($(selector)[0], {
|
||||
allowHTML: true,
|
||||
content: '',
|
||||
trigger: 'click',
|
||||
interactive: true,
|
||||
maxWidth: 'none',
|
||||
offset: [ 0, 0 ],
|
||||
appendTo: document.body,
|
||||
arrow: false,
|
||||
placement: 'bottom-start',
|
||||
delay: 0,
|
||||
duration: [ 0, 0 ],
|
||||
onCreate: (instance) => {
|
||||
$(instance.popper).addClass('mixly-drapdown-menu');
|
||||
},
|
||||
onMount: (instance) => {
|
||||
this.show();
|
||||
},
|
||||
onHide: () => {
|
||||
this.#shown_ && this.hide();
|
||||
}
|
||||
});
|
||||
this.#$contextMenuElem_ = $(`<div m-id="${contextMenuId}"><div>`);
|
||||
DropdownMenu.$container.append(this.#$contextMenuElem_);
|
||||
this.#contextMenuId_ = contextMenuId;
|
||||
this.#layer_ = layer;
|
||||
}
|
||||
|
||||
show() {
|
||||
this.#$contextMenuElem_.contextMenu();
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.#$contextMenuElem_.contextMenu('hide');
|
||||
}
|
||||
|
||||
dispose() {
|
||||
super.dispose();
|
||||
this.#layer_.destroy();
|
||||
this.#layer_ = null;
|
||||
this.#$contextMenuElem_.remove();
|
||||
this.#$contextMenuElem_ = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class EditorBlockly extends EditorBase {
|
||||
this.initBlockly = () => {
|
||||
const DEFAULT_CATEGORIES = HTMLTemplate.get('xml/default-categories.xml').render();
|
||||
const media = path.join(Env.srcDirPath, 'common/media/blockly');
|
||||
const renderer = ['geras', 'zelos'].includes(USER.blockRenderer) ? USER.blockRenderer : 'geras';
|
||||
const renderer = ['geras', 'zelos', 'thrasos'].includes(USER.blockRenderer) ? USER.blockRenderer : 'geras';
|
||||
this.editor = Blockly.inject(this.$blockly[0], {
|
||||
media,
|
||||
toolbox: DEFAULT_CATEGORIES,
|
||||
|
||||
@@ -22,7 +22,7 @@ Env.hasSocketServer = false;
|
||||
Env.hasCompiler = false;
|
||||
|
||||
/**
|
||||
* 获取当前mixly2.0的路径
|
||||
* 获取当前mixly的路径
|
||||
* @type {String}
|
||||
*/
|
||||
Env.clientPath = null;
|
||||
|
||||
@@ -16,7 +16,8 @@ goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.API2');
|
||||
goog.require('Mixly.Electron.LibManager');
|
||||
goog.require('Mixly.Electron.File');
|
||||
goog.require('Mixly.WebSocket.Socket');
|
||||
goog.require('Mixly.WebCompiler.Loader');
|
||||
goog.require('Mixly.WebSocket.Loader');
|
||||
goog.provide('Mixly.Loader');
|
||||
|
||||
const {
|
||||
@@ -35,16 +36,20 @@ const {
|
||||
API2,
|
||||
Electron = {},
|
||||
Web = {},
|
||||
WebCompiler = {},
|
||||
WebSocket = {}
|
||||
} = Mixly;
|
||||
|
||||
const { LibManager, File } = goog.isElectron? Electron : Web;
|
||||
const { Socket } = WebSocket;
|
||||
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
if (!goog.isElectron && Env.hasSocketServer) {
|
||||
Socket.init();
|
||||
if (!goog.isElectron) {
|
||||
if (Env.hasSocketServer) {
|
||||
WebSocket.Loader.init();
|
||||
} else if (Env.hasCompiler) {
|
||||
WebCompiler.Loader.init();
|
||||
}
|
||||
}
|
||||
const app = new App($('body')[0]);
|
||||
Mixly.app = app;
|
||||
|
||||
@@ -7,9 +7,9 @@ goog.provide('Mixly.LocalStorage');
|
||||
const { MArray, LocalStorage } = Mixly;
|
||||
|
||||
LocalStorage.PATH = {
|
||||
USER: 'mixly2.0/user',
|
||||
BOARD: 'mixly2.0/boards/{{d.boardType}}/user',
|
||||
THIRD_PARTY: 'mixly2.0/boards/{{d.boardType}}/third_party/{{d.thirdPartyName}}'
|
||||
USER: 'mixly3.0/user',
|
||||
BOARD: 'mixly3.0/boards/{{d.boardType}}/user',
|
||||
THIRD_PARTY: 'mixly3.0/boards/{{d.boardType}}/third_party/{{d.thirdPartyName}}'
|
||||
};
|
||||
|
||||
LocalStorage.set = function (path, value) {
|
||||
|
||||
91
common/modules/mixly-modules/common/socket.js
Normal file
91
common/modules/mixly-modules/common/socket.js
Normal file
@@ -0,0 +1,91 @@
|
||||
goog.loadJs('common', () => {
|
||||
|
||||
goog.require('io');
|
||||
goog.require('Mixly');
|
||||
goog.provide('Mixly.Socket');
|
||||
|
||||
|
||||
class Socket {
|
||||
#socket_ = null;
|
||||
constructor(path, option) {
|
||||
this.#socket_ = io(path, option);
|
||||
}
|
||||
|
||||
#detectStatus_(status, callback) {
|
||||
window.setTimeout(() => {
|
||||
if (status.finished) {
|
||||
return;
|
||||
}
|
||||
if (this.isConnected()) {
|
||||
this.#detectStatus_(status, callback);
|
||||
} else {
|
||||
callback({
|
||||
error: 'socket is not connected'
|
||||
});
|
||||
status.finished = true;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
emit(eventName, ...args) {
|
||||
const callback = args.pop();
|
||||
if (this.isConnected()) {
|
||||
let emitStatus = {
|
||||
finished: false
|
||||
};
|
||||
let status = this.#socket_.emit(eventName, ...args, (...callbackArgs) => {
|
||||
if (emitStatus.finished) {
|
||||
return;
|
||||
}
|
||||
emitStatus.finished = true;
|
||||
callback(...callbackArgs);
|
||||
});
|
||||
this.#detectStatus_(emitStatus, callback);
|
||||
return status;
|
||||
} else {
|
||||
callback({
|
||||
error: 'socket is not connected'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async emitAsync(eventName, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.isConnected()) {
|
||||
const callback = (...callbackArgs) => {
|
||||
if (callbackArgs[0].error) {
|
||||
reject(callbackArgs[0].error);
|
||||
return;
|
||||
}
|
||||
resolve(...callbackArgs);
|
||||
}
|
||||
let emitStatus = {
|
||||
finished: false
|
||||
};
|
||||
let status = this.#socket_.emit(eventName, ...args, (...callbackArgs) => {
|
||||
if (emitStatus.finished) {
|
||||
return;
|
||||
}
|
||||
emitStatus.finished = true;
|
||||
callback(...callbackArgs);
|
||||
});
|
||||
this.#detectStatus_(emitStatus, callback);
|
||||
} else {
|
||||
reject('socket is not connected');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getSocket() {
|
||||
return this.#socket_;
|
||||
}
|
||||
|
||||
isConnected() {
|
||||
return this.#socket_?.connected;
|
||||
}
|
||||
}
|
||||
|
||||
Mixly.Socket = Socket;
|
||||
|
||||
});
|
||||
@@ -86,6 +86,7 @@ class StatusBarsManager extends PagesManager {
|
||||
|
||||
#shown_ = false;
|
||||
#dropdownMenu_ = null;
|
||||
#$dropdownBtn_ = null;
|
||||
|
||||
constructor(element) {
|
||||
const managerHTMLTemplate = HTMLTemplate.get('html/statusbar/statusbars-manager.html');
|
||||
@@ -103,6 +104,7 @@ class StatusBarsManager extends PagesManager {
|
||||
this.tabId = tabHTMLTemplate.id;
|
||||
this.id = IdGenerator.generate();
|
||||
this.addEventsType(['show', 'hide', 'onSelectMenu', 'getMenu']);
|
||||
this.#$dropdownBtn_ = $tab.find('.statusbar-dropdown-menu > button');
|
||||
$tab.find('.statusbar-close > button').click(() => this.hide());
|
||||
this.#addDropdownMenu_();
|
||||
this.#addEventsListener_();
|
||||
@@ -146,7 +148,6 @@ class StatusBarsManager extends PagesManager {
|
||||
}
|
||||
|
||||
#addDropdownMenu_() {
|
||||
const selector = `div[m-id="${this.tabId}"] > .statusbar-dropdown-menu > .layui-btn`;
|
||||
let menu = new Menu();
|
||||
let serialChildMenu = new Menu(true);
|
||||
menu.add({
|
||||
@@ -240,7 +241,7 @@ class StatusBarsManager extends PagesManager {
|
||||
}
|
||||
return result;
|
||||
});
|
||||
this.#dropdownMenu_ = new DropdownMenu(selector);
|
||||
this.#dropdownMenu_ = new DropdownMenu(this.#$dropdownBtn_[0]);
|
||||
this.#dropdownMenu_.register('menu', menu);
|
||||
this.#dropdownMenu_.bind('getMenu', () => 'menu');
|
||||
}
|
||||
@@ -278,6 +279,9 @@ class StatusBarsManager extends PagesManager {
|
||||
|
||||
dispose() {
|
||||
StatusBarsManager.remove(this);
|
||||
this.#dropdownMenu_.dispose();
|
||||
this.#$dropdownBtn_.remove();
|
||||
this.#$dropdownBtn_ = null;
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user