Merge branch 'bzr/golem' of /Users/distler/Sites/code/instiki
This commit is contained in:
commit
3b87094327
|
@ -48,7 +48,8 @@ module Sanitizer
|
|||
|
||||
svg_attributes = Set.new %w[accent-height accumulate additive alphabetic
|
||||
arabic-form ascent attributeName attributeType baseProfile bbox begin
|
||||
by calcMode cap-height class clip-path clip-rule color color-rendering
|
||||
by calcMode cap-height class clip-path clip-rule color
|
||||
color-interpolation-filters color-rendering
|
||||
content cx cy d dx dy descent display dur end fill fill-opacity fill-rule
|
||||
filterRes filterUnits font-family font-size font-stretch font-style
|
||||
font-variant font-weight from fx fy g1 g2 glyph-name gradientUnits
|
||||
|
|
|
@ -86,6 +86,7 @@ function setupSVGedit(path){
|
|||
editor.addEventListener("load", function() {
|
||||
editor.svgEditor.setCustomHandlers({
|
||||
'save': function(window,svg){
|
||||
editor.svgEditor.setConfig({no_save_warning: true});
|
||||
window.opener.postMessage(svg, window.location.protocol + '//' + window.location.host);
|
||||
window.close();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
NAME=svg-edit
|
||||
VERSION=2.5
|
||||
MAKEDOCS=naturaldocs/NaturalDocs
|
||||
PACKAGE=$(NAME)-$(VERSION)
|
||||
YUI=build/yuicompressor.jar
|
||||
MAKEDOCS=naturaldocs/NaturalDocs
|
||||
CLOSURE=build/tools/closure-compiler.jar
|
||||
YUICOMPRESS=build/tools/yuicompressor.jar
|
||||
ZIP=zip
|
||||
|
||||
all: release firefox opera
|
||||
|
@ -10,18 +11,21 @@ all: release firefox opera
|
|||
build/$(PACKAGE):
|
||||
rm -rf config
|
||||
mkdir config
|
||||
$(MAKEDOCS) -i editor/ -o html docs/ -p config/ -oft -r
|
||||
if [ -x $(MAKEDOCS) ] ; then $(MAKEDOCS) -i editor/ -o html docs/ -p config/ -oft -r ; fi
|
||||
mkdir -p build/$(PACKAGE)
|
||||
cp -r editor/* build/$(PACKAGE)
|
||||
-find build/$(PACKAGE) -name .svn -type d -exec rm -rf {} \;
|
||||
# minify spin button
|
||||
java -jar $(YUI) build/$(PACKAGE)/spinbtn/JQuerySpinBtn.js > build/$(PACKAGE)/spinbtn/JQuerySpinBtn.min.js
|
||||
java -jar $(YUICOMPRESS) build/$(PACKAGE)/spinbtn/JQuerySpinBtn.js > build/$(PACKAGE)/spinbtn/JQuerySpinBtn.min.js
|
||||
java -jar $(CLOSURE) --js build/$(PACKAGE)/spinbtn/JQuerySpinBtn.js --js_output_file build/$(PACKAGE)/spinbtn/JQuerySpinBtn.min-closure.js
|
||||
# minify SVG-edit files
|
||||
java -jar $(YUI) build/$(PACKAGE)/svg-editor.js > build/$(PACKAGE)/svg-editor.min.js
|
||||
java -jar $(YUI) build/$(PACKAGE)/svgcanvas.js > build/$(PACKAGE)/svgcanvas.min.js
|
||||
java -jar $(YUICOMPRESS) build/$(PACKAGE)/svg-editor.js > build/$(PACKAGE)/svg-editor.min.js
|
||||
java -jar $(CLOSURE) --js build/$(PACKAGE)/svg-editor.js --js_output_file build/$(PACKAGE)/svg-editor.min-closure.js
|
||||
java -jar $(YUICOMPRESS) build/$(PACKAGE)/svgcanvas.js > build/$(PACKAGE)/svgcanvas.min.js
|
||||
java -jar $(CLOSURE) --js build/$(PACKAGE)/svgcanvas.js --js_output_file build/$(PACKAGE)/svgcanvas.min-closure.js
|
||||
# CSS files do not work remotely
|
||||
# java -jar $(YUI) build/$(PACKAGE)/spinbtn/JQuerySpinBtn.css > build/$(PACKAGE)/spinbtn/JQuerySpinBtn.min.css
|
||||
# java -jar $(YUI) build/$(PACKAGE)/svg-editor.css > build/$(PACKAGE)/svg-editor.min.css
|
||||
# java -jar $(YUICOMPRESS) build/$(PACKAGE)/spinbtn/JQuerySpinBtn.css > build/$(PACKAGE)/spinbtn/JQuerySpinBtn.min.css
|
||||
# java -jar $(YUICOMPRESS) build/$(PACKAGE)/svg-editor.css > build/$(PACKAGE)/svg-editor.min.css
|
||||
|
||||
release: build/$(PACKAGE)
|
||||
cd build ; $(ZIP) $(PACKAGE).zip -r $(PACKAGE) ; cd ..
|
||||
|
|
BIN
public/svg-edit/build/tools/closure-compiler.jar
Normal file
BIN
public/svg-edit/build/tools/closure-compiler.jar
Normal file
Binary file not shown.
90
public/svg-edit/editor/extensions/ext-eyedropper.js
Normal file
90
public/svg-edit/editor/extensions/ext-eyedropper.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* ext-eyedropper.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
*
|
||||
* Copyright(c) 2010 Jeff Schiller
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("eyedropper", function(S) {
|
||||
var svgcontent = S.svgcontent,
|
||||
svgns = "http://www.w3.org/2000/svg",
|
||||
svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
ChangeElementCommand = svgCanvas.getPrivateMethods().ChangeElementCommand,
|
||||
addToHistory = svgCanvas.getPrivateMethods().addCommandToHistory,
|
||||
currentStyle = {fillPaint: "red", fillOpacity: 1.0,
|
||||
strokePaint: "black", strokeOpacity: 1.0,
|
||||
strokeWidth: 5, strokeDashArray: null,
|
||||
opacity: 1.0 };
|
||||
|
||||
return {
|
||||
name: "eyedropper",
|
||||
svgicons: "extensions/eyedropper-icon.xml",
|
||||
buttons: [{
|
||||
id: "tool_eyedropper",
|
||||
type: "mode",
|
||||
title: "Eye Dropper Tool",
|
||||
events: {
|
||||
"click": function() {
|
||||
svgCanvas.setMode("eyedropper");
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
// if we have selected an element, grab its paint and enable the eye dropper button
|
||||
selectedChanged: function(opts) {
|
||||
// if we are in eyedropper mode, we don't want to disable the eye-dropper tool
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode == "eyedropper") return;
|
||||
|
||||
var elem = null;
|
||||
var tool = $('#tool_eyedropper');
|
||||
// enable-eye-dropper if one element is selected
|
||||
if (opts.elems.length == 1 && opts.elems[0] &&
|
||||
$.inArray(opts.elems[0].nodeName, ['svg', 'g', 'use']) == -1)
|
||||
{
|
||||
elem = opts.elems[0];
|
||||
tool.removeClass('disabled');
|
||||
// grab the current style
|
||||
currentStyle.fillPaint = elem.getAttribute("fill") || "black";
|
||||
currentStyle.fillOpacity = elem.getAttribute("fill-opacity") || 1.0;
|
||||
currentStyle.strokePaint = elem.getAttribute("stroke");
|
||||
currentStyle.strokeOpacity = elem.getAttribute("stroke-opacity") || 1.0;
|
||||
currentStyle.strokeWidth = elem.getAttribute("stroke-width");
|
||||
currentStyle.strokeDashArray = elem.getAttribute("stroke-dasharray");
|
||||
currentStyle.opacity = elem.getAttribute("opacity") || 1.0;
|
||||
}
|
||||
// disable eye-dropper tool
|
||||
else {
|
||||
tool.addClass('disabled');
|
||||
}
|
||||
},
|
||||
|
||||
mouseDown: function(opts) {
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode == "eyedropper") {
|
||||
var e = opts.event;
|
||||
var target = e.target;
|
||||
if ($.inArray(target.nodeName, ['svg', 'g', 'use']) == -1) {
|
||||
var changes = {};
|
||||
|
||||
var change = function(elem, attrname, newvalue) {
|
||||
changes[attrname] = elem.getAttribute(attrname);
|
||||
elem.setAttribute(attrname, newvalue);
|
||||
};
|
||||
|
||||
if (currentStyle.fillPaint) change(target, "fill", currentStyle.fillPaint);
|
||||
if (currentStyle.fillOpacity) change(target, "fill-opacity", currentStyle.fillOpacity);
|
||||
if (currentStyle.strokePaint) change(target, "stroke", currentStyle.strokePaint);
|
||||
if (currentStyle.strokeOpacity) change(target, "stroke-opacity", currentStyle.strokeOpacity);
|
||||
if (currentStyle.strokeWidth) change(target, "stroke-width", currentStyle.strokeWidth);
|
||||
if (currentStyle.strokeDashArray) change(target, "stroke-dasharray", currentStyle.strokeDashArray);
|
||||
if (currentStyle.opacity) change(target, "opacity", currentStyle.opacity);
|
||||
|
||||
addToHistory(new ChangeElementCommand(target, changes));
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
34
public/svg-edit/editor/extensions/eyedropper-icon.xml
Normal file
34
public/svg-edit/editor/extensions/eyedropper-icon.xml
Normal file
|
@ -0,0 +1,34 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g id="tool_eyedropper">
|
||||
<svg viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
|
||||
<defs>
|
||||
<radialGradient id="eyedropper_svg_6" cx="0.5" cy="0.5" r="0.5">
|
||||
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
|
||||
<stop offset="1" stop-color="#e5e5e5" stop-opacity="0.38"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="eyedropper_svg_15" x1="0" y1="0" x2="0.58594" y2="0.55078">
|
||||
<stop offset="0" stop-color="#ffffff" stop-opacity="0.57"/>
|
||||
<stop offset="1" stop-color="#000056" stop-opacity="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="eyedropper_svg_19" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
|
||||
<stop offset="1" stop-color="#ffffff" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g display="inline">
|
||||
<title>Layer 1</title>
|
||||
<path d="m193.899994,73l-119.899979,118l-15,39.5l10.25,4.5l43.750015,-20l108.999969,-112l-28.100006,-30z" id="svg_3" fill="none" stroke="#000000" stroke-width="5"/>
|
||||
<path d="m58.649994,232c-2.75,28.200012 -26.399994,28.950012 -21.899994,59c4.5,30.049988 55,28 55.5,-1.25c0.5,-29.25 -20.25,-28.75 -22.25,-54.75l-11.350006,-3z" id="svg_4" fill="#aa56ff" stroke="#000000" stroke-width="7"/>
|
||||
<path d="m45.474976,269.275024l13.775024,0.474976l-0.75,16.75l-14.25,-1.25l1.224976,-15.974976z" id="svg_5" fill="url(#eyedropper_svg_6)" stroke-width="5" fill-opacity="0.73"/>
|
||||
<path d="m217.899994,46c21.5,-101.549999 141.600006,20.449997 28.100006,33l-5,44l-63,-66l39.899994,-11z" id="svg_2" fill="#000000" stroke-width="5"/>
|
||||
<path d="m206.825012,61.075008c3.712494,-2.46249 7.637482,-3.53751 14.424988,-5.575008c10.125,-16.5 32.875,-41.5 40.5,-35c7.625,6.5 -21.25,35.625 -37.5,39.25c-5.5,10.125 -8,13.875 -17.25,16.5c-2.837494,-8.162514 -4.262482,-12.337486 -0.174988,-15.174992z" id="svg_7" fill="url(#eyedropper_svg_15)" stroke-width="5"/>
|
||||
<path d="m133.049988,134.75l46.950012,9.25l-66,70l-42.5,20.5l-11.5,-5l14,-37.5l59.049988,-57.25z" id="svg_11" fill="#aa56ff" stroke="#000000" stroke-width="7"/>
|
||||
<path d="m71.425034,212.350006l9.050888,-20.022537l51.516724,-49.327469l8.507355,0.97197l-69.074966,68.378036z" id="svg_16" fill="url(#eyedropper_svg_19)" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>
|
||||
</g>
|
||||
|
||||
<g id="svg_eof"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
BIN
public/svg-edit/editor/extensions/eyedropper.png
Normal file
BIN
public/svg-edit/editor/extensions/eyedropper.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 718 B |
|
@ -5,11 +5,10 @@
|
|||
in the extension. The SVG inside the group makes up the actual icon, and
|
||||
needs use a viewBox instead of width/height for it to scale properly.
|
||||
|
||||
Multiple icons can be included, each within their own group. A final element
|
||||
with ID "svg_eof" must be included too.
|
||||
Multiple icons can be included, each within their own group.
|
||||
-->
|
||||
<g id="hello_world">
|
||||
<svg viewBox="0 0 102 102" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg width="102" height="102" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
|
@ -19,5 +18,4 @@
|
|||
</g>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="svg_eof"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -1,47 +1,32 @@
|
|||
#About
|
||||
**jQuery.hotkeys** is a plug-in that lets you easily add and remove handlers for keyboard events anywhere in your code supporting almost any key combination.
|
||||
**jQuery Hotkeys** is a plug-in that lets you easily add and remove handlers for keyboard events anywhere in your code supporting almost any key combination.
|
||||
|
||||
It is based on a library [Shortcut.js](http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js) written by [Binny V A](http://www.openjs.com/).
|
||||
This plugin is based off of the plugin by Tzury Bar Yochay: [jQuery.hotkeys](http://github.com/tzuryby/hotkeys)
|
||||
|
||||
The syntax is as follows:
|
||||
<pre>
|
||||
$(expression).bind(<types>,<options>, <handler>);
|
||||
$(expression).unbind(<types>,<options>, <handler>);
|
||||
|
||||
$(document).bind('keydown', 'Ctrl+a', fn);
|
||||
$(expression).bind(types, keys, handler);
|
||||
$(expression).unbind(types, handler);
|
||||
|
||||
$(document).bind('keydown', 'ctrl+a', fn);
|
||||
|
||||
// e.g. replace '$' sign with 'EUR'
|
||||
$('input.foo').bind('keyup', '$', function(){
|
||||
this.value = this.value.replace('$', 'EUR');
|
||||
});
|
||||
|
||||
$('div.foo').unbind('keydown', 'Ctrl+a', fn);
|
||||
</pre>
|
||||
## [Live Demo](http://jshotkeys.googlepages.com/test-static-01.html)
|
||||
|
||||
## Types
|
||||
Supported types are `'keydown'`, `'keyup'` and `'keypress'`
|
||||
|
||||
## Options
|
||||
The options are `'combi'` i.e. the key combination, and `'disableInInput'` which allow your code not to be executed when the cursor is located inside an input ( `$(elem).is('input') || $(elem).is('textarea')` ).
|
||||
|
||||
As you can see, the key combination can be passed as string or as an object. You may pass an object in case you wish to override the default option for `disableInInput` which is set to `false`:
|
||||
<pre>
|
||||
$(document).bind('keydown', {combi:'a', disableinInput: true}, fn);
|
||||
</pre>
|
||||
I.e. when cursor is within an input field, `'a'` will be inserted into the input field without interfering.
|
||||
## Notes
|
||||
|
||||
If you want to use more than one modifiers (e.g. alt+ctrl+z) you should define them by an alphabetical order e.g. alt+ctrl+shift
|
||||
|
||||
Modifiers are case insensitive, i.e. 'Ctrl+a' 'ctrl+a'.
|
||||
|
||||
## Handler
|
||||
In previous versions there was an option propagate which is removed now and implemented at the user code level.
|
||||
|
||||
When using jQuery, if an event handler returns false, jQuery will call `stopPropagation()` and `preventDefault()`
|
||||
Hotkeys aren't tracked if you're inside of an input element (unless you explicitly bind the hotkey directly to the input). This helps to avoid conflict with normal user typing.
|
||||
|
||||
## jQuery Compatibility
|
||||
Tested with *jQuery 1.2.6*
|
||||
|
||||
Works with jQuery 1.4.2 and newer.
|
||||
|
||||
It known to be working with all the major browsers on all available platforms (Win/Mac/Linux)
|
||||
|
||||
|
@ -51,43 +36,10 @@ It known to be working with all the major browsers on all available platforms (W
|
|||
* Safari-3
|
||||
* Chrome-0.2
|
||||
|
||||
## Features added in this version (0.7.x)
|
||||
* Implemented as $.fn - let you use `this`.
|
||||
* jQuery selectors are supported.
|
||||
* Extending `$.fn.bind` and `$.fn.unbind` so you get a single interface for binding events to handlers
|
||||
|
||||
## Overriding jQuery
|
||||
The plugin wraps the following jQuery methods:
|
||||
* $.fn.bind
|
||||
* $.fn.unbind
|
||||
* $.find
|
||||
|
||||
Even though the plugin overrides these methods, the original methods will *always* be called.
|
||||
|
||||
The plugin will add functionality only for the `keydown`, `keyup` and `keypress` event types. Any other types are passed untouched to the original `'bind()'` and `'unbind()'` methods.
|
||||
|
||||
Moreover, if you call `bind()` without passing the shortcut key combination e.g. `$(document).bind('keydown', fn)` only the original `'bind()'` method will be executed.
|
||||
|
||||
I also modified the `$.fn.find` method by adding a single line at the top of the function body. here is the code:
|
||||
|
||||
<pre>
|
||||
jQuery.fn.find = function( selector ) {
|
||||
// the line I added
|
||||
this.query=selector;
|
||||
// call jQuery original find
|
||||
return jQuery.fn.__find__.apply(this, arguments);
|
||||
};
|
||||
</pre>
|
||||
|
||||
You can read about this at [jQuery's User Group](http://groups.google.com/group/jquery-en/browse_thread/thread/18f9825e8d22f18d)
|
||||
|
||||
###Notes
|
||||
### Addendum
|
||||
|
||||
Firefox is the most liberal one in the manner of letting you capture all short-cuts even those that are built-in in the browser such as `Ctrl-t` for new tab, or `Ctrl-a` for selecting all text. You can always bubble them up to the browser by returning `true` in your handler.
|
||||
|
||||
Others, (IE) either let you handle built-in short-cuts, but will add their functionality after your code has executed. Or (Opera/Safari) will *not* pass those events to the DOM at all.
|
||||
|
||||
*So, if you bind `Ctrl-Q` or `Alt-F4` and your Safari/Opera window is closed don't be surprised.*
|
||||
|
||||
|
||||
###Current Version is: beta 0.7
|
|
@ -1,19 +1,15 @@
|
|||
(function(jQuery){jQuery.fn.__bind__=jQuery.fn.bind;jQuery.fn.__unbind__=jQuery.fn.unbind;jQuery.fn.__find__=jQuery.fn.find;var hotkeys={version:'0.7.9',override:/keypress|keydown|keyup/g,triggersMap:{},specialKeys:{27:'esc',9:'tab',32:'space',13:'return',8:'backspace',145:'scroll',20:'capslock',144:'numlock',19:'pause',45:'insert',36:'home',46:'del',35:'end',33:'pageup',34:'pagedown',37:'left',38:'up',39:'right',40:'down',109:'-',112:'f1',113:'f2',114:'f3',115:'f4',116:'f5',117:'f6',118:'f7',119:'f8',120:'f9',121:'f10',122:'f11',123:'f12',191:'/'},shiftNums:{"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":"\"",",":"<",".":">","/":"?","\\":"|"},newTrigger:function(type,combi,callback){var result={};result[type]={};result[type][combi]={cb:callback,disableInInput:false};return result;}};hotkeys.specialKeys=jQuery.extend(hotkeys.specialKeys,{96:'0',97:'1',98:'2',99:'3',100:'4',101:'5',102:'6',103:'7',104:'8',105:'9',106:'*',107:'+',109:'-',110:'.',111:'/'});jQuery.fn.find=function(selector){this.query=selector;return jQuery.fn.__find__.apply(this,arguments);};jQuery.fn.unbind=function(type,combi,fn){if(jQuery.isFunction(combi)){fn=combi;combi=null;}
|
||||
if(combi&&typeof combi==='string'){var selectorId=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();var hkTypes=type.split(' ');for(var x=0;x<hkTypes.length;x++){delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi];}}
|
||||
return this.__unbind__(type,fn);};jQuery.fn.bind=function(type,data,fn){var handle=type.match(hotkeys.override);if(jQuery.isFunction(data)||!handle){return this.__bind__(type,data,fn);}
|
||||
else{var result=null,pass2jq=jQuery.trim(type.replace(hotkeys.override,''));if(pass2jq){result=this.__bind__(pass2jq,data,fn);}
|
||||
if(typeof data==="string"){data={'combi':data};}
|
||||
if(data.combi){for(var x=0;x<handle.length;x++){var eventType=handle[x];var combi=data.combi.toLowerCase(),trigger=hotkeys.newTrigger(eventType,combi,fn),selectorId=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();trigger[eventType][combi].disableInInput=data.disableInInput;if(!hotkeys.triggersMap[selectorId]){hotkeys.triggersMap[selectorId]=trigger;}
|
||||
else if(!hotkeys.triggersMap[selectorId][eventType]){hotkeys.triggersMap[selectorId][eventType]=trigger[eventType];}
|
||||
var mapPoint=hotkeys.triggersMap[selectorId][eventType][combi];if(!mapPoint){hotkeys.triggersMap[selectorId][eventType][combi]=[trigger[eventType][combi]];}
|
||||
else if(mapPoint.constructor!==Array){hotkeys.triggersMap[selectorId][eventType][combi]=[mapPoint];}
|
||||
else{hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length]=trigger[eventType][combi];}
|
||||
this.each(function(){var jqElem=jQuery(this);if(jqElem.attr('hkId')&&jqElem.attr('hkId')!==selectorId){selectorId=jqElem.attr('hkId')+";"+selectorId;}
|
||||
jqElem.attr('hkId',selectorId);});result=this.__bind__(handle.join(' '),data,hotkeys.handler)}}
|
||||
return result;}};hotkeys.findElement=function(elem){if(!jQuery(elem).attr('hkId')){if(jQuery.browser.opera||jQuery.browser.safari){while(!jQuery(elem).attr('hkId')&&elem.parentNode){elem=elem.parentNode;}}}
|
||||
return elem;};hotkeys.handler=function(event){var target=hotkeys.findElement(event.currentTarget),jTarget=jQuery(target),ids=jTarget.attr('hkId');if(ids){ids=ids.split(';');var code=event.which,type=event.type,special=hotkeys.specialKeys[code],character=!special&&String.fromCharCode(code).toLowerCase(),shift=event.shiftKey,ctrl=event.ctrlKey,alt=event.altKey||event.originalEvent.altKey,mapPoint=null;for(var x=0;x<ids.length;x++){if(hotkeys.triggersMap[ids[x]][type]){mapPoint=hotkeys.triggersMap[ids[x]][type];break;}}
|
||||
if(mapPoint){var trigger;if(!shift&&!ctrl&&!alt){trigger=mapPoint[special]||(character&&mapPoint[character]);}
|
||||
else{var modif='';if(alt)modif+='alt+';if(ctrl)modif+='ctrl+';if(shift)modif+='shift+';trigger=mapPoint[modif+special];if(!trigger){if(character){trigger=mapPoint[modif+character]||mapPoint[modif+hotkeys.shiftNums[character]]||(modif==='shift+'&&mapPoint[hotkeys.shiftNums[character]]);}}}
|
||||
if(trigger){var result=false;for(var x=0;x<trigger.length;x++){if(trigger[x].disableInInput){var elem=jQuery(event.target);if(jTarget.is("input")||jTarget.is("textarea")||jTarget.is("select")||elem.is("input")||elem.is("textarea")||elem.is("select")){return true;}}
|
||||
result=result||trigger[x].cb.apply(this,[event]);}
|
||||
return result;}}}};window.hotkeys=hotkeys;return jQuery;})(jQuery);
|
||||
/*
|
||||
* jQuery Hotkeys Plugin
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* http://github.com/jeresig/jquery.hotkeys
|
||||
*
|
||||
* Based upon the plugin by Tzury Bar Yochay:
|
||||
* http://github.com/tzuryby/hotkeys
|
||||
*
|
||||
* Original idea by:
|
||||
* Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
*/
|
||||
|
||||
(function(b){b.hotkeys={version:"0.8",specialKeys:{8:"backspace",9:"tab",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",191:"/",224:"meta"},shiftNums:{"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"}};function a(d){if(typeof d.data!=="string"){return}var c=d.handler,e=d.data.toLowerCase().split(" ");d.handler=function(n){if(this!==n.target&&(/textarea|select/i.test(n.target.nodeName)||n.target.type==="text")){return}var h=n.type!=="keypress"&&b.hotkeys.specialKeys[n.which],o=String.fromCharCode(n.which).toLowerCase(),k,m="",g={};if(n.altKey&&h!=="alt"){m+="alt+"}if(n.ctrlKey&&h!=="ctrl"){m+="ctrl+"}if(n.metaKey&&!n.ctrlKey&&h!=="meta"){m+="meta+"}if(n.shiftKey&&h!=="shift"){m+="shift+"}if(h){g[m+h]=true}else{g[m+o]=true;g[m+b.hotkeys.shiftNums[o]]=true;if(m==="shift+"){g[b.hotkeys.shiftNums[o]]=true}}for(var j=0,f=e.length;j<f;j++){if(g[e[j]]){return c.apply(this,arguments)}}}}b.each(["keydown","keyup","keypress"],function(){b.event.special[this]={add:a}})})(jQuery);
|
|
@ -383,6 +383,7 @@ body {
|
|||
top: 75px;
|
||||
left: 0;
|
||||
padding-left: 2px;
|
||||
background: #D8D8D8; /* Needed so flyout icons don't appear on the left */
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
|
@ -466,17 +467,13 @@ body {
|
|||
}
|
||||
|
||||
|
||||
.magic_field > * {
|
||||
float: left;
|
||||
}
|
||||
|
||||
span.zoom_tool {
|
||||
line-height: 26px;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.magic_field input {
|
||||
margin-top: 5px;
|
||||
#zoom_panel label {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
|
@ -701,6 +698,21 @@ span.zoom_tool {
|
|||
height: 26px;
|
||||
}
|
||||
|
||||
#toggle_stroke_tools {
|
||||
letter-spacing: -.2em;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
#toggle_stroke_tools:hover {
|
||||
cursor: pointer;
|
||||
background: #FFC;
|
||||
}
|
||||
|
||||
.stroke_tool {
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.color_tool > *:first-child {
|
||||
-moz-border-radius-topleft: 4px;
|
||||
-moz-border-radius-bottomleft: 4px;
|
||||
|
@ -739,6 +751,8 @@ span.zoom_tool {
|
|||
|
||||
|
||||
#svg_editor #tools_bottom_3 {
|
||||
// position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#svg_editor #copyright {
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
<script type="text/javascript" src="svgcanvas.js"></script>
|
||||
<script type="text/javascript" src="svg-editor.js"></script>
|
||||
<script type="text/javascript" src="locale/locale.js"></script>
|
||||
<!-- you can load extensions here -->
|
||||
<!-- <script type="text/javascript" src="extensions/ext-helloworld.js"></script> -->
|
||||
|
||||
<!-- Release version of script tags: >
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
|
||||
|
@ -340,6 +342,7 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
|||
<label id="tool_node_y">y:
|
||||
<input id="path_node_y" class="attr_changer" title="Change node's y coordinate" size="3" data-attr="y"/>
|
||||
</label>
|
||||
|
||||
<select id="seg_type" title="Change Segment type">
|
||||
<option id="straight_segments" selected="selected" value="4">Straight</option>
|
||||
<option id="curve_segments" value="6">Curve</option>
|
||||
|
@ -380,9 +383,11 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
|||
<div id="tools_bottom" class="tools_panel">
|
||||
|
||||
<!-- Zoom buttons -->
|
||||
<div id="zoom_panel" class="magic_field">
|
||||
<span id="zoomLabel" class="zoom_tool label">zoom:</span>
|
||||
<div id="zoom_panel" class="toolset">
|
||||
<label>
|
||||
<span id="zoomLabel" class="zoom_tool">zoom:</span>
|
||||
<input id="zoom" title="Change zoom level" size="3" value="100" type="text" />
|
||||
</label>
|
||||
<div id="zoom_dropdown" class="dropdown">
|
||||
<button></button>
|
||||
<ul>
|
||||
|
@ -427,7 +432,7 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
|||
<input id="stroke_width" title="Change stroke width by 1, shift-click to change by 0.1" size="2" value="5" type="text" data-attr="Stroke Width"/>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<label class="stroke_tool">
|
||||
<select id="stroke_style" title="Change stroke dash style">
|
||||
<option selected="selected" value="none">—</option>
|
||||
<option value="2,2">...</option>
|
||||
|
@ -436,6 +441,33 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
|||
<option value="5,2,2,2,2,2">- ..</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<!-- TODO: Turn these into icon lists, rather than text ones -->
|
||||
<label class="stroke_tool">
|
||||
<span>Joins:</span>
|
||||
<select id="stroke_linejoin" title="Change Linejoin type">
|
||||
<option id="linejoin_miter" selected="selected" value="miter">Miter</option>
|
||||
<option id="linejoin_round" value="round">Round</option>
|
||||
<option id="linejoin_bevel" value="bevel">Bevel</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="stroke_tool">
|
||||
<span>Caps:</span>
|
||||
<select id="stroke_linecap" title="Change Linecap type">
|
||||
<option id="linecap_butt" selected="selected" value="butt">Butt</option>
|
||||
<option id="linecap_round" value="round">Round</option>
|
||||
<option id="linecap_square" value="square">Square</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<div id="toggle_stroke_tools" title="Show/hide more stroke tools">
|
||||
>>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
imgPath: 'images/',
|
||||
langPath: 'locale/',
|
||||
extPath: 'extensions/',
|
||||
extensions: ['ext-arrows.js', 'ext-connector.js', 'ext-itex.js'],
|
||||
extensions: ['ext-arrows.js', 'ext-connector.js', 'ext-eyedropper.js', 'ext-itex.js'],
|
||||
initTool: 'select',
|
||||
wireframe: false
|
||||
},
|
||||
|
@ -59,6 +59,7 @@
|
|||
'layerHasThatName':"Layer already has that name",
|
||||
'QmoveElemsToLayer':"Move selected elements to layer '%s'?",
|
||||
'QwantToClear':'Do you want to clear the drawing?\nThis will also erase your undo history!',
|
||||
'QwantToOpen':'Do you want to open a new file?\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',
|
||||
|
@ -143,6 +144,7 @@
|
|||
svgCanvas.open = opts.open;
|
||||
}
|
||||
if(opts.save) {
|
||||
show_save_warning = false;
|
||||
svgCanvas.bind("saved", opts.save);
|
||||
}
|
||||
}
|
||||
|
@ -190,10 +192,19 @@
|
|||
}
|
||||
})();
|
||||
|
||||
// Load extensions
|
||||
var extFunc = function() {
|
||||
$.each(curConfig.extensions, function() {
|
||||
$.getScript(curConfig.extPath + this);
|
||||
});
|
||||
}
|
||||
|
||||
// Load extensions
|
||||
// Bit of a hack to run extensions in local Opera
|
||||
if(window.opera && document.location.protocol === 'file:') {
|
||||
setTimeout(extFunc, 1000);
|
||||
} else {
|
||||
extFunc();
|
||||
}
|
||||
|
||||
$.svgIcons(curConfig.imgPath + 'svg_edit_icons.svg', {
|
||||
w:24, h:24,
|
||||
|
@ -361,7 +372,8 @@
|
|||
modKey = "", //(isMac ? "meta+" : "ctrl+");
|
||||
path = svgCanvas.pathActions,
|
||||
default_img_url = curConfig.imgPath + "logo.png",
|
||||
workarea = $("#workarea");
|
||||
workarea = $("#workarea"),
|
||||
show_save_warning = false;
|
||||
|
||||
// This sets up alternative dialog boxes. They mostly work the same way as
|
||||
// their UI counterparts, expect instead of returning the result, a callback
|
||||
|
@ -388,7 +400,7 @@
|
|||
if(type == 'prompt') {
|
||||
var input = $('<input type="text">').prependTo(btn_holder);
|
||||
input.val(defText || '');
|
||||
input.bind('keydown', {combi:'return'}, function() {ok.click();});
|
||||
input.bind('keydown', 'return', function() {ok.click();});
|
||||
}
|
||||
|
||||
box.show();
|
||||
|
@ -445,6 +457,8 @@
|
|||
var strokePaint = new $.jGraduate.Paint({solidColor: curConfig.initStroke.color});
|
||||
|
||||
var saveHandler = function(window,svg) {
|
||||
show_save_warning = false;
|
||||
|
||||
// by default, we add the XML prolog back, systems integrating SVG-edit (wikis, CMSs)
|
||||
// can just provide their own custom save handler and might not want the XML prolog
|
||||
svg = "<?xml version='1.0'?>\n" + svg;
|
||||
|
@ -526,6 +540,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
show_save_warning = true;
|
||||
|
||||
// we update the contextual panel with potentially new
|
||||
// positional/sizing information (we DON'T want to update the
|
||||
// toolbar here as that creates an infinite loop)
|
||||
|
@ -607,7 +623,7 @@
|
|||
$(this).mouseup(func);
|
||||
|
||||
if(opts.key) {
|
||||
$(document).bind('keydown', {combi: opts.key+'', disableInInput:true}, func);
|
||||
$(document).bind('keydown', opts.key+'', func);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -878,7 +894,7 @@
|
|||
});
|
||||
}
|
||||
if(btn.key) {
|
||||
$(document).bind('keydown', {combi: btn.key, disableInInput: true}, func);
|
||||
$(document).bind('keydown', btn.key, func);
|
||||
if(btn.title) button.attr("title", btn.title + ' ['+btn.key+']');
|
||||
}
|
||||
} else {
|
||||
|
@ -999,6 +1015,8 @@
|
|||
|
||||
$('#stroke_width').val(selectedElement.getAttribute("stroke-width")||1);
|
||||
$('#stroke_style').val(selectedElement.getAttribute("stroke-dasharray")||"none");
|
||||
$('#stroke_linejoin').val(selectedElement.getAttribute("stroke-linejoin")||"miter");
|
||||
$('#stroke_linecap').val(selectedElement.getAttribute("stroke-linecap")||"butt");
|
||||
}
|
||||
|
||||
// All elements including image and group have opacity
|
||||
|
@ -1270,10 +1288,21 @@
|
|||
}
|
||||
|
||||
$('#stroke_style').change(function(){
|
||||
svgCanvas.setStrokeStyle(this.options[this.selectedIndex].value);
|
||||
svgCanvas.setStrokeAttr('stroke-dasharray', $(this).val());
|
||||
operaRepaint();
|
||||
});
|
||||
|
||||
$('#stroke_linejoin').change(function(){
|
||||
svgCanvas.setStrokeAttr('stroke-linejoin', $(this).val());
|
||||
operaRepaint();
|
||||
});
|
||||
|
||||
$('#stroke_linecap').change(function(){
|
||||
svgCanvas.setStrokeAttr('stroke-linecap', $(this).val());
|
||||
operaRepaint();
|
||||
});
|
||||
|
||||
|
||||
// Lose focus for select elements when changed (Allows keyboard shortcuts to work better)
|
||||
$('select').change(function(){$(this).blur();});
|
||||
|
||||
|
@ -1383,6 +1412,14 @@
|
|||
updateToolButtonState();
|
||||
});
|
||||
|
||||
$("#toggle_stroke_tools").toggle(function() {
|
||||
$(".stroke_tool").css('display','table-cell');
|
||||
$(this).text('<<');
|
||||
}, function() {
|
||||
$(".stroke_tool").css('display','none');
|
||||
$(this).text('>>');
|
||||
});
|
||||
|
||||
// This is a common function used when a tool has been clicked (chosen)
|
||||
// It does several common things:
|
||||
// - removes the tool_button_current class from whatever tool currently has it
|
||||
|
@ -1401,6 +1438,44 @@
|
|||
return true;
|
||||
};
|
||||
|
||||
(function() {
|
||||
var last_x = null, last_y = null, w_area = workarea[0],
|
||||
panning = false, keypan = false;
|
||||
|
||||
$('#svgcanvas').bind('mousemove mouseup', function(evt) {
|
||||
if(panning === false) return;
|
||||
|
||||
w_area.scrollLeft -= (evt.clientX - last_x);
|
||||
w_area.scrollTop -= (evt.clientY - last_y);
|
||||
|
||||
last_x = evt.clientX;
|
||||
last_y = evt.clientY;
|
||||
|
||||
if(evt.type === 'mouseup') panning = false;
|
||||
return false;
|
||||
}).mousedown(function(evt) {
|
||||
if(evt.button === 1 || keypan === true) {
|
||||
panning = true;
|
||||
last_x = evt.clientX;
|
||||
last_y = evt.clientY;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$(window).mouseup(function() {
|
||||
panning = false;
|
||||
});
|
||||
|
||||
$(document).bind('keydown', 'space', function(evt) {
|
||||
svgCanvas.spaceKey = keypan = true;
|
||||
evt.preventDefault();
|
||||
}).bind('keyup', 'space', function(evt) {
|
||||
evt.preventDefault();
|
||||
svgCanvas.spaceKey = keypan = false;
|
||||
});
|
||||
}());
|
||||
|
||||
|
||||
(function() {
|
||||
var button = $('#main_icon');
|
||||
var overlay = $('#main_icon span');
|
||||
|
@ -2022,6 +2097,7 @@
|
|||
".tool_button,\
|
||||
.push_button,\
|
||||
.tool_button_current,\
|
||||
.push_button_pressed,\
|
||||
.disabled,\
|
||||
.tools_flyout .tool_button": {
|
||||
'width': {s: '16px', l: '32px', xl: '48px'},
|
||||
|
@ -2047,11 +2123,11 @@
|
|||
"div#workarea": {
|
||||
'left': {s: '27px', l: '46px', xl: '65px'},
|
||||
'top': {s: '50px', l: '88px', xl: '125px'},
|
||||
'bottom': {s: '55px', l: '70px', xl: '77px'}
|
||||
'bottom': {s: '55px', l: '98px', xl: '145px'}
|
||||
},
|
||||
"#tools_bottom": {
|
||||
'left': {s: '27px', l: '46px', xl: '65px'},
|
||||
'height': {s: '58px', l: '70px', xl: '77px'}
|
||||
'height': {s: '58px', l: '98px', xl: '145px'}
|
||||
},
|
||||
"#color_tools": {
|
||||
'border-spacing': {s: '0 1px'}
|
||||
|
@ -2060,7 +2136,8 @@
|
|||
'height': {s: '20px'}
|
||||
},
|
||||
"#tool_opacity": {
|
||||
'top': {s: '1px'}
|
||||
'top': {s: '1px'},
|
||||
'height': {s: 'auto', l:'auto', xl:'auto'}
|
||||
},
|
||||
"#tools_top input, #tools_bottom input": {
|
||||
'margin-top': {s: '2px', l: '4px', xl: '5px'},
|
||||
|
@ -2888,7 +2965,7 @@
|
|||
keyval += '';
|
||||
|
||||
$.each(keyval.split('/'), function(i, key) {
|
||||
$(document).bind('keydown', {combi: key, disableInInput: disInInp}, function(e) {
|
||||
$(document).bind('keydown', key, function(e) {
|
||||
fn();
|
||||
if(pd) {
|
||||
e.preventDefault();
|
||||
|
@ -2917,7 +2994,7 @@
|
|||
// Misc additional actions
|
||||
|
||||
// Make "return" keypress trigger the change event
|
||||
$('.attr_changer, #image_url').bind('keydown', {combi:'return'},
|
||||
$('.attr_changer, #image_url').bind('keydown', 'return',
|
||||
function(evt) {$(this).change();evt.preventDefault();}
|
||||
);
|
||||
|
||||
|
@ -2994,20 +3071,44 @@
|
|||
$('#group_opacity').SpinButton({ step: 5, min: 0, max: 100, callback: changeOpacity });
|
||||
$('#zoom').SpinButton({ min: 0.001, max: 10000, step: 50, stepfunc: stepZoom, callback: changeZoom });
|
||||
|
||||
window.onbeforeunload = function() {
|
||||
// Suppress warning if page is empty
|
||||
if(svgCanvas.getHistoryPosition() === 0) {
|
||||
show_save_warning = false;
|
||||
}
|
||||
|
||||
// show_save_warning is set to "false" when the page is saved.
|
||||
if(!curConfig.no_save_warning && show_save_warning) {
|
||||
// Browser already asks question about closing the page
|
||||
return "There are unsaved changes.";
|
||||
}
|
||||
};
|
||||
|
||||
// use HTML5 File API: http://www.w3.org/TR/FileAPI/
|
||||
// if browser has HTML5 File API support, then we will show the open menu item
|
||||
// and provide a file input to click. When that change event fires, it will
|
||||
// get the text contents of the file and send it to the canvas
|
||||
if (window.FileReader) {
|
||||
var inp = $('<input type="file">').change(function() {
|
||||
$('#main_menu').hide();
|
||||
if(this.files.length==1) {
|
||||
var f = this;
|
||||
var openFile = function(ok) {
|
||||
if(!ok) return;
|
||||
svgCanvas.clear();
|
||||
if(f.files.length==1) {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function(e) {
|
||||
svgCanvas.setSvgString(e.target.result);
|
||||
updateCanvas();
|
||||
};
|
||||
reader.readAsText(this.files[0]);
|
||||
reader.readAsText(f.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$('#main_menu').hide();
|
||||
if(svgCanvas.getHistoryPosition() === 0) {
|
||||
openFile(true);
|
||||
} else {
|
||||
$.confirm(uiStrings.QwantToOpen, openFile);
|
||||
}
|
||||
});
|
||||
$("#tool_open").show().prepend(inp);
|
||||
|
@ -3092,7 +3193,7 @@
|
|||
updateCanvas(true);
|
||||
// });
|
||||
|
||||
// var revnums = "svg-editor.js ($Rev: 1470 $) ";
|
||||
// var revnums = "svg-editor.js ($Rev: 1498 $) ";
|
||||
// revnums += svgCanvas.getVersion();
|
||||
// $('#copyright')[0].setAttribute("title", revnums);
|
||||
|
||||
|
|
|
@ -97,8 +97,8 @@ var isOpera = !!window.opera,
|
|||
"defs": [],
|
||||
"desc": [],
|
||||
"ellipse": ["class", "clip-path", "clip-rule", "cx", "cy", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "requiredFeatures", "rx", "ry", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
||||
"feGaussianBlur": ["class", "id", "requiredFeatures", "stdDeviation"],
|
||||
"filter": ["class", "filterRes", "filterUnits", "height", "id", "primitiveUnits", "requiredFeatures", "width", "x", "xlink:href", "y"],
|
||||
"feGaussianBlur": ["class", "color-interpolation-filters", "id", "requiredFeatures", "stdDeviation"],
|
||||
"filter": ["class", "color-interpolation-filters", "filterRes", "filterUnits", "height", "id", "primitiveUnits", "requiredFeatures", "width", "x", "xlink:href", "y"],
|
||||
"foreignObject": ["class", "font-size", "height", "id", "opacity", "requiredFeatures", "style", "transform", "width", "x", "y"],
|
||||
"g": ["class", "clip-path", "clip-rule", "id", "display", "fill", "fill-opacity", "fill-rule", "filter", "mask", "opacity", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
||||
"image": ["class", "clip-path", "clip-rule", "filter", "height", "id", "mask", "opacity", "requiredFeatures", "style", "systemLanguage", "transform", "width", "x", "xlink:href", "xlink:title", "y"],
|
||||
|
@ -1143,6 +1143,8 @@ function BatchCommand(text) {
|
|||
'opacity':1,
|
||||
'stroke':'none',
|
||||
'stroke-dasharray':'none',
|
||||
'stroke-linejoin':'miter',
|
||||
'stroke-linecap':'butt',
|
||||
'stroke-opacity':1,
|
||||
'stroke-width':1,
|
||||
'rx':0,
|
||||
|
@ -1171,6 +1173,20 @@ function BatchCommand(text) {
|
|||
current_layer.appendChild(shape);
|
||||
}
|
||||
}
|
||||
if(data.curStyles) {
|
||||
assignAttributes(shape, {
|
||||
"fill": cur_shape.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_dasharray,
|
||||
"stroke-linejoin": cur_shape.stroke_linejoin,
|
||||
"stroke-linecap": cur_shape.stroke_linecap,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
"style": "pointer-events:inherit"
|
||||
}, 100);
|
||||
}
|
||||
assignAttributes(shape, data.attr, 100);
|
||||
cleanupElement(shape);
|
||||
return shape;
|
||||
|
@ -1211,7 +1227,9 @@ function BatchCommand(text) {
|
|||
stroke_paint: null,
|
||||
stroke_opacity: curConfig.initStroke.opacity,
|
||||
stroke_width: curConfig.initStroke.width,
|
||||
stroke_style: 'none',
|
||||
stroke_dasharray: 'none',
|
||||
stroke_linejoin: 'miter',
|
||||
stroke_linecap: 'butt',
|
||||
opacity: curConfig.initOpacity
|
||||
}
|
||||
};
|
||||
|
@ -1321,6 +1339,10 @@ function BatchCommand(text) {
|
|||
undoStackPointer = undoStack.length;
|
||||
};
|
||||
|
||||
this.getHistoryPosition = function() {
|
||||
return undoStackPointer;
|
||||
};
|
||||
|
||||
// private functions
|
||||
var getId = function() {
|
||||
if (events["getid"]) return call("getid", obj_num);
|
||||
|
@ -1953,7 +1975,7 @@ function BatchCommand(text) {
|
|||
break;
|
||||
case 9: // relative quad (q)
|
||||
case 8: // absolute quad (Q)
|
||||
dstr += seg.x + "," + seg.y + " " + seg.x1 + "," + seg.y1 + " ";
|
||||
dstr += seg.x1 + "," + seg.y1 + " " + seg.x + "," + seg.y + " ";
|
||||
break;
|
||||
case 11: // relative elliptical arc (a)
|
||||
case 10: // absolute elliptical arc (A)
|
||||
|
@ -1962,7 +1984,7 @@ function BatchCommand(text) {
|
|||
break;
|
||||
case 17: // relative smooth cubic (s)
|
||||
case 16: // absolute smooth cubic (S)
|
||||
dstr += seg.x + "," + seg.y + " " + seg.x2 + "," + seg.y2 + " ";
|
||||
dstr += seg.x2 + "," + seg.y2 + " " + seg.x + "," + seg.y + " ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2130,12 +2152,14 @@ function BatchCommand(text) {
|
|||
|
||||
var angle = canvas.getRotationAngle(child);
|
||||
var old_start_transform = start_transform;
|
||||
var childxforms = [];
|
||||
start_transform = child.getAttribute("transform");
|
||||
if(angle || hasMatrixTransform(childTlist)) {
|
||||
var e2t = svgroot.createSVGTransform();
|
||||
e2t.setMatrix(matrixMultiply(tm, sm, tmn, m));
|
||||
childTlist.clear();
|
||||
childTlist.appendItem(e2t,0);
|
||||
childTlist.appendItem(e2t);
|
||||
childxforms.push(e2t);
|
||||
}
|
||||
// if not rotated or skewed, push the [T][S][-T] down to the child
|
||||
else {
|
||||
|
@ -2144,6 +2168,7 @@ function BatchCommand(text) {
|
|||
// slide the [T][S][-T] from the front to the back
|
||||
// [T][S][-T][M] = [M][T2][S2][-T2]
|
||||
|
||||
// (only bringing [-T] to the right of [M])
|
||||
// [T][S][-T][M] = [T][S][M][-T2]
|
||||
// [-T2] = [M_inv][-T][M]
|
||||
var t2n = matrixMultiply(m.inverse(), tmn, m);
|
||||
|
@ -2165,8 +2190,28 @@ function BatchCommand(text) {
|
|||
childTlist.appendItem(translateBack);
|
||||
childTlist.appendItem(scale);
|
||||
childTlist.appendItem(translateOrigin);
|
||||
childxforms.push(translateBack);
|
||||
childxforms.push(scale);
|
||||
childxforms.push(translateOrigin);
|
||||
logMatrix(translateBack.matrix);
|
||||
logMatrix(scale.matrix);
|
||||
} // not rotated
|
||||
batchCmd.addSubCommand( recalculateDimensions(child) );
|
||||
// TODO: If any <use> have this group as a parent and are
|
||||
// referencing this child, then we need to impose a reverse
|
||||
// scale on it so that when it won't get double-translated
|
||||
// var uses = selected.getElementsByTagNameNS(svgns, "use");
|
||||
// var href = "#"+child.id;
|
||||
// var u = uses.length;
|
||||
// while (u--) {
|
||||
// var useElem = uses.item(u);
|
||||
// if(href == useElem.getAttributeNS(xlinkns, "href")) {
|
||||
// var usexlate = svgroot.createSVGTransform();
|
||||
// usexlate.setTranslate(-tx,-ty);
|
||||
// canvas.getTransformList(useElem).insertItemBefore(usexlate,0);
|
||||
// batchCmd.addSubCommand( recalculateDimensions(useElem) );
|
||||
// }
|
||||
// }
|
||||
start_transform = old_start_transform;
|
||||
} // element
|
||||
} // for each child
|
||||
|
@ -2216,6 +2261,21 @@ function BatchCommand(text) {
|
|||
newxlate.setTranslate(tx,ty);
|
||||
childTlist.insertItemBefore(newxlate, 0);
|
||||
batchCmd.addSubCommand( recalculateDimensions(child) );
|
||||
// If any <use> have this group as a parent and are
|
||||
// referencing this child, then impose a reverse translate on it
|
||||
// so that when it won't get double-translated
|
||||
var uses = selected.getElementsByTagNameNS(svgns, "use");
|
||||
var href = "#"+child.id;
|
||||
var u = uses.length;
|
||||
while (u--) {
|
||||
var useElem = uses.item(u);
|
||||
if(href == useElem.getAttributeNS(xlinkns, "href")) {
|
||||
var usexlate = svgroot.createSVGTransform();
|
||||
usexlate.setTranslate(-tx,-ty);
|
||||
canvas.getTransformList(useElem).insertItemBefore(usexlate,0);
|
||||
batchCmd.addSubCommand( recalculateDimensions(useElem) );
|
||||
}
|
||||
}
|
||||
start_transform = old_start_transform;
|
||||
}
|
||||
}
|
||||
|
@ -2810,6 +2870,7 @@ function BatchCommand(text) {
|
|||
// and do nothing else
|
||||
var mouseDown = function(evt)
|
||||
{
|
||||
if(evt.button === 1 || canvas.spaceKey) return;
|
||||
root_sctm = svgcontent.getScreenCTM().inverse();
|
||||
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm ),
|
||||
mouse_x = pt.x * current_zoom,
|
||||
|
@ -2964,17 +3025,13 @@ function BatchCommand(text) {
|
|||
var stroke_w = cur_shape.stroke_width == 0?1:cur_shape.stroke_width;
|
||||
addSvgElementFromJson({
|
||||
"element": "polyline",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"points": d_attr,
|
||||
"id": getNextId(),
|
||||
"fill": "none",
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": stroke_w,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
"stroke-linecap": "round",
|
||||
"style": "pointer-events:none"
|
||||
}
|
||||
});
|
||||
|
@ -3011,20 +3068,14 @@ function BatchCommand(text) {
|
|||
start_y = y;
|
||||
addSvgElementFromJson({
|
||||
"element": "rect",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"x": x,
|
||||
"y": y,
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"id": getNextId(),
|
||||
"fill": cur_shape.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
"style": "pointer-events:inherit"
|
||||
"opacity": cur_shape.opacity / 2
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -3033,6 +3084,7 @@ function BatchCommand(text) {
|
|||
var stroke_w = cur_shape.stroke_width == 0?1:cur_shape.stroke_width;
|
||||
addSvgElementFromJson({
|
||||
"element": "line",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"x1": x,
|
||||
"y1": y,
|
||||
|
@ -3041,7 +3093,9 @@ function BatchCommand(text) {
|
|||
"id": getNextId(),
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": stroke_w,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-dasharray": cur_shape.stroke_dasharray,
|
||||
"stroke-linejoin": cur_shape.stroke_linejoin,
|
||||
"stroke-linecap": cur_shape.stroke_linecap,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill": "none",
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
|
@ -3053,19 +3107,13 @@ function BatchCommand(text) {
|
|||
started = true;
|
||||
addSvgElementFromJson({
|
||||
"element": "circle",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"cx": x,
|
||||
"cy": y,
|
||||
"r": 0,
|
||||
"id": getNextId(),
|
||||
"fill": cur_shape.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
"style": "pointer-events:inherit"
|
||||
"opacity": cur_shape.opacity / 2
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -3073,20 +3121,14 @@ function BatchCommand(text) {
|
|||
started = true;
|
||||
addSvgElementFromJson({
|
||||
"element": "ellipse",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"cx": x,
|
||||
"cy": y,
|
||||
"rx": 0,
|
||||
"ry": 0,
|
||||
"id": getNextId(),
|
||||
"fill": cur_shape.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
"style": "pointer-events:inherit"
|
||||
"opacity": cur_shape.opacity / 2
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -3094,22 +3136,16 @@ function BatchCommand(text) {
|
|||
started = true;
|
||||
var newText = addSvgElementFromJson({
|
||||
"element": "text",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"x": x,
|
||||
"y": y,
|
||||
"id": getNextId(),
|
||||
"fill": cur_text.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_text.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
// fix for bug where text elements were always 50% opacity
|
||||
"opacity": cur_shape.opacity,
|
||||
"font-size": cur_text.font_size,
|
||||
"font-family": cur_text.font_family,
|
||||
"text-anchor": "middle",
|
||||
"style": "pointer-events:inherit",
|
||||
"xml:space": "preserve"
|
||||
}
|
||||
});
|
||||
|
@ -3155,6 +3191,7 @@ function BatchCommand(text) {
|
|||
var mouseMove = function(evt)
|
||||
{
|
||||
if (!started) return;
|
||||
if(evt.button === 1 || canvas.spaceKey) return;
|
||||
var selected = selectedElements[0],
|
||||
pt = transformPoint( evt.pageX, evt.pageY, root_sctm ),
|
||||
mouse_x = pt.x * current_zoom,
|
||||
|
@ -3452,6 +3489,7 @@ function BatchCommand(text) {
|
|||
|
||||
var mouseUp = function(evt)
|
||||
{
|
||||
if(evt.button === 1) return;
|
||||
var tempJustSelected = justSelected;
|
||||
justSelected = null;
|
||||
if (!started) return;
|
||||
|
@ -3486,7 +3524,9 @@ function BatchCommand(text) {
|
|||
cur_properties.stroke = selected.getAttribute("stroke");
|
||||
cur_properties.stroke_opacity = selected.getAttribute("stroke-opacity");
|
||||
cur_properties.stroke_width = selected.getAttribute("stroke-width");
|
||||
cur_properties.stroke_style = selected.getAttribute("stroke-dasharray");
|
||||
cur_properties.stroke_dasharray = selected.getAttribute("stroke-dasharray");
|
||||
cur_properties.stroke_linejoin = selected.getAttribute("stroke-linejoin");
|
||||
cur_properties.stroke_linecap = selected.getAttribute("stroke-linecap");
|
||||
}
|
||||
if (selected.tagName == "text") {
|
||||
cur_text.font_size = selected.getAttribute("font-size");
|
||||
|
@ -3577,20 +3617,13 @@ function BatchCommand(text) {
|
|||
(freehand.maxy - freehand.miny) > 0) {
|
||||
element = addSvgElementFromJson({
|
||||
"element": "ellipse",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"cx": (freehand.minx + freehand.maxx) / 2,
|
||||
"cy": (freehand.miny + freehand.maxy) / 2,
|
||||
"rx": (freehand.maxx - freehand.minx) / 2,
|
||||
"ry": (freehand.maxy - freehand.miny) / 2,
|
||||
"id": getId(),
|
||||
"fill": cur_shape.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"opacity": cur_shape.opacity,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"style": "pointer-events:inherit"
|
||||
"id": getId()
|
||||
}
|
||||
});
|
||||
call("changed",[element]);
|
||||
|
@ -3602,20 +3635,13 @@ function BatchCommand(text) {
|
|||
(freehand.maxy - freehand.miny) > 0) {
|
||||
element = addSvgElementFromJson({
|
||||
"element": "rect",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"x": freehand.minx,
|
||||
"y": freehand.miny,
|
||||
"width": (freehand.maxx - freehand.minx),
|
||||
"height": (freehand.maxy - freehand.miny),
|
||||
"id": getId(),
|
||||
"fill": cur_shape.fill,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"opacity": cur_shape.opacity,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"style": "pointer-events:inherit"
|
||||
"id": getId()
|
||||
}
|
||||
});
|
||||
call("changed",[element]);
|
||||
|
@ -4589,17 +4615,11 @@ function BatchCommand(text) {
|
|||
// create new path element
|
||||
element = addSvgElementFromJson({
|
||||
"element": "path",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"id": getId(),
|
||||
"d": d,
|
||||
"fill": "none",
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"opacity": cur_shape.opacity,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"style": "pointer-events:inherit"
|
||||
"fill": "none"
|
||||
}
|
||||
});
|
||||
call("changed",[element]);
|
||||
|
@ -4856,17 +4876,12 @@ function BatchCommand(text) {
|
|||
d_attr = "M" + x + "," + y + " ";
|
||||
addSvgElementFromJson({
|
||||
"element": "path",
|
||||
"curStyles": true,
|
||||
"attr": {
|
||||
"d": d_attr,
|
||||
"id": getNextId(),
|
||||
"fill": cur_shape.fill,
|
||||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"opacity": cur_shape.opacity / 2,
|
||||
"style": "pointer-events:inherit"
|
||||
|
||||
}
|
||||
});
|
||||
// set stretchy line to first point
|
||||
|
@ -5582,7 +5597,9 @@ function BatchCommand(text) {
|
|||
"fill-opacity": cur_shape.fill_opacity,
|
||||
"stroke": cur_shape.stroke,
|
||||
"stroke-width": cur_shape.stroke_width,
|
||||
"stroke-dasharray": cur_shape.stroke_style,
|
||||
"stroke-dasharray": cur_shape.stroke_dasharray,
|
||||
"stroke-linejoin": cur_shape.stroke_linejoin,
|
||||
"stroke-linecap": cur_shape.stroke_linecap,
|
||||
"stroke-opacity": cur_shape.stroke_opacity,
|
||||
"opacity": cur_shape.opacity,
|
||||
"visibility":"hidden"
|
||||
|
@ -5819,6 +5836,10 @@ function BatchCommand(text) {
|
|||
if (extensions["Arrows"]) call("unsetarrownonce") ;
|
||||
} else {
|
||||
randomize_ids = true;
|
||||
if (!svgcontent.getAttributeNS(se_ns, 'nonce')) {
|
||||
svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce);
|
||||
if (extensions["Arrows"]) call("setarrownonce", nonce) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5876,6 +5897,53 @@ function BatchCommand(text) {
|
|||
canvas.embedImage(val);
|
||||
});
|
||||
|
||||
// convert gradients with userSpaceOnUse to objectBoundingBox
|
||||
$(svgcontent).find('linearGradient, radialGradient').each(function() {
|
||||
var grad = this;
|
||||
if($(grad).attr('gradientUnits') === 'userSpaceOnUse') {
|
||||
// TODO: Support more than one element with this ref by duplicating parent grad
|
||||
var elems = $(svgcontent).find('[fill=url(#' + grad.id + ')],[stroke=url(#' + grad.id + ')]');
|
||||
if(!elems.length) return;
|
||||
|
||||
// get object's bounding box
|
||||
var bb = elems[0].getBBox();
|
||||
|
||||
if(grad.tagName === 'linearGradient') {
|
||||
var g_coords = $(grad).attr(['x1', 'y1', 'x2', 'y2']);
|
||||
|
||||
$(grad).attr({
|
||||
x1: (g_coords.x1 - bb.x) / bb.width,
|
||||
y1: (g_coords.y1 - bb.y) / bb.height,
|
||||
x2: (g_coords.x2 - bb.x) / bb.width,
|
||||
y2: (g_coords.y1 - bb.y) / bb.height
|
||||
});
|
||||
|
||||
grad.removeAttribute('gradientUnits');
|
||||
} else {
|
||||
// Note: radialGradient elements cannot be easily converted
|
||||
// because userSpaceOnUse will keep circular gradients, while
|
||||
// objectBoundingBox will x/y scale the gradient according to
|
||||
// its bbox.
|
||||
|
||||
// For now we'll do nothing, though we should probably have
|
||||
// the gradient be updated as the element is moved, as
|
||||
// inkscape/illustrator do.
|
||||
|
||||
// var g_coords = $(grad).attr(['cx', 'cy', 'r']);
|
||||
//
|
||||
// $(grad).attr({
|
||||
// cx: (g_coords.cx - bb.x) / bb.width,
|
||||
// cy: (g_coords.cy - bb.y) / bb.height,
|
||||
// r: g_coords.r
|
||||
// });
|
||||
//
|
||||
// grad.removeAttribute('gradientUnits');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Fix XML for Opera/Win/Non-EN
|
||||
if(!support.goodDecimals) {
|
||||
canvas.fixOperaXML(svgcontent, newDoc.documentElement);
|
||||
|
@ -6985,12 +7053,8 @@ function BatchCommand(text) {
|
|||
}
|
||||
};
|
||||
|
||||
this.getStrokeStyle = function() {
|
||||
return cur_shape.stroke_style;
|
||||
};
|
||||
|
||||
this.setStrokeStyle = function(val) {
|
||||
cur_shape.stroke_style = val;
|
||||
this.setStrokeAttr = function(attr, val) {
|
||||
cur_shape[attr.replace('-','_')] = val;
|
||||
var elems = [];
|
||||
var i = selectedElements.length;
|
||||
while (i--) {
|
||||
|
@ -7003,7 +7067,7 @@ function BatchCommand(text) {
|
|||
}
|
||||
}
|
||||
if (elems.length > 0) {
|
||||
this.changeSelectedAttribute("stroke-dasharray", val, elems);
|
||||
this.changeSelectedAttribute(attr, val, elems);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8239,7 +8303,7 @@ function BatchCommand(text) {
|
|||
// Function: getVersion
|
||||
// Returns a string which describes the revision number of SvgCanvas.
|
||||
this.getVersion = function() {
|
||||
return "svgcanvas.js ($Rev: 1470 $)";
|
||||
return "svgcanvas.js ($Rev: 1498 $)";
|
||||
};
|
||||
|
||||
this.setUiStrings = function(strs) {
|
||||
|
|
|
@ -293,6 +293,17 @@ $(function() {
|
|||
var svgroot = svgdoc.createElementNS(svgns, "svg");
|
||||
svgroot.setAttributeNS(svgns, 'viewBox', [0,0,icon_w,icon_h].join(' '));
|
||||
|
||||
// Make flexible by converting width/height to viewBox
|
||||
var w = svg.getAttribute('width');
|
||||
var h = svg.getAttribute('height');
|
||||
svg.removeAttribute('width');
|
||||
svg.removeAttribute('height');
|
||||
|
||||
var vb = svg.getAttribute('viewBox');
|
||||
if(!vb) {
|
||||
svg.setAttribute('viewBox', [0,0,w,h].join(' '));
|
||||
}
|
||||
|
||||
$(svgroot).attr({
|
||||
"xmlns": svgns,
|
||||
"width": icon_w,
|
||||
|
|
Loading…
Reference in a new issue