aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich-Matthias Schäfer <ulima.ums@googlemail.com>2020-03-29 10:47:16 +1000
committerUlrich-Matthias Schäfer <ulima.ums@googlemail.com>2020-03-29 10:47:16 +1000
commit28e74482b8cc7b7f2e4aca099ceea9f7d7a888d5 (patch)
treec69f495017fd96aaeee6dd39eb529c2c49e31bf3
parentf8f63d4f976b7ed87d5c6fafcc4c32d9c6d9a270 (diff)
downloadsvg.js-28e74482b8cc7b7f2e4aca099ceea9f7d7a888d5.tar.gz
svg.js-28e74482b8cc7b7f2e4aca099ceea9f7d7a888d5.zip
fixed put and adopter, added tests to cover it
-rw-r--r--CHANGELOG.md2
-rw-r--r--spec/RAFPlugin.js107
-rw-r--r--spec/helpers.js77
-rw-r--r--spec/spec/elements/Dom.js33
-rw-r--r--spec/spec/utils/adopter.js32
-rw-r--r--src/elements/Dom.js3
-rw-r--r--src/utils/adopter.js8
7 files changed, 156 insertions, 106 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 53817e1..320fd0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,8 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http:
- fixed `getOrigin()` function used by `transform()` so that all origin (#1085) popssibilities specified in the docs are working
- fixed positioning of text by its baseline when using `amove()`
- fixed tons of typings in the svg.d.ts file
+ - fixed adopter when adopting an svg/html string. It had still its wrapper as parentNode attached
+ - fixed `put()` which correctly creates an svgjs object from the passed element now before returning
### Added
- added second Parameter to `SVG(el, isHTML)` which allows to explicitely create elements in the HTML namespace (#1058)
diff --git a/spec/RAFPlugin.js b/spec/RAFPlugin.js
index 2dea383..87ce48a 100644
--- a/spec/RAFPlugin.js
+++ b/spec/RAFPlugin.js
@@ -2,83 +2,82 @@
* Jasmine RequestAnimationFrame: a set of helpers for testing funcionality
* that uses requestAnimationFrame under the Jasmine BDD framework for JavaScript.
*/
-;(function() {
+;(function () {
- var index = 0,
- callbacks = [];
+ var index = 0
+ var callbacks = []
- function MockRAF(global) {
- this.realRAF = global.requestAnimationFrame,
- this.realCAF = global.cancelAnimationFrame,
- this.realPerf = global.performance,
- this.nextTime = 0
+ function MockRAF (global) {
+ this.realRAF = global.requestAnimationFrame
+ this.realCAF = global.cancelAnimationFrame
+ this.realPerf = global.performance
+ this.nextTime = 0
- var _this = this
+ var _this = this
- /**
+ /**
* Mock for window.requestAnimationFrame
*/
- this.mockRAF = function(fn) {
- if (typeof fn !== 'function') {
- throw new Error('You should pass a function to requestAnimationFrame');
- }
+ this.mockRAF = function (fn) {
+ if (typeof fn !== 'function') {
+ throw new Error('You should pass a function to requestAnimationFrame')
+ }
- callbacks[index++] = fn;
+ callbacks[index++] = fn
- return index;
- };
+ return index
+ }
- /**
+ /**
* Mock for window.cancelAnimationFrame
*/
- this.mockCAF = function(requestID) {
- callbacks.splice(requestID, 1)
- };
+ this.mockCAF = function (requestID) {
+ callbacks.splice(requestID, 1)
+ }
- this.mockPerf = {
- now: function () {
- return _this.nextTime
- }
- }
+ this.mockPerf = {
+ now: function () {
+ return _this.nextTime
+ }
+ }
- /**
+ /**
* Install request animation frame mocks.
*/
- this.install = function() {
- global.requestAnimationFrame = _this.mockRAF;
- global.cancelAnimationFrame = _this.mockCAF;
- global.performance = _this.mockPerf;
- };
+ this.install = function () {
+ global.requestAnimationFrame = _this.mockRAF
+ global.cancelAnimationFrame = _this.mockCAF
+ global.performance = _this.mockPerf
+ }
- /**
+ /**
* Uninstall request animation frame mocks.
*/
- this.uninstall = function() {
- global.requestAnimationFrame = _this.realRAF;
- global.cancelAnimationFrame = _this.realCAF;
- global.performance = _this.realPerf;
- _this.nextTime = 0
- callbacks = []
- };
+ this.uninstall = function () {
+ global.requestAnimationFrame = _this.realRAF
+ global.cancelAnimationFrame = _this.realCAF
+ global.performance = _this.realPerf
+ _this.nextTime = 0
+ callbacks = []
+ }
- /**
+ /**
* Simulate animation frame readiness.
*/
- this.tick = function(dt) {
- _this.nextTime += (dt || 1)
+ this.tick = function (dt) {
+ _this.nextTime += (dt || 1)
- var fns = callbacks, fn, i;
+ var fns = callbacks; var fn; var i
- callbacks = [];
- index = 0;
+ callbacks = []
+ index = 0
- for (i in fns) {
- fn = fns[i];
- fn(_this.nextTime);
- }
- };
+ for (i in fns) {
+ fn = fns[i]
+ fn(_this.nextTime)
+ }
}
+ }
-
- jasmine.RequestAnimationFrame = new MockRAF(window);
-}());
+ jasmine.RequestAnimationFrame = new MockRAF(window)
+}())
diff --git a/spec/helpers.js b/spec/helpers.js
index a584b6a..0fa2a1f 100644
--- a/spec/helpers.js
+++ b/spec/helpers.js
@@ -1,16 +1,17 @@
import { getWindow } from '../src/utils/window.js'
+import { ns } from '../src/modules/core/namespaces.js'
-function tag(name, attrs, children) {
- let doc = getWindow().document
- var el = doc.createElement(name)
+function tag (name, attrs, children) {
+ const doc = getWindow().document
+ const el = doc.createElementNS(ns, name)
+ let i
- for(var i in attrs){
+ for (i in attrs) {
el.setAttribute(i, attrs[i])
}
- for(var i in children){
- if(typeof children[i] == 'string')
- children[i] = doc.createTextNode(children[i])
+ for (i in children) {
+ if (typeof children[i] === 'string') { children[i] = doc.createTextNode(children[i]) }
el.appendChild(children[i])
}
@@ -20,21 +21,21 @@ function tag(name, attrs, children) {
export function fixtures () {
return tag('svg', {
- height:0,
- width:0,
- id:'inlineSVG'
- },[
+ height: 0,
+ width: 0,
+ id: 'inlineSVG'
+ }, [
tag('defs', {}, [
tag('linearGradient', {}, [
- tag('stop', {offset: '5%', 'stop-color': 'green'}),
- tag('stop', {offset: '95%', 'stop-color': 'gold'}),
+ tag('stop', { offset: '5%', 'stop-color': 'green' }),
+ tag('stop', { offset: '95%', 'stop-color': 'gold' })
]),
tag('radialGradient', {}, [
- tag('stop', {offset: '5%', 'stop-color': 'green'}),
- tag('stop', {offset: '95%', 'stop-color': 'gold'}),
+ tag('stop', { offset: '5%', 'stop-color': 'green' }),
+ tag('stop', { offset: '95%', 'stop-color': 'gold' })
])
]),
- tag('desc', {}, ['Some description']),
+ tag('desc', {}, [ 'Some description' ]),
tag('path', {
id: 'lineAB',
d: 'M 100 350 l 150 -300',
@@ -66,24 +67,24 @@ export function fixtures () {
'stroke-width': '2',
fill: 'black',
id: 'pointGroup'
- },[
+ }, [
tag('circle', {
id: 'pointA',
cx: '100',
cy: '350',
- r: '3',
+ r: '3'
}),
tag('circle', {
id: 'pointB',
cx: '250',
cy: '50',
- r: '50',
+ r: '50'
}),
tag('circle', {
id: 'pointC',
cx: '400',
cy: '350',
- r: '50',
+ r: '50'
})
]),
tag('g', {
@@ -93,33 +94,33 @@ export function fixtures () {
stroke: 'none',
'text-anchor': 'middle',
id: 'labelGroup'
- },[
+ }, [
tag('text', {
x: '100',
y: '350',
- dy: '-30',
- }, ['A']),
+ dy: '-30'
+ }, [ 'A' ]),
tag('text', {
x: '250',
y: '50',
- dy: '-10',
- }, ['B']),
+ dy: '-10'
+ }, [ 'B' ]),
tag('text', {
x: '400',
y: '350',
- dx: '30',
- }, ['C'])
+ dx: '30'
+ }, [ 'C' ])
]),
- tag('polygon', {points: '200,10 250,190 160,210'}),
- tag('polyline', {points: '20,20 40,25 60,40 80,120 120,140 200,180'})
+ tag('polygon', { points: '200,10 250,190 160,210' }),
+ tag('polyline', { points: '20,20 40,25 60,40 80,120 120,140 200,180' })
])
}
export function buildFixtures () {
- let doc = getWindow().document
- let body = doc.body || doc.documentElement
+ const doc = getWindow().document
+ const body = doc.body || doc.documentElement
- let div = doc.createElement('div')
+ const div = doc.createElement('div')
div.id = 'fixtures'
try {
@@ -134,10 +135,10 @@ export function buildFixtures () {
}
export function buildCanvas () {
- let doc = getWindow().document
- let body = doc.body || doc.documentElement
+ const doc = getWindow().document
+ const body = doc.body || doc.documentElement
- let div = doc.createElement('div')
+ const div = doc.createElement('div')
div.id = 'canvas'
try {
@@ -150,9 +151,9 @@ export function buildCanvas () {
}
export function clear () {
- let doc = getWindow().document
- let canvas = doc.getElementById('canvas')
- let fixtures = doc.getElementById('fixtures')
+ const doc = getWindow().document
+ const canvas = doc.getElementById('canvas')
+ const fixtures = doc.getElementById('fixtures')
// remove if present
fixtures && fixtures.parentNode.removeChild(fixtures)
diff --git a/spec/spec/elements/Dom.js b/spec/spec/elements/Dom.js
index 138a391..fcdba4c 100644
--- a/spec/spec/elements/Dom.js
+++ b/spec/spec/elements/Dom.js
@@ -1,6 +1,7 @@
-/* globals describe, expect, it, beforeEach */
+/* globals describe, expect, it, beforeEach, jasmine */
import { SVG, G, Rect } from '../../../src/main.js'
+const { any } = jasmine
describe('Dom.js', function () {
describe('wrap()', function () {
@@ -36,5 +37,35 @@ describe('Dom.js', function () {
var g = new G()
expect(rect.wrap(g).parent().position()).toBe(position)
})
+
+ it('allows to pass an svg string as element', () => {
+ rect.wrap('<g>')
+ expect(rect.parent()).toEqual(any(G))
+ expect(rect.parent().parent()).toBe(canvas)
+ })
+
+ it('allows to pass an svg string as element', () => {
+ rect.wrap('<g>')
+ expect(rect.parent()).toEqual(any(G))
+ expect(rect.parent().parent()).toBe(canvas)
+ })
+
+ it('allows to pass an svg string as element when element not in the dom', () => {
+ var rect = new Rect()
+ rect.wrap(SVG('<g>'))
+ expect(rect.parent()).toEqual(any(G))
+ expect(rect.parent().parent()).toBe(null)
+ })
+
+ it('allows to pass an svg node as element', () => {
+ var g = new G()
+ const node = g.node
+ delete node.instance
+ rect.wrap(node)
+ expect(rect.parent()).toEqual(any(G))
+ expect(rect.parent().node).toBe(node)
+ expect(rect.parent()).not.toBe(g)
+ expect(rect.parent().parent()).toBe(canvas)
+ })
})
})
diff --git a/spec/spec/utils/adopter.js b/spec/spec/utils/adopter.js
index d8a7d5b..c209980 100644
--- a/spec/spec/utils/adopter.js
+++ b/spec/spec/utils/adopter.js
@@ -14,12 +14,13 @@ import {
root,
G,
Gradient,
- Dom
+ Dom,
+ Path
} from '../../../src/main.js'
import { mockAdopt, assignNewId, adopt } from '../../../src/utils/adopter.js'
import { buildFixtures } from '../../helpers.js'
-import { globals } from '../../../src/utils/window.js'
+import { globals, getWindow } from '../../../src/utils/window.js'
const { any, createSpy, objectContaining } = jasmine
@@ -39,7 +40,7 @@ describe('adopter.js', () => {
})
describe('makeInstance()', () => {
- const adoptSpy = createSpy('adopt')
+ const adoptSpy = createSpy('adopt', adopt).and.callThrough()
beforeEach(() => {
adoptSpy.calls.reset()
@@ -64,16 +65,26 @@ describe('adopter.js', () => {
})
it('creates an element from passed svg string', () => {
- makeInstance('<rect width="200px">')
+ const rect = makeInstance('<rect width="200px">')
expect(adoptSpy).toHaveBeenCalledWith(any(Node))
expect(adoptSpy).toHaveBeenCalledWith(objectContaining({ nodeName: 'rect' }))
+ expect(rect).toEqual(any(Rect))
+ expect(rect.parent()).toBe(null)
})
it('creates an element in the html namespace from passed html string', () => {
- makeInstance('<div>', true)
+ const div = makeInstance('<div>', true)
+
expect(adoptSpy).toHaveBeenCalledWith(any(Node))
expect(adoptSpy).toHaveBeenCalledWith(objectContaining({ nodeName: 'DIV', namespaceURI: 'http://www.w3.org/1999/xhtml' }))
+ expect(div).toEqual(any(Dom))
+ expect(div.parent()).toBe(null)
+ })
+
+ it('does not have its wrapper attached', () => {
+ const rect = makeInstance('<rect width="200px">')
+ expect(rect.parent()).toBe(null)
})
it('searches for element in dom if selector given', () => {
@@ -81,18 +92,21 @@ describe('adopter.js', () => {
const path = globals.window.document.getElementById('lineAB')
- makeInstance('#lineAB')
- makeInstance('#doesNotExist')
+ const pathInst = makeInstance('#lineAB')
+ const noEl = makeInstance('#doesNotExist')
expect(adoptSpy).toHaveBeenCalledWith(path)
expect(adoptSpy).toHaveBeenCalledWith(null)
+ expect(pathInst).toEqual(any(Path))
+ expect(noEl).toBe(null)
})
it('calls adopt when passed a node', () => {
- makeInstance(create('rect'))
+ const rect = makeInstance(create('rect'))
expect(adoptSpy).toHaveBeenCalledWith(any(Node))
expect(adoptSpy).toHaveBeenCalledWith(objectContaining({ nodeName: 'rect' }))
+ expect(rect).toEqual(any(Rect))
})
})
@@ -124,7 +138,7 @@ describe('adopter.js', () => {
})
it('creates Dom instances for unknown nodes', () => {
- const div = document.createElement('div')
+ const div = getWindow().document.createElement('div')
expect(adopt(div)).toEqual(any(Dom))
})
})
diff --git a/src/elements/Dom.js b/src/elements/Dom.js
index 6fd1b1b..2e081a8 100644
--- a/src/elements/Dom.js
+++ b/src/elements/Dom.js
@@ -162,6 +162,7 @@ export default class Dom extends EventTarget {
// Basically does the same as `add()` but returns the added element instead
put (element, i) {
+ element = makeInstance(element)
this.add(element, i)
return element
}
@@ -299,7 +300,7 @@ export default class Dom extends EventTarget {
const parent = this.parent()
if (!parent) {
- return node.put(this)
+ return this.addTo(node)
}
const position = parent.index(this)
diff --git a/src/utils/adopter.js b/src/utils/adopter.js
index 30eab84..b016837 100644
--- a/src/utils/adopter.js
+++ b/src/utils/adopter.js
@@ -29,13 +29,15 @@ export function makeInstance (element, isHTML = false) {
}
// Make sure, that HTML elements are created with the correct namespace
- var node = isHTML ? globals.document.createElement('div') : create('svg')
- node.innerHTML = element
+ var wrapper = isHTML ? globals.document.createElement('div') : create('svg')
+ wrapper.innerHTML = element
// We can use firstChild here because we know,
// that the first char is < and thus an element
- element = adopter(node.firstChild)
+ element = adopter(wrapper.firstChild)
+ // make sure, that element doesnt have its wrapper attached
+ wrapper.removeChild(wrapper.firstChild)
return element
}