ext-textarea.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. define("ace/theme/textmate",["ace_require","exports","module","ace/lib/dom"], function(ace_require, exports, module) {
  2. "use strict";
  3. exports.isDark = false;
  4. exports.cssClass = "ace-tm";
  5. exports.cssText = ".ace-tm .ace_gutter {\
  6. background: #f0f0f0;\
  7. color: #333;\
  8. }\
  9. .ace-tm .ace_print-margin {\
  10. width: 1px;\
  11. background: #e8e8e8;\
  12. }\
  13. .ace-tm .ace_fold {\
  14. background-color: #6B72E6;\
  15. }\
  16. .ace-tm {\
  17. background-color: #FFFFFF;\
  18. color: black;\
  19. }\
  20. .ace-tm .ace_cursor {\
  21. color: black;\
  22. }\
  23. .ace-tm .ace_invisible {\
  24. color: rgb(191, 191, 191);\
  25. }\
  26. .ace-tm .ace_storage,\
  27. .ace-tm .ace_keyword {\
  28. color: blue;\
  29. }\
  30. .ace-tm .ace_constant {\
  31. color: rgb(197, 6, 11);\
  32. }\
  33. .ace-tm .ace_constant.ace_buildin {\
  34. color: rgb(88, 72, 246);\
  35. }\
  36. .ace-tm .ace_constant.ace_language {\
  37. color: rgb(88, 92, 246);\
  38. }\
  39. .ace-tm .ace_constant.ace_library {\
  40. color: rgb(6, 150, 14);\
  41. }\
  42. .ace-tm .ace_invalid {\
  43. background-color: rgba(255, 0, 0, 0.1);\
  44. color: red;\
  45. }\
  46. .ace-tm .ace_support.ace_function {\
  47. color: rgb(60, 76, 114);\
  48. }\
  49. .ace-tm .ace_support.ace_constant {\
  50. color: rgb(6, 150, 14);\
  51. }\
  52. .ace-tm .ace_support.ace_type,\
  53. .ace-tm .ace_support.ace_class {\
  54. color: rgb(109, 121, 222);\
  55. }\
  56. .ace-tm .ace_keyword.ace_operator {\
  57. color: rgb(104, 118, 135);\
  58. }\
  59. .ace-tm .ace_string {\
  60. color: rgb(3, 106, 7);\
  61. }\
  62. .ace-tm .ace_comment {\
  63. color: rgb(76, 136, 107);\
  64. }\
  65. .ace-tm .ace_comment.ace_doc {\
  66. color: rgb(0, 102, 255);\
  67. }\
  68. .ace-tm .ace_comment.ace_doc.ace_tag {\
  69. color: rgb(128, 159, 191);\
  70. }\
  71. .ace-tm .ace_constant.ace_numeric {\
  72. color: rgb(0, 0, 205);\
  73. }\
  74. .ace-tm .ace_variable {\
  75. color: rgb(49, 132, 149);\
  76. }\
  77. .ace-tm .ace_xml-pe {\
  78. color: rgb(104, 104, 91);\
  79. }\
  80. .ace-tm .ace_entity.ace_name.ace_function {\
  81. color: #0000A2;\
  82. }\
  83. .ace-tm .ace_heading {\
  84. color: rgb(12, 7, 255);\
  85. }\
  86. .ace-tm .ace_list {\
  87. color:rgb(185, 6, 144);\
  88. }\
  89. .ace-tm .ace_meta.ace_tag {\
  90. color:rgb(0, 22, 142);\
  91. }\
  92. .ace-tm .ace_string.ace_regex {\
  93. color: rgb(255, 0, 0)\
  94. }\
  95. .ace-tm .ace_marker-layer .ace_selection {\
  96. background: rgb(181, 213, 255);\
  97. }\
  98. .ace-tm.ace_multiselect .ace_selection.ace_start {\
  99. box-shadow: 0 0 3px 0px white;\
  100. }\
  101. .ace-tm .ace_marker-layer .ace_step {\
  102. background: rgb(252, 255, 0);\
  103. }\
  104. .ace-tm .ace_marker-layer .ace_stack {\
  105. background: rgb(164, 229, 101);\
  106. }\
  107. .ace-tm .ace_marker-layer .ace_bracket {\
  108. margin: -1px 0 0 -1px;\
  109. border: 1px solid rgb(192, 192, 192);\
  110. }\
  111. .ace-tm .ace_marker-layer .ace_active-line {\
  112. background: rgba(0, 0, 0, 0.07);\
  113. }\
  114. .ace-tm .ace_gutter-active-line {\
  115. background-color : #dcdcdc;\
  116. }\
  117. .ace-tm .ace_marker-layer .ace_selected-word {\
  118. background: rgb(250, 250, 255);\
  119. border: 1px solid rgb(200, 200, 250);\
  120. }\
  121. .ace-tm .ace_indent-guide {\
  122. background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
  123. }\
  124. ";
  125. exports.$id = "ace/theme/textmate";
  126. var dom = ace_require("../lib/dom");
  127. dom.importCssString(exports.cssText, exports.cssClass);
  128. });
  129. define("ace/ext/textarea",["ace_require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/net","ace/ace","ace/theme/textmate"], function(ace_require, exports, module) {
  130. "use strict";
  131. var event = ace_require("../lib/event");
  132. var UA = ace_require("../lib/useragent");
  133. var net = ace_require("../lib/net");
  134. var ace = ace_require("../ace");
  135. ace_require("../theme/textmate");
  136. module.exports = exports = ace;
  137. var getCSSProperty = function(element, container, property) {
  138. var ret = element.style[property];
  139. if (!ret) {
  140. if (window.getComputedStyle) {
  141. ret = window.getComputedStyle(element, '').getPropertyValue(property);
  142. } else {
  143. ret = element.currentStyle[property];
  144. }
  145. }
  146. if (!ret || ret == 'auto' || ret == 'intrinsic') {
  147. ret = container.style[property];
  148. }
  149. return ret;
  150. };
  151. function applyStyles(elm, styles) {
  152. for (var style in styles) {
  153. elm.style[style] = styles[style];
  154. }
  155. }
  156. function setupContainer(element, getValue) {
  157. if (element.type != 'textarea') {
  158. throw new Error("Textarea required!");
  159. }
  160. var parentNode = element.parentNode;
  161. var container = document.createElement('div');
  162. var resizeEvent = function() {
  163. var style = 'position:relative;';
  164. [
  165. 'margin-top', 'margin-left', 'margin-right', 'margin-bottom'
  166. ].forEach(function(item) {
  167. style += item + ':' +
  168. getCSSProperty(element, container, item) + ';';
  169. });
  170. var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px");
  171. var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px");
  172. style += 'height:' + height + ';width:' + width + ';';
  173. style += 'display:inline-block;';
  174. container.setAttribute('style', style);
  175. };
  176. event.addListener(window, 'resize', resizeEvent);
  177. resizeEvent();
  178. parentNode.insertBefore(container, element.nextSibling);
  179. while (parentNode !== document) {
  180. if (parentNode.tagName.toUpperCase() === 'FORM') {
  181. var oldSumit = parentNode.onsubmit;
  182. parentNode.onsubmit = function(evt) {
  183. element.value = getValue();
  184. if (oldSumit) {
  185. oldSumit.call(this, evt);
  186. }
  187. };
  188. break;
  189. }
  190. parentNode = parentNode.parentNode;
  191. }
  192. return container;
  193. }
  194. exports.transformTextarea = function(element, options) {
  195. var isFocused = element.autofocus || document.activeElement == element;
  196. var session;
  197. var container = setupContainer(element, function() {
  198. return session.getValue();
  199. });
  200. element.style.display = 'none';
  201. container.style.background = 'white';
  202. var editorDiv = document.createElement("div");
  203. applyStyles(editorDiv, {
  204. top: "0px",
  205. left: "0px",
  206. right: "0px",
  207. bottom: "0px",
  208. border: "1px solid gray",
  209. position: "absolute"
  210. });
  211. container.appendChild(editorDiv);
  212. var settingOpener = document.createElement("div");
  213. applyStyles(settingOpener, {
  214. position: "absolute",
  215. right: "0px",
  216. bottom: "0px",
  217. cursor: "nw-resize",
  218. border: "solid 9px",
  219. borderColor: "lightblue gray gray #ceade6",
  220. zIndex: 101
  221. });
  222. var settingDiv = document.createElement("div");
  223. var settingDivStyles = {
  224. top: "0px",
  225. left: "20%",
  226. right: "0px",
  227. bottom: "0px",
  228. position: "absolute",
  229. padding: "5px",
  230. zIndex: 100,
  231. color: "white",
  232. display: "none",
  233. overflow: "auto",
  234. fontSize: "14px",
  235. boxShadow: "-5px 2px 3px gray"
  236. };
  237. if (!UA.isOldIE) {
  238. settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)";
  239. } else {
  240. settingDivStyles.backgroundColor = "#333";
  241. }
  242. applyStyles(settingDiv, settingDivStyles);
  243. container.appendChild(settingDiv);
  244. options = options || exports.defaultOptions;
  245. var editor = ace.edit(editorDiv);
  246. session = editor.getSession();
  247. session.setValue(element.value || element.innerHTML);
  248. if (isFocused)
  249. editor.focus();
  250. container.appendChild(settingOpener);
  251. setupApi(editor, editorDiv, settingDiv, ace, options);
  252. setupSettingPanel(settingDiv, settingOpener, editor);
  253. var state = "";
  254. event.addListener(settingOpener, "mousemove", function(e) {
  255. var rect = this.getBoundingClientRect();
  256. var x = e.clientX - rect.left, y = e.clientY - rect.top;
  257. if (x + y < (rect.width + rect.height)/2) {
  258. this.style.cursor = "pointer";
  259. state = "toggle";
  260. } else {
  261. state = "resize";
  262. this.style.cursor = "nw-resize";
  263. }
  264. });
  265. event.addListener(settingOpener, "mousedown", function(e) {
  266. e.preventDefault();
  267. if (state == "toggle") {
  268. editor.setDisplaySettings();
  269. return;
  270. }
  271. container.style.zIndex = 100000;
  272. var rect = container.getBoundingClientRect();
  273. var startX = rect.width + rect.left - e.clientX;
  274. var startY = rect.height + rect.top - e.clientY;
  275. event.capture(settingOpener, function(e) {
  276. container.style.width = e.clientX - rect.left + startX + "px";
  277. container.style.height = e.clientY - rect.top + startY + "px";
  278. editor.resize();
  279. }, function() {});
  280. });
  281. return editor;
  282. };
  283. function load(url, module, callback) {
  284. net.loadScript(url, function() {
  285. ace_require([module], callback);
  286. });
  287. }
  288. function setupApi(editor, editorDiv, settingDiv, ace, options) {
  289. var session = editor.getSession();
  290. var renderer = editor.renderer;
  291. function toBool(value) {
  292. return value === "true" || value == true;
  293. }
  294. editor.setDisplaySettings = function(display) {
  295. if (display == null)
  296. display = settingDiv.style.display == "none";
  297. if (display) {
  298. settingDiv.style.display = "block";
  299. settingDiv.hideButton.focus();
  300. editor.on("focus", function onFocus() {
  301. editor.removeListener("focus", onFocus);
  302. settingDiv.style.display = "none";
  303. });
  304. } else {
  305. editor.focus();
  306. }
  307. };
  308. editor.$setOption = editor.setOption;
  309. editor.$getOption = editor.getOption;
  310. editor.setOption = function(key, value) {
  311. switch (key) {
  312. case "mode":
  313. editor.$setOption("mode", "ace/mode/" + value);
  314. break;
  315. case "theme":
  316. editor.$setOption("theme", "ace/theme/" + value);
  317. break;
  318. case "keybindings":
  319. switch (value) {
  320. case "vim":
  321. editor.setKeyboardHandler("ace/keyboard/vim");
  322. break;
  323. case "emacs":
  324. editor.setKeyboardHandler("ace/keyboard/emacs");
  325. break;
  326. default:
  327. editor.setKeyboardHandler(null);
  328. }
  329. break;
  330. case "wrap":
  331. case "fontSize":
  332. editor.$setOption(key, value);
  333. break;
  334. default:
  335. editor.$setOption(key, toBool(value));
  336. }
  337. };
  338. editor.getOption = function(key) {
  339. switch (key) {
  340. case "mode":
  341. return editor.$getOption("mode").substr("ace/mode/".length);
  342. break;
  343. case "theme":
  344. return editor.$getOption("theme").substr("ace/theme/".length);
  345. break;
  346. case "keybindings":
  347. var value = editor.getKeyboardHandler();
  348. switch (value && value.$id) {
  349. case "ace/keyboard/vim":
  350. return "vim";
  351. case "ace/keyboard/emacs":
  352. return "emacs";
  353. default:
  354. return "ace";
  355. }
  356. break;
  357. default:
  358. return editor.$getOption(key);
  359. }
  360. };
  361. editor.setOptions(options);
  362. return editor;
  363. }
  364. function setupSettingPanel(settingDiv, settingOpener, editor) {
  365. var BOOL = null;
  366. var desc = {
  367. mode: "Mode:",
  368. wrap: "Soft Wrap:",
  369. theme: "Theme:",
  370. fontSize: "Font Size:",
  371. showGutter: "Display Gutter:",
  372. keybindings: "Keyboard",
  373. showPrintMargin: "Show Print Margin:",
  374. useSoftTabs: "Use Soft Tabs:",
  375. showInvisibles: "Show Invisibles"
  376. };
  377. var optionValues = {
  378. mode: {
  379. text: "Plain",
  380. javascript: "JavaScript",
  381. xml: "XML",
  382. html: "HTML",
  383. css: "CSS",
  384. scss: "SCSS",
  385. python: "Python",
  386. php: "PHP",
  387. java: "Java",
  388. ruby: "Ruby",
  389. c_cpp: "C/C++",
  390. coffee: "CoffeeScript",
  391. json: "json",
  392. perl: "Perl",
  393. clojure: "Clojure",
  394. ocaml: "OCaml",
  395. csharp: "C#",
  396. haxe: "haXe",
  397. svg: "SVG",
  398. textile: "Textile",
  399. groovy: "Groovy",
  400. liquid: "Liquid",
  401. Scala: "Scala"
  402. },
  403. theme: {
  404. clouds: "Clouds",
  405. clouds_midnight: "Clouds Midnight",
  406. cobalt: "Cobalt",
  407. crimson_editor: "Crimson Editor",
  408. dawn: "Dawn",
  409. gob: "Green on Black",
  410. eclipse: "Eclipse",
  411. idle_fingers: "Idle Fingers",
  412. kr_theme: "Kr Theme",
  413. merbivore: "Merbivore",
  414. merbivore_soft: "Merbivore Soft",
  415. mono_industrial: "Mono Industrial",
  416. monokai: "Monokai",
  417. pastel_on_dark: "Pastel On Dark",
  418. solarized_dark: "Solarized Dark",
  419. solarized_light: "Solarized Light",
  420. textmate: "Textmate",
  421. twilight: "Twilight",
  422. vibrant_ink: "Vibrant Ink"
  423. },
  424. showGutter: BOOL,
  425. fontSize: {
  426. "10px": "10px",
  427. "11px": "11px",
  428. "12px": "12px",
  429. "14px": "14px",
  430. "16px": "16px"
  431. },
  432. wrap: {
  433. off: "Off",
  434. 40: "40",
  435. 80: "80",
  436. free: "Free"
  437. },
  438. keybindings: {
  439. ace: "ace",
  440. vim: "vim",
  441. emacs: "emacs"
  442. },
  443. showPrintMargin: BOOL,
  444. useSoftTabs: BOOL,
  445. showInvisibles: BOOL
  446. };
  447. var table = [];
  448. table.push("<table><tr><th>Setting</th><th>Value</th></tr>");
  449. function renderOption(builder, option, obj, cValue) {
  450. if (!obj) {
  451. builder.push(
  452. "<input type='checkbox' title='", option, "' ",
  453. cValue + "" == "true" ? "checked='true'" : "",
  454. "'></input>"
  455. );
  456. return;
  457. }
  458. builder.push("<select title='" + option + "'>");
  459. for (var value in obj) {
  460. builder.push("<option value='" + value + "' ");
  461. if (cValue == value) {
  462. builder.push(" selected ");
  463. }
  464. builder.push(">",
  465. obj[value],
  466. "</option>");
  467. }
  468. builder.push("</select>");
  469. }
  470. for (var option in exports.defaultOptions) {
  471. table.push("<tr><td>", desc[option], "</td>");
  472. table.push("<td>");
  473. renderOption(table, option, optionValues[option], editor.getOption(option));
  474. table.push("</td></tr>");
  475. }
  476. table.push("</table>");
  477. settingDiv.innerHTML = table.join("");
  478. var onChange = function(e) {
  479. var select = e.currentTarget;
  480. editor.setOption(select.title, select.value);
  481. };
  482. var onClick = function(e) {
  483. var cb = e.currentTarget;
  484. editor.setOption(cb.title, cb.checked);
  485. };
  486. var selects = settingDiv.getElementsByTagName("select");
  487. for (var i = 0; i < selects.length; i++)
  488. selects[i].onchange = onChange;
  489. var cbs = settingDiv.getElementsByTagName("input");
  490. for (var i = 0; i < cbs.length; i++)
  491. cbs[i].onclick = onClick;
  492. var button = document.createElement("input");
  493. button.type = "button";
  494. button.value = "Hide";
  495. event.addListener(button, "click", function() {
  496. editor.setDisplaySettings(false);
  497. });
  498. settingDiv.appendChild(button);
  499. settingDiv.hideButton = button;
  500. }
  501. exports.defaultOptions = {
  502. mode: "javascript",
  503. theme: "textmate",
  504. wrap: "off",
  505. fontSize: "12px",
  506. showGutter: "false",
  507. keybindings: "ace",
  508. showPrintMargin: "false",
  509. useSoftTabs: "true",
  510. showInvisibles: "false"
  511. };
  512. }); (function() {
  513. window.ace_require(["ace/ext/textarea"], function(m) {
  514. if (typeof module == "object" && typeof exports == "object" && module) {
  515. module.exports = m;
  516. }
  517. });
  518. })();