richtextbox.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /**
  2. * @fileoverview
  3. * 직접 편집이 가능한 기능을 포함한 Tool '글상자' Source,
  4. * Class Trex.Tool.RichTextBox 와 configuration을 포함
  5. *
  6. */
  7. TrexConfig.addTool(
  8. "richtextbox",
  9. {
  10. sync: _FALSE,
  11. status: _TRUE,
  12. rows: 4,
  13. cols: 6,
  14. borderwidth: 1,
  15. bordercolor: '#cbcbcb',
  16. bgcolor: '#ffffff',
  17. padding: "10px",
  18. styles: [
  19. { klass: "", image: "#iconpath/textbox/thum_line01.gif?v=2", data: "solid" },
  20. { klass: "", image: "#iconpath/textbox/thum_line02.gif?v=2", data: "double" },
  21. { klass: "", image: "#iconpath/textbox/thum_line03.gif?v=2", data: "dashed" },
  22. { klass: "", image: "#iconpath/textbox/thum_line04.gif?v=2", data: "none" }
  23. ],
  24. options: Trex.__CONFIG_COMMON.textbox.options,
  25. thumbs: Trex.__CONFIG_COMMON.thumbs
  26. }
  27. );
  28. TrexMessage.addMsg({
  29. '@richtextbox.add': "더하기",
  30. '@richtextbox.sub': "빼기",
  31. '@richtextbox.alert': "1 이상 20 이하의 숫자만 입력 가능합니다.",
  32. '@richtextbox.bg.color': "배경색",
  33. '@richtextbox.border.color': "선 색",
  34. '@richtextbox.border.style': "선 스타일",
  35. '@richtextbox.border.width': "선 굵기"
  36. });
  37. Trex.Tool.RichTextBox = Trex.Class.create({
  38. $const: {
  39. __Identity: 'richtextbox'
  40. },
  41. $extend: Trex.Tool,
  42. oninitialized: function() {
  43. var _canvas = this.canvas;
  44. var _toolbar = this.toolbar;
  45. var _tool = this;
  46. var _toolHandler = this.handler = function() {
  47. var _this = _tool.menu;
  48. var _style = {
  49. "borderStyle": _this.elPreview.style.borderStyle,
  50. "borderWidth": _this.elPreview.style.borderWidth,
  51. "borderColor": _this.elPreview.style.borderColor,
  52. "backgroundColor": _this.elPreview.style.backgroundColor,
  53. "padding": _this.padding
  54. };
  55. var _tag = "div";
  56. var _attributes = { "className": 'txc-textbox', style: _style };
  57. _canvas.execute(function(processor) {
  58. var _nodes = processor.blocks(function() {
  59. return '%wrapper,%paragraph';
  60. });
  61. var _bNode;
  62. _nodes = _nodes.findAll(function(node) {
  63. if($tom.kindOf(node, "%innergroup")) {
  64. _bNode = processor.wrap($tom.children(node), _tag, _attributes);
  65. _toolbar.fireJobs('cmd.textbox.added', _bNode);
  66. return _FALSE;
  67. } else {
  68. return _TRUE;
  69. }
  70. });
  71. _bNode = processor.wrap(_nodes, _tag, _attributes);
  72. _toolbar.fireJobs('cmd.textbox.added', _bNode);
  73. });
  74. };
  75. /* button & menu weave */
  76. this.weave.bind(this)(
  77. /* button */
  78. new Trex.Button(this.buttonCfg),
  79. /* menu */
  80. new Trex.Menu.RichTextbox(this.menuCfg),
  81. /* handler */
  82. _toolHandler
  83. );
  84. }
  85. });
  86. Trex.MarkupTemplate.add(
  87. 'richtextbox.colorpallete',
  88. ['<dd class="#{wrapClass}">',
  89. ' <div class="tx-color-box">',
  90. ' <a href="javascript:;" class="tx-color-bg-thumb" style="background-color:#{color}"></a>', //==> _elThumb
  91. ' </div>',
  92. ' <a href="javascript:;" class="tx-color-arrow-down"></a>',
  93. ' <div class="tx-colorpallete" unselectable="on" style="display:none;z-index:15000;"></div>',
  94. '</dd>'].join("")
  95. );
  96. Trex.Menu.RichTextbox = Trex.Class.create({
  97. $extend: Trex.Menu,
  98. ongenerated: function(config) {
  99. var _this = this;
  100. var _styleHashMap = {};
  101. config.options.each(function(option) {
  102. _styleHashMap[option.data] = option.style;
  103. });
  104. this.borderWidth = config.borderWidth || 1;
  105. this.borderColor = config.borderColor || '#cbcbcb';
  106. this.bgColor = config.bgColor || '#ffffff';
  107. this.padding = config.padding;
  108. var _generateBorderStyle = this.generateBorderStyle.bind(this);
  109. var _generateBorderWidth = this.generateBorderWidth.bind(this);
  110. var _generateBorderColor = this.generateBorderColor.bind(this);
  111. var _generateBgColor = this.generateBgColor.bind(this);
  112. var _elMenu = this.elMenu;
  113. var _elHeader = $tom.collect(_elMenu, 'div.tx-menu-header');
  114. var _elPreviewArea = $tom.collect(_elHeader, 'div.tx-menu-preview-area');
  115. this.elPreview = $tom.collect(_elPreviewArea, 'div.tx-menu-preview');
  116. var _elSwitch = this.elSwitch = $tom.collect(_elHeader, 'div.tx-menu-switch');
  117. var _elSimple = $tom.collect(_elSwitch, 'div.tx-menu-simple');
  118. var _elAdvanced = $tom.collect(_elSwitch, 'div.tx-menu-advanced');
  119. var _elInner = $tom.collect(_elMenu, 'div.tx-menu-inner');
  120. var _elFooter = $tom.collect(_elMenu, 'div.tx-menu-footer');
  121. var _elConfirm = $tom.collect(_elFooter, 'img.tx-menu-confirm');
  122. var _elCancel = $tom.collect(_elFooter, 'img.tx-menu-cancel');
  123. (function create_thumbs_for_simplemode(){
  124. var _el = _this.simplePalette= tx.div({ className: 'tx-menu-list'});
  125. _elInner.appendChild(_el);
  126. var _rows = config.rows;
  127. var _cols = config.cols;
  128. _el.innerHTML = Trex.HtmlCreator.createTableMarkup(_rows, _cols, config.options);
  129. $tx.observe(_el, 'click', function(ev){
  130. var _el = $tx.element(ev);
  131. TrexEvent.fire(_el, {
  132. 'span': function(){
  133. var _class;
  134. if(_el.firstChild && _el.firstChild.nodeType == 1 && _el.firstChild.tagName.toLowerCase() == 'img') {
  135. _class = _el.firstChild.title;
  136. } else {
  137. _class = _el.innerText;
  138. }
  139. var _style = _styleHashMap[_class];
  140. applyPreviewStyle(_style);
  141. }
  142. });
  143. $tx.stop(ev);
  144. });
  145. })();
  146. (function createElementsInInnerContainerForAdvancedMode(){
  147. var _el = _this.advancedPalette = tx.div({ className: "tx-advanced-list" });
  148. _elInner.appendChild(_el);
  149. _el.appendChild(
  150. tx.dl({
  151. style: {
  152. "height": "24px"
  153. }
  154. },
  155. tx.dt(TXMSG("@richtextbox.border.style")), _generateBorderStyle()));
  156. _el.appendChild(tx.dl(tx.dt(TXMSG("@richtextbox.border.width")), _generateBorderWidth()));
  157. _el.appendChild(tx.dl(tx.dt(TXMSG("@richtextbox.border.color")), _generateBorderColor()));
  158. _el.appendChild(tx.dl(tx.dt(TXMSG("@richtextbox.bg.color")), _generateBgColor()));
  159. })();
  160. var copyStyles = function(){
  161. _this.borderWidthInput.value = parseInt(_this.elPreview.style.borderWidth);
  162. _this.borderColorInput.style.backgroundColor = _this.elPreview.style.borderTopColor;
  163. _this.bgColorInput.style.backgroundColor = _this.elPreview.style.backgroundColor;
  164. };
  165. var applyPreviewStyle = function (style){
  166. _this.elPreview.style.border = style['border'];
  167. _this.elPreview.style.backgroundColor = style['backgroundColor']
  168. };
  169. var selectMode = function(mode){
  170. if(mode =="simple"){
  171. $tx.addClassName(_elSimple, "tx-selected");
  172. $tx.show(_this.simplePalette);
  173. $tx.removeClassName(_elAdvanced, "tx-selected");
  174. $tx.hide(_this.advancedPalette);
  175. }else if(mode =="advanced"){
  176. $tx.removeClassName(_elSimple, "tx-selected");
  177. $tx.hide(_this.simplePalette);
  178. $tx.addClassName(_elAdvanced, "tx-selected");
  179. $tx.show(_this.advancedPalette);
  180. copyStyles();
  181. }
  182. _this.fireJobs(Trex.Ev.__MENU_LAYER_CHANGE_SIZE, {
  183. detail: {
  184. menu: _this
  185. }
  186. });
  187. };
  188. (function bindingEvents(){
  189. $tx.observe(_elSimple, 'click', selectMode.bind(_this, "simple") );
  190. $tx.observe(_elAdvanced, 'click', selectMode.bind(_this, "advanced") );
  191. $tx.observe(_elConfirm, 'click', _this.onSelect.bind(_this));
  192. $tx.observe(_elCancel, 'click', function(){
  193. _this.onCancel();
  194. });
  195. })();
  196. selectMode("simple");
  197. applyPreviewStyle(_styleHashMap['txc-textbox13']);
  198. },
  199. generateBorderStyle: function(){
  200. var _this = this;
  201. var _elWrap = tx.dd({ className: 'tx-border-area' });
  202. $tx.observe(_elWrap, 'click', function(ev) {
  203. var _el = $tx.element(ev);
  204. TrexEvent.fire(_el, {
  205. 'img': function(element){
  206. var _data = element.getAttribute("data");
  207. _this.elPreview.style.borderStyle = _data;
  208. if(_data == 'double' && _this.borderWidthInput.value.toNumber() < 3){
  209. _this.elPreview.style.borderWidth = "3px";
  210. _this.borderWidthInput.value = "3";
  211. }
  212. }
  213. });
  214. $tx.stop(ev);
  215. });
  216. _elWrap.innerHTML = Trex.HtmlCreator.createTableMarkup(1, 4, this.config.styles);
  217. return _elWrap;
  218. },
  219. generateBorderWidth: function() {
  220. var _this = this;
  221. var _elWrap = tx.dd({ className: 'tx-border-area' });
  222. var _elInput = this.borderWidthInput = tx.input({ type: 'text', value: this.borderWidth });
  223. _elWrap.appendChild(_elInput);
  224. var _drawDeco = function(width) {
  225. if(width > 20 ) {
  226. alert(TXMSG("@richtextbox.alert"));
  227. _elInput.value = 20;
  228. }else if(width < 1){
  229. alert(TXMSG("@richtextbox.alert"));
  230. _elInput.value = 1;
  231. }else{
  232. _this.elPreview.style.borderWidth = width + "px";
  233. _elInput.value = width;
  234. }
  235. };
  236. $tx.observe(_elInput, 'blur', function(ev) {
  237. _drawDeco(_elInput.value.toNumber(), ev);
  238. });
  239. $tx.observe( _elInput, "keydown", function(ev){
  240. if( ev.keyCode == $tx.KEY_RETURN )
  241. $tx.stop(ev);
  242. });
  243. var _elAddBtn = tx.a({ href:'javascript:;', className: 'btn_add' }, TXMSG("@richtextbox.add"));
  244. _elWrap.appendChild(_elAddBtn);
  245. $tx.observe(_elAddBtn, 'click', function(ev) {
  246. _drawDeco(_elInput.value.toNumber() + 1);
  247. $tx.stop(ev);
  248. });
  249. var _elSubBtn = tx.a({ href:'javascript:;', className: 'btn_sub' }, TXMSG("@richtextbox.sub"));
  250. _elWrap.appendChild(_elSubBtn);
  251. $tx.observe(_elSubBtn, 'click', function(ev) {
  252. _drawDeco(_elInput.value.toNumber() - 1);
  253. $tx.stop(ev);
  254. });
  255. return _elWrap;
  256. },
  257. generateBorderColor: function() {
  258. var _this = this;
  259. var _elWrap = Trex.MarkupTemplate.get("richtextbox.colorpallete").evaluateAsDom({"color": this.borderColor, "wrapClass": "tx-color-wrap"});
  260. var _elPallete = $tom.collect(_elWrap, "div.tx-colorpallete");
  261. var _changeBorderColor = function(color) {
  262. _this.elPreview.style.borderColor = _elThumb.style.backgroundColor = _this.borderColor = color;
  263. };
  264. var _colorPallete = _NULL;
  265. var _toggleColorPallete = function() {
  266. if (_colorPallete == _NULL) {
  267. _colorPallete = _this.createColorPallete(_elPallete, _changeBorderColor);
  268. _colorPallete.show();
  269. } else {
  270. if (!$tx.visible(_elPallete)) _colorPallete.show();
  271. else _colorPallete.hide();
  272. }
  273. };
  274. this.externalBorderColorToggler = function(){
  275. if ($tx.visible(_elPallete)) {
  276. _colorPallete.hide();
  277. }
  278. };
  279. var _elThumb = this.borderColorInput = $tom.collect(_elWrap, ".tx-color-box a");
  280. $tx.observe(_elThumb, 'click', function(ev) {
  281. _this.externalBgColorToggler();
  282. _toggleColorPallete();
  283. $tx.stop(ev);
  284. });
  285. var _elArrow = $tom.collect(_elWrap, "a.tx-color-arrow-down");
  286. $tx.observe(_elArrow, 'click', function(ev) {
  287. _this.externalBgColorToggler();
  288. _toggleColorPallete();
  289. $tx.stop(ev);
  290. });
  291. return _elWrap;
  292. },
  293. createColorPallete: function(element, cmd) {
  294. var self = this;
  295. var pallete = new Trex.Menu.ColorPallete({el: element, thumbs: this.config.thumbs});
  296. pallete.setCommand(cmd);
  297. pallete.observeJob(Trex.Ev.__MENU_LAYER_SHOW, function(ev){
  298. self.fireJobs(Trex.Ev.__MENU_LAYER_SHOW, ev);
  299. });
  300. pallete.observeJob(Trex.Ev.__MENU_LAYER_HIDE, function(ev){
  301. self.fireJobs(Trex.Ev.__MENU_LAYER_HIDE, ev);
  302. });
  303. pallete.observeJob(Trex.Ev.__MENU_LAYER_CHANGE_SIZE, function(ev){
  304. self.fireJobs(Trex.Ev.__MENU_LAYER_CHANGE_SIZE, ev);
  305. });
  306. return pallete;
  307. },
  308. generateBgColor: function() {
  309. var _this = this;
  310. var _elWrap = Trex.MarkupTemplate.get("richtextbox.colorpallete").evaluateAsDom({"color":this.bgColor});
  311. var _elPallete = $tom.collect(_elWrap, "div.tx-colorpallete");
  312. var _changeBgColor = function(color) {
  313. _this.elPreview.style.backgroundColor = _elThumb.style.backgroundColor = _this.bgColor = color;
  314. };
  315. var _colorPallete = _NULL;
  316. var _toggleColorPallete = function() {
  317. if (_colorPallete == _NULL) {
  318. _colorPallete = _this.createColorPallete(_elPallete, _changeBgColor);
  319. _colorPallete.show();
  320. } else {
  321. if (!$tx.visible(_elPallete)) _colorPallete.show();
  322. else _colorPallete.hide();
  323. }
  324. };
  325. this.externalBgColorToggler = function(){
  326. if ($tx.visible(_elPallete)) {
  327. _colorPallete.hide();
  328. }
  329. };
  330. var _elThumb = this.bgColorInput = $tom.collect(_elWrap, ".tx-color-box a");
  331. $tx.observe(_elThumb, 'click', function(ev) {
  332. _this.externalBorderColorToggler();
  333. _toggleColorPallete();
  334. $tx.stop(ev);
  335. });
  336. var _elArrow = $tom.collect(_elWrap, "a.tx-color-arrow-down");
  337. $tx.observe(_elArrow, 'click', function(ev) {
  338. _this.externalBorderColorToggler();
  339. _toggleColorPallete();
  340. $tx.stop(ev);
  341. });
  342. return _elWrap;
  343. }
  344. });