'use strict'; goog.provide('Blockly.JavaScript.Timeouts'); goog.require('Blockly.JavaScript'); Blockly.CustomBlocks = Blockly.CustomBlocks || []; Blockly.CustomBlocks.push('Timeouts'); Blockly.Timeouts = { HUE: 70, blocks: {} }; /** * Ensure two identically-named procedures don't exist. * @param {string} name Proposed procedure name. * @param {!Blockly.Block} block Block to disambiguate. * @return {string} Non-colliding name. */ Blockly.Timeouts.findLegalName = function(name, block) { if (block.isInFlyout) { // Flyouts can have multiple procedures called 'do something'. return name; } while (!Blockly.Timeouts.isLegalName_(name, block.workspace, block)) { // Collision with another procedure. var r = name.match(/^(.*?)(\d+)$/); if (!r) { name += '2'; } else { name = r[1] + (parseInt(r[2], 10) + 1); } } return name; }; /** * Does this procedure have a legal name? Illegal names include names of * procedures already defined. * @param {string} name The questionable name. * @param {!Blockly.Workspace} workspace The workspace to scan for collisions. * @param {Blockly.Block=} opt_exclude Optional block to exclude from * comparisons (one doesn't want to collide with oneself). * @return {boolean} True if the name is legal. * @private */ Blockly.Timeouts.isLegalName_ = function(name, workspace, opt_exclude) { var blocks = workspace.getAllBlocks(); // Iterate through every block and check the name. for (var i = 0; i < blocks.length; i++) { if (blocks[i] == opt_exclude) { continue; } if (blocks[i].isTimeout_ || blocks[i].isInterval_) { var blockName = blocks[i].getFieldValue('NAME'); if (Blockly.Names.equals(blockName, name)) { return false; } } } return true; }; /** * Rename a procedure. Called by the editable field. * @param {string} name The proposed new name. * @return {string} The accepted name. * @this {!Blockly.Field} */ Blockly.Timeouts.rename = function (name) { // Strip leading and trailing whitespace. Beyond this, all names are legal. name = name.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); return Blockly.Timeouts.findLegalName(name, this.sourceBlock_); }; // --- setTimeout ----------------------------------------------------------- Blockly.Timeouts.blocks['timeouts_settimeout'] = '' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ''; Blockly.Blocks['timeouts_settimeout'] = { init: function() { var nameField = new Blockly.FieldTextInput( Blockly.Timeouts.findLegalName('timeout', this), Blockly.Timeouts.rename); nameField.setSpellcheck(false); this.appendDummyInput() .appendField(Blockly.Words['timeouts_settimeout'][systemLang]) .appendField(nameField, 'NAME') .appendField(Blockly.Words['timeouts_settimeout_in'][systemLang]) .appendField(new Blockly.FieldTextInput(1000), "DELAY") .appendField(new Blockly.FieldDropdown([ [Blockly.Words['timeouts_settimeout_ms'][systemLang], 'ms'], [Blockly.Words['timeouts_settimeout_sec'][systemLang], 'sec'], [Blockly.Words['timeouts_settimeout_min'][systemLang], 'min'] ]), 'UNIT') .appendField(Blockly.Words['timeouts_settimeout_ms'][systemLang]); this.appendStatementInput("STATEMENT") .setCheck(null); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setInputsInline(false); this.setColour(Blockly.Timeouts.HUE); this.setTooltip(Blockly.Words['timeouts_settimeout_tooltip'][systemLang]); this.setHelpUrl(getHelp('timeouts_settimeout_help')); }, isTimeout_: true, getVars: function () { return [this.getFieldValue('NAME')]; } }; Blockly.JavaScript['timeouts_settimeout'] = function(block) { var delay = block.getFieldValue('DELAY'); var name = block.getFieldValue('NAME'); var unit = block.getFieldValue('UNIT'); if (unit === 'min') { delay *= 60000; } else if (unit === 'sec') { delay *= 1000; } var statements_name = Blockly.JavaScript.statementToCode(block, 'STATEMENT'); return name + ' = setTimeout(function () {\n' + statements_name + '}, ' + delay + ');\n'; }; // --- clearTimeout ----------------------------------------------------------- Blockly.Timeouts.getAllTimeouts = function (workspace) { var blocks = workspace.getAllBlocks(); var result = []; // Iterate through every block and check the name. for (var i = 0; i < blocks.length; i++) { if (blocks[i].isTimeout_) { result.push([blocks[i].getFieldValue('NAME'), blocks[i].getFieldValue('NAME')]); } } if (!result.length) result.push(['', '']); return result; }; Blockly.Timeouts.blocks['timeouts_cleartimeout'] = '' + ' ' + ' ' + ''; Blockly.Blocks['timeouts_cleartimeout'] = { init: function() { this.appendDummyInput('NAME') .appendField(Blockly.Words['timeouts_cleartimeout'][systemLang]) .appendField(new Blockly.FieldDropdown(function () { return Blockly.Timeouts.getAllTimeouts(scripts.blocklyWorkspace); }), 'NAME'); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setInputsInline(true); this.setColour(Blockly.Timeouts.HUE); this.setTooltip(Blockly.Words['timeouts_cleartimeout_tooltip'][systemLang]); this.setHelpUrl(getHelp('timeouts_cleartimeout_help')); } }; Blockly.JavaScript['timeouts_cleartimeout'] = function(block) { var name = block.getFieldValue('NAME'); return '(function () {if (' + name + ') {clearTimeout(' + name + '); ' + name + ' = null;}})();\n'; }; // --- setInterval ----------------------------------------------------------- Blockly.Timeouts.blocks['timeouts_setinterval'] = '' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ''; Blockly.Blocks['timeouts_setinterval'] = { init: function() { var nameField = new Blockly.FieldTextInput( Blockly.Timeouts.findLegalName(Blockly.Words['timeouts_setinterval_name'][systemLang], this), Blockly.Timeouts.rename); nameField.setSpellcheck(false); this.appendDummyInput() .appendField(Blockly.Words['timeouts_setinterval'][systemLang]) .appendField(nameField, 'NAME') .appendField(Blockly.Words['timeouts_setinterval_in'][systemLang]) .appendField(new Blockly.FieldTextInput(1000), "INTERVAL") .appendField(new Blockly.FieldDropdown([ [Blockly.Words['timeouts_settimeout_ms'][systemLang], 'ms'], [Blockly.Words['timeouts_settimeout_sec'][systemLang], 'sec'], [Blockly.Words['timeouts_settimeout_min'][systemLang], 'min'] ]), 'UNIT') .appendField(Blockly.Words['timeouts_setinterval_ms'][systemLang]); this.appendStatementInput("STATEMENT") .setCheck(null); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setInputsInline(false); this.setColour(Blockly.Timeouts.HUE); this.setTooltip(Blockly.Words['timeouts_setinterval_tooltip'][systemLang]); this.setHelpUrl(getHelp('timeouts_setinterval_help')); }, isInterval_: true, getVars: function () { return [this.getFieldValue('NAME')]; } }; Blockly.JavaScript['timeouts_setinterval'] = function(block) { var delay = block.getFieldValue('INTERVAL'); var name = block.getFieldValue('NAME'); var unit = block.getFieldValue('UNIT'); if (unit === 'min') { delay *= 60000; } else if (unit === 'sec') { delay *= 1000; } var statements_name = Blockly.JavaScript.statementToCode(block, 'STATEMENT'); return name + ' = setInterval(function () {\n' + statements_name + '}, ' + delay + ');\n'; }; // --- clearInterval ----------------------------------------------------------- Blockly.Timeouts.blocks['timeouts_clearinterval'] = '' + ' ' + ' ' + ''; Blockly.Timeouts.getAllIntervals = function (workspace) { var blocks = workspace.getAllBlocks(); var result = []; // Iterate through every block and check the name. for (var i = 0; i < blocks.length; i++) { if (blocks[i].isInterval_) { result.push([blocks[i].getFieldValue('NAME'), blocks[i].getFieldValue('NAME')]); } } if (!result.length) result.push(['', '']); return result; }; Blockly.Blocks['timeouts_clearinterval'] = { init: function() { this.appendDummyInput("NAME") .appendField(Blockly.Words['timeouts_clearinterval'][systemLang]) .appendField(new Blockly.FieldDropdown(function () { return Blockly.Timeouts.getAllIntervals(scripts.blocklyWorkspace); }), "NAME"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setInputsInline(true); this.setColour(Blockly.Timeouts.HUE); this.setTooltip(Blockly.Words['timeouts_clearinterval_tooltip'][systemLang]); this.setHelpUrl(getHelp('timeouts_clearinterval_help')); } }; Blockly.JavaScript['timeouts_clearinterval'] = function(block) { var name = block.getFieldValue('NAME'); return '(function () {if (' + name + ') {clearInterval(' + name + '); ' + name + ' = null;}})();\n'; };