ext-server_opensave.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*globals svgEditor, svgedit, svgCanvas, canvg, $*/
  2. /*jslint eqeq: true, browser: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. Utils = svgedit.utilities;
  38. $('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
  39. svgEditor.setCustomHandlers({
  40. save: function(win, data) {
  41. 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
  42. filename = getFileNameFromTitle();
  43. if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + Utils.encode64(svg))) {
  44. return;
  45. }
  46. $('<form>').attr({
  47. method: 'post',
  48. action: save_svg_action,
  49. target: 'output_frame'
  50. }).append('<input type="hidden" name="output_svg" value="' + xhtmlEscape(svg) + '">')
  51. .append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
  52. .appendTo('body')
  53. .submit().remove();
  54. },
  55. exportPDF: function (win, data) {
  56. var filename = getFileNameFromTitle(),
  57. datauri = data.dataurlstring;
  58. if (clientDownloadSupport(filename, '.pdf', datauri)) {
  59. return;
  60. }
  61. $('<form>').attr({
  62. method: 'post',
  63. action: save_img_action,
  64. target: 'output_frame'
  65. }).append('<input type="hidden" name="output_img" value="' + datauri + '">')
  66. .append('<input type="hidden" name="mime" value="application/pdf">')
  67. .append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
  68. .appendTo('body')
  69. .submit().remove();
  70. },
  71. // Todo: Integrate this extension with a new built-in exportWindowType, "download"
  72. exportImage: function(win, data) {
  73. var c,
  74. issues = data.issues,
  75. mimeType = data.mimeType,
  76. quality = data.quality;
  77. if(!$('#export_canvas').length) {
  78. $('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
  79. }
  80. c = $('#export_canvas')[0];
  81. c.width = svgCanvas.contentW;
  82. c.height = svgCanvas.contentH;
  83. Utils.buildCanvgCallback(function () {
  84. canvg(c, data.svg, {renderCallback: function() {
  85. var pre, filename, suffix,
  86. datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType),
  87. // uiStrings = svgEditor.uiStrings,
  88. note = '';
  89. // Check if there are issues
  90. if (issues.length) {
  91. pre = "\n \u2022 ";
  92. note += ("\n\n" + pre + issues.join(pre));
  93. }
  94. if(note.length) {
  95. alert(note);
  96. }
  97. filename = getFileNameFromTitle();
  98. suffix = '.' + data.type.toLowerCase();
  99. if (clientDownloadSupport(filename, suffix, datauri)) {
  100. return;
  101. }
  102. $('<form>').attr({
  103. method: 'post',
  104. action: save_img_action,
  105. target: 'output_frame'
  106. }).append('<input type="hidden" name="output_img" value="' + datauri + '">')
  107. .append('<input type="hidden" name="mime" value="' + mimeType + '">')
  108. .append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
  109. .appendTo('body')
  110. .submit().remove();
  111. }});
  112. })();
  113. }
  114. });
  115. // Do nothing if client support is found
  116. if (window.FileReader) {return;}
  117. // Change these to appropriate script file
  118. open_svg_action = svgEditor.curConfig.extPath + 'fileopen.php?type=load_svg';
  119. import_svg_action = svgEditor.curConfig.extPath + 'fileopen.php?type=import_svg';
  120. import_img_action = svgEditor.curConfig.extPath + 'fileopen.php?type=import_img';
  121. // Set up function for PHP uploader to use
  122. svgEditor.processFile = function(str64, type) {
  123. var xmlstr;
  124. if (cancelled) {
  125. cancelled = false;
  126. return;
  127. }
  128. $('#dialog_box').hide();
  129. if (type !== 'import_img') {
  130. xmlstr = Utils.decode64(str64);
  131. }
  132. switch (type) {
  133. case 'load_svg':
  134. svgCanvas.clear();
  135. svgCanvas.setSvgString(xmlstr);
  136. svgEditor.updateCanvas();
  137. break;
  138. case 'import_svg':
  139. svgCanvas.importSvgString(xmlstr);
  140. svgEditor.updateCanvas();
  141. break;
  142. case 'import_img':
  143. svgCanvas.setGoodImage(str64);
  144. break;
  145. }
  146. };
  147. // Create upload form
  148. open_svg_form = $('<form>');
  149. open_svg_form.attr({
  150. enctype: 'multipart/form-data',
  151. method: 'post',
  152. action: open_svg_action,
  153. target: 'output_frame'
  154. });
  155. // Create import form
  156. import_svg_form = open_svg_form.clone().attr('action', import_svg_action);
  157. // Create image form
  158. import_img_form = open_svg_form.clone().attr('action', import_img_action);
  159. // It appears necessary to rebuild this input every time a file is
  160. // selected so the same file can be picked and the change event can fire.
  161. function rebuildInput(form) {
  162. form.empty();
  163. var inp = $('<input type="file" name="svg_file">').appendTo(form);
  164. function submit() {
  165. // This submits the form, which returns the file data using svgEditor.processFile()
  166. form.submit();
  167. rebuildInput(form);
  168. $.process_cancel("Uploading...", function() {
  169. cancelled = true;
  170. $('#dialog_box').hide();
  171. });
  172. }
  173. if(form[0] == open_svg_form[0]) {
  174. inp.change(function() {
  175. // This takes care of the "are you sure" dialog box
  176. svgEditor.openPrep(function(ok) {
  177. if(!ok) {
  178. rebuildInput(form);
  179. return;
  180. }
  181. submit();
  182. });
  183. });
  184. } else {
  185. inp.change(function() {
  186. // This submits the form, which returns the file data using svgEditor.processFile()
  187. submit();
  188. });
  189. }
  190. }
  191. // Create the input elements
  192. rebuildInput(open_svg_form);
  193. rebuildInput(import_svg_form);
  194. rebuildInput(import_img_form);
  195. // Add forms to buttons
  196. $("#tool_open").show().prepend(open_svg_form);
  197. $("#tool_import").show().prepend(import_svg_form);
  198. $("#tool_image").prepend(import_img_form);
  199. }
  200. });