plugin.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /**
  2. * @file Mapping plugin for CKEditor
  3. * Copyright (C) 2014 BeezNest Latino S.A.C
  4. *
  5. * Licensed under the terms of any of the following licenses at your
  6. * choice:
  7. *
  8. * - GNU General Public License Version 2 or later (the "GPL")
  9. * http://www.gnu.org/licenses/gpl.html
  10. */
  11. (function () {
  12. CKEDITOR.plugins.add('mapping', {
  13. requires: ['dialog'],
  14. lang: ['es'],
  15. init: function (editor) {
  16. var iconPath = this.path + 'images/icon.png';
  17. CKEDITOR.dialog.add('Mapping', this.path + 'dialogs/mapping.js');
  18. var mappingCommand = editor.addCommand('Mapping', new CKEDITOR.dialogCommand('Mapping', {
  19. allowedContent: 'img[usemap];map[id,name];area[alt,coords,shape,target,title,url]'
  20. }));
  21. mappingCommand.startDisabled = true;
  22. editor.ui.addButton('Mapping', {
  23. label: editor.lang.mapping.toolbar,
  24. command: 'Mapping',
  25. icon: iconPath
  26. });
  27. editor.on('doubleclick', function (evt) {
  28. var element = evt.data.element;
  29. var editor = evt.editor;
  30. if (element.is('area')) {
  31. var map = element.getParent().$;
  32. var mapId = map.getAttribute('id');
  33. var document = editor.document.$;
  34. var selectedImage;
  35. if (document.querySelector) {
  36. selectedImage = document.querySelector('img[usemap="#' + mapId + '"]');
  37. }
  38. if (selectedImage) {
  39. editor.getSelection().selectElement(new CKEDITOR.dom.element(selectedImage));
  40. evt.data.dialog = 'Mapping';
  41. return;
  42. }
  43. }
  44. if (element.is('img') && element.hasAttribute('usemap')) {
  45. editor.getSelection().selectElement(element);
  46. evt.data.dialog = 'Mapping';
  47. }
  48. }, null, null, 20);
  49. editor.on('selectionChange', CKEDITOR.tools.bind(function (evt) {
  50. var elementPath = evt.data.path;
  51. var element = elementPath.lastElement;
  52. if (!element || !element.is('img')) {
  53. this.setState(CKEDITOR.TRISTATE_DISABLED);
  54. return;
  55. }
  56. this.setState(element.hasAttribute('usemap') ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF);
  57. }, mappingCommand));
  58. if (CKEDITOR.env.ie)
  59. return;
  60. CKEDITOR.on('dialogDefinition', function (e) {
  61. if (e.data.name !== 'image')
  62. return;
  63. var definition = e.data.definition;
  64. e.removeListener();
  65. definition.onOk = CKEDITOR.tools.override(definition.onOk, function (original) {
  66. return function () {
  67. original.call(this);
  68. var selectedImage = this.imageElement;
  69. var mapName = selectedImage.getAttribute('usemap');
  70. if (!mapName)
  71. return;
  72. var map = editor.document.getById(mapName.substr(1));
  73. if (!map)
  74. return;
  75. CKEDITOR.plugins.mapping.generate(selectedImage.$, map.$);
  76. };
  77. });
  78. });
  79. editor.on('contentDom', function (e) {
  80. var document = e.editor.document.$;
  81. var maps = document.getElementsByTagName('map');
  82. for (var i = 0; i < maps.length; i++) {
  83. var map = maps[i];
  84. var name = map.name;
  85. var imageWithMap = document.querySelector('img[usemap="#' + name + '"]');
  86. if (imageWithMap) {
  87. CKEDITOR.plugins.mapping.generate(imageWithMap, map);
  88. }
  89. }
  90. });
  91. if (!CKEDITOR.plugins.mapping) {
  92. CKEDITOR.plugins.mapping = {};
  93. }
  94. CKEDITOR.plugins.mapping.generate = function (baseImage, map) {
  95. if (CKEDITOR.env.ie) {
  96. return;
  97. }
  98. if (!baseImage.width) {
  99. baseImage.addEventListener('load', function () {
  100. baseImage.removeEventListener('load', onLoad);
  101. CKEDITOR.plugins.mapping.generate(baseImage, map);
  102. }, false);
  103. return;
  104. }
  105. var doc = baseImage.ownerDocument;
  106. var canvas = doc.createElement('canvas');
  107. canvas.setAttribute('width', baseImage.width);
  108. canvas.setAttribute('height', baseImage.height);
  109. var context = canvas.getContext('2d');
  110. if (baseImage.attributes['data-cke-saved-src']) {
  111. var tmpImg = new Image();
  112. tmpImg.src = baseImage.attributes['data-cke-saved-src'].nodeValue;
  113. tmpImg.width = baseImage.width;
  114. tmpImg.height = baseImage.height;
  115. context.drawImage(tmpImg, 0, 0, baseImage.width, baseImage.height);
  116. } else {
  117. context.drawImage(baseImage, 0, 0, baseImage.width, baseImage.height);
  118. }
  119. context.strokeStyle = "#F00";
  120. context.lineWidth = 2;
  121. context.shadowOffsetX = 0;
  122. context.shadowOffsetY = 0;
  123. context.shadowBlur = 3;
  124. context.shadowColor = "#DDD";
  125. for (var i = 0; i < map.areas.length; i++) {
  126. var area = map.areas[i];
  127. var coords = area.coords.split(',');
  128. switch (area.shape) {
  129. case 'circle':
  130. context.beginPath();
  131. context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2, true);
  132. context.closePath();
  133. context.stroke();
  134. break;
  135. case 'poly':
  136. context.beginPath();
  137. context.moveTo(coords[0], coords[1]);
  138. for (var j = 2; j < coords.length; j += 2) {
  139. context.lineTo(coords[j], coords[j + 1]);
  140. }
  141. context.closePath();
  142. context.stroke();
  143. break;
  144. default:
  145. context.strokeRect(coords[0], coords[1], coords[2] - coords[0], coords[3] - coords[1]);
  146. break;
  147. }
  148. }
  149. try {
  150. baseImage.src = canvas.toDataURL();
  151. } catch (e) {
  152. console.log(e.message);
  153. }
  154. };
  155. },
  156. afterInit: function (editor) {
  157. if (!(CKEDITOR.env.ie && CKEDITOR.env.quirks)) {
  158. return;
  159. }
  160. var dataProcessor = editor.dataProcessor;
  161. var htmlFilter = dataProcessor && dataProcessor.htmlFilter;
  162. htmlFilter.addRules({
  163. elements: {
  164. map: function (element) {
  165. if (element.attributes.id && !element.attributes.name) {
  166. element.attributes.name = element.attributes.id;
  167. }
  168. return element;
  169. }
  170. }
  171. });
  172. }
  173. });
  174. })();