Browse Source

Get rid of HTMLNode and Bare in favor of Dom

- words() and element() added to Dom
- svg() now returns the _parent_ of the imported element, when outerHTML is true (which means an element gets replaces)
tags/3.0.0
Ulrich-Matthias Schäfer 5 years ago
parent
commit
858f19e9f8

+ 2
- 0
CHANGELOG.md View File

@@ -28,6 +28,7 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http:
- added possibility to pass attributes into a constructor like: `new SVG.Rect({width:100})`
- added possibility to pass in additional attribues to element creators e.g. `canvas.rect({x:100})` or `canvas.rect(100, 100, {x:100})` (#796)
- added `SVG.List` (#645)
- added `words()` and `element()` to `Dom` because of (#935)

### Removed
- removed `SVG.Array.split()` function
@@ -42,6 +43,7 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http:
- removed `size()` from `SVG.Text` to avoid name clash (#799)
- removed `move(), dmove()` etc for groups to avoid inconsistencies, we will expect users to use transforms to move around groups as they should (especially since they are much simpler now).
- removed `native()` function
- removed `Bare` in favour of `Dom` (#935)

### Changed
- gradients now have there corresponding node as type and not only radial/linear

+ 21
- 0
bench/tests/10000-textContent.js View File

@@ -0,0 +1,21 @@
SVG.bench.describe('Change textContent 10000 times', function(bench) {
var data = 'M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100'

var node = bench.draw.plain('').node


bench.test('using appendChild', function() {
for (var i = 0; i < 1000000; i++) {
while (node.hasChildNodes()) {
node.removeChild(node.lastChild)
}

node.appendChild(document.createTextNode('test'+i))
}
})
bench.test('using textContent', function() {
for (var i = 0; i < 1000000; i++) {
node.textContent = 'test'+i
}
})
})

+ 16
- 2
dirty.html View File

@@ -210,9 +210,23 @@ canvas.rect(100, 100).on('click', (e) => {
})
})


console.log(schedule)
















// var bla = SVG('<rect>').size(0, 0).move(200, 200).addTo('svg')
// bla.animate().size(220, 200).queue(null, console.log)

@@ -353,7 +367,7 @@ rectangle.animate().transform({
//
// moon.animate(10000).loop().ease('-')
// .transform({rotate: 360, origin: [500, 300]}, true)
// .transform({rotate: 1080, origin: [1000, 300]}, true)
// .transform({rotate: 3600, origin: [1000, 300]}, true)




+ 26
- 71
dist/svg.js View File

@@ -6,7 +6,7 @@
* @copyright Wout Fierens <wout@mick-wout.com>
* @license MIT
*
* BUILT: Fri Nov 23 2018 14:47:42 GMT+0100 (GMT+01:00)
* BUILT: Sat Nov 24 2018 11:07:45 GMT+0100 (GMT+01:00)
*/;
var SVG = (function () {
'use strict';
@@ -430,21 +430,14 @@ var SVG = (function () {
// check for presence of node
if (!node) return null; // make sure a node isn't already adopted

if (node.instance instanceof Base) return node.instance;
if (node.instance instanceof Base) return node.instance; // initialize variables

if (!(node instanceof globals.window.SVGElement)) {
return new elements.HtmlNode(node);
} // initialize variables


var className = capitalize(node.nodeName);
var className = capitalize(node.nodeName); // Make sure that gradients are adopted correctly

if (className === 'LinearGradient' || className === 'RadialGradient') {
className = 'Gradient';
}

if (!elements[className]) {
className = 'Bare';
className = 'Gradient'; // Fallback to Dom if element is not known
} else if (!elements[className]) {
className = 'Dom';
}

return new elements[className](node);
@@ -2372,6 +2365,11 @@ var SVG = (function () {
}

return this;
}
}, {
key: "element",
value: function element(nodeName) {
return this.put(new Dom(makeNode(nodeName)));
} // Get first child

}, {
@@ -2572,10 +2570,18 @@ var SVG = (function () {

for (len = well.children.length; len--;) {
fragment.appendChild(well.firstElementChild);
} // Add the whole fragment at once
}

var parent = this.parent(); // Add the whole fragment at once

return outerHTML ? this.replace(fragment) : this.add(fragment);
return outerHTML ? this.replace(fragment) && parent : this.add(fragment);
}
}, {
key: "words",
value: function words(text) {
// This is faster than removing all children and adding a new one
this.node.textContent = text;
return this;
} // write svgjs data to the dom

}, {
@@ -6604,41 +6610,6 @@ var SVG = (function () {
});
register(Tspan);

var Bare =
/*#__PURE__*/
function (_Container) {
_inherits(Bare, _Container);

function Bare(node, attrs) {
_classCallCheck(this, Bare);

return _possibleConstructorReturn(this, _getPrototypeOf(Bare).call(this, nodeOrNew(node, typeof node === 'string' ? null : node), attrs));
}

_createClass(Bare, [{
key: "words",
value: function words(text) {
// remove contents
while (this.node.hasChildNodes()) {
this.node.removeChild(this.node.lastChild);
} // create text node


this.node.appendChild(globals.document.createTextNode(text));
return this;
}
}]);

return Bare;
}(Container);
register(Bare);
registerMethods('Container', {
// Create an element that is not described by SVG.js
element: wrapWithAttrCheck(function (node) {
return this.put(new Bare(node));
})
});

var ClipPath =
/*#__PURE__*/
function (_Container) {
@@ -6719,21 +6690,6 @@ var SVG = (function () {
});
register(G);

var HtmlNode =
/*#__PURE__*/
function (_Dom) {
_inherits(HtmlNode, _Dom);

function HtmlNode() {
_classCallCheck(this, HtmlNode);

return _possibleConstructorReturn(this, _getPrototypeOf(HtmlNode).apply(this, arguments));
}

return HtmlNode;
}(Dom);
register(HtmlNode);

var A =
/*#__PURE__*/
function (_Container) {
@@ -6867,9 +6823,10 @@ var SVG = (function () {
}

_createClass(Style, [{
key: "words",
value: function words(w) {
this.node.textContent += w || '';
key: "addText",
value: function addText() {
var w = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
this.node.textContent += w;
return this;
}
}, {
@@ -6884,7 +6841,7 @@ var SVG = (function () {
}, {
key: "rule",
value: function rule(selector, obj) {
return this.words(cssRule(selector, obj));
return this.addText(cssRule(selector, obj));
}
}]);

@@ -7090,7 +7047,6 @@ var SVG = (function () {
Point: Point,
PointArray: PointArray,
List: List,
Bare: Bare,
Circle: Circle,
ClipPath: ClipPath,
Container: Container,
@@ -7100,7 +7056,6 @@ var SVG = (function () {
Ellipse: Ellipse,
Gradient: Gradient,
G: G,
HtmlNode: HtmlNode,
A: A,
Image: Image,
Line: Line,

+ 2
- 4
spec/spec/adopter.js View File

@@ -71,11 +71,9 @@ describe('Adopter', function() {
})

describe('with node that has no matching svg.js class', function() {
it('wraps the node in the base SVG.Element class', function() {
it('wraps the node in the Dom class', function() {
var desc = SVG('#inlineSVG').find('desc')[0]
expect(desc instanceof SVG.Element).toBeTruthy()
expect(desc instanceof SVG.Dom).toBeTruthy()
})
})


})

+ 0
- 41
spec/spec/bare.js View File

@@ -1,41 +0,0 @@
describe('Bare', function() {

describe('element()', function() {
var element

beforeEach(function() {
element = draw.element('rect')
})

it('creates an instance of SVG.Bare', function() {
expect(element instanceof SVG.Bare).toBeTruthy()
})
it('creates element in called parent', function() {
expect(element.parent()).toBe(draw)
})
// it('inherits from given parent', function() {
// expect(draw.element('g', SVG.Container).rect).toBeTruthy()
// expect(draw.element('g', SVG.Container).group).toBeTruthy()
// })
})

describe('words()', function() {
it('inserts plain text in a node', function() {
var element = draw.element('title').words('These are some words.').id(null)
var result = element.svg()
expect(
result == '<title>These are some words.</title>'
|| result == '<title xmlns="http://www.w3.org/2000/svg">These are some words.</title>'
).toBe(true)
})
it('removes all nodes before adding words', function() {
var element = draw.element('title').words('These are some words.').id(null)
element.words('These are some words.')
var result = element.svg()
expect(
result == '<title>These are some words.</title>'
|| result == '<title xmlns="http://www.w3.org/2000/svg">These are some words.</title>'
).toBe(true)
})
})
})

+ 35
- 0
spec/spec/element.js View File

@@ -1045,4 +1045,39 @@ describe('Element', function() {
}))
})
})

describe('words()', function() {
it('inserts plain text in a node', function() {
var element = draw.element('title').words('These are some words.').id(null)
var result = element.svg()
expect(
result == '<title>These are some words.</title>'
|| result == '<title xmlns="http://www.w3.org/2000/svg">These are some words.</title>'
).toBe(true)
})
it('removes all nodes before adding words', function() {
var element = draw.element('title').words('These are some words.').id(null)
element.words('These are some words.')
var result = element.svg()
expect(
result == '<title>These are some words.</title>'
|| result == '<title xmlns="http://www.w3.org/2000/svg">These are some words.</title>'
).toBe(true)
})
})

describe('element()', function() {
var element

beforeEach(function() {
element = draw.element('rect')
})

it('creates an instance of Dom', function() {
expect(element instanceof SVG.Dom).toBeTruthy()
})
it('creates element in called parent', function() {
expect(element.parent()).toBe(draw)
})
})
})

+ 4
- 4
spec/spec/svg.js View File

@@ -23,15 +23,15 @@ describe('SVG', function() {
expect(SVG().node.nodeName).toBe('svg')
})

it('creates an instanceof SVG.HtmlNode with html node', function() {
it('creates an instanceof SVG.Dom with html node', function() {
var el = SVG(wrapperHTML)
expect(el instanceof SVG.HtmlNode).toBe(true)
expect(el instanceof SVG.Dom).toBe(true)
expect(el.node).toBe(wrapperHTML)
})

it('creates new SVG.HtmlNode when called with css selector pointing to html node', function() {
it('creates new SVG.Dom when called with css selector pointing to html node', function() {
var el = SVG('#testDiv')
expect(el instanceof SVG.HtmlNode).toBe(true)
expect(el instanceof SVG.Dom).toBe(true)
expect(el.node).toBe(wrapperHTML)
})


src/types/Morphable.js → src/animation/Morphable.js View File

@@ -1,14 +1,14 @@
import { Ease } from '../animation/Controller.js'
import { Ease } from './Controller.js'
import {
delimiter,
numberAndUnit,
pathLetters
} from '../modules/core/regex.js'
import { extend } from '../utils/adopter.js'
import Color from './Color.js'
import PathArray from './PathArray.js'
import SVGArray from './SVGArray.js'
import SVGNumber from './SVGNumber.js'
import Color from '../types/Color.js'
import PathArray from '../types/PathArray.js'
import SVGArray from '../types/SVGArray.js'
import SVGNumber from '../types/SVGNumber.js'

export default class Morphable {
constructor (stepper) {

+ 1
- 1
src/animation/Runner.js View File

@@ -9,7 +9,7 @@ import Animator from './Animator.js'
import Box from '../types/Box.js'
import EventTarget from '../types/EventTarget.js'
import Matrix from '../types/Matrix.js'
import Morphable, { TransformBag } from '../types/Morphable.js'
import Morphable, { TransformBag } from './Morphable.js'
import Point from '../types/Point.js'
import SVGNumber from '../types/SVGNumber.js'
import Timeline from './Timeline.js'

+ 0
- 31
src/elements/Bare.js View File

@@ -1,31 +0,0 @@
import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'
import { registerMethods } from '../utils/methods.js'
import Container from './Container.js'
import { globals } from '../utils/window.js'

export default class Bare extends Container {
constructor (node, attrs) {
super(nodeOrNew(node, typeof node === 'string' ? null : node), attrs)
}

words (text) {
// remove contents
while (this.node.hasChildNodes()) {
this.node.removeChild(this.node.lastChild)
}

// create text node
this.node.appendChild(globals.document.createTextNode(text))

return this
}
}

register(Bare)

registerMethods('Container', {
// Create an element that is not described by SVG.js
element: wrapWithAttrCheck(function (node) {
return this.put(new Bare(node))
})
})

+ 14
- 1
src/elements/Dom.js View File

@@ -4,6 +4,7 @@ import {
eid,
extend,
makeInstance,
makeNode,
register
} from '../utils/adopter.js'
import { find } from '../modules/core/selector'
@@ -88,6 +89,10 @@ export default class Dom extends EventTarget {
return this
}

element (nodeName) {
return this.put(new Dom(makeNode(nodeName)))
}

// Get first child
first () {
return adopt(this.node.firstChild)
@@ -285,12 +290,20 @@ export default class Dom extends EventTarget {
fragment.appendChild(well.firstElementChild)
}

let parent = this.parent()

// Add the whole fragment at once
return outerHTML
? this.replace(fragment)
? this.replace(fragment) && parent
: this.add(fragment)
}

words (text) {
// This is faster than removing all children and adding a new one
this.node.textContent = text
return this
}

// write svgjs data to the dom
writeDataToDom () {
// dump variables recursively

+ 0
- 6
src/elements/HtmlNode.js View File

@@ -1,6 +0,0 @@
import { register } from '../utils/adopter.js'
import Dom from './Dom.js'

export default class HtmlNode extends Dom {}

register(HtmlNode)

+ 3
- 3
src/elements/Style.js View File

@@ -23,8 +23,8 @@ export default class Style extends Element {
super(nodeOrNew('style', node), node)
}

words (w) {
this.node.textContent += (w || '')
addText (w = '') {
this.node.textContent += w
return this
}

@@ -37,7 +37,7 @@ export default class Style extends Element {
}

rule (selector, obj) {
return this.words(cssRule(selector, obj))
return this.addText(cssRule(selector, obj))
}
}


+ 1
- 3
src/main.js View File

@@ -30,7 +30,7 @@ import Morphable, {
TransformBag,
makeMorphable,
registerMorphableType
} from './types/Morphable.js'
} from './animation/Morphable.js'
import Path from './elements/Path.js'
import PathArray from './types/PathArray.js'
import Pattern from './elements/Pattern.js'
@@ -85,7 +85,6 @@ export { default as PointArray } from './types/PointArray.js'
export { default as List } from './types/List.js'

/* Elements */
export { default as Bare } from './elements/Bare.js'
export { default as Circle } from './elements/Circle.js'
export { default as ClipPath } from './elements/ClipPath.js'
export { default as Container } from './elements/Container.js'
@@ -95,7 +94,6 @@ export { default as Element } from './elements/Element.js'
export { default as Ellipse } from './elements/Ellipse.js'
export { default as Gradient } from './elements/Gradient.js'
export { default as G } from './elements/G.js'
export { default as HtmlNode } from './elements/HtmlNode.js'
export { default as A } from './elements/A.js'
export { default as Image } from './elements/Image.js'
export { default as Line } from './elements/Line.js'

+ 4
- 7
src/utils/adopter.js View File

@@ -50,19 +50,16 @@ export function adopt (node) {
// make sure a node isn't already adopted
if (node.instance instanceof Base) return node.instance

if (!(node instanceof globals.window.SVGElement)) {
return new elements.HtmlNode(node)
}

// initialize variables
var className = capitalize(node.nodeName)

// Make sure that gradients are adopted correctly
if (className === 'LinearGradient' || className === 'RadialGradient') {
className = 'Gradient'
}

if (!elements[className]) {
className = 'Bare'
// Fallback to Dom if element is not known
} else if (!elements[className]) {
className = 'Dom'
}

return new elements[className](node)

Loading…
Cancel
Save