d19b415a0279064ddfa890d0a7b3f78c.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. ace.define("ace/ext/textarea",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/net","ace/ace"], function(require, exports, module){"use strict";
  2. var event = require("../lib/event");
  3. var UA = require("../lib/useragent");
  4. var net = require("../lib/net");
  5. var ace = require("../ace");
  6. module.exports = exports = ace;
  7. var getCSSProperty = function (element, container, property) {
  8. var ret = element.style[property];
  9. if (!ret) {
  10. if (window.getComputedStyle) {
  11. ret = window.getComputedStyle(element, '').getPropertyValue(property);
  12. }
  13. else {
  14. ret = element.currentStyle[property];
  15. }
  16. }
  17. if (!ret || ret == 'auto' || ret == 'intrinsic') {
  18. ret = container.style[property];
  19. }
  20. return ret;
  21. };
  22. function applyStyles(elm, styles) {
  23. for (var style in styles) {
  24. elm.style[style] = styles[style];
  25. }
  26. }
  27. function setupContainer(element, getValue) {
  28. if (element.type != 'textarea') {
  29. throw new Error("Textarea required!");
  30. }
  31. var parentNode = element.parentNode;
  32. var container = document.createElement('div');
  33. var resizeEvent = function () {
  34. var style = 'position:relative;';
  35. [
  36. 'margin-top', 'margin-left', 'margin-right', 'margin-bottom'
  37. ].forEach(function (item) {
  38. style += item + ':' +
  39. getCSSProperty(element, container, item) + ';';
  40. });
  41. var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px");
  42. var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px");
  43. style += 'height:' + height + ';width:' + width + ';';
  44. style += 'display:inline-block;';
  45. container.setAttribute('style', style);
  46. };
  47. event.addListener(window, 'resize', resizeEvent);
  48. resizeEvent();
  49. parentNode.insertBefore(container, element.nextSibling);
  50. while (parentNode !== document) {
  51. if (parentNode.tagName.toUpperCase() === 'FORM') {
  52. var oldSumit = parentNode.onsubmit;
  53. parentNode.onsubmit = function (evt) {
  54. element.value = getValue();
  55. if (oldSumit) {
  56. oldSumit.call(this, evt);
  57. }
  58. };
  59. break;
  60. }
  61. parentNode = parentNode.parentNode;
  62. }
  63. return container;
  64. }
  65. exports.transformTextarea = function (element, options) {
  66. var isFocused = element.autofocus || document.activeElement == element;
  67. var session;
  68. var container = setupContainer(element, function () {
  69. return session.getValue();
  70. });
  71. element.style.display = 'none';
  72. container.style.background = 'white';
  73. var editorDiv = document.createElement("div");
  74. applyStyles(editorDiv, {
  75. top: "0px",
  76. left: "0px",
  77. right: "0px",
  78. bottom: "0px",
  79. border: "1px solid gray",
  80. position: "absolute"
  81. });
  82. container.appendChild(editorDiv);
  83. var settingOpener = document.createElement("div");
  84. applyStyles(settingOpener, {
  85. position: "absolute",
  86. right: "0px",
  87. bottom: "0px",
  88. cursor: "nw-resize",
  89. border: "solid 9px",
  90. borderColor: "lightblue gray gray #ceade6",
  91. zIndex: 101
  92. });
  93. var settingDiv = document.createElement("div");
  94. var settingDivStyles = {
  95. top: "0px",
  96. left: "20%",
  97. right: "0px",
  98. bottom: "0px",
  99. position: "absolute",
  100. padding: "5px",
  101. zIndex: 100,
  102. color: "white",
  103. display: "none",
  104. overflow: "auto",
  105. fontSize: "14px",
  106. boxShadow: "-5px 2px 3px gray"
  107. };
  108. if (!UA.isOldIE) {
  109. settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)";
  110. }
  111. else {
  112. settingDivStyles.backgroundColor = "#333";
  113. }
  114. applyStyles(settingDiv, settingDivStyles);
  115. container.appendChild(settingDiv);
  116. options = options || exports.defaultOptions;
  117. var editor = ace.edit(editorDiv);
  118. session = editor.getSession();
  119. session.setValue(element.value || element.innerHTML);
  120. if (isFocused)
  121. editor.focus();
  122. container.appendChild(settingOpener);
  123. setupApi(editor, editorDiv, settingDiv, ace, options);
  124. setupSettingPanel(settingDiv, settingOpener, editor);
  125. var state = "";
  126. event.addListener(settingOpener, "mousemove", function (e) {
  127. var rect = this.getBoundingClientRect();
  128. var x = e.clientX - rect.left, y = e.clientY - rect.top;
  129. if (x + y < (rect.width + rect.height) / 2) {
  130. this.style.cursor = "pointer";
  131. state = "toggle";
  132. }
  133. else {
  134. state = "resize";
  135. this.style.cursor = "nw-resize";
  136. }
  137. });
  138. event.addListener(settingOpener, "mousedown", function (e) {
  139. e.preventDefault();
  140. if (state == "toggle") {
  141. editor.setDisplaySettings();
  142. return;
  143. }
  144. container.style.zIndex = 100000;
  145. var rect = container.getBoundingClientRect();
  146. var startX = rect.width + rect.left - e.clientX;
  147. var startY = rect.height + rect.top - e.clientY;
  148. event.capture(settingOpener, function (e) {
  149. container.style.width = e.clientX - rect.left + startX + "px";
  150. container.style.height = e.clientY - rect.top + startY + "px";
  151. editor.resize();
  152. }, function () { });
  153. });
  154. return editor;
  155. };
  156. function load(url, module, callback) {
  157. net.loadScript(url, function () {
  158. require([module], callback);
  159. });
  160. }
  161. function setupApi(editor, editorDiv, settingDiv, ace, options) {
  162. var session = editor.getSession();
  163. var renderer = editor.renderer;
  164. function toBool(value) {
  165. return value === "true" || value == true;
  166. }
  167. editor.setDisplaySettings = function (display) {
  168. if (display == null)
  169. display = settingDiv.style.display == "none";
  170. if (display) {
  171. settingDiv.style.display = "block";
  172. settingDiv.hideButton.focus();
  173. editor.on("focus", function onFocus() {
  174. editor.removeListener("focus", onFocus);
  175. settingDiv.style.display = "none";
  176. });
  177. }
  178. else {
  179. editor.focus();
  180. }
  181. };
  182. editor.$setOption = editor.setOption;
  183. editor.$getOption = editor.getOption;
  184. editor.setOption = function (key, value) {
  185. switch (key) {
  186. case "mode":
  187. editor.$setOption("mode", "ace/mode/" + value);
  188. break;
  189. case "theme":
  190. editor.$setOption("theme", "ace/theme/" + value);
  191. break;
  192. case "keybindings":
  193. switch (value) {
  194. case "vim":
  195. editor.setKeyboardHandler("ace/keyboard/vim");
  196. break;
  197. case "emacs":
  198. editor.setKeyboardHandler("ace/keyboard/emacs");
  199. break;
  200. default:
  201. editor.setKeyboardHandler(null);
  202. }
  203. break;
  204. case "wrap":
  205. case "fontSize":
  206. editor.$setOption(key, value);
  207. break;
  208. default:
  209. editor.$setOption(key, toBool(value));
  210. }
  211. };
  212. editor.getOption = function (key) {
  213. switch (key) {
  214. case "mode":
  215. return editor.$getOption("mode").substr("ace/mode/".length);
  216. break;
  217. case "theme":
  218. return editor.$getOption("theme").substr("ace/theme/".length);
  219. break;
  220. case "keybindings":
  221. var value = editor.getKeyboardHandler();
  222. switch (value && value.$id) {
  223. case "ace/keyboard/vim":
  224. return "vim";
  225. case "ace/keyboard/emacs":
  226. return "emacs";
  227. default:
  228. return "ace";
  229. }
  230. break;
  231. default:
  232. return editor.$getOption(key);
  233. }
  234. };
  235. editor.setOptions(options);
  236. return editor;
  237. }
  238. function setupSettingPanel(settingDiv, settingOpener, editor) {
  239. var BOOL = null;
  240. var desc = {
  241. mode: "Mode:",
  242. wrap: "Soft Wrap:",
  243. theme: "Theme:",
  244. fontSize: "Font Size:",
  245. showGutter: "Display Gutter:",
  246. keybindings: "Keyboard",
  247. showPrintMargin: "Show Print Margin:",
  248. useSoftTabs: "Use Soft Tabs:",
  249. showInvisibles: "Show Invisibles"
  250. };
  251. var optionValues = {
  252. mode: {
  253. text: "Plain",
  254. javascript: "JavaScript",
  255. xml: "XML",
  256. html: "HTML",
  257. css: "CSS",
  258. scss: "SCSS",
  259. python: "Python",
  260. php: "PHP",
  261. java: "Java",
  262. ruby: "Ruby",
  263. c_cpp: "C/C++",
  264. coffee: "CoffeeScript",
  265. json: "json",
  266. perl: "Perl",
  267. clojure: "Clojure",
  268. ocaml: "OCaml",
  269. csharp: "C#",
  270. haxe: "haXe",
  271. svg: "SVG",
  272. textile: "Textile",
  273. groovy: "Groovy",
  274. liquid: "Liquid",
  275. Scala: "Scala"
  276. },
  277. theme: {
  278. clouds: "Clouds",
  279. clouds_midnight: "Clouds Midnight",
  280. cobalt: "Cobalt",
  281. crimson_editor: "Crimson Editor",
  282. dawn: "Dawn",
  283. gob: "Green on Black",
  284. eclipse: "Eclipse",
  285. idle_fingers: "Idle Fingers",
  286. kr_theme: "Kr Theme",
  287. merbivore: "Merbivore",
  288. merbivore_soft: "Merbivore Soft",
  289. mono_industrial: "Mono Industrial",
  290. monokai: "Monokai",
  291. pastel_on_dark: "Pastel On Dark",
  292. solarized_dark: "Solarized Dark",
  293. solarized_light: "Solarized Light",
  294. textmate: "Textmate",
  295. twilight: "Twilight",
  296. vibrant_ink: "Vibrant Ink"
  297. },
  298. showGutter: BOOL,
  299. fontSize: {
  300. "10px": "10px",
  301. "11px": "11px",
  302. "12px": "12px",
  303. "14px": "14px",
  304. "16px": "16px"
  305. },
  306. wrap: {
  307. off: "Off",
  308. 40: "40",
  309. 80: "80",
  310. free: "Free"
  311. },
  312. keybindings: {
  313. ace: "ace",
  314. vim: "vim",
  315. emacs: "emacs"
  316. },
  317. showPrintMargin: BOOL,
  318. useSoftTabs: BOOL,
  319. showInvisibles: BOOL
  320. };
  321. var table = [];
  322. table.push("<table><tr><th>Setting</th><th>Value</th></tr>");
  323. function renderOption(builder, option, obj, cValue) {
  324. if (!obj) {
  325. builder.push("<input type='checkbox' title='", option, "' ", cValue + "" == "true" ? "checked='true'" : "", "'></input>");
  326. return;
  327. }
  328. builder.push("<select title='" + option + "'>");
  329. for (var value in obj) {
  330. builder.push("<option value='" + value + "' ");
  331. if (cValue == value) {
  332. builder.push(" selected ");
  333. }
  334. builder.push(">", obj[value], "</option>");
  335. }
  336. builder.push("</select>");
  337. }
  338. for (var option in exports.defaultOptions) {
  339. table.push("<tr><td>", desc[option], "</td>");
  340. table.push("<td>");
  341. renderOption(table, option, optionValues[option], editor.getOption(option));
  342. table.push("</td></tr>");
  343. }
  344. table.push("</table>");
  345. settingDiv.innerHTML = table.join("");
  346. var onChange = function (e) {
  347. var select = e.currentTarget;
  348. editor.setOption(select.title, select.value);
  349. };
  350. var onClick = function (e) {
  351. var cb = e.currentTarget;
  352. editor.setOption(cb.title, cb.checked);
  353. };
  354. var selects = settingDiv.getElementsByTagName("select");
  355. for (var i = 0; i < selects.length; i++)
  356. selects[i].onchange = onChange;
  357. var cbs = settingDiv.getElementsByTagName("input");
  358. for (var i = 0; i < cbs.length; i++)
  359. cbs[i].onclick = onClick;
  360. var button = document.createElement("input");
  361. button.type = "button";
  362. button.value = "Hide";
  363. event.addListener(button, "click", function () {
  364. editor.setDisplaySettings(false);
  365. });
  366. settingDiv.appendChild(button);
  367. settingDiv.hideButton = button;
  368. }
  369. exports.defaultOptions = {
  370. mode: "javascript",
  371. theme: "textmate",
  372. wrap: "off",
  373. fontSize: "12px",
  374. showGutter: "false",
  375. keybindings: "ace",
  376. showPrintMargin: "false",
  377. useSoftTabs: "true",
  378. showInvisibles: "false"
  379. };
  380. }); (function() {
  381. ace.require(["ace/ext/textarea"], function(m) {
  382. if (typeof module == "object" && typeof exports == "object" && module) {
  383. module.exports = m;
  384. }
  385. });
  386. })();