foreignObject Support in SVG-Edit

Added support so that you can
create new foreignObjects, manipulate
existing ones, and edit their content.

No itex support. You need to use MathML
in there. But it's a start ...
This commit is contained in:
Jacques Distler 2010-02-12 00:01:27 -06:00
parent 9047e5d460
commit 502d4f20bb
6 changed files with 366 additions and 77 deletions

View file

@ -165,6 +165,7 @@ function svg_edit_setup() {
var selectedElement = null;
var multiselected = false;
var editingsource = false;
var editingforeign = false;
var docprops = false;
var fillPaint = new $.jGraduate.Paint({solidColor: "FF0000"}); // solid red
@ -705,7 +706,7 @@ function svg_edit_setup() {
var is_node = currentMode == 'pathedit'; //elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false;
$('#selected_panel, #multiselected_panel, #g_panel, #rect_panel, #circle_panel,\
#ellipse_panel, #line_panel, #text_panel, #image_panel').hide();
#ellipse_panel, #line_panel, #text_panel, #image_panel, #foreignObject_panel').hide();
if (elem != null) {
var elname = elem.nodeName;
var angle = svgCanvas.getRotationAngle(elem);
@ -771,6 +772,7 @@ function svg_edit_setup() {
circle: ['cx','cy','r'],
ellipse: ['cx','cy','rx','ry'],
line: ['x1','y1','x2','y2'],
foreignObject: [],
text: []
};
@ -807,6 +809,12 @@ function svg_edit_setup() {
$('#text').focus().select();
}
} // text
else if (el_name == 'foreignObject') {
$('#foreignObject_panel').css("display", "inline");
$('#foreign_font_size').val(elem.getAttribute("font-size"));
$('#foreign_width').val(elem.getAttribute("width"));
$('#foreign_height').val(elem.getAttribute("height"));
} //foreignObject
else if(el_name == 'image') {
var xlinkNS="http://www.w3.org/1999/xlink";
var href = elem.getAttributeNS(xlinkNS, "href");
@ -1294,7 +1302,12 @@ function svg_edit_setup() {
toolButtonClick('#tool_text');
svgCanvas.setMode('text');
};
var clickForeign = function(){
toolButtonClick('#tool_foreign');
svgCanvas.setMode('foreign');
};
var clickPath = function(){
toolButtonClick('#tool_path');
svgCanvas.setMode('path');
@ -1499,10 +1512,21 @@ function svg_edit_setup() {
var str = svgCanvas.getSvgString();
$('#svg_source_textarea').val(str);
$('#svg_source_editor').fadeIn();
properlySourceSizeTextArea();
properlySourceSizeTextArea('source');
$('#svg_source_textarea').focus();
};
var showForeignEditor = function(elt){
if (!elt || editingforeign) return;
editingforeign = true;
elt.removeAttribute('fill');
var str = svgCanvas.getForeignString(elt);
$('#svg_foreign_textarea').val(str);
$('#svg_foreign_editor').fadeIn();
properlySourceSizeTextArea('foreign');
$('#svg_foreign_textarea').focus();
};
$('#svg_docprops_container').draggable({cancel:'button,fieldset'});
var showDocProperties = function(){
@ -1538,18 +1562,40 @@ function svg_edit_setup() {
$('#svg_docprops').fadeIn();
};
var properlySourceSizeTextArea = function(){
var properlySourceSizeTextArea = function(str){
// TODO: remove magic numbers here and get values from CSS
var height = $('#svg_source_container').height() - 80;
$('#svg_source_textarea').css('height', height);
var height = $('#svg_'+str+'_container').height() - 80;
$('#svg_'+str+'_textarea').css('height', height);
};
var saveForeignEditor = function(elt){
if (!editingforeign) return;
var saveChanges = function() {
svgCanvas.clearSelection();
hideSourceEditor('foreign');
zoomImage();
populateLayers();
setTitle(svgCanvas.getImageTitle());
}
if (!svgCanvas.setForeignString($('#svg_foreign_textarea').val(), elt)) {
$.confirm(uiStrings.QerrorsRevertToSource, function(ok) {
if(!ok) return false;
saveChanges();
});
} else {
saveChanges();
}
setSelectMode();
}
var saveSourceEditor = function(){
if (!editingsource) return;
var saveChanges = function() {
svgCanvas.clearSelection();
hideSourceEditor();
hideSourceEditor('source');
zoomImage();
populateLayers();
setTitle(svgCanvas.getImageTitle());
@ -1776,18 +1822,28 @@ function svg_edit_setup() {
setFlyoutPositions();
}
var cancelOverlays = function() {
var cancelOverlays = function(elt) {
$('#dialog_box').hide();
if (!editingsource && !docprops) return;
if (!editingsource && !editingforeign && !docprops) return;
if (editingsource) {
var oldString = svgCanvas.getSvgString();
if (oldString != $('#svg_source_textarea').val()) {
$.confirm(uiStrings.QignoreSourceChanges, function(ok) {
if(ok) hideSourceEditor();
if(ok) hideSourceEditor('source');
});
} else {
hideSourceEditor();
hideSourceEditor('source');
}
}
else if (editingforeign) {
var oldString = svgCanvas.getForeignString(elt);
if (oldString != $('#svg_foreign_textarea').val()) {
$.confirm(uiStrings.QignoreSourceChanges, function(ok) {
if(ok) hideSourceEditor('foreign');
});
} else {
hideSourceEditor('foreign');
}
}
else if (docprops) {
@ -1796,10 +1852,11 @@ function svg_edit_setup() {
};
var hideSourceEditor = function(){
$('#svg_source_editor').hide();
var hideSourceEditor = function(str){
$('#svg_'+str+'_editor').hide();
editingsource = false;
$('#svg_source_textarea').blur();
editingforeign = false;
$('#svg_'+str+'_textarea').blur();
};
var hideDocProperties = function(){
@ -1812,8 +1869,11 @@ function svg_edit_setup() {
// TODO: add canvas-centering code in here
$(window).resize(function(evt) {
if (!editingsource) return;
properlySourceSizeTextArea();
if (editingsource) {
properlySourceSizeTextArea('source');
} else if(editingforeign) {
properlySourceSizeTextArea('foreign');
}
});
$('#url_notice').click(function() {
@ -1949,7 +2009,7 @@ function svg_edit_setup() {
var bNoFill = (svgCanvas.getFillColor() == 'none');
var bNoStroke = (svgCanvas.getStrokeColor() == 'none');
var buttonsNeedingStroke = [ '#tool_fhpath', '#tool_line' ];
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text', '#tool_path'];
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text', '#tool_foreign', '#tool_path', '#tool_edit_foreign'];
if (bNoStroke) {
for (index in buttonsNeedingStroke) {
var button = buttonsNeedingStroke[index];
@ -2412,13 +2472,19 @@ function svg_edit_setup() {
{sel:'#tool_text', fn: clickText, evt: 'click', key: 7},
{sel:'#tool_image', fn: clickImage, evt: 'mouseup', key: 8},
{sel:'#tool_zoom', fn: clickZoom, evt: 'mouseup', key: 9},
{sel:'#tool_foreign', fn: clickForeign, evt: 'mouseup'},
{sel:'#tool_edit_foreign', fn: function(){showForeignEditor(selectedElement)}, evt: 'mouseup'},
{sel:'#tool_clear', fn: clickClear, evt: 'mouseup', key: [modKey+'N', true]},
{sel:'#tool_save', fn: function() { editingsource?saveSourceEditor():clickSave()}, evt: 'mouseup', key: [modKey+'S', true]},
{sel:'#tool_save', fn: function() { if(editingsource){saveSourceEditor()}
else if(editingforeign){saveForeignEditor(selectedElement)}
else clickSave()}, evt: 'mouseup', key: [modKey+'S', true]},
{sel:'#tool_open', fn: clickOpen, evt: 'mouseup', key: [modKey+'O', true]},
{sel:'#tool_source', fn: showSourceEditor, evt: 'click', key: ['U', true]},
{sel:'#tool_wireframe', fn: clickWireframe, evt: 'click', key: ['F', true]},
{sel:'#tool_source_cancel,#svg_source_overlay,#tool_docprops_cancel', fn: cancelOverlays, evt: 'click', key: ['esc', false, false], hidekey: true},
{sel:'#tool_foreign_cancel,#svg_source_overlay,#tool_docprops_cancel', fn: function(){cancelOverlays(selectedElement)}, evt: 'click', key: ['esc', false, false], hidekey: true},
{sel:'#tool_source_save', fn: saveSourceEditor, evt: 'click'},
{sel:'#tool_foreign_save', fn: function(){saveForeignEditor(selectedElement)}, evt: 'click'},
{sel:'#tool_docprops_save', fn: saveDocProperties, evt: 'click'},
{sel:'#tool_docprops', fn: showDocProperties, evt: 'mouseup', key: [modKey+'I', true]},
{sel:'#tool_delete,#tool_delete_multi', fn: deleteSelected, evt: 'click', key: ['del/backspace', true]},
@ -2718,7 +2784,7 @@ function svg_edit_setup() {
updateCanvas(true);
});
// var revnums = "svg-editor.js ($Rev: 1372 $) ";
// var revnums = "svg-editor.js ($Rev: 1377 $) ";
// revnums += svgCanvas.getVersion();
// $('#copyright')[0].setAttribute("title", revnums);
return svgCanvas;
@ -2756,6 +2822,8 @@ function svg_edit_setup() {
'text':'text.png',
'image':'image.png',
'zoom':'zoom.png',
'foreign':'foreign.png',
'edit_foreign':'edit_foreign.png',
'clone':'clone.png',
'delete':'delete.png',
@ -2809,6 +2877,8 @@ function svg_edit_setup() {
'#tool_text,#layer_rename':'text',
'#tool_image':'image',
'#tool_zoom':'zoom',
'#tool_foreign':'foreign',
'#tool_edit_foreign':'edit_foreign',
'#tool_clone,#tool_clone_multi,#tool_node_clone':'clone',
'#layer_delete,#tool_delete,#tool_delete_multi,#tool_node_delete':'delete',
@ -2833,8 +2903,8 @@ function svg_edit_setup() {
'#layer_down':'go_down',
'#layerlist td.layervis':'eye',
'#tool_source_save,#tool_docprops_save':'ok',
'#tool_source_cancel,#tool_docprops_cancel':'cancel',
'#tool_source_save,#tool_foreign_save,#tool_docprops_save':'ok',
'#tool_source_cancel,#tool_foreign_cancel,#tool_docprops_cancel':'cancel',
'.flyout_arrow_horiz':'arrow_right',
'.dropdown button, #main_button .dropdown':'arrow_down',
@ -2907,7 +2977,11 @@ function svg_edit_setup() {
// This happens when the page is loaded
$(function() {
svgCanvas = svg_edit_setup();
put_locale(svgCanvas);
var good_langs = [];
$('#lang_select option').each(function() {
good_langs.push(this.value);
});
put_locale(svgCanvas, null, good_langs);
try{
json_encode = function(obj){