ext-imagelib.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /*globals $, svgEditor, svgedit, svgCanvas, DOMParser*/
  2. /*jslint vars: true, eqeq: true, es5: true, todo: true */
  3. /*
  4. * ext-imagelib.js
  5. *
  6. * Licensed under the MIT License
  7. *
  8. * Copyright(c) 2010 Alexis Deveria
  9. *
  10. */
  11. svgEditor.addExtension("imagelib", function() {'use strict';
  12. var uiStrings = svgEditor.uiStrings;
  13. $.extend(uiStrings, {
  14. imagelib: {
  15. select_lib: 'Select an image library',
  16. show_list: 'Show library list',
  17. import_single: 'Import single',
  18. import_multi: 'Import multiple',
  19. open: 'Open as new document'
  20. }
  21. });
  22. var img_libs = [
  23. {
  24. name: 'Local library (local)',
  25. url: 'extensions/imagelib/index.php',
  26. //description: 'Demonstration library for SVG-edit on this server'// Chamilo change this line by below
  27. description: 'Course gallery'
  28. },
  29. {
  30. name: 'Local library',
  31. url: 'extensions/imagelib/groups.php',
  32. //description: 'Demonstration library for SVG-edit on this server'// Chamilo change this line by below
  33. description: 'Group gallery'
  34. },
  35. {
  36. name: 'Local library',
  37. url: 'extensions/imagelib/users.php',
  38. //description: 'Demonstration library for SVG-edit on this server'// Chamilo change this line by below
  39. description: 'Personal gallery'
  40. },
  41. {
  42. name: 'IAN Symbol Libraries',
  43. url: 'http://ian.umces.edu/symbols/catalog/svgedit/album_chooser.php',
  44. description: 'Free library of illustrations'
  45. }
  46. ];
  47. function closeBrowser() {
  48. $('#imgbrowse_holder').hide();
  49. }
  50. function importImage(url) {
  51. var newImage = svgCanvas.addSvgElementFromJson({
  52. "element": "image",
  53. "attr": {
  54. "x": 0,
  55. "y": 0,
  56. "width": 0,
  57. "height": 0,
  58. "id": svgCanvas.getNextId(),
  59. "style": "pointer-events:inherit"
  60. }
  61. });
  62. svgCanvas.clearSelection();
  63. svgCanvas.addToSelection([newImage]);
  64. svgCanvas.setImageURL(url);
  65. }
  66. var mode = 's';
  67. var multi_arr = [];
  68. var cur_meta;
  69. var tranfer_stopped = false;
  70. var pending = {};
  71. var preview, submit;
  72. window.addEventListener("message", function(evt) {
  73. // Receive postMessage data
  74. var response = evt.data;
  75. if (!response || typeof response !== "string") { // Todo: Should namespace postMessage API for this extension and filter out here
  76. // Do nothing
  77. return;
  78. }
  79. try { // This block can be removed if embedAPI moves away from a string to an object (if IE9 support not needed)
  80. var res = JSON.parse(response);
  81. if (res.namespace) { // Part of embedAPI communications
  82. return;
  83. }
  84. }
  85. catch (e) {}
  86. var char1 = response.charAt(0);
  87. var id;
  88. var svg_str;
  89. var img_str;
  90. if (char1 != "{" && tranfer_stopped) {
  91. tranfer_stopped = false;
  92. return;
  93. }
  94. if (char1 == '|') {
  95. var secondpos = response.indexOf('|', 1);
  96. id = response.substr(1, secondpos-1);
  97. response = response.substr(secondpos+1);
  98. char1 = response.charAt(0);
  99. }
  100. // Hide possible transfer dialog box
  101. $('#dialog_box').hide();
  102. var entry, cur_meta;
  103. switch (char1) {
  104. case '{':
  105. // Metadata
  106. tranfer_stopped = false;
  107. cur_meta = JSON.parse(response);
  108. pending[cur_meta.id] = cur_meta;
  109. var name = (cur_meta.name || 'file');
  110. var message = uiStrings.notification.retrieving.replace('%s', name);
  111. if (mode != 'm') {
  112. $.process_cancel(message, function() {
  113. tranfer_stopped = true;
  114. // Should a message be sent back to the frame?
  115. $('#dialog_box').hide();
  116. });
  117. } else {
  118. entry = $('<div>' + message + '</div>').data('id', cur_meta.id);
  119. preview.append(entry);
  120. cur_meta.entry = entry;
  121. }
  122. return;
  123. case '<':
  124. svg_str = true;
  125. break;
  126. case 'd':
  127. if (response.indexOf('data:image/svg+xml') === 0) {
  128. var pre = 'data:image/svg+xml;base64,';
  129. var src = response.substring(pre.length);
  130. response = svgedit.utilities.decode64(src);
  131. svg_str = true;
  132. break;
  133. } else if (response.indexOf('data:image/') === 0) {
  134. img_str = true;
  135. break;
  136. }
  137. // Else fall through
  138. default:
  139. // TODO: See if there's a way to base64 encode the binary data stream
  140. // var str = 'data:;base64,' + svgedit.utilities.encode64(response, true);
  141. // Assume it's raw image data
  142. // importImage(str);
  143. // Don't give warning as postMessage may have been used by something else
  144. if (mode !== 'm') {
  145. closeBrowser();
  146. } else {
  147. pending[id].entry.remove();
  148. }
  149. // $.alert('Unexpected data was returned: ' + response, function() {
  150. // if (mode !== 'm') {
  151. // closeBrowser();
  152. // } else {
  153. // pending[id].entry.remove();
  154. // }
  155. // });
  156. return;
  157. }
  158. switch (mode) {
  159. case 's':
  160. // Import one
  161. if (svg_str) {
  162. svgCanvas.importSvgString(response);
  163. } else if (img_str) {
  164. importImage(response);
  165. }
  166. closeBrowser();
  167. break;
  168. case 'm':
  169. // Import multiple
  170. multi_arr.push([(svg_str ? 'svg' : 'img'), response]);
  171. var title;
  172. cur_meta = pending[id];
  173. if (svg_str) {
  174. if (cur_meta && cur_meta.name) {
  175. title = cur_meta.name;
  176. } else {
  177. // Try to find a title
  178. var xml = new DOMParser().parseFromString(response, 'text/xml').documentElement;
  179. title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';
  180. }
  181. if (cur_meta) {
  182. preview.children().each(function() {
  183. if ($(this).data('id') == id) {
  184. if (cur_meta.preview_url) {
  185. $(this).html('<img src="' + cur_meta.preview_url + '">' + title);
  186. } else {
  187. $(this).text(title);
  188. }
  189. submit.removeAttr('disabled');
  190. }
  191. });
  192. } else {
  193. preview.append('<div>'+title+'</div>');
  194. submit.removeAttr('disabled');
  195. }
  196. } else {
  197. if (cur_meta && cur_meta.preview_url) {
  198. title = cur_meta.name || '';
  199. }
  200. if (cur_meta && cur_meta.preview_url) {
  201. entry = '<img src="' + cur_meta.preview_url + '">' + title;
  202. } else {
  203. entry = '<img src="' + response + '">';
  204. }
  205. if (cur_meta) {
  206. preview.children().each(function() {
  207. if ($(this).data('id') == id) {
  208. $(this).html(entry);
  209. submit.removeAttr('disabled');
  210. }
  211. });
  212. } else {
  213. preview.append($('<div>').append(entry));
  214. submit.removeAttr('disabled');
  215. }
  216. }
  217. break;
  218. case 'o':
  219. // Open
  220. if (!svg_str) {break;}
  221. svgEditor.openPrep(function(ok) {
  222. if (!ok) {return;}
  223. svgCanvas.clear();
  224. svgCanvas.setSvgString(response);
  225. // updateCanvas();
  226. });
  227. closeBrowser();
  228. break;
  229. }
  230. }, true);
  231. function toggleMulti(show) {
  232. $('#lib_framewrap, #imglib_opts').css({right: (show ? 200 : 10)});
  233. if (!preview) {
  234. preview = $('<div id=imglib_preview>').css({
  235. position: 'absolute',
  236. top: 45,
  237. right: 10,
  238. width: 180,
  239. bottom: 45,
  240. background: '#fff',
  241. overflow: 'auto'
  242. }).insertAfter('#lib_framewrap');
  243. submit = $('<button disabled>Import selected</button>')
  244. .appendTo('#imgbrowse')
  245. .on("click touchend", function() {
  246. $.each(multi_arr, function(i) {
  247. var type = this[0];
  248. var data = this[1];
  249. if (type == 'svg') {
  250. svgCanvas.importSvgString(data);
  251. } else {
  252. importImage(data);
  253. }
  254. svgCanvas.moveSelectedElements(i*20, i*20, false);
  255. });
  256. preview.empty();
  257. multi_arr = [];
  258. $('#imgbrowse_holder').hide();
  259. }).css({
  260. position: 'absolute',
  261. bottom: 10,
  262. right: -10
  263. });
  264. }
  265. preview.toggle(show);
  266. submit.toggle(show);
  267. }
  268. function showBrowser() {
  269. var browser = $('#imgbrowse');
  270. if (!browser.length) {
  271. $('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>\
  272. </div></div>').insertAfter('#svg_docprops');
  273. browser = $('#imgbrowse');
  274. var all_libs = uiStrings.imagelib.select_lib;
  275. var lib_opts = $('<ul id=imglib_opts>').appendTo(browser);
  276. var frame = $('<iframe/>').prependTo(browser).hide().wrap('<div id=lib_framewrap>');
  277. var header = $('<h1>').prependTo(browser).text(all_libs).css({
  278. position: 'absolute',
  279. top: 0,
  280. left: 0,
  281. width: '100%'
  282. });
  283. var cancel = $('<button>' + uiStrings.common.cancel + '</button>')
  284. .appendTo(browser)
  285. .on("click touchend", function() {
  286. $('#imgbrowse_holder').hide();
  287. }).css({
  288. position: 'absolute',
  289. top: 5,
  290. right: -10
  291. });
  292. var leftBlock = $('<span>').css({position:'absolute',top:5,left:10}).appendTo(browser);
  293. var back = $('<button hidden>' + uiStrings.imagelib.show_list + '</button>')
  294. .appendTo(leftBlock)
  295. .on("click touchend", function() {
  296. frame.attr('src', 'about:blank').hide();
  297. lib_opts.show();
  298. header.text(all_libs);
  299. back.hide();
  300. }).css({
  301. 'margin-right': 5
  302. }).hide();
  303. var type = $('<select><option value=s>' +
  304. uiStrings.imagelib.import_single + '</option><option value=m>' +
  305. uiStrings.imagelib.import_multi + '</option><option value=o>' +
  306. uiStrings.imagelib.open + '</option></select>').appendTo(leftBlock).change(function() {
  307. mode = $(this).val();
  308. switch (mode) {
  309. case 's':
  310. case 'o':
  311. toggleMulti(false);
  312. break;
  313. case 'm':
  314. // Import multiple
  315. toggleMulti(true);
  316. break;
  317. }
  318. }).css({
  319. 'margin-top': 10
  320. });
  321. cancel.prepend($.getSvgIcon('cancel', true));
  322. back.prepend($.getSvgIcon('tool_imagelib', true));
  323. $.each(img_libs, function(i, opts) {
  324. $('<li>')
  325. .appendTo(lib_opts)
  326. .text(opts.name)
  327. .on("click touchend", function() {
  328. frame.attr('src', opts.url).show();
  329. header.text(opts.name);
  330. lib_opts.hide();
  331. back.show();
  332. }).append('<span>' + opts.description + '</span>');
  333. });
  334. } else {
  335. $('#imgbrowse_holder').show();
  336. }
  337. }
  338. return {
  339. svgicons: svgEditor.curConfig.extPath + "ext-imagelib.xml",
  340. buttons: [{
  341. id: "tool_imagelib",
  342. type: "app_menu", // _flyout
  343. position: 4,
  344. title: "Image library",
  345. events: {
  346. "mouseup": showBrowser
  347. }
  348. }],
  349. callback: function() {
  350. $('<style>').text('\
  351. #imgbrowse_holder {\
  352. position: absolute;\
  353. top: 0;\
  354. left: 0;\
  355. width: 100%;\
  356. height: 100%;\
  357. background-color: rgba(0, 0, 0, .5);\
  358. z-index: 5;\
  359. }\
  360. \
  361. #imgbrowse {\
  362. position: absolute;\
  363. top: 25px;\
  364. left: 25px;\
  365. right: 25px;\
  366. bottom: 25px;\
  367. min-width: 300px;\
  368. min-height: 200px;\
  369. background: #B0B0B0;\
  370. border: 1px outset #777;\
  371. }\
  372. #imgbrowse h1 {\
  373. font-size: 20px;\
  374. margin: .4em;\
  375. text-align: center;\
  376. }\
  377. #lib_framewrap,\
  378. #imgbrowse > ul {\
  379. position: absolute;\
  380. top: 45px;\
  381. left: 10px;\
  382. right: 10px;\
  383. bottom: 10px;\
  384. background: white;\
  385. margin: 0;\
  386. padding: 0;\
  387. }\
  388. #imgbrowse > ul {\
  389. overflow: auto;\
  390. }\
  391. #imgbrowse > div {\
  392. border: 1px solid #666;\
  393. }\
  394. #imglib_preview > div {\
  395. padding: 5px;\
  396. font-size: 12px;\
  397. }\
  398. #imglib_preview img {\
  399. display: block;\
  400. margin: 0 auto;\
  401. max-height: 100px;\
  402. }\
  403. #imgbrowse li {\
  404. list-style: none;\
  405. padding: .5em;\
  406. background: #E8E8E8;\
  407. border-bottom: 1px solid #B0B0B0;\
  408. line-height: 1.2em;\
  409. font-style: sans-serif;\
  410. }\
  411. #imgbrowse li > span {\
  412. color: #666;\
  413. font-size: 15px;\
  414. display: block;\
  415. }\
  416. #imgbrowse li:hover {\
  417. background: #FFC;\
  418. cursor: pointer;\
  419. }\
  420. #imgbrowse iframe {\
  421. width: 100%;\
  422. height: 100%;\
  423. border: 0;\
  424. }\
  425. ').appendTo('head');
  426. }
  427. };
  428. });