mirror of
https://github.com/google/blockly.git
synced 2026-01-04 15:40:08 +01:00
@@ -205,14 +205,23 @@ Blockly.svgResize = function(workspace) {
|
||||
// are multiple workspaces and non-main workspaces are able to accept input.
|
||||
Blockly.onKeyDown_ = function(e) {
|
||||
var mainWorkspace = Blockly.mainWorkspace;
|
||||
if (mainWorkspace.options.readOnly || Blockly.utils.isTargetInput(e) ||
|
||||
|
||||
if (Blockly.utils.isTargetInput(e) ||
|
||||
(mainWorkspace.rendered && !mainWorkspace.isVisible())) {
|
||||
// No key actions on readonly workspaces.
|
||||
// When focused on an HTML text input widget, don't trap any keys.
|
||||
// Ignore keypresses on rendered workspaces that have been explicitly
|
||||
// hidden.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWorkspace.options.readOnly) {
|
||||
// When in read only mode handle key actions for keyboard navigation.
|
||||
if (Blockly.keyboardAccessibilityMode) {
|
||||
Blockly.navigation.onKeyPress(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteBlock = false;
|
||||
if (e.keyCode == Blockly.utils.KeyCodes.ESC) {
|
||||
// Pressing esc closes the context menu.
|
||||
|
||||
@@ -288,7 +288,7 @@ Blockly.ASTNode.prototype.findPreviousEditableField_ = function(location,
|
||||
var previousField = null;
|
||||
var startIdx = opt_last ? fieldRow.length - 1 : fieldIdx - 1;
|
||||
for (var i = startIdx, field; field = fieldRow[i]; i--) {
|
||||
if (field.isCurrentlyEditable()) {
|
||||
if (field.EDITABLE) {
|
||||
previousField = field;
|
||||
return Blockly.ASTNode.createFieldNode(previousField);
|
||||
}
|
||||
@@ -312,7 +312,7 @@ Blockly.ASTNode.prototype.findNextForInput_ = function() {
|
||||
for (var i = curIdx + 1, input; input = block.inputList[i]; i++) {
|
||||
var fieldRow = input.fieldRow;
|
||||
for (var j = 0, field; field = fieldRow[j]; j++) {
|
||||
if (field.isCurrentlyEditable()) {
|
||||
if (field.EDITABLE) {
|
||||
return Blockly.ASTNode.createFieldNode(field);
|
||||
}
|
||||
}
|
||||
@@ -340,7 +340,7 @@ Blockly.ASTNode.prototype.findNextForField_ = function() {
|
||||
for (var i = curIdx, input; input = block.inputList[i]; i++) {
|
||||
var fieldRow = input.fieldRow;
|
||||
while (fieldIdx < fieldRow.length) {
|
||||
if (fieldRow[fieldIdx].isCurrentlyEditable()) {
|
||||
if (fieldRow[fieldIdx].EDITABLE) {
|
||||
return Blockly.ASTNode.createFieldNode(fieldRow[fieldIdx]);
|
||||
}
|
||||
fieldIdx++;
|
||||
@@ -371,7 +371,7 @@ Blockly.ASTNode.prototype.findPrevForInput_ = function() {
|
||||
}
|
||||
var fieldRow = input.fieldRow;
|
||||
for (var j = fieldRow.length - 1, field; field = fieldRow[j]; j--) {
|
||||
if (field.isCurrentlyEditable()) {
|
||||
if (field.EDITABLE) {
|
||||
return Blockly.ASTNode.createFieldNode(field);
|
||||
}
|
||||
}
|
||||
@@ -397,7 +397,7 @@ Blockly.ASTNode.prototype.findPrevForField_ = function() {
|
||||
}
|
||||
var fieldRow = input.fieldRow;
|
||||
while (fieldIdx > -1) {
|
||||
if (fieldRow[fieldIdx].isCurrentlyEditable()) {
|
||||
if (fieldRow[fieldIdx].EDITABLE) {
|
||||
return Blockly.ASTNode.createFieldNode(fieldRow[fieldIdx]);
|
||||
}
|
||||
fieldIdx--;
|
||||
@@ -501,7 +501,7 @@ Blockly.ASTNode.prototype.findFirstFieldOrInput_ = function(block) {
|
||||
for (var i = 0, input; input = inputs[i]; i++) {
|
||||
var fieldRow = input.fieldRow;
|
||||
for (var j = 0, field; field = fieldRow[j]; j++) {
|
||||
if (field.isCurrentlyEditable()) {
|
||||
if (field.EDITABLE) {
|
||||
return Blockly.ASTNode.createFieldNode(field);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,13 +837,18 @@ Blockly.navigation.onKeyPress = function(e) {
|
||||
var key = Blockly.user.keyMap.serializeKeyEvent(e);
|
||||
var action = Blockly.user.keyMap.getActionByKeyCode(key);
|
||||
var curNode = Blockly.navigation.cursor_.getCurNode();
|
||||
var readOnly = Blockly.getMainWorkspace().options.readOnly;
|
||||
var actionHandled = false;
|
||||
|
||||
if (action) {
|
||||
if (curNode && curNode.getType() === Blockly.ASTNode.types.FIELD) {
|
||||
actionHandled = curNode.getLocation().onBlocklyAction(action);
|
||||
}
|
||||
if (!actionHandled) {
|
||||
if (!readOnly) {
|
||||
if (curNode && curNode.getType() === Blockly.ASTNode.types.FIELD) {
|
||||
actionHandled = curNode.getLocation().onBlocklyAction(action);
|
||||
}
|
||||
if (!actionHandled) {
|
||||
actionHandled = Blockly.navigation.onBlocklyAction(action);
|
||||
}
|
||||
} else if (Blockly.navigation.READONLY_ACTION_LIST.indexOf(action) > -1) {
|
||||
actionHandled = Blockly.navigation.onBlocklyAction(action);
|
||||
}
|
||||
}
|
||||
@@ -1085,3 +1090,14 @@ Blockly.navigation.ACTION_TOOLBOX = new Blockly.Action(
|
||||
*/
|
||||
Blockly.navigation.ACTION_EXIT = new Blockly.Action(
|
||||
Blockly.navigation.actionNames.EXIT, 'Close the current modal, such as a toolbox or field editor.');
|
||||
|
||||
/**
|
||||
* List of actions that can be performed in read only mode.
|
||||
* @type {!Array<!Blockly.Action>}
|
||||
*/
|
||||
Blockly.navigation.READONLY_ACTION_LIST = [
|
||||
Blockly.navigation.ACTION_PREVIOUS,
|
||||
Blockly.navigation.ACTION_OUT,
|
||||
Blockly.navigation.ACTION_IN,
|
||||
Blockly.navigation.ACTION_NEXT
|
||||
];
|
||||
|
||||
@@ -370,6 +370,73 @@ suite('Navigation', function() {
|
||||
field.onBlocklyAction.restore();
|
||||
Blockly.navigation.onBlocklyAction.restore();
|
||||
});
|
||||
suite('Test key press in read only mode', function() {
|
||||
setup(function() {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "field_block",
|
||||
"message0": "%1 %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_dropdown",
|
||||
"name": "NAME",
|
||||
"options": [
|
||||
[
|
||||
"a",
|
||||
"optionA"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "NAME"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 230,
|
||||
"tooltip": "",
|
||||
"helpUrl": ""
|
||||
}]);
|
||||
this.workspace = new Blockly.Workspace({readOnly: true});
|
||||
Blockly.navigation.setCursor(this.workspace.cursor);
|
||||
Blockly.mainWorkspace = this.workspace;
|
||||
this.fieldBlock1 = this.workspace.newBlock('field_block');
|
||||
Blockly.keyboardAccessibilityMode = true;
|
||||
this.mockEvent = {
|
||||
getModifierState: function() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
delete Blockly.Blocks['field_block'];
|
||||
Blockly.mainWorkspace = null;
|
||||
this.workspace.dispose();
|
||||
});
|
||||
|
||||
test('Perform valid action for read only', function() {
|
||||
var astNode = Blockly.ASTNode.createBlockNode(this.fieldBlock1);
|
||||
this.workspace.cursor.setLocation(astNode);
|
||||
this.mockEvent.keyCode = Blockly.utils.KeyCodes.S;
|
||||
chai.assert.isTrue(Blockly.navigation.onKeyPress(this.mockEvent));
|
||||
});
|
||||
|
||||
test('Perform invalid action for read only', function() {
|
||||
var astNode = Blockly.ASTNode.createBlockNode(this.fieldBlock1);
|
||||
this.workspace.cursor.setLocation(astNode);
|
||||
this.mockEvent.keyCode = Blockly.utils.KeyCodes.I;
|
||||
chai.assert.isFalse(Blockly.navigation.onKeyPress(this.mockEvent));
|
||||
});
|
||||
|
||||
test('Try to perform action on a field', function() {
|
||||
var field = this.fieldBlock1.inputList[0].fieldRow[0];
|
||||
var astNode = Blockly.ASTNode.createFieldNode(field);
|
||||
this.workspace.cursor.setLocation(astNode);
|
||||
this.mockEvent.keyCode = Blockly.utils.KeyCodes.ENTER;
|
||||
chai.assert.isFalse(Blockly.navigation.onKeyPress(this.mockEvent));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Insert Functions', function() {
|
||||
|
||||
Reference in New Issue
Block a user