Skip to content
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

Symbol instances #183

Merged
merged 6 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 57 additions & 16 deletions packages/generator-sketch/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const {
Sketch,
Page,
Rect,
Style,
Artboard,
SharedStyle,
SymbolMaster,
Expand Down Expand Up @@ -38,26 +39,62 @@ const symbolMaster = (args) => {
// maxSize: 0,
// minSize: 0
// }
return symbol
return symbol;
};

const symbols = []
const excludeKeys = new Set(['_class', 'do_objectID', 'name', 'text']);
// Set instance frame size and overrides
function fillInstance(instance, symbol, json, objectID = '') {
const keys = Object.keys(json);
for (let i = 0 ; i < keys.length; i++) {
const key = keys[i];
const symbolValue = symbol[key];
const jsonValue = json[key];
if (key === 'do_objectID') {
objectID = symbolValue;
}
if (Array.isArray(jsonValue)) {
jsonValue.forEach((nestedJson, i) => fillInstance(instance, symbolValue[i], nestedJson, objectID));
} else if (!excludeKeys.has(key) && typeof symbolValue === 'string' && symbolValue !== jsonValue) {
console.log(instance.name, instance.do_objectID, '-- override', key, ':', symbolValue, '=>', jsonValue);
const override = {
"_class": "overrideValue",
"overrideName": `${objectID}_${key}Value`,
"value": jsonValue
};
instance.overrideValues.push(override);
} else if (typeof symbolValue === 'object') {
fillInstance(instance, symbolValue, jsonValue, objectID);
}
}
}

const symbols = new Map();

function enhanceJson(json) {
let enhanced = {};
Object.keys(json).forEach((key) => {
if (Array.isArray(json[key])) {
enhanced[key] = json[key].map(nestedJson => enhanceJson(nestedJson))
} else {
if (key === '_class' && json[key] === 'group' && json.isSymbol === true) {
const symbolExists = symbols.filter(s => s.name === json.name)[0]
const symbol = symbolExists ? symbolExists : symbolMaster({...json, id: uuid()})
!symbolExists && symbols.push(symbol)
return enhanced = symbol.createInstance({name: json.name});
const keys = Object.keys(json);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const value = json[key];
if (Array.isArray(value)) {
enhanced[key] = value.map(nestedJson => enhanceJson(nestedJson))
} else if (key === '_class' && value === 'group' && json.isSymbol === true) {
let symbol = symbols.get(json.name);
if (!symbol) {
const args = {...json};
symbol = symbolMaster(args);
symbols.set(json.name, symbol);
}
return enhanced[key] = json[key]
const instance = symbol.createInstance({name: json.name});
instance.frame = new Rect(json.frame);
instance.style = new Style(json.style);
fillInstance(instance, symbol, json);
return instance;
} else {
enhanced[key] = value
}
})
}
return enhanced;
}

Expand All @@ -77,10 +114,14 @@ const artboardComponents = new Artboard({
}
});

fs.writeFileSync('./debug.json', JSON.stringify(enhanceJson(json), null, 4))
const enhanced = enhanceJson(json);
fs.writeFileSync('./debug.json', JSON.stringify(enhanced, null, 4))

enhanceJson(json).layers.forEach(layer => artboardComponents.addLayer(layer));
symbols.forEach(symbol => symbolsPage.addLayer(symbol));
enhanced.layers.forEach(layer => artboardComponents.addLayer(layer));
for (const symbol of symbols.values()) {
symbolsPage.addLayer(symbol);
}
// console.log(JSON.stringify(symbolsPage, null, 4));

componentsPage.addArtboard(artboardComponents);
sketch.addPage(symbolsPage);
Expand Down
2 changes: 1 addition & 1 deletion packages/generator-sketch/src/inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const URL = require('url').URL;
const DEBUG = true
const DEBUG = false

const url = 'http://localhost:3334/';
let urlObj = null;
Expand Down
28 changes: 2 additions & 26 deletions packages/html-to-sketch/html2asketch/helpers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
import {FillType} from 'sketch-constants';
const normalizeColor = require('normalize-css-color');

const lut: any[] = [];

for (let i = 0; i < 256; i += 1) {
lut[i] = (i < 16 ? '0' : '') + i.toString(16);
}

// http://stackoverflow.com/a/21963136
function e7() {
const d0 = (Math.random() * 0xffffffff) | 0;
const d1 = (Math.random() * 0xffffffff) | 0;
const d2 = (Math.random() * 0xffffffff) | 0;
const d3 = (Math.random() * 0xffffffff) | 0;

return `${lut[d0 & 0xff] +
lut[(d0 >> 8) & 0xff] +
lut[(d0 >> 16) & 0xff] +
lut[(d0 >> 24) & 0xff]}-${lut[d1 & 0xff]}${lut[(d1 >> 8) & 0xff]}-${lut[
((d1 >> 16) & 0x0f) | 0x40
]}${lut[(d1 >> 24) & 0xff]}-${lut[(d2 & 0x3f) | 0x80]}${lut[
(d2 >> 8) & 0xff
]}-${lut[(d2 >> 16) & 0xff]}${lut[(d2 >> 24) & 0xff]}${lut[d3 & 0xff]}${lut[
(d3 >> 8) & 0xff
]}${lut[(d3 >> 16) & 0xff]}${lut[(d3 >> 24) & 0xff]}`;
}
const uuid = require('uuid').v4;

export function generateID() {
return e7();
return uuid().toUpperCase();
}

const safeToLower = (input: any) => {
Expand Down
72 changes: 41 additions & 31 deletions packages/html-to-sketch/html2asketch/model/textAttributedString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,62 @@ import { getFirstFont, makeColorFromCSS } from "../helpers/utils";
// Sketch is capable of.

class TextAttributedString {
_text: any;
_fontSize: any;
_fontFamily: any;
_color: any;
_text: any;
_fontSize: any;
_fontFamily: any;
_color: any;
_alignment: 0 | 1 | 2 | 3;

constructor({
text,
text,
color,
fontSize,
fontFamily,
skipSystemFonts,
}: any) {
alignment
}: {
text: string;
color: string;
fontSize: number;
fontFamily: string;
skipSystemFonts: boolean;
alignment: 0 | 1 | 2 | 3;
}) {
this._text = text;
this._color = color;
this._fontSize = fontSize;
this._fontFamily = getFirstFont(fontFamily, skipSystemFonts);
this._alignment = alignment;
}

toJSON() {
const result: any = {
_class: "attributedString",
string: this._text,
attributes: [
{
_class: "stringAttribute",
location: 0,
length: this._text.length,
attributes: {
MSAttributedStringFontAttribute: {
_class: "fontDescriptor",
attributes: {
name: this._fontFamily,
size: this._fontSize
}
},
MSAttributedStringColorAttribute: makeColorFromCSS(this._color),
kerning: 0,
textStyleVerticalAlignmentKey: 0,
paragraphStyle: {
_class: "paragraphStyle",
alignment: 0
}
}
}
]
}
string: this._text,
attributes: [
{
_class: "stringAttribute",
location: 0,
length: this._text.length,
attributes: {
MSAttributedStringFontAttribute: {
_class: "fontDescriptor",
attributes: {
name: this._fontFamily,
size: this._fontSize
}
},
MSAttributedStringColorAttribute: makeColorFromCSS(this._color),
kerning: 0,
textStyleVerticalAlignmentKey: 0,
paragraphStyle: {
_class: "paragraphStyle",
alignment: this._alignment
}
}
}
]
};

return result;
}
Expand Down
12 changes: 12 additions & 0 deletions packages/html-to-sketch/html2asketch/nodeToSketchLayers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ const DEFAULT_VALUES = {
boxShadow: 'none',
};

const ALIGNMENTS = {
left: 0,
right: 1,
center: 2,
justify: 3
};

function hasOnlyDefaultStyles(styles: object) {
return Object.keys(DEFAULT_VALUES).every(key => {
const defaultValue = DEFAULT_VALUES[key];
Expand Down Expand Up @@ -75,6 +82,7 @@ export default function nodeToSketchLayers(node: HTMLElement, options: any) {
borderTopRightRadius,
borderBottomLeftRadius,
borderBottomRightRadius,
textAlign,
fontFamily,
fontSize,
lineHeight,
Expand Down Expand Up @@ -273,11 +281,15 @@ export default function nodeToSketchLayers(node: HTMLElement, options: any) {
skipSystemFonts: options && options.skipSystemFonts,
});

const alignment = ALIGNMENTS[textAlign] || 0;

const textAttributedString = (text: string) => new TextAttributedString({
text,
fontFamily,
fontSize: parseInt(fontSize, 10),
skipSystemFonts: options && options.skipSystemFonts,
color,
alignment
})

const rangeHelper = document.createRange();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ const getAssignedNodes = (node: HTMLElement) => {
}

export default function nodeTreeToSketchGroup(node: HTMLElement, options: any) {
const bcr = node.getBoundingClientRect();
let bcr = node.getBoundingClientRect();
if (bcr.width === 0 && bcr.height === 0) {
// Possibly broken getBoundingClientRect, let's try selecting the node.
const rangeHelper = document.createRange();
rangeHelper.selectNodeContents(node);
bcr = rangeHelper.getBoundingClientRect();
}
const {left, top} = bcr;
const width = bcr.right - bcr.left;
const height = bcr.bottom - bcr.top;
Expand Down
3 changes: 2 additions & 1 deletion packages/html-to-sketch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
},
"dependencies": {
"normalize-css-color": "^1.0.2",
"sketch-constants": "^1.1.0"
"sketch-constants": "^1.1.0",
"uuid": "^3.4.0"
},
"main": "build/index"
}