]> source.dussan.org Git - svg.js.git/commitdiff
fixed put and adopter, added tests to cover it
authorUlrich-Matthias Schäfer <ulima.ums@googlemail.com>
Sun, 29 Mar 2020 00:47:16 +0000 (10:47 +1000)
committerUlrich-Matthias Schäfer <ulima.ums@googlemail.com>
Sun, 29 Mar 2020 00:47:16 +0000 (10:47 +1000)
CHANGELOG.md
spec/RAFPlugin.js
spec/helpers.js
spec/spec/elements/Dom.js
spec/spec/utils/adopter.js
src/elements/Dom.js
src/utils/adopter.js

index 53817e1503f4b245388dc25218de538435666df2..320fd0ae1b4887d23c9dbccf4533c1f7752faa88 100644 (file)
@@ -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)
index 2dea3835559ad639eafb35c0601f81de7f34d192..87ce48afdba8ad418ff59b6a21a94ea860eba596 100644 (file)
@@ -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)
+}())
index a584b6a1a15517661ba854fad8874f8710f88153..0fa2a1f03b4c0121636b6882abe00fff27019794 100644 (file)
@@ -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)
index 138a3918ea534673e959962e00858807078c1d4b..fcdba4ca26cd9e08306db99dbf0522f8b830c22f 100644 (file)
@@ -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)
+    })
   })
 })
index d8a7d5b0d0fbc5d0bb55f048c6370b8910c9d5a4..c209980a2d994b71baee76e00af05956ef538471 100644 (file)
@@ -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))
     })
   })
index 6fd1b1bc7af24ab7026ee825a03748fb8847e4bb..2e081a8c59506fca52e545892566ac87e1701a99 100644 (file)
@@ -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)
index 30eab84691d8dd60b8c09ad80e55ee6cab77aa3e..b01683792c8a985df61c373df2ad9e67e5c13558 100644 (file)
@@ -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
 }