UI
const PcToolbarButtonConfig = ['undo', 'redo', 'format', 'clear-format'];
const PcFullToolbarButtonConfig = ['undo', 'redo'];
const PcShortToolbarButtonConfig = ['undo'];
const PcShortToolbarButtonReadonlyConfig = ['undo', 'redo', 'format'];
switch (true) {
case window.innerWidth < 1440 && window.innerWidth >= 855:
if (isMore) null;
return canEdit ? PcToolbarButtonConfig : PcToolbarButtonReadonlyConfig;
case window.innerWidth < 855:
if (isMore) null;
return canEdit ? PcShortToolbarButtonConfig : PcShortToolbarButtonReadonlyConfig;
}
return canEdit ? PcFullToolbarButtonConfig : PcFullToolbarButtonReadonlyConfig;
Vscode Vscode Vscode package.json
contributes
"contributes": {
"menus": {
"editor/title": [
{
"when": "resourceLangId == markdown",
"command": "markdown.showPreview",
"alt": "markdown.showPreviewToSide",
"group": "navigation"
}
]
}
}
when markdown
Vscode
Vscode UIVscode ExtensionsRegistry
ExtensionsRegistry.registerExtensionPoint
menus
setHandler
ExtensionsRegistry.getExtensionPoints
package.json
setHandler
contributes
menu
MenuRegistry
ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyMenuItem[] }>({
extensionPoint: 'menus',
jsonSchema: schema.menusContribution
}).setHandler(extensions => {
for (const extension of extensions) {
const { value } = extension;
for (const command of value) {
MenuRegistry.addCommands(command);
}
}
})
Vscode ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'toolbars' }).setHandler(callback)
toolbars
ExtensionsRegistry.getExtensionPoints
contributes
toolbars
ToolbarRegistry
ToolbarRegistry
Vscode
jsonSchema
export namespace jsonSchema {
export function isValidCommand(command: IUserFriendlyCommand, collector: ExtensionMessageCollector): boolean {
if (!command) {
collector.error(localize('nonempty', "expected non-empty value."));
return false;
}
if (typeof command.command !== 'string') {
collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'command'));
return false;
}
}
JSON
switch (true) {
case window.innerWidth < 1440 && window.innerWidth >= 855:
if (isMore) null;
return canEdit ? PcToolbarButtonConfig : PcToolbarButtonReadonlyConfig;
case window.innerWidth < 855:
if (isMore) null;
return canEdit ? PcShortToolbarButtonConfig : PcShortToolbarButtonReadonlyConfig;
}
"contributes": {
"toolbars": [
{
"command": "undo",
"component": "Redobutton",
"icon": "undo",
"when": "canEdit == true && window.innerWidth < 1080 && window.innerWidth >= 855"
},
{
"command": "redo",
"icon": "redo",
"when": "platform == pc && window.innerWidth < 855 && isMore == true"
}
]
}
UI
"when": "canEdit == true && window.innerWidth < 1080 && window.innerWidth >= 855"
**Vscode UI **
when: xxx
Vscode ****
Vscode Vscode
<>=<=
"when": "canEdit == true && window.innerWidth < 1080 && window.innerWidth >= 855"
deserialize
"when": "canEdit == true || platform == pc && window.innerWidth >= 1080"
==&&>=
indexOf
split
keytype value canEdit == true
key value
private static deserialize(serializedOne: string, strict: boolean): ContextKeyExpression {
if (serializedOne.indexOf('>=') >= 0) {
let pieces = serializedOne.split('>=');
return ContextKeyGreaterOrEqualsExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
}
if (serializedOne.indexOf('<') >= 0) {
let pieces = serializedOne.split('<');
return ContextKeyLessExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
}
return ContextKeyDefinedExpr.create(serializedOne);
}
when type
ContextKey | Type | ContextKey | Type |
---|---|---|---|
False | 0 | Regex | 7 |
True | 1 | NotRegex | 8 |
Defined | 2 | Or | 9 |
Not | 3 | Greater | 10 |
Equals | 4 | Less | 11 |
NotEquals | 5 | GreaterOrEquals | 12 |
And | 6 | LessOrEquals | 13 |
||
&&
||
&&
!=``==
>=
when
ContextKey-Type
JS ContextKeyOrExprContextKeyAndExprContextKeyEqualsExpr ContextKeyGreaterOrEqualsExpr JS MenuRegistry MenuRegistry key value type
when: {
ContextKeyOrExpr: {
expr: [{
ContextKeyDefinedExpr: {
key: "canEdit",
type: 2
}
}, {
ContextKeyAndExpr: {
expr: [{
ContextKeyEqualsExpr: {
key: "platform",
type: 4,
value: "pc",
},
ContextKeyGreaterOrEqualsExpr: {
key: "window.innerWidth",
type: 12,
value: "1080",
}
}],
type: 6
}
}],
type: 9
}
}
key "window.innerWidth"
canEdit
"platform"
key key Vscode Vscode context setValue
getValue
class Context {
private readonly _values = new Map<string, any>();
getValue(key: string): any {
if (this._values.has(key)) {
return this._values.get(key);
}
}
setValue(key: string, value: any) {
this._values.set(key, value);
}
}
Map "window.innerWidth"``canEdit
"platform"
key Vscode id key
const context = new Context();
context.setValue('platform', 'pc');
context.setValue('window.innerWidth', window.innerWidth);
context.setValue('canEdit', window.SpreadsheetApp.sheetStatus.rangesStatus.status.canEdit);
key key
contextMatchesRules
MenuRegistry when context if elseswitch
const bool:boolean = contextMatchesRules(context, item.when);
for (const commandId of MenuRegistry.getCommands().keys()) {
let item = MenuRegistry.getCommand(commandId);
if (contextMatchesRules(item?.when)) {
const button = document.createElement('button');
if (item?.command) {
button.innerHTML = item?.command;
}
document.body.appendChild(button);
}
}
function contextMatchesRules(rules: ContextKeyExpression | undefined): boolean {
const result = KeybindingResolver.contextMatchesRules(context, rules);
return result;
}