-
Notifications
You must be signed in to change notification settings - Fork 16
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
[figma] Fix outdated links #74
Comments
I have spent 1 hour looking into it, out of curiosity for the needs of #10 and mui/toolpad#791. I could come up with the following Figma plugin to automate it all // This plugin will open a window to prompt the user to enter a number, and
// it will then create that many rectangles on the screen.
// This file holds the main code for the plugins. It has access to the *document*.
// You can access browser APIs in the <script> tag inside "ui.html" which has a
// full browser environment (see documentation).
// This shows the HTML page in "ui.html".
figma.showUI(__html__);
// Calls to "parent.postMessage" from within the HTML page will trigger this
// callback. The callback will be passed the "pluginMessage" property of the
// posted message.
figma.ui.onmessage = msg => {
// One way of distinguishing between different types of messages sent from
// your HTML page is to use an object with a "type" property like this.
if (msg.type === 'click-fix') {
// This plugin counts the number of layers, ignoring instance sublayers,
// in the document
let count = 0;
let changed = [];
function traverse(node) {
if (!node) {
return
}
count += 1;
// https://www.figma.com/plugin-docs/api/TextSublayer/#hyperlink
if (node.hyperlink && node.hyperlink.type === 'URL') {
const oldURL = node.hyperlink.value;
const newURL = replaceUrl(oldURL);
if (oldURL !== newURL) {
node.hyperlink = { type: 'URL', value: newURL };
changed.push({ oldURL, newURL });
}
// console.log('postMessage', { type: 'resolve-url', id: node.id, url: node.hyperlink.value });
// figma.ui.postMessage({ type: 'resolve-url', id: node.id, url: node.hyperlink.value })
}
// https://www.figma.com/plugin-docs/api/properties/nodes-documentationlinks/
if (node.documentationLinks && node.documentationLinks.length > 0) {
const oldURL= node.documentationLinks[0].uri;
const newURL = replaceUrl(oldURL);
if (oldURL !== newURL) {
node.documentationLinks = [{
uri: newURL,
}]
changed.push({ oldURL, newURL });
}
// console.log('postMessage', { type: 'resolve-url', id: node.id, url: node.documentationLinks[0].uri });
// console.log('replaceUrl', node.documentationLinks[0].uri, replaceUrl(node.documentationLinks[0].uri))
// figma.ui.postMessage({ type: 'resolve-url', id: node.id, url: node.documentationLinks[0].uri })
}
// if (count > 100) {
// return;
// }
if ("children" in node) {
// if (node.type !== "INSTANCE") {
for (const child of node.children) {
traverse(child)
}
// }
}
}
traverse(figma.root); // start the traversal at the root
// traverse(figma.currentPage.selection[0]); // start the traversal at the root
console.log('changed', changed);
}
// Make sure to close the plugin when you're done. Otherwise the plugin will
// keep running, which shows the cancel button at the bottom of the screen.
figma.closePlugin();
}; <button id="create">Run</button>
<button id="cancel">Cancel</button>
<script>
document.getElementById('create').onclick = () => {
const count = 3;
parent.postMessage({ pluginMessage: { type: 'click-fix', count } }, '*')
}
document.getElementById('cancel').onclick = () => {
parent.postMessage({ pluginMessage: { type: 'cancel' } }, '*')
}
// window.onmessage = async (event) => {
// console.log('message')
// if (event.data.pluginMessage.type === 'resolve-url') {
// console.log('resolve-url', event.data.pluginMessage.url)
// var request = new XMLHttpRequest()
// // This link has random lorem ipsum text
// request.open('GET', event.data.pluginMessage.url)
// request.responseType = 'text'
// request.onload = () => {
// // window.parent.postMessage({pluginMessage: { type: 'url-resolved' }}, '*')
// };
// request.send()
// }
// }
</script> It almost works: But I faced two challenges:
|
Some more recent work I did on this on the side: code.ts function handleClickFix() {
let count = 0;
const linkElements = [];
function traverse(node) {
if (!node) {
return
}
count += 1;
if (node.hyperlink && node.hyperlink.type === 'URL') {
linkElements.push({
node: node.hyperlink,
type: 'link',
});
}
if (node.documentationLinks && node.documentationLinks.length > 0) {
linkElements.push({
node: node.documentationLinks,
type: 'docs',
})
}
if ('children' in node) {
for (const child of node.children) {
traverse(child)
}
}
}
traverse(figma.currentPage.selection[0]); // start the traversal at the root
// traverse(figma.root); // start from the traversal from the root
// type = link
// const oldURL = node.hyperlink.value;
// const newURL = replaceUrl(oldURL);
// if (oldURL !== newURL) {
// node.hyperlink = { type: 'URL', value: newURL };
// changed.push({ oldURL, newURL });
// }
// // console.log('postMessage', { type: 'resolve-url', id: node.id, url: node.hyperlink.value });
// // figma.ui.postMessage({ type: 'resolve-url', id: node.id, url: node.hyperlink.value })
// type = docs
// const oldURL = node.documentationLinks[0].uri;
// const newURL = replaceUrl(oldURL);
// if (oldURL !== newURL) {
// node.documentationLinks = [{
// uri: newURL,
// }]
// changed.push({ oldURL, newURL });
// }
// // console.log('postMessage', { type: 'resolve-url', id: node.id, url: node.documentationLinks[0].uri });
// // figma.ui.postMessage({ type: 'resolve-url', id: node.id, url: node.documentationLinks[0].uri })
linkElements.forEach((linkElement) => {
if (linkElement.type === 'docs') {
figma.ui.postMessage({ type: 'resolveUrl', url: linkElement.node.documentationLinks[0].uri })
} else if (linkElement.type === 'link') {
figma.ui.postMessage({ type: 'resolveUrl', url: linkElement.node.value })
}
});
console.log('linkElements', linkElements);
}
// This shows the HTML page in "ui.html".
figma.showUI(__html__);
// Calls to "parent.postMessage" from within the HTML page will trigger this
// callback. The callback will be passed the "pluginMessage" property of the
// posted message.
figma.ui.onmessage = msg => {
// One way of distinguishing between different types of messages sent from
// your HTML page is to use an object with a "type" property like this.
if (msg.type === 'click-fix') {
handleClickFix();
return;
}
// Make sure to close the plugin when you're done. Otherwise the plugin will
// keep running, which shows the cancel button at the bottom of the screen.
figma.closePlugin();
}; proxy.mjs import http from 'http';
http.createServer((req, res) => {
const url = new URL(`https://0.0.0.0${req.url}`).searchParams;
console.log('url', url.get('url'));
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
}).listen(3008); ui.html <button id="run">Run</button>
<script>
document.getElementById('run').onclick = () => {
parent.postMessage({ pluginMessage: { type: 'click-fix' } }, '*')
}
window.onmessage = async (event) => {
const message = event.data.pluginMessage;
console.log('message', message)
if (message.type === 'resolveUrl') {
console.log('resolveUrl', message.url)
var request = new XMLHttpRequest()
// This link has random lorem ipsum text
request.open('GET', message.url)
request.responseType = 'text'
request.onload = () => {
// window.parent.postMessage({pluginMessage: { type: 'resolvedUrl' }}, '*')
};
request.send()
}
}
</script> |
@DavidCnoops What do you think about taking this problem on? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The problem
In the latest version of the "MUI for Figma design kit", many of the links don't return an HTTP status 200. Most of them are redirections that might break in the future and slow down the UX when opening them. Others might be 404 which breaks the designer experience.
Examples
Proposed solution
We could spend a couple of hours, likely less than 8, to create a custom Figma plugin that iterate on all the URLs in the Figma file (links, document URLs, etc.). If the link is a redirection, we can automatically replace it with the new destination (and log what happened). If the link is something else than a 200, we can report it, in a way that is easy to fix manually in the Figma editor.
The text was updated successfully, but these errors were encountered: