From 5f4caf6c53ace7dfb46820100a03de42cbfd20f5 Mon Sep 17 00:00:00 2001 From: Alexis Deveria Date: Wed, 18 Nov 2009 16:50:25 +0000 Subject: [PATCH] Finished up changes to inline image behaviour, many fixes from last update git-svn-id: http://svg-edit.googlecode.com/svn/trunk@953 eee81c28-f429-11dd-99c0-75d572ba1ddd --- editor/images/svg_edit_icons.svg | 14 +++++++ editor/svg-editor.css | 4 ++ editor/svg-editor.html | 2 +- editor/svg-editor.js | 72 ++++++++++++++++++++------------ editor/svgcanvas.js | 51 ++++++++++------------ 5 files changed, 87 insertions(+), 56 deletions(-) diff --git a/editor/images/svg_edit_icons.svg b/editor/images/svg_edit_icons.svg index 82782e11..9e06b0d2 100644 --- a/editor/images/svg_edit_icons.svg +++ b/editor/images/svg_edit_icons.svg @@ -669,6 +669,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/editor/svg-editor.css b/editor/svg-editor.css index b7651cd6..8f28e7ae 100644 --- a/editor/svg-editor.css +++ b/editor/svg-editor.css @@ -470,6 +470,10 @@ span.zoom_tool { font-style: italic; } +#url_notice { + padding-top: 4px; + display: none; +} #svg_editor #color_picker { position: absolute; diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 2ae66a9a..435f4cf4 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -183,7 +183,7 @@ script type="text/javascript" src="locale/locale.min.js"> - +
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index a466a193..a22d17b1 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -20,7 +20,8 @@ function svg_edit_setup() { 'QwantToClear':'Do you want to clear the drawing?\nThis will also erase your undo history!', 'QerrorsRevertToSource':'There were parsing errors in your SVG source.\nRevert back to original SVG source?', 'QignoreSourceChanges':'Ignore changes made to SVG source?', - 'featNotSupported':'Feature not supported' + 'featNotSupported':'Feature not supported', + 'enterNewImgURL':'Enter the new image URL' }; var palette = ["#000000","#202020","#404040","#606060","#808080","#a0a0a0","#c0c0c0","#e0e0e0","#ffffff","#800000","#ff0000","#808000","#ffff00","#008000","#00ff00","#008080","#00ffff","#000080","#0000ff","#800080","#ff00ff","#2b0000","#550000","#800000","#aa0000","#d40000","#ff0000","#ff2a2a","#ff5555","#ff8080","#ffaaaa","#ffd5d5","#280b0b","#501616","#782121","#a02c2c","#c83737","#d35f5f","#de8787","#e9afaf","#f4d7d7","#241c1c","#483737","#6c5353","#916f6f","#ac9393","#c8b7b7","#e3dbdb","#2b1100","#552200","#803300","#aa4400","#d45500","#ff6600","#ff7f2a","#ff9955","#ffb380","#ffccaa","#ffe6d5","#28170b","#502d16","#784421","#a05a2c","#c87137","#d38d5f","#deaa87","#e9c6af","#f4e3d7","#241f1c","#483e37","#6c5d53","#917c6f","#ac9d93","#c8beb7","#e3dedb","#2b2200","#554400","#806600","#aa8800","#d4aa00","#ffcc00","#ffd42a","#ffdd55","#ffe680","#ffeeaa","#fff6d5","#28220b","#504416","#786721","#a0892c","#c8ab37","#d3bc5f","#decd87","#e9ddaf","#f4eed7","#24221c","#484537","#6c6753","#918a6f","#aca793","#c8c4b7","#e3e2db","#222b00","#445500","#668000","#88aa00","#aad400","#ccff00","#d4ff2a","#ddff55","#e5ff80","#eeffaa","#f6ffd5","#22280b","#445016","#677821","#89a02c","#abc837","#bcd35f","#cdde87","#dde9af","#eef4d7","#22241c","#454837","#676c53","#8a916f","#a7ac93","#c4c8b7","#e2e3db","#112b00","#225500","#338000","#44aa00","#55d400","#66ff00","#7fff2a","#99ff55","#b3ff80","#ccffaa","#e5ffd5","#17280b","#2d5016","#447821","#5aa02c","#71c837","#8dd35f","#aade87","#c6e9af","#e3f4d7","#1f241c","#3e4837","#5d6c53","#7c916f","#9dac93","#bec8b7","#dee3db","#002b00","#005500","#008000","#00aa00","#00d400","#00ff00","#2aff2a","#55ff55","#80ff80","#aaffaa","#d5ffd5","#0b280b","#165016","#217821","#2ca02c","#37c837","#5fd35f","#87de87","#afe9af","#d7f4d7","#1c241c","#374837","#536c53","#6f916f","#93ac93","#b7c8b7","#dbe3db","#002b11","#005522","#008033","#00aa44","#00d455","#00ff66","#2aff80","#55ff99","#80ffb3","#aaffcc","#d5ffe6","#0b2817","#16502d","#217844","#2ca05a","#37c871","#5fd38d","#87deaa","#afe9c6","#d7f4e3","#1c241f","#37483e","#536c5d","#6f917c","#93ac9d","#b7c8be","#dbe3de","#002b22","#005544","#008066","#00aa88","#00d4aa","#00ffcc","#2affd5","#55ffdd","#80ffe6","#aaffee","#d5fff6","#0b2822","#165044","#217867","#2ca089","#37c8ab","#5fd3bc","#87decd","#afe9dd","#d7f4ee","#1c2422","#374845","#536c67","#6f918a","#93aca7","#b7c8c4","#dbe3e2","#00222b","#004455","#006680","#0088aa","#00aad4","#00ccff","#2ad4ff","#55ddff","#80e5ff","#aaeeff","#d5f6ff","#0b2228","#164450","#216778","#2c89a0","#37abc8","#5fbcd3","#87cdde","#afdde9","#d7eef4","#1c2224","#374548","#53676c","#6f8a91","#93a7ac","#b7c4c8","#dbe2e3","#00112b","#002255","#003380","#0044aa","#0055d4","#0066ff","#2a7fff","#5599ff","#80b3ff","#aaccff","#d5e5ff","#0b1728","#162d50","#214478","#2c5aa0","#3771c8","#5f8dd3","#87aade","#afc6e9","#d7e3f4","#1c1f24","#373e48","#535d6c","#6f7c91","#939dac","#b7bec8","#dbdee3","#00002b","#000055","#000080","#0000aa","#0000d4","#0000ff","#2a2aff","#5555ff","#8080ff","#aaaaff","#d5d5ff","#0b0b28","#161650","#212178","#2c2ca0","#3737c8","#5f5fd3","#8787de","#afafe9","#d7d7f4","#1c1c24","#373748","#53536c","#6f6f91","#9393ac","#b7b7c8","#dbdbe3","#11002b","#220055","#330080","#4400aa","#5500d4","#6600ff","#7f2aff","#9955ff","#b380ff","#ccaaff","#e5d5ff","#170b28","#2d1650","#442178","#5a2ca0","#7137c8","#8d5fd3","#aa87de","#c6afe9","#e3d7f4","#1f1c24","#3e3748","#5d536c","#7c6f91","#9d93ac","#beb7c8","#dedbe3","#22002b","#440055","#660080","#8800aa","#aa00d4","#cc00ff","#d42aff","#dd55ff","#e580ff","#eeaaff","#f6d5ff","#220b28","#441650","#672178","#892ca0","#ab37c8","#bc5fd3","#cd87de","#ddafe9","#eed7f4","#221c24","#453748","#67536c","#8a6f91","#a793ac","#c4b7c8","#e2dbe3","#2b0022","#550044","#800066","#aa0088","#d400aa","#ff00cc","#ff2ad4","#ff55dd","#ff80e5","#ffaaee","#ffd5f6","#280b22","#501644","#782167","#a02c89","#c837ab","#d35fbc","#de87cd","#e9afdd","#f4d7ee","#241c22","#483745","#6c5367","#916f8a","#ac93a7","#c8b7c4","#e3dbe2","#2b0011","#550022","#800033","#aa0044","#d40055","#ff0066","#ff2a7f","#ff5599","#ff80b2","#ffaacc","#ffd5e5","#280b17","#50162d","#782144","#a02c5a","#c83771","#d35f8d","#de87aa","#e9afc6","#f4d7e3","#241c1f","#48373e","#6c535d","#916f7c","#ac939d","#c8b7be","#e3dbde"] @@ -28,10 +29,11 @@ function svg_edit_setup() { var isMac = false; //(navigator.platform.indexOf("Mac") != -1); var modKey = ""; //(isMac ? "meta+" : "ctrl+"); var svgCanvas = new SvgCanvas(document.getElementById("svgcanvas")); + var default_img_url = "images/logo.png"; // Store and retrieve preferences $.pref = function(key, val) { - curPrefs[key] = val; + if(val) curPrefs[key] = val; key = 'svg-edit-'+key; var host = location.hostname; var onweb = host && host.indexOf('.') != -1; @@ -282,13 +284,13 @@ function svg_edit_setup() { var updateContextPanel = function() { var elem = selectedElement; var currentLayer = svgCanvas.getCurrentLayer(); - // No need to update anything else in rotate mode if (svgCanvas.getMode() == 'rotate' && elem != null) { $('#angle').val(svgCanvas.getRotationAngle(elem)); return; + } else if(svgCanvas.addedNew && elem.nodeName == 'image') { + promptImgURL(); } - var is_node = elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false; $('#selected_panel, #multiselected_panel, #g_panel, #rect_panel, #circle_panel,\ @@ -429,6 +431,11 @@ function svg_edit_setup() { if($.pref('bg_color')) { setBackground($.pref('bg_color'), $.pref('bg_url')); } + + if($.pref('img_save')) { + curPrefs.img_save = $.pref('img_save'); + $('#image_save_opts input').val([curPrefs.img_save]); + } var pos = $('#tools_rect_show').position(); $('#tools_rect').css({'left': pos.left+4, 'top': pos.top+77}); @@ -509,8 +516,7 @@ function svg_edit_setup() { svgCanvas.setTextContent(this.value); }); - // TODO: consider only setting the URL once Enter has been pressed? - $('#image_url').keyup(function(){ + $('#image_url').change(function(){ setImageURL(this.value); }); @@ -1019,6 +1025,7 @@ function svg_edit_setup() { // set image save option curPrefs.img_save = $('#image_save_opts :checked').val(); + $.pref('img_save',curPrefs.img_save); // set background var color = $('#bg_blocks div.cur_background').css('background') || '#FFF'; @@ -1061,7 +1068,7 @@ function svg_edit_setup() { var size_num = icon_sizes[size]; // Change icon size - $('.tool_button, .push_button, .tool_button_current, .tool_button_disabled, .tool_flyout_button') + $('.tool_button, .push_button, .tool_button_current, .tool_button_disabled, .tool_flyout_button, #url_notice') .find('> svg').each(function() { this.setAttribute('width',size_num); this.setAttribute('height',size_num); @@ -1276,10 +1283,17 @@ function svg_edit_setup() { $('#tools_ellipse_show').click(clickCircle); $('#tool_bold').mousedown(clickBold); $('#tool_italic').mousedown(clickItalic); - $('#change_image_url').click(function() { - var url = prompt("Select the new image URL","http://"); - if(url) setImageURL(url); + + $('#url_notice').click(function() { + alert(this.title); }); + + $('#change_image_url').click(promptImgURL); + + function promptImgURL() { + var url = prompt(uiStrings.enterNewImgURL, default_img_url); + if(url) setImageURL(url); + } function setImageURL(url) { svgCanvas.setImageURL(url); @@ -1292,14 +1306,15 @@ function svg_edit_setup() { } else { // regular URL - var img = svgCanvas.embedImage(url); - if(img == url && curPrefs.img_save == 'embed') { - // Couldn't embed, so show warning - $('#url_notice').show(); - } else { - $('#url_notice').hide(); - } - + svgCanvas.embedImage(url, function(datauri) { + if(!datauri) { + // Couldn't embed, so show warning + $('#url_notice').show(); + } else { + $('#url_notice').hide(); + } + default_img_url = url; + }); $('#image_url').show(); $('#change_image_url').hide(); } @@ -1423,8 +1438,8 @@ function svg_edit_setup() { $(document).bind('keydown', {combi:item[0], disableInInput: disable}, item[1]); }); - $('.attr_changer').bind('keydown', {combi:'return', disableInInput: false}, - function(evt) {$(this).change();evt.preventDefault();} + $('.attr_changer, #image_url').bind('keydown', {combi:'return', disableInInput: false}, + function(evt) {console.log('now');$(this).change();evt.preventDefault();} ); } @@ -1548,12 +1563,15 @@ function svg_edit_setup() { // Test for embedImage support (use timeout to not interfere with page load) setTimeout(function() { - var img = svgCanvas.embedImage('images/logo.png'); - if(img.indexOf('data:') !== 0) { - // Disable option - $('#image_save_opts [value=embed]').attr('disabled','disabled'); - $('#image_opt_embed').css('color','#666').attr('title',uiStrings.featNotSupported); - } + svgCanvas.embedImage('images/logo.png', function(datauri) { + if(!datauri) { + // Disable option + $('#image_save_opts [value=embed]').attr('disabled','disabled'); + $('#image_save_opts input').val(['ref']); + curPrefs.img_save = 'ref'; + $('#image_opt_embed').css('color','#666').attr('title',uiStrings.featNotSupported); + } + }); },1000); $('#fill_color').click(function(){ @@ -2082,6 +2100,8 @@ function setSVGIcons() { '#tool_alignmiddle':'align_middle', '#tool_alignbottom':'align_bottom', + '#url_notice':'warning', + '#layer_up':'go_up', '#layer_down':'go_down', '#layerlist td.layervis':'eye', diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 2e0a8726..e9048673 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -826,6 +826,8 @@ function BatchCommand(text) { // z-ordered array of tuples containing layer names and elements // the first layer is the one at the bottom of the rendering var all_layers = []; + var encodableImages = {}; + var last_good_img_url = 'images/logo.png'; // pointer to the current layer var current_layer = null; var save_options = {round_digits: 5}; @@ -1114,7 +1116,8 @@ function BatchCommand(text) { && attr.localName == 'href' && save_options.images && save_options.images == 'embed') { - attrVal = canvas.embedImage(attrVal); + var img = encodableImages[attrVal]; + if(img) attrVal = img; } // map various namespaces to our fixed namespace prefixes // TODO: put this into a map and do a look-up instead of if-else @@ -1173,13 +1176,7 @@ function BatchCommand(text) { return out.join(''); }; // end svgToString() - this.embedImage = function(val, img, attempts) { - var result; - - if(!attempts) attempts = 0; - // Prevent endless loop if image cannot be loaded - if(attempts > 100) return val; - attempts++; + this.embedImage = function(val, callback) { // Below is some code to fetch the data: URL representation // of local image files. It is commented out until we figure out @@ -1187,29 +1184,24 @@ function BatchCommand(text) { // does not work in Firefox at all :( // load in the image and once it's loaded, get the dimensions - if(!img) { - img = document.createElement("img"); - img.setAttribute("src", val); - } - - if (img.width > 0 && img.height > 0) { + $(new Image()).load(function() { // create a canvas the same size as the raster image var canvas = document.createElement("canvas"); - canvas.width = img.width; - canvas.height = img.height; + canvas.width = this.width; + canvas.height = this.height; // load the raster image into the canvas - canvas.getContext("2d").drawImage(img,0,0); + canvas.getContext("2d").drawImage(this,0,0); // retrieve the data: URL try { var urldata = ';svgedit_url=' + encodeURIComponent(val); - result = canvas.toDataURL().replace(';base64',urldata+';base64'); + urldata = canvas.toDataURL().replace(';base64',urldata+';base64'); + encodableImages[val] = urldata; } catch(e) { - result = val; + encodableImages[val] = false; } - } - if(result) return result; - - return canvas.embedImage(val, img, attempts); + last_good_img_url = val; + if(callback) callback(encodableImages[val]); + }).attr('src',val); } // importNode, like cloneNode, causes the comma-to-period @@ -1220,9 +1212,9 @@ function BatchCommand(text) { $.each(x_attrs, function(i, attr) { if(attr.nodeValue.indexOf(',') == -1) return; // attr val has comma, so let's get the good value - var ns = attr.nodeName == 'href' ? xlinkns : + var ns = attr.prefix == 'xlink' ? xlinkns : attr.prefix == "xml" ? xmlns : null; - var good_attrval = orig_el.getAttribute(attr.nodeName); + var good_attrval = orig_el.getAttribute(attr.localName); if(ns) { elem.setAttributeNS(ns, attr.nodeName, good_attrval); } else { @@ -2322,7 +2314,7 @@ function BatchCommand(text) { "style": "pointer-events:inherit" } }); - newImage.setAttributeNS(xlinkns, "href", "images/logo.png"); + newImage.setAttributeNS(xlinkns, "href", last_good_img_url); break; case "square": // FIXME: once we create the rect, we lose information that this was a square @@ -3848,7 +3840,6 @@ function BatchCommand(text) { canvas.setMode("select"); } - } else if (element != null) { canvas.addedNew = true; element.setAttribute("opacity", cur_shape.opacity); @@ -3859,8 +3850,8 @@ function BatchCommand(text) { current_mode = "pathedit"; recalcPathPoints(); addAllPointGripsToPath(current_path_pts.length/2 - 1); - } else if (current_mode == "text") { - // keep us in the tool we were in unless it was a text element + } else if (current_mode == "text" || current_mode == "image") { + // keep us in the tool we were in unless it was a text or image element canvas.addToSelection([element], true); } // we create the insert command that is stored on the stack @@ -3963,6 +3954,8 @@ function BatchCommand(text) { }).attr('src',url); } } + // Add to encodableImages if it loads + canvas.embedImage(val); }); // Fix XML for Opera/Win/Non-EN