ext-server_opensave.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*globals svgEditor, svgedit, svgCanvas, canvg, $*/
  2. /*jslint eqeq: true*/
  3. /*
  4. * ext-server_opensave.js
  5. *
  6. * Licensed under the MIT License
  7. *
  8. * Copyright(c) 2010 Alexis Deveria
  9. *
  10. */
  11. svgEditor.addExtension("server_opensave", {
  12. callback: function() {
  13. 'use strict';
  14. function getFileNameFromTitle () {
  15. var title = svgCanvas.getDocumentTitle();
  16. // We convert (to underscore) only those disallowed Win7 file name characters
  17. return $.trim(title).replace(/[\/\\:*?"<>|]/g, '_');
  18. }
  19. function xhtmlEscape(str) {
  20. return str.replace(/&(?!amp;)/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;'); // < is actually disallowed above anyways
  21. }
  22. function clientDownloadSupport (filename, suffix, uri) {
  23. var a,
  24. support = $('<a>')[0].download === '';
  25. if (support) {
  26. a = $('<a>hidden</a>').attr({download: (filename || 'image') + suffix, href: uri}).css('display', 'none').appendTo('body');
  27. a[0].click();
  28. return true;
  29. }
  30. }
  31. var open_svg_action, import_svg_action, import_img_action,
  32. open_svg_form, import_svg_form, import_img_form,
  33. save_svg_action = svgEditor.curConfig.extPath + 'filesave.php',
  34. save_img_action = svgEditor.curConfig.extPath + 'filesave.php',
  35. // Create upload target (hidden iframe)
  36. cancelled = false;
  37. $('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
  38. svgEditor.setCustomHandlers({
  39. save: function(win, data) {
  40. var svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data, // Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
  41. filename = getFileNameFromTitle();
  42. if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + svgedit.utilities.encode64(svg))) {
  43. return;
  44. }
  45. $('<form>').attr({
  46. method: 'post',
  47. action: save_svg_action,
  48. target: 'output_frame'
  49. }).append('<input type="hidden" name="output_svg" value="' + xhtmlEscape(svg) + '">')
  50. .append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
  51. .appendTo('body')
  52. .submit().remove();
  53. },
  54. exportImage: function(win, data) {
  55. var c,
  56. issues = data.issues,
  57. mimeType = data.mimeType,
  58. quality = data.quality;
  59. if(!$('#export_canvas').length) {
  60. $('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
  61. }
  62. c = $('#export_canvas')[0];
  63. c.width = svgCanvas.contentW;
  64. c.height = svgCanvas.contentH;
  65. canvg(c, data.svg, {renderCallback: function() {
  66. var pre, filename, suffix,
  67. datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType),
  68. // uiStrings = svgEditor.uiStrings,
  69. note = '';
  70. // Check if there are issues
  71. if (issues.length) {
  72. pre = "\n \u2022 ";
  73. note += ("\n\n" + pre + issues.join(pre));
  74. }
  75. if(note.length) {
  76. alert(note);
  77. }
  78. filename = getFileNameFromTitle();
  79. suffix = '.' + data.type.toLowerCase();
  80. if (clientDownloadSupport(filename, suffix, datauri)) {
  81. return;
  82. }
  83. $('<form>').attr({
  84. method: 'post',
  85. action: save_img_action,
  86. target: 'output_frame'
  87. }).append('<input type="hidden" name="output_img" value="' + datauri + '">')
  88. .append('<input type="hidden" name="mime" value="' + mimeType + '">')
  89. .append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
  90. .appendTo('body')
  91. .submit().remove();
  92. }});
  93. }
  94. });
  95. // Do nothing if client support is found
  96. if (window.FileReader) {return;}
  97. // Change these to appropriate script file
  98. open_svg_action = svgEditor.curConfig.extPath + 'fileopen.php?type=load_svg';
  99. import_svg_action = svgEditor.curConfig.extPath + 'fileopen.php?type=import_svg';
  100. import_img_action = svgEditor.curConfig.extPath + 'fileopen.php?type=import_img';
  101. // Set up function for PHP uploader to use
  102. svgEditor.processFile = function(str64, type) {
  103. var xmlstr;
  104. if (cancelled) {
  105. cancelled = false;
  106. return;
  107. }
  108. $('#dialog_box').hide();
  109. if (type !== 'import_img') {
  110. xmlstr = svgedit.utilities.decode64(str64);
  111. }
  112. switch (type) {
  113. case 'load_svg':
  114. svgCanvas.clear();
  115. svgCanvas.setSvgString(xmlstr);
  116. svgEditor.updateCanvas();
  117. break;
  118. case 'import_svg':
  119. svgCanvas.importSvgString(xmlstr);
  120. svgEditor.updateCanvas();
  121. break;
  122. case 'import_img':
  123. svgCanvas.setGoodImage(str64);
  124. break;
  125. }
  126. };
  127. // Create upload form
  128. open_svg_form = $('<form>');
  129. open_svg_form.attr({
  130. enctype: 'multipart/form-data',
  131. method: 'post',
  132. action: open_svg_action,
  133. target: 'output_frame'
  134. });
  135. // Create import form
  136. import_svg_form = open_svg_form.clone().attr('action', import_svg_action);
  137. // Create image form
  138. import_img_form = open_svg_form.clone().attr('action', import_img_action);
  139. // It appears necessary to rebuild this input every time a file is
  140. // selected so the same file can be picked and the change event can fire.
  141. function rebuildInput(form) {
  142. form.empty();
  143. var inp = $('<input type="file" name="svg_file">').appendTo(form);
  144. function submit() {
  145. // This submits the form, which returns the file data using svgEditor.processFile()
  146. form.submit();
  147. rebuildInput(form);
  148. $.process_cancel("Uploading...", function() {
  149. cancelled = true;
  150. $('#dialog_box').hide();
  151. });
  152. }
  153. if(form[0] == open_svg_form[0]) {
  154. inp.change(function() {
  155. // This takes care of the "are you sure" dialog box
  156. svgEditor.openPrep(function(ok) {
  157. if(!ok) {
  158. rebuildInput(form);
  159. return;
  160. }
  161. submit();
  162. });
  163. });
  164. } else {
  165. inp.change(function() {
  166. // This submits the form, which returns the file data using svgEditor.processFile()
  167. submit();
  168. });
  169. }
  170. }
  171. // Create the input elements
  172. rebuildInput(open_svg_form);
  173. rebuildInput(import_svg_form);
  174. rebuildInput(import_img_form);
  175. // Add forms to buttons
  176. $("#tool_open").show().prepend(open_svg_form);
  177. $("#tool_import").show().prepend(import_svg_form);
  178. $("#tool_image").prepend(import_img_form);
  179. }
  180. });