Skip to content

Commit 7244133

Browse files
Merge pull request #914 from sketch-hq/feature/50732
merging SketchAPI from Sketch repo
2 parents 8f6ebca + 2cc0eeb commit 7244133

File tree

7 files changed

+119
-115
lines changed

7 files changed

+119
-115
lines changed

Source/dom/layers/SymbolInstance.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class SymbolInstance extends StyledLayer {
5252
return this
5353
}
5454
const wrappedOverride = wrapObject(override)
55-
const overridePoint = wrappedOverride.sketchObject.overridePoint()
55+
const overridePoint = wrappedOverride.sketchObject
5656
if (wrappedOverride.property === 'image') {
5757
this._object.setValue_forOverridePoint(
5858
ImageData.from(value).sketchObject,
@@ -148,15 +148,13 @@ SymbolInstance.define('master', {
148148
SymbolInstance.define('overrides', {
149149
get() {
150150
// undefined when immutable
151-
if (!this._object.availableOverrides) {
151+
if (!this._object.overridePoints) {
152152
return undefined
153153
}
154-
const overrides = toArray(
155-
MSAvailableOverride.flattenAvailableOverrides(
156-
this._object.availableOverrides()
157-
)
158-
)
159154

155+
this._object.ensureDetachHasUpdated()
156+
157+
const overrides = toArray(this._object.overridePoints())
160158
return overrides.map((o) => {
161159
const wrapped = Override.fromNative(o)
162160
Object.defineProperty(wrapped, '__symbolInstance', {

Source/dom/layers/SymbolMaster.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,12 @@ SymbolMaster.define('symbolId', {
142142

143143
SymbolMaster.define('overrides', {
144144
get() {
145-
if (!this._object.availableOverrides) {
146-
return undefined
147-
}
148-
149-
const overrides = toArray(
150-
MSAvailableOverride.flattenAvailableOverrides(
151-
this._object.availableOverrides()
152-
)
153-
)
145+
if (!this._object.overridePoints) {
146+
return undefined
147+
}
148+
149+
this._object.ensureDetachHasUpdated()
150+
const overrides = toArray(this._object.overridePoints())
154151

155152
return overrides.map((o) => {
156153
const wrapped = Override.fromNative(o)

Source/dom/layers/__tests__/SymbolInstance.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ test('should detach an instance', (_context, document) => {
5959
symbolId: master.symbolId,
6060
parent: document.selectedPage,
6161
})
62+
instance.sketchObject.ensureDetachHasUpdated()
6263
expect(instance.type).toBe('SymbolInstance')
6364

6465
const group = instance.detach()
@@ -72,6 +73,7 @@ test('should detach an instance recursively', (_context, document) => {
7273
symbolId: master.symbolId,
7374
parent: document.selectedPage,
7475
})
76+
instance.sketchObject.ensureDetachHasUpdated()
7577
expect(instance.type).toBe('SymbolInstance')
7678

7779
const group = instance.detach({ recursively: true })

Source/dom/layers/__tests__/SymbolMaster.test.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* globals expect, test */
22
/* eslint-disable no-param-reassign */
3-
import { SymbolMaster, Text, Artboard } from '../..'
3+
import { SymbolInstance, SymbolMaster, Text, Artboard } from '../..'
44
import { createSymbolMaster, canBeLogged } from '../../../test-utils'
55

66
test('should create a symbol master from an artboard', (_context, document) => {
@@ -66,7 +66,8 @@ test('should create a symbol master with a nested symbol', (_context, document)
6666

6767
// add the instance to the page
6868
document.selectedPage.layers = document.selectedPage.layers.concat(instance)
69-
expect(instance.overrides.length).toBe(13)
69+
expect(instance.overrides.length).toBe(14)
70+
canBeLogged(instance, SymbolInstance)
7071
const result0 = {
7172
type: 'Override',
7273
id: `${text2.id}_stringValue`,
@@ -96,7 +97,7 @@ test('should create a symbol master with a nested symbol', (_context, document)
9697
}
9798
delete result1.affectedLayer.overrides
9899
delete result1.affectedLayer.selected
99-
result1.affectedLayer.style = instance.overrides[6].affectedLayer.style.toJSON()
100+
result1.affectedLayer.style = instance.overrides[7].affectedLayer.style.toJSON()
100101
const result2 = {
101102
type: 'Override',
102103
id: `${nestedInstance.id}/${text.id}_stringValue`,
@@ -110,10 +111,10 @@ test('should create a symbol master with a nested symbol', (_context, document)
110111
selected: false,
111112
}
112113
delete result2.affectedLayer.selected
113-
result2.affectedLayer.style = instance.overrides[7].affectedLayer.style.toJSON()
114+
result2.affectedLayer.style = instance.overrides[8].affectedLayer.style.toJSON()
114115
expect(instance.overrides[0].toJSON()).toEqual(result0)
115-
expect(instance.overrides[6].toJSON()).toEqual(result1)
116-
expect(instance.overrides[7].toJSON()).toEqual(result2)
116+
expect(instance.overrides[7].toJSON()).toEqual(result1)
117+
expect(instance.overrides[8].toJSON()).toEqual(result2)
117118
})
118119

119120
test('should have overrides', (_context, document) => {
@@ -131,6 +132,7 @@ test('should have overrides', (_context, document) => {
131132
isDefault: true,
132133
editable: true,
133134
affectedLayer: text.toJSON(),
135+
selected: false,
134136
}
135137
delete result.affectedLayer.selected
136138
result.affectedLayer.style = master.overrides[0].affectedLayer.style.toJSON()

Source/dom/models/Override.js

Lines changed: 89 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,120 @@
1-
import { toArray } from 'util'
21
import { DefinedPropertiesKey, WrappedObject } from '../WrappedObject'
32
import { Types } from '../enums'
43
import { Factory } from '../Factory'
54
import { ImageData } from './ImageData'
65
import { wrapNativeObject } from '../wrapNativeObject'
76
import { Rectangle } from './Rectangle'
87

9-
/**
10-
* An MSAvailableOverride. This is not exposed, only used by SymbolInstance
11-
*/
128
export class Override extends WrappedObject {
13-
_findRepresentation() {
9+
// Returns any override directly set on the symbol instance or null if none is set or this is an override point on a symbol source
10+
getValueSetOnInstance() {
1411
if (!this.__symbolInstance) {
15-
return undefined
12+
return null
13+
}
14+
var overrideValues = this.__symbolInstance.sketchObject.overrideValues()
15+
for (var i = 0; i < overrideValues.length; i++) {
16+
if (
17+
overrideValues[i].overridePath().isEqual(this._object.overridePath())
18+
) {
19+
return overrideValues[i].value()
20+
}
1621
}
17-
this.__symbolInstance.sketchObject.ensureDetachHasUpdated()
18-
return toArray(
19-
this.__symbolInstance.sketchObject.overrideContainer().flattenedChildren()
20-
).find((x) => x.availableOverride().overridePoint().fullPath().isEqual(this.sketchObject.overridePoint().fullPath()))
22+
return null
2123
}
2224

23-
getFrame() {
24-
const representation = this._findRepresentation()
25-
if (!representation) {
26-
return undefined
25+
// Returns the current value of the override point. This is the value set on the layer in the detached version of the symbol. It may be
26+
// out-of-date if the detached symbol hasn't yet updated.
27+
getResolvedValueOnDetachedSymbol() {
28+
return this.affectedLayer.sketchObject.valueForOverrideAttribute(
29+
this.property
30+
)
31+
}
32+
33+
// Returns the value the override point will have if there is no override set on this instance.
34+
getDefaultValue() {
35+
if (!this.__symbolInstance) {
36+
return this.getResolvedValueOnDetachedSymbol()
2737
}
28-
const path = representation.pathInInstance()
29-
return new Rectangle(CGPathGetBoundingBox(path))
38+
return this.__symbolInstance.sketchObject.defaultValueForOverridePoint(
39+
this._object
40+
)
41+
}
42+
43+
// Returns a SelectionItem representing this override point
44+
selectionItem() {
45+
if (this.__symbolInstance) {
46+
return this.__symbolInstance.sketchObject.selectionItemForOverridePoint(
47+
this.sketchObject
48+
)
49+
}
50+
if (this.__symbolMaster) {
51+
return this.__symbolMaster.sketchObject.selectionItemForOverridePoint(
52+
this.sketchObject
53+
)
54+
}
55+
return null
3056
}
31-
}
3257

58+
getOwningPage() {
59+
if (this.__symbolInstance) {
60+
return this.__symbolInstance.sketchObject.parentPage()
61+
}
62+
if (this.__symbolMaster) {
63+
return this.__symbolMaster.sketchObject.parentPage()
64+
}
65+
return null
66+
}
67+
68+
getFrame() {
69+
return new Rectangle(this._object.layer().frame().rect())
70+
}
71+
}
3372
Override.type = Types.Override
3473
Override[DefinedPropertiesKey] = { ...WrappedObject[DefinedPropertiesKey] }
35-
Factory.registerClass(Override, MSAvailableOverride)
74+
Factory.registerClass(Override, MSOverridePoint)
3675

3776
Override.define('path', {
3877
get() {
39-
return String(this._object.overridePoint().path())
78+
return String(this._object.path())
4079
},
4180
})
4281

4382
Override.define('property', {
4483
get() {
45-
return String(this._object.overridePoint().attributeName())
84+
return String(this._object.attributeName())
4685
},
4786
})
4887

4988
Override.define('affectedLayer', {
5089
get() {
51-
return wrapNativeObject(this._object.affectedLayer())
90+
var layer = this._object.layer()
91+
if (layer.instance) {
92+
layer = layer.instance()
93+
}
94+
return wrapNativeObject(layer)
5295
},
5396
})
5497

5598
Override.define('id', {
5699
exportable: true,
57100
importable: false,
58101
get() {
59-
return String(this._object.overridePoint().name())
102+
return String(this._object.name())
60103
},
61104
})
62105

63106
Override.define('symbolOverride', {
64107
get() {
65-
return Boolean(this._object.overridePoint().isSymbolOverride())
108+
return Boolean(this._object.isSymbolOverride())
66109
},
67110
})
68111

69112
Override.define('value', {
70113
get() {
71-
const value = this._object.currentValue()
114+
var value = this.getValueSetOnInstance()
115+
if (!value) {
116+
value = this.getResolvedValueOnDetachedSymbol()
117+
}
72118
if (this.property === 'image') {
73119
return ImageData.fromNative(value)
74120
}
@@ -78,9 +124,9 @@ Override.define('value', {
78124
Object.keys(value).forEach((name) => {
79125
map[name] = value[name]
80126
})
81-
return map
127+
return map
82128
}
83-
return String(this._object.currentValue())
129+
return String(value)
84130
},
85131
set(value) {
86132
// __symbolInstance is set when building the Override
@@ -93,45 +139,30 @@ Override.define('value', {
93139

94140
Override.define('isDefault', {
95141
get() {
96-
return !this._object.hasOverride()
142+
return this.getValueSetOnInstance() == null
97143
},
98144
})
99145

100146
Override.define('editable', {
101147
get() {
102-
var overrides
103148
var master
104149
if (typeof this.__symbolMaster !== 'undefined') {
105150
master = this.__symbolMaster.sketchObject
106-
overrides = master.overridePoints
107151
} else if (typeof this.__symbolInstance !== 'undefined') {
108152
var masterGetter = this.__symbolInstance.sketchObject.symbolMaster
109153
if (masterGetter !== 'undefined') {
110154
master = masterGetter()
111155
}
112-
overrides = this.__symbolInstance.sketchObject.overridePoints
113-
}
114-
115-
if (typeof overrides == 'undefined') {
116-
// Can't get the override points - maybe this is an immutable?
117-
return false
118156
}
157+
119158
if (typeof master == 'undefined') {
120159
throw new Error('Unable to find the symbol source for this override')
121160
}
122-
123-
var point
124-
overrides().forEach((o) => {
125-
if (o.fullPath().isEqual(this._object.overridePoint().fullPath())) {
126-
point = o
127-
}
128-
})
129-
130-
if (typeof point == 'undefined') {
131-
return false
132-
}
133-
134-
if (master.allowsOverrides() && master.isOverridePointEditable(point) && point.isConfigurable()) {
161+
if (
162+
master.allowsOverrides() &&
163+
master.isOverridePointEditable(this._object) &&
164+
this._object.isConfigurable()
165+
) {
135166
return true
136167
} else {
137168
return false
@@ -143,60 +174,33 @@ Override.define('editable', {
143174
throw new Error('Can only set `editable` for a symbol master')
144175
}
145176
this.__symbolMaster.sketchObject.setOverridePoint_editable(
146-
this._object.overridePoint(),
177+
this._object,
147178
editable
148179
)
149180
},
150181
})
151182

152183
Override.define('selected', {
153184
get() {
154-
// __symbolInstance is set when building the Override
155-
if (!this.__symbolInstance) {
156-
return undefined
157-
}
158-
159-
const representation = this._findRepresentation()
160-
161-
if (!representation) {
162-
return false
185+
let item = this.selectionItem()
186+
if (this.getOwningPage().selection().isItemSelected(item)) {
187+
return true
163188
}
164-
165-
return Boolean(Number(representation.isSelected()))
189+
return false
166190
},
167191
set(selected) {
168-
// __symbolInstance is set when building the Override
169-
if (!this.__symbolInstance) {
170-
throw new Error('Can only set `selected` for a symbol instance')
171-
}
172-
173-
const documentData =
174-
this.__symbolInstance.sketchObject.documentData &&
175-
this.__symbolInstance.sketchObject.documentData()
176-
if (!documentData) {
177-
return
178-
}
179-
180-
const representation = this._findRepresentation()
181-
182-
if (!representation) {
183-
return
184-
}
185-
186-
var selectionItem = representation.selectionItem()
187-
if (!selectionItem) {
192+
let item = this.selectionItem()
193+
if (!item) {
188194
return
189195
}
190-
191-
var page = this.__symbolInstance.sketchObject.parentPage()
196+
let page = this.getOwningPage()
192197
if (!page) {
193198
return
194199
}
195-
196200
if (selected) {
197-
page.changeSelectionByAddingItems_extendExisting([selectionItem], true)
201+
page.changeSelectionByAddingItems_extendExisting([item], true)
198202
} else {
199-
page.changeSelectionByRemovingItems([selectionItem])
203+
page.changeSelectionByRemovingItems([item])
200204
}
201205
},
202206
})

0 commit comments

Comments
 (0)