diff options
author | Saivan <savian@me.com> | 2018-11-25 16:21:53 +1300 |
---|---|---|
committer | Saivan <savian@me.com> | 2018-11-25 16:21:53 +1300 |
commit | 62de7d0a1b994b69032a759b796b486e6bc382e3 (patch) | |
tree | 112b19f2903b4dc5b4cf61ebef0d021c6ca2f14d /src/modules | |
parent | 2b37d7ba5b4267b39c86f9aba5fb14a1b376e846 (diff) | |
download | svg.js-62de7d0a1b994b69032a759b796b486e6bc382e3.tar.gz svg.js-62de7d0a1b994b69032a759b796b486e6bc382e3.zip |
Changed the esLint rules to avoid silly ternary operators, and to let code breathe!
This commit modifies some of the eslint rules, to allow our code to be a little bit more
readable. This came about because we had a particularly pesky problem, where the code
was indenting ternary operators. This fixes that, and makes it easy to add new rules
to eslint as we please in the future.
Changes
=======
- Rebuilt the library with new eslint rules
- Changed the eslintrc file to a yaml file by default
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/core/attr.js | 104 | ||||
-rw-r--r-- | src/modules/core/circled.js | 52 | ||||
-rw-r--r-- | src/modules/core/event.js | 160 | ||||
-rw-r--r-- | src/modules/core/gradiented.js | 20 | ||||
-rw-r--r-- | src/modules/core/parser.js | 16 | ||||
-rw-r--r-- | src/modules/core/pointed.js | 24 | ||||
-rw-r--r-- | src/modules/core/poly.js | 30 | ||||
-rw-r--r-- | src/modules/core/selector.js | 18 | ||||
-rw-r--r-- | src/modules/core/textable.js | 12 | ||||
-rw-r--r-- | src/modules/optional/arrange.js | 82 | ||||
-rw-r--r-- | src/modules/optional/class.js | 48 | ||||
-rw-r--r-- | src/modules/optional/css.js | 80 | ||||
-rw-r--r-- | src/modules/optional/data.js | 38 | ||||
-rw-r--r-- | src/modules/optional/memory.js | 38 | ||||
-rw-r--r-- | src/modules/optional/sugar.js | 240 | ||||
-rw-r--r-- | src/modules/optional/transform.js | 78 |
16 files changed, 697 insertions, 343 deletions
diff --git a/src/modules/core/attr.js b/src/modules/core/attr.js index f90dcb9..7cb9e2a 100644 --- a/src/modules/core/attr.js +++ b/src/modules/core/attr.js @@ -5,77 +5,113 @@ import SVGArray from '../../types/SVGArray.js' import SVGNumber from '../../types/SVGNumber.js' const hooks = [] -export function registerAttrHook (fn) { - hooks.push(fn) +export function registerAttrHook ( fn ) { + + hooks.push( fn ) + } // Set svg element attribute -export default function attr (attr, val, ns) { +export default function attr ( attr, val, ns ) { + // act as full getter - if (attr == null) { + if ( attr == null ) { + // get an object of attributes attr = {} val = this.node.attributes - for (let node of val) { - attr[node.nodeName] = isNumber.test(node.nodeValue) - ? parseFloat(node.nodeValue) + for ( let node of val ) { + + attr[node.nodeName] = isNumber.test( node.nodeValue ) + ? parseFloat( node.nodeValue ) : node.nodeValue + } return attr - } else if (attr instanceof Array) { + + } else if ( attr instanceof Array ) { + // loop through array and get all values - return attr.reduce((last, curr) => { - last[curr] = this.attr(curr) + return attr.reduce( ( last, curr ) => { + + last[curr] = this.attr( curr ) return last - }, {}) - } else if (typeof attr === 'object') { + + }, {} ) + + } else if ( typeof attr === 'object' ) { + // apply every attribute individually if an object is passed - for (val in attr) this.attr(val, attr[val]) - } else if (val === null) { + for ( val in attr ) this.attr( val, attr[val] ) + + } else if ( val === null ) { + // remove value - this.node.removeAttribute(attr) - } else if (val == null) { + this.node.removeAttribute( attr ) + + } else if ( val == null ) { + // act as a getter if the first and only argument is not an object - val = this.node.getAttribute(attr) + val = this.node.getAttribute( attr ) return val == null ? defaults[attr] - : isNumber.test(val) ? parseFloat(val) - : val + : isNumber.test( val ) ? parseFloat( val ) + : val + } else { + // Loop through hooks and execute them to convert value - val = hooks.reduce((_val, hook) => { - return hook(attr, _val, this) - }, val) + val = hooks.reduce( ( _val, hook ) => { + + return hook( attr, _val, this ) + + }, val ) // ensure correct numeric values (also accepts NaN and Infinity) - if (typeof val === 'number') { - val = new SVGNumber(val) - } else if (Color.isColor(val)) { + if ( typeof val === 'number' ) { + + val = new SVGNumber( val ) + + } else if ( Color.isColor( val ) ) { + // ensure full hex color - val = new Color(val) - } else if (val.constructor === Array) { + val = new Color( val ) + + } else if ( val.constructor === Array ) { + // Check for plain arrays and parse array values - val = new SVGArray(val) + val = new SVGArray( val ) + } // if the passed attribute is leading... - if (attr === 'leading') { + if ( attr === 'leading' ) { + // ... call the leading method instead - if (this.leading) { - this.leading(val) + if ( this.leading ) { + + this.leading( val ) + } + } else { + // set given attribute on node - typeof ns === 'string' ? this.node.setAttributeNS(ns, attr, val.toString()) - : this.node.setAttribute(attr, val.toString()) + typeof ns === 'string' ? this.node.setAttributeNS( ns, attr, val.toString() ) + : this.node.setAttribute( attr, val.toString() ) + } // rebuild if required - if (this.rebuild && (attr === 'font-size' || attr === 'x')) { + if ( this.rebuild && ( attr === 'font-size' || attr === 'x' ) ) { + this.rebuild() + } + } return this + } diff --git a/src/modules/core/circled.js b/src/modules/core/circled.js index 597d252..ad901b9 100644 --- a/src/modules/core/circled.js +++ b/src/modules/core/circled.js @@ -1,53 +1,69 @@ import SVGNumber from '../../types/SVGNumber.js' // Radius x value -export function rx (rx) { - return this.attr('rx', rx) +export function rx ( rx ) { + + return this.attr( 'rx', rx ) + } // Radius y value -export function ry (ry) { - return this.attr('ry', ry) +export function ry ( ry ) { + + return this.attr( 'ry', ry ) + } // Move over x-axis -export function x (x) { +export function x ( x ) { + return x == null ? this.cx() - this.rx() - : this.cx(x + this.rx()) + : this.cx( x + this.rx() ) + } // Move over y-axis -export function y (y) { +export function y ( y ) { + return y == null ? this.cy() - this.ry() - : this.cy(y + this.ry()) + : this.cy( y + this.ry() ) + } // Move by center over x-axis -export function cx (x) { +export function cx ( x ) { + return x == null - ? this.attr('cx') - : this.attr('cx', x) + ? this.attr( 'cx' ) + : this.attr( 'cx', x ) + } // Move by center over y-axis -export function cy (y) { +export function cy ( y ) { + return y == null - ? this.attr('cy') - : this.attr('cy', y) + ? this.attr( 'cy' ) + : this.attr( 'cy', y ) + } // Set width of element -export function width (width) { +export function width ( width ) { + return width == null ? this.rx() * 2 - : this.rx(new SVGNumber(width).divide(2)) + : this.rx( new SVGNumber( width ).divide( 2 ) ) + } // Set height of element -export function height (height) { +export function height ( height ) { + return height == null ? this.ry() * 2 - : this.ry(new SVGNumber(height).divide(2)) + : this.ry( new SVGNumber( height ).divide( 2 ) ) + } diff --git a/src/modules/core/event.js b/src/modules/core/event.js index a52a744..23459fb 100644 --- a/src/modules/core/event.js +++ b/src/modules/core/event.js @@ -4,38 +4,48 @@ import { globals } from '../../utils/window.js' let listenerId = 0 -function getEvents (node) { - const n = makeInstance(node).getEventHolder() - if (!n.events) n.events = {} +function getEvents ( node ) { + + const n = makeInstance( node ).getEventHolder() + if ( !n.events ) n.events = {} return n.events + } -function getEventTarget (node) { - return makeInstance(node).getEventTarget() +function getEventTarget ( node ) { + + return makeInstance( node ).getEventTarget() + } -function clearEvents (node) { - const n = makeInstance(node).getEventHolder() - if (n.events) n.events = {} +function clearEvents ( node ) { + + const n = makeInstance( node ).getEventHolder() + if ( n.events ) n.events = {} + } // Add event binder in the SVG namespace -export function on (node, events, listener, binding, options) { - var l = listener.bind(binding || node) - var bag = getEvents(node) - var n = getEventTarget(node) +export function on ( node, events, listener, binding, options ) { + + var l = listener.bind( binding || node ) + var bag = getEvents( node ) + var n = getEventTarget( node ) // events can be an array of events or a string of events - events = Array.isArray(events) ? events : events.split(delimiter) + events = Array.isArray( events ) ? events : events.split( delimiter ) // add id to listener - if (!listener._svgjsListenerId) { + if ( !listener._svgjsListenerId ) { + listener._svgjsListenerId = ++listenerId + } - events.forEach(function (event) { - var ev = event.split('.')[0] - var ns = event.split('.')[1] || '*' + events.forEach( function ( event ) { + + var ev = event.split( '.' )[0] + var ns = event.split( '.' )[1] || '*' // ensure valid object bag[ev] = bag[ev] || {} @@ -45,76 +55,126 @@ export function on (node, events, listener, binding, options) { bag[ev][ns][listener._svgjsListenerId] = l // add listener - n.addEventListener(ev, l, options || false) - }) + n.addEventListener( ev, l, options || false ) + + } ) + } // Add event unbinder in the SVG namespace -export function off (node, events, listener, options) { - var bag = getEvents(node) - var n = getEventTarget(node) +export function off ( node, events, listener, options ) { + + var bag = getEvents( node ) + var n = getEventTarget( node ) // listener can be a function or a number - if (typeof listener === 'function') { + if ( typeof listener === 'function' ) { + listener = listener._svgjsListenerId - if (!listener) return + if ( !listener ) return + } // events can be an array of events or a string or undefined - events = Array.isArray(events) ? events : (events || '').split(delimiter) + events = Array.isArray( events ) ? events : ( events || '' ).split( delimiter ) + + events.forEach( function ( event ) { - events.forEach(function (event) { - var ev = event && event.split('.')[0] - var ns = event && event.split('.')[1] + var ev = event && event.split( '.' )[0] + var ns = event && event.split( '.' )[1] var namespace, l - if (listener) { + if ( listener ) { + // remove listener reference - if (bag[ev] && bag[ev][ns || '*']) { + if ( bag[ev] && bag[ev][ns || '*'] ) { + // removeListener - n.removeEventListener(ev, bag[ev][ns || '*'][listener], options || false) + n.removeEventListener( ev, bag[ev][ns || '*'][listener], options || false ) delete bag[ev][ns || '*'][listener] + } - } else if (ev && ns) { + + } else if ( ev && ns ) { + // remove all listeners for a namespaced event - if (bag[ev] && bag[ev][ns]) { - for (l in bag[ev][ns]) { off(n, [ev, ns].join('.'), l) } + if ( bag[ev] && bag[ev][ns] ) { + + for ( l in bag[ev][ns] ) { + + off( n, [ ev, ns ].join( '.' ), l ) + + } delete bag[ev][ns] + } - } else if (ns) { + + } else if ( ns ) { + // remove all listeners for a specific namespace - for (event in bag) { - for (namespace in bag[event]) { - if (ns === namespace) { off(n, [event, ns].join('.')) } + for ( event in bag ) { + + for ( namespace in bag[event] ) { + + if ( ns === namespace ) { + + off( n, [ event, ns ].join( '.' ) ) + + } + } + } - } else if (ev) { + + } else if ( ev ) { + // remove all listeners for the event - if (bag[ev]) { - for (namespace in bag[ev]) { off(n, [ev, namespace].join('.')) } + if ( bag[ev] ) { + + for ( namespace in bag[ev] ) { + + off( n, [ ev, namespace ].join( '.' ) ) + + } delete bag[ev] + } + } else { + // remove all listeners on a given node - for (event in bag) { off(n, event) } + for ( event in bag ) { + + off( n, event ) + + } + + clearEvents( node ) - clearEvents(node) } - }) + + } ) + } -export function dispatch (node, event, data) { - var n = getEventTarget(node) +export function dispatch ( node, event, data ) { + + var n = getEventTarget( node ) // Dispatch event - if (event instanceof globals.window.Event) { - n.dispatchEvent(event) + if ( event instanceof globals.window.Event ) { + + n.dispatchEvent( event ) + } else { - event = new globals.window.CustomEvent(event, { detail: data, cancelable: true }) - n.dispatchEvent(event) + + event = new globals.window.CustomEvent( event, { detail: data, cancelable: true } ) + n.dispatchEvent( event ) + } return event + } diff --git a/src/modules/core/gradiented.js b/src/modules/core/gradiented.js index 6c744e4..dd9c46f 100644 --- a/src/modules/core/gradiented.js +++ b/src/modules/core/gradiented.js @@ -1,13 +1,17 @@ import SVGNumber from '../../types/SVGNumber.js' -export function from (x, y) { - return (this._element || this).type === 'radialGradient' - ? this.attr({ fx: new SVGNumber(x), fy: new SVGNumber(y) }) - : this.attr({ x1: new SVGNumber(x), y1: new SVGNumber(y) }) +export function from ( x, y ) { + + return ( this._element || this ).type === 'radialGradient' + ? this.attr( { fx: new SVGNumber( x ), fy: new SVGNumber( y ) } ) + : this.attr( { x1: new SVGNumber( x ), y1: new SVGNumber( y ) } ) + } -export function to (x, y) { - return (this._element || this).type === 'radialGradient' - ? this.attr({ cx: new SVGNumber(x), cy: new SVGNumber(y) }) - : this.attr({ x2: new SVGNumber(x), y2: new SVGNumber(y) }) +export function to ( x, y ) { + + return ( this._element || this ).type === 'radialGradient' + ? this.attr( { cx: new SVGNumber( x ), cy: new SVGNumber( y ) } ) + : this.attr( { x2: new SVGNumber( x ), y2: new SVGNumber( y ) } ) + } diff --git a/src/modules/core/parser.js b/src/modules/core/parser.js index 1ff2380..12c9728 100644 --- a/src/modules/core/parser.js +++ b/src/modules/core/parser.js @@ -2,26 +2,32 @@ import { globals } from '../../utils/window.js' import { makeInstance } from '../../utils/adopter.js' export default function parser () { + // Reuse cached element if possible - if (!parser.nodes) { - let svg = makeInstance().size(2, 0) + if ( !parser.nodes ) { + + let svg = makeInstance().size( 2, 0 ) svg.node.cssText = [ 'opacity: 0', 'position: absolute', 'left: -100%', 'top: -100%', 'overflow: hidden' - ].join(';') + ].join( ';' ) let path = svg.path().node parser.nodes = { svg, path } + } - if (!parser.nodes.svg.node.parentNode) { + if ( !parser.nodes.svg.node.parentNode ) { + let b = globals.document.body || globals.document.documentElement - parser.nodes.svg.addTo(b) + parser.nodes.svg.addTo( b ) + } return parser.nodes + } diff --git a/src/modules/core/pointed.js b/src/modules/core/pointed.js index 95e6819..813b0e3 100644 --- a/src/modules/core/pointed.js +++ b/src/modules/core/pointed.js @@ -3,23 +3,31 @@ import PointArray from '../../types/PointArray.js' export let MorphArray = PointArray // Move by left top corner over x-axis -export function x (x) { - return x == null ? this.bbox().x : this.move(x, this.bbox().y) +export function x ( x ) { + + return x == null ? this.bbox().x : this.move( x, this.bbox().y ) + } // Move by left top corner over y-axis -export function y (y) { - return y == null ? this.bbox().y : this.move(this.bbox().x, y) +export function y ( y ) { + + return y == null ? this.bbox().y : this.move( this.bbox().x, y ) + } // Set width of element -export function width (width) { +export function width ( width ) { + let b = this.bbox() - return width == null ? b.width : this.size(width, b.height) + return width == null ? b.width : this.size( width, b.height ) + } // Set height of element -export function height (height) { +export function height ( height ) { + let b = this.bbox() - return height == null ? b.height : this.size(b.width, height) + return height == null ? b.height : this.size( b.width, height ) + } diff --git a/src/modules/core/poly.js b/src/modules/core/poly.js index ad12020..56703a5 100644 --- a/src/modules/core/poly.js +++ b/src/modules/core/poly.js @@ -3,29 +3,39 @@ import PointArray from '../../types/PointArray.js' // Get array export function array () { - return this._array || (this._array = new PointArray(this.attr('points'))) + + return this._array || ( this._array = new PointArray( this.attr( 'points' ) ) ) + } // Plot new path -export function plot (p) { - return (p == null) ? this.array() - : this.clear().attr('points', typeof p === 'string' ? p - : (this._array = new PointArray(p))) +export function plot ( p ) { + + return ( p == null ) ? this.array() + : this.clear().attr( 'points', typeof p === 'string' ? p + : ( this._array = new PointArray( p ) ) ) + } // Clear array cache export function clear () { + delete this._array return this + } // Move by left top corner -export function move (x, y) { - return this.attr('points', this.array().move(x, y)) +export function move ( x, y ) { + + return this.attr( 'points', this.array().move( x, y ) ) + } // Set element size to given width and height -export function size (width, height) { - let p = proportionalSize(this, width, height) - return this.attr('points', this.array().size(p.width, p.height)) +export function size ( width, height ) { + + let p = proportionalSize( this, width, height ) + return this.attr( 'points', this.array().size( p.width, p.height ) ) + } diff --git a/src/modules/core/selector.js b/src/modules/core/selector.js index 24841c5..a60df02 100644 --- a/src/modules/core/selector.js +++ b/src/modules/core/selector.js @@ -3,13 +3,19 @@ import { globals } from '../../utils/window.js' import { map } from '../../utils/utils.js' import List from '../../types/List.js' -export default function baseFind (query, parent) { - return new List(map((parent || globals.document).querySelectorAll(query), function (node) { - return adopt(node) - })) +export default function baseFind ( query, parent ) { + + return new List( map( ( parent || globals.document ).querySelectorAll( query ), function ( node ) { + + return adopt( node ) + + } ) ) + } // Scoped find method -export function find (query) { - return baseFind(query, this.node) +export function find ( query ) { + + return baseFind( query, this.node ) + } diff --git a/src/modules/core/textable.js b/src/modules/core/textable.js index 55df7c6..b0a0993 100644 --- a/src/modules/core/textable.js +++ b/src/modules/core/textable.js @@ -1,19 +1,25 @@ import { globals } from '../../utils/window.js' // Create plain text node -export function plain (text) { +export function plain ( text ) { + // clear if build mode is disabled - if (this._build === false) { + if ( this._build === false ) { + this.clear() + } // create text node - this.node.appendChild(globals.document.createTextNode(text)) + this.node.appendChild( globals.document.createTextNode( text ) ) return this + } // Get length of text element export function length () { + return this.node.getComputedTextLength() + } diff --git a/src/modules/optional/arrange.js b/src/modules/optional/arrange.js index 6ce2eea..51e8605 100644 --- a/src/modules/optional/arrange.js +++ b/src/modules/optional/arrange.js @@ -3,109 +3,141 @@ import { registerMethods } from '../../utils/methods.js' // Get all siblings, including myself export function siblings () { + return this.parent().children() + } // Get the curent position siblings export function position () { - return this.parent().index(this) + + return this.parent().index( this ) + } // Get the next element (will return null if there is none) export function next () { + return this.siblings()[this.position() + 1] + } // Get the next element (will return null if there is none) export function prev () { + return this.siblings()[this.position() - 1] + } // Send given element one step forward export function forward () { + var i = this.position() + 1 var p = this.parent() // move node one step forward - p.removeElement(this).add(this, i) + p.removeElement( this ).add( this, i ) // make sure defs node is always at the top - if (typeof p.isRoot === 'function' && p.isRoot()) { - p.node.appendChild(p.defs().node) + if ( typeof p.isRoot === 'function' && p.isRoot() ) { + + p.node.appendChild( p.defs().node ) + } return this + } // Send given element one step backward export function backward () { + var i = this.position() - if (i > 0) { - this.parent().removeElement(this).add(this, i - 1) + if ( i > 0 ) { + + this.parent().removeElement( this ).add( this, i - 1 ) + } return this + } // Send given element all the way to the front export function front () { + var p = this.parent() // Move node forward - p.node.appendChild(this.node) + p.node.appendChild( this.node ) // Make sure defs node is always at the top - if (typeof p.isRoot === 'function' && p.isRoot()) { - p.node.appendChild(p.defs().node) + if ( typeof p.isRoot === 'function' && p.isRoot() ) { + + p.node.appendChild( p.defs().node ) + } return this + } // Send given element all the way to the back export function back () { - if (this.position() > 0) { - this.parent().removeElement(this).add(this, 0) + + if ( this.position() > 0 ) { + + this.parent().removeElement( this ).add( this, 0 ) + } return this + } // Inserts a given element before the targeted element -export function before (element) { - element = makeInstance(element) +export function before ( element ) { + + element = makeInstance( element ) element.remove() var i = this.position() - this.parent().add(element, i) + this.parent().add( element, i ) return this + } // Inserts a given element after the targeted element -export function after (element) { - element = makeInstance(element) +export function after ( element ) { + + element = makeInstance( element ) element.remove() var i = this.position() - this.parent().add(element, i + 1) + this.parent().add( element, i + 1 ) return this + } -export function insertBefore (element) { - element = makeInstance(element) - element.before(this) +export function insertBefore ( element ) { + + element = makeInstance( element ) + element.before( this ) + } -export function insertAfter (element) { - element = makeInstance(element) - element.after(this) +export function insertAfter ( element ) { + + element = makeInstance( element ) + element.after( this ) + } -registerMethods('Dom', { +registerMethods( 'Dom', { siblings, position, next, prev, forward, backward, front, back, before, after -}) +} ) diff --git a/src/modules/optional/class.js b/src/modules/optional/class.js index b08c82b..93ccd0e 100644 --- a/src/modules/optional/class.js +++ b/src/modules/optional/class.js @@ -3,42 +3,58 @@ import { registerMethods } from '../../utils/methods.js' // Return array of classes on the node export function classes () { - var attr = this.attr('class') - return attr == null ? [] : attr.trim().split(delimiter) + + var attr = this.attr( 'class' ) + return attr == null ? [] : attr.trim().split( delimiter ) + } // Return true if class exists on the node, false otherwise -export function hasClass (name) { - return this.classes().indexOf(name) !== -1 +export function hasClass ( name ) { + + return this.classes().indexOf( name ) !== -1 + } // Add class to the node -export function addClass (name) { - if (!this.hasClass(name)) { +export function addClass ( name ) { + + if ( !this.hasClass( name ) ) { + var array = this.classes() - array.push(name) - this.attr('class', array.join(' ')) + array.push( name ) + this.attr( 'class', array.join( ' ' ) ) + } return this + } // Remove class from the node -export function removeClass (name) { - if (this.hasClass(name)) { - this.attr('class', this.classes().filter(function (c) { +export function removeClass ( name ) { + + if ( this.hasClass( name ) ) { + + this.attr( 'class', this.classes().filter( function ( c ) { + return c !== name - }).join(' ')) + + } ).join( ' ' ) ) + } return this + } // Toggle the presence of a class on the node -export function toggleClass (name) { - return this.hasClass(name) ? this.removeClass(name) : this.addClass(name) +export function toggleClass ( name ) { + + return this.hasClass( name ) ? this.removeClass( name ) : this.addClass( name ) + } -registerMethods('Dom', { +registerMethods( 'Dom', { classes, hasClass, addClass, removeClass, toggleClass -}) +} ) diff --git a/src/modules/optional/css.js b/src/modules/optional/css.js index babee7a..d5378f4 100644 --- a/src/modules/optional/css.js +++ b/src/modules/optional/css.js @@ -3,68 +3,98 @@ import { isBlank } from '../core/regex.js' import { registerMethods } from '../../utils/methods.js' // Dynamic style generator -export function css (style, val) { +export function css ( style, val ) { + let ret = {} - if (arguments.length === 0) { + if ( arguments.length === 0 ) { + // get full style as object - this.node.style.cssText.split(/\s*;\s*/) - .filter(function (el) { return !!el.length }) - .forEach(function (el) { - let t = el.split(/\s*:\s*/) + this.node.style.cssText.split( /\s*;\s*/ ) + .filter( function ( el ) { + + return !!el.length + + } ) + .forEach( function ( el ) { + + let t = el.split( /\s*:\s*/ ) ret[t[0]] = t[1] - }) + + } ) return ret + } - if (arguments.length < 2) { + if ( arguments.length < 2 ) { + // get style properties in the array - if (Array.isArray(style)) { - for (let name of style) { - let cased = camelCase(name) + if ( Array.isArray( style ) ) { + + for ( let name of style ) { + + let cased = camelCase( name ) ret[cased] = this.node.style[cased] + } return ret + } // get style for property - if (typeof style === 'string') { - return this.node.style[camelCase(style)] + if ( typeof style === 'string' ) { + + return this.node.style[camelCase( style )] + } // set styles in object - if (typeof style === 'object') { - for (let name in style) { + if ( typeof style === 'object' ) { + + for ( let name in style ) { + // set empty string if null/undefined/'' was given - this.node.style[camelCase(name)] = - (style[name] == null || isBlank.test(style[name])) ? '' : style[name] + this.node.style[camelCase( name )] + = ( style[name] == null || isBlank.test( style[name] ) ) ? '' : style[name] + } + } + } // set style for property - if (arguments.length === 2) { - this.node.style[camelCase(style)] = - (val == null || isBlank.test(val)) ? '' : val + if ( arguments.length === 2 ) { + + this.node.style[camelCase( style )] + = ( val == null || isBlank.test( val ) ) ? '' : val + } return this + } // Show element export function show () { - return this.css('display', '') + + return this.css( 'display', '' ) + } // Hide element export function hide () { - return this.css('display', 'none') + + return this.css( 'display', 'none' ) + } // Is element visible? export function visible () { - return this.css('display') !== 'none' + + return this.css( 'display' ) !== 'none' + } -registerMethods('Dom', { +registerMethods( 'Dom', { css, show, hide, visible -}) +} ) diff --git a/src/modules/optional/data.js b/src/modules/optional/data.js index 341d129..498e65a 100644 --- a/src/modules/optional/data.js +++ b/src/modules/optional/data.js @@ -1,26 +1,40 @@ import { registerMethods } from '../../utils/methods.js' // Store data values on svg nodes -export function data (a, v, r) { - if (typeof a === 'object') { - for (v in a) { - this.data(v, a[v]) +export function data ( a, v, r ) { + + if ( typeof a === 'object' ) { + + for ( v in a ) { + + this.data( v, a[v] ) + } - } else if (arguments.length < 2) { + + } else if ( arguments.length < 2 ) { + try { - return JSON.parse(this.attr('data-' + a)) - } catch (e) { - return this.attr('data-' + a) + + return JSON.parse( this.attr( 'data-' + a ) ) + + } catch ( e ) { + + return this.attr( 'data-' + a ) + } + } else { - this.attr('data-' + a, + + this.attr( 'data-' + a, v === null ? null - : r === true || typeof v === 'string' || typeof v === 'number' ? v - : JSON.stringify(v) + : r === true || typeof v === 'string' || typeof v === 'number' ? v + : JSON.stringify( v ) ) + } return this + } -registerMethods('Dom', { data }) +registerMethods( 'Dom', { data } ) diff --git a/src/modules/optional/memory.js b/src/modules/optional/memory.js index 6478367..7c599f0 100644 --- a/src/modules/optional/memory.js +++ b/src/modules/optional/memory.js @@ -1,40 +1,60 @@ import { registerMethods } from '../../utils/methods.js' // Remember arbitrary data -export function remember (k, v) { +export function remember ( k, v ) { + // remember every item in an object individually - if (typeof arguments[0] === 'object') { - for (var key in k) { - this.remember(key, k[key]) + if ( typeof arguments[0] === 'object' ) { + + for ( var key in k ) { + + this.remember( key, k[key] ) + } - } else if (arguments.length === 1) { + + } else if ( arguments.length === 1 ) { + // retrieve memory return this.memory()[k] + } else { + // store memory this.memory()[k] = v + } return this + } // Erase a given memory export function forget () { - if (arguments.length === 0) { + + if ( arguments.length === 0 ) { + this._memory = {} + } else { - for (var i = arguments.length - 1; i >= 0; i--) { + + for ( var i = arguments.length - 1; i >= 0; i-- ) { + delete this.memory()[arguments[i]] + } + } return this + } // This triggers creation of a new hidden class which is not performant // However, this function is not rarely used so it will not happen frequently // Return local memory object export function memory () { - return (this._memory = this._memory || {}) + + return ( this._memory = this._memory || {} ) + } -registerMethods('Dom', { remember, forget, memory }) +registerMethods( 'Dom', { remember, forget, memory } ) diff --git a/src/modules/optional/sugar.js b/src/modules/optional/sugar.js index 6001631..4b6e6f3 100644 --- a/src/modules/optional/sugar.js +++ b/src/modules/optional/sugar.js @@ -8,169 +8,227 @@ import SVGNumber from '../../types/SVGNumber.js' // Define list of available attributes for stroke and fill var sugar = { - stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'], - fill: ['color', 'opacity', 'rule'], - prefix: function (t, a) { + stroke: [ 'color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset' ], + fill: [ 'color', 'opacity', 'rule' ], + prefix: function ( t, a ) { + return a === 'color' ? t : t + '-' + a + } } // Add sugar for fill and stroke -;['fill', 'stroke'].forEach(function (m) { +;[ 'fill', 'stroke' ].forEach( function ( m ) { + var extension = {} var i - extension[m] = function (o) { - if (typeof o === 'undefined') { - return this.attr(m) + extension[m] = function ( o ) { + + if ( typeof o === 'undefined' ) { + + return this.attr( m ) + } - if (typeof o === 'string' || Color.isRgb(o) || (o instanceof Element)) { - this.attr(m, o) + if ( typeof o === 'string' || Color.isRgb( o ) || ( o instanceof Element ) ) { + + this.attr( m, o ) + } else { + // set all attributes from sugar.fill and sugar.stroke list - for (i = sugar[m].length - 1; i >= 0; i--) { - if (o[sugar[m][i]] != null) { - this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]]) + for ( i = sugar[m].length - 1; i >= 0; i-- ) { + + if ( o[sugar[m][i]] != null ) { + + this.attr( sugar.prefix( m, sugar[m][i] ), o[sugar[m][i]] ) + } + } + } return this + } - registerMethods(['Shape', 'Runner'], extension) -}) + registerMethods( [ 'Shape', 'Runner' ], extension ) -registerMethods(['Element', 'Runner'], { +} ) + +registerMethods( [ 'Element', 'Runner' ], { // Let the user set the matrix directly - matrix: function (mat, b, c, d, e, f) { + matrix: function ( mat, b, c, d, e, f ) { + // Act as a getter - if (mat == null) { - return new Matrix(this) + if ( mat == null ) { + + return new Matrix( this ) + } // Act as a setter, the user can pass a matrix or a set of numbers - return this.attr('transform', new Matrix(mat, b, c, d, e, f)) + return this.attr( 'transform', new Matrix( mat, b, c, d, e, f ) ) + }, // Map rotation to transform - rotate: function (angle, cx, cy) { - return this.transform({ rotate: angle, ox: cx, oy: cy }, true) + rotate: function ( angle, cx, cy ) { + + return this.transform( { rotate: angle, ox: cx, oy: cy }, true ) + }, // Map skew to transform - skew: function (x, y, cx, cy) { + skew: function ( x, y, cx, cy ) { + return arguments.length === 1 || arguments.length === 3 - ? this.transform({ skew: x, ox: y, oy: cx }, true) - : this.transform({ skew: [x, y], ox: cx, oy: cy }, true) + ? this.transform( { skew: x, ox: y, oy: cx }, true ) + : this.transform( { skew: [ x, y ], ox: cx, oy: cy }, true ) + }, - shear: function (lam, cx, cy) { - return this.transform({ shear: lam, ox: cx, oy: cy }, true) + shear: function ( lam, cx, cy ) { + + return this.transform( { shear: lam, ox: cx, oy: cy }, true ) + }, // Map scale to transform - scale: function (x, y, cx, cy) { + scale: function ( x, y, cx, cy ) { + return arguments.length === 1 || arguments.length === 3 - ? this.transform({ scale: x, ox: y, oy: cx }, true) - : this.transform({ scale: [x, y], ox: cx, oy: cy }, true) + ? this.transform( { scale: x, ox: y, oy: cx }, true ) + : this.transform( { scale: [ x, y ], ox: cx, oy: cy }, true ) + }, // Map translate to transform - translate: function (x, y) { - return this.transform({ translate: [x, y] }, true) + translate: function ( x, y ) { + + return this.transform( { translate: [ x, y ] }, true ) + }, // Map relative translations to transform - relative: function (x, y) { - return this.transform({ relative: [x, y] }, true) + relative: function ( x, y ) { + + return this.transform( { relative: [ x, y ] }, true ) + }, // Map flip to transform - flip: function (direction, around) { + flip: function ( direction, around ) { + var directionString = typeof direction === 'string' ? direction - : isFinite(direction) ? 'both' - : 'both' - var origin = (direction === 'both' && isFinite(around)) ? [around, around] - : (direction === 'x') ? [around, 0] - : (direction === 'y') ? [0, around] - : isFinite(direction) ? [direction, direction] - : [0, 0] - this.transform({ flip: directionString, origin: origin }, true) + : isFinite( direction ) ? 'both' + : 'both' + var origin = ( direction === 'both' && isFinite( around ) ) ? [ around, around ] + : ( direction === 'x' ) ? [ around, 0 ] + : ( direction === 'y' ) ? [ 0, around ] + : isFinite( direction ) ? [ direction, direction ] + : [ 0, 0 ] + this.transform( { flip: directionString, origin: origin }, true ) + }, // Opacity - opacity: function (value) { - return this.attr('opacity', value) + opacity: function ( value ) { + + return this.attr( 'opacity', value ) + }, // Relative move over x and y axes - dmove: function (x, y) { - return this.dx(x).dy(y) + dmove: function ( x, y ) { + + return this.dx( x ).dy( y ) + } -}) +} ) -registerMethods('Element', { +registerMethods( 'Element', { // Relative move over x axis - dx: function (x) { - return this.x(new SVGNumber(x).plus(this.x())) + dx: function ( x ) { + + return this.x( new SVGNumber( x ).plus( this.x() ) ) + }, // Relative move over y axis - dy: function (y) { - return this.y(new SVGNumber(y).plus(this.y())) + dy: function ( y ) { + + return this.y( new SVGNumber( y ).plus( this.y() ) ) + } -}) +} ) -registerMethods('radius', { +registerMethods( 'radius', { // Add x and y radius - radius: function (x, y) { - var type = (this._element || this).type + radius: function ( x, y ) { + + var type = ( this._element || this ).type return type === 'radialGradient' || type === 'radialGradient' - ? this.attr('r', new SVGNumber(x)) - : this.rx(x).ry(y == null ? x : y) + ? this.attr( 'r', new SVGNumber( x ) ) + : this.rx( x ).ry( y == null ? x : y ) + } -}) +} ) -registerMethods('Path', { +registerMethods( 'Path', { // Get path length length: function () { + return this.node.getTotalLength() + }, // Get point at length - pointAt: function (length) { - return new Point(this.node.getPointAtLength(length)) + pointAt: function ( length ) { + + return new Point( this.node.getPointAtLength( length ) ) + } -}) +} ) -registerMethods(['Element', 'Runner'], { +registerMethods( [ 'Element', 'Runner' ], { // Set font - font: function (a, v) { - if (typeof a === 'object') { - for (v in a) this.font(v, a[v]) + font: function ( a, v ) { + + if ( typeof a === 'object' ) { + + for ( v in a ) this.font( v, a[v] ) + } return a === 'leading' - ? this.leading(v) + ? this.leading( v ) : a === 'anchor' - ? this.attr('text-anchor', v) + ? this.attr( 'text-anchor', v ) : a === 'size' || a === 'family' || a === 'weight' || a === 'stretch' || a === 'variant' || a === 'style' - ? this.attr('font-' + a, v) - : this.attr(a, v) + ? this.attr( 'font-' + a, v ) + : this.attr( a, v ) + } -}) +} ) + +registerMethods( 'Text', { + ax ( x ) { + + return this.attr( 'x', x ) -registerMethods('Text', { - ax (x) { - return this.attr('x', x) }, - ay (y) { - return this.attr('y', y) + ay ( y ) { + + return this.attr( 'y', y ) + }, - amove (x, y) { - return this.ax(x).ay(y) + amove ( x, y ) { + + return this.ax( x ).ay( y ) + } -}) +} ) // Add events to elements const methods = [ 'click', @@ -186,19 +244,27 @@ const methods = [ 'click', 'touchmove', 'touchleave', 'touchend', - 'touchcancel' ].reduce(function (last, event) { + 'touchcancel' ].reduce( function ( last, event ) { + // add event to Element - const fn = function (f) { - if (f === null) { - off(this, event) + const fn = function ( f ) { + + if ( f === null ) { + + off( this, event ) + } else { - on(this, event, f) + + on( this, event, f ) + } return this + } last[event] = fn return last -}, {}) -registerMethods('Element', methods) +}, {} ) + +registerMethods( 'Element', methods ) diff --git a/src/modules/optional/transform.js b/src/modules/optional/transform.js index b8f4c74..717fbf3 100644 --- a/src/modules/optional/transform.js +++ b/src/modules/optional/transform.js @@ -5,68 +5,92 @@ import Matrix from '../../types/Matrix.js' // Reset all transformations export function untransform () { - return this.attr('transform', null) + + return this.attr( 'transform', null ) + } // merge the whole transformation chain into one matrix and returns it export function matrixify () { - var matrix = (this.attr('transform') || '') + + var matrix = ( this.attr( 'transform' ) || '' ) // split transformations - .split(transforms).slice(0, -1).map(function (str) { + .split( transforms ).slice( 0, -1 ).map( function ( str ) { + // generate key => value pairs - var kv = str.trim().split('(') - return [kv[0], - kv[1].split(delimiter) - .map(function (str) { return parseFloat(str) }) + var kv = str.trim().split( '(' ) + return [ kv[0], + kv[1].split( delimiter ) + .map( function ( str ) { + + return parseFloat( str ) + + } ) ] - }) + + } ) .reverse() // merge every transformation into one matrix - .reduce(function (matrix, transform) { - if (transform[0] === 'matrix') { - return matrix.lmultiply(Matrix.fromArray(transform[1])) + .reduce( function ( matrix, transform ) { + + if ( transform[0] === 'matrix' ) { + + return matrix.lmultiply( Matrix.fromArray( transform[1] ) ) + } - return matrix[transform[0]].apply(matrix, transform[1]) - }, new Matrix()) + return matrix[transform[0]].apply( matrix, transform[1] ) + + }, new Matrix() ) return matrix + } // add an element to another parent without changing the visual representation on the screen -export function toParent (parent) { - if (this === parent) return this +export function toParent ( parent ) { + + if ( this === parent ) return this var ctm = this.screenCTM() var pCtm = parent.screenCTM().inverse() - this.addTo(parent).untransform().transform(pCtm.multiply(ctm)) + this.addTo( parent ).untransform().transform( pCtm.multiply( ctm ) ) return this + } // same as above with parent equals root-svg export function toRoot () { - return this.toParent(this.root()) + + return this.toParent( this.root() ) + } // Add transformations -export function transform (o, relative) { +export function transform ( o, relative ) { + // Act as a getter if no object was passed - if (o == null || typeof o === 'string') { - var decomposed = new Matrix(this).decompose() + if ( o == null || typeof o === 'string' ) { + + var decomposed = new Matrix( this ).decompose() return decomposed[o] || decomposed + } - if (!Matrix.isMatrixLike(o)) { + if ( !Matrix.isMatrixLike( o ) ) { + // Set the origin according to the defined transform - o = { ...o, origin: getOrigin(o, this) } + o = { ...o, origin: getOrigin( o, this ) } + } // The user can pass a boolean, an Element or an Matrix or nothing - var cleanRelative = relative === true ? this : (relative || false) - var result = new Matrix(cleanRelative).transform(o) - return this.attr('transform', result) + var cleanRelative = relative === true ? this : ( relative || false ) + var result = new Matrix( cleanRelative ).transform( o ) + return this.attr( 'transform', result ) + } -registerMethods('Element', { +registerMethods( 'Element', { untransform, matrixify, toParent, toRoot, transform -}) +} ) |