Fixed Issue 123: Support for <a> element to make elements link to URLs

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1878 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Alexis Deveria 2010-12-01 17:54:11 +00:00
parent fe03c8f7e4
commit aafe843485
6 changed files with 172 additions and 14 deletions

View File

@ -251,7 +251,7 @@ svgEditor.addExtension("Connector", function(S) {
svgCanvas.groupSelectedElements = function() {
svgCanvas.removeFromSelection($(conn_sel).toArray());
gse();
return gse.apply(this, arguments);
}
var mse = svgCanvas.moveSelectedElements;

View File

@ -999,6 +999,36 @@
</svg>
</g>
<g id="globe_link">
<svg width="66" height="66" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="svg_8" spreadMethod="pad" cx="0.5" cy="0.32513">
<stop stop-color="#7791ef" stop-opacity="0.99219" offset="0"/>
<stop stop-color="#3c3cfc" offset="1"/>
</radialGradient>
<linearGradient id="svg_10" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#333333" stop-opacity="0.99609"/>
<stop offset="1" stop-opacity="0.99609" stop-color="#666666"/>
</linearGradient>
</defs>
<g>
<title>Layer 1</title>
<g opacity="0.8" id="svg_5">
<circle id="svg_1" r="27.90625" cy="33" cx="33" stroke-width="0" stroke="#AAAAAA" fill="url(#svg_8)"/>
<g id="svg_7">
<path d="m38.2478,36.06121c-0.43732,0 -0.87463,0 -1.31195,0c-0.43731,0 -0.87463,0 -2.6239,0c-0.87463,0 -1.74926,0 -2.18658,0c-0.43732,0 -2.19828,0.33684 -2.6239,0.43732c-0.95172,0.22467 -1.27098,0.48253 -1.74927,0.87463c-1.21939,0.99965 -1.44004,1.00272 -1.74926,1.31195c-0.30923,0.30923 -0.21265,0.79756 -0.43732,1.74926c-0.10048,0.42562 0.16736,0.90792 0,1.31195c-0.23668,0.57138 -0.43732,0.87463 -0.43732,1.74926c0,0.43732 0.12809,0.56541 0.43732,0.87463c0.30923,0.30923 0.12809,0.56541 0.43732,0.87463c0.30923,0.30923 1.32364,0.77415 1.74926,0.87463c0.95171,0.22467 0.69349,0.69349 1.31195,1.31195c0.30923,0.30923 0.90791,-0.16736 1.31195,0c0.57138,0.23668 0.56541,0.56541 0.87463,0.87463c0.30923,0.30923 0.56541,0.12809 0.87463,0.43732c0.61846,0.61846 -0.10048,1.32365 0,1.74926c0.22467,0.95171 0.43732,1.31195 0.43732,2.6239c0,0.87463 0,2.18658 0,3.06121c0,0.43732 0,1.31195 0,2.6239c0,0.43732 0.12809,1.00272 0.43732,1.31195c0.30922,0.30923 1.31195,0 1.74926,0c0.87463,0 1.31195,0 1.74927,0c0.43731,0 0.6065,-0.40129 1.74926,-0.87464c0.40403,-0.16736 0.74057,-0.20064 1.31195,-0.43732c0.40403,-0.16736 0.63795,-0.74057 0.87463,-1.31195c0.16736,-0.40403 0.15712,-2.20917 0.43732,-3.93585c0.22151,-1.36505 0.43732,-2.18658 0.43732,-2.6239c0,-0.43732 -0.12928,-0.88101 0,-2.18658c0.21973,-2.21904 0.43732,-3.49853 0.43732,-3.93585c0,-0.43732 0,-0.87463 0,-1.74927c0,-1.31195 0.16736,-1.78254 0,-2.18658c-0.23668,-0.57138 -1.00272,-0.56541 -1.31195,-0.87463c-0.30923,-0.30922 -0.43732,-0.43731 -1.74926,-1.74926l0,-0.87463l-0.43732,0l0,-0.43732" id="svg_2" stroke="#007f00" fill="#44b544" stroke-width="0"/>
<path d="m5.66773,37.0452c1.12973,-0.3645 0.87463,-0.2187 1.74927,-0.656c0.87463,-0.4373 1.34081,-0.8211 2.18658,-1.3119c1.36372,-0.7915 1.44002,-1.4401 1.74922,-1.7493c0.3093,-0.3092 0.1281,-0.5654 0.4374,-0.8746c0.6184,-0.6185 0.8746,-0.4374 1.7492,-1.312c0.8747,-0.8746 1.0027,-1.0027 1.312,-1.3119c0.6184,-0.6185 0.1281,-1.0028 0.4373,-1.312c0.3092,-0.3092 0,-0.8746 0,-1.3119c0,-0.4374 0,-1.312 0,-1.7493c0,-0.4373 0.2009,-1.7727 0,-2.6239c-0.2247,-0.9517 -0.1281,-1.4401 -0.4373,-1.7493c-0.3093,-0.3092 -0.7073,-1.3452 -0.8746,-1.7492c-0.2367,-0.5714 -0.8747,-0.8747 -0.8747,-1.312c0,-0.4373 -0.4373,-0.4373 -0.4373,-0.8746l0,-0.4374l-1.2026,-0.8746c-3.7901,5.8674 -6.81486,11.6253 -5.79446,21.2099l-0.00001,0z" id="svg_3" stroke="#007f00" fill="#44b544" stroke-width="0"/>
<path d="m52.2419,13.1021c-0.4373,0.4373 -1.3495,0.8398 -2.1866,1.0933c-3.0182,0.9138 -3.2212,2.2857 -3.4985,2.6239c-1.4137,1.7245 -2.4979,1.3039 -4.8105,1.7493c-0.4294,0.0827 -0.4373,0.4373 -0.8746,0.4373c-0.4373,0 -0.8746,0 -1.312,0c-0.4373,0 -1.3119,0 -1.7492,0c-0.4373,0 -1.3453,-0.27 -1.7493,-0.4373c-0.5714,-0.2367 -0.5654,-0.5654 -0.8746,-0.8747c-0.3092,-0.3092 -0.5654,-0.1281 -0.8746,-0.4373c-0.3093,-0.3092 -0.8747,0 -1.312,0c-0.4373,0 -0.9079,-0.1673 -1.3119,0c-0.5714,0.2367 -0.3033,1.0753 -0.8747,1.312c-0.404,0.1673 -0.1281,0.5654 -0.4373,0.8746c-0.3092,0.3092 -0.4373,0.4373 -0.4373,0.8746c0,0.4373 0,0.8747 0,1.312c0,0.4373 0.0333,0.7073 0.4373,0.8746c0.5714,0.2367 0.638,0.7406 0.8746,1.312c0.1674,0.404 0.4374,0.4373 0.4374,0.8746c0,0.4373 0,0.8746 0,1.3119c0,0.4374 -0.4374,0.4374 -0.8747,0.8747c-1.3119,1.3119 -1.9499,1.1779 -2.1865,1.7492c-0.1674,0.4041 -1.0753,0.3033 -1.312,0.8747c-0.1674,0.404 0,0.8746 0.4373,0.8746c0.4373,0 0.8746,0.4373 1.312,0.4373c0.4373,0 0.8746,-0.4373 1.3119,-0.4373c0.4373,0 0.5654,-0.1281 0.8746,-0.4373c0.6185,-0.6185 1.312,0 1.7493,0c0.4373,0 0.397,-0.6543 2.1866,-0.8747c0.434,-0.0534 2.8801,-0.2561 3.4985,-0.8746c0.3093,-0.3092 0.8343,-0.6543 2.6239,-0.8746c0.4341,-0.0535 0.8747,0 1.312,0c0.4373,0 0.8746,0.4373 0.8746,0.8746c0,0.4373 0.4373,0.4373 0.4373,0.8746c0,0.4374 0.5654,2.3147 0.8746,2.6239c0.3093,0.3093 0.1281,1.0028 0.4374,1.312c0.3092,0.3092 2.1095,2.8366 3.0612,3.0612c0.4256,0.1005 0.8215,0.2158 2.1866,0.4373c0.4316,0.0701 1.3119,0 1.7492,0c0.4373,0 0.8864,0.1005 1.312,0c0.9517,-0.2246 1.44,-0.5654 1.7492,-0.8746c0.3093,-0.3092 0.8747,-0.4373 1.312,-0.4373c0.4373,0 0.5654,-0.5654 0.8746,-0.8746c0.3092,-0.3093 0.8746,0 1.312,0l1.0933,-0.656c1.1661,-7.7259 -2.4782,-14.1399 -7.6531,-20.5539l0,0z" id="svg_4" stroke="#007f00" fill="#44b544" stroke-width="0"/>
<path id="svg_6" d="m10.0409,48.3061c2.1137,-0.2187 4.6647,-0.2187 6.3411,1.9679c1.1662,1.5306 1.239,3.7172 0.2186,4.5918c-2.4052,-0.8746 -5.0291,-2.6239 -6.5597,-6.5597l0,0z" stroke="#007f00" fill="#44b544" stroke-width="0"/>
</g>
</g>
<rect transform="rotate(45, 16.9336, 16.9375)" ry="9" rx="9" id="svg_9" height="19.32339" width="29.34293" y="7.27574" x="2.26257" stroke-width="5" stroke="url(#svg_10)" fill="none" stroke-linecap="round"/>
<rect id="svg_11" transform="rotate(45, 49.0664, 49.0625)" ry="9" rx="9" height="19.32339" width="29.34293" y="39.40074" x="34.39538" stroke-width="5" stroke="url(#svg_10)" fill="none" stroke-linecap="round"/>
<line id="svg_12" y2="45.75" x2="45.75" y1="20.25" x1="20.25" stroke-linecap="round" stroke-width="5" stroke="url(#svg_10)" fill="none"/>
</g>
</svg>
</g>
<g id="svg_eof"/>
</svg>

View File

@ -163,6 +163,11 @@
padding-top: 4px
}
#svg_editor #linkLabel > svg {
height: 20px;
padding-top: 4px;
}
#color_tools .icon_label > * {
position: relative;
top: 1px;

