From: Ulrich-Matthias Schäfer Date: Sun, 29 Mar 2020 00:47:16 +0000 (+1000) Subject: fixed put and adopter, added tests to cover it X-Git-Tag: 3.1.0~73 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=28e74482b8cc7b7f2e4aca099ceea9f7d7a888d5;p=svg.js.git fixed put and adopter, added tests to cover it --- 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('') + expect(rect.parent()).toEqual(any(G)) + expect(rect.parent().parent()).toBe(canvas) + }) + + it('allows to pass an svg string as element', () => { + rect.wrap('') + 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('')) + 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('') + const rect = makeInstance('') 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('
', true) + const div = makeInstance('
', 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('') + 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 }