plugin.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /**
  2. * oEmbed Plugin plugin
  3. * Licensed under the MIT license
  4. * jQuery Embed Plugin: http://code.google.com/p/jquery-oembed/ (MIT License)
  5. * Plugin for: http://ckeditor.com/license (GPL/LGPL/MPL: http://ckeditor.com/license)
  6. */
  7. (function() {
  8. CKEDITOR.plugins.add('oembed', {
  9. icons: 'oembed',
  10. hidpi: true,
  11. requires: 'widget,dialog',
  12. lang: 'de,en,fr,nl,pl,pt-br,ru,tr', // %REMOVE_LINE_CORE%
  13. version: 1.17,
  14. init: function(editor) {
  15. // Load jquery?
  16. loadjQueryLibaries();
  17. CKEDITOR.tools.extend(CKEDITOR.editor.prototype, {
  18. oEmbed: function(url, maxWidth, maxHeight, responsiveResize) {
  19. if (url.length < 1 || url.indexOf('http') < 0) {
  20. alert(editor.lang.oembed.invalidUrl);
  21. return false;
  22. }
  23. function embed() {
  24. if (maxWidth == null || maxWidth == 'undefined') {
  25. maxWidth = null;
  26. }
  27. if (maxHeight == null || maxHeight == 'undefined') {
  28. maxHeight = null;
  29. }
  30. if (responsiveResize == null || responsiveResize == 'undefined') {
  31. responsiveResize = false;
  32. }
  33. embedCode(url, editor, false, maxWidth, maxHeight, responsiveResize);
  34. }
  35. if (typeof(jQuery.fn.oembed) === 'undefined') {
  36. CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('oembed') + 'libs/jquery.oembed.min.js'), function() {
  37. embed();
  38. });
  39. } else {
  40. embed();
  41. }
  42. return true;
  43. }
  44. });
  45. editor.widgets.add('oembed', {
  46. draggable: false,
  47. mask: true,
  48. dialog: 'oembed',
  49. allowedContent: {
  50. div: {
  51. styles: 'text-align,float',
  52. attributes: '*',
  53. classes: editor.config.oembed_WrapperClass != null ? editor.config.oembed_WrapperClass : "embeddedContent"
  54. },
  55. 'div(embeddedContent,oembed-provider-*) iframe': {
  56. attributes: '*'
  57. },
  58. 'div(embeddedContent,oembed-provider-*) blockquote': {
  59. attributes: '*'
  60. },
  61. 'div(embeddedContent,oembed-provider-*) script': {
  62. attributes: '*'
  63. }
  64. },
  65. template:
  66. '<div class="' + (editor.config.oembed_WrapperClass != null ? editor.config.oembed_WrapperClass : "embeddedContent") + '">' +
  67. '</div>',
  68. upcast: function(element) {
  69. return element.name == 'div' && element.hasClass(editor.config.oembed_WrapperClass != null ? editor.config.oembed_WrapperClass : "embeddedContent");
  70. },
  71. init: function() {
  72. var data = {
  73. oembed: this.element.data('oembed') || '',
  74. resizeType: this.element.data('resizeType') || 'noresize',
  75. maxWidth: this.element.data('maxWidth') || 560,
  76. maxHeight: this.element.data('maxHeight') || 315,
  77. align: this.element.data('align') || 'none',
  78. oembed_provider: this.element.data('oembed_provider') || ''
  79. };
  80. this.setData(data);
  81. this.element.addClass('oembed-provider-' + data.oembed_provider);
  82. this.on('dialog', function(evt) {
  83. evt.data.widget = this;
  84. }, this);
  85. }
  86. });
  87. editor.ui.addButton('oembed', {
  88. label: editor.lang.oembed.button,
  89. command: 'oembed',
  90. toolbar: 'insert,6',
  91. icon: this.path + "icons/" + (CKEDITOR.env.hidpi ? "hidpi/" : "") + "oembed.png"
  92. });
  93. var resizeTypeChanged = function() {
  94. var dialog = this.getDialog(),
  95. resizetype = this.getValue(),
  96. maxSizeBox = dialog.getContentElement('general', 'maxSizeBox').getElement(),
  97. sizeBox = dialog.getContentElement('general', 'sizeBox').getElement();
  98. if (resizetype == 'noresize') {
  99. maxSizeBox.hide();
  100. sizeBox.hide();
  101. } else if (resizetype == "custom") {
  102. maxSizeBox.hide();
  103. sizeBox.show();
  104. } else {
  105. maxSizeBox.show();
  106. sizeBox.hide();
  107. }
  108. };
  109. String.prototype.beginsWith = function(string) {
  110. return (this.indexOf(string) === 0);
  111. };
  112. function loadjQueryLibaries() {
  113. if (typeof(jQuery) === 'undefined') {
  114. CKEDITOR.scriptLoader.load('//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js', function() {
  115. jQuery.noConflict();
  116. if (typeof(jQuery.fn.oembed) === 'undefined') {
  117. CKEDITOR.scriptLoader.load(
  118. CKEDITOR.getUrl(CKEDITOR.plugins.getPath('oembed') + 'libs/jquery.oembed.min.js')
  119. );
  120. }
  121. });
  122. } else if (typeof(jQuery.fn.oembed) === 'undefined') {
  123. CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('oembed') + 'libs/jquery.oembed.min.js'));
  124. }
  125. }
  126. function embedCode(url, instance, maxWidth, maxHeight, responsiveResize, resizeType, align, widget) {
  127. jQuery('body').oembed(url, {
  128. onEmbed: function(e) {
  129. var elementAdded = false,
  130. provider = jQuery.fn.oembed.getOEmbedProvider(url);
  131. widget.element.data('resizeType', resizeType);
  132. if (resizeType == "responsive" || resizeType == "custom") {
  133. widget.element.data('maxWidth', maxWidth);
  134. widget.element.data('maxHeight', maxHeight);
  135. }
  136. widget.element.data('align', align);
  137. // TODO handle align
  138. if (align == 'center') {
  139. if (!widget.inline)
  140. widget.element.setStyle('text-align', 'center');
  141. widget.element.removeStyle('float');
  142. } else {
  143. if (!widget.inline)
  144. widget.element.removeStyle('text-align');
  145. if (align == 'none')
  146. widget.element.removeStyle('float');
  147. else
  148. widget.element.setStyle('float', align);
  149. }
  150. if (typeof e.code === 'string') {
  151. if (widget.element.$.firstChild) {
  152. widget.element.$.removeChild(widget.element.$.firstChild);
  153. }
  154. widget.element.appendHtml(e.code);
  155. widget.element.data('oembed', url);
  156. widget.element.data('oembed_provider', provider.name);
  157. widget.element.addClass('oembed-provider-' + provider.name);
  158. elementAdded = true;
  159. } else if (typeof e.code[0].outerHTML === 'string') {
  160. if (widget.element.$.firstChild) {
  161. widget.element.$.removeChild(widget.element.$.firstChild);
  162. }
  163. widget.element.appendHtml(e.code[0].outerHTML);
  164. widget.element.data('oembed', url);
  165. widget.element.data('oembed_provider', provider.name);
  166. widget.element.addClass('oembed-provider-' + provider.name);
  167. elementAdded = true;
  168. } else {
  169. alert(editor.lang.oembed.noEmbedCode);
  170. }
  171. },
  172. onError: function(externalUrl) {
  173. if (externalUrl.indexOf("vimeo.com") > 0) {
  174. alert(editor.lang.oembed.noVimeo);
  175. } else {
  176. alert(editor.lang.oembed.Error);
  177. }
  178. },
  179. maxHeight: maxHeight,
  180. maxWidth: maxWidth,
  181. useResponsiveResize: responsiveResize,
  182. embedMethod: 'editor'
  183. });
  184. }
  185. CKEDITOR.dialog.add('oembed', function(editor) {
  186. return {
  187. title: editor.lang.oembed.title,
  188. minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 568 : 550,
  189. minHeight: 155,
  190. onShow: function() {
  191. var data = {
  192. oembed: this.widget.element.data('oembed') || '',
  193. resizeType: this.widget.element.data('resizeType') || 'noresize',
  194. maxWidth: this.widget.element.data('maxWidth'),
  195. maxHeight: this.widget.element.data('maxHeight'),
  196. align: this.widget.element.data('align') || 'none'
  197. };
  198. this.widget.setData(data);
  199. this.getContentElement('general', 'resizeType').setValue(data.resizeType);
  200. this.getContentElement('general', 'align').setValue(data.align);
  201. var resizetype = this.getContentElement('general', 'resizeType').getValue(),
  202. maxSizeBox = this.getContentElement('general', 'maxSizeBox').getElement(),
  203. sizeBox = this.getContentElement('general', 'sizeBox').getElement();
  204. if (resizetype == 'noresize') {
  205. maxSizeBox.hide();
  206. sizeBox.hide();
  207. } else if (resizetype == "custom") {
  208. maxSizeBox.hide();
  209. sizeBox.show();
  210. } else {
  211. maxSizeBox.show();
  212. sizeBox.hide();
  213. }
  214. },
  215. onOk: function() {
  216. },
  217. contents: [
  218. {
  219. label: editor.lang.common.generalTab,
  220. id: 'general',
  221. elements: [
  222. {
  223. type: 'html',
  224. id: 'oembedHeader',
  225. html: '<div style="white-space:normal;width:500px;padding-bottom:10px">' + editor.lang.oembed.pasteUrl + '</div>'
  226. }, {
  227. type: 'text',
  228. id: 'embedCode',
  229. focus: function() {
  230. this.getElement().focus();
  231. },
  232. label: editor.lang.oembed.url,
  233. title: editor.lang.oembed.pasteUrl,
  234. setup: function(widget) {
  235. if (widget.data.oembed) {
  236. this.setValue(widget.data.oembed);
  237. }
  238. },
  239. commit: function(widget) {
  240. var dialog = CKEDITOR.dialog.getCurrent(),
  241. inputCode = dialog.getValueOf('general', 'embedCode').replace(/\s/g, ""),
  242. resizeType = dialog.getContentElement('general', 'resizeType').
  243. getValue(),
  244. align = dialog.getContentElement('general', 'align').
  245. getValue(),
  246. maxWidth = null,
  247. maxHeight = null,
  248. responsiveResize = false,
  249. editorInstance = dialog.getParentEditor();
  250. if (inputCode.length < 1 || inputCode.indexOf('http') < 0) {
  251. alert(editor.lang.oembed.invalidUrl);
  252. return false;
  253. }
  254. if (resizeType == "noresize") {
  255. responsiveResize = false;
  256. maxWidth = null;
  257. maxHeight = null;
  258. } else if (resizeType == "responsive") {
  259. maxWidth = dialog.getContentElement('general', 'maxWidth').
  260. getInputElement().
  261. getValue();
  262. maxHeight = dialog.getContentElement('general', 'maxHeight').
  263. getInputElement().
  264. getValue();
  265. responsiveResize = true;
  266. } else if (resizeType == "custom") {
  267. maxWidth = dialog.getContentElement('general', 'width').
  268. getInputElement().
  269. getValue();
  270. maxHeight = dialog.getContentElement('general', 'height').
  271. getInputElement().
  272. getValue();
  273. responsiveResize = false;
  274. }
  275. embedCode(inputCode, editorInstance, maxWidth, maxHeight, responsiveResize, resizeType, align, widget);
  276. widget.setData('oembed', inputCode);
  277. widget.setData('resizeType', resizeType);
  278. widget.setData('align', align);
  279. widget.setData('maxWidth', maxWidth);
  280. widget.setData('maxHeight', maxHeight);
  281. }
  282. }, {
  283. type: 'hbox',
  284. widths: ['50%', '50%'],
  285. children: [
  286. {
  287. id: 'resizeType',
  288. type: 'select',
  289. label: editor.lang.oembed.resizeType,
  290. 'default': 'noresize',
  291. setup: function(widget) {
  292. if (widget.data.resizeType) {
  293. this.setValue(widget.data.resizeType);
  294. }
  295. },
  296. items: [
  297. [editor.lang.oembed.noresize, 'noresize'],
  298. [editor.lang.oembed.responsive, 'responsive'],
  299. [editor.lang.oembed.custom, 'custom']
  300. ],
  301. onChange: resizeTypeChanged
  302. }, {
  303. type: 'hbox',
  304. id: 'maxSizeBox',
  305. widths: ['120px', '120px'],
  306. style: 'float:left;position:absolute;left:58%;width:200px',
  307. children: [
  308. {
  309. type: 'text',
  310. width: '100px',
  311. id: 'maxWidth',
  312. 'default': editor.config.oembed_maxWidth != null ? editor.config.oembed_maxWidth : '560',
  313. label: editor.lang.oembed.maxWidth,
  314. title: editor.lang.oembed.maxWidthTitle,
  315. setup: function(widget) {
  316. if (widget.data.maxWidth) {
  317. this.setValue(widget.data.maxWidth);
  318. }
  319. }
  320. }, {
  321. type: 'text',
  322. id: 'maxHeight',
  323. width: '120px',
  324. 'default': editor.config.oembed_maxHeight != null ? editor.config.oembed_maxHeight : '315',
  325. label: editor.lang.oembed.maxHeight,
  326. title: editor.lang.oembed.maxHeightTitle,
  327. setup: function(widget) {
  328. if (widget.data.maxHeight) {
  329. this.setValue(widget.data.maxHeight);
  330. }
  331. }
  332. }
  333. ]
  334. }, {
  335. type: 'hbox',
  336. id: 'sizeBox',
  337. widths: ['120px', '120px'],
  338. style: 'float:left;position:absolute;left:58%;width:200px',
  339. children: [
  340. {
  341. type: 'text',
  342. id: 'width',
  343. width: '100px',
  344. 'default': editor.config.oembed_maxWidth != null ? editor.config.oembed_maxWidth : '560',
  345. label: editor.lang.oembed.width,
  346. title: editor.lang.oembed.widthTitle,
  347. setup: function(widget) {
  348. if (widget.data.maxWidth) {
  349. this.setValue(widget.data.maxWidth);
  350. }
  351. }
  352. }, {
  353. type: 'text',
  354. id: 'height',
  355. width: '120px',
  356. 'default': editor.config.oembed_maxHeight != null ? editor.config.oembed_maxHeight : '315',
  357. label: editor.lang.oembed.height,
  358. title: editor.lang.oembed.heightTitle,
  359. setup: function(widget) {
  360. if (widget.data.maxHeight) {
  361. this.setValue(widget.data.maxHeight);
  362. }
  363. }
  364. }
  365. ]
  366. }
  367. ]
  368. }, {
  369. type: 'hbox',
  370. id: 'alignment',
  371. children: [
  372. {
  373. id: 'align',
  374. type: 'radio',
  375. items: [
  376. [editor.lang.oembed.none, 'none'],
  377. [editor.lang.common.alignLeft, 'left'],
  378. [editor.lang.common.alignCenter, 'center'],
  379. [editor.lang.common.alignRight, 'right']
  380. ],
  381. label: editor.lang.common.align,
  382. setup: function(widget) {
  383. this.setValue(widget.data.align);
  384. }
  385. }
  386. ]
  387. }
  388. ]
  389. }
  390. ]
  391. };
  392. });
  393. }
  394. });
  395. }
  396. )();