View File

@ -189,6 +189,7 @@
<div class="push_button" id="tool_move_bottom" title="Send to Back [ Ctrl+Shift+[ ]"></div>
<div class="push_button" id="tool_topath" title="Convert to Path"></div>
<div class="push_button" id="tool_reorient" title="Reorient path"></div>
<div class="push_button" id="tool_make_link" title="Make (hyper)link"></div>
<div class="tool_sep"></div>
<label id="idLabel" title="Identify the element">
<span>id:</span>
@ -228,7 +229,7 @@
</label>
</div>
</div>
<!-- Buttons when multiple elements are selected -->
<div id="multiselected_panel">
<div class="tool_sep"></div>
@ -236,6 +237,7 @@
<div class="push_button" id="tool_delete_multi" title="Delete Selected Elements [Delete/Backspace]"></div>
<div class="tool_sep"></div>
<div class="push_button" id="tool_group" title="Group Elements [G]"></div>
<div class="push_button" id="tool_make_link_multi" title="Make (hyper)link"></div>
<div class="push_button" id="tool_alignleft" title="Align Left"></div>
<div class="push_button" id="tool_aligncenter" title="Align Center"></div>
<div class="push_button" id="tool_alignright" title="Align Right"></div>
@ -398,6 +400,13 @@
<div class="push_button" id="tool_ungroup" title="Ungroup Elements [G]"></div>
</div>
<!-- For anchor elements -->
<div id="a_panel">
<label id="tool_link_url" title="Set link URL (leave empty to remove)">
<span id="linkLabel" class="icon_label"></span>
<input id="link_url" type="text" size="35"/>
</label>
</div>
<div id="path_node_panel">
<div class="tool_sep"></div>

