暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ext-textarea.js 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(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. border-radius: 2px;\
  101. }\
  102. .ace-tm .ace_marker-layer .ace_step {\
  103. background: rgb(252, 255, 0);\
  104. }\
  105. .ace-tm .ace_marker-layer .ace_stack {\
  106. background: rgb(164, 229, 101);\
  107. }\
  108. .ace-tm .ace_marker-layer .ace_bracket {\
  109. margin: -1px 0 0 -1px;\
  110. border: 1px solid rgb(192, 192, 192);\
  111. }\
  112. .ace-tm .ace_marker-layer .ace_active-line {\
  113. background: rgba(0, 0, 0, 0.07);\
  114. }\
  115. .ace-tm .ace_gutter-active-line {\
  116. background-color : #dcdcdc;\
  117. }\
  118. .ace-tm .ace_marker-layer .ace_selected-word {\
  119. background: rgb(250, 250, 255);\
  120. border: 1px solid rgb(200, 200, 250);\
  121. }\
  122. .ace-tm .ace_indent-guide {\
  123. background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
  124. }\
  125. ";
  126. var dom = require("../lib/dom");
  127. dom.importCssString(exports.cssText, exports.cssClass);
  128. });
  129. ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"], function(require, exports, module) {
  130. "use strict";
  131. require("./lib/fixoldbrowsers");
  132. var dom = require("./lib/dom");
  133. var event = require("./lib/event");
  134. var Editor = require("./editor").Editor;
  135. var EditSession = require("./edit_session").EditSession;
  136. var UndoManager = require("./undomanager").UndoManager;
  137. var Renderer = require("./virtual_renderer").VirtualRenderer;
  138. require("./worker/worker_client");
  139. require("./keyboard/hash_handler");
  140. require("./placeholder");
  141. require("./multi_select");
  142. require("./mode/folding/fold_mode");
  143. require("./theme/textmate");
  144. require("./ext/error_marker");
  145. exports.config = require("./config");
  146. exports.require = require;
  147. exports.edit = function(el) {
  148. if (typeof(el) == "string") {
  149. var _id = el;
  150. el = document.getElementById(_id);
  151. if (!el)
  152. throw new Error("ace.edit can't find div #" + _id);
  153. }
  154. if (el && el.env && el.env.editor instanceof Editor)
  155. return el.env.editor;
  156. var value = "";
  157. if (el && /input|textarea/i.test(el.tagName)) {
  158. var oldNode = el;
  159. value = oldNode.value;
  160. el = dom.createElement("pre");
  161. oldNode.parentNode.replaceChild(el, oldNode);
  162. } else {
  163. value = dom.getInnerText(el);
  164. el.innerHTML = '';
  165. }
  166. var doc = exports.createEditSession(value);
  167. var editor = new Editor(new Renderer(el));
  168. editor.setSession(doc);
  169. var env = {
  170. document: doc,
  171. editor: editor,
  172. onResize: editor.resize.bind(editor, null)
  173. };
  174. if (oldNode) env.textarea = oldNode;
  175. event.addListener(window, "resize", env.onResize);
  176. editor.on("destroy", function() {
  177. event.removeListener(window, "resize", env.onResize);
  178. env.editor.container.env = null; // prevent memory leak on old ie
  179. });
  180. editor.container.env = editor.env = env;
  181. return editor;
  182. };
  183. exports.createEditSession = function(text, mode) {
  184. var doc = new EditSession(text, mode);
  185. doc.setUndoManager(new UndoManager());
  186. return doc;
  187. }
  188. exports.EditSession = EditSession;
  189. exports.UndoManager = UndoManager;
  190. });
  191. ace.define("ace/ext/textarea",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/net","ace/ace","ace/theme/textmate"], function(require, exports, module) {
  192. "use strict";
  193. var event = require("../lib/event");
  194. var UA = require("../lib/useragent");
  195. var net = require("../lib/net");
  196. var ace = require("../ace");
  197. require("../theme/textmate");
  198. module.exports = exports = ace;
  199. var getCSSProperty = function(element, container, property) {
  200. var ret = element.style[property];
  201. if (!ret) {
  202. if (window.getComputedStyle) {
  203. ret = window.getComputedStyle(element, '').getPropertyValue(property);
  204. } else {
  205. ret = element.currentStyle[property];
  206. }
  207. }
  208. if (!ret || ret == 'auto' || ret == 'intrinsic') {
  209. ret = container.style[property];
  210. }
  211. return ret;
  212. };
  213. function applyStyles(elm, styles) {
  214. for (var style in styles) {
  215. elm.style[style] = styles[style];
  216. }
  217. }
  218. function setupContainer(element, getValue) {
  219. if (element.type != 'textarea') {
  220. throw new Error("Textarea required!");
  221. }
  222. var parentNode = element.parentNode;
  223. var container = document.createElement('div');
  224. var resizeEvent = function() {
  225. var style = 'position:relative;';
  226. [
  227. 'margin-top', 'margin-left', 'margin-right', 'margin-bottom'
  228. ].forEach(function(item) {
  229. style += item + ':' +
  230. getCSSProperty(element, container, item) + ';';
  231. });
  232. var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px");
  233. var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px");
  234. style += 'height:' + height + ';width:' + width + ';';
  235. style += 'display:inline-block;';
  236. container.setAttribute('style', style);
  237. };
  238. event.addListener(window, 'resize', resizeEvent);
  239. resizeEvent();
  240. parentNode.insertBefore(container, element.nextSibling);
  241. while (parentNode !== document) {
  242. if (parentNode.tagName.toUpperCase() === 'FORM') {
  243. var oldSumit = parentNode.onsubmit;
  244. parentNode.onsubmit = function(evt) {
  245. element.value = getValue();
  246. if (oldSumit) {
  247. oldSumit.call(this, evt);
  248. }
  249. };
  250. break;
  251. }
  252. parentNode = parentNode.parentNode;
  253. }
  254. return container;
  255. }
  256. exports.transformTextarea = function(element, options) {
  257. var session;
  258. var container = setupContainer(element, function() {
  259. return session.getValue();
  260. });
  261. element.style.display = 'none';
  262. container.style.background = 'white';
  263. var editorDiv = document.createElement("div");
  264. applyStyles(editorDiv, {
  265. top: "0px",
  266. left: "0px",
  267. right: "0px",
  268. bottom: "0px",
  269. border: "1px solid gray",
  270. position: "absolute"
  271. });
  272. container.appendChild(editorDiv);
  273. var settingOpener = document.createElement("div");
  274. applyStyles(settingOpener, {
  275. position: "absolute",
  276. right: "0px",
  277. bottom: "0px",
  278. background: "red",
  279. cursor: "nw-resize",
  280. borderStyle: "solid",
  281. borderWidth: "9px 8px 10px 9px",
  282. width: "2px",
  283. borderColor: "lightblue gray gray lightblue",
  284. zIndex: 101
  285. });
  286. var settingDiv = document.createElement("div");
  287. var settingDivStyles = {
  288. top: "0px",
  289. left: "20%",
  290. right: "0px",
  291. bottom: "0px",
  292. position: "absolute",
  293. padding: "5px",
  294. zIndex: 100,
  295. color: "white",
  296. display: "none",
  297. overflow: "auto",
  298. fontSize: "14px",
  299. boxShadow: "-5px 2px 3px gray"
  300. };
  301. if (!UA.isOldIE) {
  302. settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)";
  303. } else {
  304. settingDivStyles.backgroundColor = "#333";
  305. }
  306. applyStyles(settingDiv, settingDivStyles);
  307. container.appendChild(settingDiv);
  308. options = options || exports.defaultOptions;
  309. var editor = ace.edit(editorDiv);
  310. session = editor.getSession();
  311. session.setValue(element.value || element.innerHTML);
  312. editor.focus();
  313. container.appendChild(settingOpener);
  314. setupApi(editor, editorDiv, settingDiv, ace, options, load);
  315. setupSettingPanel(settingDiv, settingOpener, editor);
  316. var state = "";
  317. event.addListener(settingOpener, "mousemove", function(e) {
  318. var rect = this.getBoundingClientRect();
  319. var x = e.clientX - rect.left, y = e.clientY - rect.top;
  320. if (x + y < (rect.width + rect.height)/2) {
  321. this.style.cursor = "pointer";
  322. state = "toggle";
  323. } else {
  324. state = "resize";
  325. this.style.cursor = "nw-resize";
  326. }
  327. });
  328. event.addListener(settingOpener, "mousedown", function(e) {
  329. if (state == "toggle") {
  330. editor.setDisplaySettings();
  331. return;
  332. }
  333. container.style.zIndex = 100000;
  334. var rect = container.getBoundingClientRect();
  335. var startX = rect.width + rect.left - e.clientX;
  336. var startY = rect.height + rect.top - e.clientY;
  337. event.capture(settingOpener, function(e) {
  338. container.style.width = e.clientX - rect.left + startX + "px";
  339. container.style.height = e.clientY - rect.top + startY + "px";
  340. editor.resize();
  341. }, function() {});
  342. });
  343. return editor;
  344. };
  345. function load(url, module, callback) {
  346. net.loadScript(url, function() {
  347. require([module], callback);
  348. });
  349. }
  350. function setupApi(editor, editorDiv, settingDiv, ace, options, loader) {
  351. var session = editor.getSession();
  352. var renderer = editor.renderer;
  353. loader = loader || load;
  354. function toBool(value) {
  355. return value === "true" || value == true;
  356. }
  357. editor.setDisplaySettings = function(display) {
  358. if (display == null)
  359. display = settingDiv.style.display == "none";
  360. if (display) {
  361. settingDiv.style.display = "block";
  362. settingDiv.hideButton.focus();
  363. editor.on("focus", function onFocus() {
  364. editor.removeListener("focus", onFocus);
  365. settingDiv.style.display = "none";
  366. });
  367. } else {
  368. editor.focus();
  369. }
  370. };
  371. editor.$setOption = editor.setOption;
  372. editor.$getOption = editor.getOption;
  373. editor.setOption = function(key, value) {
  374. switch (key) {
  375. case "mode":
  376. editor.$setOption("mode", "ace/mode/" + value)
  377. break;
  378. case "theme":
  379. editor.$setOption("theme", "ace/theme/" + value)
  380. break;
  381. case "keybindings":
  382. switch (value) {
  383. case "vim":
  384. editor.setKeyboardHandler("ace/keyboard/vim");
  385. break;
  386. case "emacs":
  387. editor.setKeyboardHandler("ace/keyboard/emacs");
  388. break;
  389. default:
  390. editor.setKeyboardHandler(null);
  391. }
  392. break;
  393. case "softWrap":
  394. case "fontSize":
  395. editor.$setOption(key, value);
  396. break;
  397. default:
  398. editor.$setOption(key, toBool(value));
  399. }
  400. };
  401. editor.getOption = function(key) {
  402. switch (key) {
  403. case "mode":
  404. return editor.$getOption("mode").substr("ace/mode/".length)
  405. break;
  406. case "theme":
  407. return editor.$getOption("theme").substr("ace/theme/".length)
  408. break;
  409. case "keybindings":
  410. var value = editor.getKeyboardHandler()
  411. switch (value && value.$id) {
  412. case "ace/keyboard/vim":
  413. return "vim";
  414. case "ace/keyboard/emacs":
  415. return "emacs";
  416. default:
  417. return "ace";
  418. }
  419. break;
  420. default:
  421. return editor.$getOption(key);
  422. }
  423. };
  424. editor.setOptions(options);
  425. return editor;
  426. }
  427. function setupSettingPanel(settingDiv, settingOpener, editor) {
  428. var BOOL = null;
  429. var desc = {
  430. mode: "Mode:",
  431. wrap: "Soft Wrap:",
  432. theme: "Theme:",
  433. fontSize: "Font Size:",
  434. showGutter: "Display Gutter:",
  435. keybindings: "Keyboard",
  436. showPrintMargin: "Show Print Margin:",
  437. useSoftTabs: "Use Soft Tabs:",
  438. showInvisibles: "Show Invisibles"
  439. };
  440. var optionValues = {
  441. mode: {
  442. text: "Plain",
  443. javascript: "JavaScript",
  444. xml: "XML",
  445. html: "HTML",
  446. css: "CSS",
  447. scss: "SCSS",
  448. python: "Python",
  449. php: "PHP",
  450. java: "Java",
  451. ruby: "Ruby",
  452. c_cpp: "C/C++",
  453. coffee: "CoffeeScript",
  454. json: "json",
  455. perl: "Perl",
  456. clojure: "Clojure",
  457. ocaml: "OCaml",
  458. csharp: "C#",
  459. haxe: "haXe",
  460. svg: "SVG",
  461. textile: "Textile",
  462. groovy: "Groovy",
  463. liquid: "Liquid",
  464. Scala: "Scala"
  465. },
  466. theme: {
  467. clouds: "Clouds",
  468. clouds_midnight: "Clouds Midnight",
  469. cobalt: "Cobalt",
  470. crimson_editor: "Crimson Editor",
  471. dawn: "Dawn",
  472. eclipse: "Eclipse",
  473. idle_fingers: "Idle Fingers",
  474. kr_theme: "Kr Theme",
  475. merbivore: "Merbivore",
  476. merbivore_soft: "Merbivore Soft",
  477. mono_industrial: "Mono Industrial",
  478. monokai: "Monokai",
  479. pastel_on_dark: "Pastel On Dark",
  480. solarized_dark: "Solarized Dark",
  481. solarized_light: "Solarized Light",
  482. textmate: "Textmate",
  483. twilight: "Twilight",
  484. vibrant_ink: "Vibrant Ink"
  485. },
  486. showGutter: BOOL,
  487. fontSize: {
  488. "10px": "10px",
  489. "11px": "11px",
  490. "12px": "12px",
  491. "14px": "14px",
  492. "16px": "16px"
  493. },
  494. wrap: {
  495. off: "Off",
  496. 40: "40",
  497. 80: "80",
  498. free: "Free"
  499. },
  500. keybindings: {
  501. ace: "ace",
  502. vim: "vim",
  503. emacs: "emacs"
  504. },
  505. showPrintMargin: BOOL,
  506. useSoftTabs: BOOL,
  507. showInvisibles: BOOL
  508. };
  509. var table = [];
  510. table.push("<table><tr><th>Setting</th><th>Value</th></tr>");
  511. function renderOption(builder, option, obj, cValue) {
  512. if (!obj) {
  513. builder.push(
  514. "<input type='checkbox' title='", option, "' ",
  515. cValue + "" == "true" ? "checked='true'" : "",
  516. "'></input>"
  517. );
  518. return;
  519. }
  520. builder.push("<select title='" + option + "'>");
  521. for (var value in obj) {
  522. builder.push("<option value='" + value + "' ");
  523. if (cValue == value) {
  524. builder.push(" selected ");
  525. }
  526. builder.push(">",
  527. obj[value],
  528. "</option>");
  529. }
  530. builder.push("</select>");
  531. }
  532. for (var option in exports.defaultOptions) {
  533. table.push("<tr><td>", desc[option], "</td>");
  534. table.push("<td>");
  535. renderOption(table, option, optionValues[option], editor.getOption(option));
  536. table.push("</td></tr>");
  537. }
  538. table.push("</table>");
  539. settingDiv.innerHTML = table.join("");
  540. var onChange = function(e) {
  541. var select = e.currentTarget;
  542. editor.setOption(select.title, select.value);
  543. };
  544. var onClick = function(e) {
  545. var cb = e.currentTarget;
  546. editor.setOption(cb.title, cb.checked);
  547. };
  548. var selects = settingDiv.getElementsByTagName("select");
  549. for (var i = 0; i < selects.length; i++)
  550. selects[i].onchange = onChange;
  551. var cbs = settingDiv.getElementsByTagName("input");
  552. for (var i = 0; i < cbs.length; i++)
  553. cbs[i].onclick = onClick;
  554. var button = document.createElement("input");
  555. button.type = "button";
  556. button.value = "Hide";
  557. event.addListener(button, "click", function() {
  558. editor.setDisplaySettings(false);
  559. });
  560. settingDiv.appendChild(button);
  561. settingDiv.hideButton = button;
  562. }
  563. exports.defaultOptions = {
  564. mode: "javascript",
  565. theme: "textmate",
  566. wrap: "off",
  567. fontSize: "12px",
  568. showGutter: "false",
  569. keybindings: "ace",
  570. showPrintMargin: "false",
  571. useSoftTabs: "true",
  572. showInvisibles: "false"
  573. };
  574. });
  575. (function() {
  576. ace.require(["ace/ext/textarea"], function() {});
  577. })();