php_rules.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Distributed under the BSD license:
  3. *
  4. * Copyright (c) 2012, Ajax.org B.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Ajax.org B.V. nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * ***** END LICENSE BLOCK ***** */
  30. define(function(require, exports, module) {
  31. "use strict";
  32. var TokenIterator = require("ace/token_iterator").TokenIterator;
  33. exports.newLines = [{
  34. type: 'support.php_tag',
  35. value: '<?php'
  36. }, {
  37. type: 'support.php_tag',
  38. value: '<?'
  39. }, {
  40. type: 'support.php_tag',
  41. value: '?>'
  42. }, {
  43. type: 'paren.lparen',
  44. value: '{',
  45. indent: true
  46. }, {
  47. type: 'paren.rparen',
  48. breakBefore: true,
  49. value: '}',
  50. indent: false
  51. }, {
  52. type: 'paren.rparen',
  53. breakBefore: true,
  54. value: '})',
  55. indent: false,
  56. dontBreak: true
  57. }, {
  58. type: 'comment'
  59. }, {
  60. type: 'text',
  61. value: ';'
  62. }, {
  63. type: 'text',
  64. value: ':',
  65. context: 'php'
  66. }, {
  67. type: 'keyword',
  68. value: 'case',
  69. indent: true,
  70. dontBreak: true
  71. }, {
  72. type: 'keyword',
  73. value: 'default',
  74. indent: true,
  75. dontBreak: true
  76. }, {
  77. type: 'keyword',
  78. value: 'break',
  79. indent: false,
  80. dontBreak: true
  81. }, {
  82. type: 'punctuation.doctype.end',
  83. value: '>'
  84. }, {
  85. type: 'meta.tag.punctuation.end',
  86. value: '>'
  87. }, {
  88. type: 'meta.tag.punctuation.begin',
  89. value: '<',
  90. blockTag: true,
  91. indent: true,
  92. dontBreak: true
  93. }, {
  94. type: 'meta.tag.punctuation.begin',
  95. value: '</',
  96. indent: false,
  97. breakBefore: true,
  98. dontBreak: true
  99. }, {
  100. type: 'punctuation.operator',
  101. value: ';'
  102. }];
  103. exports.spaces = [{
  104. type: 'xml-pe',
  105. prepend: true
  106. },{
  107. type: 'entity.other.attribute-name',
  108. prepend: true
  109. }, {
  110. type: 'storage.type',
  111. value: 'var',
  112. append: true
  113. }, {
  114. type: 'storage.type',
  115. value: 'function',
  116. append: true
  117. }, {
  118. type: 'keyword.operator',
  119. value: '='
  120. }, {
  121. type: 'keyword',
  122. value: 'as',
  123. prepend: true,
  124. append: true
  125. }, {
  126. type: 'keyword',
  127. value: 'function',
  128. append: true
  129. }, {
  130. type: 'support.function',
  131. next: /[^\(]/,
  132. append: true
  133. }, {
  134. type: 'keyword',
  135. value: 'or',
  136. append: true,
  137. prepend: true
  138. }, {
  139. type: 'keyword',
  140. value: 'and',
  141. append: true,
  142. prepend: true
  143. }, {
  144. type: 'keyword',
  145. value: 'case',
  146. append: true
  147. }, {
  148. type: 'keyword.operator',
  149. value: '||',
  150. append: true,
  151. prepend: true
  152. }, {
  153. type: 'keyword.operator',
  154. value: '&&',
  155. append: true,
  156. prepend: true
  157. }];
  158. exports.singleTags = ['!doctype','area','base','br','hr','input','img','link','meta'];
  159. exports.transform = function(iterator, maxPos, context) {
  160. var token = iterator.getCurrentToken();
  161. var newLines = exports.newLines;
  162. var spaces = exports.spaces;
  163. var singleTags = exports.singleTags;
  164. var code = '';
  165. var indentation = 0;
  166. var dontBreak = false;
  167. var tag;
  168. var lastTag;
  169. var lastToken = {};
  170. var nextTag;
  171. var nextToken = {};
  172. var breakAdded = false;
  173. var value = '';
  174. while (token!==null) {
  175. console.log(token);
  176. if( !token ){
  177. token = iterator.stepForward();
  178. continue;
  179. }
  180. //change syntax
  181. //php
  182. if( token.type == 'support.php_tag' && token.value != '?>' ){
  183. context = 'php';
  184. }
  185. else if( token.type == 'support.php_tag' && token.value == '?>' ){
  186. context = 'html';
  187. }
  188. //css
  189. else if( token.type == 'meta.tag.name.style' && context != 'css' ){
  190. context = 'css';
  191. }
  192. else if( token.type == 'meta.tag.name.style' && context == 'css' ){
  193. context = 'html';
  194. }
  195. //js
  196. else if( token.type == 'meta.tag.name.script' && context != 'js' ){
  197. context = 'js';
  198. }
  199. else if( token.type == 'meta.tag.name.script' && context == 'js' ){
  200. context = 'html';
  201. }
  202. nextToken = iterator.stepForward();
  203. //tag name
  204. if (nextToken && nextToken.type.indexOf('meta.tag.name') == 0) {
  205. nextTag = nextToken.value;
  206. }
  207. //don't linebreak
  208. if ( lastToken.type == 'support.php_tag' && lastToken.value == '<?=') {
  209. dontBreak = true;
  210. }
  211. //lowercase
  212. if (token.type == 'meta.tag.name') {
  213. token.value = token.value.toLowerCase();
  214. }
  215. //trim spaces
  216. if (token.type == 'text') {
  217. token.value = token.value.trim();
  218. }
  219. //skip empty tokens
  220. if (!token.value) {
  221. token = nextToken;
  222. continue;
  223. }
  224. //put spaces back in
  225. value = token.value;
  226. for (var i in spaces) {
  227. if (
  228. token.type == spaces[i].type &&
  229. (!spaces[i].value || token.value == spaces[i].value) &&
  230. (
  231. nextToken &&
  232. (!spaces[i].next || spaces[i].next.test(nextToken.value))
  233. )
  234. ) {
  235. if (spaces[i].prepend) {
  236. value = ' ' + token.value;
  237. }
  238. if (spaces[i].append) {
  239. value += ' ';
  240. }
  241. }
  242. }
  243. //tag name
  244. if (token.type.indexOf('meta.tag.name') == 0) {
  245. tag = token.value;
  246. //console.log(tag);
  247. }
  248. //new line before
  249. breakAdded = false;
  250. //outdent
  251. for (i in newLines) {
  252. if (
  253. token.type == newLines[i].type &&
  254. (
  255. !newLines[i].value ||
  256. token.value == newLines[i].value
  257. ) &&
  258. (
  259. !newLines[i].blockTag ||
  260. singleTags.indexOf(nextTag) === -1
  261. ) &&
  262. (
  263. !newLines[i].context ||
  264. newLines[i].context === context
  265. )
  266. ) {
  267. if (newLines[i].indent === false) {
  268. indentation--;
  269. }
  270. if (
  271. newLines[i].breakBefore &&
  272. ( !newLines[i].prev || newLines[i].prev.test(lastToken.value) )
  273. ) {
  274. code += "\n";
  275. breakAdded = true;
  276. //indent
  277. for (i = 0; i < indentation; i++) {
  278. code += "\t";
  279. }
  280. }
  281. break;
  282. }
  283. }
  284. if (dontBreak===false) {
  285. for (i in newLines) {
  286. if (
  287. lastToken.type == newLines[i].type &&
  288. (
  289. !newLines[i].value || lastToken.value == newLines[i].value
  290. ) &&
  291. (
  292. !newLines[i].blockTag ||
  293. singleTags.indexOf(tag) === -1
  294. ) &&
  295. (
  296. !newLines[i].context ||
  297. newLines[i].context === context
  298. )
  299. ) {
  300. if (newLines[i].indent === true) {
  301. indentation++;
  302. }
  303. if (!newLines[i].dontBreak && !breakAdded) {
  304. code += "\n";
  305. //indent
  306. for (i = 0; i < indentation; i++) {
  307. code += "\t";
  308. }
  309. }
  310. break;
  311. }
  312. }
  313. }
  314. code += value;
  315. //linebreaks back on after end short php tag
  316. if ( lastToken.type == 'support.php_tag' && lastToken.value == '?>' ) {
  317. dontBreak = false;
  318. }
  319. //next token
  320. lastTag = tag;
  321. lastToken = token;
  322. token = nextToken;
  323. if (token===null) {
  324. break;
  325. }
  326. }
  327. return code;
  328. };
  329. });