2018-05-18 03:25:45 +00:00
/* globals jQuery, ActiveXObject */
2010-10-26 02:48:36 +00:00
/ * *
2010-11-05 17:00:32 +00:00
* Package : svgedit . utilities
2010-10-26 02:48:36 +00:00
*
2012-09-16 18:53:27 +00:00
* Licensed under the MIT License
2010-10-26 02:48:36 +00:00
*
* Copyright ( c ) 2010 Alexis Deveria
* Copyright ( c ) 2010 Jeff Schiller
* /
2018-05-18 03:25:45 +00:00
import './pathseg.js' ;
import RGBColor from './canvg/rgbcolor.js' ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
import jqPluginSVG from './jquery-svg.js' ; // Needed for SVG attribute setting and array form with `attr`
import { importScript , importModule } from './external/dynamic-import-polyfill/importModule.js' ;
2018-05-18 03:25:45 +00:00
import { NS } from './svgedit.js' ;
import { getTransformList } from './svgtransformlist.js' ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
import { setUnitAttr , getTypeMap } from './units.js' ;
import { convertPath } from './path.js' ;
2018-05-18 03:25:45 +00:00
import {
hasMatrixTransform , transformListToTransform , transformBox
} from './math.js' ;
import {
isWebkit , supportsHVLineContainerBBox , supportsPathBBox , supportsXpath ,
supportsSelectors
} from './browser.js' ;
2010-10-26 02:48:36 +00:00
2010-10-29 05:09:39 +00:00
// Constants
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
const $ = jqPluginSVG ( jQuery ) ;
2010-10-29 05:09:39 +00:00
2010-10-26 02:48:36 +00:00
// String used to encode base64.
2018-05-18 03:25:45 +00:00
const KEYSTR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ;
2010-10-26 02:48:36 +00:00
2010-11-05 15:29:30 +00:00
// Much faster than running getBBox() every time
2018-05-18 03:25:45 +00:00
const visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use' ;
const visElemsArr = visElems . split ( ',' ) ;
// const hidElems = 'clipPath,defs,desc,feGaussianBlur,filter,linearGradient,marker,mask,metadata,pattern,radialGradient,stop,switch,symbol,title,textPath';
2010-11-05 15:29:30 +00:00
2018-05-18 03:25:45 +00:00
let editorContext _ = null ;
let domdoc _ = null ;
let domcontainer _ = null ;
let svgroot _ = null ;
2010-12-02 17:14:24 +00:00
2018-05-18 03:25:45 +00:00
export const init = function ( editorContext ) {
2018-05-18 04:02:30 +00:00
editorContext _ = editorContext ;
domdoc _ = editorContext . getDOMDocument ( ) ;
domcontainer _ = editorContext . getDOMContainer ( ) ;
svgroot _ = editorContext . getSVGRoot ( ) ;
2010-12-02 17:14:24 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Converts characters in a string to XML - friendly entities .
* @ example : '&' becomes '&'
* @ param str - The string to be converted
* @ returns { String } The converted string
* /
2018-05-18 03:25:45 +00:00
export const toXml = function ( str ) {
2018-05-18 04:02:30 +00:00
// ' is ok in XML, but not HTML
// > does not normally need escaping, though it can if within a CDATA expression (and preceded by "]]")
return str . replace ( /&/g , '&' ) . replace ( /</g , '<' ) . replace ( />/g , '>' ) . replace ( /"/g , '"' ) . replace ( /'/ , ''' ) ;
2010-10-26 02:48:36 +00:00
} ;
2013-02-15 23:05:23 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Converts XML entities in a string to single characters .
* @ example '&amp;' becomes '&'
* @ param str - The string to be converted
* @ returns The converted string
* /
2018-05-18 03:25:45 +00:00
export const fromXml = function ( str ) {
2018-05-18 04:02:30 +00:00
return $ ( '<p/>' ) . html ( str ) . text ( ) ;
2010-10-26 02:48:36 +00:00
} ;
// This code was written by Tyler Akins and has been placed in the
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
// schiller: Removed string concatenation in favour of Array.join() optimization,
2018-05-18 06:41:43 +00:00
// also precalculate the size of the array needed.
2010-10-26 02:48:36 +00:00
// Converts a string to base64
2018-05-18 03:25:45 +00:00
export const encode64 = function ( input ) {
2018-05-18 04:02:30 +00:00
// base64 strings are 4/3 larger than the original string
2018-05-18 03:25:45 +00:00
input = encodeUTF8 ( input ) ; // convert non-ASCII characters
// input = convertToXMLReferences(input);
2018-05-18 04:02:30 +00:00
if ( window . btoa ) {
return window . btoa ( input ) ; // Use native if available
}
2018-05-18 03:25:45 +00:00
const output = [ ] ;
2018-05-18 04:02:30 +00:00
output . length = Math . floor ( ( input . length + 2 ) / 3 ) * 4 ;
2018-05-18 03:25:45 +00:00
let i = 0 , p = 0 ;
2018-05-18 04:02:30 +00:00
do {
2018-05-18 03:25:45 +00:00
const chr1 = input . charCodeAt ( i ++ ) ;
const chr2 = input . charCodeAt ( i ++ ) ;
const chr3 = input . charCodeAt ( i ++ ) ;
const enc1 = chr1 >> 2 ;
const enc2 = ( ( chr1 & 3 ) << 4 ) | ( chr2 >> 4 ) ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
let enc3 = ( ( chr2 & 15 ) << 2 ) | ( chr3 >> 6 ) ;
let enc4 = chr3 & 63 ;
2018-05-18 04:02:30 +00:00
if ( isNaN ( chr2 ) ) {
enc3 = enc4 = 64 ;
} else if ( isNaN ( chr3 ) ) {
enc4 = 64 ;
}
output [ p ++ ] = KEYSTR . charAt ( enc1 ) ;
output [ p ++ ] = KEYSTR . charAt ( enc2 ) ;
output [ p ++ ] = KEYSTR . charAt ( enc3 ) ;
output [ p ++ ] = KEYSTR . charAt ( enc4 ) ;
} while ( i < input . length ) ;
return output . join ( '' ) ;
2010-10-26 02:48:36 +00:00
} ;
// Converts a string from base64
2018-05-18 03:25:45 +00:00
export const decode64 = function ( input ) {
2018-05-18 04:02:30 +00:00
if ( window . atob ) {
2018-05-18 03:25:45 +00:00
return decodeUTF8 ( window . atob ( input ) ) ;
2018-05-18 04:02:30 +00:00
}
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input . replace ( /[^A-Za-z0-9+/=]/g , '' ) ;
2018-05-18 03:25:45 +00:00
let output = '' ;
let i = 0 ;
2018-05-18 04:02:30 +00:00
do {
2018-05-18 03:25:45 +00:00
const enc1 = KEYSTR . indexOf ( input . charAt ( i ++ ) ) ;
const enc2 = KEYSTR . indexOf ( input . charAt ( i ++ ) ) ;
const enc3 = KEYSTR . indexOf ( input . charAt ( i ++ ) ) ;
const enc4 = KEYSTR . indexOf ( input . charAt ( i ++ ) ) ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
const chr1 = ( enc1 << 2 ) | ( enc2 >> 4 ) ;
const chr2 = ( ( enc2 & 15 ) << 4 ) | ( enc3 >> 2 ) ;
const chr3 = ( ( enc3 & 3 ) << 6 ) | enc4 ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
output += String . fromCharCode ( chr1 ) ;
2018-05-18 04:02:30 +00:00
if ( enc3 !== 64 ) {
output = output + String . fromCharCode ( chr2 ) ;
}
if ( enc4 !== 64 ) {
output = output + String . fromCharCode ( chr3 ) ;
}
} while ( i < input . length ) ;
2018-05-18 03:25:45 +00:00
return decodeUTF8 ( output ) ;
2014-06-12 23:42:27 +00:00
} ;
2018-05-18 03:25:45 +00:00
export const decodeUTF8 = function ( argString ) {
2018-05-18 04:02:30 +00:00
return decodeURIComponent ( escape ( argString ) ) ;
2010-10-26 02:48:36 +00:00
} ;
2014-02-01 16:13:51 +00:00
// codedread:does not seem to work with webkit-based browsers on OSX // Brettz9: please test again as function upgraded
2018-05-18 03:25:45 +00:00
export const encodeUTF8 = function ( argString ) {
2018-05-18 04:02:30 +00:00
return unescape ( encodeURIComponent ( argString ) ) ;
2014-02-01 16:13:51 +00:00
} ;
2010-10-26 02:48:36 +00:00
2018-04-12 18:00:52 +00:00
/ * *
* convert dataURL to object URL
* @ param { string } dataurl
* @ return { string } object URL or empty string
* /
2018-05-18 03:25:45 +00:00
export const dataURLToObjectURL = function ( dataurl ) {
2018-05-18 04:02:30 +00:00
if ( typeof Uint8Array === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || ! URL . createObjectURL ) {
return '' ;
}
2018-05-18 03:25:45 +00:00
const arr = dataurl . split ( ',' ) , mime = arr [ 0 ] . match ( /:(.*?);/ ) [ 1 ] ,
bstr = atob ( arr [ 1 ] ) ;
let n = bstr . length ;
const u8arr = new Uint8Array ( n ) ;
2018-05-18 04:02:30 +00:00
while ( n -- ) {
u8arr [ n ] = bstr . charCodeAt ( n ) ;
}
2018-05-18 03:25:45 +00:00
const blob = new Blob ( [ u8arr ] , { type : mime } ) ;
2018-05-18 04:02:30 +00:00
return URL . createObjectURL ( blob ) ;
2018-04-12 18:00:52 +00:00
} ;
/ * *
* get object URL for a blob object
* @ param { Blob } blob A Blob object or File object
* @ return { string } object URL or empty string
* /
2018-05-18 03:25:45 +00:00
export const createObjectURL = function ( blob ) {
2018-05-18 04:02:30 +00:00
if ( ! blob || typeof URL === 'undefined' || ! URL . createObjectURL ) {
return '' ;
}
return URL . createObjectURL ( blob ) ;
2018-04-12 18:00:52 +00:00
} ;
/ * *
* @ property { string } blankPageObjectURL
* /
2018-05-18 03:25:45 +00:00
export const blankPageObjectURL = ( function ( ) {
2018-05-18 04:02:30 +00:00
if ( typeof Blob === 'undefined' ) {
return '' ;
}
2018-05-18 03:25:45 +00:00
const blob = new Blob ( [ '<html><head><title>SVG-edit</title></head><body> </body></html>' ] , { type : 'text/html' } ) ;
return createObjectURL ( blob ) ;
2018-05-16 00:53:27 +00:00
} ) ( ) ;
2018-04-12 18:00:52 +00:00
2010-10-26 02:48:36 +00:00
// Converts a string to use XML references
2018-05-18 03:25:45 +00:00
export const convertToXMLReferences = function ( input ) {
let n ,
2018-05-18 04:02:30 +00:00
output = '' ;
for ( n = 0 ; n < input . length ; n ++ ) {
2018-05-18 03:25:45 +00:00
const c = input . charCodeAt ( n ) ;
2018-05-18 04:02:30 +00:00
if ( c < 128 ) {
output += input [ n ] ;
} else if ( c > 127 ) {
output += ( '&#' + c + ';' ) ;
}
}
return output ;
2010-10-26 02:48:36 +00:00
} ;
// Cross-browser compatible method of converting a string to an XML tree
2018-05-18 03:25:45 +00:00
// found this function here: http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f
export const text2xml = function ( sXML ) {
if ( sXML . includes ( '<svg:svg' ) ) {
2018-05-18 04:02:30 +00:00
sXML = sXML . replace ( /<(\/?)svg:/g , '<$1' ) . replace ( 'xmlns:svg' , 'xmlns' ) ;
}
2018-05-18 03:25:45 +00:00
let out , dXML ;
2018-05-18 04:02:30 +00:00
try {
dXML = ( window . DOMParser ) ? new DOMParser ( ) : new ActiveXObject ( 'Microsoft.XMLDOM' ) ;
dXML . async = false ;
} catch ( e ) {
throw new Error ( 'XML Parser could not be instantiated' ) ;
}
try {
if ( dXML . loadXML ) {
out = ( dXML . loadXML ( sXML ) ) ? dXML : false ;
} else {
out = dXML . parseFromString ( sXML , 'text/xml' ) ;
}
} catch ( e2 ) { throw new Error ( 'Error parsing XML string' ) ; }
return out ;
2010-10-26 02:48:36 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Converts a SVGRect into an object .
* @ param bbox - a SVGRect
* @ returns An object with properties names x , y , width , height .
* /
2018-05-18 03:25:45 +00:00
export const bboxToObj = function ( bbox ) {
2018-05-18 04:02:30 +00:00
return {
x : bbox . x ,
y : bbox . y ,
width : bbox . width ,
height : bbox . height
} ;
2010-10-26 02:48:36 +00:00
} ;
2010-10-26 16:33:44 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Walks the tree and executes the callback on each element in a top - down fashion
* @ param elem - DOM element to traverse
* @ param { Function } cbFn - Callback function to run on each element
* /
2018-05-18 03:25:45 +00:00
export const walkTree = function ( elem , cbFn ) {
2018-05-18 04:02:30 +00:00
if ( elem && elem . nodeType === 1 ) {
cbFn ( elem ) ;
2018-05-18 03:25:45 +00:00
let i = elem . childNodes . length ;
2018-05-18 04:02:30 +00:00
while ( i -- ) {
2018-05-18 03:25:45 +00:00
walkTree ( elem . childNodes . item ( i ) , cbFn ) ;
2018-05-18 04:02:30 +00:00
}
}
2010-10-26 17:11:23 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Walks the tree and executes the callback on each element in a depth - first fashion
* @ todo FIXME : Shouldn ' t this be calling walkTreePost ?
* @ param elem - DOM element to traverse
* @ param { Function } cbFn - Callback function to run on each element
* /
2018-05-18 03:25:45 +00:00
export const walkTreePost = function ( elem , cbFn ) {
2018-05-18 04:02:30 +00:00
if ( elem && elem . nodeType === 1 ) {
2018-05-18 03:25:45 +00:00
let i = elem . childNodes . length ;
2018-05-18 04:02:30 +00:00
while ( i -- ) {
2018-05-18 03:25:45 +00:00
walkTree ( elem . childNodes . item ( i ) , cbFn ) ;
2018-05-18 04:02:30 +00:00
}
cbFn ( elem ) ;
}
2010-10-26 17:11:23 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Extracts the URL from the url ( ... ) syntax of some attributes .
* Three variants :
* - < circle fill = "url(someFile.svg#foo)" / >
* - < circle fill = "url('someFile.svg#foo')" / >
* - < circle fill = 'url("someFile.svg#foo")' / >
* @ param attrVal - The attribute value as a string
* @ returns { String } String with just the URL , like "someFile.svg#foo"
* /
2018-05-18 03:25:45 +00:00
export const getUrlFromAttr = function ( attrVal ) {
2018-05-18 04:02:30 +00:00
if ( attrVal ) {
2018-05-30 23:52:13 +00:00
// url('#somegrad')
2018-05-18 03:25:45 +00:00
if ( attrVal . startsWith ( 'url("' ) ) {
2018-05-18 04:02:30 +00:00
return attrVal . substring ( 5 , attrVal . indexOf ( '"' , 6 ) ) ;
}
// url('#somegrad')
2018-05-18 03:25:45 +00:00
if ( attrVal . startsWith ( "url('" ) ) {
2018-05-18 04:02:30 +00:00
return attrVal . substring ( 5 , attrVal . indexOf ( "'" , 6 ) ) ;
}
2018-05-18 03:25:45 +00:00
if ( attrVal . startsWith ( 'url(' ) ) {
2018-05-18 04:02:30 +00:00
return attrVal . substring ( 4 , attrVal . indexOf ( ')' ) ) ;
}
}
return null ;
2010-10-26 17:11:23 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* @ returns The given element ' s xlink : href value
* /
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
export let getHref = function ( elem ) {
2018-05-18 04:02:30 +00:00
return elem . getAttributeNS ( NS . XLINK , 'href' ) ;
2013-02-19 11:18:04 +00:00
} ;
2010-10-28 05:50:39 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Sets the given element ' s xlink : href value
* @ param elem
* @ param { String } val
* /
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
export let setHref = function ( elem , val ) {
2018-05-18 04:02:30 +00:00
elem . setAttributeNS ( NS . XLINK , 'xlink:href' , val ) ;
2013-02-19 11:18:04 +00:00
} ;
2010-10-28 05:50:39 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* @ returns The document ' s & lt ; defs > element , create it first if necessary
* /
2018-05-18 03:25:45 +00:00
export const findDefs = function ( ) {
const svgElement = editorContext _ . getSVGContent ( ) ;
let defs = svgElement . getElementsByTagNameNS ( NS . SVG , 'defs' ) ;
2018-05-18 04:02:30 +00:00
if ( defs . length > 0 ) {
defs = defs [ 0 ] ;
} else {
defs = svgElement . ownerDocument . createElementNS ( NS . SVG , 'defs' ) ;
if ( svgElement . firstChild ) {
// first child is a comment, so call nextSibling
svgElement . insertBefore ( defs , svgElement . firstChild . nextSibling ) ;
} else {
svgElement . appendChild ( defs ) ;
}
}
return defs ;
2010-10-28 05:50:39 +00:00
} ;
2010-11-08 08:42:46 +00:00
// TODO(codedread): Consider moving the next to functions to bbox.js
2018-05-29 12:31:24 +00:00
/ * *
* Get correct BBox for a path in Webkit
* Converted from code found here :
* http : //blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
* @ param path - The path DOM element to get the BBox for
* @ returns A BBox - like object
* /
2018-05-18 03:25:45 +00:00
export const getPathBBox = function ( path ) {
const seglist = path . pathSegList ;
const tot = seglist . numberOfItems ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
const bounds = [ [ ] , [ ] ] ;
const start = seglist . getItem ( 0 ) ;
let P0 = [ start . x , start . y ] ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
for ( let i = 0 ; i < tot ; i ++ ) {
const seg = seglist . getItem ( i ) ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
if ( seg . x === undefined ) { continue ; }
2018-05-18 04:02:30 +00:00
// Add actual points to limits
bounds [ 0 ] . push ( P0 [ 0 ] ) ;
bounds [ 1 ] . push ( P0 [ 1 ] ) ;
if ( seg . x1 ) {
2018-05-18 03:25:45 +00:00
const P1 = [ seg . x1 , seg . y1 ] ,
2018-05-18 04:02:30 +00:00
P2 = [ seg . x2 , seg . y2 ] ,
P3 = [ seg . x , seg . y ] ;
2018-05-18 03:25:45 +00:00
for ( let j = 0 ; j < 2 ; j ++ ) {
const calc = function ( t ) {
2018-05-18 04:02:30 +00:00
return Math . pow ( 1 - t , 3 ) * P0 [ j ] +
3 * Math . pow ( 1 - t , 2 ) * t * P1 [ j ] +
3 * ( 1 - t ) * Math . pow ( t , 2 ) * P2 [ j ] +
Math . pow ( t , 3 ) * P3 [ j ] ;
} ;
2018-05-18 03:25:45 +00:00
const b = 6 * P0 [ j ] - 12 * P1 [ j ] + 6 * P2 [ j ] ;
const a = - 3 * P0 [ j ] + 9 * P1 [ j ] - 9 * P2 [ j ] + 3 * P3 [ j ] ;
const c = 3 * P1 [ j ] - 3 * P0 [ j ] ;
2018-05-18 04:02:30 +00:00
if ( a === 0 ) {
if ( b === 0 ) {
continue ;
}
2018-05-18 03:25:45 +00:00
const t = - c / b ;
2018-05-18 04:02:30 +00:00
if ( t > 0 && t < 1 ) {
bounds [ j ] . push ( calc ( t ) ) ;
}
continue ;
}
2018-05-18 03:25:45 +00:00
const b2ac = Math . pow ( b , 2 ) - 4 * c * a ;
2018-05-18 04:02:30 +00:00
if ( b2ac < 0 ) { continue ; }
2018-05-18 03:25:45 +00:00
const t1 = ( - b + Math . sqrt ( b2ac ) ) / ( 2 * a ) ;
2018-05-18 04:02:30 +00:00
if ( t1 > 0 && t1 < 1 ) { bounds [ j ] . push ( calc ( t1 ) ) ; }
2018-05-18 03:25:45 +00:00
const t2 = ( - b - Math . sqrt ( b2ac ) ) / ( 2 * a ) ;
2018-05-18 04:02:30 +00:00
if ( t2 > 0 && t2 < 1 ) { bounds [ j ] . push ( calc ( t2 ) ) ; }
}
P0 = P3 ;
} else {
bounds [ 0 ] . push ( seg . x ) ;
bounds [ 1 ] . push ( seg . y ) ;
}
}
2018-05-18 03:25:45 +00:00
const x = Math . min . apply ( null , bounds [ 0 ] ) ;
const w = Math . max . apply ( null , bounds [ 0 ] ) - x ;
const y = Math . min . apply ( null , bounds [ 1 ] ) ;
const h = Math . max . apply ( null , bounds [ 1 ] ) - y ;
2018-05-18 04:02:30 +00:00
return {
2018-05-18 03:25:45 +00:00
x ,
y ,
width : w ,
height : h
2018-05-18 04:02:30 +00:00
} ;
2010-11-05 15:29:30 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Get the given / selected element ' s bounding box object , checking for
* horizontal / vertical lines ( see issue 717 )
* Note that performance is currently terrible , so some way to improve would
* be great .
* @ param selected - Container or & lt ; use > DOM element
* @ returns Bounding box object
* /
2018-05-16 00:53:27 +00:00
function groupBBFix ( selected ) {
2018-05-18 03:25:45 +00:00
if ( supportsHVLineContainerBBox ( ) ) {
2018-05-18 04:02:30 +00:00
try { return selected . getBBox ( ) ; } catch ( e ) { }
}
2018-05-18 03:25:45 +00:00
const ref = $ . data ( selected , 'ref' ) ;
let matched = null ;
let ret , copy ;
2018-05-18 04:02:30 +00:00
if ( ref ) {
copy = $ ( ref ) . children ( ) . clone ( ) . attr ( 'visibility' , 'hidden' ) ;
$ ( svgroot _ ) . append ( copy ) ;
matched = copy . filter ( 'line, path' ) ;
} else {
matched = $ ( selected ) . find ( 'line, path' ) ;
}
2018-05-18 03:25:45 +00:00
let issue = false ;
2018-05-18 04:02:30 +00:00
if ( matched . length ) {
matched . each ( function ( ) {
2018-05-18 03:25:45 +00:00
const bb = this . getBBox ( ) ;
2018-05-18 04:02:30 +00:00
if ( ! bb . width || ! bb . height ) {
issue = true ;
}
} ) ;
if ( issue ) {
2018-05-18 03:25:45 +00:00
const elems = ref ? copy : $ ( selected ) . children ( ) ;
2018-05-18 04:02:30 +00:00
ret = getStrokedBBox ( elems ) ; // getStrokedBBox defined in svgcanvas
} else {
ret = selected . getBBox ( ) ;
}
} else {
ret = selected . getBBox ( ) ;
}
if ( ref ) {
copy . remove ( ) ;
}
return ret ;
2011-02-09 21:32:53 +00:00
}
2018-05-29 12:31:24 +00:00
/ * *
* Get the given / selected element ' s bounding box object , convert it to be more
* usable when necessary
* @ param elem - Optional DOM element to get the BBox for
* @ returns Bounding box object
* /
2018-05-18 03:25:45 +00:00
export const getBBox = function ( elem ) {
const selected = elem || editorContext _ . geSelectedElements ( ) [ 0 ] ;
2018-05-18 04:02:30 +00:00
if ( elem . nodeType !== 1 ) { return null ; }
2018-05-18 03:25:45 +00:00
const elname = selected . nodeName ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
let ret = null ;
2018-05-18 04:02:30 +00:00
switch ( elname ) {
case 'text' :
if ( selected . textContent === '' ) {
selected . textContent = 'a' ; // Some character needed for the selector to use.
ret = selected . getBBox ( ) ;
selected . textContent = '' ;
} else {
if ( selected . getBBox ) { ret = selected . getBBox ( ) ; }
}
break ;
case 'path' :
2018-05-18 03:25:45 +00:00
if ( ! supportsPathBBox ( ) ) {
ret = getPathBBox ( selected ) ;
2018-05-18 04:02:30 +00:00
} else {
if ( selected . getBBox ) { ret = selected . getBBox ( ) ; }
}
break ;
case 'g' :
case 'a' :
ret = groupBBFix ( selected ) ;
break ;
default :
if ( elname === 'use' ) {
ret = groupBBFix ( selected , true ) ;
}
2018-05-18 03:25:45 +00:00
if ( elname === 'use' || ( elname === 'foreignObject' && isWebkit ( ) ) ) {
2018-05-18 04:02:30 +00:00
if ( ! ret ) { ret = selected . getBBox ( ) ; }
// This is resolved in later versions of webkit, perhaps we should
// have a featured detection for correct 'use' behavior?
// ——————————
2018-05-18 03:25:45 +00:00
if ( ! isWebkit ( ) ) {
const bb = { } ;
2018-05-18 04:02:30 +00:00
bb . width = ret . width ;
bb . height = ret . height ;
bb . x = ret . x + parseFloat ( selected . getAttribute ( 'x' ) || 0 ) ;
bb . y = ret . y + parseFloat ( selected . getAttribute ( 'y' ) || 0 ) ;
ret = bb ;
}
2018-05-18 03:25:45 +00:00
} else if ( visElemsArr . includes ( elname ) ) {
2018-05-18 04:02:30 +00:00
if ( selected ) {
try {
ret = selected . getBBox ( ) ;
} catch ( err ) {
// tspan (and textPath apparently) have no `getBBox` in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=937268
// Re: Chrome returning bbox for containing text element, see: https://bugs.chromium.org/p/chromium/issues/detail?id=349835
2018-05-18 03:25:45 +00:00
const extent = selected . getExtentOfChar ( 0 ) ; // pos+dimensions of the first glyph
const width = selected . getComputedTextLength ( ) ; // width of the tspan
2018-05-18 04:02:30 +00:00
ret = {
x : extent . x ,
y : extent . y ,
2018-05-18 03:25:45 +00:00
width ,
2018-05-18 04:02:30 +00:00
height : extent . height
} ;
}
} else {
// Check if element is child of a foreignObject
2018-05-18 03:25:45 +00:00
const fo = $ ( selected ) . closest ( 'foreignObject' ) ;
2018-05-18 04:02:30 +00:00
if ( fo . length ) {
if ( fo [ 0 ] . getBBox ) {
ret = fo [ 0 ] . getBBox ( ) ;
}
}
}
}
}
if ( ret ) {
2018-05-18 03:25:45 +00:00
ret = bboxToObj ( ret ) ;
2018-05-18 04:02:30 +00:00
}
// get the bounding box from the DOM (which is in that element's coordinate system)
return ret ;
2010-11-05 15:29:30 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Create a path 'd' attribute from path segments .
* Each segment is an array of the form : [ singleChar , [ x , y , x , y , ... ] ]
* @ param pathSegments - An array of path segments to be converted
* @ returns The converted path d attribute .
* /
2018-05-18 03:25:45 +00:00
export const getPathDFromSegments = function ( pathSegments ) {
let d = '' ;
2018-05-18 04:02:30 +00:00
$ . each ( pathSegments , function ( j , seg ) {
2018-05-18 03:25:45 +00:00
const pts = seg [ 1 ] ;
2018-05-18 04:02:30 +00:00
d += seg [ 0 ] ;
2018-05-18 03:25:45 +00:00
for ( let i = 0 ; i < pts . length ; i += 2 ) {
2018-05-18 04:02:30 +00:00
d += ( pts [ i ] + ',' + pts [ i + 1 ] ) + ' ' ;
}
} ) ;
return d ;
2016-04-26 20:01:39 +00:00
} ;
2016-04-22 16:24:52 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Make a path 'd' attribute from a simple SVG element shape .
* @ param elem - The element to be converted
* @ returns The path d attribute or ` undefined ` if the element type is unknown .
* /
2018-05-18 03:25:45 +00:00
export const getPathDFromElement = function ( elem ) {
2018-05-18 04:02:30 +00:00
// Possibly the cubed root of 6, but 1.81 works best
2018-05-18 03:25:45 +00:00
let num = 1.81 ;
let d , a , rx , ry ;
2018-05-18 04:02:30 +00:00
switch ( elem . tagName ) {
case 'ellipse' :
case 'circle' :
a = $ ( elem ) . attr ( [ 'rx' , 'ry' , 'cx' , 'cy' ] ) ;
2018-05-18 03:25:45 +00:00
const { cx , cy } = a ;
( { rx , ry } = a ) ;
2018-05-18 04:02:30 +00:00
if ( elem . tagName === 'circle' ) {
rx = ry = $ ( elem ) . attr ( 'r' ) ;
}
2018-05-18 03:25:45 +00:00
d = getPathDFromSegments ( [
2018-05-18 04:02:30 +00:00
[ 'M' , [ ( cx - rx ) , ( cy ) ] ] ,
[ 'C' , [ ( cx - rx ) , ( cy - ry / num ) , ( cx - rx / num ) , ( cy - ry ) , ( cx ) , ( cy - ry ) ] ] ,
[ 'C' , [ ( cx + rx / num ) , ( cy - ry ) , ( cx + rx ) , ( cy - ry / num ) , ( cx + rx ) , ( cy ) ] ] ,
[ 'C' , [ ( cx + rx ) , ( cy + ry / num ) , ( cx + rx / num ) , ( cy + ry ) , ( cx ) , ( cy + ry ) ] ] ,
[ 'C' , [ ( cx - rx / num ) , ( cy + ry ) , ( cx - rx ) , ( cy + ry / num ) , ( cx - rx ) , ( cy ) ] ] ,
[ 'Z' , [ ] ]
] ) ;
break ;
case 'path' :
d = elem . getAttribute ( 'd' ) ;
break ;
case 'line' :
a = $ ( elem ) . attr ( [ 'x1' , 'y1' , 'x2' , 'y2' ] ) ;
d = 'M' + a . x1 + ',' + a . y1 + 'L' + a . x2 + ',' + a . y2 ;
break ;
case 'polyline' :
d = 'M' + elem . getAttribute ( 'points' ) ;
break ;
case 'polygon' :
d = 'M' + elem . getAttribute ( 'points' ) + ' Z' ;
break ;
case 'rect' :
2018-05-18 03:25:45 +00:00
const r = $ ( elem ) . attr ( [ 'rx' , 'ry' ] ) ;
( { rx , ry } = r ) ;
const b = elem . getBBox ( ) ;
const { x , y } = b , w = b . width , h = b . height ;
2018-05-18 04:02:30 +00:00
num = 4 - num ; // Why? Because!
if ( ! rx && ! ry ) {
// Regular rect
2018-05-18 03:25:45 +00:00
d = getPathDFromSegments ( [
2018-05-18 04:02:30 +00:00
[ 'M' , [ x , y ] ] ,
[ 'L' , [ x + w , y ] ] ,
[ 'L' , [ x + w , y + h ] ] ,
[ 'L' , [ x , y + h ] ] ,
[ 'L' , [ x , y ] ] ,
[ 'Z' , [ ] ]
] ) ;
} else {
2018-05-18 03:25:45 +00:00
d = getPathDFromSegments ( [
2018-05-18 04:02:30 +00:00
[ 'M' , [ x , y + ry ] ] ,
[ 'C' , [ x , y + ry / num , x + rx / num , y , x + rx , y ] ] ,
[ 'L' , [ x + w - rx , y ] ] ,
[ 'C' , [ x + w - rx / num , y , x + w , y + ry / num , x + w , y + ry ] ] ,
[ 'L' , [ x + w , y + h - ry ] ] ,
[ 'C' , [ x + w , y + h - ry / num , x + w - rx / num , y + h , x + w - rx , y + h ] ] ,
[ 'L' , [ x + rx , y + h ] ] ,
[ 'C' , [ x + rx / num , y + h , x , y + h - ry / num , x , y + h - ry ] ] ,
[ 'L' , [ x , y + ry ] ] ,
[ 'Z' , [ ] ]
] ) ;
}
break ;
default :
break ;
}
return d ;
2016-04-22 16:24:52 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Get a set of attributes from an element that is useful for convertToPath .
* @ param elem - The element to be probed
* @ returns { Object } An object with attributes .
* /
2018-05-18 03:25:45 +00:00
export const getExtraAttributesForConvertToPath = function ( elem ) {
const attrs = { } ;
2018-05-18 04:02:30 +00:00
// TODO: make this list global so that we can properly maintain it
// TODO: what about @transform, @clip-rule, @fill-rule, etc?
$ . each ( [ 'marker-start' , 'marker-end' , 'marker-mid' , 'filter' , 'clip-path' ] , function ( ) {
2018-05-18 03:25:45 +00:00
const a = elem . getAttribute ( this ) ;
2018-05-18 04:02:30 +00:00
if ( a ) {
attrs [ this ] = a ;
}
} ) ;
return attrs ;
2016-04-22 16:24:52 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Get the BBox of an element - as - path
* @ param elem - The DOM element to be probed
* @ param addSvgElementFromJson - Function to add the path element to the current layer . See canvas . addSvgElementFromJson
* @ param pathActions - If a transform exists , ` pathActions.resetOrientation() ` is used . See : canvas . pathActions .
* @ returns The resulting path ' s bounding box object .
* /
2018-05-18 03:25:45 +00:00
export const getBBoxOfElementAsPath = function ( elem , addSvgElementFromJson , pathActions ) {
const path = addSvgElementFromJson ( {
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
element : 'path' ,
attr : getExtraAttributesForConvertToPath ( elem )
2018-05-18 04:02:30 +00:00
} ) ;
2018-05-18 03:25:45 +00:00
const eltrans = elem . getAttribute ( 'transform' ) ;
2018-05-18 04:02:30 +00:00
if ( eltrans ) {
path . setAttribute ( 'transform' , eltrans ) ;
}
2018-05-18 03:25:45 +00:00
const parent = elem . parentNode ;
2018-05-18 04:02:30 +00:00
if ( elem . nextSibling ) {
parent . insertBefore ( path , elem ) ;
} else {
parent . appendChild ( path ) ;
}
2018-05-18 03:25:45 +00:00
const d = getPathDFromElement ( elem ) ;
2018-05-18 04:02:30 +00:00
if ( d ) path . setAttribute ( 'd' , d ) ;
else path . parentNode . removeChild ( path ) ;
// Get the correct BBox of the new path, then discard it
pathActions . resetOrientation ( path ) ;
2018-05-18 03:25:45 +00:00
let bb = false ;
2018-05-18 04:02:30 +00:00
try {
bb = path . getBBox ( ) ;
} catch ( e ) {
// Firefox fails
}
path . parentNode . removeChild ( path ) ;
return bb ;
2016-04-26 20:01:39 +00:00
} ;
2016-04-22 16:24:52 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Convert selected element to a path .
* @ param elem - The DOM element to be converted
* @ param attrs - Apply attributes to new path . see canvas . convertToPath
* @ param addSvgElementFromJson - Function to add the path element to the current layer . See canvas . addSvgElementFromJson
* @ param pathActions - If a transform exists , pathActions . resetOrientation ( ) is used . See : canvas . pathActions .
* @ param clearSelection - see canvas . clearSelection
* @ param addToSelection - see canvas . addToSelection
* @ param history - see svgedit . history
* @ param addCommandToHistory - see canvas . addCommandToHistory
* @ returns The converted path element or null if the DOM element was not recognized .
* /
2018-05-18 03:25:45 +00:00
export const convertToPath = function ( elem , attrs , addSvgElementFromJson , pathActions , clearSelection , addToSelection , history , addCommandToHistory ) {
const batchCmd = new history . BatchCommand ( 'Convert element to Path' ) ;
2018-05-18 04:02:30 +00:00
// Any attribute on the element not covered by the passed-in attributes
2018-05-18 03:25:45 +00:00
attrs = $ . extend ( { } , attrs , getExtraAttributesForConvertToPath ( elem ) ) ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
const path = addSvgElementFromJson ( {
element : 'path' ,
attr : attrs
2018-05-18 04:02:30 +00:00
} ) ;
2018-05-18 03:25:45 +00:00
const eltrans = elem . getAttribute ( 'transform' ) ;
2018-05-18 04:02:30 +00:00
if ( eltrans ) {
path . setAttribute ( 'transform' , eltrans ) ;
}
2018-05-18 03:25:45 +00:00
const { id } = elem ;
const parent = elem . parentNode ;
2018-05-18 04:02:30 +00:00
if ( elem . nextSibling ) {
parent . insertBefore ( path , elem ) ;
} else {
parent . appendChild ( path ) ;
}
2018-05-18 03:25:45 +00:00
const d = getPathDFromElement ( elem ) ;
2018-05-18 04:02:30 +00:00
if ( d ) {
path . setAttribute ( 'd' , d ) ;
// Replace the current element with the converted one
// Reorient if it has a matrix
if ( eltrans ) {
2018-05-18 03:25:45 +00:00
const tlist = getTransformList ( path ) ;
if ( hasMatrixTransform ( tlist ) ) {
2018-05-18 04:02:30 +00:00
pathActions . resetOrientation ( path ) ;
}
}
2018-05-18 03:25:45 +00:00
const { nextSibling } = elem ;
2018-05-18 04:02:30 +00:00
batchCmd . addSubCommand ( new history . RemoveElementCommand ( elem , nextSibling , parent ) ) ;
batchCmd . addSubCommand ( new history . InsertElementCommand ( path ) ) ;
clearSelection ( ) ;
elem . parentNode . removeChild ( elem ) ;
path . setAttribute ( 'id' , id ) ;
path . removeAttribute ( 'visibility' ) ;
addToSelection ( [ path ] , true ) ;
addCommandToHistory ( batchCmd ) ;
return path ;
} else {
// the elem.tagName was not recognized, so no "d" attribute. Remove it, so we've haven't changed anything.
path . parentNode . removeChild ( path ) ;
return null ;
}
2016-04-22 16:24:52 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Can the bbox be optimized over the native getBBox ? The optimized bbox is the same as the native getBBox when
* the rotation angle is a multiple of 90 degrees and there are no complex transforms .
* Getting an optimized bbox can be dramatically slower , so we want to make sure it ' s worth it .
*
* The best example for this is a circle rotate 45 degrees . The circle doesn ' t get wider or taller when rotated
* about it ' s center .
*
* The standard , unoptimized technique gets the native bbox of the circle , rotates the box 45 degrees , uses
* that width and height , and applies any transforms to get the final bbox . This means the calculated bbox
* is much wider than the original circle . If the angle had been 0 , 90 , 180 , etc . both techniques render the
* same bbox .
*
* The optimization is not needed if the rotation is a multiple 90 degrees . The default technique is to call
* getBBox then apply the angle and any transforms .
*
* @ param angle - The rotation angle in degrees
* @ param { Boolean } hasMatrixTransform - True if there is a matrix transform
* @ returns { Boolean } True if the bbox can be optimized .
* /
2018-05-16 00:53:27 +00:00
function bBoxCanBeOptimizedOverNativeGetBBox ( angle , hasMatrixTransform ) {
2018-05-18 03:25:45 +00:00
const angleModulo90 = angle % 90 ;
const closeTo90 = angleModulo90 < - 89.99 || angleModulo90 > 89.99 ;
const closeTo0 = angleModulo90 > - 0.001 && angleModulo90 < 0.001 ;
2018-05-18 04:02:30 +00:00
return hasMatrixTransform || ! ( closeTo0 || closeTo90 ) ;
2016-04-28 16:11:54 +00:00
}
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
/ * *
* Get bounding box that includes any transforms .
* @ param elem - The DOM element to be converted
* @ param addSvgElementFromJson - Function to add the path element to the current layer . See canvas . addSvgElementFromJson
* @ param pathActions - If a transform exists , pathActions . resetOrientation ( ) is used . See : canvas . pathActions .
* @ returns A single bounding box object
* /
2018-05-18 03:25:45 +00:00
export const getBBoxWithTransform = function ( elem , addSvgElementFromJson , pathActions ) {
2018-05-18 04:02:30 +00:00
// TODO: Fix issue with rotated groups. Currently they work
// fine in FF, but not in other browsers (same problem mentioned
// in Issue 339 comment #2).
2018-05-18 03:25:45 +00:00
let bb = getBBox ( elem ) ;
2018-05-18 04:02:30 +00:00
if ( ! bb ) {
return null ;
}
2018-05-18 03:25:45 +00:00
const tlist = getTransformList ( elem ) ;
const angle = getRotationAngleFromTransformList ( tlist ) ;
const hasMatrixXForm = hasMatrixTransform ( tlist ) ;
2018-05-18 04:02:30 +00:00
2018-05-18 03:25:45 +00:00
if ( angle || hasMatrixXForm ) {
let goodBb = false ;
if ( bBoxCanBeOptimizedOverNativeGetBBox ( angle , hasMatrixXForm ) ) {
2018-05-18 04:02:30 +00:00
// Get the BBox from the raw path for these elements
// TODO: why ellipse and not circle
2018-05-18 03:25:45 +00:00
const elemNames = [ 'ellipse' , 'path' , 'line' , 'polyline' , 'polygon' ] ;
if ( elemNames . includes ( elem . tagName ) ) {
bb = goodBb = getBBoxOfElementAsPath ( elem , addSvgElementFromJson , pathActions ) ;
2018-05-18 04:02:30 +00:00
} else if ( elem . tagName === 'rect' ) {
// Look for radius
2018-05-18 03:25:45 +00:00
const rx = elem . getAttribute ( 'rx' ) ;
const ry = elem . getAttribute ( 'ry' ) ;
2018-05-18 04:02:30 +00:00
if ( rx || ry ) {
2018-05-18 03:25:45 +00:00
bb = goodBb = getBBoxOfElementAsPath ( elem , addSvgElementFromJson , pathActions ) ;
2018-05-18 04:02:30 +00:00
}
}
}
if ( ! goodBb ) {
2018-05-18 03:25:45 +00:00
const { matrix } = transformListToTransform ( tlist ) ;
bb = transformBox ( bb . x , bb . y , bb . width , bb . height , matrix ) . aabox ;
2018-05-18 04:02:30 +00:00
// Old technique that was exceedingly slow with large documents.
//
// Accurate way to get BBox of rotated element in Firefox:
// Put element in group and get its BBox
//
// Must use clone else FF freaks out
2018-05-18 03:25:45 +00:00
// const clone = elem.cloneNode(true);
// const g = document.createElementNS(NS.SVG, 'g');
// const parent = elem.parentNode;
2018-05-18 04:02:30 +00:00
// parent.appendChild(g);
// g.appendChild(clone);
2018-05-18 03:25:45 +00:00
// const bb2 = bboxToObj(g.getBBox());
2018-05-18 04:02:30 +00:00
// parent.removeChild(g);
}
}
return bb ;
2016-04-24 20:43:20 +00:00
} ;
// TODO: This is problematic with large stroke-width and, for example, a single horizontal line. The calculated BBox extends way beyond left and right sides.
2018-05-16 00:53:27 +00:00
function getStrokeOffsetForBBox ( elem ) {
2018-05-18 03:25:45 +00:00
const sw = elem . getAttribute ( 'stroke-width' ) ;
2018-05-18 04:02:30 +00:00
return ( ! isNaN ( sw ) && elem . getAttribute ( 'stroke' ) !== 'none' ) ? sw / 2 : 0 ;
2018-05-17 18:57:28 +00:00
}
2016-04-24 20:43:20 +00:00
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
/ * *
* Get the bounding box for one or more stroked and / or transformed elements
* @ param elems - Array with DOM elements to check
* @ param addSvgElementFromJson - Function to add the path element to the current layer . See canvas . addSvgElementFromJson
* @ param pathActions - If a transform exists , pathActions . resetOrientation ( ) is used . See : canvas . pathActions .
* @ returns A single bounding box object
* /
2018-05-18 03:25:45 +00:00
export const getStrokedBBox = function ( elems , addSvgElementFromJson , pathActions ) {
2018-05-18 04:02:30 +00:00
if ( ! elems || ! elems . length ) { return false ; }
2018-05-18 03:25:45 +00:00
let fullBb ;
2018-05-18 04:02:30 +00:00
$ . each ( elems , function ( ) {
if ( fullBb ) { return ; }
if ( ! this . parentNode ) { return ; }
2018-05-18 03:25:45 +00:00
fullBb = getBBoxWithTransform ( this , addSvgElementFromJson , pathActions ) ;
2018-05-18 04:02:30 +00:00
} ) ;
// This shouldn't ever happen...
if ( fullBb === undefined ) { return null ; }
// fullBb doesn't include the stoke, so this does no good!
// if (elems.length == 1) return fullBb;
2018-05-18 03:25:45 +00:00
let maxX = fullBb . x + fullBb . width ;
let maxY = fullBb . y + fullBb . height ;
let minX = fullBb . x ;
let minY = fullBb . y ;
2018-05-18 04:02:30 +00:00
// If only one elem, don't call the potentially slow getBBoxWithTransform method again.
if ( elems . length === 1 ) {
2018-05-18 03:25:45 +00:00
const offset = getStrokeOffsetForBBox ( elems [ 0 ] ) ;
2018-05-18 04:02:30 +00:00
minX -= offset ;
minY -= offset ;
maxX += offset ;
maxY += offset ;
} else {
$ . each ( elems , function ( i , elem ) {
2018-05-18 03:25:45 +00:00
const curBb = getBBoxWithTransform ( elem , addSvgElementFromJson , pathActions ) ;
2018-05-18 04:02:30 +00:00
if ( curBb ) {
2018-05-18 03:25:45 +00:00
const offset = getStrokeOffsetForBBox ( elem ) ;
2018-05-18 04:02:30 +00:00
minX = Math . min ( minX , curBb . x - offset ) ;
minY = Math . min ( minY , curBb . y - offset ) ;
// TODO: The old code had this test for max, but not min. I suspect this test should be for both min and max
if ( elem . nodeType === 1 ) {
maxX = Math . max ( maxX , curBb . x + curBb . width + offset ) ;
maxY = Math . max ( maxY , curBb . y + curBb . height + offset ) ;
}
}
} ) ;
}
fullBb . x = minX ;
fullBb . y = minY ;
fullBb . width = maxX - minX ;
fullBb . height = maxY - minY ;
return fullBb ;
2016-04-24 20:43:20 +00:00
} ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
/ * *
2018-05-29 12:31:24 +00:00
* Get all elements that have a BBox ( excludes ` <defs> ` , ` <title> ` , etc ) .
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
* Note that 0 - opacity , off - screen etc elements are still considered "visible"
* for this function
* @ param parent - The parent DOM element to search within
* @ returns { Array } All "visible" elements .
* /
export const getVisibleElements = function ( parent ) {
if ( ! parent ) {
parent = $ ( editorContext _ . getSVGContent ( ) ) . children ( ) ; // Prevent layers from being included
}
const contentElems = [ ] ;
$ ( parent ) . children ( ) . each ( function ( i , elem ) {
if ( elem . getBBox ) {
contentElems . push ( elem ) ;
}
} ) ;
return contentElems . reverse ( ) ;
} ;
/ * *
* Get the bounding box for one or more stroked and / or transformed elements
* @ param elems - Array with DOM elements to check
* @ returns A single bounding box object
* /
export const getStrokedBBoxDefaultVisible = function ( elems ) {
if ( ! elems ) { elems = getVisibleElements ( ) ; }
return getStrokedBBox (
elems ,
editorContext _ . addSvgElementFromJson ,
editorContext _ . pathActions
) ;
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Get the rotation angle of the given transform list .
* @ param tlist - List of transforms
* @ param { Boolean } toRad - When true returns the value in radians rather than degrees
* @ returns { Number } Float with the angle in degrees or radians
* /
2018-05-18 03:25:45 +00:00
export const getRotationAngleFromTransformList = function ( tlist , toRad ) {
2018-05-18 04:02:30 +00:00
if ( ! tlist ) { return 0 ; } // <svg> elements have no tlist
2018-05-18 03:25:45 +00:00
const N = tlist . numberOfItems ;
for ( let i = 0 ; i < N ; ++ i ) {
const xform = tlist . getItem ( i ) ;
2018-05-18 04:02:30 +00:00
if ( xform . type === 4 ) {
return toRad ? xform . angle * Math . PI / 180.0 : xform . angle ;
}
}
return 0.0 ;
2010-11-05 15:59:30 +00:00
} ;
2010-11-05 15:29:30 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Get the rotation angle of the given / selected DOM element
* @ param elem - Optional DOM element to get the angle for
* @ param { Boolean } toRad - When true returns the value in radians rather than degrees
* @ returns { Number } Float with the angle in degrees or radians
* /
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
export let getRotationAngle = function ( elem , toRad ) {
2018-05-18 03:25:45 +00:00
const selected = elem || editorContext _ . getSelectedElements ( ) [ 0 ] ;
2018-05-18 04:02:30 +00:00
// find the rotation transform (if any) and set it
2018-05-18 03:25:45 +00:00
const tlist = getTransformList ( selected ) ;
return getRotationAngleFromTransformList ( tlist , toRad ) ;
2016-04-24 20:43:20 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Get the reference element associated with the given attribute value
* @ param { String } attrVal - The attribute value as a string
* @ returns Reference element
* /
2018-05-18 03:25:45 +00:00
export const getRefElem = function ( attrVal ) {
return getElem ( getUrlFromAttr ( attrVal ) . substr ( 1 ) ) ;
2013-02-14 15:19:46 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Get a DOM element by ID within the SVG root element .
* @ param { String } id - String with the element ' s new ID
* /
2018-05-18 03:25:45 +00:00
export const getElem = ( supportsSelectors ( ) )
? function ( id ) {
2018-05-18 04:02:30 +00:00
// querySelector lookup
return svgroot _ . querySelector ( '#' + id ) ;
2018-05-18 03:25:45 +00:00
} : supportsXpath ( )
? function ( id ) {
// xpath lookup
return domdoc _ . evaluate (
'svg:svg[@id="svgroot"]//svg:*[@id="' + id + '"]' ,
domcontainer _ ,
function ( ) { return NS . SVG ; } ,
9 ,
null ) . singleNodeValue ;
}
: function ( id ) {
// jQuery lookup: twice as slow as xpath in FF
return $ ( svgroot _ ) . find ( '[id=' + id + ']' ) [ 0 ] ;
} ;
2011-02-04 08:02:46 +00:00
2018-05-29 12:31:24 +00:00
/ * *
* Assigns multiple attributes to an element .
* @ param node - DOM element to apply new attribute values to
* @ param { Object } attrs - Object with attribute keys / values
* @ param { Number } suspendLength - Optional integer of milliseconds to suspend redraw
* @ param { Boolean } unitCheck - Boolean to indicate the need to use svgedit . units . setUnitAttr
* /
2018-05-18 03:25:45 +00:00
export const assignAttributes = function ( node , attrs , suspendLength , unitCheck ) {
for ( const i in attrs ) {
const ns = ( i . substr ( 0 , 4 ) === 'xml:'
2018-05-18 04:02:30 +00:00
? NS . XML
: i . substr ( 0 , 6 ) === 'xlink:' ? NS . XLINK : null ) ;
if ( ns ) {
node . setAttributeNS ( ns , i , attrs [ i ] ) ;
} else if ( ! unitCheck ) {
node . setAttribute ( i , attrs [ i ] ) ;
} else {
2018-05-18 03:25:45 +00:00
setUnitAttr ( node , i , attrs [ i ] ) ;
2018-05-18 04:02:30 +00:00
}
}
2011-02-04 08:02:46 +00:00
} ;
2018-05-29 12:31:24 +00:00
/ * *
* Remove unneeded ( default ) attributes , makes resulting SVG smaller
* @ param element - DOM element to clean up
* /
2018-05-18 03:25:45 +00:00
export const cleanupElement = function ( element ) {
const defaults = {
2018-05-18 04:02:30 +00:00
'fill-opacity' : 1 ,
'stop-opacity' : 1 ,
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
opacity : 1 ,
stroke : 'none' ,
2018-05-18 04:02:30 +00:00
'stroke-dasharray' : 'none' ,
'stroke-linejoin' : 'miter' ,
'stroke-linecap' : 'butt' ,
'stroke-opacity' : 1 ,
'stroke-width' : 1 ,
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
rx : 0 ,
ry : 0
2018-05-18 04:02:30 +00:00
} ;
if ( element . nodeName === 'ellipse' ) {
// Ellipse elements requires rx and ry attributes
delete defaults . rx ;
delete defaults . ry ;
}
2018-05-18 03:25:45 +00:00
for ( const attr in defaults ) {
const val = defaults [ attr ] ;
2018-05-18 04:02:30 +00:00
if ( element . getAttribute ( attr ) === String ( val ) ) {
element . removeAttribute ( attr ) ;
}
}
2011-02-10 04:10:03 +00:00
} ;
2013-02-17 04:58:04 +00:00
// round value to for snapping
2018-05-18 03:25:45 +00:00
export const snapToGrid = function ( value ) {
const unit = editorContext _ . getBaseUnit ( ) ;
let stepSize = editorContext _ . getSnappingStep ( ) ;
2018-05-18 04:02:30 +00:00
if ( unit !== 'px' ) {
2018-05-18 03:25:45 +00:00
stepSize *= getTypeMap ( ) [ unit ] ;
2018-05-18 04:02:30 +00:00
}
value = Math . round ( value / stepSize ) * stepSize ;
return value ;
2013-02-17 04:58:04 +00:00
} ;
2018-05-18 03:25:45 +00:00
export const regexEscape = function ( str , delimiter ) {
2018-05-18 04:02:30 +00:00
// From: http://phpjs.org/functions
return String ( str ) . replace ( new RegExp ( '[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + ( delimiter || '' ) + '-]' , 'g' ) , '\\$&' ) ;
2014-02-19 01:37:21 +00:00
} ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
const loadedScripts = { } ;
2014-05-22 10:21:29 +00:00
/ * *
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
* @ param { string } name A global which can be used to determine if the script is already loaded
2014-05-22 10:21:29 +00:00
* @ param { array } scripts An array of scripts to preload ( in order )
* @ param { function } cb The callback to execute upon load .
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
* @ param { object } options Object with ` globals ` boolean property ( if it is not a module )
2014-05-22 10:21:29 +00:00
* /
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
export const executeAfterLoads = function ( name , scripts , cb , options = { globals : false } ) {
2018-05-18 04:02:30 +00:00
return function ( ) {
2018-05-18 03:25:45 +00:00
const args = arguments ;
2018-05-18 04:02:30 +00:00
function endCallback ( ) {
cb . apply ( null , args ) ;
}
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
const modularVersion = ! ( 'svgEditor' in window ) ||
! window . svgEditor ||
window . svgEditor . modules !== false ;
if ( loadedScripts [ name ] === true ) {
2018-05-18 04:02:30 +00:00
endCallback ( ) ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
} else if ( Array . isArray ( loadedScripts [ name ] ) ) { // Still loading
loadedScripts [ name ] . push ( endCallback ) ;
2018-05-18 04:02:30 +00:00
} else {
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
loadedScripts [ name ] = [ ] ;
const importer = modularVersion && ! options . globals
? importModule
: importScript ;
scripts . reduce ( function ( oldProm , script ) {
// Todo: Once `import()` and modules widely supported, switch to it
return oldProm . then ( ( ) => importer ( script ) ) ;
} , Promise . resolve ( ) ) . then ( function ( ) {
endCallback ( ) ;
loadedScripts [ name ] . forEach ( ( cb ) => {
cb ( ) ;
} ) ;
2018-05-25 14:43:01 +00:00
loadedScripts [ name ] = true ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
} ) ( ) ;
2018-05-18 04:02:30 +00:00
}
} ;
2014-05-22 10:21:29 +00:00
} ;
2018-05-18 03:25:45 +00:00
export const buildCanvgCallback = function ( callCanvg ) {
return executeAfterLoads ( 'canvg' , [ 'canvg/rgbcolor.js' , 'canvg/canvg.js' ] , callCanvg ) ;
2014-05-22 10:21:29 +00:00
} ;
2018-05-18 03:25:45 +00:00
export const buildJSPDFCallback = function ( callJSPDF ) {
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
return executeAfterLoads ( 'RGBColor' , [ 'canvg/rgbcolor.js' ] , ( ) => {
2018-05-18 03:25:45 +00:00
const arr = [ ] ;
if ( ! RGBColor || RGBColor . ok === undefined ) { // It's not our RGBColor, so we'll need to load it
2018-05-18 04:02:30 +00:00
arr . push ( 'canvg/rgbcolor.js' ) ;
}
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
executeAfterLoads ( 'jsPDF' , [
... arr ,
'jspdf/underscore-min.js' ,
'jspdf/jspdf.min.js' ,
'jspdf/jspdf.plugin.svgToPdf.js'
] , callJSPDF , { globals : true } ) ( ) ;
2018-05-18 04:02:30 +00:00
} ) ;
2014-05-22 10:21:29 +00:00
} ;
2016-05-04 13:38:29 +00:00
/ * *
* Prevents default browser click behaviour on the given element
* @ param img - The DOM element to prevent the click on
* /
2018-05-18 03:25:45 +00:00
export const preventClickDefault = function ( img ) {
2018-05-18 04:02:30 +00:00
$ ( img ) . click ( function ( e ) { e . preventDefault ( ) ; } ) ;
2016-05-04 13:38:29 +00:00
} ;
/ * *
* Create a clone of an element , updating its ID and its children ' s IDs when needed
* @ param { Element } el - DOM element to clone
2018-06-01 07:59:17 +00:00
* @ param { Function } getNextId - The getter of the next unique ID .
2016-05-04 13:38:29 +00:00
* @ returns { Element }
* /
2018-05-18 03:25:45 +00:00
export const copyElem = function ( el , getNextId ) {
2018-05-18 04:02:30 +00:00
// manually create a copy of the element
2018-05-18 03:25:45 +00:00
const newEl = document . createElementNS ( el . namespaceURI , el . nodeName ) ;
2018-05-18 04:02:30 +00:00
$ . each ( el . attributes , function ( i , attr ) {
if ( attr . localName !== '-moz-math-font-style' ) {
newEl . setAttributeNS ( attr . namespaceURI , attr . nodeName , attr . value ) ;
}
} ) ;
// set the copied element's new id
newEl . removeAttribute ( 'id' ) ;
newEl . id = getNextId ( ) ;
// Opera's "d" value needs to be reset for Opera/Win/non-EN
// Also needed for webkit (else does not keep curved segments on clone)
2018-05-18 03:25:45 +00:00
if ( isWebkit ( ) && el . nodeName === 'path' ) {
const fixedD = convertPath ( el ) ;
2018-05-18 04:02:30 +00:00
newEl . setAttribute ( 'd' , fixedD ) ;
}
// now create copies of all children
$ . each ( el . childNodes , function ( i , child ) {
switch ( child . nodeType ) {
case 1 : // element node
2018-05-18 03:25:45 +00:00
newEl . appendChild ( copyElem ( child , getNextId ) ) ;
2018-05-18 04:02:30 +00:00
break ;
case 3 : // text node
newEl . textContent = child . nodeValue ;
break ;
default :
break ;
}
} ) ;
if ( $ ( el ) . data ( 'gsvg' ) ) {
$ ( newEl ) . data ( 'gsvg' , newEl . firstChild ) ;
} else if ( $ ( el ) . data ( 'symbol' ) ) {
2018-05-18 03:25:45 +00:00
const ref = $ ( el ) . data ( 'symbol' ) ;
2018-05-18 04:02:30 +00:00
$ ( newEl ) . data ( 'ref' , ref ) . data ( 'symbol' , ref ) ;
} else if ( newEl . tagName === 'image' ) {
2018-05-18 03:25:45 +00:00
preventClickDefault ( newEl ) ;
2018-05-18 04:02:30 +00:00
}
return newEl ;
2016-05-04 13:38:29 +00:00
} ;
- Breaking change: Rename config file to `svgedit-config-iife.js` (or for the module version, `svgedit-config-es.js`);
also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
make Node build routine for converting modular source to non-modular,
use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
2018-05-22 10:03:16 +00:00
// Unit testing
export const mock = ( {
getHref : getHrefUser , setHref : setHrefUser , getRotationAngle : getRotationAngleUser
} ) => {
getHref = getHrefUser ;
setHref = setHrefUser ;
getRotationAngle = getRotationAngleUser ;
2016-05-04 13:38:29 +00:00
} ;