forked from figma/plugin-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ui.html
134 lines (105 loc) · 3.83 KB
/
ui.html
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
<script>
// This function attemps to load an image from a url and return the arrayBuffer
// to pass back to Figma to render the image
async function getEncodedImageFromURL(url) {
return new Promise((resolve, reject) => {
const img = new Image();
// Some websites will allow loading of images into a canvas if set to Anonymous
img.crossOrigin = "Anonymous";
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext("2d");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
canvas.toBlob(async (blob) => {
let blobBuffer = await blob.arrayBuffer();
resolve({
img: img,
data: new Uint8Array(blobBuffer)
});
})
}
// If an Anonymous image does not load, attempt to load it
// cross origin using cors-anywhere
img.onerror = () => {
if(img.src.indexOf("cors-anywhere") === -1){
img.src = `https://cors-anywhere.com/${url.replace(/http(s)?:\/\//,'')}`;
} else {
reject("Error fetching image");
}
}
img.src = url;
});
}
// This function loads html content at a url and then scrapes the OG meta tags
// to render onto a Figma canvas
async function fetchMetaTags(url){
return new Promise(function(resolve, reject) {
let fetchUrl = `https://cors-anywhere.com/${url.replace(/http(s)?:\/\//,'')}`;
fetch(fetchUrl).then(function (response) {
// The API call was successful!
return response.text();
}).then(async (html) => {
let metaTags = {};
// This is the HTML from our response as a text string
let head = document.createElement('div');
let headMatch = html.match(/<head>([\s\S]*?)<\/head>/);
let headHTML = headMatch !== null? headMatch[1] : html;
headHTML.replace(/<script\b[^>]*>([\s\S]*?)<\/script>/gm,'');
head.innerHTML = headHTML;
//Get the title
let title = head.querySelector('meta[property="og:title"],meta[name="twitter:title"]');
if(!title){
reject("No meta data found");
return;
}
metaTags.title = title.getAttribute("content");
// Get the description
let description = head.querySelector('meta[name="description"]');
metaTags.description = description.getAttribute("content");
// get image
let image = head.querySelector('meta[property="og:image"],meta[name="twitter:image"]');
// Get image data to pass back to Figma
let imageData = await getEncodedImageFromURL(image.getAttribute("content"));
metaTags.image = {
data: imageData.data,
url: imageData.img.src,
width: imageData.img.naturalWidth,
height: imageData.img.naturalHeight
}
// Save the link that we scraped meta data from
metaTags.hyperlink = url;
resolve(metaTags);
}).catch(function (err) {
// There was an error
console.warn('Something went wrong.', err);
reject('Something went wrong.');
});
});
}
// Handle messages from figma plugin
window.onmessage = async (event) => {
if(event.data.pluginMessage){
let msg = event.data.pluginMessage;
if(msg.function === "fetchMetaTags"){
let url = msg.data;
let nodeId = msg.nodeId;
fetchMetaTags(url)
.then(metaTags => {
parent.postMessage({ pluginMessage: {
function: 'createMetaCard',
data: metaTags,
nodeId: nodeId
} }, '*')
})
.catch(err => {
parent.postMessage({ pluginMessage: {
function: 'fetchError',
data: err
} }, '*')
});
}
}
}
</script>