New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for symbols #78

Merged
merged 32 commits into from Jan 23, 2018
Commits
Jump to file or symbol
Failed to load files and symbols.
+1,307 −211
Diff settings

Always

Just for now

View
@@ -43,6 +43,12 @@ globals:
MSDefaultStyle: false
MSLayer: false
MSDocumentData: false
MSSymbolMaster: false
MSSymbolInstance: false
MSAvailableOverride: false
NSData: false
NSDataBase64DecodingIgnoreUnknownCharacters: false
MSDocument: false
rules:
###########
View
@@ -3,9 +3,11 @@ export const Factory = {
_nativeToBox: {},
_typeToNative: {},
registerClass(boxedClass, nativeClass) {
this._typeToBox[boxedClass.type] = boxedClass
if (!this._typeToBox[boxedClass.type]) {
this._typeToBox[boxedClass.type] = boxedClass
this._typeToNative[boxedClass.type] = nativeClass
}
this._nativeToBox[String(nativeClass.class())] = boxedClass
this._typeToNative[boxedClass.type] = nativeClass
},
create(type, props) {
const _type = type && type.type ? type.type : type
View
@@ -74,4 +74,13 @@ export class Rectangle {
toString() {
return `{${this.x}, ${this.y}, ${this.width}, ${this.height}}`
}
toJSON() {
return {
x: this.x,
y: this.y,
width: this.width,
height: this.height,
}
}
}
View
@@ -1,5 +1,6 @@
import { WrappedObject, DefinedPropertiesKey } from './WrappedObject'
import { toArray } from './utils'
import { Types } from './enums'
export const FillType = {
color: 0, // A solid fill/border.
@@ -59,6 +60,7 @@ export class Style extends WrappedObject {
}
}
Style.type = Types.Style
Style[DefinedPropertiesKey] = { ...WrappedObject[DefinedPropertiesKey] }
Style.FillType = FillType
View
@@ -7,20 +7,46 @@ export const DefinedPropertiesKey = '_DefinedPropertiesKey'
export class WrappedObject {
constructor(options) {
this._object = options.sketchObject
this.type = this.constructor.type
const propertyList = this.constructor[DefinedPropertiesKey]
Object.keys(options).forEach(k => {
if (!propertyList[k]) {
log(`no idea what to do with "${k}" in ${this.type}`)
return
}
if (!propertyList[k].importable) {
return
}
this[k] = options[k]
Object.defineProperty(this, 'type', {
enumerable: true,
value: this.constructor.type,
})
this.update(options)
}
update(options = {}) {
const propertyList = this.constructor[DefinedPropertiesKey]
Object.keys(options)
.sort((a, b) => {
if (
propertyList[a] &&
propertyList[a].depends &&
propertyList[a].depends === b
) {
return 1
} else if (
propertyList[b] &&
propertyList[b].depends &&
propertyList[b].depends === a
) {
return -1
}
return 0
})
.forEach(k => {
if (!propertyList[k]) {
log(`no idea what to do with "${k}" in ${this.type}`)
return
}
if (!propertyList[k].importable) {
return
}
this[k] = options[k]
})
}
/**
@@ -34,22 +60,6 @@ export class WrappedObject {
})
}
update(json) {
const propertyList = this.constructor[DefinedPropertiesKey]
Object.keys(json).forEach(k => {
if (!propertyList[k]) {
log(`no idea what to do with "${k}" in ${this.type}`)
return
}
if (!propertyList[k].importable) {
return
}
this[k] = json[k]
})
}
toJSON() {
const propertyList = this.constructor[DefinedPropertiesKey]
@@ -59,7 +69,19 @@ export class WrappedObject {
if (!propertyList[k].exportable) {
return
}
json[k] = this[k]
const value = this[k]
if (value && Array.isArray(value)) {
json[k] = value.map(x => {
if (x && typeof x.toJSON === 'function') {
return x.toJSON()
}
return x
})
} else if (value && typeof value.toJSON === 'function') {
json[k] = value.toJSON()
} else {
json[k] = value
}
})
return json
@@ -140,6 +162,14 @@ export class WrappedObject {
WrappedObject[DefinedPropertiesKey] = {}
WrappedObject.define('type', {
exportable: true,
importable: false,
get() {
return this.type
},
})
WrappedObject.define('id', {
exportable: true,
importable: false,
@@ -3,6 +3,8 @@ import { Rectangle } from '../Rectangle'
test('should create a rectangle', () => {
const r = new Rectangle(1, 2, 3, 4)
// check that a rectangle can be logged
log(r)
expect(r.x).toBe(1)
expect(r.y).toBe(2)
expect(r.width).toBe(3)
@@ -15,6 +15,8 @@ test('should clear the selection', (context, document) => {
selected: true,
})
const selection = document.selectedLayers
// check that a selection can be logged
log(selection)
expect(group.selected).toBe(true)
expect(selection.isEmpty).toBe(false)
selection.clear()
@@ -5,6 +5,8 @@ import { Style } from '../Style'
test('should set the borders', () => {
// setting the borders after creation
const style = new Style()
// check that a style can be logged
log(style)
style.borders = ['#11223344', '#1234']
expect(style.sketchObject.borders().count()).toBe(2)
View
@@ -16,8 +16,7 @@ export function message(text, document) {
.orderedDocuments()
.firstObject()
.showMessage(text)
}
if (isNativeObject(document)) {
} else if (isNativeObject(document)) {
document.showMessage(text)
} else {
document.sketchObject.showMessage(text)
@@ -28,24 +28,6 @@ export class Document extends WrappedObject {
super(document)
}
/**
* The layers that the user has selected in the currently selected page.
*
* @return {Selection} A selection object representing the layers that the user has selected in the currently selected page.
*/
get selectedLayers() {
return new Selection(this.selectedPage)
}
/**
* The current page that the user has selected.
*
* @return {Page} A page object representing the page that the user is currently viewing.
*/
get selectedPage() {
return Page.fromNative(this._object.currentPage())
}
/**
* Returns a list of the pages in this document.
*
@@ -62,7 +44,7 @@ export class Document extends WrappedObject {
* @return {Layer} A layer object, if one was found.
*/
getLayerWithID(layerId) {
const layer = this._object.documentData().layerWithID_(layerId)
const layer = this._object.documentData().layerWithID(layerId)

This comment has been minimized.

@bomberstudios

bomberstudios Jan 18, 2018

Collaborator

This block of code is repeated verbatim on lines 83:87… maybe an opportunity to refactor it into a method?

@bomberstudios

bomberstudios Jan 18, 2018

Collaborator

This block of code is repeated verbatim on lines 83:87… maybe an opportunity to refactor it into a method?

This comment has been minimized.

@mathieudutour

mathieudutour Jan 18, 2018

Contributor

There is a comment from Sam explaining why :)

@mathieudutour

mathieudutour Jan 18, 2018

Contributor

There is a comment from Sam explaining why :)

This comment has been minimized.

@bomberstudios

bomberstudios Jan 19, 2018

Collaborator

I missed that, it now makes sense. Thanks! : )

@bomberstudios

bomberstudios Jan 19, 2018

Collaborator

I missed that, it now makes sense. Thanks! : )

if (layer) {
return wrapObject(layer)
}
@@ -80,13 +62,26 @@ export class Document extends WrappedObject {
// That might not always be true though, which is why the JS API splits
// them into separate functions.
const layer = this._object.documentData().layerWithID_(layerName)
const layer = this._object.documentData().layerWithID(layerName)
if (layer) {
return wrapObject(layer)
}
return undefined
}
/**
* Find the first symbol master in this document which has the given id.
*
* @return {SymbolMaster} A symbol master object, if one was found.
*/
getSymbolMasterWithID(symbolId) {
const symbol = this._object.documentData().symbolWithID(symbolId)
if (symbol) {
return wrapObject(symbol)
}
return undefined
}
/**
* Center the view of the document window on a given layer.
*
@@ -101,3 +96,48 @@ export class Document extends WrappedObject {
Document.type = Types.Document
Document[DefinedPropertiesKey] = { ...WrappedObject[DefinedPropertiesKey] }
Factory.registerClass(Document, MSDocumentData)
// also register MSDocument if it exists
if (typeof MSDocument !== 'undefined') {
Factory.registerClass(Document, MSDocument)
}
// override getting the id to make sure it's fine if we have an MSDocument
Document.define('id', {
exportable: true,
importable: false,
get() {
if (!this._object.objectID) {
return String(this._object.documentData().objectID())
}
return String(this._object.objectID())
},
})
/**
* The layers that the user has selected in the currently selected page.
*
* @return {Selection} A selection object representing the layers that the user has selected in the currently selected page.
*/
Document.define('selectedLayers', {
enumerable: false,
exportable: false,
importable: false,
get() {
return new Selection(this.selectedPage)
},
})
/**
* The current page that the user has selected.
*
* @return {Page} A page object representing the page that the user is currently viewing.
*/
Document.define('selectedPage', {
enumerable: false,
exportable: false,
importable: false,
get() {
return Page.fromNative(this._object.currentPage())
},
})
@@ -56,7 +56,6 @@ Group[DefinedPropertiesKey] = { ...Layer[DefinedPropertiesKey] }
Factory.registerClass(Group, MSLayerGroup)
Group.define('layers', {
exportable: false,
get() {
return toArray(this._object.layers()).map(wrapNativeObject)
},
View
@@ -1,8 +1,10 @@
import { DefinedPropertiesKey } from '../WrappedObject'
import { Layer } from './Layer'
import { ImageData } from './ImageData'
import { Rectangle } from '../Rectangle'
import { Types } from '../enums'
import { Factory } from '../Factory'
import { wrapObject } from '../wrapNativeObject'
/**
* Represents an image layer.
@@ -33,22 +35,10 @@ Factory.registerClass(Image, MSBitmapLayer)
Image.define('image', {
get() {
// TODO: return something nice here
return this._object.image
return wrapObject(this._object.image())
},
set(image) {
let nsImage
if (typeof image === 'string') {
nsImage = NSImage.alloc().initByReferencingFile(image)
} else if (image.class && String(image.class()) === 'NSImage') {
nsImage = image
} else if (image.class && String(image.class()) === 'NSURL') {
nsImage = NSImage.alloc().initWithContentsOfURL_(image)
} else {
throw new Error('`image` needs to be a string')
}
const imageData = MSImageData.alloc().initWithImage(nsImage)
this._object.setImage(imageData)
const imageData = ImageData.from(image)
this._object.setImage(imageData.sketchObject)
},
})
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.