zoukankan      html  css  js  c++  java
  • 1.Google Blockly概述以及入门

    一.什么是Blockly

    (1)概述:

    • Blockly是一种可视化编程工具,是众多可视化编程工具的鼻祖。
    • 2012年6月,Google发布的完全可视化的编程语言Goole Blockly。
    • Blockly代码块由类似于积木的图形对象构成,只需要拖拖拽拽就可以实现程序的功能。

    (2)详述:

    • 一种基于网页的可视化是程序:
      • Google Blockly是基于网页的可视化编程库,用户可以离线或者在线进行编程操作。
    • 多种开发语言环境库:
      • Blockly代码块可以通过自带的语言转换工具箱转换成JavaScript、Python、PHP、Lua、Dart等多种语言。
    • 开源的自定义编程环境:
      • 用户可以自己定义Blockly代码块放入Blockly的工具箱中,用于以后使用。

    (3)Blockly的使用流程图:

    • 我们可以使用Blockly的工具箱编写Blockly代码块实现程序功能,然后使用语言转换器转换为需要的语言。
    • 我们也可以自定义Blockly代码块生成工具放入工具箱和语言转换器中,用于以后使用。

    二.Blockly的编程环境

    (1)Blockly有在线和离线版本

    • 在线版本网址: https://developers.google.cn/blockly
    • 离线版本下载网址:https://github.com/google/blockly
      • 下载后在demos目录下,使用浏览器打开index.html即可。

    (2)Blockly在线版本

    (3)Blockly离线版本

    • 离线Blockly的一些demo例子:

      •  Fixed Blockly :固定大小的Blockly块的工作空间,不会随浏览器大小变化而变化。
      •  Resizable Blockly :可变大小的Blockly块的工作空间,会随浏览器大小变化而变化。
      •  Defining the Toolbox :Blockly自定义的工具箱
      •  Maximum Block Limit :限制Blockly块的个数,不能超过指定Blockly个数。
      •  Generate JavaScript :生成JavaScript代码
      •  Headless :将xml代码生成其他的语言的代码
      •  JS Interpreter :展示使用Blockly代码块生成JavaScript代码并可以单步执行
      •  Graph :通过数学公式在坐标系中生成图形
      •  RTL :从右到左显示Blockly块(对于阿拉伯语和希伯来语使用)
      •  Custom Dialogs :自定义实现覆盖浏览器对话框
      •  Custom Fields :自定义字段
      •    Cloud Storage :云存储在App Engine
      •   Mirrored Blockly  :展示两个同步的Blockly工作区,左侧主工作区变化,右侧从工作区也发生变化。
      •  Accessible Blockly : 屏幕阅读无障碍访问版本
      •  Plane :支持35种语言
      •  Code Editor :将Blocky程序导出成JavaScript,Python,PHP,Lua,Dart或XML
      •  Blockly Developer Tools :使用Blockly构建自定义的代码块并设置到工作箱。

    三.Blockly的功能模块

    工具箱中有8个主要模块: blockly-master>demos>code>index.html 中可以查看源码

    运行index.html结果:(右上角可以修改语言类型为简体中文)

    主要为大家讲解三个文件 blockly_compressed.js , blocks_compressed.js , javascript_compressed.js 

    (1)  blocks_compressed.js :定义了Blockly工具箱中的所有可用Blockly块,仅仅是Blockly.Blocks的内容。

    以下:讲解loops(循环)模块程序代码

    • 其中 Blockly.defineBlocksWithJsonArray([{...},{...},{...},...]) :用于定义某一个工具,例如循环工具所有Blockly块。
    • 每一个 {...} 都包含一个循环模块的Blockly块:6个循环模块
      • controls_repeat_ext
      • controls_repeat
      • controls_whileUntil
      • controls_for
      • controls_forEach
      • controls_flow_statements
      1 Blockly.Blocks.loops = {};
      2 Blockly.Constants.Loops = {};
      3 Blockly.Constants.Loops.HUE = 120;
      4 Blockly.defineBlocksWithJsonArray([{
      5     type: "controls_repeat_ext",
      6     message0: "%{BKY_CONTROLS_REPEAT_TITLE}",
      7     args0: [{
      8         type: "input_value",
      9         name: "TIMES",
     10         check: "Number"
     11     }],
     12     message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
     13     args1: [{
     14         type: "input_statement",
     15         name: "DO"
     16     }],
     17     previousStatement: null,
     18     nextStatement: null,
     19     style: "loop_blocks",
     20     tooltip: "%{BKY_CONTROLS_REPEAT_TOOLTIP}",
     21     helpUrl: "%{BKY_CONTROLS_REPEAT_HELPURL}"
     22 }, {
     23     type: "controls_repeat",
     24     message0: "%{BKY_CONTROLS_REPEAT_TITLE}",
     25     args0: [{
     26         type: "field_number",
     27         name: "TIMES",
     28         value: 10,
     29         min: 0,
     30         precision: 1
     31     }],
     32     message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
     33     args1: [{
     34         type: "input_statement",
     35         name: "DO"
     36     }],
     37     previousStatement: null,
     38     nextStatement: null,
     39     style: "loop_blocks",
     40     tooltip: "%{BKY_CONTROLS_REPEAT_TOOLTIP}",
     41     helpUrl: "%{BKY_CONTROLS_REPEAT_HELPURL}"
     42 }, {
     43     type: "controls_whileUntil",
     44     message0: "%1 %2",
     45     args0: [{
     46         type: "field_dropdown",
     47         name: "MODE",
     48         options: [
     49             ["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}", "WHILE"],
     50             ["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}", "UNTIL"]
     51         ]
     52     }, {
     53         type: "input_value",
     54         name: "BOOL",
     55         check: "Boolean"
     56     }],
     57     message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
     58     args1: [{
     59         type: "input_statement",
     60         name: "DO"
     61     }],
     62     previousStatement: null,
     63     nextStatement: null,
     64     style: "loop_blocks",
     65     helpUrl: "%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",
     66     extensions: ["controls_whileUntil_tooltip"]
     67 }, {
     68     type: "controls_for",
     69     message0: "%{BKY_CONTROLS_FOR_TITLE}",
     70     args0: [{
     71         type: "field_variable",
     72         name: "VAR",
     73         variable: null
     74     }, {
     75         type: "input_value",
     76         name: "FROM",
     77         check: "Number",
     78         align: "RIGHT"
     79     }, {
     80         type: "input_value",
     81         name: "TO",
     82         check: "Number",
     83         align: "RIGHT"
     84     }, {
     85         type: "input_value",
     86         name: "BY",
     87         check: "Number",
     88         align: "RIGHT"
     89     }],
     90     message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
     91     args1: [{
     92         type: "input_statement",
     93         name: "DO"
     94     }],
     95     inputsInline: !0,
     96     previousStatement: null,
     97     nextStatement: null,
     98     style: "loop_blocks",
     99     helpUrl: "%{BKY_CONTROLS_FOR_HELPURL}",
    100     extensions: ["contextMenu_newGetVariableBlock", "controls_for_tooltip"]
    101 }, {
    102     type: "controls_forEach",
    103     message0: "%{BKY_CONTROLS_FOREACH_TITLE}",
    104     args0: [{
    105         type: "field_variable",
    106         name: "VAR",
    107         variable: null
    108     }, {
    109         type: "input_value",
    110         name: "LIST",
    111         check: "Array"
    112     }],
    113     message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
    114     args1: [{
    115         type: "input_statement",
    116         name: "DO"
    117     }],
    118     previousStatement: null,
    119     nextStatement: null,
    120     style: "loop_blocks",
    121     helpUrl: "%{BKY_CONTROLS_FOREACH_HELPURL}",
    122     extensions: ["contextMenu_newGetVariableBlock", "controls_forEach_tooltip"]
    123 }, {
    124     type: "controls_flow_statements",
    125     message0: "%1",
    126     args0: [{
    127         type: "field_dropdown",
    128         name: "FLOW",
    129         options: [
    130             ["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}", "BREAK"],
    131             ["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}", "CONTINUE"]
    132         ]
    133     }],
    134     previousStatement: null,
    135     style: "loop_blocks",
    136     helpUrl: "%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",
    137     extensions: ["controls_flow_tooltip", "controls_flow_in_loop_check"]
    138 }]);
    139 Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS = {
    140     WHILE: "%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",
    141     UNTIL: "%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"
    142 };
    143 Blockly.Extensions.register("controls_whileUntil_tooltip", Blockly.Extensions.buildTooltipForDropdown("MODE", Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
    144 Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS = {
    145     BREAK: "%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",
    146     CONTINUE: "%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"
    147 };
    148 Blockly.Extensions.register("controls_flow_tooltip", Blockly.Extensions.buildTooltipForDropdown("FLOW", Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
    149 Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
    150     customContextMenu: function (a) {
    151         if (!this.isInFlyout) {
    152             var b = this.getField("VAR").getVariable(),
    153                 c = b.name;
    154             if (!this.isCollapsed() && null != c) {
    155                 var d = {
    156                     enabled: !0
    157                 };
    158                 d.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1", c);
    159                 b = Blockly.Variables.generateVariableFieldDom(b);
    160                 c = Blockly.utils.xml.createElement("block");
    161                 c.setAttribute("type", "variables_get");
    162                 c.appendChild(b);
    163                 d.callback = Blockly.ContextMenu.callbackFactory(this, c);
    164                 a.push(d)
    165             }
    166         }
    167     }
    168 };
    169 Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock", Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);
    170 Blockly.Extensions.register("controls_for_tooltip", Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOR_TOOLTIP}", "VAR"));
    171 Blockly.Extensions.register("controls_forEach_tooltip", Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOREACH_TOOLTIP}", "VAR"));
    172 Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
    173     LOOP_TYPES: ["controls_repeat", "controls_repeat_ext", "controls_forEach", "controls_for", "controls_whileUntil"],
    174     suppressPrefixSuffix: !0,
    175     getSurroundLoop: function (a) {
    176         do {
    177             if (-1 != Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf(a.type)) return a;
    178             a = a.getSurroundParent()
    179         } while (a);
    180         return null
    181     },
    182     onchange: function (a) {
    183         this.workspace.isDragging && !this.workspace.isDragging() && (Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this) ?
    184             (this.setWarningText(null), this.isInFlyout || this.setEnabled(!0)) : (this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING), this.isInFlyout || this.getInheritedDisabled() || this.setEnabled(!1)))
    185     }
    186 };
    187 Blockly.Extensions.registerMixin("controls_flow_in_loop_check", Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);
    View Code

    抽取定义的一段代码: controls_for 循环功能模块

    分析:一个message对应一个args,args中是一个数组里面嵌套多个对象,一个对象中主要有type表示类型,name表示名称。

     1 {
     2     type: "controls_for",
     3     message0: "%{BKY_CONTROLS_FOR_TITLE}",
     4     args0: [{
     5         type: "field_variable",
     6         name: "VAR",
     7         variable: null
     8     }, {
     9         type: "input_value",
    10         name: "FROM",
    11         check: "Number",
    12         align: "RIGHT"
    13     }, {
    14         type: "input_value",
    15         name: "TO",
    16         check: "Number",
    17         align: "RIGHT"
    18     }, {
    19         type: "input_value",
    20         name: "BY",
    21         check: "Number",
    22         align: "RIGHT"
    23     }],
    24     message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
    25     args1: [{
    26         type: "input_statement",
    27         name: "DO"
    28     }],
    29     inputsInline: !0,
    30     previousStatement: null,
    31     nextStatement: null,
    32     style: "loop_blocks",
    33     helpUrl: "%{BKY_CONTROLS_FOR_HELPURL}",
    34     extensions: ["contextMenu_newGetVariableBlock", "controls_for_tooltip"]
    35 }

    在html中的代码:

    我们根据值以及类型进行赋值

     1 <block type="controls_for">
     2     <field name="VAR">i</field>
     3     <value name="FROM">
     4         <block type="math_number">
     5             <field name="NUM">1</field>
     6         </block>
     7     </value>
     8     <value name="TO">
     9         <block type="math_number">
    10             <field name="NUM">10</field>
    11         </block>
    12     </value>
    13     <value name="BY">
    14         <block type="math_number">
    15             <field name="NUM">1</field>
    16         </block>
    17     </value>
    18 </block>

    显示的样式:

     

    (2) javascript_compressed.js :主要是将定义好的Blocks的工具箱创建出来的程序解析成JavaScript代码。

    以下截取一小段:主要将Blocks的list解析为JavaScript的Array。

      1 Blockly.JavaScript.lists = {};
      2 Blockly.JavaScript.lists_create_empty = function (a) {
      3     return ["[]", Blockly.JavaScript.ORDER_ATOMIC]
      4 };
      5 Blockly.JavaScript.lists_create_with = function (a) {
      6     for (var b = Array(a.itemCount_), c = 0; c < a.itemCount_; c++) b[c] = Blockly.JavaScript.valueToCode(a, "ADD" + c, Blockly.JavaScript.ORDER_COMMA) || "null";
      7     return ["[" + b.join(", ") + "]", Blockly.JavaScript.ORDER_ATOMIC]
      8 };
      9 Blockly.JavaScript.lists_repeat = function (a) {
     10     var b = Blockly.JavaScript.provideFunction_("listsRepeat", ["function " + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + "(value, n) {", "  var array = [];", "  for (var i = 0; i < n; i++) {", "    array[i] = value;", "  }", "  return array;", "}"]),
     11         c = Blockly.JavaScript.valueToCode(a, "ITEM", Blockly.JavaScript.ORDER_COMMA) || "null";
     12     a = Blockly.JavaScript.valueToCode(a, "NUM", Blockly.JavaScript.ORDER_COMMA) || "0";
     13     return [b + "(" + c + ", " + a + ")", Blockly.JavaScript.ORDER_FUNCTION_CALL]
     14 };
     15 Blockly.JavaScript.lists_length = function (a) {
     16     return [(Blockly.JavaScript.valueToCode(a, "VALUE", Blockly.JavaScript.ORDER_MEMBER) || "[]") + ".length", Blockly.JavaScript.ORDER_MEMBER]
     17 };
     18 Blockly.JavaScript.lists_isEmpty = function (a) {
     19     return ["!" + (Blockly.JavaScript.valueToCode(a, "VALUE", Blockly.JavaScript.ORDER_MEMBER) || "[]") + ".length", Blockly.JavaScript.ORDER_LOGICAL_NOT]
     20 };
     21 Blockly.JavaScript.lists_indexOf = function (a) {
     22     var b = "FIRST" == a.getFieldValue("END") ? "indexOf" : "lastIndexOf",
     23         c = Blockly.JavaScript.valueToCode(a, "FIND", Blockly.JavaScript.ORDER_NONE) || "''";
     24     b = (Blockly.JavaScript.valueToCode(a, "VALUE", Blockly.JavaScript.ORDER_MEMBER) || "[]") + "." + b + "(" + c + ")";
     25     return a.workspace.options.oneBasedIndex ? [b + " + 1", Blockly.JavaScript.ORDER_ADDITION] : [b, Blockly.JavaScript.ORDER_FUNCTION_CALL]
     26 };
     27 Blockly.JavaScript.lists_getIndex = function (a) {
     28     var b = a.getFieldValue("MODE") || "GET",
     29         c = a.getFieldValue("WHERE") || "FROM_START",
     30         d = Blockly.JavaScript.valueToCode(a, "VALUE", "RANDOM" == c ? Blockly.JavaScript.ORDER_COMMA : Blockly.JavaScript.ORDER_MEMBER) || "[]";
     31     switch (c) {
     32         case "FIRST":
     33             if ("GET" == b) return [d + "[0]", Blockly.JavaScript.ORDER_MEMBER];
     34             if ("GET_REMOVE" == b) return [d + ".shift()", Blockly.JavaScript.ORDER_MEMBER];
     35             if ("REMOVE" == b) return d + ".shift();
    ";
     36             break;
     37         case "LAST":
     38             if ("GET" == b) return [d + ".slice(-1)[0]", Blockly.JavaScript.ORDER_MEMBER];
     39             if ("GET_REMOVE" == b) return [d + ".pop()", Blockly.JavaScript.ORDER_MEMBER];
     40             if ("REMOVE" == b) return d + ".pop();
    ";
     41             break;
     42         case "FROM_START":
     43             a = Blockly.JavaScript.getAdjusted(a, "AT");
     44             if ("GET" == b) return [d + "[" + a + "]", Blockly.JavaScript.ORDER_MEMBER];
     45             if ("GET_REMOVE" == b) return [d + ".splice(" + a + ", 1)[0]", Blockly.JavaScript.ORDER_FUNCTION_CALL];
     46             if ("REMOVE" == b) return d + ".splice(" + a + ", 1);
    ";
     47             break;
     48         case "FROM_END":
     49             a = Blockly.JavaScript.getAdjusted(a, "AT", 1, !0);
     50             if ("GET" == b) return [d + ".slice(" + a + ")[0]", Blockly.JavaScript.ORDER_FUNCTION_CALL];
     51             if ("GET_REMOVE" == b) return [d + ".splice(" + a + ", 1)[0]", Blockly.JavaScript.ORDER_FUNCTION_CALL];
     52             if ("REMOVE" == b) return d + ".splice(" + a + ", 1);";
     53             break;
     54         case "RANDOM":
     55             d = Blockly.JavaScript.provideFunction_("listsGetRandomItem", ["function " + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + "(list, remove) {", "  var x = Math.floor(Math.random() * list.length);", "  if (remove) {", "    return list.splice(x, 1)[0];", "  } else {", "    return list[x];", "  }", "}"]) + "(" + d + ", " + ("GET" != b) + ")";
     56             if ("GET" == b || "GET_REMOVE" == b) return [d,
     57                 Blockly.JavaScript.ORDER_FUNCTION_CALL
     58             ];
     59             if ("REMOVE" == b) return d + ";
    "
     60     }
     61     throw Error("Unhandled combination (lists_getIndex).");
     62 };
     63 Blockly.JavaScript.lists_setIndex = function (a) {
     64     function b() {
     65         if (c.match(/^w+$/)) return "";
     66         var a = Blockly.JavaScript.variableDB_.getDistinctName("tmpList", Blockly.Variables.NAME_TYPE),
     67             b = "var " + a + " = " + c + ";
    ";
     68         c = a;
     69         return b
     70     }
     71     var c = Blockly.JavaScript.valueToCode(a, "LIST", Blockly.JavaScript.ORDER_MEMBER) || "[]",
     72         d = a.getFieldValue("MODE") || "GET",
     73         e = a.getFieldValue("WHERE") || "FROM_START",
     74         f = Blockly.JavaScript.valueToCode(a, "TO", Blockly.JavaScript.ORDER_ASSIGNMENT) || "null";
     75     switch (e) {
     76         case "FIRST":
     77             if ("SET" == d) return c +
     78                 "[0] = " + f + ";
    ";
     79             if ("INSERT" == d) return c + ".unshift(" + f + ");
    ";
     80             break;
     81         case "LAST":
     82             if ("SET" == d) return a = b(), a + (c + "[" + c + ".length - 1] = " + f + ";
    ");
     83             if ("INSERT" == d) return c + ".push(" + f + ");
    ";
     84             break;
     85         case "FROM_START":
     86             e = Blockly.JavaScript.getAdjusted(a, "AT");
     87             if ("SET" == d) return c + "[" + e + "] = " + f + ";
    ";
     88             if ("INSERT" == d) return c + ".splice(" + e + ", 0, " + f + ");
    ";
     89             break;
     90         case "FROM_END":
     91             e = Blockly.JavaScript.getAdjusted(a, "AT", 1, !1, Blockly.JavaScript.ORDER_SUBTRACTION);
     92             a = b();
     93             if ("SET" == d) return a + (c + "[" + c + ".length - " + e +
     94                 "] = " + f + ";
    ");
     95             if ("INSERT" == d) return a + (c + ".splice(" + c + ".length - " + e + ", 0, " + f + ");
    ");
     96             break;
     97         case "RANDOM":
     98             a = b();
     99             e = Blockly.JavaScript.variableDB_.getDistinctName("tmpX", Blockly.Variables.NAME_TYPE);
    100             a += "var " + e + " = Math.floor(Math.random() * " + c + ".length);
    ";
    101             if ("SET" == d) return a + (c + "[" + e + "] = " + f + ";
    ");
    102             if ("INSERT" == d) return a + (c + ".splice(" + e + ", 0, " + f + ");
    ")
    103     }
    104     throw Error("Unhandled combination (lists_setIndex).");
    105 };
    106 Blockly.JavaScript.lists.getIndex_ = function (a, b, c) {
    107     return "FIRST" == b ? "0" : "FROM_END" == b ? a + ".length - 1 - " + c : "LAST" == b ? a + ".length - 1" : c
    108 };
    109 Blockly.JavaScript.lists_getSublist = function (a) {
    110     var b = Blockly.JavaScript.valueToCode(a, "LIST", Blockly.JavaScript.ORDER_MEMBER) || "[]",
    111         c = a.getFieldValue("WHERE1"),
    112         d = a.getFieldValue("WHERE2");
    113     if ("FIRST" == c && "LAST" == d) b += ".slice(0)";
    114     else if (b.match(/^w+$/) || "FROM_END" != c && "FROM_START" == d) {
    115         switch (c) {
    116             case "FROM_START":
    117                 var e = Blockly.JavaScript.getAdjusted(a, "AT1");
    118                 break;
    119             case "FROM_END":
    120                 e = Blockly.JavaScript.getAdjusted(a, "AT1", 1, !1, Blockly.JavaScript.ORDER_SUBTRACTION);
    121                 e = b + ".length - " + e;
    122                 break;
    123             case "FIRST":
    124                 e =
    125                     "0";
    126                 break;
    127             default:
    128                 throw Error("Unhandled option (lists_getSublist).");
    129         }
    130         switch (d) {
    131             case "FROM_START":
    132                 a = Blockly.JavaScript.getAdjusted(a, "AT2", 1);
    133                 break;
    134             case "FROM_END":
    135                 a = Blockly.JavaScript.getAdjusted(a, "AT2", 0, !1, Blockly.JavaScript.ORDER_SUBTRACTION);
    136                 a = b + ".length - " + a;
    137                 break;
    138             case "LAST":
    139                 a = b + ".length";
    140                 break;
    141             default:
    142                 throw Error("Unhandled option (lists_getSublist).");
    143         }
    144         b = b + ".slice(" + e + ", " + a + ")"
    145     } else {
    146         e = Blockly.JavaScript.getAdjusted(a, "AT1");
    147         a = Blockly.JavaScript.getAdjusted(a, "AT2");
    148         var f = Blockly.JavaScript.lists.getIndex_,
    149             g = {
    150                 FIRST: "First",
    151                 LAST: "Last",
    152                 FROM_START: "FromStart",
    153                 FROM_END: "FromEnd"
    154             };
    155         b = Blockly.JavaScript.provideFunction_("subsequence" + g[c] + g[d], ["function " + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + "(sequence" + ("FROM_END" == c || "FROM_START" == c ? ", at1" : "") + ("FROM_END" == d || "FROM_START" == d ? ", at2" : "") + ") {", "  var start = " + f("sequence", c, "at1") + ";", "  var end = " + f("sequence", d, "at2") + " + 1;", "  return sequence.slice(start, end);", "}"]) + "(" + b + ("FROM_END" == c || "FROM_START" == c ? ", " + e : "") + ("FROM_END" == d || "FROM_START" ==
    156             d ? ", " + a : "") + ")"
    157     }
    158     return [b, Blockly.JavaScript.ORDER_FUNCTION_CALL]
    159 };
    160 Blockly.JavaScript.lists_sort = function (a) {
    161     var b = Blockly.JavaScript.valueToCode(a, "LIST", Blockly.JavaScript.ORDER_FUNCTION_CALL) || "[]",
    162         c = "1" === a.getFieldValue("DIRECTION") ? 1 : -1;
    163     a = a.getFieldValue("TYPE");
    164     var d = Blockly.JavaScript.provideFunction_("listsGetSortCompare", ["function " + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + "(type, direction) {", "  var compareFuncs = {", '    "NUMERIC": function(a, b) {', "        return Number(a) - Number(b); },", '    "TEXT": function(a, b) {', "        return a.toString() > b.toString() ? 1 : -1; },",
    165         '    "IGNORE_CASE": function(a, b) {', "        return a.toString().toLowerCase() > b.toString().toLowerCase() ? 1 : -1; },", "  };", "  var compare = compareFuncs[type];", "  return function(a, b) { return compare(a, b) * direction; }", "}"
    166     ]);
    167     return [b + ".slice().sort(" + d + '("' + a + '", ' + c + "))", Blockly.JavaScript.ORDER_FUNCTION_CALL]
    168 };
    169 Blockly.JavaScript.lists_split = function (a) {
    170     var b = Blockly.JavaScript.valueToCode(a, "INPUT", Blockly.JavaScript.ORDER_MEMBER),
    171         c = Blockly.JavaScript.valueToCode(a, "DELIM", Blockly.JavaScript.ORDER_NONE) || "''";
    172     a = a.getFieldValue("MODE");
    173     if ("SPLIT" == a) b || (b = "''"), a = "split";
    174     else if ("JOIN" == a) b || (b = "[]"), a = "join";
    175     else throw Error("Unknown mode: " + a);
    176     return [b + "." + a + "(" + c + ")", Blockly.JavaScript.ORDER_FUNCTION_CALL]
    177 };
    178 Blockly.JavaScript.lists_reverse = function (a) {
    179     return [(Blockly.JavaScript.valueToCode(a, "LIST", Blockly.JavaScript.ORDER_FUNCTION_CALL) || "[]") + ".slice().reverse()", Blockly.JavaScript.ORDER_FUNCTION_CALL]
    180 };
    View Code

    (3) blockly_compressed.js :提供了整体框架以及配套设施,拥有大量API函数供使用。

  • 相关阅读:
    redis数据结构
    django内置密码原理
    生成图片验证码
    如何封装VUE的axios请求
    杭电1717小数化分数2
    杭电2504 又见GCD
    杭电 2136 Largest prime factor(最大素数因子的位置)
    Linux终端的一些快捷键命令
    杭电 1772 cake
    杭电ACM 1713 相遇周期
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/11957098.html
Copyright © 2011-2022 走看看