mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 07:01:31 +08:00 
			
		
		
		
	added in-editor help for editing attributes
This commit is contained in:
		
							parent
							
								
									0533b95562
								
							
						
					
					
						commit
						ed6181a85e
					
				@ -1,51 +1,56 @@
 | 
				
			|||||||
import attributeParser from '../src/public/app/services/attribute_parser.js';
 | 
					import attributeParser from '../src/public/app/services/attribute_parser.js';
 | 
				
			||||||
import {describe, it, expect, execute} from './mini_test.js';
 | 
					import {describe, it, expect, execute} from './mini_test.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("Lexer", () => {
 | 
					describe("Lexing", () => {
 | 
				
			||||||
    it("simple label", () => {
 | 
					    it("simple label", () => {
 | 
				
			||||||
        expect(attributeParser.lexer("#label").map(t => t.text))
 | 
					        expect(attributeParser.lex("#label").map(t => t.text))
 | 
				
			||||||
 | 
					            .toEqual(["#label"]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it("simple label with trailing spaces", () => {
 | 
				
			||||||
 | 
					        expect(attributeParser.lex("   #label  ").map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label"]);
 | 
					            .toEqual(["#label"]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("inherited label", () => {
 | 
					    it("inherited label", () => {
 | 
				
			||||||
        expect(attributeParser.lexer("#label(inheritable)").map(t => t.text))
 | 
					        expect(attributeParser.lex("#label(inheritable)").map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label", "(", "inheritable", ")"]);
 | 
					            .toEqual(["#label", "(", "inheritable", ")"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attributeParser.lexer("#label ( inheritable ) ").map(t => t.text))
 | 
					        expect(attributeParser.lex("#label ( inheritable ) ").map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label", "(", "inheritable", ")"]);
 | 
					            .toEqual(["#label", "(", "inheritable", ")"]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("label with value", () => {
 | 
					    it("label with value", () => {
 | 
				
			||||||
        expect(attributeParser.lexer("#label=Hallo").map(t => t.text))
 | 
					        expect(attributeParser.lex("#label=Hallo").map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label", "=", "Hallo"]);
 | 
					            .toEqual(["#label", "=", "Hallo"]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("label with value", () => {
 | 
					    it("label with value", () => {
 | 
				
			||||||
        const tokens = attributeParser.lexer("#label=Hallo");
 | 
					        const tokens = attributeParser.lex("#label=Hallo");
 | 
				
			||||||
        expect(tokens[0].startIndex).toEqual(0);
 | 
					        expect(tokens[0].startIndex).toEqual(0);
 | 
				
			||||||
        expect(tokens[0].endIndex).toEqual(5);
 | 
					        expect(tokens[0].endIndex).toEqual(5);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("relation with value", () => {
 | 
					    it("relation with value", () => {
 | 
				
			||||||
        expect(attributeParser.lexer('~relation=#root/RclIpMauTOKS/NFi2gL4xtPxM').map(t => t.text))
 | 
					        expect(attributeParser.lex('~relation=#root/RclIpMauTOKS/NFi2gL4xtPxM').map(t => t.text))
 | 
				
			||||||
            .toEqual(["~relation", "=", "#root/RclIpMauTOKS/NFi2gL4xtPxM"]);
 | 
					            .toEqual(["~relation", "=", "#root/RclIpMauTOKS/NFi2gL4xtPxM"]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("use quotes to define value", () => {
 | 
					    it("use quotes to define value", () => {
 | 
				
			||||||
        expect(attributeParser.lexer("#'label a'='hello\"` world'").map(t => t.text))
 | 
					        expect(attributeParser.lex("#'label a'='hello\"` world'").map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label a", "=", 'hello"` world']);
 | 
					            .toEqual(["#label a", "=", 'hello"` world']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attributeParser.lexer('#"label a" = "hello\'` world"').map(t => t.text))
 | 
					        expect(attributeParser.lex('#"label a" = "hello\'` world"').map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label a", "=", "hello'` world"]);
 | 
					            .toEqual(["#label a", "=", "hello'` world"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attributeParser.lexer('#`label a` = `hello\'" world`').map(t => t.text))
 | 
					        expect(attributeParser.lex('#`label a` = `hello\'" world`').map(t => t.text))
 | 
				
			||||||
            .toEqual(["#label a", "=", "hello'\" world"]);
 | 
					            .toEqual(["#label a", "=", "hello'\" world"]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("Parser", () => {
 | 
					describe("Parser", () => {
 | 
				
			||||||
    it("simple label", () => {
 | 
					    it("simple label", () => {
 | 
				
			||||||
        const attrs = attributeParser.parser(["#token"].map(t => ({text: t})));
 | 
					        const attrs = attributeParser.parse(["#token"].map(t => ({text: t})));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attrs.length).toEqual(1);
 | 
					        expect(attrs.length).toEqual(1);
 | 
				
			||||||
        expect(attrs[0].type).toEqual('label');
 | 
					        expect(attrs[0].type).toEqual('label');
 | 
				
			||||||
@ -55,7 +60,7 @@ describe("Parser", () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("inherited label", () => {
 | 
					    it("inherited label", () => {
 | 
				
			||||||
        const attrs = attributeParser.parser(["#token", "(", "inheritable", ")"].map(t => ({text: t})));
 | 
					        const attrs = attributeParser.parse(["#token", "(", "inheritable", ")"].map(t => ({text: t})));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attrs.length).toEqual(1);
 | 
					        expect(attrs.length).toEqual(1);
 | 
				
			||||||
        expect(attrs[0].type).toEqual('label');
 | 
					        expect(attrs[0].type).toEqual('label');
 | 
				
			||||||
@ -65,7 +70,7 @@ describe("Parser", () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("label with value", () => {
 | 
					    it("label with value", () => {
 | 
				
			||||||
        const attrs = attributeParser.parser(["#token", "=", "val"].map(t => ({text: t})));
 | 
					        const attrs = attributeParser.parse(["#token", "=", "val"].map(t => ({text: t})));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attrs.length).toEqual(1);
 | 
					        expect(attrs.length).toEqual(1);
 | 
				
			||||||
        expect(attrs[0].type).toEqual('label');
 | 
					        expect(attrs[0].type).toEqual('label');
 | 
				
			||||||
@ -74,14 +79,14 @@ describe("Parser", () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("relation", () => {
 | 
					    it("relation", () => {
 | 
				
			||||||
        let attrs = attributeParser.parser(["~token", "=", "#root/RclIpMauTOKS/NFi2gL4xtPxM"].map(t => ({text: t})));
 | 
					        let attrs = attributeParser.parse(["~token", "=", "#root/RclIpMauTOKS/NFi2gL4xtPxM"].map(t => ({text: t})));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attrs.length).toEqual(1);
 | 
					        expect(attrs.length).toEqual(1);
 | 
				
			||||||
        expect(attrs[0].type).toEqual('relation');
 | 
					        expect(attrs[0].type).toEqual('relation');
 | 
				
			||||||
        expect(attrs[0].name).toEqual("token");
 | 
					        expect(attrs[0].name).toEqual("token");
 | 
				
			||||||
        expect(attrs[0].value).toEqual('NFi2gL4xtPxM');
 | 
					        expect(attrs[0].value).toEqual('NFi2gL4xtPxM');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        attrs = attributeParser.parser(["~token", "=", "#NFi2gL4xtPxM"].map(t => ({text: t})));
 | 
					        attrs = attributeParser.parse(["~token", "=", "#NFi2gL4xtPxM"].map(t => ({text: t})));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(attrs.length).toEqual(1);
 | 
					        expect(attrs.length).toEqual(1);
 | 
				
			||||||
        expect(attrs[0].type).toEqual('relation');
 | 
					        expect(attrs[0].type).toEqual('relation');
 | 
				
			||||||
@ -97,6 +102,9 @@ describe("error cases", () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        expect(() => attributeParser.lexAndParse("#a&b/s"))
 | 
					        expect(() => attributeParser.lexAndParse("#a&b/s"))
 | 
				
			||||||
            .toThrow(`Attribute name "a&b/s" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`);
 | 
					            .toThrow(`Attribute name "a&b/s" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(() => attributeParser.lexAndParse("#"))
 | 
				
			||||||
 | 
					            .toThrow(`Attribute name is empty, please fill the name.`);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
function lexer(str) {
 | 
					function lex(str) {
 | 
				
			||||||
 | 
					    str = str.trim();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const tokens = [];
 | 
					    const tokens = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let quotes = false;
 | 
					    let quotes = false;
 | 
				
			||||||
@ -106,12 +108,16 @@ function lexer(str) {
 | 
				
			|||||||
const attrNameMatcher = new RegExp("^[\\p{L}\\p{N}_:]+$", "u");
 | 
					const attrNameMatcher = new RegExp("^[\\p{L}\\p{N}_:]+$", "u");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function checkAttributeName(attrName) {
 | 
					function checkAttributeName(attrName) {
 | 
				
			||||||
 | 
					    if (attrName.length === 0) {
 | 
				
			||||||
 | 
					        throw new Error("Attribute name is empty, please fill the name.");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!attrNameMatcher.test(attrName)) {
 | 
					    if (!attrNameMatcher.test(attrName)) {
 | 
				
			||||||
        throw new Error(`Attribute name "${attrName}" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`);
 | 
					        throw new Error(`Attribute name "${attrName}" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function parser(tokens, str, allowEmptyRelations = false) {
 | 
					function parse(tokens, str, allowEmptyRelations = false) {
 | 
				
			||||||
    const attrs = [];
 | 
					    const attrs = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function context(i) {
 | 
					    function context(i) {
 | 
				
			||||||
@ -213,13 +219,13 @@ function parser(tokens, str, allowEmptyRelations = false) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function lexAndParse(str, allowEmptyRelations = false) {
 | 
					function lexAndParse(str, allowEmptyRelations = false) {
 | 
				
			||||||
    const tokens = lexer(str);
 | 
					    const tokens = lex(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return parser(tokens, str, allowEmptyRelations);
 | 
					    return parse(tokens, str, allowEmptyRelations);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    lexer,
 | 
					    lex,
 | 
				
			||||||
    parser,
 | 
					    parse,
 | 
				
			||||||
    lexAndParse
 | 
					    lexAndParse
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@ function renderAttribute(attribute, $container, renderIsInheritable) {
 | 
				
			|||||||
            $container.append(document.createTextNode(formatValue(attribute.value)));
 | 
					            $container.append(document.createTextNode(formatValue(attribute.value)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $container.append(' ');
 | 
					        $container.append(" ");
 | 
				
			||||||
    } else if (attribute.type === 'relation') {
 | 
					    } else if (attribute.type === 'relation') {
 | 
				
			||||||
        if (attribute.isAutoLink) {
 | 
					        if (attribute.isAutoLink) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
@ -20,7 +20,7 @@ function renderAttribute(attribute, $container, renderIsInheritable) {
 | 
				
			|||||||
        if (attribute.value) {
 | 
					        if (attribute.value) {
 | 
				
			||||||
            $container.append(document.createTextNode('~' + attribute.name + isInheritable + "="));
 | 
					            $container.append(document.createTextNode('~' + attribute.name + isInheritable + "="));
 | 
				
			||||||
            $container.append(createNoteLink(attribute.value));
 | 
					            $container.append(createNoteLink(attribute.value));
 | 
				
			||||||
            $container.append(" ");
 | 
					            $container.append(" ");
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            ws.logError(`Relation ${attribute.attributeId} has empty target`);
 | 
					            ws.logError(`Relation ${attribute.attributeId} has empty target`);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -34,12 +34,12 @@ function setupGlobs() {
 | 
				
			|||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
    <ul>
 | 
					    <ul>
 | 
				
			||||||
        <li>Just enter any text for full text search</li>
 | 
					        <li>Just enter any text for full text search</li>
 | 
				
			||||||
        <li><code>@abc</code> - returns notes with label abc</li>
 | 
					        <li><code>#abc</code> - returns notes with label abc</li>
 | 
				
			||||||
        <li><code>@year=2019</code> - matches notes with label <code>year</code> having value <code>2019</code></li>
 | 
					        <li><code>#year = 2019</code> - matches notes with label <code>year</code> having value <code>2019</code></li>
 | 
				
			||||||
        <li><code>@rock @pop</code> - matches notes which have both <code>rock</code> and <code>pop</code> labels</li>
 | 
					        <li><code>#rock #pop</code> - matches notes which have both <code>rock</code> and <code>pop</code> labels</li>
 | 
				
			||||||
        <li><code>@rock or @pop</code> - only one of the labels must be present</li>
 | 
					        <li><code>#rock or #pop</code> - only one of the labels must be present</li>
 | 
				
			||||||
        <li><code>@year<=2000</code> - numerical comparison (also >, >=, <).</li>
 | 
					        <li><code>#year <= 2000</code> - numerical comparison (also >, >=, <).</li>
 | 
				
			||||||
        <li><code>@dateCreated>=MONTH-1</code> - notes created in the last month</li>
 | 
					        <li><code>note.dateCreated >= MONTH-1</code> - notes created in the last month</li>
 | 
				
			||||||
        <li><code>=handler</code> - will execute script defined in <code>handler</code> relation to get results</li>
 | 
					        <li><code>=handler</code> - will execute script defined in <code>handler</code> relation to get results</li>
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    </p>`;
 | 
					    </p>`;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,13 @@ import libraryLoader from "../services/library_loader.js";
 | 
				
			|||||||
import treeCache from "../services/tree_cache.js";
 | 
					import treeCache from "../services/tree_cache.js";
 | 
				
			||||||
import attributeRenderer from "../services/attribute_renderer.js";
 | 
					import attributeRenderer from "../services/attribute_renderer.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const HELP_TEXT = `
 | 
				
			||||||
 | 
					<p>To add label, just type e.g. <code>#rock</code> or if you want to add also value then e.g. <code>#year = 2020</code></p> 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>For relation, type <code>~author = @</code> which should bring up an autocomplete where you can look up the desired note.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>Alternatively you can add label and relation using the <code>+</code> button on the right side.</p>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TPL = `
 | 
					const TPL = `
 | 
				
			||||||
<div style="position: relative">
 | 
					<div style="position: relative">
 | 
				
			||||||
    <style>
 | 
					    <style>
 | 
				
			||||||
@ -170,7 +177,7 @@ const editorConfig = {
 | 
				
			|||||||
    toolbar: {
 | 
					    toolbar: {
 | 
				
			||||||
        items: []
 | 
					        items: []
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    placeholder: "Type the labels and relations here, e.g. #year=2020",
 | 
					    placeholder: "Type the labels and relations here",
 | 
				
			||||||
    mention: mentionSetup
 | 
					    mention: mentionSetup
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -339,10 +346,10 @@ export default class AttributeEditorWidget extends TabAwareWidget {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async handleEditorClick(e) {console.log("click")
 | 
					    async handleEditorClick(e) {
 | 
				
			||||||
        const pos = this.textEditor.model.document.selection.getFirstPosition();
 | 
					        const pos = this.textEditor.model.document.selection.getFirstPosition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (pos && pos.textNode && pos.textNode.data) {console.log(pos);
 | 
					        if (pos && pos.textNode && pos.textNode.data) {
 | 
				
			||||||
            const clickIndex = this.getClickIndex(pos);
 | 
					            const clickIndex = this.getClickIndex(pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let parsedAttrs;
 | 
					            let parsedAttrs;
 | 
				
			||||||
@ -350,7 +357,7 @@ export default class AttributeEditorWidget extends TabAwareWidget {
 | 
				
			|||||||
            try {
 | 
					            try {
 | 
				
			||||||
                parsedAttrs = attributesParser.lexAndParse(this.getPreprocessedData(), true);
 | 
					                parsedAttrs = attributesParser.lexAndParse(this.getPreprocessedData(), true);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (e) {console.log(e);
 | 
					            catch (e) {
 | 
				
			||||||
                // the input is incorrect because user messed up with it and now needs to fix it manually
 | 
					                // the input is incorrect because user messed up with it and now needs to fix it manually
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -365,6 +372,9 @@ export default class AttributeEditorWidget extends TabAwareWidget {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            setTimeout(() => {
 | 
					            setTimeout(() => {
 | 
				
			||||||
 | 
					                if (matchedAttr) {
 | 
				
			||||||
 | 
					                    this.$editor.tooltip('hide');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    this.attributeDetailWidget.showAttributeDetail({
 | 
					                    this.attributeDetailWidget.showAttributeDetail({
 | 
				
			||||||
                        allAttributes: parsedAttrs,
 | 
					                        allAttributes: parsedAttrs,
 | 
				
			||||||
                        attribute: matchedAttr,
 | 
					                        attribute: matchedAttr,
 | 
				
			||||||
@ -372,8 +382,27 @@ export default class AttributeEditorWidget extends TabAwareWidget {
 | 
				
			|||||||
                        x: e.pageX,
 | 
					                        x: e.pageX,
 | 
				
			||||||
                        y: e.pageY
 | 
					                        y: e.pageY
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    this.showHelpTooltip();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }, 100);
 | 
					            }, 100);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            this.showHelpTooltip();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showHelpTooltip() {console.log("showHelpTooltip");
 | 
				
			||||||
 | 
					        this.attributeDetailWidget.hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.$editor.tooltip({
 | 
				
			||||||
 | 
					            trigger: 'focus',
 | 
				
			||||||
 | 
					            html: true,
 | 
				
			||||||
 | 
					            title: HELP_TEXT,
 | 
				
			||||||
 | 
					            placement: 'bottom',
 | 
				
			||||||
 | 
					            offset: "0,20"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getClickIndex(pos) {
 | 
					    getClickIndex(pos) {
 | 
				
			||||||
@ -436,8 +465,13 @@ export default class AttributeEditorWidget extends TabAwareWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async focusOnAttributesEvent({tabId}) {
 | 
					    async focusOnAttributesEvent({tabId}) {
 | 
				
			||||||
        if (this.tabContext.tabId === tabId) {
 | 
					        if (this.tabContext.tabId === tabId) {
 | 
				
			||||||
 | 
					            if (this.$editor.is(":visible")) {
 | 
				
			||||||
                this.$editor.trigger('focus');
 | 
					                this.$editor.trigger('focus');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                this.triggerCommand('focusOnDetail', {tabId: this.tabContext.tabId});
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateAttributeList(attributes) {
 | 
					    updateAttributeList(attributes) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user