Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

266 linhas
9.8 KiB

  1. // Options
  2. // parent
  3. // change (event)
  4. // Properties
  5. // set_input
  6. // input
  7. wn.provide("wn.editors");
  8. wn.editors.BootstrapWYSIWYG = Class.extend({
  9. init: function(opts) {
  10. wn.require("lib/js/lib/jquery/jquery.hotkeys.js");
  11. wn.require("lib/js/lib/bootstrap-wysiwyg.js");
  12. this.opts = opts;
  13. this.make_body();
  14. this.make_bindings();
  15. },
  16. make_body: function() {
  17. var me = this;
  18. this.myid = "editor-" + wn.dom.set_unique_id();
  19. $('<div class="for-rich-text">\
  20. <div class="btn-toolbar" data-role="editor-toolbar" style="margin-bottom: 7px;"\
  21. data-target="#'+ this.myid +'">\
  22. <div class="btn-group hidden-sm">\
  23. <a class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown" title="Font"><i class="icon-font"></i><b class="caret"></b></a>\
  24. <ul class="dropdown-menu"></ul>\
  25. </div>\
  26. <div class="btn-group">\
  27. <a class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown" title="Font Size"><i class="icon-text-height"></i> <b class="caret"></b></a>\
  28. <ul class="dropdown-menu">\
  29. <li><a data-edit="formatBlock &lt;p&gt;"><p>Paragraph</p></a></li>\
  30. <li><a data-edit="formatBlock &lt;h1&gt;"><h1>Heading 1</h1></a></li>\
  31. <li><a data-edit="formatBlock &lt;h2&gt;"><h2>Heading 2</h2></a></li>\
  32. <li><a data-edit="formatBlock &lt;h3&gt;"><h3>Heading 3</h3></a></li>\
  33. <li><a data-edit="formatBlock &lt;h4&gt;"><h4>Heading 4</h4></a></li>\
  34. <li><a data-edit="formatBlock &lt;h5&gt;"><h5>Heading 5</h5></a></li>\
  35. </ul>\
  36. </div>\
  37. <div class="btn-group">\
  38. <a class="btn btn-default btn-small" data-edit="bold" title="Bold (Ctrl/Cmd+B)"><i class="icon-bold"></i></a>\
  39. <a class="btn btn-default btn-small" data-edit="italic" title="Italic (Ctrl/Cmd+I)"><i class="icon-italic"></i></a>\
  40. <a class="btn btn-default btn-small" data-edit="underline" title="Underline (Ctrl/Cmd+U)"><i class="icon-underline"></i></a>\
  41. </div>\
  42. <div class="btn-group">\
  43. <a class="btn btn-default btn-small" data-edit="insertunorderedlist" title="Bullet list"><i class="icon-list-ul"></i></a>\
  44. <a class="btn btn-default btn-small" data-edit="insertorderedlist" title="Number list"><i class="icon-list-ol"></i></a>\
  45. <a class="btn btn-default btn-small" data-edit="outdent" title="Reduce indent (Shift+Tab)"><i class="icon-indent-left"></i></a>\
  46. <a class="btn btn-default btn-small" data-edit="indent" title="Indent (Tab)"><i class="icon-indent-right"></i></a>\
  47. </div>\
  48. <div class="btn-group hidden-sm">\
  49. <a class="btn btn-default btn-small" data-edit="justifyleft" title="Align Left (Ctrl/Cmd+L)"><i class="icon-align-left"></i></a>\
  50. <a class="btn btn-default btn-small" data-edit="justifycenter" title="Center (Ctrl/Cmd+E)"><i class="icon-align-center"></i></a>\
  51. </div>\
  52. <div class="btn-group hidden-sm">\
  53. <a class="btn btn-default btn-small btn-add-link" title="Insert Link">\
  54. <i class="icon-link"></i></a>\
  55. <a class="btn btn-default btn-small" title="Remove Link" data-edit="unlink">\
  56. <i class="icon-unlink"></i></a>\
  57. <a class="btn btn-default btn-small" title="Insert picture (or just drag & drop)" id="pictureBtn-'+this.myid+'"><i class="icon-picture"></i></a>\
  58. <input type="file" data-role="magic-overlay" data-target="#pictureBtn-'+this.myid+'" data-edit="insertImage" />\
  59. <a class="btn btn-default btn-small" data-edit="insertHorizontalRule" title="Horizontal Line Break">-</a>\
  60. </div>\
  61. </div>\
  62. <div id="'+this.myid+'" class="wysiwyg-editor">\
  63. </div>\
  64. </div>\
  65. <div class="for-html" style="display:none">\
  66. <textarea class="html-editor" style="width:95%; height: 440px;\
  67. font-family: Monaco, Menlo, Consolas, Courier, monospace;\
  68. font-size: 11px;"></textarea>\
  69. </div>\
  70. <div class="btn-toolbar pull-right" style="margin-top: 7px;">\
  71. <div class="btn-group">\
  72. <a class="btn btn-default btn-small btn-info btn-rich-text" title="Rich Text" disabled="disabled"><i class="icon-reorder"></i></a>\
  73. <a class="btn btn-default btn-small btn-html" title="HTML"><i class="icon-wrench"></i></a>\
  74. </div>\
  75. </div><div class="clearfix"></div>').appendTo(this.opts.parent);
  76. this.$parent = $(this.opts.parent);
  77. this.$editor = $("#" + this.myid);
  78. this.$parent.find(".btn-add-link").click(function() {
  79. me.show_link_dialog();
  80. return false;
  81. })
  82. this.$editor.on("keyup", function() { me.save_selection() });
  83. this.$editor.on("mouseup", function() { me.save_selection() });
  84. this.$textarea = this.$parent.find(".html-editor");
  85. this.input = this.$editor.get(0);
  86. },
  87. set_focus: function() {
  88. this.$editor.focus();
  89. },
  90. save_selection: function() {
  91. this.saved_selection = wn.dom.save_selection();
  92. },
  93. show_link_dialog: function() {
  94. var me = this;
  95. var d = new wn.ui.Dialog({
  96. title: "Add Link",
  97. fields: [
  98. {fieldtype: "Data", label:"Link", fieldname: "link", reqd: 1,
  99. description:"example: http://example.com"},
  100. {fieldtype: "Button", label:"Add", fieldname: "add"},
  101. ]
  102. });
  103. d.show();
  104. d.fields_dict.link.set_input("http://");
  105. $(d.fields_dict.add.input).click(function() {
  106. var values = d.get_values();
  107. if(values) {
  108. d.hide();
  109. wn.dom.restore_selection(me.saved_selection);
  110. document.execCommand("CreateLink", false, values.link);
  111. }
  112. });
  113. d.onhide = function() {
  114. wn.dom.restore_selection(me.saved_selection);
  115. }
  116. },
  117. make_bindings: function() {
  118. var me = this;
  119. var fonts = ['Serif', 'Sans', 'Arial', 'Arial Black', 'Courier',
  120. 'Courier New', 'Comic Sans MS', 'Helvetica', 'Impact', 'Lucida Grande',
  121. 'Lucida Sans', 'Tahoma', 'Times', 'Times New Roman', 'Verdana'],
  122. fontTarget = this.$parent.find('[title=Font]').siblings('.dropdown-menu');
  123. $.each(fonts, function (idx, fontName) {
  124. fontTarget.append($('<li><a data-edit="fontName ' +
  125. fontName +'" style="font-family:\''+ fontName +'\'">'+
  126. fontName + '</a></li>'));
  127. });
  128. // magic-overlay
  129. this.$parent.find('[data-role=magic-overlay]').each(function () {
  130. var overlay = $(this), target = $(overlay.data('target'));
  131. overlay.css('opacity', 0).css('position', 'absolute')
  132. .offset(target.offset())
  133. .width(40).height(30);
  134. });
  135. this.$editor
  136. .wysiwyg()
  137. .on("mouseup keyup mouseout", function() {
  138. var value = $(this).html();
  139. if(value==null) value="";
  140. me.opts.change(value);
  141. })
  142. this.$textarea
  143. .on("change", function() {
  144. var value = $(this).val();
  145. if(value==null) value="";
  146. me.opts.change(value);
  147. });
  148. this.current_editor = this.$editor;
  149. this.$parent.find(".btn-html").click(function() {
  150. if($(this).attr("disabled")=="disabled") return;
  151. wn.require("lib/js/lib/beautify-html.js");
  152. me.$textarea.val(html_beautify(me.$editor.cleanHtml()));
  153. me.$parent.find(".for-rich-text").toggle(false);
  154. me.$parent.find(".for-html").toggle(true);
  155. me.$parent.find(".btn-html").addClass("btn-info").attr("disabled", "disabled");
  156. me.$parent.find(".btn-rich-text").removeClass("btn-info").attr("disabled", false);
  157. me.current_editor = me.$textarea;
  158. });
  159. this.$parent.find(".btn-rich-text").click(function() {
  160. if($(this).attr("disabled")=="disabled") return;
  161. me.$editor.html(me.$textarea.val());
  162. me.$parent.find(".for-rich-text").toggle(true);
  163. me.$parent.find(".for-html").toggle(false);
  164. me.$parent.find(".btn-html").removeClass("btn-info").attr("disabled", false);
  165. me.$parent.find(".btn-rich-text").addClass("btn-info").attr("disabled", "disabled");
  166. me.current_editor = me.$editor;
  167. });
  168. },
  169. set_input: function(value) {
  170. if(this.opts.field.inside_change_event)
  171. return;
  172. if(this.value!=value) {
  173. this.value = value==null ? "" : value;
  174. this.$editor.html(this.value);
  175. this.$textarea.val(this.value);
  176. }
  177. },
  178. get_value: function() {
  179. if(this.current_editor==this.$editor)
  180. return this.$editor.cleanHtml();
  181. else
  182. return this.$textarea.val();
  183. }
  184. })
  185. wn.editors.ACE = Class.extend({
  186. init: function(opts) {
  187. this.opts = opts;
  188. // setup ace
  189. wn.require('lib/js/lib/ace/ace.js');
  190. this.make();
  191. this.bind_form_load();
  192. },
  193. make: function() {
  194. $(this.opts.parent).css('border','1px solid #aaa');
  195. this.pre = $("<pre style='position: relative; height: 400px; \
  196. width: 100%; padding: 0px; border-radius: 0px;\
  197. margin: 0px; background-color: #fff;'>").appendTo(this.opts.parent).get(0);
  198. this.input = {};
  199. this.myid = wn.dom.set_unique_id(this.pre);
  200. this.editor = ace.edit(this.myid);
  201. if(this.opts.field.df.options=='Markdown' || this.opts.field.df.options=='HTML') {
  202. wn.require('lib/js/lib/ace/mode-html.js');
  203. var HTMLMode = require("ace/mode/html").Mode;
  204. this.editor.getSession().setMode(new HTMLMode());
  205. }
  206. else if(this.opts.field.df.options=='Javascript') {
  207. wn.require('lib/js/lib/ace/mode-javascript.js');
  208. var JavascriptMode = require("ace/mode/javascript").Mode;
  209. this.editor.getSession().setMode(new JavascriptMode());
  210. }
  211. else if(this.opts.field.df.options=='Python') {
  212. wn.require('lib/js/lib/ace/mode-python.js');
  213. var PythonMode = require("ace/mode/python").Mode;
  214. this.editor.getSession().setMode(new PythonMode());
  215. }
  216. },
  217. set_input: function(value) {
  218. // during field refresh in run trigger, set_input is called
  219. // if called during on_change, setting doesn't make sense
  220. // and causes cursor to shift back to first position
  221. if(this.opts.field.inside_change_event) return;
  222. this.setting_value = true;
  223. this.editor.getSession().setValue(value==null ? "" : value);
  224. this.setting_value = false;
  225. },
  226. get_value: function() {
  227. return this.editor.getSession().getValue();
  228. },
  229. set_focus: function() {
  230. this.editor.focus();
  231. },
  232. bind_form_load: function() {
  233. var me = this;
  234. if(cur_frm) {
  235. $(cur_frm.wrapper).bind('render_complete', function() {
  236. me.editor.resize();
  237. me.editor.getSession().on('change', function() {
  238. if(me.setting_value) return;
  239. me.opts.change(me.get_value())
  240. })
  241. });
  242. }
  243. },
  244. set_focus: function() {
  245. this.$editor.focus();
  246. },
  247. })