Skip to content

Commit

Permalink
Implementing copying of layers with id’s
Browse files Browse the repository at this point in the history
  • Loading branch information
nvh committed Jan 26, 2018
1 parent d9d5ef5 commit 0b25219
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
16 changes: 16 additions & 0 deletions framer/SVGLayer.coffee
Expand Up @@ -78,3 +78,19 @@ class exports.SVGLayer extends Layer
copy: ->
layer = @copySingle()
return layer

copySingle: ->
props = @props
if props.html? and props.svg?
delete props.svg
ids = Utils.getIdAttributesFromString(props.html)
html = props.html
for id in ids
uniqueId = Utils.getUniqueId(id)
if id isnt uniqueId
html = html.replace(///((id|xlink:href)=["'']\#?)#{id}(["'])///g, "$1#{uniqueId}$3")
html = html.replace(///(["'']url\(\#)#{id}(\)["'])///g, "$1#{uniqueId}$2")
props.html = html
copy = new @constructor(props)
copy.style = @style
copy
10 changes: 10 additions & 0 deletions framer/Utils.coffee
Expand Up @@ -1431,5 +1431,15 @@ Utils.getIdAttributesFromString = (string) ->
matches.push(id)
matches

Utils.getUniqueId = (prefix = 'id') ->
id = prefix
count = 1
existingElement = document.querySelector("[id='#{id}']")
while existingElement?
id = "#{prefix}#{count}"
existingElement = document.querySelector("[id='#{id}']")
return id



_.extend exports, Utils
62 changes: 59 additions & 3 deletions test/tests/SVGLayerTest.coffee
Expand Up @@ -37,15 +37,71 @@ describe "SVGLayer", ->
b.html.should.equal '<svg xmlns="http://www.w3.org/2000/svg" width="182" height="182"><path d="M 0 0 L 182 0 L 182 182 L 0 182 Z" name="Rectangle" style="-webkit-perspective: none; pointer-events: none; display: block; opacity: 1; overflow: visible; -webkit-transform-style: preserve-3d; -webkit-backface-visibility: visible; -webkit-perspective-origin-x: 50%; -webkit-perspective-origin-y: 50%;"></path></svg>'
b._elementHTML.should.not.be.equal a._elementHTML

# it "should change the id's to random id's"
it "should change the id's to random id's", ->
svgWithIds = """
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="85" height="74">
<g>
<defs>
<path d="M 42.5 0 L 54.99 22.033 L 82.92 25.566 L 62.71 42.717 L 67.481 66.934 L 42.5 55.5 L 17.519 66.934 L 22.29 42.717 L 2.08 25.566 L 30.01 22.033 Z" id="shape_id_M2JpFHsBN"></path>
<filter x="-14.9%" y="-19.7%" width="129.1%" height="138.8%" filterUnits="objectBoundingBox" id="shape_id_M2JpFHsBN_shadow_out">
<feOffset dx="0" dy="2" in="SourceAlpha" result="shape_id_M2JpFHsBN_outer_shadow0offset"></feOffset>
<feGaussianBlur stdDeviation="2.5" in="shape_id_M2JpFHsBN_outer_shadow0offset" result="shape_id_M2JpFHsBN_outer_shadow0blur"></feGaussianBlur>
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shape_id_M2JpFHsBN_outer_shadow0blur" result="shape_id_M2JpFHsBN_outer_shadow0matrix"></feColorMatrix>
</filter>
<filter x="-5.8%" y="-9.4%" width="111.1%" height="118.1%" filterUnits="objectBoundingBox" id="shape_id_M2JpFHsBN_shadow_inside">
<feGaussianBlur stdDeviation="2.5" in="SourceAlpha" result="shape_id_M2JpFHsBN_inside_shadow0blur"></feGaussianBlur>
<feOffset dx="0" dy="2" in="shape_id_M2JpFHsBN_inside_shadow0blur" result="shape_id_M2JpFHsBN_inside_shadow0offset"></feOffset>
<feComposite in="shape_id_M2JpFHsBN_inside_shadow0offset" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shape_id_M2JpFHsBN_inside_shadow0composite"></feComposite>
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shape_id_M2JpFHsBN_inside_shadow0composite" result="shape_id_M2JpFHsBN_inside_shadow0matrix"></feColorMatrix>
</filter>
</defs>
<g filter="url(#shape_id_M2JpFHsBN_shadow_out)">
<use stroke-width="1" stroke="black" fill="black" fill-opacity="1" stroke-opacity="1" xlink:href="#shape_id_M2JpFHsBN"></use>
</g>
<use xlink:href="#shape_id_M2JpFHsBN" fill="#CCC" stroke-opacity="0" id="transparent"></use>
<use fill="black" fill-opacity="1" filter="url(#shape_id_M2JpFHsBN_shadow_inside)" xlink:href="#shape_id_M2JpFHsBN"></use>
<use xlink:href="#shape_id_M2JpFHsBN" fill="transparent" stroke-width="1" stroke="#0AF" id="CCC"></use>
</g>
</svg>
"""
a = new SVGLayer
svg: svgWithIds
b = a.copy()
b.html.should.equal """
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="85" height="74">
<g>
<defs>
<path d="M 42.5 0 L 54.99 22.033 L 82.92 25.566 L 62.71 42.717 L 67.481 66.934 L 42.5 55.5 L 17.519 66.934 L 22.29 42.717 L 2.08 25.566 L 30.01 22.033 Z" id="shape_id_M2JpFHsBN1"></path>
<filter x="-14.9%" y="-19.7%" width="129.1%" height="138.8%" filterUnits="objectBoundingBox" id="shape_id_M2JpFHsBN_shadow_out1">
<feOffset dx="0" dy="2" in="SourceAlpha" result="shape_id_M2JpFHsBN_outer_shadow0offset"></feOffset>
<feGaussianBlur stdDeviation="2.5" in="shape_id_M2JpFHsBN_outer_shadow0offset" result="shape_id_M2JpFHsBN_outer_shadow0blur"></feGaussianBlur>
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shape_id_M2JpFHsBN_outer_shadow0blur" result="shape_id_M2JpFHsBN_outer_shadow0matrix"></feColorMatrix>
</filter>
<filter x="-5.8%" y="-9.4%" width="111.1%" height="118.1%" filterUnits="objectBoundingBox" id="shape_id_M2JpFHsBN_shadow_inside1">
<feGaussianBlur stdDeviation="2.5" in="SourceAlpha" result="shape_id_M2JpFHsBN_inside_shadow0blur"></feGaussianBlur>
<feOffset dx="0" dy="2" in="shape_id_M2JpFHsBN_inside_shadow0blur" result="shape_id_M2JpFHsBN_inside_shadow0offset"></feOffset>
<feComposite in="shape_id_M2JpFHsBN_inside_shadow0offset" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shape_id_M2JpFHsBN_inside_shadow0composite"></feComposite>
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shape_id_M2JpFHsBN_inside_shadow0composite" result="shape_id_M2JpFHsBN_inside_shadow0matrix"></feColorMatrix>
</filter>
</defs>
<g filter="url(#shape_id_M2JpFHsBN_shadow_out1)">
<use stroke-width="1" stroke="black" fill="black" fill-opacity="1" stroke-opacity="1" xlink:href="#shape_id_M2JpFHsBN1"></use>
</g>
<use xlink:href="#shape_id_M2JpFHsBN1" fill="#CCC" stroke-opacity="0" id="transparent1"></use>
<use fill="black" fill-opacity="1" filter="url(#shape_id_M2JpFHsBN_shadow_inside1)" xlink:href="#shape_id_M2JpFHsBN1"></use>
<use xlink:href="#shape_id_M2JpFHsBN1" fill="transparent" stroke-width="1" stroke="#0AF" id="CCC1"></use>
</g>
</svg>
"""
a.destroy()

it "should not copy SVGLayer that has ids", ->
it "should copy SVGLayer that has ids", ->
a = new SVGLayer
x: 123
y: 456
svg: '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path d="M 100 50 C 100 77.614 77.614 100 50 100 C 22.386 100 0 77.614 0 50 C 0 22.386 22.386 0 50 0" id="path" name="path" fill="transparent" stroke="#0AF"></path></svg>'
b = a.copy()
expect(b.html).to.equal ''
expect(b.html).to.equal '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path d="M 100 50 C 100 77.614 77.614 100 50 100 C 22.386 100 0 77.614 0 50 C 0 22.386 22.386 0 50 0" id="path1" name="path" fill="transparent" stroke="#0AF" style="-webkit-perspective: none; pointer-events: none; display: block; opacity: 1; overflow: visible; -webkit-transform-style: preserve-3d; -webkit-backface-visibility: visible; fill: rgba(0, 0, 0, 0); stroke: #00aaff; -webkit-perspective-origin-x: 50%; -webkit-perspective-origin-y: 50%;"></path></svg>'
a.destroy()

describe "initializing", ->
Expand Down

0 comments on commit 0b25219

Please sign in to comment.