Skip to content

Instantly share code, notes, and snippets.

@blineberry
Last active May 3, 2024 18:24
Show Gist options
  • Save blineberry/fd5018a2924200fc57c6330bd51d1873 to your computer and use it in GitHub Desktop.
Save blineberry/fd5018a2924200fc57c6330bd51d1873 to your computer and use it in GitHub Desktop.
Supports Webmentions? Bookmarklet
javascript: (() => {
// Set some strings for the common result scenarios.
const support = "Page supports webmentions!";
const noSupport = "Page does not support webmentions :(";
// Create a dialog element and insert into the DOM.
let d = document.createElement('dialog');
document.getElementsByTagName('body')[0].appendChild(d);
// Remove the dialog element when it's closed.
d.addEventListener('close', () => {
d.remove();
});
// Create the contents of the dialog.
let content = document.createElement('p');
let close = document.createElement('form');
close.method = 'dialog';
close.innerHTML = "<button>Close</button>";
// Insert into the dialog element.
d.appendChild(content);
d.appendChild(close);
// Go ahead and set the initial status and show the dialog as a modal.
content.innerHTML = "Checking page source for <code>link[rel~=webmention]</code> or <code>a[rel~=webmention]</code>…";
d.showModal();
// The official spec (https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint) calls for
// checking for a Link HTTP header first, and then for these elements in the source. Since we don't care about
// finding the correct webmention endpoint, only if one exists, we can check source first and potentially save
// an HTTP request.
// Get all `link` and `a` elements that have a `rel` attribute containing "webmention".
let els = document.querySelectorAll('link[rel~=webmention], a[rel~=webmention]');
// If any of those elements exist, the page supports webmentions.
if (els.length > 0) {
content.innerHTML += '<br/>Page source contains <code>link[rel~=webmention]</code> or <code>a[rel~=webmention]</code>!<br/><br/>' + support;
return;
}
// If none exist, check the Link HTTP header.
content.innerHTML += '<br/>Page source does not contain <code>link[rel~=webmention]</code> or <code>a[rel~=webmention]</code>.<br/><br/>Checking page for Link HTTP header…';
// Make a HTTP request for the current page.
let location = window.location;
fetch(location).then((response) => {
// If the response does not have a Link header, then this page does not support webmentions.
if (!response.headers.has("Link")) {
content.innerHTML += '<br/>Page does not have a Link HTTP header.<br/><br/>' + noSupport;
return;
}
// The Link header can contain multiple values, separated by commas.
let links = response.headers.get("Link").split(",");
// If no links, then the Link header is empty and the page does not support webmentions.
if (links.length <= 0) {
content.innerHTML += '<br/>Link HTTP header is empty.<br/><br/>' + noSupport;
return;
}
// Iterate over the links, checking each one for a `rel=webmention` value. If one exists, then the page
// supports webmentions.
for (let link of links) {
if(/;\s*rel=["']?webmention["']?/.test(link)) {
content.innerHTML += '<br/>Page has a Link HTTP header with `rel="webmention"`.<br/><br/>' + support;
return;
}
}
// Otherwise the page does not support webmentions.
content.innerHTML += '<br/>Page does not have a Link HTTP header with `rel="webmention"`.<br/><br/>' + noSupport;
}).catch(e => {
// Output any errors from the Link header check to the dialog.
content.innerHTML += "<br/><br/>Error checking for Link header: " + e;
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment