text.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /**
  2. * @license
  3. * Visual Blocks Language
  4. *
  5. * Copyright 2014 Google Inc.
  6. * https://developers.google.com/blockly/
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. /**
  21. * @fileoverview Generating Dart for text blocks.
  22. * @author fraser@google.com (Neil Fraser)
  23. */
  24. 'use strict';
  25. goog.provide('Blockly.Dart.texts');
  26. goog.require('Blockly.Dart');
  27. Blockly.Dart.addReservedWords('Html,Math');
  28. Blockly.Dart['text'] = function(block) {
  29. // Text value.
  30. var code = Blockly.Dart.quote_(block.getFieldValue('TEXT'));
  31. return [code, Blockly.Dart.ORDER_ATOMIC];
  32. };
  33. Blockly.Dart['text_join'] = function(block) {
  34. // Create a string made up of any number of elements of any type.
  35. var code;
  36. if (block.itemCount_ == 0) {
  37. return ['\'\'', Blockly.Dart.ORDER_ATOMIC];
  38. } else if (block.itemCount_ == 1) {
  39. var argument0 = Blockly.Dart.valueToCode(block, 'ADD0',
  40. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  41. code = argument0 + '.toString()';
  42. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  43. } else {
  44. code = new Array(block.itemCount_);
  45. for (var n = 0; n < block.itemCount_; n++) {
  46. code[n] = Blockly.Dart.valueToCode(block, 'ADD' + n,
  47. Blockly.Dart.ORDER_NONE) || '\'\'';
  48. }
  49. code = '[' + code.join(',') + '].join()';
  50. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  51. }
  52. };
  53. Blockly.Dart['text_append'] = function(block) {
  54. // Append to a variable in place.
  55. var varName = Blockly.Dart.variableDB_.getName(block.getFieldValue('VAR'),
  56. Blockly.Variables.NAME_TYPE);
  57. var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
  58. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  59. return varName + ' = [' + varName + ', ' + argument0 + '].join();\n';
  60. };
  61. Blockly.Dart['text_length'] = function(block) {
  62. // String or array length.
  63. var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
  64. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  65. return [argument0 + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
  66. };
  67. Blockly.Dart['text_isEmpty'] = function(block) {
  68. // Is the string null or array empty?
  69. var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
  70. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  71. return [argument0 + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
  72. };
  73. Blockly.Dart['text_indexOf'] = function(block) {
  74. // Search the text for a substring.
  75. var operator = block.getFieldValue('END') == 'FIRST' ?
  76. 'indexOf' : 'lastIndexOf';
  77. var argument0 = Blockly.Dart.valueToCode(block, 'FIND',
  78. Blockly.Dart.ORDER_NONE) || '\'\'';
  79. var argument1 = Blockly.Dart.valueToCode(block, 'VALUE',
  80. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  81. var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
  82. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  83. };
  84. Blockly.Dart['text_charAt'] = function(block) {
  85. // Get letter at index.
  86. // Note: Until January 2013 this block did not have the WHERE input.
  87. var where = block.getFieldValue('WHERE') || 'FROM_START';
  88. var at = Blockly.Dart.valueToCode(block, 'AT',
  89. Blockly.Dart.ORDER_NONE) || '1';
  90. var text = Blockly.Dart.valueToCode(block, 'VALUE',
  91. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  92. switch (where) {
  93. case 'FIRST':
  94. var code = text + '[0]';
  95. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  96. case 'FROM_START':
  97. // Blockly uses one-based indicies.
  98. if (at.match(/^-?\d+$/)) {
  99. // If the index is a naked number, decrement it right now.
  100. at = parseInt(at, 10) - 1;
  101. } else {
  102. // If the index is dynamic, decrement it in code.
  103. at += ' - 1';
  104. }
  105. var code = text + '[' + at + ']';
  106. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  107. case 'LAST':
  108. at = 1;
  109. // Fall through.
  110. case 'FROM_END':
  111. var functionName = Blockly.Dart.provideFunction_(
  112. 'text_get_from_end',
  113. [ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
  114. '(String text, num x) {',
  115. ' return text[text.length - x];',
  116. '}']);
  117. code = functionName + '(' + text + ', ' + at + ')';
  118. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  119. case 'RANDOM':
  120. Blockly.Dart.definitions_['import_dart_math'] =
  121. 'import \'dart:math\' as Math;';
  122. var functionName = Blockly.Dart.provideFunction_(
  123. 'text_random_letter',
  124. [ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
  125. '(String text) {',
  126. ' int x = new Math.Random().nextInt(text.length);',
  127. ' return text[x];',
  128. '}']);
  129. code = functionName + '(' + text + ')';
  130. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  131. }
  132. throw 'Unhandled option (text_charAt).';
  133. };
  134. Blockly.Dart['text_getSubstring'] = function(block) {
  135. // Get substring.
  136. var text = Blockly.Dart.valueToCode(block, 'STRING',
  137. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  138. var where1 = block.getFieldValue('WHERE1');
  139. var where2 = block.getFieldValue('WHERE2');
  140. var at1 = Blockly.Dart.valueToCode(block, 'AT1',
  141. Blockly.Dart.ORDER_NONE) || '1';
  142. var at2 = Blockly.Dart.valueToCode(block, 'AT2',
  143. Blockly.Dart.ORDER_NONE) || '1';
  144. if (where1 == 'FIRST' && where2 == 'LAST') {
  145. var code = text;
  146. } else {
  147. var functionName = Blockly.Dart.provideFunction_(
  148. 'text_get_substring',
  149. [ 'function ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
  150. '(text, where1, at1, where2, at2) {',
  151. ' function getAt(where, at) {',
  152. ' if (where == \'FROM_START\') {',
  153. ' at--;',
  154. ' } else if (where == \'FROM_END\') {',
  155. ' at = text.length - at;',
  156. ' } else if (where == \'FIRST\') {',
  157. ' at = 0;',
  158. ' } else if (where == \'LAST\') {',
  159. ' at = text.length - 1;',
  160. ' } else {',
  161. ' throw \'Unhandled option (text_getSubstring).\';',
  162. ' }',
  163. ' return at;',
  164. ' }',
  165. ' at1 = getAt(where1, at1);',
  166. ' at2 = getAt(where2, at2) + 1;',
  167. ' return text.substring(at1, at2);',
  168. '}']);
  169. var code = functionName + '(' + text + ', \'' +
  170. where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
  171. }
  172. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  173. };
  174. Blockly.Dart['text_changeCase'] = function(block) {
  175. // Change capitalization.
  176. var OPERATORS = {
  177. 'UPPERCASE': '.toUpperCase()',
  178. 'LOWERCASE': '.toLowerCase()',
  179. 'TITLECASE': null
  180. };
  181. var operator = OPERATORS[block.getFieldValue('CASE')];
  182. var code;
  183. if (operator) {
  184. // Upper and lower case are functions built into Dart.
  185. var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
  186. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  187. code = argument0 + operator;
  188. } else {
  189. // Title case is not a native Dart function. Define one.
  190. var functionName = Blockly.Dart.provideFunction_(
  191. 'text_toTitleCase',
  192. [ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
  193. '(String str) {',
  194. ' RegExp exp = new RegExp(r\'\\b\');',
  195. ' List<String> list = str.split(exp);',
  196. ' final title = new StringBuffer();',
  197. ' for (String part in list) {',
  198. ' if (part.length > 0) {',
  199. ' title.write(part[0].toUpperCase());',
  200. ' if (part.length > 0) {',
  201. ' title.write(part.substring(1).toLowerCase());',
  202. ' }',
  203. ' }',
  204. ' }',
  205. ' return title.toString();',
  206. '}']);
  207. var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
  208. Blockly.Dart.ORDER_NONE) || '\'\'';
  209. code = functionName + '(' + argument0 + ')';
  210. }
  211. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  212. };
  213. Blockly.Dart['text_trim'] = function(block) {
  214. // Trim spaces.
  215. var OPERATORS = {
  216. 'LEFT': '.replaceFirst(new RegExp(r\'^\\s+\'), \'\')',
  217. 'RIGHT': '.replaceFirst(new RegExp(r\'\\s+$\'), \'\')',
  218. 'BOTH': '.trim()'
  219. };
  220. var operator = OPERATORS[block.getFieldValue('MODE')];
  221. var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
  222. Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
  223. return [argument0 + operator, Blockly.Dart.ORDER_UNARY_POSTFIX];
  224. };
  225. Blockly.Dart['text_print'] = function(block) {
  226. // Print statement.
  227. var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
  228. Blockly.Dart.ORDER_NONE) || '\'\'';
  229. return 'print(' + argument0 + ');\n';
  230. };
  231. Blockly.Dart['text_prompt_ext'] = function(block) {
  232. // Prompt function.
  233. Blockly.Dart.definitions_['import_dart_html'] =
  234. 'import \'dart:html\' as Html;';
  235. if (block.getField('TEXT')) {
  236. // Internal message.
  237. var msg = Blockly.Dart.quote_(block.getFieldValue('TEXT'));
  238. } else {
  239. // External message.
  240. var msg = Blockly.Dart.valueToCode(block, 'TEXT',
  241. Blockly.Dart.ORDER_NONE) || '\'\'';
  242. }
  243. var code = 'Html.window.prompt(' + msg + ', \'\')';
  244. var toNumber = block.getFieldValue('TYPE') == 'NUMBER';
  245. if (toNumber) {
  246. Blockly.Dart.definitions_['import_dart_math'] =
  247. 'import \'dart:math\' as Math;';
  248. code = 'Math.parseDouble(' + code + ')';
  249. }
  250. return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
  251. };
  252. Blockly.Dart['text_prompt'] = Blockly.Dart['text_prompt_ext'];