View File

@ -392,6 +392,7 @@
'#rheightLabel, #iheightLabel':'height',
'#cornerRadiusLabel span':'c_radius',
'#angleLabel':'angle',
'#linkLabel,#tool_make_link,#tool_make_link_multi':'globe_link',
'#zoomLabel':'zoom',
'#tool_fill label': 'fill',
'#tool_stroke .icon_label': 'stroke',
@ -1424,7 +1425,7 @@
var is_node = currentMode == 'pathedit'; //elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false;
var menu_items = $('#cmenu_canvas li');
$('#selected_panel, #multiselected_panel, #g_panel, #rect_panel, #circle_panel,\
#ellipse_panel, #line_panel, #text_panel, #image_panel, #container_panel, #use_panel').hide();
#ellipse_panel, #line_panel, #text_panel, #image_panel, #container_panel, #use_panel, #a_panel').hide();
if (elem != null) {
var elname = elem.nodeName;
@ -1517,6 +1518,7 @@
// update contextual tools here
var panels = {
g: [],
a: [],
rect: ['rx','width','height'],
image: ['width','height'],
circle: ['cx','cy','r'],
@ -1532,10 +1534,29 @@
// $('#g_panel').show();
// }
var link_href = null;
if (el_name === 'a') {
link_href = svgCanvas.getHref(elem);
$('#g_panel').show();
}
if(elem.parentNode.tagName === 'a') {
if(!$(elem).siblings().length) {
$('#a_panel').show();
link_href = svgCanvas.getHref(elem.parentNode);
}
}
// Hide/show the make_link buttons
$('#tool_make_link, #tool_make_link').toggle(!link_href);
if(link_href) {
$('#link_url').val(link_href);
}
if(panels[el_name]) {
var cur_panel = panels[el_name];
$('#' + el_name + '_panel').show();
$.each(cur_panel, function(i, item) {
@ -1798,10 +1819,12 @@
setImageURL(this.value);
});
$('#g_title').change(function() {
svgCanvas.setGroupTitle(this.value);
setInputWidth(this);
$('#link_url').change(function() {
if(this.value.length) {
svgCanvas.setLinkURL(this.value);
} else {
svgCanvas.removeHyperlink();
}
});
$('.attr_changer').change(function() {
@ -2392,6 +2415,14 @@
}
}
var makeHyperlink = function() {
if (selectedElement != null || multiselected) {
$.prompt("Set URL for hyperlink", "http://", function(url) {
if(url) svgCanvas.makeHyperlink(url);
});
}
}
var moveSelected = function(dx,dy) {
if (selectedElement != null || multiselected) {
if(curConfig.gridSnapping) {
@ -3819,6 +3850,7 @@
{sel:'#tool_move_top', fn: moveToTopSelected, evt: 'click', key: 'ctrl+shift+]'},
{sel:'#tool_move_bottom', fn: moveToBottomSelected, evt: 'click', key: 'ctrl+shift+['},
{sel:'#tool_topath', fn: convertToPath, evt: 'click'},
{sel:'#tool_make_link,#tool_make_link_multi', fn: makeHyperlink, evt: 'click'},
{sel:'#tool_undo', fn: clickUndo, evt: 'click', key: ['Z', true]},
{sel:'#tool_redo', fn: clickRedo, evt: 'click', key: ['Y', true]},
{sel:'#tool_clone,#tool_clone_multi', fn: clickClone, evt: 'click', key: ['C', true]},

View File

@ -3539,7 +3539,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
textActions.select(mouse_target, pt.x, pt.y);
}
if(tagName === "g" && getRotationAngle(mouse_target)) {
if((tagName === "g" || tagName === "a") && getRotationAngle(mouse_target)) {
// TODO: Allow method of in-group editing without having to do
// this (similar to editing rotated paths)
@ -3553,7 +3553,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
leaveContext();
}
if(parent.tagName !== 'g' || parent === current_layer || mouse_target === selectorManager.selectorParentGroup) {
if((parent.tagName !== 'g' && parent.tagName !== 'a') || parent === current_layer || mouse_target === selectorManager.selectorParentGroup) {
// Escape from in-group edit
return;
}
@ -8433,6 +8433,39 @@ this.setImageURL = function(val) {
}
};
// Function: setLinkURL
// Sets the new link URL for the selected anchor element.
//
// Parameters:
// val - String with the link URL/path
this.setLinkURL = function(val) {
var elem = selectedElements[0];
if(!elem) return;
if(elem.tagName !== 'a') {
// See if parent is an anchor
var parents_a = $(elem).parents('a');
if(parents_a.length) {
elem = parents_a[0];
} else {
return;
}
}
var cur_href = getHref(elem);
if(cur_href === val) return;
var batchCmd = new BatchCommand("Change Link URL");
setHref(elem, val);
batchCmd.addSubCommand(new ChangeElementCommand(elem, {
"#href": cur_href
}));
addCommandToHistory(batchCmd);
};
// Function: setRectRadius
// Sets the rx & ry values to the selected rect element to change its corner radius
//
@ -8451,6 +8484,21 @@ this.setRectRadius = function(val) {
}
};
// Function: makeHyperlink
// Wraps the selected element(s) in an anchor element or converts group to one
this.makeHyperlink = function(url) {
canvas.groupSelectedElements('a', url);
// TODO: If element is a single "g", convert to "a"
// if(selectedElements.length > 1 && selectedElements[1]) {
}
// Function: removeHyperlink
this.removeHyperlink = function() {
canvas.ungroupSelectedElement();
}
// Group: Element manipulation
// Function: setSegType
@ -8899,16 +8947,39 @@ this.pasteElements = function(type) {
// Function: groupSelectedElements
// Wraps all the selected elements in a group (g) element
this.groupSelectedElements = function() {
var batchCmd = new BatchCommand("Group Elements");
// Parameters:
// type - type of element to group into, defaults to <g>
this.groupSelectedElements = function(type) {
if(!type) type = 'g';
var cmd_str = '';
switch ( type ) {
case "a":
cmd_str = "Make hyperlink";
var url = '';
if(arguments.length > 1) {
url = arguments[1];
}
break;
default:
type = 'g';
cmd_str = "Group Elements";
break;
}
var batchCmd = new BatchCommand(cmd_str);
// create and insert the group element
var g = addSvgElementFromJson({
"element": "g",
"element": type,
"attr": {
"id": getNextId()
}
});
if(type === 'a') {
setHref(g, url);
}
batchCmd.addSubCommand(new InsertElementCommand(g));
// now move all children into the group
@ -8916,6 +8987,11 @@ this.groupSelectedElements = function() {
while (i--) {
var elem = selectedElements[i];
if (elem == null) continue;
if (elem.parentNode.tagName === 'a' && elem.parentNode.childNodes.length === 1) {
elem = elem.parentNode;
}
var oldNextSibling = elem.nextSibling;
var oldParent = elem.parentNode;
g.appendChild(elem);
@ -9125,8 +9201,14 @@ this.ungroupSelectedElement = function() {
convertToGroup(g);
return;
}
if (g.tagName === "g") {
var parents_a = $(g).parents('a');
if(parents_a.length) {
g = parents_a[0];
}
// Look for parent "a"
if (g.tagName === "g" || g.tagName === "a") {
var batchCmd = new BatchCommand("Ungroup Elements");
var cmd = pushGroupProperties(g, true);
if(cmd) batchCmd.addSubCommand(cmd);