Browse Source

fix css, dont throw when screenCtm fails (fixes #968)

master
Ulrich-Matthias Schäfer 9 months ago
parent
commit
e70cdef7a5
6 changed files with 38 additions and 59 deletions
  1. 5
    0
      spec/spec/types/Matrix.js
  2. 0
    17
      spec/spec/utils/utils.js
  3. 4
    7
      src/modules/optional/css.js
  4. 18
    11
      src/types/Matrix.js
  5. 0
    7
      src/utils/utils.js
  6. 11
    17
      svg.js.d.ts

+ 5
- 0
spec/spec/types/Matrix.js View File

@@ -594,6 +594,11 @@ describe('Matrix.js', () => {
svg.screenCTM()
expect(spy).toHaveBeenCalled()
})

it('does not throw and returns identity matrix if element is not rendered', () => {
const canvas = SVG().viewbox(0, 0, 0, 0)
expect(canvas.screenCTM()).toEqual(new Matrix())
})
})
})
})

+ 0
- 17
spec/spec/utils/utils.js View File

@@ -5,7 +5,6 @@ import {
filter,
radians,
degrees,
camelCase,
unCamelCase,
capitalize,
proportionalSize,
@@ -81,22 +80,6 @@ describe('utils.js', function () {
})
})

describe('camelCase()', function () {
it('converts dash-case and PascalCase to camelCase', function () {
var dash1 = 'dash-1'
var dashTwo = 'dash-two'
var camelOne = 'camelOne'
var pascalOne = 'PascalOne'
var mixOne = 'mix-One'

expect(camelCase(dash1)).toBe('dash1')
expect(camelCase(dashTwo)).toBe('dashTwo')
expect(camelCase(camelOne)).toBe('camelone')
expect(camelCase(pascalOne)).toBe('pascalone')
expect(camelCase(mixOne)).toBe('mixOne')
})
})

describe('unCamelCase()', function () {
it('converts camelCase to dash-case', function () {
var dash1 = 'dash-1'

+ 4
- 7
src/modules/optional/css.js View File

@@ -1,9 +1,6 @@
import { camelCase } from '../../utils/utils.js'
import { isBlank } from '../core/regex.js'
import { registerMethods } from '../../utils/methods.js'

const camelCaseWithVars = (str) => (str.startsWith('--') ? str : camelCase(str))

// Dynamic style generator
export function css(style, val) {
const ret = {}
@@ -25,7 +22,7 @@ export function css(style, val) {
// get style properties as array
if (Array.isArray(style)) {
for (const name of style) {
const cased = camelCaseWithVars(name)
const cased = name
ret[name] = this.node.style.getPropertyValue(cased)
}
return ret
@@ -33,7 +30,7 @@ export function css(style, val) {

// get style for property
if (typeof style === 'string') {
return this.node.style.getPropertyValue(camelCaseWithVars(style))
return this.node.style.getPropertyValue(style)
}

// set styles in object
@@ -41,7 +38,7 @@ export function css(style, val) {
for (const name in style) {
// set empty string if null/undefined/'' was given
this.node.style.setProperty(
camelCaseWithVars(name),
name,
style[name] == null || isBlank.test(style[name]) ? '' : style[name]
)
}
@@ -51,7 +48,7 @@ export function css(style, val) {
// set style for property
if (arguments.length === 2) {
this.node.style.setProperty(
camelCaseWithVars(style),
style,
val == null || isBlank.test(val) ? '' : val
)
}

+ 18
- 11
src/types/Matrix.js View File

@@ -520,17 +520,24 @@ export function ctm() {
}

export function screenCTM() {
/* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537
This is needed because FF does not return the transformation matrix
for the inner coordinate system when getScreenCTM() is called on nested svgs.
However all other Browsers do that */
if (typeof this.isRoot === 'function' && !this.isRoot()) {
const rect = this.rect(1, 1)
const m = rect.node.getScreenCTM()
rect.remove()
return new Matrix(m)
}
return new Matrix(this.node.getScreenCTM())
try {
/* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537
This is needed because FF does not return the transformation matrix
for the inner coordinate system when getScreenCTM() is called on nested svgs.
However all other Browsers do that */
if (typeof this.isRoot === 'function' && !this.isRoot()) {
const rect = this.rect(1, 1)
const m = rect.node.getScreenCTM()
rect.remove()
return new Matrix(m)
}
return new Matrix(this.node.getScreenCTM())
} catch (e) {
console.warn(
`Cannot get CTM from SVG node ${this.node.nodeName}. Is the element rendered?`
)
return new Matrix()
}
}

register(Matrix, 'Matrix')

+ 0
- 7
src/utils/utils.js View File

@@ -36,13 +36,6 @@ export function degrees(r) {
return ((r * 180) / Math.PI) % 360
}

// Convert dash-separated-string to camelCase
export function camelCase(s) {
return s.toLowerCase().replace(/-(.)/g, function (m, g) {
return g.toUpperCase()
})
}

// Convert camel cased string to dash separated
export function unCamelCase(s) {
return s.replace(/([A-Z])/g, function (m, g) {

+ 11
- 17
svg.js.d.ts View File

@@ -1340,35 +1340,29 @@ declare module '@svgdotjs/svg.js' {
}

interface Sugar {
fill(): any
fill(): string
fill(fill: FillData): this
fill(color: string): this
fill(pattern: Element): this
fill(image: Image): this
stroke(): any
stroke(): string
stroke(stroke: StrokeData): this
stroke(color: string): this
matrix(): Matrix
matrix(
a?: number,
b?: number,
c?: number,
d?: number,
e?: number,
f?: number
): this
matrix(
mat: MatrixAlias,
b?: number,
c?: number,
d?: number,
e?: number,
f?: number
a: number,
b: number,
c: number,
d: number,
e: number,
f: number
): this
matrix(mat: MatrixAlias): this
rotate(degrees: number, cx?: number, cy?: number): this
skew(skewX?: number, skewY?: number, cx?: number, cy?: number): this
scale(scaleX?: number, scaleY?: number, cx?: number, cy?: number): this
translate(x: number, y: number): this
shear(lam: Matrix, cx: number, cy: number): this
shear(lam: number, cx: number, cy: number): this
relative(x: number, y: number): this
flip(direction?: string, around?: number): this
flip(around: number): this

Loading…
Cancel
Save