mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
@@ -44,9 +44,9 @@ def xmlToKey(xml_content):
|
||||
# Store XML and return a generated key.
|
||||
xml_hash = int(hashlib.sha1(xml_content.encode("utf-8")).hexdigest(), 16)
|
||||
xml_hash = int(xml_hash % (2 ** 64) - (2 ** 63))
|
||||
lookup_query = Xml.query(Xml.xml_hash == xml_hash)
|
||||
client = ndb.Client()
|
||||
with client.context():
|
||||
lookup_query = Xml.query(Xml.xml_hash == xml_hash)
|
||||
lookup_result = lookup_query.get()
|
||||
if lookup_result:
|
||||
xml_key = lookup_result.key.string_id()
|
||||
|
||||
@@ -42,5 +42,5 @@ export const blocks: {[key: string]: BlockDefinition} = Object.assign(
|
||||
math.blocks,
|
||||
procedures.blocks,
|
||||
variables.blocks,
|
||||
variablesDynamic.blocks
|
||||
variablesDynamic.blocks,
|
||||
);
|
||||
|
||||
@@ -130,7 +130,7 @@ const LISTS_CREATE_WITH = {
|
||||
this.updateShape_();
|
||||
this.setOutput(true, 'Array');
|
||||
this.setMutator(
|
||||
new MutatorIcon(['lists_create_with_item'], this as unknown as BlockSvg)
|
||||
new MutatorIcon(['lists_create_with_item'], this as unknown as BlockSvg),
|
||||
); // BUG(#6905)
|
||||
this.setTooltip(Msg['LISTS_CREATE_WITH_TOOLTIP']);
|
||||
},
|
||||
@@ -182,16 +182,16 @@ const LISTS_CREATE_WITH = {
|
||||
*/
|
||||
decompose: function (
|
||||
this: CreateWithBlock,
|
||||
workspace: Workspace
|
||||
workspace: Workspace,
|
||||
): ContainerBlock {
|
||||
const containerBlock = workspace.newBlock(
|
||||
'lists_create_with_container'
|
||||
'lists_create_with_container',
|
||||
) as ContainerBlock;
|
||||
(containerBlock as BlockSvg).initSvg();
|
||||
let connection = containerBlock.getInput('STACK')!.connection;
|
||||
for (let i = 0; i < this.itemCount_; i++) {
|
||||
const itemBlock = workspace.newBlock(
|
||||
'lists_create_with_item'
|
||||
'lists_create_with_item',
|
||||
) as ItemBlock;
|
||||
(itemBlock as BlockSvg).initSvg();
|
||||
if (!itemBlock.previousConnection) {
|
||||
@@ -209,7 +209,7 @@ const LISTS_CREATE_WITH = {
|
||||
*/
|
||||
compose: function (this: CreateWithBlock, containerBlock: Block) {
|
||||
let itemBlock: ItemBlock | null = containerBlock.getInputTargetBlock(
|
||||
'STACK'
|
||||
'STACK',
|
||||
) as ItemBlock;
|
||||
// Count number of inputs.
|
||||
const connections: Connection[] = [];
|
||||
@@ -242,7 +242,7 @@ const LISTS_CREATE_WITH = {
|
||||
*/
|
||||
saveConnections: function (this: CreateWithBlock, containerBlock: Block) {
|
||||
let itemBlock: ItemBlock | null = containerBlock.getInputTargetBlock(
|
||||
'STACK'
|
||||
'STACK',
|
||||
) as ItemBlock;
|
||||
let i = 0;
|
||||
while (itemBlock) {
|
||||
@@ -265,7 +265,7 @@ const LISTS_CREATE_WITH = {
|
||||
this.removeInput('EMPTY');
|
||||
} else if (!this.itemCount_ && !this.getInput('EMPTY')) {
|
||||
this.appendDummyInput('EMPTY').appendField(
|
||||
Msg['LISTS_CREATE_EMPTY_TITLE']
|
||||
Msg['LISTS_CREATE_EMPTY_TITLE'],
|
||||
);
|
||||
}
|
||||
// Add new inputs.
|
||||
@@ -297,7 +297,7 @@ const LISTS_CREATE_WITH_CONTAINER = {
|
||||
init: function (this: ContainerBlock) {
|
||||
this.setStyle('list_blocks');
|
||||
this.appendDummyInput().appendField(
|
||||
Msg['LISTS_CREATE_WITH_CONTAINER_TITLE_ADD']
|
||||
Msg['LISTS_CREATE_WITH_CONTAINER_TITLE_ADD'],
|
||||
);
|
||||
this.appendStatementInput('STACK');
|
||||
this.setTooltip(Msg['LISTS_CREATE_WITH_CONTAINER_TOOLTIP']);
|
||||
@@ -358,7 +358,7 @@ const LISTS_INDEXOF = {
|
||||
this.setTooltip(() => {
|
||||
return Msg['LISTS_INDEX_OF_TOOLTIP'].replace(
|
||||
'%1',
|
||||
this.workspace.options.oneBasedIndex ? '0' : '-1'
|
||||
this.workspace.options.oneBasedIndex ? '0' : '-1',
|
||||
);
|
||||
});
|
||||
},
|
||||
@@ -401,7 +401,7 @@ const LISTS_GETINDEX = {
|
||||
const isStatement = value === 'REMOVE';
|
||||
(this.getSourceBlock() as GetIndexBlock).updateStatement_(isStatement);
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
);
|
||||
this.appendValueInput('VALUE')
|
||||
.setCheck('Array')
|
||||
@@ -568,7 +568,7 @@ const LISTS_GETINDEX = {
|
||||
this.appendValueInput('AT').setCheck('Number');
|
||||
if (Msg['ORDINAL_NUMBER_SUFFIX']) {
|
||||
this.appendDummyInput('ORDINAL').appendField(
|
||||
Msg['ORDINAL_NUMBER_SUFFIX']
|
||||
Msg['ORDINAL_NUMBER_SUFFIX'],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -596,7 +596,7 @@ const LISTS_GETINDEX = {
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
);
|
||||
this.getInput('AT')!.appendField(menu, 'WHERE');
|
||||
if (Msg['LISTS_GET_INDEX_TAIL']) {
|
||||
@@ -685,7 +685,7 @@ const LISTS_SETINDEX = {
|
||||
' ' +
|
||||
Msg['LISTS_INDEX_FROM_START_TOOLTIP'].replace(
|
||||
'%1',
|
||||
this.workspace.options.oneBasedIndex ? '#1' : '#0'
|
||||
this.workspace.options.oneBasedIndex ? '#1' : '#0',
|
||||
);
|
||||
}
|
||||
return tooltip;
|
||||
@@ -747,7 +747,7 @@ const LISTS_SETINDEX = {
|
||||
this.appendValueInput('AT').setCheck('Number');
|
||||
if (Msg['ORDINAL_NUMBER_SUFFIX']) {
|
||||
this.appendDummyInput('ORDINAL').appendField(
|
||||
Msg['ORDINAL_NUMBER_SUFFIX']
|
||||
Msg['ORDINAL_NUMBER_SUFFIX'],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -775,7 +775,7 @@ const LISTS_SETINDEX = {
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
);
|
||||
this.moveInputBefore('AT', 'TO');
|
||||
if (this.getInput('ORDINAL')) {
|
||||
@@ -887,7 +887,7 @@ const LISTS_GETSUBLIST = {
|
||||
this.appendValueInput('AT' + n).setCheck('Number');
|
||||
if (Msg['ORDINAL_NUMBER_SUFFIX']) {
|
||||
this.appendDummyInput('ORDINAL' + n).appendField(
|
||||
Msg['ORDINAL_NUMBER_SUFFIX']
|
||||
Msg['ORDINAL_NUMBER_SUFFIX'],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -915,7 +915,7 @@ const LISTS_GETSUBLIST = {
|
||||
block.setFieldValue(value, 'WHERE' + n);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
this.getInput('AT' + n)!.appendField(menu, 'WHERE' + n);
|
||||
if (n === 1) {
|
||||
|
||||
@@ -276,7 +276,7 @@ const TOOLTIPS_BY_OP = {
|
||||
|
||||
Extensions.register(
|
||||
'logic_op_tooltip',
|
||||
Extensions.buildTooltipForDropdown('OP', TOOLTIPS_BY_OP)
|
||||
Extensions.buildTooltipForDropdown('OP', TOOLTIPS_BY_OP),
|
||||
);
|
||||
|
||||
/** Type of a block that has CONTROLS_IF_MUTATOR_MIXIN */
|
||||
@@ -417,10 +417,10 @@ const CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
this.elseifCount_++;
|
||||
// TODO(#6920): null valid, undefined not.
|
||||
valueConnections.push(
|
||||
clauseBlock.valueConnection_ as Connection | null
|
||||
clauseBlock.valueConnection_ as Connection | null,
|
||||
);
|
||||
statementConnections.push(
|
||||
clauseBlock.statementConnection_ as Connection | null
|
||||
clauseBlock.statementConnection_ as Connection | null,
|
||||
);
|
||||
break;
|
||||
case 'controls_if_else':
|
||||
@@ -438,7 +438,7 @@ const CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
this.reconnectChildBlocks_(
|
||||
valueConnections,
|
||||
statementConnections,
|
||||
elseStatementConnection
|
||||
elseStatementConnection,
|
||||
);
|
||||
},
|
||||
/**
|
||||
@@ -500,7 +500,7 @@ const CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
this.reconnectChildBlocks_(
|
||||
valueConnections,
|
||||
statementConnections,
|
||||
elseStatementConnection
|
||||
elseStatementConnection,
|
||||
);
|
||||
},
|
||||
/**
|
||||
@@ -523,12 +523,12 @@ const CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
.setCheck('Boolean')
|
||||
.appendField(Msg['CONTROLS_IF_MSG_ELSEIF']);
|
||||
this.appendStatementInput('DO' + i).appendField(
|
||||
Msg['CONTROLS_IF_MSG_THEN']
|
||||
Msg['CONTROLS_IF_MSG_THEN'],
|
||||
);
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
this.appendStatementInput('ELSE').appendField(
|
||||
Msg['CONTROLS_IF_MSG_ELSE']
|
||||
Msg['CONTROLS_IF_MSG_ELSE'],
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -545,7 +545,7 @@ const CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
this: IfBlock,
|
||||
valueConnections: Array<Connection | null>,
|
||||
statementConnections: Array<Connection | null>,
|
||||
elseStatementConnection: Connection | null
|
||||
elseStatementConnection: Connection | null,
|
||||
) {
|
||||
for (let i = 1; i <= this.elseifCount_; i++) {
|
||||
valueConnections[i]?.reconnect(this, 'IF' + i);
|
||||
@@ -559,7 +559,7 @@ Extensions.registerMutator(
|
||||
'controls_if_mutator',
|
||||
CONTROLS_IF_MUTATOR_MIXIN,
|
||||
null as unknown as undefined, // TODO(#6920)
|
||||
['controls_if_elseif', 'controls_if_else']
|
||||
['controls_if_elseif', 'controls_if_else'],
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -579,7 +579,7 @@ const CONTROLS_IF_TOOLTIP_EXTENSION = function (this: IfBlock) {
|
||||
return Msg['CONTROLS_IF_TOOLTIP_4'];
|
||||
}
|
||||
return '';
|
||||
}.bind(this)
|
||||
}.bind(this),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -617,7 +617,7 @@ const LOGIC_COMPARE_ONCHANGE_MIXIN = {
|
||||
blockB &&
|
||||
!this.workspace.connectionChecker.doTypeChecks(
|
||||
blockA.outputConnection!,
|
||||
blockB.outputConnection!
|
||||
blockB.outputConnection!,
|
||||
)
|
||||
) {
|
||||
// Mismatch between two inputs. Revert the block connections,
|
||||
@@ -686,7 +686,7 @@ const LOGIC_TERNARY_ONCHANGE_MIXIN = {
|
||||
block &&
|
||||
!block.workspace.connectionChecker.doTypeChecks(
|
||||
block.outputConnection!,
|
||||
parentConnection
|
||||
parentConnection,
|
||||
)
|
||||
) {
|
||||
// Ensure that any disconnections are grouped with the causing
|
||||
|
||||
@@ -227,7 +227,7 @@ const WHILE_UNTIL_TOOLTIPS = {
|
||||
|
||||
Extensions.register(
|
||||
'controls_whileUntil_tooltip',
|
||||
Extensions.buildTooltipForDropdown('MODE', WHILE_UNTIL_TOOLTIPS)
|
||||
Extensions.buildTooltipForDropdown('MODE', WHILE_UNTIL_TOOLTIPS),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -242,7 +242,7 @@ const BREAK_CONTINUE_TOOLTIPS = {
|
||||
|
||||
Extensions.register(
|
||||
'controls_flow_tooltip',
|
||||
Extensions.buildTooltipForDropdown('FLOW', BREAK_CONTINUE_TOOLTIPS)
|
||||
Extensions.buildTooltipForDropdown('FLOW', BREAK_CONTINUE_TOOLTIPS),
|
||||
);
|
||||
|
||||
/** Type of a block that has CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN */
|
||||
@@ -264,7 +264,7 @@ const CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
|
||||
*/
|
||||
customContextMenu: function (
|
||||
this: CustomContextMenuBlock,
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>,
|
||||
) {
|
||||
if (this.isInFlyout) {
|
||||
return;
|
||||
@@ -289,17 +289,20 @@ const CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
|
||||
|
||||
Extensions.registerMixin(
|
||||
'contextMenu_newGetVariableBlock',
|
||||
CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN
|
||||
CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN,
|
||||
);
|
||||
|
||||
Extensions.register(
|
||||
'controls_for_tooltip',
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_CONTROLS_FOR_TOOLTIP}', 'VAR')
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_CONTROLS_FOR_TOOLTIP}', 'VAR'),
|
||||
);
|
||||
|
||||
Extensions.register(
|
||||
'controls_forEach_tooltip',
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_CONTROLS_FOREACH_TOOLTIP}', 'VAR')
|
||||
Extensions.buildTooltipWithFieldText(
|
||||
'%{BKY_CONTROLS_FOREACH_TOOLTIP}',
|
||||
'VAR',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -366,7 +369,7 @@ const CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
|
||||
}
|
||||
const enabled = !!this.getSurroundLoop();
|
||||
this.setWarningText(
|
||||
enabled ? null : Msg['CONTROLS_FLOW_STATEMENTS_WARNING']
|
||||
enabled ? null : Msg['CONTROLS_FLOW_STATEMENTS_WARNING'],
|
||||
);
|
||||
if (!this.isInFlyout) {
|
||||
const group = Events.getGroup();
|
||||
@@ -380,7 +383,7 @@ const CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
|
||||
|
||||
Extensions.registerMixin(
|
||||
'controls_flow_in_loop_check',
|
||||
CONTROL_FLOW_IN_LOOP_CHECK_MIXIN
|
||||
CONTROL_FLOW_IN_LOOP_CHECK_MIXIN,
|
||||
);
|
||||
|
||||
// Register provided blocks.
|
||||
|
||||
@@ -427,7 +427,7 @@ const TOOLTIPS_BY_OP = {
|
||||
|
||||
Extensions.register(
|
||||
'math_op_tooltip',
|
||||
Extensions.buildTooltipForDropdown('OP', TOOLTIPS_BY_OP)
|
||||
Extensions.buildTooltipForDropdown('OP', TOOLTIPS_BY_OP),
|
||||
);
|
||||
|
||||
/** Type of a block that has IS_DIVISBLEBY_MUTATOR_MIXIN */
|
||||
@@ -502,20 +502,20 @@ const IS_DIVISIBLE_MUTATOR_EXTENSION = function (this: DivisiblebyBlock) {
|
||||
const divisorInput = option === 'DIVISIBLE_BY';
|
||||
(this.getSourceBlock() as DivisiblebyBlock).updateShape_(divisorInput);
|
||||
return undefined; // FieldValidators can't be void. Use option as-is.
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
Extensions.registerMutator(
|
||||
'math_is_divisibleby_mutator',
|
||||
IS_DIVISIBLEBY_MUTATOR_MIXIN,
|
||||
IS_DIVISIBLE_MUTATOR_EXTENSION
|
||||
IS_DIVISIBLE_MUTATOR_EXTENSION,
|
||||
);
|
||||
|
||||
// Update the tooltip of 'math_change' block to reference the variable.
|
||||
Extensions.register(
|
||||
'math_change_tooltip',
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_MATH_CHANGE_TOOLTIP}', 'VAR')
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_MATH_CHANGE_TOOLTIP}', 'VAR'),
|
||||
);
|
||||
|
||||
/** Type of a block that has LIST_MODES_MUTATOR_MIXIN */
|
||||
@@ -578,14 +578,14 @@ const LIST_MODES_MUTATOR_EXTENSION = function (this: ListModesBlock) {
|
||||
function (this: ListModesBlock, newOp: string) {
|
||||
this.updateType_(newOp);
|
||||
return undefined;
|
||||
}.bind(this)
|
||||
}.bind(this),
|
||||
);
|
||||
};
|
||||
|
||||
Extensions.registerMutator(
|
||||
'math_modes_of_list_mutator',
|
||||
LIST_MODES_MUTATOR_MIXIN,
|
||||
LIST_MODES_MUTATOR_EXTENSION
|
||||
LIST_MODES_MUTATOR_EXTENSION,
|
||||
);
|
||||
|
||||
// Register provided blocks.
|
||||
|
||||
@@ -77,7 +77,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
}
|
||||
if (hasStatements) {
|
||||
this.appendStatementInput('STACK').appendField(
|
||||
Msg['PROCEDURES_DEFNORETURN_DO']
|
||||
Msg['PROCEDURES_DEFNORETURN_DO'],
|
||||
);
|
||||
if (this.getInput('RETURN')) {
|
||||
this.moveInputBefore('STACK', 'RETURN');
|
||||
@@ -118,7 +118,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
*/
|
||||
mutationToDom: function (
|
||||
this: ProcedureBlock,
|
||||
opt_paramIds: boolean
|
||||
opt_paramIds: boolean,
|
||||
): Element {
|
||||
const container = xmlUtils.createElement('mutation');
|
||||
if (opt_paramIds) {
|
||||
@@ -162,13 +162,13 @@ const PROCEDURE_DEF_COMMON = {
|
||||
this.workspace,
|
||||
varId,
|
||||
varName,
|
||||
''
|
||||
'',
|
||||
);
|
||||
if (variable !== null) {
|
||||
this.argumentVarModels_.push(variable);
|
||||
} else {
|
||||
console.log(
|
||||
`Failed to create a variable named "${varName}", ignoring.`
|
||||
`Failed to create a variable named "${varName}", ignoring.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -221,7 +221,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
this.workspace,
|
||||
param['id'],
|
||||
param['name'],
|
||||
''
|
||||
'',
|
||||
);
|
||||
this.arguments_.push(variable.name);
|
||||
this.argumentVarModels_.push(variable);
|
||||
@@ -239,7 +239,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
*/
|
||||
decompose: function (
|
||||
this: ProcedureBlock,
|
||||
workspace: Workspace
|
||||
workspace: Workspace,
|
||||
): ContainerBlock {
|
||||
/*
|
||||
* Creates the following XML:
|
||||
@@ -277,7 +277,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
|
||||
const containerBlock = Xml.domToBlock(
|
||||
containerBlockNode,
|
||||
workspace
|
||||
workspace,
|
||||
) as ContainerBlock;
|
||||
|
||||
if (this.type === 'procedures_defreturn') {
|
||||
@@ -366,7 +366,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
renameVarById: function (
|
||||
this: ProcedureBlock & BlockSvg,
|
||||
oldId: string,
|
||||
newId: string
|
||||
newId: string,
|
||||
) {
|
||||
const oldVariable = this.workspace.getVariableById(oldId)!;
|
||||
if (oldVariable.type !== '') {
|
||||
@@ -397,7 +397,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
*/
|
||||
updateVarName: function (
|
||||
this: ProcedureBlock & BlockSvg,
|
||||
variable: VariableModel
|
||||
variable: VariableModel,
|
||||
) {
|
||||
const newName = variable.name;
|
||||
let change = false;
|
||||
@@ -424,7 +424,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
displayRenamedVar_: function (
|
||||
this: ProcedureBlock & BlockSvg,
|
||||
oldName: string,
|
||||
newName: string
|
||||
newName: string,
|
||||
) {
|
||||
this.updateParams_();
|
||||
// Update the mutator's variables if the mutator is open.
|
||||
@@ -448,7 +448,7 @@ const PROCEDURE_DEF_COMMON = {
|
||||
*/
|
||||
customContextMenu: function (
|
||||
this: ProcedureBlock,
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>,
|
||||
) {
|
||||
if (this.isInFlyout) {
|
||||
return;
|
||||
@@ -599,7 +599,7 @@ const PROCEDURES_MUTATORCONTAINER = {
|
||||
*/
|
||||
init: function (this: ContainerBlock) {
|
||||
this.appendDummyInput().appendField(
|
||||
Msg['PROCEDURES_MUTATORCONTAINER_TITLE']
|
||||
Msg['PROCEDURES_MUTATORCONTAINER_TITLE'],
|
||||
);
|
||||
this.appendStatementInput('STACK');
|
||||
this.appendDummyInput('STATEMENT_INPUT')
|
||||
@@ -609,7 +609,7 @@ const PROCEDURES_MUTATORCONTAINER = {
|
||||
type: 'field_checkbox',
|
||||
checked: true,
|
||||
}) as FieldCheckbox,
|
||||
'STATEMENTS'
|
||||
'STATEMENTS',
|
||||
);
|
||||
this.setStyle('procedure_blocks');
|
||||
this.setTooltip(Msg['PROCEDURES_MUTATORCONTAINER_TOOLTIP']);
|
||||
@@ -678,7 +678,7 @@ const PROCEDURES_MUTATORARGUMENT = {
|
||||
*/
|
||||
validator_: function (
|
||||
this: FieldTextInputForArgument,
|
||||
varName: string
|
||||
varName: string,
|
||||
): string | null {
|
||||
const sourceBlock = this.getSourceBlock()!;
|
||||
const outerWs = sourceBlock!.workspace.getRootWorkspace()!;
|
||||
@@ -734,7 +734,7 @@ const PROCEDURES_MUTATORARGUMENT = {
|
||||
*/
|
||||
deleteIntermediateVars_: function (
|
||||
this: FieldTextInputForArgument,
|
||||
newText: string
|
||||
newText: string,
|
||||
) {
|
||||
const outerWs = this.getSourceBlock()!.workspace.getRootWorkspace();
|
||||
if (!outerWs) {
|
||||
@@ -792,7 +792,7 @@ const PROCEDURE_CALL_COMMON = {
|
||||
renameProcedure: function (
|
||||
this: CallBlock,
|
||||
oldName: string,
|
||||
newName: string
|
||||
newName: string,
|
||||
) {
|
||||
if (Names.equals(oldName, this.getProcedureCall())) {
|
||||
this.setFieldValue(newName, 'NAME');
|
||||
@@ -814,7 +814,7 @@ const PROCEDURE_CALL_COMMON = {
|
||||
setProcedureParameters_: function (
|
||||
this: CallBlock,
|
||||
paramNames: string[],
|
||||
paramIds: string[]
|
||||
paramIds: string[],
|
||||
) {
|
||||
// Data structures:
|
||||
// this.arguments = ['x', 'y']
|
||||
@@ -827,7 +827,7 @@ const PROCEDURE_CALL_COMMON = {
|
||||
// which might reappear if a param is reattached in the mutator.
|
||||
const defBlock = Procedures.getDefinition(
|
||||
this.getProcedureCall(),
|
||||
this.workspace
|
||||
this.workspace,
|
||||
);
|
||||
const mutatorIcon = defBlock && defBlock.getIcon(Mutator.TYPE);
|
||||
const mutatorOpen = mutatorIcon && mutatorIcon.bubbleIsVisible();
|
||||
@@ -880,7 +880,7 @@ const PROCEDURE_CALL_COMMON = {
|
||||
this.workspace,
|
||||
null,
|
||||
this.arguments_[i],
|
||||
''
|
||||
'',
|
||||
);
|
||||
this.argumentVarModels_.push(variable);
|
||||
}
|
||||
@@ -1126,7 +1126,7 @@ const PROCEDURE_CALL_COMMON = {
|
||||
// investigate. If the use ends up being valid we may need to reorder
|
||||
// events in the undo stack.
|
||||
console.log(
|
||||
'Saw an existing group while responding to a definition change'
|
||||
'Saw an existing group while responding to a definition change',
|
||||
);
|
||||
}
|
||||
Events.setGroup(event.group);
|
||||
@@ -1147,7 +1147,7 @@ const PROCEDURE_CALL_COMMON = {
|
||||
*/
|
||||
customContextMenu: function (
|
||||
this: CallBlock,
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>,
|
||||
) {
|
||||
if (!(this.workspace as WorkspaceSvg).isMovable()) {
|
||||
// If we center on the block and the workspace isn't movable we could
|
||||
@@ -1230,7 +1230,7 @@ const PROCEDURES_IFRETURN = {
|
||||
.setCheck('Boolean')
|
||||
.appendField(Msg['CONTROLS_IF_MSG_IF']);
|
||||
this.appendValueInput('VALUE').appendField(
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN']
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN'],
|
||||
);
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true);
|
||||
@@ -1261,7 +1261,7 @@ const PROCEDURES_IFRETURN = {
|
||||
if (!this.hasReturnValue_) {
|
||||
this.removeInput('VALUE');
|
||||
this.appendDummyInput('VALUE').appendField(
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN']
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN'],
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -1300,7 +1300,7 @@ const PROCEDURES_IFRETURN = {
|
||||
if (block.type === 'procedures_defnoreturn' && this.hasReturnValue_) {
|
||||
this.removeInput('VALUE');
|
||||
this.appendDummyInput('VALUE').appendField(
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN']
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN'],
|
||||
);
|
||||
this.hasReturnValue_ = false;
|
||||
} else if (
|
||||
@@ -1309,7 +1309,7 @@ const PROCEDURES_IFRETURN = {
|
||||
) {
|
||||
this.removeInput('VALUE');
|
||||
this.appendValueInput('VALUE').appendField(
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN']
|
||||
Msg['PROCEDURES_DEFRETURN_RETURN'],
|
||||
);
|
||||
this.hasReturnValue_ = true;
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ const GET_SUBSTRING_BLOCK = {
|
||||
this.appendValueInput('AT' + n).setCheck('Number');
|
||||
if (Msg['ORDINAL_NUMBER_SUFFIX']) {
|
||||
this.appendDummyInput('ORDINAL' + n).appendField(
|
||||
Msg['ORDINAL_NUMBER_SUFFIX']
|
||||
Msg['ORDINAL_NUMBER_SUFFIX'],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -345,7 +345,7 @@ const GET_SUBSTRING_BLOCK = {
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.getInput('AT' + n)!.appendField(menu, 'WHERE' + n);
|
||||
@@ -379,7 +379,7 @@ blocks['text_changeCase'] = {
|
||||
type: 'field_dropdown',
|
||||
options: OPERATORS,
|
||||
}) as FieldDropdown,
|
||||
'CASE'
|
||||
'CASE',
|
||||
);
|
||||
this.setOutput(true, 'String');
|
||||
this.setTooltip(Msg['TEXT_CHANGECASE_TOOLTIP']);
|
||||
@@ -405,7 +405,7 @@ blocks['text_trim'] = {
|
||||
type: 'field_dropdown',
|
||||
options: OPERATORS,
|
||||
}) as FieldDropdown,
|
||||
'MODE'
|
||||
'MODE',
|
||||
);
|
||||
this.setOutput(true, 'String');
|
||||
this.setTooltip(Msg['TEXT_TRIM_TOOLTIP']);
|
||||
@@ -542,7 +542,7 @@ const TEXT_PROMPT_BLOCK = {
|
||||
type: 'field_input',
|
||||
text: '',
|
||||
}) as FieldTextInput,
|
||||
'TEXT'
|
||||
'TEXT',
|
||||
)
|
||||
.appendField(this.newQuote_(false));
|
||||
this.setOutput(true, 'String');
|
||||
@@ -691,7 +691,7 @@ const QUOTE_IMAGE_MIXIN = {
|
||||
}
|
||||
}
|
||||
console.warn(
|
||||
'field named "' + fieldName + '" not found in ' + this.toDevString()
|
||||
'field named "' + fieldName + '" not found in ' + this.toDevString(),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -790,13 +790,13 @@ const JOIN_MUTATOR_MIXIN = {
|
||||
*/
|
||||
decompose: function (this: JoinMutatorBlock, workspace: Workspace): Block {
|
||||
const containerBlock = workspace.newBlock(
|
||||
'text_create_join_container'
|
||||
'text_create_join_container',
|
||||
) as BlockSvg;
|
||||
containerBlock.initSvg();
|
||||
let connection = containerBlock.getInput('STACK')!.connection!;
|
||||
for (let i = 0; i < this.itemCount_; i++) {
|
||||
const itemBlock = workspace.newBlock(
|
||||
'text_create_join_item'
|
||||
'text_create_join_item',
|
||||
) as JoinItemBlock;
|
||||
itemBlock.initSvg();
|
||||
connection.connect(itemBlock.previousConnection);
|
||||
@@ -811,7 +811,7 @@ const JOIN_MUTATOR_MIXIN = {
|
||||
*/
|
||||
compose: function (this: JoinMutatorBlock, containerBlock: Block) {
|
||||
let itemBlock = containerBlock.getInputTargetBlock(
|
||||
'STACK'
|
||||
'STACK',
|
||||
) as JoinItemBlock;
|
||||
// Count number of inputs.
|
||||
const connections = [];
|
||||
@@ -901,7 +901,7 @@ const JOIN_EXTENSION = function (this: JoinMutatorBlock) {
|
||||
// Update the tooltip of 'text_append' block to reference the variable.
|
||||
Extensions.register(
|
||||
'text_append_tooltip',
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_TEXT_APPEND_TOOLTIP}', 'VAR')
|
||||
Extensions.buildTooltipWithFieldText('%{BKY_TEXT_APPEND_TOOLTIP}', 'VAR'),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -911,7 +911,7 @@ const INDEXOF_TOOLTIP_EXTENSION = function (this: Block) {
|
||||
this.setTooltip(() => {
|
||||
return Msg['TEXT_INDEXOF_TOOLTIP'].replace(
|
||||
'%1',
|
||||
this.workspace.options.oneBasedIndex ? '0' : '-1'
|
||||
this.workspace.options.oneBasedIndex ? '0' : '-1',
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -970,7 +970,7 @@ const CHARAT_MUTATOR_MIXIN = {
|
||||
this.appendValueInput('AT').setCheck('Number');
|
||||
if (Msg['ORDINAL_NUMBER_SUFFIX']) {
|
||||
this.appendDummyInput('ORDINAL').appendField(
|
||||
Msg['ORDINAL_NUMBER_SUFFIX']
|
||||
Msg['ORDINAL_NUMBER_SUFFIX'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1022,13 +1022,13 @@ Extensions.register('text_quotes', QUOTES_EXTENSION);
|
||||
Extensions.registerMutator(
|
||||
'text_join_mutator',
|
||||
JOIN_MUTATOR_MIXIN,
|
||||
JOIN_EXTENSION
|
||||
JOIN_EXTENSION,
|
||||
);
|
||||
|
||||
Extensions.registerMutator(
|
||||
'text_charAt_mutator',
|
||||
CHARAT_MUTATOR_MIXIN,
|
||||
CHARAT_EXTENSION
|
||||
CHARAT_EXTENSION,
|
||||
);
|
||||
|
||||
// Register provided blocks.
|
||||
|
||||
@@ -89,7 +89,7 @@ const CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
|
||||
*/
|
||||
customContextMenu: function (
|
||||
this: VariableBlock,
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>,
|
||||
) {
|
||||
if (!this.isInFlyout) {
|
||||
let oppositeType;
|
||||
@@ -148,7 +148,7 @@ const CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
|
||||
* @returns A function that renames the variable.
|
||||
*/
|
||||
const renameOptionCallbackFactory = function (
|
||||
block: VariableBlock
|
||||
block: VariableBlock,
|
||||
): () => void {
|
||||
return function () {
|
||||
const workspace = block.workspace;
|
||||
@@ -166,7 +166,7 @@ const renameOptionCallbackFactory = function (
|
||||
* @returns A function that deletes the variable.
|
||||
*/
|
||||
const deleteOptionCallbackFactory = function (
|
||||
block: VariableBlock
|
||||
block: VariableBlock,
|
||||
): () => void {
|
||||
return function () {
|
||||
const workspace = block.workspace;
|
||||
@@ -179,7 +179,7 @@ const deleteOptionCallbackFactory = function (
|
||||
|
||||
Extensions.registerMixin(
|
||||
'contextMenu_variableSetterGetter',
|
||||
CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN
|
||||
CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN,
|
||||
);
|
||||
|
||||
// Register provided blocks.
|
||||
|
||||
@@ -90,7 +90,7 @@ const CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
|
||||
*/
|
||||
customContextMenu: function (
|
||||
this: VariableBlock,
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>
|
||||
options: Array<ContextMenuOption | LegacyContextMenuOption>,
|
||||
) {
|
||||
// Getter blocks have the option to create a setter block, and vice versa.
|
||||
if (!this.isInFlyout) {
|
||||
@@ -194,7 +194,7 @@ const deleteOptionCallbackFactory = function (block: VariableBlock) {
|
||||
|
||||
Extensions.registerMixin(
|
||||
'contextMenu_variableDynamicSetterGetter',
|
||||
CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN
|
||||
CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN,
|
||||
);
|
||||
|
||||
// Register provided blocks.
|
||||
|
||||
@@ -366,8 +366,8 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
* change).
|
||||
*/
|
||||
initModel() {
|
||||
for (let i = 0, input; (input = this.inputList[i]); i++) {
|
||||
for (let j = 0, field; (field = input.fieldRow[j]); j++) {
|
||||
for (const input of this.inputList) {
|
||||
for (const field of input.fieldRow) {
|
||||
if (field.initModel) {
|
||||
field.initModel();
|
||||
}
|
||||
@@ -430,7 +430,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
this.workspace.connectionChecker.canConnect(
|
||||
childConnection,
|
||||
parentConnection,
|
||||
false
|
||||
false,
|
||||
)
|
||||
) {
|
||||
parentConnection.connect(childConnection!);
|
||||
@@ -491,7 +491,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
this.workspace.connectionChecker.canConnect(
|
||||
previousTarget,
|
||||
nextTarget,
|
||||
false
|
||||
false,
|
||||
)
|
||||
) {
|
||||
// Attach the next statement to the previous statement.
|
||||
@@ -624,25 +624,6 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
return this.previousConnection && this.previousConnection.targetBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the connection on the first statement input on this block, or null
|
||||
* if there are none.
|
||||
*
|
||||
* @returns The first statement connection or null.
|
||||
* @internal
|
||||
*/
|
||||
getFirstStatementConnection(): Connection | null {
|
||||
for (let i = 0, input; (input = this.inputList[i]); i++) {
|
||||
if (
|
||||
input.connection &&
|
||||
input.connection.type === ConnectionType.NEXT_STATEMENT
|
||||
) {
|
||||
return input.connection;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the top-most block in this block's tree.
|
||||
* This will return itself if this block is at the top level.
|
||||
@@ -738,7 +719,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
} else if (isConnected && !newParent) {
|
||||
throw Error(
|
||||
'Cannot set parent to null while block is still connected to' +
|
||||
' superior block.'
|
||||
' superior block.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -863,7 +844,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
return true;
|
||||
}
|
||||
return this.workspace.isCapacityAvailable(
|
||||
common.getBlockTypeCounts(this, true)
|
||||
common.getBlockTypeCounts(this, true),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -964,7 +945,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
*/
|
||||
getMatchingConnection(
|
||||
otherBlock: Block,
|
||||
conn: Connection
|
||||
conn: Connection,
|
||||
): Connection | null {
|
||||
const connections = this.getConnections_(true);
|
||||
const otherConnections = otherBlock.getConnections_(true);
|
||||
@@ -1090,7 +1071,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'Block.prototype.getField expects a string ' +
|
||||
'with the field name but received ' +
|
||||
(name === undefined ? 'nothing' : name + ' of type ' + typeof name) +
|
||||
' instead'
|
||||
' instead',
|
||||
);
|
||||
}
|
||||
for (let i = 0, input; (input = this.inputList[i]); i++) {
|
||||
@@ -1133,7 +1114,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
for (let j = 0, field; (field = input.fieldRow[j]); j++) {
|
||||
if (field.referencesVariables()) {
|
||||
const model = this.workspace.getVariableById(
|
||||
field.getValue() as string
|
||||
field.getValue() as string,
|
||||
);
|
||||
// Check if the variable actually exists (and isn't just a potential
|
||||
// variable).
|
||||
@@ -1221,7 +1202,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
*/
|
||||
setPreviousStatement(
|
||||
newBoolean: boolean,
|
||||
opt_check?: string | string[] | null
|
||||
opt_check?: string | string[] | null,
|
||||
) {
|
||||
if (newBoolean) {
|
||||
if (opt_check === undefined) {
|
||||
@@ -1229,7 +1210,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
}
|
||||
if (!this.previousConnection) {
|
||||
this.previousConnection = this.makeConnection_(
|
||||
ConnectionType.PREVIOUS_STATEMENT
|
||||
ConnectionType.PREVIOUS_STATEMENT,
|
||||
);
|
||||
}
|
||||
this.previousConnection.setCheck(opt_check);
|
||||
@@ -1238,7 +1219,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
if (this.previousConnection.isConnected()) {
|
||||
throw Error(
|
||||
'Must disconnect previous statement before removing ' +
|
||||
'connection.'
|
||||
'connection.',
|
||||
);
|
||||
}
|
||||
this.previousConnection.dispose();
|
||||
@@ -1261,7 +1242,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
}
|
||||
if (!this.nextConnection) {
|
||||
this.nextConnection = this.makeConnection_(
|
||||
ConnectionType.NEXT_STATEMENT
|
||||
ConnectionType.NEXT_STATEMENT,
|
||||
);
|
||||
}
|
||||
this.nextConnection.setCheck(opt_check);
|
||||
@@ -1269,7 +1250,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
if (this.nextConnection) {
|
||||
if (this.nextConnection.isConnected()) {
|
||||
throw Error(
|
||||
'Must disconnect next statement before removing ' + 'connection.'
|
||||
'Must disconnect next statement before removing ' + 'connection.',
|
||||
);
|
||||
}
|
||||
this.nextConnection.dispose();
|
||||
@@ -1292,7 +1273,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
}
|
||||
if (!this.outputConnection) {
|
||||
this.outputConnection = this.makeConnection_(
|
||||
ConnectionType.OUTPUT_VALUE
|
||||
ConnectionType.OUTPUT_VALUE,
|
||||
);
|
||||
}
|
||||
this.outputConnection.setCheck(opt_check);
|
||||
@@ -1300,7 +1281,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
if (this.outputConnection) {
|
||||
if (this.outputConnection.isConnected()) {
|
||||
throw Error(
|
||||
'Must disconnect output value before removing connection.'
|
||||
'Must disconnect output value before removing connection.',
|
||||
);
|
||||
}
|
||||
this.outputConnection.dispose();
|
||||
@@ -1322,8 +1303,8 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'inline',
|
||||
null,
|
||||
this.inputsInline,
|
||||
newBoolean
|
||||
)
|
||||
newBoolean,
|
||||
),
|
||||
);
|
||||
this.inputsInline = newBoolean;
|
||||
}
|
||||
@@ -1403,8 +1384,8 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'disabled',
|
||||
null,
|
||||
oldValue,
|
||||
!enabled
|
||||
)
|
||||
!enabled,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1449,8 +1430,8 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'collapsed',
|
||||
null,
|
||||
this.collapsed_,
|
||||
collapsed
|
||||
)
|
||||
collapsed,
|
||||
),
|
||||
);
|
||||
this.collapsed_ = collapsed;
|
||||
}
|
||||
@@ -1602,7 +1583,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
const inputConstructor = registry.getClass(
|
||||
registry.Type.INPUT,
|
||||
type,
|
||||
false
|
||||
false,
|
||||
);
|
||||
if (!inputConstructor) return null;
|
||||
return this.appendInput(new inputConstructor(name, this));
|
||||
@@ -1620,7 +1601,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
// Validate inputs.
|
||||
if (json['output'] && json['previousStatement']) {
|
||||
throw Error(
|
||||
warningPrefix + 'Must not have both an output and a previousStatement.'
|
||||
warningPrefix + 'Must not have both an output and a previousStatement.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1648,7 +1629,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
json['message' + i],
|
||||
json['args' + i] || [],
|
||||
json['lastDummyAlign' + i],
|
||||
warningPrefix
|
||||
warningPrefix,
|
||||
);
|
||||
i++;
|
||||
}
|
||||
@@ -1691,7 +1672,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
"JSON attribute 'extensions' should be an array of" +
|
||||
" strings. Found raw string in JSON for '" +
|
||||
json['type'] +
|
||||
"' block."
|
||||
"' block.",
|
||||
);
|
||||
json['extensions'] = [json['extensions']]; // Correct and continue.
|
||||
}
|
||||
@@ -1771,7 +1752,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
}
|
||||
if (overwrites.length) {
|
||||
throw Error(
|
||||
'Mixin will overwrite block members: ' + JSON.stringify(overwrites)
|
||||
'Mixin will overwrite block members: ' + JSON.stringify(overwrites),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1792,7 +1773,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
message: string,
|
||||
args: AnyDuringMigration[],
|
||||
lastDummyAlign: string | undefined,
|
||||
warningPrefix: string
|
||||
warningPrefix: string,
|
||||
) {
|
||||
const tokens = parsing.tokenizeInterpolation(message);
|
||||
this.validateTokens_(tokens, args.length);
|
||||
@@ -1844,7 +1825,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'": ' +
|
||||
'Message index %' +
|
||||
token +
|
||||
' out of range.'
|
||||
' out of range.',
|
||||
);
|
||||
}
|
||||
if (visitedArgsHash[token]) {
|
||||
@@ -1854,7 +1835,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'": ' +
|
||||
'Message index %' +
|
||||
token +
|
||||
' duplicated.'
|
||||
' duplicated.',
|
||||
);
|
||||
}
|
||||
visitedArgsHash[token] = true;
|
||||
@@ -1867,7 +1848,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'": ' +
|
||||
'Message does not reference all ' +
|
||||
argsCount +
|
||||
' arg(s).'
|
||||
' arg(s).',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1886,7 +1867,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
private interpolateArguments_(
|
||||
tokens: Array<string | number>,
|
||||
args: Array<AnyDuringMigration | string>,
|
||||
lastDummyAlign: string | undefined
|
||||
lastDummyAlign: string | undefined,
|
||||
): AnyDuringMigration[] {
|
||||
const elements = [];
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
@@ -1910,7 +1891,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
if (
|
||||
length &&
|
||||
!this.isInputKeyword_(
|
||||
(elements as AnyDuringMigration)[length - 1]['type']
|
||||
(elements as AnyDuringMigration)[length - 1]['type'],
|
||||
)
|
||||
) {
|
||||
const dummyInput = {'type': 'input_dummy'};
|
||||
@@ -1959,7 +1940,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
*/
|
||||
private inputFromJson_(
|
||||
element: AnyDuringMigration,
|
||||
warningPrefix: string
|
||||
warningPrefix: string,
|
||||
): Input | null {
|
||||
const alignmentLookup = {
|
||||
'LEFT': Align.LEFT,
|
||||
@@ -2179,8 +2160,8 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
'comment',
|
||||
null,
|
||||
oldText,
|
||||
text
|
||||
)
|
||||
text,
|
||||
),
|
||||
);
|
||||
|
||||
if (text !== null) {
|
||||
@@ -2285,7 +2266,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
throw Error('Block has parent');
|
||||
}
|
||||
const event = new (eventUtils.get(eventUtils.BLOCK_MOVE))(
|
||||
this
|
||||
this,
|
||||
) as BlockMove;
|
||||
reason && event.setReason(reason);
|
||||
this.xy_.translate(dx, dy);
|
||||
|
||||
@@ -68,7 +68,7 @@ function disposeUiStep(
|
||||
rect: CloneRect,
|
||||
rtl: boolean,
|
||||
start: Date,
|
||||
workspaceScale: number
|
||||
workspaceScale: number,
|
||||
) {
|
||||
const ms = new Date().getTime() - start.getTime();
|
||||
const percent = ms / 150;
|
||||
@@ -81,7 +81,7 @@ function disposeUiStep(
|
||||
const scale = (1 - percent) * workspaceScale;
|
||||
clone.setAttribute(
|
||||
'transform',
|
||||
'translate(' + x + ',' + y + ')' + ' scale(' + scale + ')'
|
||||
'translate(' + x + ',' + y + ')' + ' scale(' + scale + ')',
|
||||
);
|
||||
setTimeout(disposeUiStep, 10, clone, rect, rtl, start, workspaceScale);
|
||||
}
|
||||
@@ -120,29 +120,38 @@ export function connectionUiEffect(block: BlockSvg) {
|
||||
'stroke': '#888',
|
||||
'stroke-width': 10,
|
||||
},
|
||||
workspace.getParentSvg()
|
||||
workspace.getParentSvg(),
|
||||
);
|
||||
// Start the animation.
|
||||
connectionUiStep(ripple, new Date(), scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a ripple around a connection.
|
||||
*
|
||||
* @param ripple Element to animate.
|
||||
* @param start Date of animation's start.
|
||||
* @param scale Scale of workspace.
|
||||
*/
|
||||
function connectionUiStep(ripple: SVGElement, start: Date, scale: number) {
|
||||
const ms = new Date().getTime() - start.getTime();
|
||||
const percent = ms / 150;
|
||||
if (percent > 1) {
|
||||
dom.removeNode(ripple);
|
||||
} else {
|
||||
ripple.setAttribute('r', String(percent * 25 * scale));
|
||||
ripple.style.opacity = String(1 - percent);
|
||||
disconnectPid = setTimeout(connectionUiStep, 10, ripple, start, scale);
|
||||
}
|
||||
const scaleAnimation = dom.createSvgElement(
|
||||
Svg.ANIMATE,
|
||||
{
|
||||
'id': 'animationCircle',
|
||||
'begin': 'indefinite',
|
||||
'attributeName': 'r',
|
||||
'dur': '150ms',
|
||||
'from': 0,
|
||||
'to': 25 * scale,
|
||||
},
|
||||
ripple,
|
||||
);
|
||||
const opacityAnimation = dom.createSvgElement(
|
||||
Svg.ANIMATE,
|
||||
{
|
||||
'id': 'animationOpacity',
|
||||
'begin': 'indefinite',
|
||||
'attributeName': 'opacity',
|
||||
'dur': '150ms',
|
||||
'from': 1,
|
||||
'to': 0,
|
||||
},
|
||||
ripple,
|
||||
);
|
||||
|
||||
scaleAnimation.beginElement();
|
||||
opacityAnimation.beginElement();
|
||||
|
||||
setTimeout(() => void dom.removeNode(ripple), 150);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,7 +196,7 @@ function disconnectUiStep(block: BlockSvg, magnitude: number, start: Date) {
|
||||
let skew = '';
|
||||
if (percent <= 1) {
|
||||
const val = Math.round(
|
||||
Math.sin(percent * Math.PI * WIGGLES) * (1 - percent) * magnitude
|
||||
Math.sin(percent * Math.PI * WIGGLES) * (1 - percent) * magnitude,
|
||||
);
|
||||
skew = `skewX(${val})`;
|
||||
disconnectPid = setTimeout(disconnectUiStep, 10, block, magnitude, start);
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class that manages a surface for dragging blocks. When a
|
||||
* block drag is started, we move the block (and children) to a separate DOM
|
||||
* element that we move around using translate3d. At the end of the drag, the
|
||||
* blocks are put back in into the SVG they came from. This helps
|
||||
* performance by avoiding repainting the entire SVG on every mouse move
|
||||
* while dragging blocks.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
import * as goog from '../closure/goog/goog.js';
|
||||
goog.declareModuleId('Blockly.BlockDragSurfaceSvg');
|
||||
|
||||
import {Coordinate} from './utils/coordinate.js';
|
||||
import * as deprecation from './utils/deprecation.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
import {Svg} from './utils/svg.js';
|
||||
import * as svgMath from './utils/svg_math.js';
|
||||
|
||||
/**
|
||||
* Class for a drag surface for the currently dragged block. This is a separate
|
||||
* SVG that contains only the currently moving block, or nothing.
|
||||
*
|
||||
* @alias Blockly.BlockDragSurfaceSvg
|
||||
*/
|
||||
export class BlockDragSurfaceSvg {
|
||||
/**
|
||||
* The root element of the drag surface.
|
||||
*/
|
||||
private svg: SVGElement;
|
||||
|
||||
/**
|
||||
* This is where blocks live while they are being dragged if the drag
|
||||
* surface is enabled.
|
||||
*/
|
||||
private dragGroup: SVGElement;
|
||||
|
||||
/**
|
||||
* Cached value for the scale of the drag surface.
|
||||
* Used to set/get the correct translation during and after a drag.
|
||||
*/
|
||||
private scale = 1;
|
||||
|
||||
/**
|
||||
* Cached value for the translation of the drag surface.
|
||||
* This translation is in pixel units, because the scale is applied to the
|
||||
* drag group rather than the top-level SVG.
|
||||
*/
|
||||
private surfaceXY = new Coordinate(0, 0);
|
||||
|
||||
/**
|
||||
* Cached value for the translation of the child drag surface in pixel
|
||||
* units. Since the child drag surface tracks the translation of the
|
||||
* workspace this is ultimately the translation of the workspace.
|
||||
*/
|
||||
private readonly childSurfaceXY = new Coordinate(0, 0);
|
||||
|
||||
/** @param container Containing element. */
|
||||
constructor(private readonly container: Element) {
|
||||
this.svg = dom.createSvgElement(
|
||||
Svg.SVG,
|
||||
{
|
||||
'xmlns': dom.SVG_NS,
|
||||
'xmlns:html': dom.HTML_NS,
|
||||
'xmlns:xlink': dom.XLINK_NS,
|
||||
'version': '1.1',
|
||||
'class': 'blocklyBlockDragSurface',
|
||||
},
|
||||
this.container
|
||||
);
|
||||
|
||||
this.dragGroup = dom.createSvgElement(Svg.G, {}, this.svg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the drag surface and inject it into the container.
|
||||
*
|
||||
* @deprecated The DOM is automatically created by the constructor.
|
||||
*/
|
||||
createDom() {
|
||||
// No alternative provided, because now the dom is just automatically
|
||||
// created in the constructor now.
|
||||
deprecation.warn('BlockDragSurfaceSvg createDom', 'June 2022', 'June 2023');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SVG blocks on the drag surface's group and show the surface.
|
||||
* Only one block group should be on the drag surface at a time.
|
||||
*
|
||||
* @param blocks Block or group of blocks to place on the drag surface.
|
||||
*/
|
||||
setBlocksAndShow(blocks: SVGElement) {
|
||||
if (this.dragGroup.childNodes.length) {
|
||||
throw Error('Already dragging a block.');
|
||||
}
|
||||
// appendChild removes the blocks from the previous parent
|
||||
this.dragGroup.appendChild(blocks);
|
||||
this.svg.style.display = 'block';
|
||||
this.surfaceXY = new Coordinate(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate and scale the entire drag surface group to the given position, to
|
||||
* keep in sync with the workspace.
|
||||
*
|
||||
* @param x X translation in pixel coordinates.
|
||||
* @param y Y translation in pixel coordinates.
|
||||
* @param scale Scale of the group.
|
||||
*/
|
||||
translateAndScaleGroup(x: number, y: number, scale: number) {
|
||||
this.scale = scale;
|
||||
// Make sure the svg exists on a pixel boundary so that it is not fuzzy.
|
||||
const roundX = Math.round(x);
|
||||
const roundY = Math.round(y);
|
||||
this.childSurfaceXY.x = roundX;
|
||||
this.childSurfaceXY.y = roundY;
|
||||
this.dragGroup.setAttribute(
|
||||
'transform',
|
||||
'translate(' + roundX + ',' + roundY + ') scale(' + scale + ')'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the drag surface's SVG based on its internal state.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
translateSurfaceInternal_() {
|
||||
// Make sure the svg exists on a pixel boundary so that it is not fuzzy.
|
||||
const x = Math.round(this.surfaceXY.x);
|
||||
const y = Math.round(this.surfaceXY.y);
|
||||
this.svg.style.display = 'block';
|
||||
dom.setCssTransform(this.svg, 'translate3d(' + x + 'px, ' + y + 'px, 0)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the entire surface by a relative offset.
|
||||
*
|
||||
* @param deltaX Horizontal offset in pixel units.
|
||||
* @param deltaY Vertical offset in pixel units.
|
||||
*/
|
||||
translateBy(deltaX: number, deltaY: number) {
|
||||
const x = this.surfaceXY.x + deltaX;
|
||||
const y = this.surfaceXY.y + deltaY;
|
||||
this.surfaceXY = new Coordinate(x, y);
|
||||
this.translateSurfaceInternal_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the entire drag surface during a drag.
|
||||
* We translate the drag surface instead of the blocks inside the surface
|
||||
* so that the browser avoids repainting the SVG.
|
||||
* Because of this, the drag coordinates must be adjusted by scale.
|
||||
*
|
||||
* @param x X translation for the entire surface.
|
||||
* @param y Y translation for the entire surface.
|
||||
*/
|
||||
translateSurface(x: number, y: number) {
|
||||
this.surfaceXY = new Coordinate(x * this.scale, y * this.scale);
|
||||
this.translateSurfaceInternal_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the surface translation in scaled workspace coordinates.
|
||||
* Use this when finishing a drag to return blocks to the correct position.
|
||||
*
|
||||
* @returns Current translation of the surface.
|
||||
*/
|
||||
getSurfaceTranslation(): Coordinate {
|
||||
const xy = svgMath.getRelativeXY(this.svg);
|
||||
return new Coordinate(xy.x / this.scale, xy.y / this.scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a reference to the drag group (primarily for
|
||||
* BlockSvg.getRelativeToSurfaceXY).
|
||||
*
|
||||
* @returns Drag surface group element.
|
||||
*/
|
||||
getGroup(): SVGElement {
|
||||
return this.dragGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SVG drag surface.
|
||||
*
|
||||
* @returns The SVG drag surface.
|
||||
*/
|
||||
getSvgRoot(): SVGElement {
|
||||
return this.svg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current blocks on the drag surface, if any (primarily
|
||||
* for BlockSvg.getRelativeToSurfaceXY).
|
||||
*
|
||||
* @returns Drag surface block DOM element, or null if no blocks exist.
|
||||
*/
|
||||
getCurrentBlock(): Element | null {
|
||||
return this.dragGroup.firstChild as Element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translation of the child block surface
|
||||
* This surface is in charge of keeping track of how much the workspace has
|
||||
* moved.
|
||||
*
|
||||
* @returns The amount the workspace has been moved.
|
||||
*/
|
||||
getWsTranslation(): Coordinate {
|
||||
// Returning a copy so the coordinate can not be changed outside this class.
|
||||
return this.childSurfaceXY.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the group and hide the surface; move the blocks off onto the provided
|
||||
* element.
|
||||
* If the block is being deleted it doesn't need to go back to the original
|
||||
* surface, since it would be removed immediately during dispose.
|
||||
*
|
||||
* @param opt_newSurface Surface the dragging blocks should be moved to, or
|
||||
* null if the blocks should be removed from this surface without being
|
||||
* moved to a different surface.
|
||||
*/
|
||||
clearAndHide(opt_newSurface?: Element) {
|
||||
const currentBlockElement = this.getCurrentBlock();
|
||||
if (currentBlockElement) {
|
||||
if (opt_newSurface) {
|
||||
// appendChild removes the node from this.dragGroup
|
||||
opt_newSurface.appendChild(currentBlockElement);
|
||||
} else {
|
||||
this.dragGroup.removeChild(currentBlockElement);
|
||||
}
|
||||
}
|
||||
this.svg.style.display = 'none';
|
||||
if (this.dragGroup.childNodes.length) {
|
||||
throw Error('Drag group was not cleared.');
|
||||
}
|
||||
this.surfaceXY = new Coordinate(0, 0);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
|
||||
/** Object that keeps track of connections on dragged blocks. */
|
||||
this.draggedConnectionManager_ = new InsertionMarkerManager(
|
||||
this.draggingBlock_
|
||||
this.draggingBlock_,
|
||||
);
|
||||
|
||||
this.workspace_ = workspace;
|
||||
@@ -149,7 +149,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
*/
|
||||
protected disconnectBlock_(
|
||||
healStack: boolean,
|
||||
currentDragDeltaXY: Coordinate
|
||||
currentDragDeltaXY: Coordinate,
|
||||
) {
|
||||
this.draggingBlock_.unplug(healStack);
|
||||
const delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
|
||||
@@ -165,7 +165,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
const event = new (eventUtils.get(eventUtils.BLOCK_DRAG))(
|
||||
this.draggingBlock_,
|
||||
true,
|
||||
this.draggingBlock_.getDescendants(false)
|
||||
this.draggingBlock_.getDescendants(false),
|
||||
);
|
||||
eventUtils.fire(event);
|
||||
}
|
||||
@@ -247,7 +247,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
bumpObjects.bumpIntoBounds(
|
||||
this.draggingBlock_.workspace,
|
||||
this.workspace_.getMetricsManager().getScrollMetrics(true),
|
||||
this.draggingBlock_
|
||||
this.draggingBlock_,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
const event = new (eventUtils.get(eventUtils.BLOCK_DRAG))(
|
||||
this.draggingBlock_,
|
||||
false,
|
||||
this.draggingBlock_.getDescendants(false)
|
||||
this.draggingBlock_.getDescendants(false),
|
||||
);
|
||||
eventUtils.fire(event);
|
||||
}
|
||||
@@ -359,7 +359,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
protected fireMoveEvent_() {
|
||||
if (this.draggingBlock_.isDeadOrDying()) return;
|
||||
const event = new (eventUtils.get(eventUtils.BLOCK_MOVE))(
|
||||
this.draggingBlock_
|
||||
this.draggingBlock_,
|
||||
) as BlockMove;
|
||||
event.setReason(['drag']);
|
||||
event.oldCoordinate = this.startXY_;
|
||||
@@ -387,7 +387,7 @@ export class BlockDragger implements IBlockDragger {
|
||||
protected pixelsToWorkspaceUnits_(pixelCoord: Coordinate): Coordinate {
|
||||
const result = new Coordinate(
|
||||
pixelCoord.x / this.workspace_.scale,
|
||||
pixelCoord.y / this.workspace_.scale
|
||||
pixelCoord.y / this.workspace_.scale,
|
||||
);
|
||||
if (this.workspace_.isMutator) {
|
||||
// If we're in a mutator, its scale is always 1, purely because of some
|
||||
@@ -447,7 +447,7 @@ export interface IconPositionData {
|
||||
*/
|
||||
function initIconData(
|
||||
block: BlockSvg,
|
||||
blockOrigin: Coordinate
|
||||
blockOrigin: Coordinate,
|
||||
): IconPositionData[] {
|
||||
// Build a list of icons that need to be moved and where they started.
|
||||
const dragIconData = [];
|
||||
@@ -462,7 +462,7 @@ function initIconData(
|
||||
|
||||
for (const child of block.getChildren(false)) {
|
||||
dragIconData.push(
|
||||
...initIconData(child, Coordinate.sum(blockOrigin, child.relativeCoords))
|
||||
...initIconData(child, Coordinate.sum(blockOrigin, child.relativeCoords)),
|
||||
);
|
||||
}
|
||||
// AnyDuringMigration because: Type '{ location: Coordinate | null; icon:
|
||||
|
||||
@@ -59,7 +59,7 @@ import * as svgMath from './utils/svg_math.js';
|
||||
import {WarningIcon} from './icons/warning_icon.js';
|
||||
import type {Workspace} from './workspace.js';
|
||||
import type {WorkspaceSvg} from './workspace_svg.js';
|
||||
import {queueRender} from './render_management.js';
|
||||
import * as renderManagement from './render_management.js';
|
||||
import * as deprecation from './utils/deprecation.js';
|
||||
import {IconType} from './icons/icon_types.js';
|
||||
|
||||
@@ -87,7 +87,7 @@ export class BlockSvg
|
||||
// override compose?: ((p1: BlockSvg) => void)|null;
|
||||
saveConnections?: (p1: BlockSvg) => void;
|
||||
customContextMenu?: (
|
||||
p1: Array<ContextMenuOption | LegacyContextMenuOption>
|
||||
p1: Array<ContextMenuOption | LegacyContextMenuOption>,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
@@ -212,7 +212,7 @@ export class BlockSvg
|
||||
svg,
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onMouseDown_
|
||||
this.onMouseDown_,
|
||||
);
|
||||
}
|
||||
this.eventsInit_ = true;
|
||||
@@ -267,7 +267,7 @@ export class BlockSvg
|
||||
const event = new (eventUtils.get(eventUtils.SELECTED))(
|
||||
oldId,
|
||||
this.id,
|
||||
this.workspace.id
|
||||
this.workspace.id,
|
||||
);
|
||||
eventUtils.fire(event);
|
||||
common.setSelected(this);
|
||||
@@ -285,7 +285,7 @@ export class BlockSvg
|
||||
const event = new (eventUtils.get(eventUtils.SELECTED))(
|
||||
this.id,
|
||||
null,
|
||||
this.workspace.id
|
||||
this.workspace.id,
|
||||
);
|
||||
event.workspaceId = this.workspace.id;
|
||||
eventUtils.fire(event);
|
||||
@@ -428,21 +428,13 @@ export class BlockSvg
|
||||
this.getSvgRoot().setAttribute('transform', this.getTranslation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the block of transform="..." attributes.
|
||||
* Used when the block is switching from 3d to 2d transform or vice versa.
|
||||
*/
|
||||
private clearTransformAttributes_() {
|
||||
this.getSvgRoot().removeAttribute('transform');
|
||||
}
|
||||
|
||||
/** Snap this block to the nearest grid point. */
|
||||
snapToGrid() {
|
||||
if (this.isDeadOrDying()) {
|
||||
return; // Deleted block.
|
||||
}
|
||||
if (this.workspace.isDragging()) {
|
||||
return; // Don't bump blocks during a drag.;
|
||||
return; // Don't bump blocks during a drag.
|
||||
}
|
||||
|
||||
if (this.getParent()) {
|
||||
@@ -459,10 +451,10 @@ export class BlockSvg
|
||||
const half = spacing / 2;
|
||||
const xy = this.getRelativeToSurfaceXY();
|
||||
const dx = Math.round(
|
||||
Math.round((xy.x - half) / spacing) * spacing + half - xy.x
|
||||
Math.round((xy.x - half) / spacing) * spacing + half - xy.x,
|
||||
);
|
||||
const dy = Math.round(
|
||||
Math.round((xy.y - half) / spacing) * spacing + half - xy.y
|
||||
Math.round((xy.y - half) / spacing) * spacing + half - xy.y,
|
||||
);
|
||||
if (dx || dy) {
|
||||
this.moveBy(dx, dy, ['snap']);
|
||||
@@ -619,7 +611,7 @@ export class BlockSvg
|
||||
}
|
||||
const menuOptions = ContextMenuRegistry.registry.getContextMenuOptions(
|
||||
ContextMenuRegistry.ScopeType.BLOCK,
|
||||
{block: this}
|
||||
{block: this},
|
||||
);
|
||||
|
||||
// Allow the block to add or modify menuOptions.
|
||||
@@ -745,7 +737,7 @@ export class BlockSvg
|
||||
this.isInsertionMarker_ = insertionMarker;
|
||||
if (this.isInsertionMarker_) {
|
||||
this.setColour(
|
||||
this.workspace.getRenderer().getConstants().INSERTION_MARKER_COLOUR
|
||||
this.workspace.getRenderer().getConstants().INSERTION_MARKER_COLOUR,
|
||||
);
|
||||
this.pathObject.updateInsertionMarker(true);
|
||||
}
|
||||
@@ -930,7 +922,7 @@ export class BlockSvg
|
||||
this.warningTextDb.delete(id);
|
||||
this.setWarningText(text, id);
|
||||
}
|
||||
}, 100)
|
||||
}, 100),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -952,7 +944,7 @@ export class BlockSvg
|
||||
if (collapsedParent) {
|
||||
collapsedParent.setWarningText(
|
||||
Msg['COLLAPSED_WARNINGS_WARNING'],
|
||||
BlockSvg.COLLAPSED_WARNING_ID
|
||||
BlockSvg.COLLAPSED_WARNING_ID,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -991,8 +983,8 @@ export class BlockSvg
|
||||
icon.initView(this.createIconPointerDownListener(icon));
|
||||
icon.applyColour();
|
||||
icon.updateEditable();
|
||||
// TODO: Change this based on #7068.
|
||||
this.render();
|
||||
this.queueRender();
|
||||
renderManagement.triggerQueuedRenders();
|
||||
this.bumpNeighbours();
|
||||
}
|
||||
|
||||
@@ -1020,8 +1012,8 @@ export class BlockSvg
|
||||
if (type.equals(MutatorIcon.TYPE)) this.mutator = null;
|
||||
|
||||
if (this.rendered) {
|
||||
// TODO: Change this based on #7068.
|
||||
this.render();
|
||||
this.queueRender();
|
||||
renderManagement.triggerQueuedRenders();
|
||||
this.bumpNeighbours();
|
||||
}
|
||||
return removed;
|
||||
@@ -1085,7 +1077,6 @@ export class BlockSvg
|
||||
}
|
||||
|
||||
// Overrides of functions on Blockly.Block that take into account whether the
|
||||
|
||||
// block has been rendered.
|
||||
|
||||
/**
|
||||
@@ -1174,7 +1165,7 @@ export class BlockSvg
|
||||
*/
|
||||
override setPreviousStatement(
|
||||
newBoolean: boolean,
|
||||
opt_check?: string | string[] | null
|
||||
opt_check?: string | string[] | null,
|
||||
) {
|
||||
super.setPreviousStatement(newBoolean, opt_check);
|
||||
|
||||
@@ -1193,7 +1184,7 @@ export class BlockSvg
|
||||
*/
|
||||
override setNextStatement(
|
||||
newBoolean: boolean,
|
||||
opt_check?: string | string[] | null
|
||||
opt_check?: string | string[] | null,
|
||||
) {
|
||||
super.setNextStatement(newBoolean, opt_check);
|
||||
|
||||
@@ -1212,7 +1203,7 @@ export class BlockSvg
|
||||
*/
|
||||
override setOutput(
|
||||
newBoolean: boolean,
|
||||
opt_check?: string | string[] | null
|
||||
opt_check?: string | string[] | null,
|
||||
) {
|
||||
super.setOutput(newBoolean, opt_check);
|
||||
|
||||
@@ -1374,7 +1365,7 @@ export class BlockSvg
|
||||
* @internal
|
||||
*/
|
||||
override lastConnectionInStack(
|
||||
ignoreShadows: boolean
|
||||
ignoreShadows: boolean,
|
||||
): RenderedConnection | null {
|
||||
return super.lastConnectionInStack(ignoreShadows) as RenderedConnection;
|
||||
}
|
||||
@@ -1391,7 +1382,7 @@ export class BlockSvg
|
||||
*/
|
||||
override getMatchingConnection(
|
||||
otherBlock: Block,
|
||||
conn: Connection
|
||||
conn: Connection,
|
||||
): RenderedConnection | null {
|
||||
return super.getMatchingConnection(otherBlock, conn) as RenderedConnection;
|
||||
}
|
||||
@@ -1514,7 +1505,7 @@ export class BlockSvg
|
||||
*/
|
||||
positionNearConnection(
|
||||
sourceConnection: RenderedConnection,
|
||||
targetConnection: RenderedConnection
|
||||
targetConnection: RenderedConnection,
|
||||
) {
|
||||
// We only need to position the new block if it's before the existing one,
|
||||
// otherwise its position is set by the previous block.
|
||||
@@ -1529,14 +1520,6 @@ export class BlockSvg
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns The first statement connection or null.
|
||||
* @internal
|
||||
*/
|
||||
override getFirstStatementConnection(): RenderedConnection | null {
|
||||
return super.getFirstStatementConnection() as RenderedConnection | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the blocks that are directly nested inside this one.
|
||||
* Includes value and statement inputs, as well as any following statement.
|
||||
@@ -1559,51 +1542,16 @@ export class BlockSvg
|
||||
* @internal
|
||||
*/
|
||||
queueRender(): Promise<void> {
|
||||
return queueRender(this);
|
||||
return renderManagement.queueRender(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately lays out and reflows a block based on its contents and
|
||||
* settings.
|
||||
*
|
||||
* @param opt_bubble If false, just render this block.
|
||||
* If true, also render block's parent, grandparent, etc. Defaults to true.
|
||||
*/
|
||||
render(opt_bubble?: boolean) {
|
||||
if (this.renderIsInProgress_) {
|
||||
return; // Don't allow recursive renders.
|
||||
}
|
||||
this.renderIsInProgress_ = true;
|
||||
try {
|
||||
this.rendered = true;
|
||||
dom.startTextWidthCache();
|
||||
|
||||
if (!this.isEnabled()) {
|
||||
// Apply disabled styles if needed.
|
||||
this.updateDisabled();
|
||||
}
|
||||
|
||||
if (this.isCollapsed()) {
|
||||
this.updateCollapsed_();
|
||||
}
|
||||
this.workspace.getRenderer().render(this);
|
||||
this.updateConnectionAndIconLocations();
|
||||
|
||||
if (opt_bubble !== false) {
|
||||
const parentBlock = this.getParent();
|
||||
if (parentBlock) {
|
||||
parentBlock.render(true);
|
||||
} else {
|
||||
// Top-most block. Fire an event to allow scrollbars to resize.
|
||||
this.workspace.resizeContents();
|
||||
}
|
||||
}
|
||||
|
||||
dom.stopTextWidthCache();
|
||||
this.updateMarkers_();
|
||||
} finally {
|
||||
this.renderIsInProgress_ = false;
|
||||
}
|
||||
render() {
|
||||
this.queueRender();
|
||||
renderManagement.triggerQueuedRenders();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -410,14 +410,14 @@ export const PROCEDURE_CATEGORY_NAME: string = Procedures.CATEGORY_NAME;
|
||||
// clang-format off
|
||||
Workspace.prototype.newBlock = function (
|
||||
prototypeName: string,
|
||||
opt_id?: string
|
||||
opt_id?: string,
|
||||
): Block {
|
||||
return new Block(this, prototypeName, opt_id);
|
||||
};
|
||||
|
||||
WorkspaceSvg.prototype.newBlock = function (
|
||||
prototypeName: string,
|
||||
opt_id?: string
|
||||
opt_id?: string,
|
||||
): BlockSvg {
|
||||
return new BlockSvg(this, prototypeName, opt_id);
|
||||
};
|
||||
@@ -428,7 +428,7 @@ WorkspaceSvg.newTrashcan = function (workspace: WorkspaceSvg): Trashcan {
|
||||
|
||||
WorkspaceCommentSvg.prototype.showContextMenu = function (
|
||||
this: WorkspaceCommentSvg,
|
||||
e: Event
|
||||
e: Event,
|
||||
) {
|
||||
if (this.workspace.options.readOnly) {
|
||||
return;
|
||||
@@ -444,14 +444,14 @@ WorkspaceCommentSvg.prototype.showContextMenu = function (
|
||||
};
|
||||
|
||||
MiniWorkspaceBubble.prototype.newWorkspaceSvg = function (
|
||||
options: Options
|
||||
options: Options,
|
||||
): WorkspaceSvg {
|
||||
return new WorkspaceSvg(options);
|
||||
};
|
||||
|
||||
Names.prototype.populateProcedures = function (
|
||||
this: Names,
|
||||
workspace: Workspace
|
||||
workspace: Workspace,
|
||||
) {
|
||||
const procedures = Procedures.allProcedures(workspace);
|
||||
// Flatten the return vs no-return procedure lists.
|
||||
|
||||
@@ -50,7 +50,7 @@ export function conditionalBind(
|
||||
name: string,
|
||||
thisObject: Object | null,
|
||||
func: Function,
|
||||
opt_noCaptureIdentifier?: boolean
|
||||
opt_noCaptureIdentifier?: boolean,
|
||||
): Data {
|
||||
/**
|
||||
*
|
||||
@@ -98,7 +98,7 @@ export function bind(
|
||||
node: EventTarget,
|
||||
name: string,
|
||||
thisObject: Object | null,
|
||||
func: Function
|
||||
func: Function,
|
||||
): Data {
|
||||
/**
|
||||
*
|
||||
@@ -208,7 +208,7 @@ export function isRightButton(e: MouseEvent): boolean {
|
||||
export function mouseToSvg(
|
||||
e: MouseEvent,
|
||||
svg: SVGSVGElement,
|
||||
matrix: SVGMatrix | null
|
||||
matrix: SVGMatrix | null,
|
||||
): SVGPoint {
|
||||
const svgPoint = svg.createSVGPoint();
|
||||
svgPoint.x = e.clientX;
|
||||
|
||||
@@ -39,7 +39,10 @@ export class BubbleDragger {
|
||||
* @param bubble The item on the bubble canvas to drag.
|
||||
* @param workspace The workspace to drag on.
|
||||
*/
|
||||
constructor(private bubble: IBubble, private workspace: WorkspaceSvg) {
|
||||
constructor(
|
||||
private bubble: IBubble,
|
||||
private workspace: WorkspaceSvg,
|
||||
) {
|
||||
/**
|
||||
* The location of the top left corner of the dragging bubble's body at the
|
||||
* beginning of the drag, in workspace coordinates.
|
||||
@@ -108,7 +111,7 @@ export class BubbleDragger {
|
||||
const componentManager = this.workspace.getComponentManager();
|
||||
const isDeleteArea = componentManager.hasCapability(
|
||||
dragTarget.id,
|
||||
ComponentManager.Capability.DELETE_AREA
|
||||
ComponentManager.Capability.DELETE_AREA,
|
||||
);
|
||||
if (isDeleteArea) {
|
||||
return (dragTarget as IDeleteArea).wouldDelete(this.bubble, false);
|
||||
@@ -173,7 +176,7 @@ export class BubbleDragger {
|
||||
private fireMoveEvent_() {
|
||||
if (this.bubble instanceof WorkspaceCommentSvg) {
|
||||
const event = new (eventUtils.get(eventUtils.COMMENT_MOVE))(
|
||||
this.bubble
|
||||
this.bubble,
|
||||
) as CommentMove;
|
||||
event.setOldCoordinate(this.startXY_);
|
||||
event.recordNew();
|
||||
@@ -195,7 +198,7 @@ export class BubbleDragger {
|
||||
private pixelsToWorkspaceUnits_(pixelCoord: Coordinate): Coordinate {
|
||||
const result = new Coordinate(
|
||||
pixelCoord.x / this.workspace.scale,
|
||||
pixelCoord.y / this.workspace.scale
|
||||
pixelCoord.y / this.workspace.scale,
|
||||
);
|
||||
if (this.workspace.isMutator) {
|
||||
// If we're in a mutator, its scale is always 1, purely because of some
|
||||
|
||||
@@ -88,7 +88,7 @@ export abstract class Bubble implements IBubble {
|
||||
constructor(
|
||||
protected readonly workspace: WorkspaceSvg,
|
||||
protected anchor: Coordinate,
|
||||
protected ownerRect?: Rect
|
||||
protected ownerRect?: Rect,
|
||||
) {
|
||||
this.svgRoot = dom.createSvgElement(Svg.G, {}, workspace.getBubbleCanvas());
|
||||
const embossGroup = dom.createSvgElement(
|
||||
@@ -98,7 +98,7 @@ export abstract class Bubble implements IBubble {
|
||||
this.workspace.getRenderer().getConstants().embossFilterId
|
||||
})`,
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
this.tail = dom.createSvgElement(Svg.PATH, {}, embossGroup);
|
||||
this.background = dom.createSvgElement(
|
||||
@@ -110,7 +110,7 @@ export abstract class Bubble implements IBubble {
|
||||
'rx': Bubble.BORDER_WIDTH,
|
||||
'ry': Bubble.BORDER_WIDTH,
|
||||
},
|
||||
embossGroup
|
||||
embossGroup,
|
||||
);
|
||||
this.contentContainer = dom.createSvgElement(Svg.G, {}, this.svgRoot);
|
||||
|
||||
@@ -118,7 +118,7 @@ export abstract class Bubble implements IBubble {
|
||||
this.background,
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onMouseDown
|
||||
this.onMouseDown,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ export abstract class Bubble implements IBubble {
|
||||
const closerPositionOverlap = this.getOverlap(closerPosition, viewMetrics);
|
||||
const fartherPositionOverlap = this.getOverlap(
|
||||
fartherPosition,
|
||||
viewMetrics
|
||||
viewMetrics,
|
||||
);
|
||||
|
||||
// Set the position to whichever position shows the most of the bubble,
|
||||
@@ -259,7 +259,7 @@ export abstract class Bubble implements IBubble {
|
||||
topPositionOverlap,
|
||||
startPositionOverlap,
|
||||
closerPositionOverlap,
|
||||
fartherPositionOverlap
|
||||
fartherPositionOverlap,
|
||||
);
|
||||
if (topPositionOverlap === mostOverlap) {
|
||||
this.relativeLeft = topPosition.x;
|
||||
@@ -299,7 +299,7 @@ export abstract class Bubble implements IBubble {
|
||||
*/
|
||||
private getOverlap(
|
||||
relativeMin: {x: number; y: number},
|
||||
viewMetrics: ContainerRegion
|
||||
viewMetrics: ContainerRegion,
|
||||
): number {
|
||||
// The position of the top-left corner of the bubble in workspace units.
|
||||
const bubbleMin = {
|
||||
@@ -337,8 +337,8 @@ export abstract class Bubble implements IBubble {
|
||||
0,
|
||||
Math.min(
|
||||
1,
|
||||
(overlapWidth * overlapHeight) / (this.size.width * this.size.height)
|
||||
)
|
||||
(overlapWidth * overlapHeight) / (this.size.width * this.size.height),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ export abstract class Bubble implements IBubble {
|
||||
|
||||
// Distortion to curve the tail.
|
||||
const radians = math.toRadians(
|
||||
this.workspace.RTL ? -Bubble.TAIL_ANGLE : Bubble.TAIL_ANGLE
|
||||
this.workspace.RTL ? -Bubble.TAIL_ANGLE : Bubble.TAIL_ANGLE,
|
||||
);
|
||||
let swirlAngle = angle + radians;
|
||||
if (swirlAngle > Math.PI * 2) {
|
||||
@@ -519,7 +519,7 @@ export abstract class Bubble implements IBubble {
|
||||
' ' +
|
||||
relAnchorX +
|
||||
',' +
|
||||
relAnchorY
|
||||
relAnchorY,
|
||||
);
|
||||
steps.push(
|
||||
'C' +
|
||||
@@ -533,7 +533,7 @@ export abstract class Bubble implements IBubble {
|
||||
' ' +
|
||||
baseX2 +
|
||||
',' +
|
||||
baseY2
|
||||
baseY2,
|
||||
);
|
||||
}
|
||||
steps.push('z');
|
||||
@@ -560,7 +560,7 @@ export abstract class Bubble implements IBubble {
|
||||
this.workspace.RTL
|
||||
? -this.relativeLeft + this.anchor.x - this.size.width
|
||||
: this.anchor.x + this.relativeLeft,
|
||||
this.anchor.y + this.relativeTop
|
||||
this.anchor.y + this.relativeTop,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
workspaceOptions: BlocklyOptions,
|
||||
protected readonly workspace: WorkspaceSvg,
|
||||
protected anchor: Coordinate,
|
||||
protected ownerRect?: Rect
|
||||
protected ownerRect?: Rect,
|
||||
) {
|
||||
super(workspace, anchor, ownerRect);
|
||||
const options = new Options(workspaceOptions);
|
||||
@@ -61,7 +61,7 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
'x': Bubble.BORDER_WIDTH,
|
||||
'y': Bubble.BORDER_WIDTH,
|
||||
},
|
||||
this.contentContainer
|
||||
this.contentContainer,
|
||||
);
|
||||
workspaceOptions.parentWorkspace = this.workspace;
|
||||
this.miniWorkspace = this.newWorkspaceSvg(new Options(workspaceOptions));
|
||||
@@ -70,7 +70,7 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
if (options.languageTree) {
|
||||
background.insertBefore(
|
||||
this.miniWorkspace.addFlyout(Svg.G),
|
||||
this.miniWorkspace.getCanvas()
|
||||
this.miniWorkspace.getCanvas(),
|
||||
);
|
||||
const flyout = this.miniWorkspace.getFlyout();
|
||||
flyout?.init(this.miniWorkspace);
|
||||
@@ -107,7 +107,7 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
private validateWorkspaceOptions(options: Options) {
|
||||
if (options.hasCategories) {
|
||||
throw new Error(
|
||||
'The miniworkspace bubble does not support toolboxes with categories'
|
||||
'The miniworkspace bubble does not support toolboxes with categories',
|
||||
);
|
||||
}
|
||||
if (options.hasTrashcan) {
|
||||
@@ -126,12 +126,12 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
options.moveOptions.drag
|
||||
) {
|
||||
throw new Error(
|
||||
'The miniworkspace bubble does not scrolling/moving the workspace'
|
||||
'The miniworkspace bubble does not scrolling/moving the workspace',
|
||||
);
|
||||
}
|
||||
if (options.horizontalLayout) {
|
||||
throw new Error(
|
||||
'The miniworkspace bubble does not support horizontal layouts'
|
||||
'The miniworkspace bubble does not support horizontal layouts',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -206,9 +206,9 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
this.setSize(
|
||||
new Size(
|
||||
newSize.width + Bubble.DOUBLE_BORDER,
|
||||
newSize.height + Bubble.DOUBLE_BORDER
|
||||
newSize.height + Bubble.DOUBLE_BORDER,
|
||||
),
|
||||
this.autoLayout
|
||||
this.autoLayout,
|
||||
);
|
||||
this.miniWorkspace.resize();
|
||||
this.miniWorkspace.recordDragTargets();
|
||||
@@ -276,7 +276,7 @@ export class MiniWorkspaceBubble extends Bubble {
|
||||
newWorkspaceSvg(options: Options): WorkspaceSvg {
|
||||
throw new Error(
|
||||
'The implementation of newWorkspaceSvg should be ' +
|
||||
'monkey-patched in by blockly.ts'
|
||||
'monkey-patched in by blockly.ts',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export class TextBubble extends Bubble {
|
||||
private text: string,
|
||||
protected readonly workspace: WorkspaceSvg,
|
||||
protected anchor: Coordinate,
|
||||
protected ownerRect?: Rect
|
||||
protected ownerRect?: Rect,
|
||||
) {
|
||||
super(workspace, anchor, ownerRect);
|
||||
this.paragraph = this.stringToSvg(text, this.contentContainer);
|
||||
@@ -62,7 +62,7 @@ export class TextBubble extends Bubble {
|
||||
'class': 'blocklyText blocklyBubbleText blocklyNoPointerEvents',
|
||||
'y': Bubble.BORDER_WIDTH,
|
||||
},
|
||||
container
|
||||
container,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export class TextBubble extends Bubble {
|
||||
const tspan = dom.createSvgElement(
|
||||
Svg.TSPAN,
|
||||
{'dy': '1em', 'x': Bubble.BORDER_WIDTH},
|
||||
parent
|
||||
parent,
|
||||
);
|
||||
const textNode = document.createTextNode(line);
|
||||
tspan.appendChild(textNode);
|
||||
@@ -94,9 +94,9 @@ export class TextBubble extends Bubble {
|
||||
this.setSize(
|
||||
new Size(
|
||||
bbox.width + Bubble.BORDER_WIDTH * 2,
|
||||
bbox.height + Bubble.BORDER_WIDTH * 2
|
||||
bbox.height + Bubble.BORDER_WIDTH * 2,
|
||||
),
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@ export class TextInputBubble extends Bubble {
|
||||
/** The default size of this bubble, including borders. */
|
||||
private readonly DEFAULT_SIZE = new Size(
|
||||
160 + Bubble.DOUBLE_BORDER,
|
||||
80 + Bubble.DOUBLE_BORDER
|
||||
80 + Bubble.DOUBLE_BORDER,
|
||||
);
|
||||
|
||||
/** The minimum size of this bubble, including borders. */
|
||||
private readonly MIN_SIZE = new Size(
|
||||
45 + Bubble.DOUBLE_BORDER,
|
||||
20 + Bubble.DOUBLE_BORDER
|
||||
20 + Bubble.DOUBLE_BORDER,
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -72,11 +72,11 @@ export class TextInputBubble extends Bubble {
|
||||
constructor(
|
||||
protected readonly workspace: WorkspaceSvg,
|
||||
protected anchor: Coordinate,
|
||||
protected ownerRect?: Rect
|
||||
protected ownerRect?: Rect,
|
||||
) {
|
||||
super(workspace, anchor, ownerRect);
|
||||
({inputRoot: this.inputRoot, textArea: this.textArea} = this.createEditor(
|
||||
this.contentContainer
|
||||
this.contentContainer,
|
||||
));
|
||||
this.resizeGroup = this.createResizeHandle(this.svgRoot);
|
||||
this.setSize(this.DEFAULT_SIZE, true);
|
||||
@@ -115,7 +115,7 @@ export class TextInputBubble extends Bubble {
|
||||
'x': Bubble.BORDER_WIDTH,
|
||||
'y': Bubble.BORDER_WIDTH,
|
||||
},
|
||||
container
|
||||
container,
|
||||
);
|
||||
|
||||
const body = document.createElementNS(dom.HTML_NS, 'body');
|
||||
@@ -124,7 +124,7 @@ export class TextInputBubble extends Bubble {
|
||||
|
||||
const textArea = document.createElementNS(
|
||||
dom.HTML_NS,
|
||||
'textarea'
|
||||
'textarea',
|
||||
) as HTMLTextAreaElement;
|
||||
textArea.className = 'blocklyCommentTextarea';
|
||||
textArea.setAttribute('dir', this.workspace.RTL ? 'RTL' : 'LTR');
|
||||
@@ -152,7 +152,7 @@ export class TextInputBubble extends Bubble {
|
||||
'focus',
|
||||
this,
|
||||
this.onStartEdit,
|
||||
true
|
||||
true,
|
||||
);
|
||||
browserEvents.conditionalBind(textArea, 'change', this, this.onTextChange);
|
||||
}
|
||||
@@ -164,13 +164,13 @@ export class TextInputBubble extends Bubble {
|
||||
{
|
||||
'class': this.workspace.RTL ? 'blocklyResizeSW' : 'blocklyResizeSE',
|
||||
},
|
||||
container
|
||||
container,
|
||||
);
|
||||
const size = 2 * Bubble.BORDER_WIDTH;
|
||||
dom.createSvgElement(
|
||||
Svg.POLYGON,
|
||||
{'points': `0,${size} ${size},${size} ${size},0`},
|
||||
resizeGroup
|
||||
resizeGroup,
|
||||
);
|
||||
dom.createSvgElement(
|
||||
Svg.LINE,
|
||||
@@ -181,7 +181,7 @@ export class TextInputBubble extends Bubble {
|
||||
'x2': size - 1,
|
||||
'y2': size / 3,
|
||||
},
|
||||
resizeGroup
|
||||
resizeGroup,
|
||||
);
|
||||
dom.createSvgElement(
|
||||
Svg.LINE,
|
||||
@@ -192,14 +192,14 @@ export class TextInputBubble extends Bubble {
|
||||
'x2': size - 1,
|
||||
'y2': (size * 2) / 3,
|
||||
},
|
||||
resizeGroup
|
||||
resizeGroup,
|
||||
);
|
||||
|
||||
browserEvents.conditionalBind(
|
||||
resizeGroup,
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onResizePointerDown
|
||||
this.onResizePointerDown,
|
||||
);
|
||||
|
||||
return resizeGroup;
|
||||
@@ -227,12 +227,12 @@ export class TextInputBubble extends Bubble {
|
||||
if (this.workspace.RTL) {
|
||||
this.resizeGroup.setAttribute(
|
||||
'transform',
|
||||
`translate(${Bubble.DOUBLE_BORDER}, ${heightMinusBorder}) scale(-1 1)`
|
||||
`translate(${Bubble.DOUBLE_BORDER}, ${heightMinusBorder}) scale(-1 1)`,
|
||||
);
|
||||
} else {
|
||||
this.resizeGroup.setAttribute(
|
||||
'transform',
|
||||
`translate(${widthMinusBorder}, ${heightMinusBorder})`
|
||||
`translate(${widthMinusBorder}, ${heightMinusBorder})`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -258,21 +258,21 @@ export class TextInputBubble extends Bubble {
|
||||
e,
|
||||
new Coordinate(
|
||||
this.workspace.RTL ? -this.getSize().width : this.getSize().width,
|
||||
this.getSize().height
|
||||
)
|
||||
this.getSize().height,
|
||||
),
|
||||
);
|
||||
|
||||
this.resizePointerUpListener = browserEvents.conditionalBind(
|
||||
document,
|
||||
'pointerup',
|
||||
this,
|
||||
this.onResizePointerUp
|
||||
this.onResizePointerUp,
|
||||
);
|
||||
this.resizePointerMoveListener = browserEvents.conditionalBind(
|
||||
document,
|
||||
'pointermove',
|
||||
this,
|
||||
this.onResizePointerMove
|
||||
this.onResizePointerMove,
|
||||
);
|
||||
this.workspace.hideChaff();
|
||||
// This event has been handled. No need to bubble up to the document.
|
||||
@@ -297,7 +297,7 @@ export class TextInputBubble extends Bubble {
|
||||
const delta = this.workspace.moveDrag(e);
|
||||
this.setSize(
|
||||
new Size(this.workspace.RTL ? -delta.x : delta.x, delta.y),
|
||||
false
|
||||
false,
|
||||
);
|
||||
this.onSizeChange();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import type {WorkspaceSvg} from './workspace_svg.js';
|
||||
function bumpObjectIntoBounds(
|
||||
workspace: WorkspaceSvg,
|
||||
bounds: ContainerRegion,
|
||||
object: IBoundedElement
|
||||
object: IBoundedElement,
|
||||
): boolean {
|
||||
// Compute new top/left position for object.
|
||||
const objectMetrics = object.getBoundingRectangle();
|
||||
@@ -50,7 +50,7 @@ function bumpObjectIntoBounds(
|
||||
const newYPosition = mathUtils.clamp(
|
||||
topClamp,
|
||||
objectMetrics.top,
|
||||
bottomClamp
|
||||
bottomClamp,
|
||||
);
|
||||
const deltaY = newYPosition - objectMetrics.top;
|
||||
|
||||
@@ -73,7 +73,7 @@ function bumpObjectIntoBounds(
|
||||
const newXPosition = mathUtils.clamp(
|
||||
leftClamp,
|
||||
objectMetrics.left,
|
||||
rightClamp
|
||||
rightClamp,
|
||||
);
|
||||
const deltaX = newXPosition - objectMetrics.left;
|
||||
|
||||
@@ -92,7 +92,7 @@ export const bumpIntoBounds = bumpObjectIntoBounds;
|
||||
* @returns The event handler.
|
||||
*/
|
||||
export function bumpIntoBoundsHandler(
|
||||
workspace: WorkspaceSvg
|
||||
workspace: WorkspaceSvg,
|
||||
): (p1: Abstract) => void {
|
||||
return (e) => {
|
||||
const metricsManager = workspace.getMetricsManager();
|
||||
@@ -106,7 +106,7 @@ export function bumpIntoBoundsHandler(
|
||||
// Triggered by move/create event
|
||||
const object = extractObjectFromEvent(
|
||||
workspace,
|
||||
e as eventUtils.BumpEvent
|
||||
e as eventUtils.BumpEvent,
|
||||
);
|
||||
if (!object) {
|
||||
return;
|
||||
@@ -118,13 +118,13 @@ export function bumpIntoBoundsHandler(
|
||||
const wasBumped = bumpObjectIntoBounds(
|
||||
workspace,
|
||||
scrollMetricsInWsCoords,
|
||||
object as IBoundedElement
|
||||
object as IBoundedElement,
|
||||
);
|
||||
|
||||
if (wasBumped && !e.group) {
|
||||
console.warn(
|
||||
'Moved object in bounds but there was no' +
|
||||
' event group. This may break undo.'
|
||||
' event group. This may break undo.',
|
||||
);
|
||||
}
|
||||
eventUtils.setGroup(existingGroup);
|
||||
@@ -152,7 +152,7 @@ export function bumpIntoBoundsHandler(
|
||||
*/
|
||||
function extractObjectFromEvent(
|
||||
workspace: WorkspaceSvg,
|
||||
e: eventUtils.BumpEvent
|
||||
e: eventUtils.BumpEvent,
|
||||
): BlockSvg | null | WorkspaceCommentSvg {
|
||||
let object = null;
|
||||
switch (e.type) {
|
||||
@@ -166,7 +166,7 @@ function extractObjectFromEvent(
|
||||
case eventUtils.COMMENT_CREATE:
|
||||
case eventUtils.COMMENT_MOVE:
|
||||
object = workspace.getCommentById(
|
||||
(e as CommentCreate | CommentMove).commentId!
|
||||
(e as CommentCreate | CommentMove).commentId!,
|
||||
) as WorkspaceCommentSvg | null;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ export const draggingConnections: Connection[] = [];
|
||||
*/
|
||||
export function getBlockTypeCounts(
|
||||
block: Block,
|
||||
opt_stripFollowing?: boolean
|
||||
opt_stripFollowing?: boolean,
|
||||
): {[key: string]: number} {
|
||||
const typeCountsMap = Object.create(null);
|
||||
const descendants = block.getDescendants(true);
|
||||
@@ -249,7 +249,7 @@ function defineBlocksWithJsonArrayInternal(jsonArray: AnyDuringMigration[]) {
|
||||
* definitions created.
|
||||
*/
|
||||
export function createBlockDefinitionsFromJsonArray(
|
||||
jsonArray: AnyDuringMigration[]
|
||||
jsonArray: AnyDuringMigration[],
|
||||
): {[key: string]: BlockDefinition} {
|
||||
const blocks: {[key: string]: BlockDefinition} = {};
|
||||
for (let i = 0; i < jsonArray.length; i++) {
|
||||
@@ -262,7 +262,7 @@ export function createBlockDefinitionsFromJsonArray(
|
||||
if (!type) {
|
||||
console.warn(
|
||||
`Block definition #${i} in JSON array is missing a type attribute. ` +
|
||||
'Skipping.'
|
||||
'Skipping.',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ export class ComponentManager {
|
||||
id +
|
||||
'" with capabilities "' +
|
||||
this.componentData.get(id)?.capabilities +
|
||||
'" already added.'
|
||||
'" already added.',
|
||||
);
|
||||
}
|
||||
this.componentData.set(id, componentInfo);
|
||||
@@ -117,12 +117,12 @@ export class ComponentManager {
|
||||
capability +
|
||||
'". Plugin "' +
|
||||
id +
|
||||
'" has not been added to the ComponentManager'
|
||||
'" has not been added to the ComponentManager',
|
||||
);
|
||||
}
|
||||
if (this.hasCapability(id, capability)) {
|
||||
console.warn(
|
||||
'Plugin "' + id + 'already has capability "' + capability + '"'
|
||||
'Plugin "' + id + 'already has capability "' + capability + '"',
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ export class ComponentManager {
|
||||
capability +
|
||||
'". Plugin "' +
|
||||
id +
|
||||
'" has not been added to the ComponentManager'
|
||||
'" has not been added to the ComponentManager',
|
||||
);
|
||||
}
|
||||
if (!this.hasCapability(id, capability)) {
|
||||
@@ -153,7 +153,7 @@ export class ComponentManager {
|
||||
id +
|
||||
'doesn\'t have capability "' +
|
||||
capability +
|
||||
'" to remove'
|
||||
'" to remove',
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ export class ComponentManager {
|
||||
*/
|
||||
getComponents<T extends IComponent>(
|
||||
capability: string | Capability<T>,
|
||||
sorted: boolean
|
||||
sorted: boolean,
|
||||
): T[] {
|
||||
capability = `${capability}`.toLowerCase();
|
||||
const componentIds = this.capabilityToComponentIds.get(capability);
|
||||
|
||||
@@ -75,7 +75,10 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
* @param source The block establishing this connection.
|
||||
* @param type The type of the connection.
|
||||
*/
|
||||
constructor(source: Block, public type: number) {
|
||||
constructor(
|
||||
source: Block,
|
||||
public type: number,
|
||||
) {
|
||||
this.sourceBlock_ = source;
|
||||
}
|
||||
|
||||
@@ -113,7 +116,7 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
let event;
|
||||
if (eventUtils.isEnabled()) {
|
||||
event = new (eventUtils.get(eventUtils.BLOCK_MOVE))(
|
||||
childBlock
|
||||
childBlock,
|
||||
) as BlockMove;
|
||||
event.setReason(['connect']);
|
||||
}
|
||||
@@ -133,7 +136,7 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
if (!orphanConnection) return;
|
||||
const connection = Connection.getConnectionForOrphanedConnection(
|
||||
childBlock,
|
||||
orphanConnection
|
||||
orphanConnection,
|
||||
);
|
||||
if (connection) {
|
||||
orphanConnection.connect(connection);
|
||||
@@ -278,7 +281,7 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
let event;
|
||||
if (eventUtils.isEnabled()) {
|
||||
event = new (eventUtils.get(eventUtils.BLOCK_MOVE))(
|
||||
childConnection.getSourceBlock()
|
||||
childConnection.getSourceBlock(),
|
||||
) as BlockMove;
|
||||
event.setReason(['disconnect']);
|
||||
}
|
||||
@@ -386,7 +389,7 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
!this.getConnectionChecker().canConnect(
|
||||
this,
|
||||
this.targetConnection,
|
||||
false
|
||||
false,
|
||||
))
|
||||
) {
|
||||
const child = this.isSuperior() ? this.targetBlock() : this.sourceBlock_;
|
||||
@@ -648,7 +651,7 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
}
|
||||
|
||||
if (shadowDom) {
|
||||
blockShadow = Xml.domToBlock(shadowDom, parentBlock.workspace);
|
||||
blockShadow = Xml.domToBlockInternal(shadowDom, parentBlock.workspace);
|
||||
if (attemptToConnect) {
|
||||
if (this.type === ConnectionType.INPUT_VALUE) {
|
||||
if (!blockShadow.outputConnection) {
|
||||
@@ -666,7 +669,7 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'Cannot connect a shadow block to a previous/output connection'
|
||||
'Cannot connect a shadow block to a previous/output connection',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -700,12 +703,12 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
*/
|
||||
static getConnectionForOrphanedConnection(
|
||||
startBlock: Block,
|
||||
orphanConnection: Connection
|
||||
orphanConnection: Connection,
|
||||
): Connection | null {
|
||||
if (orphanConnection.type === ConnectionType.OUTPUT_VALUE) {
|
||||
return getConnectionForOrphanedOutput(
|
||||
startBlock,
|
||||
orphanConnection.getSourceBlock()
|
||||
orphanConnection.getSourceBlock(),
|
||||
);
|
||||
}
|
||||
// Otherwise we're dealing with a stack.
|
||||
@@ -743,7 +746,7 @@ function connectReciprocally(first: Connection, second: Connection) {
|
||||
*/
|
||||
function getSingleConnection(
|
||||
block: Block,
|
||||
orphanBlock: Block
|
||||
orphanBlock: Block,
|
||||
): Connection | null {
|
||||
let foundConnection = null;
|
||||
const output = orphanBlock.outputConnection;
|
||||
@@ -774,7 +777,7 @@ function getSingleConnection(
|
||||
*/
|
||||
function getConnectionForOrphanedOutput(
|
||||
startBlock: Block,
|
||||
orphanBlock: Block
|
||||
orphanBlock: Block,
|
||||
): Connection | null {
|
||||
let newBlock: Block | null = startBlock;
|
||||
let connection;
|
||||
|
||||
@@ -40,7 +40,7 @@ export class ConnectionChecker implements IConnectionChecker {
|
||||
a: Connection | null,
|
||||
b: Connection | null,
|
||||
isDragging: boolean,
|
||||
opt_distance?: number
|
||||
opt_distance?: number,
|
||||
): boolean {
|
||||
return (
|
||||
this.canConnectWithReason(a, b, isDragging, opt_distance) ===
|
||||
@@ -64,7 +64,7 @@ export class ConnectionChecker implements IConnectionChecker {
|
||||
a: Connection | null,
|
||||
b: Connection | null,
|
||||
isDragging: boolean,
|
||||
opt_distance?: number
|
||||
opt_distance?: number,
|
||||
): number {
|
||||
const safety = this.doSafetyChecks(a, b);
|
||||
if (safety !== Connection.CAN_CONNECT) {
|
||||
@@ -83,7 +83,7 @@ export class ConnectionChecker implements IConnectionChecker {
|
||||
!this.doDragChecks(
|
||||
a as RenderedConnection,
|
||||
b as RenderedConnection,
|
||||
opt_distance || 0
|
||||
opt_distance || 0,
|
||||
)
|
||||
) {
|
||||
return Connection.REASON_DRAG_CHECKS_FAILED;
|
||||
@@ -103,7 +103,7 @@ export class ConnectionChecker implements IConnectionChecker {
|
||||
getErrorMessage(
|
||||
errorCode: number,
|
||||
a: Connection | null,
|
||||
b: Connection | null
|
||||
b: Connection | null,
|
||||
): string {
|
||||
switch (errorCode) {
|
||||
case Connection.REASON_SELF_CONNECTION:
|
||||
@@ -230,7 +230,7 @@ export class ConnectionChecker implements IConnectionChecker {
|
||||
doDragChecks(
|
||||
a: RenderedConnection,
|
||||
b: RenderedConnection,
|
||||
distance: number
|
||||
distance: number,
|
||||
): boolean {
|
||||
if (a.distanceFrom(b) > distance) {
|
||||
return false;
|
||||
@@ -345,5 +345,5 @@ export class ConnectionChecker implements IConnectionChecker {
|
||||
registry.register(
|
||||
registry.Type.CONNECTION_CHECKER,
|
||||
registry.DEFAULT,
|
||||
ConnectionChecker
|
||||
ConnectionChecker,
|
||||
);
|
||||
|
||||
@@ -59,7 +59,7 @@ export class ConnectionDB {
|
||||
*/
|
||||
private findIndexOfConnection(
|
||||
conn: RenderedConnection,
|
||||
yPos: number
|
||||
yPos: number,
|
||||
): number {
|
||||
if (!this.connections.length) {
|
||||
return -1;
|
||||
@@ -145,7 +145,7 @@ export class ConnectionDB {
|
||||
*/
|
||||
getNeighbours(
|
||||
connection: RenderedConnection,
|
||||
maxRadius: number
|
||||
maxRadius: number,
|
||||
): RenderedConnection[] {
|
||||
const db = this.connections;
|
||||
const currentX = connection.x;
|
||||
@@ -225,7 +225,7 @@ export class ConnectionDB {
|
||||
searchForClosest(
|
||||
conn: RenderedConnection,
|
||||
maxRadius: number,
|
||||
dxy: Coordinate
|
||||
dxy: Coordinate,
|
||||
): {connection: RenderedConnection | null; radius: number} {
|
||||
if (!this.connections.length) {
|
||||
// Don't bother.
|
||||
|
||||
@@ -70,7 +70,7 @@ let menu_: Menu | null = null;
|
||||
export function show(
|
||||
e: Event,
|
||||
options: (ContextMenuOption | LegacyContextMenuOption)[],
|
||||
rtl: boolean
|
||||
rtl: boolean,
|
||||
) {
|
||||
WidgetDiv.show(dummyOwner, rtl, dispose);
|
||||
if (!options.length) {
|
||||
@@ -98,7 +98,7 @@ export function show(
|
||||
*/
|
||||
function populate_(
|
||||
options: (ContextMenuOption | LegacyContextMenuOption)[],
|
||||
rtl: boolean
|
||||
rtl: boolean,
|
||||
): Menu {
|
||||
/* Here's what one option object looks like:
|
||||
{text: 'Make It So',
|
||||
@@ -151,7 +151,7 @@ function position_(menu: Menu, e: Event, rtl: boolean) {
|
||||
mouseEvent.clientY + viewportBBox.top,
|
||||
mouseEvent.clientY + viewportBBox.top,
|
||||
mouseEvent.clientX + viewportBBox.left,
|
||||
mouseEvent.clientX + viewportBBox.left
|
||||
mouseEvent.clientX + viewportBBox.left,
|
||||
);
|
||||
|
||||
createWidget_(menu);
|
||||
@@ -188,7 +188,7 @@ function createWidget_(menu: Menu) {
|
||||
menuDom as EventTarget,
|
||||
'contextmenu',
|
||||
null,
|
||||
haltPropagation
|
||||
haltPropagation,
|
||||
);
|
||||
// Focus only after the initial render to avoid issue #1329.
|
||||
menu.focus();
|
||||
@@ -235,7 +235,7 @@ export function callbackFactory(block: Block, xml: Element): () => void {
|
||||
eventUtils.disable();
|
||||
let newBlock;
|
||||
try {
|
||||
newBlock = Xml.domToBlock(xml, block.workspace!) as BlockSvg;
|
||||
newBlock = Xml.domToBlockInternal(xml, block.workspace!) as BlockSvg;
|
||||
// Move the new block next to the old block.
|
||||
const xy = block.getRelativeToSurfaceXY();
|
||||
if (block.RTL) {
|
||||
@@ -267,7 +267,7 @@ export function callbackFactory(block: Block, xml: Element): () => void {
|
||||
* @internal
|
||||
*/
|
||||
export function commentDeleteOption(
|
||||
comment: WorkspaceCommentSvg
|
||||
comment: WorkspaceCommentSvg,
|
||||
): LegacyContextMenuOption {
|
||||
const deleteOption = {
|
||||
text: Msg['REMOVE_COMMENT'],
|
||||
@@ -291,7 +291,7 @@ export function commentDeleteOption(
|
||||
* @internal
|
||||
*/
|
||||
export function commentDuplicateOption(
|
||||
comment: WorkspaceCommentSvg
|
||||
comment: WorkspaceCommentSvg,
|
||||
): LegacyContextMenuOption {
|
||||
const duplicateOption = {
|
||||
text: Msg['DUPLICATE_COMMENT'],
|
||||
@@ -315,7 +315,7 @@ export function commentDuplicateOption(
|
||||
*/
|
||||
export function workspaceCommentOption(
|
||||
ws: WorkspaceSvg,
|
||||
e: Event
|
||||
e: Event,
|
||||
): ContextMenuOption {
|
||||
/**
|
||||
* Helper function to create and position a comment correctly based on the
|
||||
@@ -326,7 +326,7 @@ export function workspaceCommentOption(
|
||||
ws,
|
||||
Msg['WORKSPACE_COMMENT_DEFAULT_TEXT'],
|
||||
WorkspaceCommentSvg.DEFAULT_SIZE,
|
||||
WorkspaceCommentSvg.DEFAULT_SIZE
|
||||
WorkspaceCommentSvg.DEFAULT_SIZE,
|
||||
);
|
||||
|
||||
const injectionDiv = ws.getInjectionDiv();
|
||||
@@ -339,7 +339,7 @@ export function workspaceCommentOption(
|
||||
const mouseEvent = e as MouseEvent;
|
||||
const clientOffsetPixels = new Coordinate(
|
||||
mouseEvent.clientX - boundingRect.left,
|
||||
mouseEvent.clientY - boundingRect.top
|
||||
mouseEvent.clientY - boundingRect.top,
|
||||
);
|
||||
|
||||
// The offset in pixels between the main workspace's origin and the upper
|
||||
@@ -350,7 +350,7 @@ export function workspaceCommentOption(
|
||||
// main workspace.
|
||||
const finalOffset = Coordinate.difference(
|
||||
clientOffsetPixels,
|
||||
mainOffsetPixels
|
||||
mainOffsetPixels,
|
||||
);
|
||||
// The position of the new comment in main workspace coordinates.
|
||||
finalOffset.scale(1 / ws.scale);
|
||||
|
||||
@@ -286,13 +286,13 @@ export function registerDeleteAll() {
|
||||
dialog.confirm(
|
||||
Msg['DELETE_ALL_BLOCKS'].replace(
|
||||
'%1',
|
||||
String(deletableBlocks.length)
|
||||
String(deletableBlocks.length),
|
||||
),
|
||||
function (ok) {
|
||||
if (ok) {
|
||||
deleteNext_(deletableBlocks);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ export class ContextMenuRegistry {
|
||||
*/
|
||||
getContextMenuOptions(
|
||||
scopeType: ScopeType,
|
||||
scope: Scope
|
||||
scope: Scope,
|
||||
): ContextMenuOption[] {
|
||||
const menuOptions: ContextMenuOption[] = [];
|
||||
for (const item of this.registry_.values()) {
|
||||
|
||||
@@ -9,7 +9,7 @@ goog.declareModuleId('Blockly.dialog');
|
||||
|
||||
let alertImplementation = function (
|
||||
message: string,
|
||||
opt_callback?: () => void
|
||||
opt_callback?: () => void,
|
||||
) {
|
||||
window.alert(message);
|
||||
if (opt_callback) {
|
||||
@@ -19,7 +19,7 @@ let alertImplementation = function (
|
||||
|
||||
let confirmImplementation = function (
|
||||
message: string,
|
||||
callback: (result: boolean) => void
|
||||
callback: (result: boolean) => void,
|
||||
) {
|
||||
callback(window.confirm(message));
|
||||
};
|
||||
@@ -27,7 +27,7 @@ let confirmImplementation = function (
|
||||
let promptImplementation = function (
|
||||
message: string,
|
||||
defaultValue: string,
|
||||
callback: (result: string | null) => void
|
||||
callback: (result: string | null) => void,
|
||||
) {
|
||||
callback(window.prompt(message, defaultValue));
|
||||
};
|
||||
@@ -78,7 +78,7 @@ function confirmInternal(message: string, callback: (p1: boolean) => void) {
|
||||
* @see Blockly.dialog.confirm
|
||||
*/
|
||||
export function setConfirm(
|
||||
confirmFunction: (p1: string, p2: (p1: boolean) => void) => void
|
||||
confirmFunction: (p1: string, p2: (p1: boolean) => void) => void,
|
||||
) {
|
||||
confirmImplementation = confirmFunction;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ export function setConfirm(
|
||||
export function prompt(
|
||||
message: string,
|
||||
defaultValue: string,
|
||||
callback: (p1: string | null) => void
|
||||
callback: (p1: string | null) => void,
|
||||
) {
|
||||
promptImplementation(message, defaultValue, callback);
|
||||
}
|
||||
@@ -111,8 +111,8 @@ export function setPrompt(
|
||||
promptFunction: (
|
||||
p1: string,
|
||||
p2: string,
|
||||
p3: (p1: string | null) => void
|
||||
) => void
|
||||
p3: (p1: string | null) => void,
|
||||
) => void,
|
||||
) {
|
||||
promptImplementation = promptFunction;
|
||||
}
|
||||
|
||||
@@ -204,13 +204,13 @@ export function showPositionedByBlock<T>(
|
||||
field: Field<T>,
|
||||
block: BlockSvg,
|
||||
opt_onHide?: Function,
|
||||
opt_secondaryYOffset?: number
|
||||
opt_secondaryYOffset?: number,
|
||||
): boolean {
|
||||
return showPositionedByRect(
|
||||
getScaledBboxOfBlock(block),
|
||||
field as Field,
|
||||
opt_onHide,
|
||||
opt_secondaryYOffset
|
||||
opt_secondaryYOffset,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -228,14 +228,14 @@ export function showPositionedByBlock<T>(
|
||||
export function showPositionedByField<T>(
|
||||
field: Field<T>,
|
||||
opt_onHide?: Function,
|
||||
opt_secondaryYOffset?: number
|
||||
opt_secondaryYOffset?: number,
|
||||
): boolean {
|
||||
positionToField = true;
|
||||
return showPositionedByRect(
|
||||
getScaledBboxOfField(field as Field),
|
||||
field as Field,
|
||||
opt_onHide,
|
||||
opt_secondaryYOffset
|
||||
opt_secondaryYOffset,
|
||||
);
|
||||
}
|
||||
/**
|
||||
@@ -280,7 +280,7 @@ function showPositionedByRect(
|
||||
bBox: Rect,
|
||||
field: Field,
|
||||
opt_onHide?: Function,
|
||||
opt_secondaryYOffset?: number
|
||||
opt_secondaryYOffset?: number,
|
||||
): boolean {
|
||||
// If we can fit it, render below the block.
|
||||
const primaryX = bBox.left + (bBox.right - bBox.left) / 2;
|
||||
@@ -305,7 +305,7 @@ function showPositionedByRect(
|
||||
primaryY,
|
||||
secondaryX,
|
||||
secondaryY,
|
||||
opt_onHide
|
||||
opt_onHide,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ export function show<T>(
|
||||
primaryY: number,
|
||||
secondaryX: number,
|
||||
secondaryY: number,
|
||||
opt_onHide?: Function
|
||||
opt_onHide?: Function,
|
||||
): boolean {
|
||||
owner = newOwner as Field;
|
||||
onHide = opt_onHide || null;
|
||||
@@ -399,7 +399,7 @@ const internal = {
|
||||
primaryX: number,
|
||||
primaryY: number,
|
||||
secondaryX: number,
|
||||
secondaryY: number
|
||||
secondaryY: number,
|
||||
): PositionMetrics {
|
||||
const boundsInfo = internal.getBoundsInfo();
|
||||
const divSize = style.getSize(div as Element);
|
||||
@@ -414,7 +414,7 @@ const internal = {
|
||||
secondaryX,
|
||||
secondaryY,
|
||||
boundsInfo,
|
||||
divSize
|
||||
divSize,
|
||||
);
|
||||
}
|
||||
// Can we fit outside the workspace bounds (but inside the window)
|
||||
@@ -429,7 +429,7 @@ const internal = {
|
||||
secondaryX,
|
||||
secondaryY,
|
||||
boundsInfo,
|
||||
divSize
|
||||
divSize,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -454,13 +454,13 @@ function getPositionBelowMetrics(
|
||||
primaryX: number,
|
||||
primaryY: number,
|
||||
boundsInfo: BoundsInfo,
|
||||
divSize: Size
|
||||
divSize: Size,
|
||||
): PositionMetrics {
|
||||
const xCoords = getPositionX(
|
||||
primaryX,
|
||||
boundsInfo.left,
|
||||
boundsInfo.right,
|
||||
divSize.width
|
||||
divSize.width,
|
||||
);
|
||||
|
||||
const arrowY = -(ARROW_SIZE / 2 + BORDER_SIZE);
|
||||
@@ -494,13 +494,13 @@ function getPositionAboveMetrics(
|
||||
secondaryX: number,
|
||||
secondaryY: number,
|
||||
boundsInfo: BoundsInfo,
|
||||
divSize: Size
|
||||
divSize: Size,
|
||||
): PositionMetrics {
|
||||
const xCoords = getPositionX(
|
||||
secondaryX,
|
||||
boundsInfo.left,
|
||||
boundsInfo.right,
|
||||
divSize.width
|
||||
divSize.width,
|
||||
);
|
||||
|
||||
const arrowY = divSize.height - BORDER_SIZE * 2 - ARROW_SIZE / 2;
|
||||
@@ -533,13 +533,13 @@ function getPositionAboveMetrics(
|
||||
function getPositionTopOfPageMetrics(
|
||||
sourceX: number,
|
||||
boundsInfo: BoundsInfo,
|
||||
divSize: Size
|
||||
divSize: Size,
|
||||
): PositionMetrics {
|
||||
const xCoords = getPositionX(
|
||||
sourceX,
|
||||
boundsInfo.left,
|
||||
boundsInfo.right,
|
||||
divSize.width
|
||||
divSize.width,
|
||||
);
|
||||
|
||||
// No need to provide arrow-specific information because it won't be visible.
|
||||
@@ -571,7 +571,7 @@ export function getPositionX(
|
||||
sourceX: number,
|
||||
boundsLeft: number,
|
||||
boundsRight: number,
|
||||
divWidth: number
|
||||
divWidth: number,
|
||||
): {divX: number; arrowX: number} {
|
||||
let divX = sourceX;
|
||||
// Offset the topLeft coord so that the dropdowndiv is centered.
|
||||
@@ -589,7 +589,7 @@ export function getPositionX(
|
||||
relativeArrowX = math.clamp(
|
||||
horizPadding,
|
||||
relativeArrowX,
|
||||
divWidth - horizPadding - ARROW_SIZE
|
||||
divWidth - horizPadding - ARROW_SIZE,
|
||||
);
|
||||
|
||||
return {arrowX: relativeArrowX, divX};
|
||||
@@ -614,7 +614,7 @@ export function isVisible(): boolean {
|
||||
*/
|
||||
export function hideIfOwner<T>(
|
||||
divOwner: Field<T>,
|
||||
opt_withoutAnimation?: boolean
|
||||
opt_withoutAnimation?: boolean,
|
||||
): boolean {
|
||||
if (owner === divOwner) {
|
||||
if (opt_withoutAnimation) {
|
||||
@@ -693,13 +693,13 @@ function positionInternal(
|
||||
primaryX: number,
|
||||
primaryY: number,
|
||||
secondaryX: number,
|
||||
secondaryY: number
|
||||
secondaryY: number,
|
||||
): boolean {
|
||||
const metrics = internal.getPositionMetrics(
|
||||
primaryX,
|
||||
primaryY,
|
||||
secondaryX,
|
||||
secondaryY
|
||||
secondaryY,
|
||||
);
|
||||
|
||||
// Update arrow CSS.
|
||||
@@ -715,7 +715,7 @@ function positionInternal(
|
||||
'class',
|
||||
metrics.arrowAtTop
|
||||
? 'blocklyDropDownArrow blocklyArrowTop'
|
||||
: 'blocklyDropDownArrow blocklyArrowBottom'
|
||||
: 'blocklyDropDownArrow blocklyArrowBottom',
|
||||
);
|
||||
} else {
|
||||
arrow.style.display = 'none';
|
||||
|
||||
@@ -77,7 +77,7 @@ export abstract class Abstract {
|
||||
static fromJson(
|
||||
json: AbstractEventJson,
|
||||
workspace: Workspace,
|
||||
event: any
|
||||
event: any,
|
||||
): Abstract {
|
||||
event.isBlank = false;
|
||||
event.group = json['group'] || '';
|
||||
@@ -119,7 +119,7 @@ export abstract class Abstract {
|
||||
if (!workspace) {
|
||||
throw Error(
|
||||
'Workspace is null. Event must have been generated from real' +
|
||||
' Blockly events.'
|
||||
' Blockly events.',
|
||||
);
|
||||
}
|
||||
return workspace;
|
||||
|
||||
@@ -53,7 +53,7 @@ export class BlockBase extends AbstractEvent {
|
||||
if (!this.blockId) {
|
||||
throw new Error(
|
||||
'The block ID is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['blockId'] = this.blockId;
|
||||
@@ -72,12 +72,12 @@ export class BlockBase extends AbstractEvent {
|
||||
static fromJson(
|
||||
json: BlockBaseJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockBase {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockBase()
|
||||
event ?? new BlockBase(),
|
||||
) as BlockBase;
|
||||
newEvent.blockId = json['blockId'];
|
||||
return newEvent;
|
||||
|
||||
@@ -57,7 +57,7 @@ export class BlockChange extends BlockBase {
|
||||
opt_element?: string,
|
||||
opt_name?: string | null,
|
||||
opt_oldValue?: unknown,
|
||||
opt_newValue?: unknown
|
||||
opt_newValue?: unknown,
|
||||
) {
|
||||
super(opt_block);
|
||||
|
||||
@@ -80,7 +80,7 @@ export class BlockChange extends BlockBase {
|
||||
if (!this.element) {
|
||||
throw new Error(
|
||||
'The changed element is undefined. Either pass an ' +
|
||||
'element to the constructor, or call fromJson'
|
||||
'element to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['element'] = this.element;
|
||||
@@ -102,12 +102,12 @@ export class BlockChange extends BlockBase {
|
||||
static fromJson(
|
||||
json: BlockChangeJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockChange {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockChange()
|
||||
event ?? new BlockChange(),
|
||||
) as BlockChange;
|
||||
newEvent.element = json['element'];
|
||||
newEvent.name = json['name'];
|
||||
@@ -135,14 +135,14 @@ export class BlockChange extends BlockBase {
|
||||
if (!this.blockId) {
|
||||
throw new Error(
|
||||
'The block ID is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
const block = workspace.getBlockById(this.blockId);
|
||||
if (!block) {
|
||||
throw new Error(
|
||||
'The associated block is undefined. Either pass a ' +
|
||||
'block to the constructor, or call fromJson'
|
||||
'block to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
// Assume the block is rendered so that then we can check.
|
||||
@@ -180,11 +180,11 @@ export class BlockChange extends BlockBase {
|
||||
block.loadExtraState(JSON.parse((value as string) || '{}'));
|
||||
} else if (block.domToMutation) {
|
||||
block.domToMutation(
|
||||
utilsXml.textToDom((value as string) || '<mutation/>')
|
||||
utilsXml.textToDom((value as string) || '<mutation/>'),
|
||||
);
|
||||
}
|
||||
eventUtils.fire(
|
||||
new BlockChange(block, 'mutation', null, oldState, value)
|
||||
new BlockChange(block, 'mutation', null, oldState, value),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -67,19 +67,19 @@ export class BlockCreate extends BlockBase {
|
||||
if (!this.xml) {
|
||||
throw new Error(
|
||||
'The block XML is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.ids) {
|
||||
throw new Error(
|
||||
'The block IDs are undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.json) {
|
||||
throw new Error(
|
||||
'The block JSON is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['xml'] = Xml.domToText(this.xml);
|
||||
@@ -103,12 +103,12 @@ export class BlockCreate extends BlockBase {
|
||||
static fromJson(
|
||||
json: BlockCreateJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockCreate {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockCreate()
|
||||
event ?? new BlockCreate(),
|
||||
) as BlockCreate;
|
||||
newEvent.xml = utilsXml.textToDom(json['xml']);
|
||||
newEvent.ids = json['ids'];
|
||||
@@ -129,13 +129,13 @@ export class BlockCreate extends BlockBase {
|
||||
if (!this.json) {
|
||||
throw new Error(
|
||||
'The block JSON is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.ids) {
|
||||
throw new Error(
|
||||
'The block IDs are undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (forward) {
|
||||
|
||||
@@ -75,25 +75,25 @@ export class BlockDelete extends BlockBase {
|
||||
if (!this.oldXml) {
|
||||
throw new Error(
|
||||
'The old block XML is undefined. Either pass a block ' +
|
||||
'to the constructor, or call fromJson'
|
||||
'to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.ids) {
|
||||
throw new Error(
|
||||
'The block IDs are undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (this.wasShadow === undefined) {
|
||||
throw new Error(
|
||||
'Whether the block was a shadow is undefined. Either ' +
|
||||
'pass a block to the constructor, or call fromJson'
|
||||
'pass a block to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.oldJson) {
|
||||
throw new Error(
|
||||
'The old block JSON is undefined. Either pass a block ' +
|
||||
'to the constructor, or call fromJson'
|
||||
'to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['oldXml'] = Xml.domToText(this.oldXml);
|
||||
@@ -118,12 +118,12 @@ export class BlockDelete extends BlockBase {
|
||||
static fromJson(
|
||||
json: BlockDeleteJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockDelete {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockDelete()
|
||||
event ?? new BlockDelete(),
|
||||
) as BlockDelete;
|
||||
newEvent.oldXml = utilsXml.textToDom(json['oldXml']);
|
||||
newEvent.ids = json['ids'];
|
||||
@@ -146,13 +146,13 @@ export class BlockDelete extends BlockBase {
|
||||
if (!this.ids) {
|
||||
throw new Error(
|
||||
'The block IDs are undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.oldJson) {
|
||||
throw new Error(
|
||||
'The old block JSON is undefined. Either pass a block ' +
|
||||
'to the constructor, or call fromJson'
|
||||
'to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (forward) {
|
||||
|
||||
@@ -65,13 +65,13 @@ export class BlockDrag extends UiBase {
|
||||
if (this.isStart === undefined) {
|
||||
throw new Error(
|
||||
'Whether this event is the start of a drag is undefined. ' +
|
||||
'Either pass the value to the constructor, or call fromJson'
|
||||
'Either pass the value to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (this.blockId === undefined) {
|
||||
throw new Error(
|
||||
'The block ID is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['isStart'] = this.isStart;
|
||||
@@ -94,12 +94,12 @@ export class BlockDrag extends UiBase {
|
||||
static fromJson(
|
||||
json: BlockDragJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockDrag {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockDrag()
|
||||
event ?? new BlockDrag(),
|
||||
) as BlockDrag;
|
||||
newEvent.isStart = json['isStart'];
|
||||
newEvent.blockId = json['blockId'];
|
||||
|
||||
@@ -59,7 +59,7 @@ export class BlockFieldIntermediateChange extends BlockBase {
|
||||
opt_block?: Block,
|
||||
opt_name?: string,
|
||||
opt_oldValue?: unknown,
|
||||
opt_newValue?: unknown
|
||||
opt_newValue?: unknown,
|
||||
) {
|
||||
super(opt_block);
|
||||
if (!opt_block) {
|
||||
@@ -81,7 +81,7 @@ export class BlockFieldIntermediateChange extends BlockBase {
|
||||
if (!this.name) {
|
||||
throw new Error(
|
||||
'The changed field name is undefined. Either pass a ' +
|
||||
'name to the constructor, or call fromJson.'
|
||||
'name to the constructor, or call fromJson.',
|
||||
);
|
||||
}
|
||||
json['name'] = this.name;
|
||||
@@ -102,12 +102,12 @@ export class BlockFieldIntermediateChange extends BlockBase {
|
||||
static fromJson(
|
||||
json: BlockFieldIntermediateChangeJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockFieldIntermediateChange {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockFieldIntermediateChange()
|
||||
event ?? new BlockFieldIntermediateChange(),
|
||||
) as BlockFieldIntermediateChange;
|
||||
newEvent.name = json['name'];
|
||||
newEvent.oldValue = json['oldValue'];
|
||||
@@ -134,5 +134,5 @@ export interface BlockFieldIntermediateChangeJson extends BlockBaseJson {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.BLOCK_FIELD_INTERMEDIATE_CHANGE,
|
||||
BlockFieldIntermediateChange
|
||||
BlockFieldIntermediateChange,
|
||||
);
|
||||
|
||||
@@ -139,12 +139,12 @@ export class BlockMove extends BlockBase {
|
||||
static fromJson(
|
||||
json: BlockMoveJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BlockMove {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BlockMove()
|
||||
event ?? new BlockMove(),
|
||||
) as BlockMove;
|
||||
newEvent.oldParentId = json['oldParentId'];
|
||||
newEvent.oldInputName = json['oldInputName'];
|
||||
@@ -195,13 +195,14 @@ export class BlockMove extends BlockBase {
|
||||
if (!this.blockId) {
|
||||
throw new Error(
|
||||
'The block ID is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
const block = workspace.getBlockById(this.blockId);
|
||||
if (!block) {
|
||||
throw new Error(
|
||||
'The block associated with the block move event ' + 'could not be found'
|
||||
'The block associated with the block move event ' +
|
||||
'could not be found',
|
||||
);
|
||||
}
|
||||
const location = {} as BlockLocation;
|
||||
@@ -241,7 +242,7 @@ export class BlockMove extends BlockBase {
|
||||
if (!this.blockId) {
|
||||
throw new Error(
|
||||
'The block ID is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
const block = workspace.getBlockById(this.blockId);
|
||||
|
||||
@@ -44,7 +44,7 @@ export class BubbleOpen extends UiBase {
|
||||
constructor(
|
||||
opt_block?: BlockSvg,
|
||||
opt_isOpen?: boolean,
|
||||
opt_bubbleType?: BubbleType
|
||||
opt_bubbleType?: BubbleType,
|
||||
) {
|
||||
const workspaceId = opt_block ? opt_block.workspace.id : undefined;
|
||||
super(workspaceId);
|
||||
@@ -65,13 +65,13 @@ export class BubbleOpen extends UiBase {
|
||||
if (this.isOpen === undefined) {
|
||||
throw new Error(
|
||||
'Whether this event is for opening the bubble is undefined. ' +
|
||||
'Either pass the value to the constructor, or call fromJson'
|
||||
'Either pass the value to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.bubbleType) {
|
||||
throw new Error(
|
||||
'The type of bubble is undefined. Either pass the ' +
|
||||
'value to the constructor, or call fromJson'
|
||||
'value to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['isOpen'] = this.isOpen;
|
||||
@@ -92,12 +92,12 @@ export class BubbleOpen extends UiBase {
|
||||
static fromJson(
|
||||
json: BubbleOpenJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): BubbleOpen {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new BubbleOpen()
|
||||
event ?? new BubbleOpen(),
|
||||
) as BubbleOpen;
|
||||
newEvent.isOpen = json['isOpen'];
|
||||
newEvent.bubbleType = json['bubbleType'];
|
||||
|
||||
@@ -46,7 +46,7 @@ export class Click extends UiBase {
|
||||
constructor(
|
||||
opt_block?: Block | null,
|
||||
opt_workspaceId?: string | null,
|
||||
opt_targetType?: ClickTarget
|
||||
opt_targetType?: ClickTarget,
|
||||
) {
|
||||
let workspaceId = opt_block ? opt_block.workspace.id : opt_workspaceId;
|
||||
if (workspaceId === null) {
|
||||
@@ -68,7 +68,7 @@ export class Click extends UiBase {
|
||||
if (!this.targetType) {
|
||||
throw new Error(
|
||||
'The click target type is undefined. Either pass a block to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['targetType'] = this.targetType;
|
||||
@@ -89,7 +89,7 @@ export class Click extends UiBase {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new Click()
|
||||
event ?? new Click(),
|
||||
) as Click;
|
||||
newEvent.targetType = json['targetType'];
|
||||
newEvent.blockId = json['blockId'];
|
||||
|
||||
@@ -61,7 +61,7 @@ export class CommentBase extends AbstractEvent {
|
||||
if (!this.commentId) {
|
||||
throw new Error(
|
||||
'The comment ID is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['commentId'] = this.commentId;
|
||||
@@ -80,12 +80,12 @@ export class CommentBase extends AbstractEvent {
|
||||
static fromJson(
|
||||
json: CommentBaseJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): CommentBase {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new CommentBase()
|
||||
event ?? new CommentBase(),
|
||||
) as CommentBase;
|
||||
newEvent.commentId = json['commentId'];
|
||||
return newEvent;
|
||||
@@ -99,7 +99,7 @@ export class CommentBase extends AbstractEvent {
|
||||
*/
|
||||
static CommentCreateDeleteHelper(
|
||||
event: CommentCreate | CommentDelete,
|
||||
create: boolean
|
||||
create: boolean,
|
||||
) {
|
||||
const workspace = event.getEventWorkspace_();
|
||||
if (create) {
|
||||
@@ -113,7 +113,7 @@ export class CommentBase extends AbstractEvent {
|
||||
if (!event.commentId) {
|
||||
throw new Error(
|
||||
'The comment ID is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
const comment = workspace.getCommentById(event.commentId);
|
||||
|
||||
@@ -41,7 +41,7 @@ export class CommentChange extends CommentBase {
|
||||
constructor(
|
||||
opt_comment?: WorkspaceComment,
|
||||
opt_oldContents?: string,
|
||||
opt_newContents?: string
|
||||
opt_newContents?: string,
|
||||
) {
|
||||
super(opt_comment);
|
||||
|
||||
@@ -65,13 +65,13 @@ export class CommentChange extends CommentBase {
|
||||
if (!this.oldContents_) {
|
||||
throw new Error(
|
||||
'The old contents is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.newContents_) {
|
||||
throw new Error(
|
||||
'The new contents is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['oldContents'] = this.oldContents_;
|
||||
@@ -91,12 +91,12 @@ export class CommentChange extends CommentBase {
|
||||
static fromJson(
|
||||
json: CommentChangeJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): CommentChange {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new CommentChange()
|
||||
event ?? new CommentChange(),
|
||||
) as CommentChange;
|
||||
newEvent.oldContents_ = json['oldContents'];
|
||||
newEvent.newContents_ = json['newContents'];
|
||||
@@ -122,7 +122,7 @@ export class CommentChange extends CommentBase {
|
||||
if (!this.commentId) {
|
||||
throw new Error(
|
||||
'The comment ID is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
const comment = workspace.getCommentById(this.commentId);
|
||||
@@ -135,12 +135,12 @@ export class CommentChange extends CommentBase {
|
||||
if (forward) {
|
||||
throw new Error(
|
||||
'The new contents is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
'The old contents is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
comment.setContent(contents);
|
||||
@@ -155,5 +155,5 @@ export interface CommentChangeJson extends CommentBaseJson {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.COMMENT_CHANGE,
|
||||
CommentChange
|
||||
CommentChange,
|
||||
);
|
||||
|
||||
@@ -55,7 +55,7 @@ export class CommentCreate extends CommentBase {
|
||||
if (!this.xml) {
|
||||
throw new Error(
|
||||
'The comment XML is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['xml'] = Xml.domToText(this.xml);
|
||||
@@ -74,12 +74,12 @@ export class CommentCreate extends CommentBase {
|
||||
static fromJson(
|
||||
json: CommentCreateJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): CommentCreate {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new CommentCreate()
|
||||
event ?? new CommentCreate(),
|
||||
) as CommentCreate;
|
||||
newEvent.xml = utilsXml.textToDom(json['xml']);
|
||||
return newEvent;
|
||||
@@ -102,5 +102,5 @@ export interface CommentCreateJson extends CommentBaseJson {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.COMMENT_CREATE,
|
||||
CommentCreate
|
||||
CommentCreate,
|
||||
);
|
||||
|
||||
@@ -63,7 +63,7 @@ export class CommentDelete extends CommentBase {
|
||||
if (!this.xml) {
|
||||
throw new Error(
|
||||
'The comment XML is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['xml'] = Xml.domToText(this.xml);
|
||||
@@ -82,12 +82,12 @@ export class CommentDelete extends CommentBase {
|
||||
static fromJson(
|
||||
json: CommentDeleteJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): CommentDelete {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new CommentDelete()
|
||||
event ?? new CommentDelete(),
|
||||
) as CommentDelete;
|
||||
newEvent.xml = utilsXml.textToDom(json['xml']);
|
||||
return newEvent;
|
||||
@@ -101,5 +101,5 @@ export interface CommentDeleteJson extends CommentBaseJson {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.COMMENT_DELETE,
|
||||
CommentDelete
|
||||
CommentDelete,
|
||||
);
|
||||
|
||||
@@ -59,13 +59,13 @@ export class CommentMove extends CommentBase {
|
||||
if (this.newCoordinate_) {
|
||||
throw Error(
|
||||
'Tried to record the new position of a comment on the ' +
|
||||
'same event twice.'
|
||||
'same event twice.',
|
||||
);
|
||||
}
|
||||
if (!this.comment_) {
|
||||
throw new Error(
|
||||
'The comment is undefined. Pass a comment to ' +
|
||||
'the constructor if you want to use the record functionality'
|
||||
'the constructor if you want to use the record functionality',
|
||||
);
|
||||
}
|
||||
this.newCoordinate_ = this.comment_.getRelativeToSurfaceXY();
|
||||
@@ -92,13 +92,13 @@ export class CommentMove extends CommentBase {
|
||||
if (!this.oldCoordinate_) {
|
||||
throw new Error(
|
||||
'The old comment position is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.newCoordinate_) {
|
||||
throw new Error(
|
||||
'The new comment position is undefined. Either call recordNew, or ' +
|
||||
'call fromJson'
|
||||
'call fromJson',
|
||||
);
|
||||
}
|
||||
json['oldCoordinate'] =
|
||||
@@ -123,12 +123,12 @@ export class CommentMove extends CommentBase {
|
||||
static fromJson(
|
||||
json: CommentMoveJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): CommentMove {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new CommentMove()
|
||||
event ?? new CommentMove(),
|
||||
) as CommentMove;
|
||||
let xy = json['oldCoordinate'].split(',');
|
||||
newEvent.oldCoordinate_ = new Coordinate(Number(xy[0]), Number(xy[1]));
|
||||
@@ -156,7 +156,7 @@ export class CommentMove extends CommentBase {
|
||||
if (!this.commentId) {
|
||||
throw new Error(
|
||||
'The comment ID is undefined. Either pass a comment to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
const comment = workspace.getCommentById(this.commentId);
|
||||
@@ -170,7 +170,7 @@ export class CommentMove extends CommentBase {
|
||||
throw new Error(
|
||||
'Either oldCoordinate_ or newCoordinate_ is undefined. ' +
|
||||
'Either pass a comment to the constructor and call recordNew, ' +
|
||||
'or call fromJson'
|
||||
'or call fromJson',
|
||||
);
|
||||
}
|
||||
// TODO: Check if the comment is being dragged, and give up if so.
|
||||
|
||||
@@ -58,7 +58,7 @@ export class MarkerMove extends UiBase {
|
||||
opt_block?: Block | null,
|
||||
isCursor?: boolean,
|
||||
opt_oldNode?: ASTNode | null,
|
||||
opt_newNode?: ASTNode
|
||||
opt_newNode?: ASTNode,
|
||||
) {
|
||||
let workspaceId = opt_block ? opt_block.workspace.id : undefined;
|
||||
if (opt_newNode && opt_newNode.getType() === ASTNode.types.WORKSPACE) {
|
||||
@@ -82,13 +82,13 @@ export class MarkerMove extends UiBase {
|
||||
if (this.isCursor === undefined) {
|
||||
throw new Error(
|
||||
'Whether this is a cursor event or not is undefined. Either pass ' +
|
||||
'a value to the constructor, or call fromJson'
|
||||
'a value to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.newNode) {
|
||||
throw new Error(
|
||||
'The new node is undefined. Either pass a node to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['isCursor'] = this.isCursor;
|
||||
@@ -110,12 +110,12 @@ export class MarkerMove extends UiBase {
|
||||
static fromJson(
|
||||
json: MarkerMoveJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): MarkerMove {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new MarkerMove()
|
||||
event ?? new MarkerMove(),
|
||||
) as MarkerMove;
|
||||
newEvent.isCursor = json['isCursor'];
|
||||
newEvent.blockId = json['blockId'];
|
||||
|
||||
@@ -46,7 +46,7 @@ export class Selected extends UiBase {
|
||||
constructor(
|
||||
opt_oldElementId?: string | null,
|
||||
opt_newElementId?: string | null,
|
||||
opt_workspaceId?: string
|
||||
opt_workspaceId?: string,
|
||||
) {
|
||||
super(opt_workspaceId);
|
||||
|
||||
@@ -78,12 +78,12 @@ export class Selected extends UiBase {
|
||||
static fromJson(
|
||||
json: SelectedJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): Selected {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new Selected()
|
||||
event ?? new Selected(),
|
||||
) as Selected;
|
||||
newEvent.oldElementId = json['oldElementId'];
|
||||
newEvent.newElementId = json['newElementId'];
|
||||
|
||||
@@ -47,7 +47,7 @@ export class ThemeChange extends UiBase {
|
||||
if (!this.themeName) {
|
||||
throw new Error(
|
||||
'The theme name is undefined. Either pass a theme name to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['themeName'] = this.themeName;
|
||||
@@ -66,12 +66,12 @@ export class ThemeChange extends UiBase {
|
||||
static fromJson(
|
||||
json: ThemeChangeJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): ThemeChange {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new ThemeChange()
|
||||
event ?? new ThemeChange(),
|
||||
) as ThemeChange;
|
||||
newEvent.themeName = json['themeName'];
|
||||
return newEvent;
|
||||
|
||||
@@ -41,7 +41,7 @@ export class ToolboxItemSelect extends UiBase {
|
||||
constructor(
|
||||
opt_oldItem?: string | null,
|
||||
opt_newItem?: string | null,
|
||||
opt_workspaceId?: string
|
||||
opt_workspaceId?: string,
|
||||
) {
|
||||
super(opt_workspaceId);
|
||||
this.oldItem = opt_oldItem ?? undefined;
|
||||
@@ -72,12 +72,12 @@ export class ToolboxItemSelect extends UiBase {
|
||||
static fromJson(
|
||||
json: ToolboxItemSelectJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): ToolboxItemSelect {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new ToolboxItemSelect()
|
||||
event ?? new ToolboxItemSelect(),
|
||||
) as ToolboxItemSelect;
|
||||
newEvent.oldItem = json['oldItem'];
|
||||
newEvent.newItem = json['newItem'];
|
||||
@@ -93,5 +93,5 @@ export interface ToolboxItemSelectJson extends AbstractEventJson {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.TOOLBOX_ITEM_SELECT,
|
||||
ToolboxItemSelect
|
||||
ToolboxItemSelect,
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@ export class TrashcanOpen extends UiBase {
|
||||
if (this.isOpen === undefined) {
|
||||
throw new Error(
|
||||
'Whether this is already open or not is undefined. Either pass ' +
|
||||
'a value to the constructor, or call fromJson'
|
||||
'a value to the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['isOpen'] = this.isOpen;
|
||||
@@ -70,12 +70,12 @@ export class TrashcanOpen extends UiBase {
|
||||
static fromJson(
|
||||
json: TrashcanOpenJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): TrashcanOpen {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new TrashcanOpen()
|
||||
event ?? new TrashcanOpen(),
|
||||
) as TrashcanOpen;
|
||||
newEvent.isOpen = json['isOpen'];
|
||||
return newEvent;
|
||||
|
||||
@@ -51,7 +51,7 @@ export class VarBase extends AbstractEvent {
|
||||
if (!this.varId) {
|
||||
throw new Error(
|
||||
'The var ID is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['varId'] = this.varId;
|
||||
@@ -70,12 +70,12 @@ export class VarBase extends AbstractEvent {
|
||||
static fromJson(
|
||||
json: VarBaseJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): VarBase {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new VarBase()
|
||||
event ?? new VarBase(),
|
||||
) as VarBase;
|
||||
newEvent.varId = json['varId'];
|
||||
return newEvent;
|
||||
|
||||
@@ -54,13 +54,13 @@ export class VarCreate extends VarBase {
|
||||
if (this.varType === undefined) {
|
||||
throw new Error(
|
||||
'The var type is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.varName) {
|
||||
throw new Error(
|
||||
'The var name is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['varType'] = this.varType;
|
||||
@@ -80,12 +80,12 @@ export class VarCreate extends VarBase {
|
||||
static fromJson(
|
||||
json: VarCreateJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): VarCreate {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new VarCreate()
|
||||
event ?? new VarCreate(),
|
||||
) as VarCreate;
|
||||
newEvent.varType = json['varType'];
|
||||
newEvent.varName = json['varName'];
|
||||
@@ -102,13 +102,13 @@ export class VarCreate extends VarBase {
|
||||
if (!this.varId) {
|
||||
throw new Error(
|
||||
'The var ID is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.varName) {
|
||||
throw new Error(
|
||||
'The var name is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (forward) {
|
||||
|
||||
@@ -49,13 +49,13 @@ export class VarDelete extends VarBase {
|
||||
if (this.varType === undefined) {
|
||||
throw new Error(
|
||||
'The var type is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.varName) {
|
||||
throw new Error(
|
||||
'The var name is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['varType'] = this.varType;
|
||||
@@ -75,12 +75,12 @@ export class VarDelete extends VarBase {
|
||||
static fromJson(
|
||||
json: VarDeleteJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): VarDelete {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new VarDelete()
|
||||
event ?? new VarDelete(),
|
||||
) as VarDelete;
|
||||
newEvent.varType = json['varType'];
|
||||
newEvent.varName = json['varName'];
|
||||
@@ -97,13 +97,13 @@ export class VarDelete extends VarBase {
|
||||
if (!this.varId) {
|
||||
throw new Error(
|
||||
'The var ID is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.varName) {
|
||||
throw new Error(
|
||||
'The var name is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (forward) {
|
||||
|
||||
@@ -52,13 +52,13 @@ export class VarRename extends VarBase {
|
||||
if (!this.oldName) {
|
||||
throw new Error(
|
||||
'The old var name is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.newName) {
|
||||
throw new Error(
|
||||
'The new var name is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['oldName'] = this.oldName;
|
||||
@@ -78,12 +78,12 @@ export class VarRename extends VarBase {
|
||||
static fromJson(
|
||||
json: VarRenameJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): VarRename {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new VarRename()
|
||||
event ?? new VarRename(),
|
||||
) as VarRename;
|
||||
newEvent.oldName = json['oldName'];
|
||||
newEvent.newName = json['newName'];
|
||||
@@ -100,19 +100,19 @@ export class VarRename extends VarBase {
|
||||
if (!this.varId) {
|
||||
throw new Error(
|
||||
'The var ID is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.oldName) {
|
||||
throw new Error(
|
||||
'The old var name is undefined. Either pass a variable to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (!this.newName) {
|
||||
throw new Error(
|
||||
'The new var name is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (forward) {
|
||||
|
||||
@@ -61,7 +61,7 @@ export class ViewportChange extends UiBase {
|
||||
opt_left?: number,
|
||||
opt_scale?: number,
|
||||
opt_workspaceId?: string,
|
||||
opt_oldScale?: number
|
||||
opt_oldScale?: number,
|
||||
) {
|
||||
super(opt_workspaceId);
|
||||
|
||||
@@ -81,25 +81,25 @@ export class ViewportChange extends UiBase {
|
||||
if (this.viewTop === undefined) {
|
||||
throw new Error(
|
||||
'The view top is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (this.viewLeft === undefined) {
|
||||
throw new Error(
|
||||
'The view left is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (this.scale === undefined) {
|
||||
throw new Error(
|
||||
'The scale is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
if (this.oldScale === undefined) {
|
||||
throw new Error(
|
||||
'The old scale is undefined. Either pass a value to ' +
|
||||
'the constructor, or call fromJson'
|
||||
'the constructor, or call fromJson',
|
||||
);
|
||||
}
|
||||
json['viewTop'] = this.viewTop;
|
||||
@@ -121,12 +121,12 @@ export class ViewportChange extends UiBase {
|
||||
static fromJson(
|
||||
json: ViewportChangeJson,
|
||||
workspace: Workspace,
|
||||
event?: any
|
||||
event?: any,
|
||||
): ViewportChange {
|
||||
const newEvent = super.fromJson(
|
||||
json,
|
||||
workspace,
|
||||
event ?? new ViewportChange()
|
||||
event ?? new ViewportChange(),
|
||||
) as ViewportChange;
|
||||
newEvent.viewTop = json['viewTop'];
|
||||
newEvent.viewLeft = json['viewLeft'];
|
||||
@@ -146,5 +146,5 @@ export interface ViewportChangeJson extends AbstractEventJson {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.VIEWPORT_CHANGE,
|
||||
ViewportChange
|
||||
ViewportChange,
|
||||
);
|
||||
|
||||
@@ -343,7 +343,7 @@ export function filter(queueIn: Abstract[], forward: boolean): Abstract[] {
|
||||
if (lastEvent.reason) {
|
||||
// Concatenate reasons without duplicates.
|
||||
const reasonSet = new Set(
|
||||
moveEvent.reason.concat(lastEvent.reason)
|
||||
moveEvent.reason.concat(lastEvent.reason),
|
||||
);
|
||||
lastEvent.reason = Array.from(reasonSet);
|
||||
} else {
|
||||
@@ -489,7 +489,7 @@ export function getDescendantIds(block: Block): string[] {
|
||||
*/
|
||||
export function fromJson(
|
||||
json: AnyDuringMigration,
|
||||
workspace: Workspace
|
||||
workspace: Workspace,
|
||||
): Abstract {
|
||||
const eventClass = get(json['type']);
|
||||
if (!eventClass) throw Error('Unknown event type.');
|
||||
@@ -504,7 +504,7 @@ export function fromJson(
|
||||
* @returns The event class with the given type.
|
||||
*/
|
||||
export function get(
|
||||
eventType: string
|
||||
eventType: string,
|
||||
): new (...p1: AnyDuringMigration[]) => Abstract {
|
||||
const event = registry.getClass(registry.Type.EVENT, eventType);
|
||||
if (!event) {
|
||||
@@ -528,7 +528,7 @@ export function disableOrphans(event: Abstract) {
|
||||
return;
|
||||
}
|
||||
const eventWorkspace = common.getWorkspaceById(
|
||||
blockEvent.workspaceId
|
||||
blockEvent.workspaceId,
|
||||
) as WorkspaceSvg;
|
||||
if (!blockEvent.blockId) {
|
||||
throw new Error('Encountered a blockEvent without a proper blockId');
|
||||
|
||||
@@ -43,5 +43,5 @@ export class FinishedLoading extends AbstractEvent {
|
||||
registry.register(
|
||||
registry.Type.EVENT,
|
||||
eventUtils.FINISHED_LOADING,
|
||||
FinishedLoading
|
||||
FinishedLoading,
|
||||
);
|
||||
|
||||
@@ -75,7 +75,7 @@ export function registerMutator(
|
||||
name: string,
|
||||
mixinObj: AnyDuringMigration,
|
||||
opt_helperFn?: () => AnyDuringMigration,
|
||||
opt_blockList?: string[]
|
||||
opt_blockList?: string[],
|
||||
) {
|
||||
const errorPrefix = 'Error when registering mutator "' + name + '": ';
|
||||
|
||||
@@ -110,7 +110,7 @@ export function unregister(name: string) {
|
||||
delete allExtensions[name];
|
||||
} else {
|
||||
console.warn(
|
||||
'No extension mapping for name "' + name + '" found to unregister'
|
||||
'No extension mapping for name "' + name + '" found to unregister',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ export function apply(name: string, block: Block, isMutator: boolean) {
|
||||
'Error when applying extension "' +
|
||||
name +
|
||||
'": ' +
|
||||
'mutation properties changed when applying a non-mutator extension.'
|
||||
'mutation properties changed when applying a non-mutator extension.',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,7 @@ function checkNoMutatorProperties(mutationName: string, block: Block) {
|
||||
mutationName +
|
||||
'" to a block that already has mutator functions.' +
|
||||
' Block id: ' +
|
||||
block.id
|
||||
block.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -202,12 +202,12 @@ function checkNoMutatorProperties(mutationName: string, block: Block) {
|
||||
*/
|
||||
function checkXmlHooks(
|
||||
object: AnyDuringMigration,
|
||||
errorPrefix: string
|
||||
errorPrefix: string,
|
||||
): boolean {
|
||||
return checkHasFunctionPair(
|
||||
object.mutationToDom,
|
||||
object.domToMutation,
|
||||
errorPrefix + ' mutationToDom/domToMutation'
|
||||
errorPrefix + ' mutationToDom/domToMutation',
|
||||
);
|
||||
}
|
||||
/**
|
||||
@@ -223,12 +223,12 @@ function checkXmlHooks(
|
||||
*/
|
||||
function checkJsonHooks(
|
||||
object: AnyDuringMigration,
|
||||
errorPrefix: string
|
||||
errorPrefix: string,
|
||||
): boolean {
|
||||
return checkHasFunctionPair(
|
||||
object.saveExtraState,
|
||||
object.loadExtraState,
|
||||
errorPrefix + ' saveExtraState/loadExtraState'
|
||||
errorPrefix + ' saveExtraState/loadExtraState',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -244,12 +244,12 @@ function checkJsonHooks(
|
||||
*/
|
||||
function checkMutatorDialog(
|
||||
object: AnyDuringMigration,
|
||||
errorPrefix: string
|
||||
errorPrefix: string,
|
||||
): boolean {
|
||||
return checkHasFunctionPair(
|
||||
object.compose,
|
||||
object.decompose,
|
||||
errorPrefix + ' compose/decompose'
|
||||
errorPrefix + ' compose/decompose',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ function checkMutatorDialog(
|
||||
function checkHasFunctionPair(
|
||||
func1: AnyDuringMigration,
|
||||
func2: AnyDuringMigration,
|
||||
errorPrefix: string
|
||||
errorPrefix: string,
|
||||
): boolean {
|
||||
if (func1 && func2) {
|
||||
if (typeof func1 !== 'function' || typeof func2 !== 'function') {
|
||||
@@ -289,14 +289,14 @@ function checkHasFunctionPair(
|
||||
*/
|
||||
function checkHasMutatorProperties(
|
||||
errorPrefix: string,
|
||||
object: AnyDuringMigration
|
||||
object: AnyDuringMigration,
|
||||
) {
|
||||
const hasXmlHooks = checkXmlHooks(object, errorPrefix);
|
||||
const hasJsonHooks = checkJsonHooks(object, errorPrefix);
|
||||
if (!hasXmlHooks && !hasJsonHooks) {
|
||||
throw Error(
|
||||
errorPrefix +
|
||||
'Mutations must contain either XML hooks, or JSON hooks, or both'
|
||||
'Mutations must contain either XML hooks, or JSON hooks, or both',
|
||||
);
|
||||
}
|
||||
// A block with a mutator isn't required to have a mutation dialog, but
|
||||
@@ -347,7 +347,7 @@ function getMutatorProperties(block: Block): AnyDuringMigration[] {
|
||||
*/
|
||||
function mutatorPropertiesMatch(
|
||||
oldProperties: AnyDuringMigration[],
|
||||
block: Block
|
||||
block: Block,
|
||||
): boolean {
|
||||
const newProperties = getMutatorProperties(block);
|
||||
if (newProperties.length !== oldProperties.length) {
|
||||
@@ -406,7 +406,7 @@ export function runAfterPageLoad(fn: () => void) {
|
||||
*/
|
||||
export function buildTooltipForDropdown(
|
||||
dropdownName: string,
|
||||
lookupTable: {[key: string]: string}
|
||||
lookupTable: {[key: string]: string},
|
||||
): Function {
|
||||
// List of block types already validated, to minimize duplicate warnings.
|
||||
const blockTypesChecked: AnyDuringMigration[] = [];
|
||||
@@ -453,7 +453,7 @@ export function buildTooltipForDropdown(
|
||||
tooltip = parsing.replaceMessageReferences(tooltip);
|
||||
}
|
||||
return tooltip;
|
||||
}.bind(this)
|
||||
}.bind(this),
|
||||
);
|
||||
}
|
||||
return extensionFn;
|
||||
@@ -470,7 +470,7 @@ export function buildTooltipForDropdown(
|
||||
function checkDropdownOptionsInTable(
|
||||
block: Block,
|
||||
dropdownName: string,
|
||||
lookupTable: {[key: string]: string}
|
||||
lookupTable: {[key: string]: string},
|
||||
) {
|
||||
// Validate all dropdown options have values.
|
||||
const dropdown = block.getField(dropdownName);
|
||||
@@ -485,7 +485,7 @@ function checkDropdownOptionsInTable(
|
||||
' of field ' +
|
||||
dropdownName +
|
||||
' of block type ' +
|
||||
block.type
|
||||
block.type,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -504,7 +504,7 @@ function checkDropdownOptionsInTable(
|
||||
*/
|
||||
export function buildTooltipWithFieldText(
|
||||
msgTemplate: string,
|
||||
fieldName: string
|
||||
fieldName: string,
|
||||
): Function {
|
||||
// Check the tooltip string messages for invalid references.
|
||||
// Wait for load, in case Blockly.Msg is not yet populated.
|
||||
@@ -526,7 +526,7 @@ export function buildTooltipWithFieldText(
|
||||
return parsing
|
||||
.replaceMessageReferences(msgTemplate)
|
||||
.replace('%1', field ? field.getText() : '');
|
||||
}.bind(this)
|
||||
}.bind(this),
|
||||
);
|
||||
}
|
||||
return extensionFn;
|
||||
@@ -547,7 +547,7 @@ function extensionParentTooltip(this: Block) {
|
||||
(parent && parent.getInputsInline() && parent.tooltip) ||
|
||||
tooltipWhenNotConnected
|
||||
);
|
||||
}.bind(this)
|
||||
}.bind(this),
|
||||
);
|
||||
}
|
||||
register('parent_tooltip_when_inline', extensionParentTooltip);
|
||||
|
||||
@@ -214,7 +214,7 @@ export abstract class Field<T = any>
|
||||
constructor(
|
||||
value: T | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldValidator<T> | null,
|
||||
config?: FieldConfig
|
||||
config?: FieldConfig,
|
||||
) {
|
||||
/**
|
||||
* A generic value possessed by the field.
|
||||
@@ -321,10 +321,8 @@ export abstract class Field<T = any>
|
||||
|
||||
/**
|
||||
* Create the block UI for this field.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
initView() {
|
||||
protected initView() {
|
||||
this.createBorderRect_();
|
||||
this.createTextElement_();
|
||||
}
|
||||
@@ -332,8 +330,6 @@ export abstract class Field<T = any>
|
||||
/**
|
||||
* Initializes the model of the field after it has been installed on a block.
|
||||
* No-op by default.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
initModel() {}
|
||||
|
||||
@@ -354,7 +350,7 @@ export abstract class Field<T = any>
|
||||
'width': this.size_.width,
|
||||
'class': 'blocklyFieldRect',
|
||||
},
|
||||
this.fieldGroup_
|
||||
this.fieldGroup_,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -369,7 +365,7 @@ export abstract class Field<T = any>
|
||||
{
|
||||
'class': 'blocklyText',
|
||||
},
|
||||
this.fieldGroup_
|
||||
this.fieldGroup_,
|
||||
);
|
||||
if (this.getConstants()!.FIELD_TEXT_BASELINE_CENTER) {
|
||||
this.textElement_.setAttribute('dominant-baseline', 'central');
|
||||
@@ -390,7 +386,7 @@ export abstract class Field<T = any>
|
||||
clickTarget,
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onMouseDown_
|
||||
this.onMouseDown_,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -471,7 +467,7 @@ export abstract class Field<T = any>
|
||||
const text = utilsXml.domToText(this.toXml(elem));
|
||||
return text.replace(
|
||||
' xmlns="https://developers.google.com/blockly/xml"',
|
||||
''
|
||||
'',
|
||||
);
|
||||
}
|
||||
// Either they called this on purpose from their saveState, or they have
|
||||
@@ -490,7 +486,7 @@ export abstract class Field<T = any>
|
||||
*/
|
||||
loadLegacyState(
|
||||
callingClass: FieldProto,
|
||||
state: AnyDuringMigration
|
||||
state: AnyDuringMigration,
|
||||
): boolean {
|
||||
if (
|
||||
callingClass.prototype.loadState === this.loadState &&
|
||||
@@ -605,7 +601,7 @@ export abstract class Field<T = any>
|
||||
console.warn(
|
||||
'Detected an editable field that was not serializable.' +
|
||||
' Please define SERIALIZABLE property as true on all editable custom' +
|
||||
' fields. Proceeding with serialization.'
|
||||
' fields. Proceeding with serialization.',
|
||||
);
|
||||
isSerializable = true;
|
||||
}
|
||||
@@ -813,7 +809,7 @@ export abstract class Field<T = any>
|
||||
this.textElement_,
|
||||
constants!.FIELD_TEXT_FONTSIZE,
|
||||
constants!.FIELD_TEXT_FONTWEIGHT,
|
||||
constants!.FIELD_TEXT_FONTFAMILY
|
||||
constants!.FIELD_TEXT_FONTFAMILY,
|
||||
);
|
||||
totalWidth += contentWidth;
|
||||
}
|
||||
@@ -847,8 +843,8 @@ export abstract class Field<T = any>
|
||||
String(
|
||||
this.getSourceBlock()?.RTL
|
||||
? this.size_.width - contentWidth - xOffset
|
||||
: xOffset
|
||||
)
|
||||
: xOffset,
|
||||
),
|
||||
);
|
||||
this.textElement_.setAttribute(
|
||||
'y',
|
||||
@@ -857,8 +853,8 @@ export abstract class Field<T = any>
|
||||
? halfHeight
|
||||
: halfHeight -
|
||||
constants!.FIELD_TEXT_HEIGHT / 2 +
|
||||
constants!.FIELD_TEXT_BASELINE
|
||||
)
|
||||
constants!.FIELD_TEXT_BASELINE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -871,11 +867,11 @@ export abstract class Field<T = any>
|
||||
this.borderRect_.setAttribute('height', String(this.size_.height));
|
||||
this.borderRect_.setAttribute(
|
||||
'rx',
|
||||
String(this.getConstants()!.FIELD_BORDER_RECT_RADIUS)
|
||||
String(this.getConstants()!.FIELD_BORDER_RECT_RADIUS),
|
||||
);
|
||||
this.borderRect_.setAttribute(
|
||||
'ry',
|
||||
String(this.getConstants()!.FIELD_BORDER_RECT_RADIUS)
|
||||
String(this.getConstants()!.FIELD_BORDER_RECT_RADIUS),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -902,7 +898,7 @@ export abstract class Field<T = any>
|
||||
if (this.size_.width !== 0) {
|
||||
console.warn(
|
||||
'Deprecated use of setting size_.width to 0 to rerender a' +
|
||||
' field. Set field.isDirty_ to true instead.'
|
||||
' field. Set field.isDirty_ to true instead.',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1090,8 +1086,8 @@ export abstract class Field<T = any>
|
||||
'field',
|
||||
this.name || null,
|
||||
oldValue,
|
||||
localValue
|
||||
)
|
||||
localValue,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (this.isDirty_) {
|
||||
@@ -1109,7 +1105,7 @@ export abstract class Field<T = any>
|
||||
*/
|
||||
private processValidation_(
|
||||
newValue: AnyDuringMigration,
|
||||
validatedValue: T | null | undefined
|
||||
validatedValue: T | null | undefined,
|
||||
): T | Error {
|
||||
if (validatedValue === null) {
|
||||
this.doValueInvalid_(newValue);
|
||||
@@ -1153,7 +1149,7 @@ export abstract class Field<T = any>
|
||||
protected doClassValidation_(newValue: T): T | null | undefined;
|
||||
protected doClassValidation_(newValue?: AnyDuringMigration): T | null;
|
||||
protected doClassValidation_(
|
||||
newValue?: T | AnyDuringMigration
|
||||
newValue?: T | AnyDuringMigration,
|
||||
): T | null | undefined {
|
||||
if (newValue === null || newValue === undefined) {
|
||||
return null;
|
||||
@@ -1416,7 +1412,7 @@ export class UnattachedFieldError extends Error {
|
||||
constructor() {
|
||||
super(
|
||||
'The field has not yet been attached to its input. ' +
|
||||
'Call appendField to attach it.'
|
||||
'Call appendField to attach it.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
constructor(
|
||||
value?: string | number | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldAngleValidator,
|
||||
config?: FieldAngleConfig
|
||||
config?: FieldAngleConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -165,8 +165,6 @@ export class FieldAngle extends FieldInput<number> {
|
||||
|
||||
/**
|
||||
* Create the block UI for this field.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
super.initView();
|
||||
@@ -200,7 +198,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
if (this.sourceBlock_ instanceof BlockSvg) {
|
||||
dropDownDiv.setColour(
|
||||
this.sourceBlock_.style.colourPrimary,
|
||||
this.sourceBlock_.style.colourTertiary
|
||||
this.sourceBlock_.style.colourTertiary,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -232,12 +230,12 @@ export class FieldAngle extends FieldInput<number> {
|
||||
'r': FieldAngle.RADIUS,
|
||||
'class': 'blocklyAngleCircle',
|
||||
},
|
||||
svg
|
||||
svg,
|
||||
);
|
||||
this.gauge = dom.createSvgElement(
|
||||
Svg.PATH,
|
||||
{'class': 'blocklyAngleGauge'},
|
||||
svg
|
||||
svg,
|
||||
);
|
||||
this.line = dom.createSvgElement(
|
||||
Svg.LINE,
|
||||
@@ -246,7 +244,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
'y1': FieldAngle.HALF,
|
||||
'class': 'blocklyAngleLine',
|
||||
},
|
||||
svg
|
||||
svg,
|
||||
);
|
||||
// Draw markers around the edge.
|
||||
for (let angle = 0; angle < 360; angle += 15) {
|
||||
@@ -268,7 +266,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
FieldAngle.HALF +
|
||||
')',
|
||||
},
|
||||
svg
|
||||
svg,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -276,7 +274,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
// mousemove even if it's not in the middle of a drag. In future we may
|
||||
// change this behaviour.
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(svg, 'click', this, this.hide)
|
||||
browserEvents.conditionalBind(svg, 'click', this, this.hide),
|
||||
);
|
||||
// On touch devices, the picker's value is only updated with a drag. Add
|
||||
// a click handler on the drag surface to update the value if the surface
|
||||
@@ -287,8 +285,8 @@ export class FieldAngle extends FieldInput<number> {
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onMouseMove_,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -296,8 +294,8 @@ export class FieldAngle extends FieldInput<number> {
|
||||
'pointermove',
|
||||
this,
|
||||
this.onMouseMove_,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
return svg;
|
||||
}
|
||||
@@ -380,8 +378,8 @@ export class FieldAngle extends FieldInput<number> {
|
||||
this.sourceBlock_,
|
||||
this.name || null,
|
||||
oldValue,
|
||||
this.value_
|
||||
)
|
||||
this.value_,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -411,7 +409,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
y2 -= Math.sin(angleRadians) * FieldAngle.RADIUS;
|
||||
// Don't ask how the flag calculations work. They just do.
|
||||
let largeFlag = Math.abs(
|
||||
Math.floor((angleRadians - angle1) / Math.PI) % 2
|
||||
Math.floor((angleRadians - angle1) / Math.PI) % 2,
|
||||
);
|
||||
if (clockwiseFlag) {
|
||||
largeFlag = 1 - largeFlag;
|
||||
@@ -433,7 +431,7 @@ export class FieldAngle extends FieldInput<number> {
|
||||
x2,
|
||||
',',
|
||||
y2,
|
||||
' z'
|
||||
' z',
|
||||
);
|
||||
}
|
||||
this.gauge.setAttribute('d', path.join(''));
|
||||
|
||||
@@ -64,7 +64,7 @@ export class FieldCheckbox extends Field<CheckboxBool> {
|
||||
constructor(
|
||||
value?: CheckboxBool | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldCheckboxValidator,
|
||||
config?: FieldCheckboxConfig
|
||||
config?: FieldCheckboxConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -110,8 +110,6 @@ export class FieldCheckbox extends Field<CheckboxBool> {
|
||||
|
||||
/**
|
||||
* Create the block UI for this checkbox.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
super.initView();
|
||||
@@ -155,7 +153,7 @@ export class FieldCheckbox extends Field<CheckboxBool> {
|
||||
* @returns A valid value ('TRUE' or 'FALSE), or null if invalid.
|
||||
*/
|
||||
protected override doClassValidation_(
|
||||
newValue?: AnyDuringMigration
|
||||
newValue?: AnyDuringMigration,
|
||||
): BoolString | null {
|
||||
if (newValue === true || newValue === 'TRUE') {
|
||||
return 'TRUE';
|
||||
|
||||
@@ -135,7 +135,7 @@ export class FieldColour extends Field<string> {
|
||||
constructor(
|
||||
value?: string | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldColourValidator,
|
||||
config?: FieldColourConfig
|
||||
config?: FieldColourConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -163,13 +163,11 @@ export class FieldColour extends Field<string> {
|
||||
|
||||
/**
|
||||
* Create the block UI for this colour field.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
this.size_ = new Size(
|
||||
this.getConstants()!.FIELD_COLOUR_DEFAULT_WIDTH,
|
||||
this.getConstants()!.FIELD_COLOUR_DEFAULT_HEIGHT
|
||||
this.getConstants()!.FIELD_COLOUR_DEFAULT_HEIGHT,
|
||||
);
|
||||
if (!this.getConstants()!.FIELD_COLOUR_FULL_BLOCK) {
|
||||
this.createBorderRect_();
|
||||
@@ -190,7 +188,7 @@ export class FieldColour extends Field<string> {
|
||||
} else if (this.sourceBlock_ instanceof BlockSvg) {
|
||||
this.sourceBlock_.pathObject.svgPath.setAttribute(
|
||||
'fill',
|
||||
this.getValue() as string
|
||||
this.getValue() as string,
|
||||
);
|
||||
this.sourceBlock_.pathObject.svgPath.setAttribute('stroke', '#fff');
|
||||
}
|
||||
@@ -486,7 +484,7 @@ export class FieldColour extends Field<string> {
|
||||
aria.setState(
|
||||
table,
|
||||
aria.State.ROWCOUNT,
|
||||
Math.floor(colours.length / columns)
|
||||
Math.floor(colours.length / columns),
|
||||
);
|
||||
aria.setState(table, aria.State.COLCOUNT, columns);
|
||||
let row: Element;
|
||||
@@ -520,8 +518,8 @@ export class FieldColour extends Field<string> {
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onClick,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -529,8 +527,8 @@ export class FieldColour extends Field<string> {
|
||||
'pointermove',
|
||||
this,
|
||||
this.onMouseMove,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -538,8 +536,8 @@ export class FieldColour extends Field<string> {
|
||||
'pointerenter',
|
||||
this,
|
||||
this.onMouseEnter,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -547,8 +545,8 @@ export class FieldColour extends Field<string> {
|
||||
'pointerleave',
|
||||
this,
|
||||
this.onMouseLeave,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -556,8 +554,8 @@ export class FieldColour extends Field<string> {
|
||||
'keydown',
|
||||
this,
|
||||
this.onKeyDown,
|
||||
false
|
||||
)
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
this.picker = table;
|
||||
|
||||
@@ -115,13 +115,13 @@ export class FieldDropdown extends Field<string> {
|
||||
constructor(
|
||||
menuGenerator: MenuGenerator,
|
||||
validator?: FieldDropdownValidator,
|
||||
config?: FieldDropdownConfig
|
||||
config?: FieldDropdownConfig,
|
||||
);
|
||||
constructor(menuGenerator: typeof Field.SKIP_SETUP);
|
||||
constructor(
|
||||
menuGenerator: MenuGenerator | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldDropdownValidator,
|
||||
config?: FieldDropdownConfig
|
||||
config?: FieldDropdownConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -185,8 +185,6 @@ export class FieldDropdown extends Field<string> {
|
||||
|
||||
/**
|
||||
* Create the block UI for this dropdown.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
if (this.shouldAddBorderRect_()) {
|
||||
@@ -229,8 +227,8 @@ export class FieldDropdown extends Field<string> {
|
||||
document.createTextNode(
|
||||
this.getSourceBlock()?.RTL
|
||||
? FieldDropdown.ARROW_CHAR + ' '
|
||||
: ' ' + FieldDropdown.ARROW_CHAR
|
||||
)
|
||||
: ' ' + FieldDropdown.ARROW_CHAR,
|
||||
),
|
||||
);
|
||||
if (this.getSourceBlock()?.RTL) {
|
||||
this.getTextElement().insertBefore(this.arrow, this.textContent_);
|
||||
@@ -247,12 +245,12 @@ export class FieldDropdown extends Field<string> {
|
||||
'height': this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE + 'px',
|
||||
'width': this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE + 'px',
|
||||
},
|
||||
this.fieldGroup_
|
||||
this.fieldGroup_,
|
||||
);
|
||||
this.svgArrow!.setAttributeNS(
|
||||
dom.XLINK_NS,
|
||||
'xlink:href',
|
||||
this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_DATAURI
|
||||
this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_DATAURI,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -302,7 +300,7 @@ export class FieldDropdown extends Field<string> {
|
||||
style.scrollIntoContainerView(
|
||||
this.selectedMenuItem.getElement()!,
|
||||
dropDownDiv.getContentDiv(),
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -428,7 +426,7 @@ export class FieldDropdown extends Field<string> {
|
||||
', Field name: ' +
|
||||
this.name +
|
||||
', Value: ' +
|
||||
newValue
|
||||
newValue,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
@@ -506,7 +504,7 @@ export class FieldDropdown extends Field<string> {
|
||||
this.imageElement!.setAttributeNS(
|
||||
dom.XLINK_NS,
|
||||
'xlink:href',
|
||||
imageJson.src
|
||||
imageJson.src,
|
||||
);
|
||||
this.imageElement!.setAttribute('height', String(imageJson.height));
|
||||
this.imageElement!.setAttribute('width', String(imageJson.width));
|
||||
@@ -518,7 +516,7 @@ export class FieldDropdown extends Field<string> {
|
||||
const hasBorder = !!this.borderRect_;
|
||||
const height = Math.max(
|
||||
hasBorder ? this.getConstants()!.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
|
||||
imageHeight + IMAGE_Y_PADDING
|
||||
imageHeight + IMAGE_Y_PADDING,
|
||||
);
|
||||
const xPadding = hasBorder
|
||||
? this.getConstants()!.FIELD_BORDER_RECT_X_PADDING
|
||||
@@ -527,14 +525,14 @@ export class FieldDropdown extends Field<string> {
|
||||
if (this.svgArrow) {
|
||||
arrowWidth = this.positionSVGArrow(
|
||||
imageWidth + xPadding,
|
||||
height / 2 - this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2
|
||||
height / 2 - this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2,
|
||||
);
|
||||
} else {
|
||||
arrowWidth = dom.getFastTextWidth(
|
||||
this.arrow as SVGTSpanElement,
|
||||
this.getConstants()!.FIELD_TEXT_FONTSIZE,
|
||||
this.getConstants()!.FIELD_TEXT_FONTWEIGHT,
|
||||
this.getConstants()!.FIELD_TEXT_FONTFAMILY
|
||||
this.getConstants()!.FIELD_TEXT_FONTFAMILY,
|
||||
);
|
||||
}
|
||||
this.size_.width = imageWidth + arrowWidth + xPadding * 2;
|
||||
@@ -566,13 +564,13 @@ export class FieldDropdown extends Field<string> {
|
||||
const hasBorder = !!this.borderRect_;
|
||||
const height = Math.max(
|
||||
hasBorder ? this.getConstants()!.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
|
||||
this.getConstants()!.FIELD_TEXT_HEIGHT
|
||||
this.getConstants()!.FIELD_TEXT_HEIGHT,
|
||||
);
|
||||
const textWidth = dom.getFastTextWidth(
|
||||
this.getTextElement(),
|
||||
this.getConstants()!.FIELD_TEXT_FONTSIZE,
|
||||
this.getConstants()!.FIELD_TEXT_FONTWEIGHT,
|
||||
this.getConstants()!.FIELD_TEXT_FONTFAMILY
|
||||
this.getConstants()!.FIELD_TEXT_FONTFAMILY,
|
||||
);
|
||||
const xPadding = hasBorder
|
||||
? this.getConstants()!.FIELD_BORDER_RECT_X_PADDING
|
||||
@@ -581,7 +579,7 @@ export class FieldDropdown extends Field<string> {
|
||||
if (this.svgArrow) {
|
||||
arrowWidth = this.positionSVGArrow(
|
||||
textWidth + xPadding,
|
||||
height / 2 - this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2
|
||||
height / 2 - this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2,
|
||||
);
|
||||
}
|
||||
this.size_.width = textWidth + arrowWidth + xPadding * 2;
|
||||
@@ -614,7 +612,7 @@ export class FieldDropdown extends Field<string> {
|
||||
const arrowX = block.RTL ? xPadding : x + textPadding;
|
||||
this.svgArrow.setAttribute(
|
||||
'transform',
|
||||
'translate(' + arrowX + ',' + y + ')'
|
||||
'translate(' + arrowX + ',' + y + ')',
|
||||
);
|
||||
return svgArrowSize + textPadding;
|
||||
}
|
||||
@@ -650,7 +648,7 @@ export class FieldDropdown extends Field<string> {
|
||||
throw new Error(
|
||||
'options are required for the dropdown field. The ' +
|
||||
'options property must be assigned an array of ' +
|
||||
'[humanReadableValue, languageNeutralValue] tuples.'
|
||||
'[humanReadableValue, languageNeutralValue] tuples.',
|
||||
);
|
||||
}
|
||||
// `this` might be a subclass of FieldDropdown if that class doesn't
|
||||
@@ -794,7 +792,7 @@ function trimOptions(options: MenuOption[]): {
|
||||
function applyTrim(
|
||||
options: [string, string][],
|
||||
prefixLength: number,
|
||||
suffixLength: number
|
||||
suffixLength: number,
|
||||
): MenuOption[] {
|
||||
return options.map(([text, value]) => [
|
||||
text.substring(prefixLength, text.length - suffixLength),
|
||||
@@ -825,7 +823,7 @@ function validateOptions(options: MenuOption[]) {
|
||||
i +
|
||||
']: Each FieldDropdown option must be an ' +
|
||||
'array. Found: ',
|
||||
tuple
|
||||
tuple,
|
||||
);
|
||||
} else if (typeof tuple[1] !== 'string') {
|
||||
foundError = true;
|
||||
@@ -836,7 +834,7 @@ function validateOptions(options: MenuOption[]) {
|
||||
'a string. Found ' +
|
||||
tuple[1] +
|
||||
' in: ',
|
||||
tuple
|
||||
tuple,
|
||||
);
|
||||
} else if (
|
||||
tuple[0] &&
|
||||
@@ -851,7 +849,7 @@ function validateOptions(options: MenuOption[]) {
|
||||
'string label or image description. Found' +
|
||||
tuple[0] +
|
||||
' in: ',
|
||||
tuple
|
||||
tuple,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,13 +29,13 @@ export class FieldImage extends Field<string> {
|
||||
*/
|
||||
private static readonly Y_PADDING = 1;
|
||||
protected override size_: Size;
|
||||
private readonly imageHeight: number;
|
||||
protected readonly imageHeight: number;
|
||||
|
||||
/** The function to be called when this field is clicked. */
|
||||
private clickHandler: ((p1: FieldImage) => void) | null = null;
|
||||
|
||||
/** The rendered field's image element. */
|
||||
private imageElement: SVGImageElement | null = null;
|
||||
protected imageElement: SVGImageElement | null = null;
|
||||
|
||||
/**
|
||||
* Editable fields usually show some sort of UI indicating they are
|
||||
@@ -79,7 +79,7 @@ export class FieldImage extends Field<string> {
|
||||
alt?: string,
|
||||
onClick?: (p1: FieldImage) => void,
|
||||
flipRtl?: boolean,
|
||||
config?: FieldImageConfig
|
||||
config?: FieldImageConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -87,12 +87,13 @@ export class FieldImage extends Field<string> {
|
||||
const imageWidth = Number(parsing.replaceMessageReferences(width));
|
||||
if (isNaN(imageHeight) || isNaN(imageWidth)) {
|
||||
throw Error(
|
||||
'Height and width values of an image field must cast to' + ' numbers.'
|
||||
'Height and width values of an image field must cast to' + ' numbers.',
|
||||
);
|
||||
}
|
||||
if (imageHeight <= 0 || imageWidth <= 0) {
|
||||
throw Error(
|
||||
'Height and width values of an image field must be greater' + ' than 0.'
|
||||
'Height and width values of an image field must be greater' +
|
||||
' than 0.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,8 +135,6 @@ export class FieldImage extends Field<string> {
|
||||
|
||||
/**
|
||||
* Create the block UI for this image.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
this.imageElement = dom.createSvgElement(
|
||||
@@ -145,12 +144,12 @@ export class FieldImage extends Field<string> {
|
||||
'width': this.size_.width + 'px',
|
||||
'alt': this.altText,
|
||||
},
|
||||
this.fieldGroup_
|
||||
this.fieldGroup_,
|
||||
);
|
||||
this.imageElement.setAttributeNS(
|
||||
dom.XLINK_NS,
|
||||
'xlink:href',
|
||||
this.value_ as string
|
||||
this.value_ as string,
|
||||
);
|
||||
|
||||
if (this.clickHandler) {
|
||||
@@ -256,7 +255,7 @@ export class FieldImage extends Field<string> {
|
||||
if (!options.src || !options.width || !options.height) {
|
||||
throw new Error(
|
||||
'src, width, and height values for an image field are' +
|
||||
'required. The width and height must be non-zero.'
|
||||
'required. The width and height must be non-zero.',
|
||||
);
|
||||
}
|
||||
// `this` might be a subclass of FieldImage if that class doesn't override
|
||||
@@ -268,7 +267,7 @@ export class FieldImage extends Field<string> {
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
options
|
||||
options,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
constructor(
|
||||
value?: string | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldInputValidator<T> | null,
|
||||
config?: FieldInputConfig
|
||||
config?: FieldInputConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -141,7 +141,6 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
override initView() {
|
||||
const block = this.getSourceBlock();
|
||||
if (!block) {
|
||||
@@ -200,8 +199,8 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
'field',
|
||||
this.name || null,
|
||||
oldValue,
|
||||
this.value_
|
||||
)
|
||||
this.value_,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -234,7 +233,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
} else {
|
||||
source.pathObject.svgPath.setAttribute(
|
||||
'fill',
|
||||
this.getConstants()!.FIELD_BORDER_RECT_COLOUR
|
||||
this.getConstants()!.FIELD_BORDER_RECT_COLOUR,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -275,7 +274,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
// assignable to parameter of type 'string'.
|
||||
this.htmlInput_.setAttribute(
|
||||
'spellcheck',
|
||||
this.spellcheck_ as AnyDuringMigration
|
||||
this.spellcheck_ as AnyDuringMigration,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -318,7 +317,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
if (text !== null) {
|
||||
this.setValue(this.getValueFromEditorText_(text));
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -368,7 +367,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
// to parameter of type 'string'.
|
||||
htmlInput.setAttribute(
|
||||
'spellcheck',
|
||||
this.spellcheck_ as AnyDuringMigration
|
||||
this.spellcheck_ as AnyDuringMigration,
|
||||
);
|
||||
const scale = this.workspace_!.getScale();
|
||||
const fontSize = this.getConstants()!.FIELD_TEXT_FONTSIZE * scale + 'pt';
|
||||
@@ -435,8 +434,8 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
'field',
|
||||
this.name || null,
|
||||
this.valueWhenEditorWasOpened_,
|
||||
this.value_
|
||||
)
|
||||
this.value_,
|
||||
),
|
||||
);
|
||||
this.valueWhenEditorWasOpened_ = null;
|
||||
}
|
||||
@@ -478,14 +477,14 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
htmlInput,
|
||||
'keydown',
|
||||
this,
|
||||
this.onHtmlInputKeyDown_
|
||||
this.onHtmlInputKeyDown_,
|
||||
);
|
||||
// Resize after every input change.
|
||||
this.onKeyInputWrapper_ = browserEvents.conditionalBind(
|
||||
htmlInput,
|
||||
'input',
|
||||
this,
|
||||
this.onHtmlInputChange_
|
||||
this.onHtmlInputChange_,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -512,7 +511,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
dropDownDiv.hideWithoutAnimation();
|
||||
} else if (e.key === 'Escape') {
|
||||
this.setValue(
|
||||
this.htmlInput_!.getAttribute('data-untyped-default-value')
|
||||
this.htmlInput_!.getAttribute('data-untyped-default-value'),
|
||||
);
|
||||
WidgetDiv.hide();
|
||||
dropDownDiv.hideWithoutAnimation();
|
||||
@@ -549,8 +548,8 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
this.sourceBlock_,
|
||||
this.name || null,
|
||||
oldValue,
|
||||
this.value_
|
||||
)
|
||||
this.value_,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -572,7 +571,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
*/
|
||||
protected setEditorValue_(
|
||||
newValue: AnyDuringMigration,
|
||||
fireChangeEvent = true
|
||||
fireChangeEvent = true,
|
||||
) {
|
||||
this.isDirty_ = true;
|
||||
if (this.isBeingEdited_) {
|
||||
@@ -622,7 +621,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
|
||||
bumpObjects.bumpIntoBounds(
|
||||
this.workspace_!,
|
||||
this.workspace_!.getMetricsManager().getViewMetrics(true),
|
||||
block
|
||||
block,
|
||||
);
|
||||
|
||||
this.resizeEditor_();
|
||||
|
||||
@@ -49,7 +49,7 @@ export class FieldLabel extends Field<string> {
|
||||
constructor(
|
||||
value?: string | typeof Field.SKIP_SETUP,
|
||||
textClass?: string,
|
||||
config?: FieldLabelConfig
|
||||
config?: FieldLabelConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -69,8 +69,6 @@ export class FieldLabel extends Field<string> {
|
||||
|
||||
/**
|
||||
* Create block UI for this label.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
this.createTextElement_();
|
||||
@@ -86,7 +84,7 @@ export class FieldLabel extends Field<string> {
|
||||
* @returns A valid string, or null if invalid.
|
||||
*/
|
||||
protected override doClassValidation_(
|
||||
newValue?: AnyDuringMigration
|
||||
newValue?: AnyDuringMigration,
|
||||
): string | null {
|
||||
if (newValue === null || newValue === undefined) {
|
||||
return null;
|
||||
|
||||
@@ -62,7 +62,7 @@ export class FieldLabelSerializable extends FieldLabel {
|
||||
* @internal
|
||||
*/
|
||||
static override fromJson(
|
||||
options: FieldLabelFromJsonConfig
|
||||
options: FieldLabelFromJsonConfig,
|
||||
): FieldLabelSerializable {
|
||||
const text = parsing.replaceMessageReferences(options.text);
|
||||
// `this` might be a subclass of FieldLabelSerializable if that class
|
||||
|
||||
@@ -64,7 +64,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
constructor(
|
||||
value?: string | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldMultilineInputValidator,
|
||||
config?: FieldMultilineInputConfig
|
||||
config?: FieldMultilineInputConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -103,7 +103,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
// limitation of the plain-text format).
|
||||
fieldElement.textContent = (this.getValue() as string).replace(
|
||||
/\n/g,
|
||||
' '
|
||||
' ',
|
||||
);
|
||||
return fieldElement;
|
||||
}
|
||||
@@ -152,8 +152,6 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
|
||||
/**
|
||||
* Create the block UI for this field.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initView() {
|
||||
this.createBorderRect_();
|
||||
@@ -162,7 +160,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
{
|
||||
'class': 'blocklyEditableText',
|
||||
},
|
||||
this.fieldGroup_
|
||||
this.fieldGroup_,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -255,7 +253,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
'y': y + this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING,
|
||||
'dy': this.getConstants()!.FIELD_TEXT_BASELINE,
|
||||
},
|
||||
textGroup
|
||||
textGroup,
|
||||
);
|
||||
span.appendChild(document.createTextNode(lines[i]));
|
||||
y += lineHeight;
|
||||
@@ -306,7 +304,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
tspan,
|
||||
fontSize,
|
||||
fontWeight,
|
||||
fontFamily
|
||||
fontFamily,
|
||||
);
|
||||
if (textWidth > totalWidth) {
|
||||
totalWidth = textWidth;
|
||||
@@ -330,7 +328,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
if (actualEditorLines[i].length > this.maxDisplayLength) {
|
||||
actualEditorLines[i] = actualEditorLines[i].substring(
|
||||
0,
|
||||
this.maxDisplayLength
|
||||
this.maxDisplayLength,
|
||||
);
|
||||
}
|
||||
dummyTextElement.textContent = actualEditorLines[i];
|
||||
@@ -338,7 +336,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
dummyTextElement,
|
||||
fontSize,
|
||||
fontWeight,
|
||||
fontFamily
|
||||
fontFamily,
|
||||
);
|
||||
if (lineWidth > totalWidth) {
|
||||
totalWidth = lineWidth;
|
||||
@@ -468,7 +466,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
* @internal
|
||||
*/
|
||||
static override fromJson(
|
||||
options: FieldMultilineInputFromJsonConfig
|
||||
options: FieldMultilineInputFromJsonConfig,
|
||||
): FieldMultilineInput {
|
||||
const text = parsing.replaceMessageReferences(options.text);
|
||||
// `this` might be a subclass of FieldMultilineInput if that class doesn't
|
||||
|
||||
@@ -68,7 +68,7 @@ export class FieldNumber extends FieldInput<number> {
|
||||
max?: string | number | null,
|
||||
precision?: string | number | null,
|
||||
validator?: FieldNumberValidator | null,
|
||||
config?: FieldNumberConfig
|
||||
config?: FieldNumberConfig,
|
||||
) {
|
||||
// Pass SENTINEL so that we can define properties before value validation.
|
||||
super(Field.SKIP_SETUP);
|
||||
@@ -113,7 +113,7 @@ export class FieldNumber extends FieldInput<number> {
|
||||
setConstraints(
|
||||
min: number | string | undefined | null,
|
||||
max: number | string | undefined | null,
|
||||
precision: number | string | undefined | null
|
||||
precision: number | string | undefined | null,
|
||||
) {
|
||||
this.setMinInternal(min);
|
||||
this.setMaxInternal(max);
|
||||
@@ -253,7 +253,7 @@ export class FieldNumber extends FieldInput<number> {
|
||||
* @returns A valid number, or null if invalid.
|
||||
*/
|
||||
protected override doClassValidation_(
|
||||
newValue?: AnyDuringMigration
|
||||
newValue?: AnyDuringMigration,
|
||||
): number | null {
|
||||
if (newValue === null) {
|
||||
return null;
|
||||
@@ -325,7 +325,7 @@ export class FieldNumber extends FieldInput<number> {
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
options
|
||||
options,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ function fromJsonInternal<T>(options: RegistryOptions): Field<T> | null {
|
||||
options['type'] +
|
||||
'. The field is probably not being registered. This could be because' +
|
||||
' the file is not loaded, the field does not register itself (Issue' +
|
||||
' #1584), or the registration is not being reached.'
|
||||
' #1584), or the registration is not being reached.',
|
||||
);
|
||||
return null;
|
||||
} else if (typeof (fieldObject as any).fromJson !== 'function') {
|
||||
|
||||
@@ -45,7 +45,7 @@ export class FieldTextInput extends FieldInput<string> {
|
||||
constructor(
|
||||
value?: string | typeof Field.SKIP_SETUP,
|
||||
validator?: FieldTextInputValidator | null,
|
||||
config?: FieldTextInputConfig
|
||||
config?: FieldTextInputConfig,
|
||||
) {
|
||||
super(value, validator, config);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export class FieldTextInput extends FieldInput<string> {
|
||||
* @returns A valid string, or null if invalid.
|
||||
*/
|
||||
protected override doClassValidation_(
|
||||
newValue?: AnyDuringMigration
|
||||
newValue?: AnyDuringMigration,
|
||||
): string | null {
|
||||
if (newValue === undefined) {
|
||||
return null;
|
||||
|
||||
@@ -84,7 +84,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
validator?: FieldVariableValidator,
|
||||
variableTypes?: string[],
|
||||
defaultType?: string,
|
||||
config?: FieldVariableConfig
|
||||
config?: FieldVariableConfig,
|
||||
) {
|
||||
super(Field.SKIP_SETUP);
|
||||
|
||||
@@ -130,8 +130,6 @@ export class FieldVariable extends FieldDropdown {
|
||||
* Initialize the model for this field if it has not already been initialized.
|
||||
* If the value has not been set to a variable by the first render, we make up
|
||||
* a variable rather than let the value be invalid.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
override initModel() {
|
||||
const block = this.getSourceBlock();
|
||||
@@ -145,7 +143,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
block.workspace,
|
||||
null,
|
||||
this.defaultVariableName,
|
||||
this.defaultType
|
||||
this.defaultType,
|
||||
);
|
||||
// Don't call setValue because we don't want to cause a rerender.
|
||||
this.doValueUpdate_(variable.getId());
|
||||
@@ -189,7 +187,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
block.workspace,
|
||||
id,
|
||||
variableName as AnyDuringMigration,
|
||||
variableType
|
||||
variableType,
|
||||
);
|
||||
|
||||
// This should never happen :)
|
||||
@@ -202,7 +200,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
', and ' +
|
||||
'does not match variable field that references it: ' +
|
||||
Xml.domToText(fieldElement) +
|
||||
'.'
|
||||
'.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -271,7 +269,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
block.workspace,
|
||||
state['id'] || null,
|
||||
state['name'],
|
||||
state['type'] || ''
|
||||
state['type'] || '',
|
||||
);
|
||||
this.setValue(variable.getId());
|
||||
}
|
||||
@@ -344,7 +342,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
* @returns The validated ID, or null if invalid.
|
||||
*/
|
||||
protected override doClassValidation_(
|
||||
newValue?: AnyDuringMigration
|
||||
newValue?: AnyDuringMigration,
|
||||
): string | null {
|
||||
if (newValue === null) {
|
||||
return null;
|
||||
@@ -357,7 +355,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
const variable = Variables.getVariable(block.workspace, newId);
|
||||
if (!variable) {
|
||||
console.warn(
|
||||
"Variable id doesn't point to a real variable! " + 'ID was ' + newId
|
||||
"Variable id doesn't point to a real variable! " + 'ID was ' + newId,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
@@ -425,7 +423,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
// Throw an error if variableTypes is an empty list.
|
||||
const name = this.getText();
|
||||
throw Error(
|
||||
"'variableTypes' of field variable " + name + ' was an empty list'
|
||||
"'variableTypes' of field variable " + name + ' was an empty list',
|
||||
);
|
||||
}
|
||||
return variableTypes;
|
||||
@@ -460,13 +458,13 @@ export class FieldVariable extends FieldDropdown {
|
||||
"Invalid default type '" +
|
||||
defaultType +
|
||||
"' in " +
|
||||
'the definition of a FieldVariable'
|
||||
'the definition of a FieldVariable',
|
||||
);
|
||||
}
|
||||
} else if (variableTypes !== null) {
|
||||
throw Error(
|
||||
"'variableTypes' was not an array in the definition of " +
|
||||
'a FieldVariable'
|
||||
'a FieldVariable',
|
||||
);
|
||||
}
|
||||
// Only update the field once all checks pass.
|
||||
@@ -501,7 +499,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
// Rename variable.
|
||||
Variables.renameVariable(
|
||||
this.sourceBlock_.workspace,
|
||||
this.variable as VariableModel
|
||||
this.variable as VariableModel,
|
||||
);
|
||||
return;
|
||||
} else if (id === internalConstants.DELETE_VARIABLE_ID) {
|
||||
@@ -536,7 +534,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
* @internal
|
||||
*/
|
||||
static override fromJson(
|
||||
options: FieldVariableFromJsonConfig
|
||||
options: FieldVariableFromJsonConfig,
|
||||
): FieldVariable {
|
||||
const varName = parsing.replaceMessageReferences(options.variable);
|
||||
// `this` might be a subclass of FieldVariable if that class doesn't
|
||||
@@ -554,7 +552,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
if (!this.variable) {
|
||||
throw Error(
|
||||
'Tried to call dropdownCreate on a variable field with no' +
|
||||
' variable selected.'
|
||||
' variable selected.',
|
||||
);
|
||||
}
|
||||
const name = this.getText();
|
||||
|
||||
@@ -36,6 +36,7 @@ import * as Variables from './variables.js';
|
||||
import {WorkspaceSvg} from './workspace_svg.js';
|
||||
import * as utilsXml from './utils/xml.js';
|
||||
import * as Xml from './xml.js';
|
||||
import * as renderManagement from './render_management.js';
|
||||
|
||||
enum FlyoutItemType {
|
||||
BLOCK = 'block',
|
||||
@@ -263,7 +264,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
|
||||
this.workspace_ = new WorkspaceSvg(workspaceOptions);
|
||||
this.workspace_.setMetricsManager(
|
||||
new FlyoutMetricsManager(this.workspace_, this)
|
||||
new FlyoutMetricsManager(this.workspace_, this),
|
||||
);
|
||||
|
||||
this.workspace_.internalIsFlyout = true;
|
||||
@@ -328,7 +329,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
* @returns The flyout's SVG group.
|
||||
*/
|
||||
createDom(
|
||||
tagName: string | Svg<SVGSVGElement> | Svg<SVGGElement>
|
||||
tagName: string | Svg<SVGSVGElement> | Svg<SVGGElement>,
|
||||
): SVGElement {
|
||||
/*
|
||||
<svg | g>
|
||||
@@ -345,7 +346,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
this.svgBackground_ = dom.createSvgElement(
|
||||
Svg.PATH,
|
||||
{'class': 'blocklyFlyoutBackground'},
|
||||
this.svgGroup_
|
||||
this.svgGroup_,
|
||||
);
|
||||
this.svgGroup_.appendChild(this.workspace_.createDom());
|
||||
this.workspace_
|
||||
@@ -372,7 +373,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
this.horizontalLayout,
|
||||
!this.horizontalLayout,
|
||||
'blocklyFlyoutScrollbar',
|
||||
this.SCROLLBAR_MARGIN
|
||||
this.SCROLLBAR_MARGIN,
|
||||
);
|
||||
|
||||
this.hide();
|
||||
@@ -382,8 +383,8 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
this.svgGroup_ as SVGGElement,
|
||||
'wheel',
|
||||
this,
|
||||
this.wheel_
|
||||
)
|
||||
this.wheel_,
|
||||
),
|
||||
);
|
||||
if (!this.autoClose) {
|
||||
this.filterWrapper = this.filterForCapacity.bind(this);
|
||||
@@ -396,13 +397,13 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
this.svgBackground_ as SVGPathElement,
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onMouseDown
|
||||
)
|
||||
this.onMouseDown,
|
||||
),
|
||||
);
|
||||
|
||||
// A flyout connected to a workspace doesn't have its own current gesture.
|
||||
this.workspace_.getGesture = this.targetWorkspace.getGesture.bind(
|
||||
this.targetWorkspace
|
||||
this.targetWorkspace,
|
||||
);
|
||||
|
||||
// Get variables from the main workspace rather than the target workspace.
|
||||
@@ -571,13 +572,13 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
if (scrollbar.hScroll) {
|
||||
scrollbar.hScroll.setPosition(
|
||||
scrollbar.hScroll.position.x,
|
||||
scrollbar.hScroll.position.y
|
||||
scrollbar.hScroll.position.y,
|
||||
);
|
||||
}
|
||||
if (scrollbar.vScroll) {
|
||||
scrollbar.vScroll.setPosition(
|
||||
scrollbar.vScroll.position.x,
|
||||
scrollbar.vScroll.position.y
|
||||
scrollbar.vScroll.position.y,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -626,6 +627,8 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
const parsedContent = toolbox.convertFlyoutDefToJsonArray(flyoutDef);
|
||||
const flyoutInfo = this.createFlyoutInfo(parsedContent);
|
||||
|
||||
renderManagement.triggerQueuedRenders();
|
||||
|
||||
this.layout_(flyoutInfo.contents, flyoutInfo.gaps);
|
||||
|
||||
if (this.horizontalLayout) {
|
||||
@@ -717,7 +720,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
* flyout in one of its many forms.
|
||||
*/
|
||||
private getDynamicCategoryContents(
|
||||
categoryName: string
|
||||
categoryName: string,
|
||||
): toolbox.FlyoutDefinition {
|
||||
// Look up the correct category generation function and call that to get a
|
||||
// valid XML list.
|
||||
@@ -726,7 +729,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
if (typeof fnToApply !== 'function') {
|
||||
throw TypeError(
|
||||
"Couldn't find a callback function when opening" +
|
||||
' a toolbox category.'
|
||||
' a toolbox category.',
|
||||
);
|
||||
}
|
||||
return fnToApply(this.workspace_.targetWorkspace!);
|
||||
@@ -742,13 +745,13 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
*/
|
||||
private createButton(
|
||||
btnInfo: toolbox.ButtonOrLabelInfo,
|
||||
isLabel: boolean
|
||||
isLabel: boolean,
|
||||
): FlyoutButton {
|
||||
const curButton = new FlyoutButton(
|
||||
this.workspace_,
|
||||
this.targetWorkspace as WorkspaceSvg,
|
||||
btnInfo,
|
||||
isLabel
|
||||
isLabel,
|
||||
);
|
||||
return curButton;
|
||||
}
|
||||
@@ -770,7 +773,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
) as Element;
|
||||
block = this.getRecycledBlock(xml.getAttribute('type')!);
|
||||
if (!block) {
|
||||
block = Xml.domToBlock(xml, this.workspace_);
|
||||
block = Xml.domToBlockInternal(xml, this.workspace_);
|
||||
}
|
||||
} else {
|
||||
block = this.getRecycledBlock(blockInfo['type']!);
|
||||
@@ -779,7 +782,10 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
blockInfo['enabled'] =
|
||||
blockInfo['disabled'] !== 'true' && blockInfo['disabled'] !== true;
|
||||
}
|
||||
block = blocks.append(blockInfo as blocks.State, this.workspace_);
|
||||
block = blocks.appendInternal(
|
||||
blockInfo as blocks.State,
|
||||
this.workspace_,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -821,7 +827,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
private addBlockGap(
|
||||
blockInfo: toolbox.BlockInfo,
|
||||
gaps: number[],
|
||||
defaultGap: number
|
||||
defaultGap: number,
|
||||
) {
|
||||
let gap;
|
||||
if (blockInfo['gap']) {
|
||||
@@ -849,7 +855,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
private addSeparatorGap(
|
||||
sepInfo: toolbox.SeparatorInfo,
|
||||
gaps: number[],
|
||||
defaultGap: number
|
||||
defaultGap: number,
|
||||
) {
|
||||
// Change the gap between two toolbox elements.
|
||||
// <sep gap="36"></sep>
|
||||
@@ -941,35 +947,35 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
protected addBlockListeners_(
|
||||
root: SVGElement,
|
||||
block: BlockSvg,
|
||||
rect: SVGElement
|
||||
rect: SVGElement,
|
||||
) {
|
||||
this.listeners.push(
|
||||
browserEvents.conditionalBind(
|
||||
root,
|
||||
'pointerdown',
|
||||
null,
|
||||
this.blockMouseDown(block)
|
||||
)
|
||||
this.blockMouseDown(block),
|
||||
),
|
||||
);
|
||||
this.listeners.push(
|
||||
browserEvents.conditionalBind(
|
||||
rect,
|
||||
'pointerdown',
|
||||
null,
|
||||
this.blockMouseDown(block)
|
||||
)
|
||||
this.blockMouseDown(block),
|
||||
),
|
||||
);
|
||||
this.listeners.push(
|
||||
browserEvents.bind(root, 'pointerenter', block, block.addSelect)
|
||||
browserEvents.bind(root, 'pointerenter', block, block.addSelect),
|
||||
);
|
||||
this.listeners.push(
|
||||
browserEvents.bind(root, 'pointerleave', block, block.removeSelect)
|
||||
browserEvents.bind(root, 'pointerleave', block, block.removeSelect),
|
||||
);
|
||||
this.listeners.push(
|
||||
browserEvents.bind(rect, 'pointerenter', block, block.addSelect)
|
||||
browserEvents.bind(rect, 'pointerenter', block, block.addSelect),
|
||||
);
|
||||
this.listeners.push(
|
||||
browserEvents.bind(rect, 'pointerleave', block, block.removeSelect)
|
||||
browserEvents.bind(rect, 'pointerleave', block, block.removeSelect),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1038,7 +1044,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
|
||||
const newVariables = Variables.getAddedVariables(
|
||||
this.targetWorkspace,
|
||||
variablesBeforeCreation
|
||||
variablesBeforeCreation,
|
||||
);
|
||||
|
||||
if (eventUtils.isEnabled()) {
|
||||
@@ -1047,7 +1053,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
for (let i = 0; i < newVariables.length; i++) {
|
||||
const thisVariable = newVariables[i];
|
||||
eventUtils.fire(
|
||||
new (eventUtils.get(eventUtils.VAR_CREATE))(thisVariable)
|
||||
new (eventUtils.get(eventUtils.VAR_CREATE))(thisVariable),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1082,8 +1088,8 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
buttonSvg,
|
||||
'pointerdown',
|
||||
this,
|
||||
this.onMouseDown
|
||||
)
|
||||
this.onMouseDown,
|
||||
),
|
||||
);
|
||||
|
||||
this.buttons_.push(button);
|
||||
@@ -1107,7 +1113,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
x: number,
|
||||
y: number,
|
||||
blockHW: {height: number; width: number},
|
||||
index: number
|
||||
index: number,
|
||||
): SVGElement {
|
||||
// Create an invisible rectangle under the block to act as a button. Just
|
||||
// using the block as a button is poor, since blocks have holes in them.
|
||||
@@ -1144,7 +1150,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
rect.setAttribute('y', String(blockXY.y));
|
||||
rect.setAttribute(
|
||||
'x',
|
||||
String(this.RTL ? blockXY.x - blockHW.width : blockXY.x)
|
||||
String(this.RTL ? blockXY.x - blockHW.width : blockXY.x),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1159,7 +1165,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
for (let i = 0, block; (block = blocks[i]); i++) {
|
||||
if (this.permanentlyDisabled.indexOf(block) === -1) {
|
||||
const enable = this.targetWorkspace.isCapacityAvailable(
|
||||
common.getBlockTypeCounts(block)
|
||||
common.getBlockTypeCounts(block),
|
||||
);
|
||||
while (block) {
|
||||
block.setEnabled(enable);
|
||||
@@ -1244,14 +1250,14 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
|
||||
// of the injection div.
|
||||
const oldBlockOffsetPixels = Coordinate.sum(
|
||||
flyoutOffsetPixels,
|
||||
oldBlockPos
|
||||
oldBlockPos,
|
||||
);
|
||||
|
||||
// The position of the old block in pixels relative to the origin of the
|
||||
// main workspace.
|
||||
const finalOffset = Coordinate.difference(
|
||||
oldBlockOffsetPixels,
|
||||
mainOffsetPixels
|
||||
mainOffsetPixels,
|
||||
);
|
||||
// The position of the old block in main workspace coordinates.
|
||||
finalOffset.scale(1 / targetWorkspace.scale);
|
||||
|
||||
@@ -67,7 +67,7 @@ export class FlyoutButton {
|
||||
private readonly workspace: WorkspaceSvg,
|
||||
private readonly targetWorkspace: WorkspaceSvg,
|
||||
json: toolbox.ButtonOrLabelInfo,
|
||||
private readonly isLabel_: boolean
|
||||
private readonly isLabel_: boolean,
|
||||
) {
|
||||
this.text = json['text'];
|
||||
|
||||
@@ -102,7 +102,7 @@ export class FlyoutButton {
|
||||
this.svgGroup = dom.createSvgElement(
|
||||
Svg.G,
|
||||
{'class': cssClass},
|
||||
this.workspace.getCanvas()
|
||||
this.workspace.getCanvas(),
|
||||
);
|
||||
|
||||
let shadow;
|
||||
@@ -117,7 +117,7 @@ export class FlyoutButton {
|
||||
'x': 1,
|
||||
'y': 1,
|
||||
},
|
||||
this.svgGroup!
|
||||
this.svgGroup!,
|
||||
);
|
||||
}
|
||||
// Background rectangle.
|
||||
@@ -130,7 +130,7 @@ export class FlyoutButton {
|
||||
'rx': FlyoutButton.BORDER_RADIUS,
|
||||
'ry': FlyoutButton.BORDER_RADIUS,
|
||||
},
|
||||
this.svgGroup!
|
||||
this.svgGroup!,
|
||||
);
|
||||
|
||||
const svgText = dom.createSvgElement(
|
||||
@@ -141,7 +141,7 @@ export class FlyoutButton {
|
||||
'y': 0,
|
||||
'text-anchor': 'middle',
|
||||
},
|
||||
this.svgGroup!
|
||||
this.svgGroup!,
|
||||
);
|
||||
let text = parsing.replaceMessageReferences(this.text);
|
||||
if (this.workspace.RTL) {
|
||||
@@ -163,13 +163,13 @@ export class FlyoutButton {
|
||||
svgText,
|
||||
fontSize,
|
||||
fontWeight,
|
||||
fontFamily
|
||||
fontFamily,
|
||||
);
|
||||
const fontMetrics = dom.measureFontMetrics(
|
||||
text,
|
||||
fontSize,
|
||||
fontWeight,
|
||||
fontFamily
|
||||
fontFamily,
|
||||
);
|
||||
this.height = fontMetrics.height;
|
||||
|
||||
@@ -185,7 +185,7 @@ export class FlyoutButton {
|
||||
svgText.setAttribute('x', String(this.width / 2));
|
||||
svgText.setAttribute(
|
||||
'y',
|
||||
String(this.height / 2 - fontMetrics.height / 2 + fontMetrics.baseline)
|
||||
String(this.height / 2 - fontMetrics.height / 2 + fontMetrics.baseline),
|
||||
);
|
||||
|
||||
this.updateTransform();
|
||||
@@ -196,7 +196,7 @@ export class FlyoutButton {
|
||||
this.svgGroup as AnyDuringMigration,
|
||||
'pointerup',
|
||||
this,
|
||||
this.onMouseUp
|
||||
this.onMouseUp,
|
||||
);
|
||||
return this.svgGroup!;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ export class FlyoutButton {
|
||||
private updateTransform() {
|
||||
this.svgGroup!.setAttribute(
|
||||
'transform',
|
||||
'translate(' + this.position.x + ',' + this.position.y + ')'
|
||||
'translate(' + this.position.x + ',' + this.position.y + ')',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ export class FlyoutButton {
|
||||
|
||||
if (this.isLabel_ && this.callbackKey) {
|
||||
console.warn(
|
||||
'Labels should not have callbacks. Label text: ' + this.text
|
||||
'Labels should not have callbacks. Label text: ' + this.text,
|
||||
);
|
||||
} else if (
|
||||
!this.isLabel_ &&
|
||||
|
||||
@@ -19,7 +19,7 @@ import type {FlyoutButton} from './flyout_button.js';
|
||||
import type {Options} from './options.js';
|
||||
import * as registry from './registry.js';
|
||||
import {Scrollbar} from './scrollbar.js';
|
||||
import type {Coordinate} from './utils/coordinate.js';
|
||||
import {Coordinate} from './utils/coordinate.js';
|
||||
import {Rect} from './utils/rect.js';
|
||||
import * as toolbox from './utils/toolbox.js';
|
||||
import * as WidgetDiv from './widgetdiv.js';
|
||||
@@ -60,7 +60,7 @@ export class HorizontalFlyout extends Flyout {
|
||||
|
||||
this.workspace_.translate(
|
||||
this.workspace_.scrollX + absoluteMetrics.left,
|
||||
this.workspace_.scrollY + absoluteMetrics.top
|
||||
this.workspace_.scrollY + absoluteMetrics.top,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ export class HorizontalFlyout extends Flyout {
|
||||
0,
|
||||
1,
|
||||
-this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS
|
||||
this.CORNER_RADIUS,
|
||||
);
|
||||
path.push('h', -width);
|
||||
// Left.
|
||||
@@ -182,7 +182,7 @@ export class HorizontalFlyout extends Flyout {
|
||||
0,
|
||||
1,
|
||||
-this.CORNER_RADIUS,
|
||||
-this.CORNER_RADIUS
|
||||
-this.CORNER_RADIUS,
|
||||
);
|
||||
path.push('z');
|
||||
} else {
|
||||
@@ -195,7 +195,7 @@ export class HorizontalFlyout extends Flyout {
|
||||
0,
|
||||
1,
|
||||
this.CORNER_RADIUS,
|
||||
-this.CORNER_RADIUS
|
||||
-this.CORNER_RADIUS,
|
||||
);
|
||||
path.push('h', width);
|
||||
// Right.
|
||||
@@ -207,7 +207,7 @@ export class HorizontalFlyout extends Flyout {
|
||||
0,
|
||||
1,
|
||||
this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS
|
||||
this.CORNER_RADIUS,
|
||||
);
|
||||
path.push('v', height);
|
||||
// Bottom.
|
||||
@@ -285,7 +285,8 @@ export class HorizontalFlyout extends Flyout {
|
||||
} else {
|
||||
moveX = cursorX - tab;
|
||||
}
|
||||
block!.moveBy(moveX, cursorY);
|
||||
// No 'reason' provided since events are disabled.
|
||||
block!.moveTo(new Coordinate(moveX, cursorY));
|
||||
|
||||
const rect = this.createRect_(block!, moveX, cursorY, blockHW, i);
|
||||
cursorX += blockHW.width + gaps[i];
|
||||
@@ -393,7 +394,7 @@ export class HorizontalFlyout extends Flyout {
|
||||
// (ie toolbox edge).
|
||||
this.targetWorkspace!.translate(
|
||||
this.targetWorkspace!.scrollX,
|
||||
this.targetWorkspace!.scrollY + flyoutHeight
|
||||
this.targetWorkspace!.scrollY + flyoutHeight,
|
||||
);
|
||||
}
|
||||
this.height_ = flyoutHeight;
|
||||
@@ -406,5 +407,5 @@ export class HorizontalFlyout extends Flyout {
|
||||
registry.register(
|
||||
registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,
|
||||
registry.DEFAULT,
|
||||
HorizontalFlyout
|
||||
HorizontalFlyout,
|
||||
);
|
||||
|
||||
@@ -70,7 +70,7 @@ export class FlyoutMetricsManager extends MetricsManager {
|
||||
override getScrollMetrics(
|
||||
opt_getWorkspaceCoordinates?: boolean,
|
||||
opt_viewMetrics?: ContainerRegion,
|
||||
opt_contentMetrics?: ContainerRegion
|
||||
opt_contentMetrics?: ContainerRegion,
|
||||
) {
|
||||
const contentMetrics = opt_contentMetrics || this.getContentMetrics();
|
||||
const margin = this.flyout_.MARGIN * this.workspace_.scale;
|
||||
|
||||
@@ -19,7 +19,7 @@ import type {FlyoutButton} from './flyout_button.js';
|
||||
import type {Options} from './options.js';
|
||||
import * as registry from './registry.js';
|
||||
import {Scrollbar} from './scrollbar.js';
|
||||
import type {Coordinate} from './utils/coordinate.js';
|
||||
import {Coordinate} from './utils/coordinate.js';
|
||||
import {Rect} from './utils/rect.js';
|
||||
import * as toolbox from './utils/toolbox.js';
|
||||
import * as WidgetDiv from './widgetdiv.js';
|
||||
@@ -59,7 +59,7 @@ export class VerticalFlyout extends Flyout {
|
||||
}
|
||||
this.workspace_.translate(
|
||||
this.workspace_.scrollX + absoluteMetrics.left,
|
||||
this.workspace_.scrollY + absoluteMetrics.top
|
||||
this.workspace_.scrollY + absoluteMetrics.top,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ export class VerticalFlyout extends Flyout {
|
||||
0,
|
||||
atRight ? 0 : 1,
|
||||
atRight ? -this.CORNER_RADIUS : this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS
|
||||
this.CORNER_RADIUS,
|
||||
);
|
||||
// Side closest to workspace.
|
||||
path.push('v', Math.max(0, height));
|
||||
@@ -180,7 +180,7 @@ export class VerticalFlyout extends Flyout {
|
||||
0,
|
||||
atRight ? 0 : 1,
|
||||
atRight ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS
|
||||
this.CORNER_RADIUS,
|
||||
);
|
||||
// Bottom.
|
||||
path.push('h', atRight ? width : -width);
|
||||
@@ -246,14 +246,15 @@ export class VerticalFlyout extends Flyout {
|
||||
const moveX = block!.outputConnection
|
||||
? cursorX - this.tabWidth_
|
||||
: cursorX;
|
||||
block!.moveBy(moveX, cursorY);
|
||||
// No 'reason' provided since events are disabled.
|
||||
block!.moveTo(new Coordinate(moveX, cursorY));
|
||||
|
||||
const rect = this.createRect_(
|
||||
block!,
|
||||
this.RTL ? moveX - blockHW.width : moveX,
|
||||
cursorY,
|
||||
blockHW,
|
||||
i
|
||||
i,
|
||||
);
|
||||
|
||||
this.addBlockListeners_(root, block!, rect);
|
||||
@@ -357,7 +358,8 @@ export class VerticalFlyout extends Flyout {
|
||||
if (!block.outputConnection) {
|
||||
newX -= this.tabWidth_;
|
||||
}
|
||||
block.moveBy(newX - oldX, 0);
|
||||
// No 'reason' provided since events are disabled.
|
||||
block.moveTo(new Coordinate(newX - oldX, 0));
|
||||
}
|
||||
if (this.rectMap_.has(block)) {
|
||||
this.moveRectToBlock_(this.rectMap_.get(block)!, block);
|
||||
@@ -386,7 +388,7 @@ export class VerticalFlyout extends Flyout {
|
||||
// (ie toolbox edge).
|
||||
this.targetWorkspace!.translate(
|
||||
this.targetWorkspace!.scrollX + flyoutWidth,
|
||||
this.targetWorkspace!.scrollY
|
||||
this.targetWorkspace!.scrollY,
|
||||
);
|
||||
}
|
||||
this.width_ = flyoutWidth;
|
||||
@@ -399,5 +401,5 @@ export class VerticalFlyout extends Flyout {
|
||||
registry.register(
|
||||
registry.Type.FLYOUTS_VERTICAL_TOOLBOX,
|
||||
registry.DEFAULT,
|
||||
VerticalFlyout
|
||||
VerticalFlyout,
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ import {warn} from './utils/deprecation.js';
|
||||
*/
|
||||
export type BlockGenerator = (
|
||||
block: Block,
|
||||
generator: CodeGenerator
|
||||
generator: CodeGenerator,
|
||||
) => [string, number] | string | null;
|
||||
|
||||
/**
|
||||
@@ -117,7 +117,7 @@ export class CodeGenerator {
|
||||
|
||||
this.FUNCTION_NAME_PLACEHOLDER_REGEXP_ = new RegExp(
|
||||
this.FUNCTION_NAME_PLACEHOLDER_,
|
||||
'g'
|
||||
'g',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ export class CodeGenerator {
|
||||
if (!workspace) {
|
||||
// Backwards compatibility from before there could be multiple workspaces.
|
||||
console.warn(
|
||||
'No workspace specified in workspaceToCode call. Guessing.'
|
||||
'No workspace specified in workspaceToCode call. Guessing.',
|
||||
);
|
||||
workspace = common.getMainWorkspace();
|
||||
}
|
||||
@@ -220,11 +220,11 @@ export class CodeGenerator {
|
||||
*/
|
||||
blockToCode(
|
||||
block: Block | null,
|
||||
opt_thisOnly?: boolean
|
||||
opt_thisOnly?: boolean,
|
||||
): string | [string, number] {
|
||||
if (this.isInitialized === false) {
|
||||
console.warn(
|
||||
'CodeGenerator init was not called before blockToCode was called.'
|
||||
'CodeGenerator init was not called before blockToCode was called.',
|
||||
);
|
||||
}
|
||||
if (!block) {
|
||||
@@ -247,14 +247,14 @@ export class CodeGenerator {
|
||||
'block generator functions on CodeGenerator objects',
|
||||
'10.0',
|
||||
'11.0',
|
||||
'the .forBlock[blockType] dictionary'
|
||||
'the .forBlock[blockType] dictionary',
|
||||
);
|
||||
func = (this as any)[block.type];
|
||||
}
|
||||
if (typeof func !== 'function') {
|
||||
throw Error(
|
||||
`${this.name_} generator does not know how to generate code` +
|
||||
`for block type "${block.type}".`
|
||||
`for block type "${block.type}".`,
|
||||
);
|
||||
}
|
||||
// First argument to func.call is the value of 'this' in the generator.
|
||||
@@ -313,14 +313,14 @@ export class CodeGenerator {
|
||||
throw TypeError(
|
||||
`Expecting tuple from value block: ${targetBlock.type} See ` +
|
||||
`developers.google.com/blockly/guides/create-custom-blocks/generating-code ` +
|
||||
`for more information`
|
||||
`for more information`,
|
||||
);
|
||||
}
|
||||
let code = tuple[0];
|
||||
const innerOrder = tuple[1];
|
||||
if (isNaN(innerOrder)) {
|
||||
throw TypeError(
|
||||
'Expecting valid order from value block: ' + targetBlock.type
|
||||
'Expecting valid order from value block: ' + targetBlock.type,
|
||||
);
|
||||
}
|
||||
if (!code) {
|
||||
@@ -383,7 +383,7 @@ export class CodeGenerator {
|
||||
if (typeof code !== 'string') {
|
||||
throw TypeError(
|
||||
'Expecting code from statement block: ' +
|
||||
(targetBlock && targetBlock.type)
|
||||
(targetBlock && targetBlock.type),
|
||||
);
|
||||
}
|
||||
if (code) {
|
||||
@@ -407,14 +407,14 @@ export class CodeGenerator {
|
||||
branch =
|
||||
this.prefixLines(
|
||||
this.injectId(this.INFINITE_LOOP_TRAP, block),
|
||||
this.INDENT
|
||||
this.INDENT,
|
||||
) + branch;
|
||||
}
|
||||
if (this.STATEMENT_SUFFIX && !block.suppressPrefixSuffix) {
|
||||
branch =
|
||||
this.prefixLines(
|
||||
this.injectId(this.STATEMENT_SUFFIX, block),
|
||||
this.INDENT
|
||||
this.INDENT,
|
||||
) + branch;
|
||||
}
|
||||
if (this.STATEMENT_PREFIX && !block.suppressPrefixSuffix) {
|
||||
@@ -422,7 +422,7 @@ export class CodeGenerator {
|
||||
branch +
|
||||
this.prefixLines(
|
||||
this.injectId(this.STATEMENT_PREFIX, block),
|
||||
this.INDENT
|
||||
this.INDENT,
|
||||
);
|
||||
}
|
||||
return branch;
|
||||
@@ -475,7 +475,7 @@ export class CodeGenerator {
|
||||
if (!this.definitions_[desiredName]) {
|
||||
const functionName = this.nameDB_!.getDistinctName(
|
||||
desiredName,
|
||||
NameType.PROCEDURE
|
||||
NameType.PROCEDURE,
|
||||
);
|
||||
this.functionNames_[desiredName] = functionName;
|
||||
if (Array.isArray(code)) {
|
||||
@@ -531,7 +531,7 @@ export class CodeGenerator {
|
||||
protected scrub_(
|
||||
_block: Block,
|
||||
code: string,
|
||||
_opt_thisOnly?: boolean
|
||||
_opt_thisOnly?: boolean,
|
||||
): string {
|
||||
// Optionally override
|
||||
return code;
|
||||
|
||||
@@ -177,7 +177,7 @@ export class Gesture {
|
||||
*/
|
||||
constructor(
|
||||
e: PointerEvent,
|
||||
private readonly creatorWorkspace: WorkspaceSvg
|
||||
private readonly creatorWorkspace: WorkspaceSvg,
|
||||
) {
|
||||
this.mostRecentEvent = e;
|
||||
|
||||
@@ -245,7 +245,7 @@ export class Gesture {
|
||||
private updateDragDelta(currentXY: Coordinate): boolean {
|
||||
this.currentDragDeltaXY = Coordinate.difference(
|
||||
currentXY,
|
||||
this.mouseDownXY
|
||||
this.mouseDownXY,
|
||||
);
|
||||
|
||||
if (!this.hasExceededDragRadius) {
|
||||
@@ -361,7 +361,7 @@ export class Gesture {
|
||||
if (!this.startWorkspace_) {
|
||||
throw new Error(
|
||||
'Cannot update dragging the workspace because the ' +
|
||||
'start workspace is undefined'
|
||||
'start workspace is undefined',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -406,12 +406,12 @@ export class Gesture {
|
||||
const BlockDraggerClass = registry.getClassFromOptions(
|
||||
registry.Type.BLOCK_DRAGGER,
|
||||
this.creatorWorkspace.options,
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
this.blockDragger = new BlockDraggerClass!(
|
||||
this.targetBlock,
|
||||
this.startWorkspace_
|
||||
this.startWorkspace_,
|
||||
);
|
||||
this.blockDragger!.startDrag(this.currentDragDeltaXY, this.healStack);
|
||||
this.blockDragger!.drag(this.mostRecentEvent, this.currentDragDeltaXY);
|
||||
@@ -422,24 +422,24 @@ export class Gesture {
|
||||
if (!this.startBubble) {
|
||||
throw new Error(
|
||||
'Cannot update dragging the bubble because the start ' +
|
||||
'bubble is undefined'
|
||||
'bubble is undefined',
|
||||
);
|
||||
}
|
||||
if (!this.startWorkspace_) {
|
||||
throw new Error(
|
||||
'Cannot update dragging the bubble because the start ' +
|
||||
'workspace is undefined'
|
||||
'workspace is undefined',
|
||||
);
|
||||
}
|
||||
|
||||
this.bubbleDragger = new BubbleDragger(
|
||||
this.startBubble,
|
||||
this.startWorkspace_
|
||||
this.startWorkspace_,
|
||||
);
|
||||
this.bubbleDragger.startBubbleDrag();
|
||||
this.bubbleDragger.dragBubble(
|
||||
this.mostRecentEvent,
|
||||
this.currentDragDeltaXY
|
||||
this.currentDragDeltaXY,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@ export class Gesture {
|
||||
if (!this.startWorkspace_) {
|
||||
throw new Error(
|
||||
'Cannot start the touch gesture becauase the start ' +
|
||||
'workspace is undefined'
|
||||
'workspace is undefined',
|
||||
);
|
||||
}
|
||||
this.isPinchZoomEnabled =
|
||||
@@ -524,8 +524,8 @@ export class Gesture {
|
||||
'pointerdown',
|
||||
null,
|
||||
this.handleStart.bind(this),
|
||||
/* opt_noCaptureIdentifier */ true
|
||||
)
|
||||
/* opt_noCaptureIdentifier */ true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -533,8 +533,8 @@ export class Gesture {
|
||||
'pointermove',
|
||||
null,
|
||||
this.handleMove.bind(this),
|
||||
/* opt_noCaptureIdentifier */ true
|
||||
)
|
||||
/* opt_noCaptureIdentifier */ true,
|
||||
),
|
||||
);
|
||||
this.boundEvents.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -542,8 +542,8 @@ export class Gesture {
|
||||
'pointerup',
|
||||
null,
|
||||
this.handleUp.bind(this),
|
||||
/* opt_noCaptureIdentifier */ true
|
||||
)
|
||||
/* opt_noCaptureIdentifier */ true,
|
||||
),
|
||||
);
|
||||
|
||||
e.preventDefault();
|
||||
@@ -587,7 +587,7 @@ export class Gesture {
|
||||
} else if (this.bubbleDragger) {
|
||||
this.bubbleDragger.dragBubble(
|
||||
this.mostRecentEvent,
|
||||
this.currentDragDeltaXY
|
||||
this.currentDragDeltaXY,
|
||||
);
|
||||
}
|
||||
e.preventDefault();
|
||||
@@ -717,14 +717,14 @@ export class Gesture {
|
||||
: gestureScale * ZOOM_OUT_MULTIPLIER;
|
||||
if (!this.startWorkspace_) {
|
||||
throw new Error(
|
||||
'Cannot handle a pinch because the start workspace ' + 'is undefined'
|
||||
'Cannot handle a pinch because the start workspace ' + 'is undefined',
|
||||
);
|
||||
}
|
||||
const workspace = this.startWorkspace_;
|
||||
const position = browserEvents.mouseToSvg(
|
||||
e,
|
||||
workspace.getParentSvg(),
|
||||
workspace.getInverseScreenCTM()
|
||||
workspace.getInverseScreenCTM(),
|
||||
);
|
||||
workspace.zoom(position.x, position.y, delta);
|
||||
}
|
||||
@@ -790,7 +790,7 @@ export class Gesture {
|
||||
if (this.bubbleDragger) {
|
||||
this.bubbleDragger.endBubbleDrag(
|
||||
this.mostRecentEvent,
|
||||
this.currentDragDeltaXY
|
||||
this.currentDragDeltaXY,
|
||||
);
|
||||
} else if (this.blockDragger) {
|
||||
this.blockDragger.endDrag(this.mostRecentEvent, this.currentDragDeltaXY);
|
||||
@@ -836,7 +836,7 @@ export class Gesture {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.handleWsStart, ' +
|
||||
'but the gesture had already been started.'
|
||||
'but the gesture had already been started.',
|
||||
);
|
||||
}
|
||||
this.setStartWorkspace(ws);
|
||||
@@ -851,7 +851,7 @@ export class Gesture {
|
||||
*/
|
||||
private fireWorkspaceClick(ws: WorkspaceSvg) {
|
||||
eventUtils.fire(
|
||||
new (eventUtils.get(eventUtils.CLICK))(null, ws.id, 'workspace')
|
||||
new (eventUtils.get(eventUtils.CLICK))(null, ws.id, 'workspace'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -866,7 +866,7 @@ export class Gesture {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.handleFlyoutStart, ' +
|
||||
'but the gesture had already been started.'
|
||||
'but the gesture had already been started.',
|
||||
);
|
||||
}
|
||||
this.setStartFlyout(flyout);
|
||||
@@ -884,7 +884,7 @@ export class Gesture {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.handleBlockStart, ' +
|
||||
'but the gesture had already been started.'
|
||||
'but the gesture had already been started.',
|
||||
);
|
||||
}
|
||||
this.setStartBlock(block);
|
||||
@@ -902,7 +902,7 @@ export class Gesture {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.handleBubbleStart, ' +
|
||||
'but the gesture had already been started.'
|
||||
'but the gesture had already been started.',
|
||||
);
|
||||
}
|
||||
this.setStartBubble(bubble);
|
||||
@@ -926,7 +926,7 @@ export class Gesture {
|
||||
private doFieldClick() {
|
||||
if (!this.startField) {
|
||||
throw new Error(
|
||||
'Cannot do a field click because the start field is undefined'
|
||||
'Cannot do a field click because the start field is undefined',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -943,7 +943,7 @@ export class Gesture {
|
||||
private doIconClick() {
|
||||
if (!this.startIcon) {
|
||||
throw new Error(
|
||||
'Cannot do an icon click because the start icon is undefined'
|
||||
'Cannot do an icon click because the start icon is undefined',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -956,7 +956,7 @@ export class Gesture {
|
||||
if (this.flyout && this.flyout.autoClose) {
|
||||
if (!this.targetBlock) {
|
||||
throw new Error(
|
||||
'Cannot do a block click because the target block is ' + 'undefined'
|
||||
'Cannot do a block click because the target block is ' + 'undefined',
|
||||
);
|
||||
}
|
||||
if (this.targetBlock.isEnabled()) {
|
||||
@@ -970,14 +970,14 @@ export class Gesture {
|
||||
if (!this.startWorkspace_) {
|
||||
throw new Error(
|
||||
'Cannot do a block click because the start workspace ' +
|
||||
'is undefined'
|
||||
'is undefined',
|
||||
);
|
||||
}
|
||||
// Clicks events are on the start block, even if it was a shadow.
|
||||
const event = new (eventUtils.get(eventUtils.CLICK))(
|
||||
this.startBlock,
|
||||
this.startWorkspace_.id,
|
||||
'block'
|
||||
'block',
|
||||
);
|
||||
eventUtils.fire(event);
|
||||
}
|
||||
@@ -1027,7 +1027,7 @@ export class Gesture {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.setStartField, ' +
|
||||
'but the gesture had already been started.'
|
||||
'but the gesture had already been started.',
|
||||
);
|
||||
}
|
||||
if (!this.startField) {
|
||||
@@ -1045,7 +1045,7 @@ export class Gesture {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.setStartIcon, ' +
|
||||
'but the gesture had already been started.'
|
||||
'but the gesture had already been started.',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
15
core/grid.ts
15
core/grid.ts
@@ -33,7 +33,10 @@ export class Grid {
|
||||
* See grid documentation:
|
||||
* https://developers.google.com/blockly/guides/configure/web/grid
|
||||
*/
|
||||
constructor(private pattern: SVGElement, options: GridOptions) {
|
||||
constructor(
|
||||
private pattern: SVGElement,
|
||||
options: GridOptions,
|
||||
) {
|
||||
/** The spacing of the grid lines (in px). */
|
||||
this.spacing = options['spacing'] ?? 0;
|
||||
|
||||
@@ -122,7 +125,7 @@ export class Grid {
|
||||
x1: number,
|
||||
x2: number,
|
||||
y1: number,
|
||||
y2: number
|
||||
y2: number,
|
||||
) {
|
||||
if (line) {
|
||||
line.setAttribute('stroke-width', `${width}`);
|
||||
@@ -158,7 +161,7 @@ export class Grid {
|
||||
static createDom(
|
||||
rnd: string,
|
||||
gridOptions: GridOptions,
|
||||
defs: SVGElement
|
||||
defs: SVGElement,
|
||||
): SVGElement {
|
||||
/*
|
||||
<pattern id="blocklyGridPattern837493" patternUnits="userSpaceOnUse">
|
||||
@@ -169,20 +172,20 @@ export class Grid {
|
||||
const gridPattern = dom.createSvgElement(
|
||||
Svg.PATTERN,
|
||||
{'id': 'blocklyGridPattern' + rnd, 'patternUnits': 'userSpaceOnUse'},
|
||||
defs
|
||||
defs,
|
||||
);
|
||||
// x1, y1, x1, x2 properties will be set later in update.
|
||||
if ((gridOptions['length'] ?? 1) > 0 && (gridOptions['spacing'] ?? 0) > 0) {
|
||||
dom.createSvgElement(
|
||||
Svg.LINE,
|
||||
{'stroke': gridOptions['colour']},
|
||||
gridPattern
|
||||
gridPattern,
|
||||
);
|
||||
if (gridOptions['length'] ?? 1 > 1) {
|
||||
dom.createSvgElement(
|
||||
Svg.LINE,
|
||||
{'stroke': gridOptions['colour']},
|
||||
gridPattern
|
||||
gridPattern,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -84,7 +84,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
dom.createSvgElement(
|
||||
Svg.CIRCLE,
|
||||
{'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
// Can't use a real '?' text character since different browsers and
|
||||
// operating systems render it differently. Body of question mark.
|
||||
@@ -97,7 +97,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
'0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' +
|
||||
'-1.201,0.998 -1.201,1.528 -1.204,2.19z',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
// Dot of question mark.
|
||||
dom.createSvgElement(
|
||||
@@ -109,7 +109,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
'height': '2',
|
||||
'width': '2',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
this.text = state['text'] ?? '';
|
||||
this.bubbleSize = new Size(
|
||||
state['width'] ?? DEFAULT_BUBBLE_WIDTH,
|
||||
state['height'] ?? DEFAULT_BUBBLE_HEIGHT
|
||||
state['height'] ?? DEFAULT_BUBBLE_HEIGHT,
|
||||
);
|
||||
this.bubbleVisiblity = state['pinned'] ?? false;
|
||||
// Give the block a chance to be positioned and rendered before showing.
|
||||
@@ -260,8 +260,8 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
new (eventUtils.get(eventUtils.BUBBLE_OPEN))(
|
||||
this.sourceBlock,
|
||||
visible,
|
||||
'comment'
|
||||
)
|
||||
'comment',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
this.textInputBubble = new TextInputBubble(
|
||||
this.sourceBlock.workspace as WorkspaceSvg,
|
||||
this.getAnchorLocation(),
|
||||
this.getBubbleOwnerRect()
|
||||
this.getBubbleOwnerRect(),
|
||||
);
|
||||
this.textInputBubble.setText(this.getText());
|
||||
this.textInputBubble.setSize(this.bubbleSize, true);
|
||||
@@ -287,7 +287,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
this.getText(),
|
||||
this.sourceBlock.workspace as WorkspaceSvg,
|
||||
this.getAnchorLocation(),
|
||||
this.getBubbleOwnerRect()
|
||||
this.getBubbleOwnerRect(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ export class CommentIcon extends Icon implements IHasBubble, ISerializable {
|
||||
const midIcon = SIZE / 2;
|
||||
return Coordinate.sum(
|
||||
this.workspaceLocation,
|
||||
new Coordinate(midIcon, midIcon)
|
||||
new Coordinate(midIcon, midIcon),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export class DuplicateIconType extends Error {
|
||||
super(
|
||||
`Tried to append an icon of type ${icon.getType()} when an icon of ` +
|
||||
`that type already exists on the block. ` +
|
||||
`Use getIcon to access the existing icon.`
|
||||
`Use getIcon to access the existing icon.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export abstract class Icon implements IIcon {
|
||||
this.svgRoot,
|
||||
'pointerdown',
|
||||
this,
|
||||
pointerdownListener
|
||||
pointerdownListener,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ export abstract class Icon implements IIcon {
|
||||
private updateSvgRootOffset(): void {
|
||||
this.svgRoot?.setAttribute(
|
||||
'transform',
|
||||
`translate(${this.offsetInBlock.x}, ${this.offsetInBlock.y})`
|
||||
`translate(${this.offsetInBlock.x}, ${this.offsetInBlock.y})`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
|
||||
constructor(
|
||||
private readonly flyoutBlockTypes: string[],
|
||||
protected readonly sourceBlock: BlockSvg
|
||||
protected readonly sourceBlock: BlockSvg,
|
||||
) {
|
||||
super(sourceBlock);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
'height': '16',
|
||||
'width': '16',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
// Gear teeth.
|
||||
dom.createSvgElement(
|
||||
@@ -102,13 +102,13 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
'-0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,' +
|
||||
'0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
// Axle hole.
|
||||
dom.createSvgElement(
|
||||
Svg.CIRCLE,
|
||||
{'class': 'blocklyIconShape', 'r': '2.7', 'cx': '8', 'cy': '8'},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -158,13 +158,13 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
this.getMiniWorkspaceConfig(),
|
||||
this.sourceBlock.workspace,
|
||||
this.getAnchorLocation(),
|
||||
this.getBubbleOwnerRect()
|
||||
this.getBubbleOwnerRect(),
|
||||
);
|
||||
this.applyColour();
|
||||
this.createRootBlock();
|
||||
this.addSaveConnectionsListener();
|
||||
this.miniWorkspaceBubble?.addWorkspaceChangeListener(
|
||||
this.createMiniWorkspaceChangeListener()
|
||||
this.createMiniWorkspaceChangeListener(),
|
||||
);
|
||||
} else {
|
||||
this.miniWorkspaceBubble?.dispose();
|
||||
@@ -175,8 +175,8 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
new (eventUtils.get(eventUtils.BUBBLE_OPEN))(
|
||||
this.sourceBlock,
|
||||
visible,
|
||||
'mutator'
|
||||
)
|
||||
'mutator',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
const midIcon = SIZE / 2;
|
||||
return Coordinate.sum(
|
||||
this.workspaceLocation,
|
||||
new Coordinate(midIcon, midIcon)
|
||||
new Coordinate(midIcon, midIcon),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -227,8 +227,13 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
|
||||
/** Decomposes the source block to create blocks in the mini workspace. */
|
||||
private createRootBlock() {
|
||||
this.rootBlock = this.sourceBlock.decompose!(
|
||||
this.miniWorkspaceBubble!.getWorkspace()
|
||||
if (!this.sourceBlock.decompose) {
|
||||
throw new Error(
|
||||
'Blocks with mutator icons must include a decompose method',
|
||||
);
|
||||
}
|
||||
this.rootBlock = this.sourceBlock.decompose(
|
||||
this.miniWorkspaceBubble!.getWorkspace(),
|
||||
)!;
|
||||
|
||||
for (const child of this.rootBlock.getDescendants(false)) {
|
||||
@@ -242,7 +247,7 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
this.miniWorkspaceBubble?.getWorkspace()?.getFlyout()?.getWidth() ?? 0;
|
||||
this.rootBlock.moveBy(
|
||||
this.rootBlock.RTL ? -(flyoutWidth + WORKSPACE_MARGIN) : WORKSPACE_MARGIN,
|
||||
WORKSPACE_MARGIN
|
||||
WORKSPACE_MARGIN,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -290,12 +295,17 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
/** Recomposes the source block based on changes to the mini workspace. */
|
||||
private recomposeSourceBlock() {
|
||||
if (!this.rootBlock) return;
|
||||
if (!this.sourceBlock.compose) {
|
||||
throw new Error(
|
||||
'Blocks with mutator icons must include a compose method',
|
||||
);
|
||||
}
|
||||
|
||||
const existingGroup = eventUtils.getGroup();
|
||||
if (!existingGroup) eventUtils.setGroup(true);
|
||||
|
||||
const oldExtraState = BlockChange.getExtraBlockState_(this.sourceBlock);
|
||||
this.sourceBlock.compose!(this.rootBlock);
|
||||
this.sourceBlock.compose(this.rootBlock);
|
||||
const newExtraState = BlockChange.getExtraBlockState_(this.sourceBlock);
|
||||
|
||||
if (oldExtraState !== newExtraState) {
|
||||
@@ -305,8 +315,8 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
'mutation',
|
||||
null,
|
||||
oldExtraState,
|
||||
newExtraState
|
||||
)
|
||||
newExtraState,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -329,13 +339,13 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
static reconnect(
|
||||
connectionChild: Connection | null,
|
||||
block: Block,
|
||||
inputName: string
|
||||
inputName: string,
|
||||
): boolean {
|
||||
deprecation.warn(
|
||||
'MutatorIcon.reconnect',
|
||||
'v10',
|
||||
'v11',
|
||||
'connection.reconnect'
|
||||
'connection.reconnect',
|
||||
);
|
||||
if (!connectionChild) return false;
|
||||
return connectionChild.reconnect(block, inputName);
|
||||
@@ -352,7 +362,7 @@ export class MutatorIcon extends Icon implements IHasBubble {
|
||||
'MutatorIcon.findParentWs',
|
||||
'v10',
|
||||
'v11',
|
||||
'workspace.getRootWorkspace'
|
||||
'workspace.getRootWorkspace',
|
||||
);
|
||||
return workspace.getRootWorkspace();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import {IconType} from './icon_types.js';
|
||||
*/
|
||||
export function register(
|
||||
type: IconType<IIcon>,
|
||||
iconConstructor: new (block: Block) => IIcon
|
||||
iconConstructor: new (block: Block) => IIcon,
|
||||
) {
|
||||
registry.register(registry.Type.ICON, type.toString(), iconConstructor);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ export class WarningIcon extends Icon implements IHasBubble {
|
||||
'class': 'blocklyIconShape',
|
||||
'd': 'M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
// Can't use a real '!' text character since different browsers and
|
||||
// operating systems render it differently. Body of exclamation point.
|
||||
@@ -75,7 +75,7 @@ export class WarningIcon extends Icon implements IHasBubble {
|
||||
'class': 'blocklyIconSymbol',
|
||||
'd': 'm7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
// Dot of exclamation point.
|
||||
dom.createSvgElement(
|
||||
@@ -87,7 +87,7 @@ export class WarningIcon extends Icon implements IHasBubble {
|
||||
'height': '2',
|
||||
'width': '2',
|
||||
},
|
||||
this.svgRoot
|
||||
this.svgRoot,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ export class WarningIcon extends Icon implements IHasBubble {
|
||||
this.getText(),
|
||||
this.sourceBlock.workspace,
|
||||
this.getAnchorLocation(),
|
||||
this.getBubbleOwnerRect()
|
||||
this.getBubbleOwnerRect(),
|
||||
);
|
||||
this.applyColour();
|
||||
} else {
|
||||
@@ -184,8 +184,8 @@ export class WarningIcon extends Icon implements IHasBubble {
|
||||
new (eventUtils.get(eventUtils.BUBBLE_OPEN))(
|
||||
this.sourceBlock,
|
||||
visible,
|
||||
'warning'
|
||||
)
|
||||
'warning',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ export class WarningIcon extends Icon implements IHasBubble {
|
||||
const midIcon = SIZE / 2;
|
||||
return Coordinate.sum(
|
||||
this.workspaceLocation,
|
||||
new Coordinate(midIcon, midIcon)
|
||||
new Coordinate(midIcon, midIcon),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import {WorkspaceSvg} from './workspace_svg.js';
|
||||
*/
|
||||
export function inject(
|
||||
container: Element | string,
|
||||
opt_options?: BlocklyOptions
|
||||
opt_options?: BlocklyOptions,
|
||||
): WorkspaceSvg {
|
||||
let containerElement: Element | null = null;
|
||||
if (typeof container === 'string') {
|
||||
@@ -115,7 +115,7 @@ function createDom(container: Element, options: Options): SVGElement {
|
||||
'class': 'blocklySvg',
|
||||
'tabindex': '0',
|
||||
},
|
||||
container
|
||||
container,
|
||||
);
|
||||
/*
|
||||
<defs>
|
||||
@@ -177,7 +177,7 @@ function createMainWorkspace(svg: SVGElement, options: Options): WorkspaceSvg {
|
||||
mainWorkspace.translate(0, 0);
|
||||
|
||||
mainWorkspace.addChangeListener(
|
||||
bumpObjects.bumpIntoBoundsHandler(mainWorkspace)
|
||||
bumpObjects.bumpIntoBoundsHandler(mainWorkspace),
|
||||
);
|
||||
|
||||
// The SVG is now fully assembled.
|
||||
@@ -206,7 +206,7 @@ function init(mainWorkspace: WorkspaceSvg) {
|
||||
if (!browserEvents.isTargetInput(e)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const workspaceResizeHandler = browserEvents.conditionalBind(
|
||||
@@ -222,7 +222,7 @@ function init(mainWorkspace: WorkspaceSvg) {
|
||||
WidgetDiv.repositionForWindowResize();
|
||||
common.svgResize(mainWorkspace);
|
||||
bumpObjects.bumpTopObjectsIntoBounds(mainWorkspace);
|
||||
}
|
||||
},
|
||||
);
|
||||
mainWorkspace.setResizeHandlerWrapper(workspaceResizeHandler);
|
||||
|
||||
@@ -261,7 +261,7 @@ function init(mainWorkspace: WorkspaceSvg) {
|
||||
mainWorkspace,
|
||||
horizontalScroll,
|
||||
verticalScroll,
|
||||
'blocklyMainWorkspaceScrollbar'
|
||||
'blocklyMainWorkspaceScrollbar',
|
||||
);
|
||||
mainWorkspace.scrollbar.resize();
|
||||
} else {
|
||||
@@ -340,7 +340,7 @@ function bindDocumentEvents() {
|
||||
function () {
|
||||
// TODO (#397): Fix for multiple Blockly workspaces.
|
||||
common.svgResize(common.getMainWorkspace() as WorkspaceSvg);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -361,7 +361,7 @@ function loadSounds(pathToMedia: string, workspace: WorkspaceSvg) {
|
||||
pathToMedia + 'click.wav',
|
||||
pathToMedia + 'click.ogg',
|
||||
],
|
||||
'click'
|
||||
'click',
|
||||
);
|
||||
audioMgr.load(
|
||||
[
|
||||
@@ -369,7 +369,7 @@ function loadSounds(pathToMedia: string, workspace: WorkspaceSvg) {
|
||||
pathToMedia + 'disconnect.mp3',
|
||||
pathToMedia + 'disconnect.ogg',
|
||||
],
|
||||
'disconnect'
|
||||
'disconnect',
|
||||
);
|
||||
audioMgr.load(
|
||||
[
|
||||
@@ -377,7 +377,7 @@ function loadSounds(pathToMedia: string, workspace: WorkspaceSvg) {
|
||||
pathToMedia + 'delete.ogg',
|
||||
pathToMedia + 'delete.wav',
|
||||
],
|
||||
'delete'
|
||||
'delete',
|
||||
);
|
||||
|
||||
// Bind temporary hooks that preload the sounds.
|
||||
@@ -407,8 +407,8 @@ function loadSounds(pathToMedia: string, workspace: WorkspaceSvg) {
|
||||
'pointermove',
|
||||
null,
|
||||
unbindSounds,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
soundBinds.push(
|
||||
browserEvents.conditionalBind(
|
||||
@@ -416,7 +416,7 @@ function loadSounds(pathToMedia: string, workspace: WorkspaceSvg) {
|
||||
'touchstart',
|
||||
null,
|
||||
unbindSounds,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@ export class DummyInput extends Input {
|
||||
* again.
|
||||
* @param block The block containing this input.
|
||||
*/
|
||||
constructor(public name: string, block: Block) {
|
||||
constructor(
|
||||
public name: string,
|
||||
block: Block,
|
||||
) {
|
||||
super(name, block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,10 @@ export class Input {
|
||||
* again.
|
||||
* @param sourceBlock The block containing this input.
|
||||
*/
|
||||
constructor(public name: string, private sourceBlock: Block) {}
|
||||
constructor(
|
||||
public name: string,
|
||||
private sourceBlock: Block,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get the source block for this input.
|
||||
@@ -80,7 +83,7 @@ export class Input {
|
||||
insertFieldAt<T>(
|
||||
index: number,
|
||||
field: string | Field<T>,
|
||||
opt_name?: string
|
||||
opt_name?: string,
|
||||
): number {
|
||||
if (index < 0 || index > this.fieldRow.length) {
|
||||
throw Error('index ' + index + ' out of bounds.');
|
||||
|
||||
@@ -21,7 +21,10 @@ export class StatementInput extends Input {
|
||||
* again.
|
||||
* @param block The block containing this input.
|
||||
*/
|
||||
constructor(public name: string, block: Block) {
|
||||
constructor(
|
||||
public name: string,
|
||||
block: Block,
|
||||
) {
|
||||
// Errors are maintained for people not using typescript.
|
||||
if (!name) throw new Error('Statement inputs must have a non-empty name');
|
||||
|
||||
|
||||
@@ -18,7 +18,10 @@ export class ValueInput extends Input {
|
||||
* again.
|
||||
* @param block The block containing this input.
|
||||
*/
|
||||
constructor(public name: string, block: Block) {
|
||||
constructor(
|
||||
public name: string,
|
||||
block: Block,
|
||||
) {
|
||||
// Errors are maintained for people not using typescript.
|
||||
if (!name) throw new Error('Value inputs must have a non-empty name');
|
||||
super(name, block);
|
||||
|
||||
@@ -18,13 +18,14 @@ import type {BlockSvg} from './block_svg.js';
|
||||
import * as common from './common.js';
|
||||
import {ComponentManager} from './component_manager.js';
|
||||
import {config} from './config.js';
|
||||
import * as constants from './constants.js';
|
||||
import * as eventUtils from './events/utils.js';
|
||||
import type {IDeleteArea} from './interfaces/i_delete_area.js';
|
||||
import type {IDragTarget} from './interfaces/i_drag_target.js';
|
||||
import type {RenderedConnection} from './rendered_connection.js';
|
||||
import * as blocks from './serialization/blocks.js';
|
||||
import type {Coordinate} from './utils/coordinate.js';
|
||||
import type {WorkspaceSvg} from './workspace_svg.js';
|
||||
import * as renderManagement from './render_management.js';
|
||||
|
||||
/** Represents a nearby valid connection. */
|
||||
interface CandidateConnection {
|
||||
@@ -42,16 +43,6 @@ interface CandidateConnection {
|
||||
radius: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* An error message to throw if the block created by createMarkerBlock_ is
|
||||
* missing any components.
|
||||
*/
|
||||
const DUPLICATE_BLOCK_ERROR =
|
||||
'The insertion marker ' +
|
||||
'manager tried to create a marker but the result is missing %1. If ' +
|
||||
'you are using a mutator, make sure your domToMutation method is ' +
|
||||
'properly defined.';
|
||||
|
||||
/**
|
||||
* Class that controls updates to connections during drags. It is primarily
|
||||
* responsible for finding the closest eligible connection and highlighting or
|
||||
@@ -136,7 +127,7 @@ export class InsertionMarkerManager {
|
||||
|
||||
if (this.lastOnStack) {
|
||||
this.lastMarker = this.createMarkerBlock(
|
||||
this.lastOnStack.getSourceBlock()
|
||||
this.lastOnStack.getSourceBlock(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -231,48 +222,16 @@ export class InsertionMarkerManager {
|
||||
* @returns The insertion marker that represents the given block.
|
||||
*/
|
||||
private createMarkerBlock(sourceBlock: BlockSvg): BlockSvg {
|
||||
const imType = sourceBlock.type;
|
||||
|
||||
eventUtils.disable();
|
||||
let result: BlockSvg;
|
||||
try {
|
||||
result = this.workspace.newBlock(imType);
|
||||
result.setInsertionMarker(true);
|
||||
if (sourceBlock.saveExtraState) {
|
||||
const state = sourceBlock.saveExtraState();
|
||||
if (state && result.loadExtraState) {
|
||||
result.loadExtraState(state);
|
||||
}
|
||||
} else if (sourceBlock.mutationToDom) {
|
||||
const oldMutationDom = sourceBlock.mutationToDom();
|
||||
if (oldMutationDom && result.domToMutation) {
|
||||
result.domToMutation(oldMutationDom);
|
||||
}
|
||||
}
|
||||
// Copy field values from the other block. These values may impact the
|
||||
// rendered size of the insertion marker. Note that we do not care about
|
||||
// child blocks here.
|
||||
for (let i = 0; i < sourceBlock.inputList.length; i++) {
|
||||
const sourceInput = sourceBlock.inputList[i];
|
||||
if (sourceInput.name === constants.COLLAPSED_INPUT_NAME) {
|
||||
continue; // Ignore the collapsed input.
|
||||
}
|
||||
const resultInput = result.inputList[i];
|
||||
if (!resultInput) {
|
||||
throw new Error(DUPLICATE_BLOCK_ERROR.replace('%1', 'an input'));
|
||||
}
|
||||
for (let j = 0; j < sourceInput.fieldRow.length; j++) {
|
||||
const sourceField = sourceInput.fieldRow[j];
|
||||
const resultField = resultInput.fieldRow[j];
|
||||
if (!resultField) {
|
||||
throw new Error(DUPLICATE_BLOCK_ERROR.replace('%1', 'a field'));
|
||||
}
|
||||
resultField.setValue(sourceField.getValue());
|
||||
}
|
||||
const blockJson = blocks.save(sourceBlock);
|
||||
if (!blockJson) {
|
||||
throw new Error('Failed to serialize source block.');
|
||||
}
|
||||
result = blocks.append(blockJson, this.workspace) as BlockSvg;
|
||||
|
||||
result.setCollapsed(sourceBlock.isCollapsed());
|
||||
result.setInputsInline(sourceBlock.getInputsInline());
|
||||
result.setInsertionMarker(true);
|
||||
|
||||
result.initSvg();
|
||||
result.getSvgRoot().setAttribute('visibility', 'hidden');
|
||||
@@ -311,7 +270,7 @@ export class InsertionMarkerManager {
|
||||
*/
|
||||
private shouldUpdatePreviews(
|
||||
newCandidate: CandidateConnection | null,
|
||||
dxy: Coordinate
|
||||
dxy: Coordinate,
|
||||
): boolean {
|
||||
// Only need to update if we were showing a preview before.
|
||||
if (!newCandidate) return !!this.activeCandidate;
|
||||
@@ -404,18 +363,18 @@ export class InsertionMarkerManager {
|
||||
*/
|
||||
private shouldDelete(
|
||||
newCandidate: boolean,
|
||||
dragTarget: IDragTarget | null
|
||||
dragTarget: IDragTarget | null,
|
||||
): boolean {
|
||||
if (dragTarget) {
|
||||
const componentManager = this.workspace.getComponentManager();
|
||||
const isDeleteArea = componentManager.hasCapability(
|
||||
dragTarget.id,
|
||||
ComponentManager.Capability.DELETE_AREA
|
||||
ComponentManager.Capability.DELETE_AREA,
|
||||
);
|
||||
if (isDeleteArea) {
|
||||
return (dragTarget as IDeleteArea).wouldDelete(
|
||||
this.topBlock,
|
||||
newCandidate
|
||||
newCandidate,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -462,7 +421,7 @@ export class InsertionMarkerManager {
|
||||
const method = renderer.getConnectionPreviewMethod(
|
||||
activeCandidate.closest,
|
||||
activeCandidate.local,
|
||||
this.topBlock
|
||||
this.topBlock,
|
||||
);
|
||||
|
||||
switch (method) {
|
||||
@@ -552,14 +511,14 @@ export class InsertionMarkerManager {
|
||||
if (!insertionMarker) {
|
||||
throw new Error(
|
||||
'Cannot show the insertion marker because there is no insertion ' +
|
||||
'marker block'
|
||||
'marker block',
|
||||
);
|
||||
}
|
||||
let imConn;
|
||||
try {
|
||||
imConn = insertionMarker.getMatchingConnection(
|
||||
local.getSourceBlock(),
|
||||
local
|
||||
local,
|
||||
);
|
||||
} catch (e) {
|
||||
// It's possible that the number of connections on the local block has
|
||||
@@ -571,7 +530,7 @@ export class InsertionMarkerManager {
|
||||
if (isLastInStack && this.lastOnStack) {
|
||||
this.disposeInsertionMarker(this.lastMarker);
|
||||
this.lastMarker = this.createMarkerBlock(
|
||||
this.lastOnStack.getSourceBlock()
|
||||
this.lastOnStack.getSourceBlock(),
|
||||
);
|
||||
insertionMarker = this.lastMarker;
|
||||
} else {
|
||||
@@ -583,43 +542,42 @@ export class InsertionMarkerManager {
|
||||
if (!insertionMarker) {
|
||||
throw new Error(
|
||||
'Cannot show the insertion marker because there is no insertion ' +
|
||||
'marker block'
|
||||
'marker block',
|
||||
);
|
||||
}
|
||||
imConn = insertionMarker.getMatchingConnection(
|
||||
local.getSourceBlock(),
|
||||
local
|
||||
local,
|
||||
);
|
||||
}
|
||||
|
||||
if (!imConn) {
|
||||
throw new Error(
|
||||
'Cannot show the insertion marker because there is no ' +
|
||||
'associated connection'
|
||||
'associated connection',
|
||||
);
|
||||
}
|
||||
|
||||
if (imConn === this.markerConnection) {
|
||||
throw new Error(
|
||||
"Made it to showInsertionMarker_ even though the marker isn't " +
|
||||
'changing'
|
||||
'changing',
|
||||
);
|
||||
}
|
||||
|
||||
// Render disconnected from everything else so that we have a valid
|
||||
// connection location.
|
||||
insertionMarker.render();
|
||||
insertionMarker.rendered = true;
|
||||
insertionMarker.getSvgRoot().setAttribute('visibility', 'visible');
|
||||
insertionMarker.queueRender();
|
||||
renderManagement.triggerQueuedRenders();
|
||||
|
||||
if (imConn && closest) {
|
||||
// Position so that the existing block doesn't move.
|
||||
insertionMarker.positionNearConnection(imConn, closest);
|
||||
}
|
||||
if (closest) {
|
||||
// Connect() also renders the insertion marker.
|
||||
imConn.connect(closest);
|
||||
}
|
||||
// Position so that the existing block doesn't move.
|
||||
insertionMarker.positionNearConnection(imConn, closest);
|
||||
// Connect() also renders the insertion marker.
|
||||
imConn.connect(closest);
|
||||
|
||||
renderManagement.finishQueuedRenders().then(() => {
|
||||
insertionMarker?.getSvgRoot().setAttribute('visibility', 'visible');
|
||||
});
|
||||
|
||||
this.markerConnection = imConn;
|
||||
}
|
||||
@@ -648,7 +606,7 @@ export class InsertionMarkerManager {
|
||||
if (markerConn.targetConnection) {
|
||||
throw Error(
|
||||
'markerConnection still connected at the end of ' +
|
||||
'disconnectInsertionMarker'
|
||||
'disconnectInsertionMarker',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -678,12 +636,12 @@ export class InsertionMarkerManager {
|
||||
if (!this.activeCandidate) {
|
||||
throw new Error(
|
||||
'Cannot hide the insertion marker outline because ' +
|
||||
'there is no active candidate'
|
||||
'there is no active candidate',
|
||||
);
|
||||
}
|
||||
this.highlightedBlock.highlightShapeForInput(
|
||||
this.activeCandidate.closest,
|
||||
false
|
||||
false,
|
||||
);
|
||||
this.highlightedBlock = null;
|
||||
}
|
||||
@@ -700,7 +658,7 @@ export class InsertionMarkerManager {
|
||||
if (!this.fadedBlock) {
|
||||
throw new Error(
|
||||
'Cannot show the replacement fade because the ' +
|
||||
'closest connection does not have a target block'
|
||||
'closest connection does not have a target block',
|
||||
);
|
||||
}
|
||||
this.fadedBlock.fadeForReplacement(true);
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface IConnectionChecker {
|
||||
a: Connection | null,
|
||||
b: Connection | null,
|
||||
isDragging: boolean,
|
||||
opt_distance?: number
|
||||
opt_distance?: number,
|
||||
): boolean;
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ export interface IConnectionChecker {
|
||||
a: Connection | null,
|
||||
b: Connection | null,
|
||||
isDragging: boolean,
|
||||
opt_distance?: number
|
||||
opt_distance?: number,
|
||||
): number;
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ export interface IConnectionChecker {
|
||||
getErrorMessage(
|
||||
errorCode: number,
|
||||
a: Connection | null,
|
||||
b: Connection | null
|
||||
b: Connection | null,
|
||||
): string;
|
||||
|
||||
/**
|
||||
@@ -96,6 +96,6 @@ export interface IConnectionChecker {
|
||||
doDragChecks(
|
||||
a: RenderedConnection,
|
||||
b: RenderedConnection,
|
||||
distance: number
|
||||
distance: number,
|
||||
): boolean;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export interface IFlyout extends IRegistrable {
|
||||
* @returns The flyout's SVG group.
|
||||
*/
|
||||
createDom(
|
||||
tagName: string | Svg<SVGSVGElement> | Svg<SVGGElement>
|
||||
tagName: string | Svg<SVGSVGElement> | Svg<SVGGElement>,
|
||||
): SVGElement;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface LegacyProcedureDefBlock {
|
||||
|
||||
/** @internal */
|
||||
export function isLegacyProcedureDefBlock(
|
||||
block: Object
|
||||
block: Object,
|
||||
): block is LegacyProcedureDefBlock {
|
||||
return (block as any).getProcedureDef !== undefined;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export interface LegacyProcedureCallBlock {
|
||||
|
||||
/** @internal */
|
||||
export function isLegacyProcedureCallBlock(
|
||||
block: Object
|
||||
block: Object,
|
||||
): block is LegacyProcedureCallBlock {
|
||||
return (
|
||||
(block as any).getProcedureCall !== undefined &&
|
||||
|
||||
@@ -43,7 +43,7 @@ export interface IMetricsManager {
|
||||
getScrollMetrics(
|
||||
opt_getWorkspaceCoordinates?: boolean,
|
||||
opt_viewMetrics?: ContainerRegion,
|
||||
opt_contentMetrics?: ContainerRegion
|
||||
opt_contentMetrics?: ContainerRegion,
|
||||
): ContainerRegion;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface IProcedureBlock {
|
||||
|
||||
/** A type guard which checks if the given block is a procedure block. */
|
||||
export function isProcedureBlock(
|
||||
block: Block | IProcedureBlock
|
||||
block: Block | IProcedureBlock,
|
||||
): block is IProcedureBlock {
|
||||
return (
|
||||
(block as IProcedureBlock).getProcedureModel !== undefined &&
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user