The demo site that turns Gfycat's lowercase ID to CamelCase formatted ID. It has iframe API.
Gfycat's ID matches such pattern: AdjectiveAdjectiveAnimal.
The example:
lazyfatcat
turns toLazyFatCat
.emobluedog
turns toEmoBlueDog
hexakosioihexekontahexaphobicparaskavidekatriaphobicqueenalexandrasbirdwingbutterfly
turns toHexakosioihexekontahexaphobicParaskavidekatriaphobicQueenalexandrasbirdwingbutterfly
It is trying to match the most longer string by pattern ["adjective", "adjective", "animal"]
ignoring non [a-zA-Z]
characters.
If the first is "adjective", then it looks for "adjective", then for "animal".
If no result has found, it is looking for any word sequence available in both dictionaries (adjectives and animals).
For example:
34REDCAT
→Red
("adjective")blueredcatdog
→BlueRedCat
("adjective", "adjective", "animal")catwhitedogred
→CatWhiteDogRed
(No pattern used)happy-wideeyed-bullmastif
→HappyWideeyedBull
happy-wideeyed-bullmastiff
→HappyWideeyedBullmastiff
While I do not bundle the code to a single file (as a library), to use matchGfyId
function on any site (if it allows iframes) you can open this static site in an iframe and delegate the work to its JS.
Here is the code snipped that you only need, which does two things:
- creates, appends, awaits the loading of the iframe,
- incapsulates the message communication logic within an easy to use async function.
This function is not this project specific, and can be reused for any other single function iframe API. Just copy and paste it.
async function initIframeAPI({src, name}) {
const iframe = document.createElement("iframe");
iframe.setAttribute("sandbox", "allow-scripts");
iframe.setAttribute("referrerpolicy", "no-referrer");
iframe.setAttribute("style", "display: none;");
iframe.setAttribute("src", src);
document.body.append(iframe);
await new Promise(resolve => {
iframe.addEventListener("load", resolve, {once: true});
});
let i = 0; const seed = Math.random().toString().substring(2);
return function() {
const inputArguments = [...arguments];
const id = `${name}:${seed}:${i++}`;
iframe.contentWindow.postMessage({inputArguments, id}, "*");
let promiseResolve;
const handler = event => {
const {data, from, messageId} = event.data;
if (name === from && id === messageId) {
window.removeEventListener("message", handler);
promiseResolve(data);
}
}
return new Promise(resolve => {
promiseResolve = resolve;
window.addEventListener("message", handler);
});
}
}
Here is the usage example:
/**
* @param {String} inputString
* @param {TypeWord[]?} types = ["adjective", "adjective", "animal"]
* @return {Promise<MatchResult>}
*/
const matchGfyId = await initIframeAPI({
src: "https://alttiri.github.io/gfycat-id-camel-caser/iframe-api.html",
name: "gfy-id-camel-caser"
});
/** @type {MatchResult} */
const result = await matchGfyId("redbluecat");
console.log(result.string); // "RedBlueCat"
console.log(await matchGfyId("catduck", ["animal", "animal"]));
The code of iframe-api.html
is pretty simple:
import {matchGfyId} from "./js/api.js";
const iframeApiName = "gfy-id-camel-caser";
window.onmessage = async function(event) {
const {data: {inputArguments, id}, source, origin} = event;
const result = await matchGfyId(...inputArguments);
source.postMessage({
data: result,
from: iframeApiName,
messageId: id
}, origin);
};
Here is the example of the site that uses such approach: alttiri.github.io/gfycat-id-camel-caser/?iframe=true
This site uses dictionaries of animals and adjectives words that are compilations of words available there: [1], [1.1], [2], [3].