-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathutils.js
210 lines (190 loc) · 6.15 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
const storage = require("uxp").storage;
const fs = storage.localFileSystem;
let data;
/**
* Downloads an image from the photoUrl and
* stores it in a temp file and returns the file
*
* @param {url} photoUrl
*/
async function downloadImage(photoUrl) {
const photoObj = await xhrBinary(photoUrl);
const tempFolder = await fs.getTemporaryFolder();
const tempFile = await tempFolder.createFile("tmp", { overwrite: true });
await tempFile.write(photoObj, { format: storage.formats.binary });
return tempFile;
}
/**
* Fetches a url with binary data and returns a promise
* which resolves with this data
*
* @param {url} url
*/
function xhrBinary(url) {
return new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
req.onload = () => {
if (req.status === 200) {
try {
const arr = new Uint8Array(req.response);
resolve(arr);
} catch (err) {
reject('Couldnt parse response. ${err.message}, ${req.response}');
}
} else {
reject('Request had an error: ${req.status}');
}
}
req.onerror = function() {
reject('Network Request failed. Please ensure you have internet connectivitiy.');
};
req.onabort = reject;
req.open('GET', url, true);
req.responseType = "arraybuffer";
req.send();
});
}
/**
* Converts a styles json to styles url parameter
* Copied from https://stackoverflow.com/questions/19115223/converting-google-maps-styles-array-to-google-static-maps-styles-string
*
* @param {string} jsonStr
* @return string
*/
function parseStyles(jsonStr) {
let json;
let result = [];
json = JSON.parse(jsonStr);
json.forEach((item) => {
let style = '';
if (item.stylers && item.stylers.length > 0) {
// add feature
if (item.hasOwnProperty('featureType')) {
style += 'feature:' + item.featureType + '|'
} else {
style += 'feature:all' + '|'
}
// add element
if (item.hasOwnProperty('elementType')) {
style += 'element:' + item.elementType + '|'
} else {
style += 'element:all' + '|'
}
// add stylers
item.stylers.forEach((styler) => {
const propName = Object.keys(styler)[0];
const propVal = styler[propName].toString().replace('#', '0x');
style += propName + ':' + propVal + '|';
});
}
result.push('style=' + encodeURIComponent(style));
});
return '&' + result.join('&');
}
/**
* Gets the dimensions of a node based on its type
*
* @returns {Object} Object containing width and height
*/
function getDimensions(node) {
let width, height;
switch(node.constructor.name) {
case "Rectangle":
case "Polygon":
width = node.width;
height = node.height;
break;
case "Ellipse":
width = node.radiusX * 2;
height = node.radiusY * 2;
break;
case "BooleanGroup": // Selecting arbitrary values for path and boolean group
case "Path":
width = 500;
height = 500;
break;
default:
throw "Not supported"
}
return {
width, height
}
}
/**
* A little helper class to make storing key-value-pairs (e.g. settings) for plugins for Adobe XD CC easier.
*/
class storageHelper {
/**
* Creates a data file if none was previously existent.
* @return {Promise<storage.File>} The data file
* @private
*/
static async init() {
let dataFolder = await fs.getDataFolder();
try {
let returnFile = await dataFolder.getEntry('storage.json');
data = JSON.parse((await returnFile.read({format: storage.formats.utf8})).toString());
return returnFile;
} catch (e) {
const file = await dataFolder.createEntry('storage.json', {type: storage.types.file, overwrite: true});
if (file.isFile) {
await file.write('{}', {append: false});
data = {};
return file;
} else {
throw new Error('Storage file storage.json was not a file.');
}
}
}
/**
* Retrieves a value from storage. Saves default value if none is set.
* @param {string} key The identifier
* @param {*} defaultValue The default value. Gets saved and returned if no value was previously set for the speciefied key.
* @return {Promise<*>} The value retrieved from storage. If none is saved, the `defaultValue` is returned.
*/
static async get(key, defaultValue) {
if (!data) {
const dataFile = await this.init();
data = JSON.parse((await dataFile.read({format: storage.formats.utf8})).toString());
}
if (data[key] === undefined) {
await this.set(key, defaultValue);
return defaultValue;
} else {
return data[key];
}
}
/**
* Saves a certain key-value-pair to the storage.
* @param {string} key The identifier
* @param {*} value The value that get's saved
* @return {Promise<void>}
*/
static async set(key, value) {
const dataFile = await this.init();
data[key] = value;
return await dataFile.write(JSON.stringify(data), {append: false, format: storage.formats.utf8})
}
/**
* Deletes a certain key-value-pair from the storage
* @param {string} key The key of the deleted pair
* @return {Promise<void>}
*/
static async delete(key) {
return await this.set(key, undefined);
}
/**
* Resets (i.e. purges) all stored settings.
* @returns {Promise<void>}
*/
static async reset() {
const dataFile = await this.init();
return await dataFile.write('{}', {append: false, format: storage.formats.utf8})
}
}
module.exports = {
downloadImage,
parseStyles,
getDimensions,
storageHelper
};