初始化提交
This commit is contained in:
208
common/modules/mixly-modules/common/toolbox-searcher.js
Normal file
208
common/modules/mixly-modules/common/toolbox-searcher.js
Normal file
@@ -0,0 +1,208 @@
|
||||
goog.loadJs('common', () => {
|
||||
|
||||
goog.require('path');
|
||||
goog.require('Blockly');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.XML');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.HTMLTemplate');
|
||||
goog.require('Mixly.Debug');
|
||||
goog.provide('Mixly.ToolboxSearcher');
|
||||
|
||||
const {
|
||||
Env,
|
||||
XML,
|
||||
Msg,
|
||||
HTMLTemplate,
|
||||
Debug
|
||||
} = Mixly;
|
||||
|
||||
class ToolboxSearcher {
|
||||
static {
|
||||
this.searchHtmlTemplate = new HTMLTemplate(
|
||||
goog.get(path.join(Env.templatePath, 'html/search-div.html'))
|
||||
);
|
||||
}
|
||||
|
||||
constructor(mainWorkspace) {
|
||||
this.mainWorkspace = mainWorkspace;
|
||||
this.searchWorkspace = new Blockly.Workspace(new Blockly.Options({
|
||||
toolbox: null
|
||||
}));
|
||||
this.mainToolbox = this.mainWorkspace.getToolbox();
|
||||
this.$search = $(ToolboxSearcher.searchHtmlTemplate.render({
|
||||
search: Msg.Lang['toolboxSearcher.search']
|
||||
}));
|
||||
this.$i = this.$search.find('i');
|
||||
this.$input = this.$search.find('input');
|
||||
this.prevText = '';
|
||||
$(this.mainToolbox.HtmlDiv).append(this.$search);
|
||||
this.addEventsListener();
|
||||
}
|
||||
|
||||
addEventsListener() {
|
||||
this.$input.change(() => this.startSearch());
|
||||
this.$input.bind('input propertychange', (event) => {
|
||||
const searchCategory = this.mainToolbox.getToolboxItemById('catSearch');
|
||||
const keyText = event.target.value;
|
||||
if (!keyText.replaceAll(' ', '')) {
|
||||
searchCategory.hide();
|
||||
this.$i.addClass('disabled');
|
||||
return;
|
||||
} else {
|
||||
searchCategory.show();
|
||||
}
|
||||
this.scrollTop();
|
||||
if (keyText === this.prevText) {
|
||||
this.$i.addClass('disabled');
|
||||
} else {
|
||||
this.$i.removeClass('disabled');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
scrollTop() {
|
||||
const { HtmlDiv } = this.mainToolbox;
|
||||
$(HtmlDiv).scrollTop(HtmlDiv.scrollHeight);
|
||||
}
|
||||
|
||||
checkBlock(blockxml, keys) {
|
||||
this.searchWorkspace.clear();
|
||||
try {
|
||||
Blockly.Xml.domToBlock(blockxml, this.searchWorkspace);
|
||||
} catch (error) {
|
||||
Debug.error(error);
|
||||
return false;
|
||||
}
|
||||
const blocks = this.searchWorkspace.getAllBlocks(true);
|
||||
let select = false;
|
||||
for (let block of blocks) {
|
||||
const { inputList } = block;
|
||||
for (let input of inputList) {
|
||||
const { fieldRow } = input;
|
||||
for (let field of fieldRow) {
|
||||
const fieldText = field.getText().toLowerCase();
|
||||
let times = 0;
|
||||
for (let key = 0; key < keys.length; key++) {
|
||||
if (fieldText.indexOf(keys[key]) === -1) {
|
||||
continue;
|
||||
}
|
||||
times++;
|
||||
}
|
||||
if (keys.length === times) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
searchBlocks(keys) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const searchCategory = this.mainToolbox.getToolboxItemById('catSearch');
|
||||
let outputXML = [];
|
||||
let selectedBlocksLen = 0;
|
||||
const categories = this.mainToolbox.getToolboxItems();
|
||||
for (let j = 0; categories[j]; j++) {
|
||||
const category = categories[j];
|
||||
if (category.id_ === 'catSearch') continue;
|
||||
if (typeof category.getContents !== 'function') continue;
|
||||
const blocksList = category.getContents();
|
||||
let addLabel = true;
|
||||
for (let blockDef of blocksList) {
|
||||
const { type, kind, blockxml } = blockDef;
|
||||
if (kind !== 'BLOCK') {
|
||||
continue;
|
||||
}
|
||||
if (!this.checkBlock(blockxml, keys)) {
|
||||
continue;
|
||||
}
|
||||
if (addLabel) {
|
||||
const categoryPath = this.getCategoryPath(category);
|
||||
outputXML.push({
|
||||
kind: 'LABEL',
|
||||
text: categoryPath
|
||||
});
|
||||
addLabel = false;
|
||||
}
|
||||
outputXML.push(blockDef);
|
||||
selectedBlocksLen++;
|
||||
if (selectedBlocksLen > 30) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (selectedBlocksLen > 30) {
|
||||
outputXML.unshift({
|
||||
kind: 'LABEL',
|
||||
text: Msg.Lang['toolboxSearcher.tooManyResultsInfo']
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.searchWorkspace.clear();
|
||||
searchCategory.updateFlyoutContents(
|
||||
outputXML.length ?
|
||||
outputXML : [{
|
||||
kind: 'LABEL',
|
||||
text: Msg.Lang['toolboxSearcher.empty']
|
||||
}]
|
||||
);
|
||||
this.mainToolbox.refreshSelection();
|
||||
this.mainToolbox.setSelectedItem(searchCategory);
|
||||
const { selectedItem_ } = this.mainToolbox;
|
||||
if (selectedItem_ && selectedItem_.isCollapsible()) {
|
||||
selectedItem_.setExpanded(true);
|
||||
}
|
||||
this.scrollTop();
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
getCategoryPath(category) {
|
||||
let categoryPath = '';
|
||||
for (; category; category = category.getParent()) {
|
||||
categoryPath = category.toolboxItemDef_.name + (categoryPath && (' > ' + categoryPath));
|
||||
}
|
||||
return categoryPath;
|
||||
}
|
||||
|
||||
startSearch() {
|
||||
if (this.$i.hasClass('disabled')) {
|
||||
return
|
||||
};
|
||||
let text = this.$input.val();
|
||||
this.prevText = text;
|
||||
try {
|
||||
if (!text.replaceAll(' ', '')) {
|
||||
return;
|
||||
}
|
||||
} catch(error) {
|
||||
Debug.error(error);
|
||||
}
|
||||
this.$input.attr('disabled', true);
|
||||
this.$i.removeClass('codicon-search-fuzzy');
|
||||
this.$i.addClass('codicon-loading layui-anim-rotate layui-anim-loop');
|
||||
setTimeout(() => {
|
||||
let keys = text.toLowerCase().split(' ');
|
||||
this.searchBlocks(keys)
|
||||
.catch(Debug.error)
|
||||
.finally(() => {
|
||||
this.$i.removeClass('codicon-loading layui-anim-rotate layui-anim-loop');
|
||||
this.$i.addClass('codicon-search-fuzzy disabled');
|
||||
this.$input.removeAttr('disabled');
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
restart() {
|
||||
this.prevText = '';
|
||||
const searchCategory = this.mainToolbox.getToolboxItemById('catSearch');
|
||||
this.$input.val('');
|
||||
searchCategory.hide();
|
||||
}
|
||||
}
|
||||
|
||||
Mixly.ToolboxSearcher = ToolboxSearcher;
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user