PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/sites/all/libraries/blockly/generators/php/lists.js

https://gitlab.com/Drulenium-test/pantheon-travis
JavaScript | 381 lines | 321 code | 16 blank | 44 comment | 173 complexity | 62a80ce35270a2be51de91e3711b4be2 MD5 | raw file
  1. /**
  2. * @license
  3. * Visual Blocks Language
  4. *
  5. * Copyright 2015 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 PHP for list blocks.
  22. * @author daarond@gmail.com (Daaron Dwyer)
  23. */
  24. 'use strict';
  25. goog.provide('Blockly.PHP.lists');
  26. goog.require('Blockly.PHP');
  27. Blockly.PHP['lists_create_empty'] = function(block) {
  28. // Create an empty list.
  29. return ['array()', Blockly.PHP.ORDER_ATOMIC];
  30. };
  31. Blockly.PHP['lists_create_with'] = function(block) {
  32. // Create a list with any number of elements of any type.
  33. var code = new Array(block.itemCount_);
  34. for (var n = 0; n < block.itemCount_; n++) {
  35. code[n] = Blockly.PHP.valueToCode(block, 'ADD' + n,
  36. Blockly.PHP.ORDER_COMMA) || 'null';
  37. }
  38. code = 'array(' + code.join(', ') + ')';
  39. return [code, Blockly.PHP.ORDER_ATOMIC];
  40. };
  41. Blockly.PHP['lists_repeat'] = function(block) {
  42. // Create a list with one element repeated.
  43. var functionName = Blockly.PHP.provideFunction_(
  44. 'lists_repeat',
  45. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  46. '($value, $count) {',
  47. ' $array = array();',
  48. ' for ($index = 0; $index < $count; $index++) {',
  49. ' $array[] = $value;',
  50. ' }',
  51. ' return $array;',
  52. '}']);
  53. var argument0 = Blockly.PHP.valueToCode(block, 'ITEM',
  54. Blockly.PHP.ORDER_COMMA) || 'null';
  55. var argument1 = Blockly.PHP.valueToCode(block, 'NUM',
  56. Blockly.PHP.ORDER_COMMA) || '0';
  57. var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
  58. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  59. };
  60. Blockly.PHP['lists_length'] = function(block) {
  61. // String or array length.
  62. var functionName = Blockly.PHP.provideFunction_(
  63. 'length',
  64. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
  65. ' if (is_string($value)) {',
  66. ' return strlen($value);',
  67. ' } else {',
  68. ' return count($value);',
  69. ' }',
  70. '}']);
  71. var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
  72. Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
  73. return [functionName + '(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
  74. };
  75. Blockly.PHP['lists_isEmpty'] = function(block) {
  76. // Is the string null or array empty?
  77. var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
  78. Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
  79. return ['empty(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
  80. };
  81. Blockly.PHP['lists_indexOf'] = function(block) {
  82. // Find an item in the list.
  83. var operator = block.getFieldValue('END') == 'FIRST' ?
  84. 'indexOf' : 'lastIndexOf';
  85. var argument0 = Blockly.PHP.valueToCode(block, 'FIND',
  86. Blockly.PHP.ORDER_NONE) || '\'\'';
  87. var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
  88. Blockly.PHP.ORDER_MEMBER) || '[]';
  89. var functionName;
  90. if (block.getFieldValue('END') == 'FIRST'){
  91. // indexOf
  92. functionName = Blockly.PHP.provideFunction_(
  93. 'indexOf',
  94. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  95. '($haystack, $needle) {',
  96. ' for ($index = 0; $index < count($haystack); $index++) {',
  97. ' if ($haystack[$index] == $needle) return $index+1;',
  98. ' }',
  99. ' return 0;',
  100. '}']);
  101. } else {
  102. // lastIndexOf
  103. functionName = Blockly.PHP.provideFunction_(
  104. 'lastIndexOf',
  105. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  106. '($haystack, $needle) {',
  107. ' $last = 0;',
  108. ' for ($index = 0; $index < count($haystack); $index++) {',
  109. ' if ($haystack[$index] == $needle) $last = $index+1;',
  110. ' }',
  111. ' return $last;',
  112. '}']);
  113. }
  114. var code = functionName + '(' + argument1 + ', ' + argument0 + ')';
  115. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  116. };
  117. Blockly.PHP['lists_getIndex'] = function(block) {
  118. // Get element at index.
  119. var mode = block.getFieldValue('MODE') || 'GET';
  120. var where = block.getFieldValue('WHERE') || 'FROM_START';
  121. var at = Blockly.PHP.valueToCode(block, 'AT',
  122. Blockly.PHP.ORDER_UNARY_NEGATION) || '1';
  123. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  124. Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
  125. if (where == 'FIRST') {
  126. if (mode == 'GET') {
  127. var code = list + '[0]';
  128. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  129. } else if (mode == 'GET_REMOVE') {
  130. var code = 'array_shift(' + list + ')';
  131. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  132. } else if (mode == 'REMOVE') {
  133. return 'array_shift(' + list + ');\n';
  134. }
  135. } else if (where == 'LAST') {
  136. if (mode == 'GET') {
  137. var code = 'end(' + list + ')';
  138. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  139. } else if (mode == 'GET_REMOVE') {
  140. var code = 'array_pop(' + list + ')';
  141. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  142. } else if (mode == 'REMOVE') {
  143. return 'array_pop(' + list + ');\n';
  144. }
  145. } else if (where == 'FROM_START') {
  146. // Blockly uses one-based indicies.
  147. if (Blockly.isNumber(at)) {
  148. // If the index is a naked number, decrement it right now.
  149. at = parseFloat(at) - 1;
  150. } else {
  151. // If the index is dynamic, decrement it in code.
  152. at += ' - 1';
  153. }
  154. if (mode == 'GET') {
  155. var code = list + '[' + at + ']';
  156. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  157. } else if (mode == 'GET_REMOVE') {
  158. var code = 'array_splice(' + list + ', ' + at + ', 1)[0]';
  159. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  160. } else if (mode == 'REMOVE') {
  161. return 'array_splice(' + list + ', ' + at + ', 1);\n';
  162. }
  163. } else if (where == 'FROM_END') {
  164. if (mode == 'GET') {
  165. var code = 'array_slice(' + list + ', -' + at + ', 1)[0]';
  166. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  167. } else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
  168. code = 'array_splice(' + list +
  169. ', count(' + list + ') - ' + at + ', 1)[0]';
  170. if (mode == 'GET_REMOVE') {
  171. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  172. } else if (mode == 'REMOVE') {
  173. return code + ';\n';
  174. }
  175. }
  176. } else if (where == 'RANDOM') {
  177. if (mode == 'GET'){
  178. var functionName = Blockly.PHP.provideFunction_(
  179. 'lists_get_random_item',
  180. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  181. '($list) {',
  182. ' return $list[rand(0,count($list)-1)];',
  183. '}']);
  184. code = functionName + '(' + list + ')';
  185. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  186. } else if (mode == 'GET_REMOVE'){
  187. var functionName = Blockly.PHP.provideFunction_(
  188. 'lists_get_remove_random_item',
  189. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  190. '(&$list) {',
  191. ' $x = rand(0,count($list)-1);',
  192. ' unset($list[$x]);',
  193. ' return array_values($list);',
  194. '}']);
  195. code = functionName + '(' + list + ')';
  196. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  197. } else if (mode == 'REMOVE') {
  198. var functionName = Blockly.PHP.provideFunction_(
  199. 'lists_remove_random_item',
  200. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  201. '(&$list) {',
  202. ' unset($list[rand(0,count($list)-1)]);',
  203. '}']);
  204. return functionName + '(' + list + ');\n';
  205. }
  206. }
  207. throw 'Unhandled combination (lists_getIndex).';
  208. };
  209. Blockly.PHP['lists_setIndex'] = function(block) {
  210. // Set element at index.
  211. // Note: Until February 2013 this block did not have MODE or WHERE inputs.
  212. var list = Blockly.PHP.valueToCode(block, 'LIST',
  213. Blockly.PHP.ORDER_MEMBER) || 'array()';
  214. var mode = block.getFieldValue('MODE') || 'GET';
  215. var where = block.getFieldValue('WHERE') || 'FROM_START';
  216. var at = Blockly.PHP.valueToCode(block, 'AT',
  217. Blockly.PHP.ORDER_NONE) || '1';
  218. var value = Blockly.PHP.valueToCode(block, 'TO',
  219. Blockly.PHP.ORDER_ASSIGNMENT) || 'null';
  220. // Cache non-trivial values to variables to prevent repeated look-ups.
  221. // Closure, which accesses and modifies 'list'.
  222. function cacheList() {
  223. if (list.match(/^\w+$/)) {
  224. return '';
  225. }
  226. var listVar = Blockly.PHP.variableDB_.getDistinctName(
  227. 'tmp_list', Blockly.Variables.NAME_TYPE);
  228. var code = listVar + ' = &' + list + ';\n';
  229. list = listVar;
  230. return code;
  231. }
  232. if (where == 'FIRST') {
  233. if (mode == 'SET') {
  234. return list + '[0] = ' + value + ';\n';
  235. } else if (mode == 'INSERT') {
  236. return 'array_unshift(' + list + ', ' + value + ');\n';
  237. }
  238. } else if (where == 'LAST') {
  239. if (mode == 'SET') {
  240. var functionName = Blockly.PHP.provideFunction_(
  241. 'lists_set_last_item',
  242. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  243. '(&$list, $value) {',
  244. ' $list[count($list) - 1] = $value;',
  245. '}']);
  246. return functionName + '(' + list + ', ' + value + ');\n';
  247. } else if (mode == 'INSERT') {
  248. return 'array_push(' + list + ', ' + value + ');\n';
  249. }
  250. } else if (where == 'FROM_START') {
  251. // Blockly uses one-based indicies.
  252. if (Blockly.isNumber(at)) {
  253. // If the index is a naked number, decrement it right now.
  254. at = parseFloat(at) - 1;
  255. } else {
  256. // If the index is dynamic, decrement it in code.
  257. at += ' - 1';
  258. }
  259. if (mode == 'SET') {
  260. return list + '[' + at + '] = ' + value + ';\n';
  261. } else if (mode == 'INSERT') {
  262. return 'array_splice(' + list + ', ' + at + ', 0, ' + value + ');\n';
  263. }
  264. } else if (where == 'FROM_END') {
  265. if (mode == 'SET') {
  266. var functionName = Blockly.PHP.provideFunction_(
  267. 'lists_set_from_end',
  268. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  269. '(&$list, $at, $value) {',
  270. ' $list[count($list) - $at] = $value;',
  271. '}']);
  272. return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
  273. } else if (mode == 'INSERT') {
  274. var functionName = Blockly.PHP.provideFunction_(
  275. 'lists_insert_from_end',
  276. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  277. '(&$list, $at, $value) {',
  278. ' return array_splice($list, count($list) - $at, 0, $value);',
  279. '}']);
  280. return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
  281. }
  282. } else if (where == 'RANDOM') {
  283. var code = cacheList();
  284. var xVar = Blockly.PHP.variableDB_.getDistinctName(
  285. 'tmp_x', Blockly.Variables.NAME_TYPE);
  286. code += xVar + ' = rand(0, count(' + list + ')-1);\n';
  287. if (mode == 'SET') {
  288. code += list + '[' + xVar + '] = ' + value + ';\n';
  289. return code;
  290. } else if (mode == 'INSERT') {
  291. code += 'array_splice(' + list + ', ' + xVar + ', 0, ' + value + ');\n';
  292. return code;
  293. }
  294. }
  295. throw 'Unhandled combination (lists_setIndex).';
  296. };
  297. Blockly.PHP['lists_getSublist'] = function(block) {
  298. // Get sublist.
  299. var list = Blockly.PHP.valueToCode(block, 'LIST',
  300. Blockly.PHP.ORDER_MEMBER) || 'array()';
  301. var where1 = block.getFieldValue('WHERE1');
  302. var where2 = block.getFieldValue('WHERE2');
  303. var at1 = Blockly.PHP.valueToCode(block, 'AT1',
  304. Blockly.PHP.ORDER_NONE) || '1';
  305. var at2 = Blockly.PHP.valueToCode(block, 'AT2',
  306. Blockly.PHP.ORDER_NONE) || '1';
  307. if (where1 == 'FIRST' && where2 == 'LAST') {
  308. var code = list;
  309. } else {
  310. var functionName = Blockly.PHP.provideFunction_(
  311. 'lists_get_sublist',
  312. [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  313. '($list, $where1, $at1, $where2, $at2) {',
  314. ' if ($where2 == \'FROM_START\') {',
  315. ' $at2--;',
  316. ' } else if ($where2 == \'FROM_END\') {',
  317. ' $at2 = $at2 - $at1;',
  318. ' } else if ($where2 == \'FIRST\') {',
  319. ' $at2 = 0;',
  320. ' } else if ($where2 == \'LAST\') {',
  321. ' $at2 = count($list);',
  322. ' } else {',
  323. ' throw \'Unhandled option (lists_getSublist).\';',
  324. ' }',
  325. ' if ($where1 == \'FROM_START\') {',
  326. ' $at1--;',
  327. ' } else if ($where1 == \'FROM_END\') {',
  328. ' $at1 = count($list) - $at1;',
  329. ' } else if ($where1 == \'FIRST\') {',
  330. ' $at1 = 0;',
  331. ' } else if ($where1 == \'LAST\') {',
  332. ' $at1 = count($list) - 1;',
  333. ' } else {',
  334. ' throw \'Unhandled option (lists_getSublist).\';',
  335. ' }',
  336. ' return array_slice($list, $at1, $at2);',
  337. '}']);
  338. var code = functionName + '(' + list + ', \'' +
  339. where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
  340. }
  341. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  342. };
  343. Blockly.PHP['lists_split'] = function(block) {
  344. // Block for splitting text into a list, or joining a list into text.
  345. var value_input = Blockly.PHP.valueToCode(block, 'INPUT',
  346. Blockly.PHP.ORDER_MEMBER);
  347. var value_delim = Blockly.PHP.valueToCode(block, 'DELIM',
  348. Blockly.PHP.ORDER_NONE) || '\'\'';
  349. var mode = block.getFieldValue('MODE');
  350. if (mode == 'SPLIT') {
  351. if (!value_input) {
  352. value_input = '\'\'';
  353. }
  354. var functionName = 'explode';
  355. } else if (mode == 'JOIN') {
  356. if (!value_input) {
  357. value_input = 'array()';
  358. }
  359. var functionName = 'implode';
  360. } else {
  361. throw 'Unknown mode: ' + mode;
  362. }
  363. var code = functionName + '(' + value_delim + ', ' + value_input + ')';
  364. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  365. };