-
Notifications
You must be signed in to change notification settings - Fork 0
/
ui.html
1 lines (1 loc) · 18.8 KB
/
ui.html
1
<style>@import "https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&display=swap";@import "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200&display=swap";@import "https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700;900&display=swap";:root{--grey-outline:#ddd;--grey-background:#f7f7f7;--grey-inactive-label:grey;--blue-active:#0075ff;--grey-text-input:#ededf5;--ui-font-family:"Google Sans Text",system-ui,sans-serif;font-family:var(--ui-font-family);background-color:var(--grey-background);padding:6px;font-size:12px}.controls-new input{font-family:var(--ui-font-family);cursor:default;background-color:#0000;border:none}.controls-new input:focus{outline-color:var(--blue-active)}.material-symbols{font-family:Material Symbols Outlined}h2{padding-top:0;padding-bottom:2px;font-size:14px;font-weight:700}h2.emoji-group{text-transform:uppercase;padding-top:7px;padding-bottom:7px;font-size:11px}#intro{font-size:.75rem}.controls-new{grid-template-rows:auto auto 1fr auto auto;height:100%;display:grid}.mode-select{grid-template-columns:50% 50%;width:100%;font-size:14px;display:grid}.mode{text-align:center;border-bottom:2px solid var(--blue-active);cursor:default;-webkit-user-select:none;user-select:none;padding-bottom:9px;position:relative}.icon{-webkit-user-select:none;user-select:none;font-family:Material Symbols Outlined;font-size:20px;font-weight:400;display:inline-block;position:absolute;top:-4px}.font{grid-template-columns:70px 1fr;width:100%;display:grid}.font .size{display:grid}.axes .axis{grid-template-columns:70px 1fr;align-items:center;width:100%;display:grid}.axes .axis .tag{cursor:pointer}.axes .axis .numeric{border:none;width:100%}.axes .axis .slider{vertical-align:middle;width:100%}.select{position:relative}.select .current{width:100%}.select .dropdown{cursor:pointer;z-index:10;background-color:#fff;border:1px solid #d3d3d3;border-top-width:0;padding:.3em;line-height:1.5em;display:none;position:absolute;top:1em}.select .dropdown .dropdown-item:hover{background-color:var(--blue-active);color:#fff}.style{grid-column:1/3}.icon-wrap{padding-right:2em;position:relative}.dropdown-icon{text-align:right;position:absolute}.palettes .palette{grid-template-columns:20px repeat(18,1fr);align-items:center;column-gap:2px;width:100%;display:grid}.palettes .palette input[type=color]{border:none;width:40px;height:40px;padding:0;position:absolute;top:-10px;left:-10px}.palettes .palette .frame{border:1px solid var(--grey-outline);width:13px;height:13px;position:relative;overflow:hidden}.common{grid-template-columns:50% 50%;display:grid}.button{border:2px solid #000;border-radius:5em;width:100%;padding:10px;font-size:14px;display:inline-block}.text-input{width:100%;margin-top:.8em}.text-input input,.search input{background-color:var(--grey-text-input);border:none;border-radius:5em;width:100%;padding:.8em}.emoji-picker{_display:none;_width:300px;--emoji-grey:#606368;--selected:#2c54d0;--highlight:#edf3fe;box-sizing:border-box;border:2px solid var(--emoji-grey);border-radius:5px;grid-column:span 2;width:100%;height:300px;position:relative}.emoji-picker .emoji-type{cursor:pointer;grid-template-columns:repeat(10,1fr);margin-bottom:.3em;display:grid}.emoji-picker .emoji-group-icon{letter-spacing:normal;text-transform:none;white-space:nowrap;word-wrap:normal;-webkit-font-feature-settings:"liga";-webkit-font-smoothing:antialiased;color:var(--emoji-grey);font-variation-settings:"FILL" 1;text-align:center;direction:ltr;font-family:Material Symbols Outlined;font-size:24px;font-style:normal;font-weight:400;line-height:1;display:inline-block}.emoji-picker .emoji-main{color:var(--emoji-grey)}.emoji-picker .emoji-main label{text-transform:uppercase;margin-left:.4em;font-size:.7em;font-weight:700}.emoji-picker .emoji-main .emoji-grid{grid-template-columns:repeat(9,1fr);grid-auto-rows:34px;width:100%;height:221px;font-size:25px;display:grid;overflow-y:scroll}.emoji-picker .emoji-main .emoji-variants-grid{z-index:1;background-color:#fff;border:1px solid #000;border-radius:3px;display:none;position:absolute;top:-1em;left:0}.emoji-picker .emoji-main .emoji-cell{text-align:center;cursor:pointer;position:relative;overflow:hidden}.selected{color:var(--selected)}.dropzone{opacity:.2;background-color:green;width:100%;height:100%;display:none;position:absolute;top:0;left:0}.panel{background-color:#fff;width:100%;height:100%;display:none;position:absolute;top:100%;left:0}.panel .content{box-sizing:border-box;background-color:#fff;width:100%;height:100%;padding:1em;position:absolute;top:0;left:0}.css :is(.panel .content){white-space:pre;tab-size:4;font-family:monospace}.panel .close{width:2em;height:1em;position:fixed;top:.5em;right:0}</style><div class="controls-new"> <div class="mode-select"> <div class="emoji mode"><span class="icon-wrap"><div class="icon">mood</div></span> Emoji</div> <div class="mode text"><span class="icon-wrap"><div class="icon">insert_text</div></span> Text</div> </div> <div class="controls emoji"> <div class="font"> <div class="select size"><input class="current" value="24px"><div class="dropdown"></div></div> <div class="family select"><input class="current" readonly><div class="dropdown"></div></div> <div class="select style"><input class="current" readonly><div class="dropdown"></div></div> </div> <div class="search"> <input type="text" placeholder="Search emoji"> </div> <div class="emoji-picker"> <div class="emoji-type"> <div class="emoji-group-icon">schedule</div> <div class="default emoji-group-icon">mood</div> <div class="emoji-group-icon">emoji_people</div> <div class="emoji-group-icon">emoji_nature</div> <div class="emoji-group-icon">emoji_food_beverage</div> <div class="emoji-group-icon">emoji_transportation</div> <div class="emoji-group-icon">emoji_events</div> <div class="emoji-group-icon">emoji_objects</div> <div class="emoji-group-icon">glyphs</div> <div class="emoji-group-icon">emoji_flags</div> </div> <h2 class="emoji-group">Heading</h2> <div class="emoji-main"> <div class="emoji-grid"></div> <div class="emoji-variants-grid"></div> </div> </div> </div> <div class="controls text"> <div class="font"> <div class="select size"><input class="current" value="24px"><div class="dropdown"></div></div> <div class="family select"><input class="current" readonly><div class="dropdown"></div></div> <div class="select style"><input class="current" readonly><div class="dropdown"></div></div> </div> <div class="axes"> <h2><span class="icon-wrap"><div class="icon" style="font-size:1.625em;top:-3px">custom_typography</div></span> Axes</h2> <div class="axis-controls"> </div> </div> <div class="palettes"> <h2><span class="icon-wrap"><div class="icon">palette</div></span> Palettes</h2> <div class="palette-controls"> </div> </div> </div> <div class="text-input"> <input type="text" placeholder="Text will update as you type"> </div> <div class="common" style="padding-top:14px"> <div class="info show-panel"> <span class="icon-wrap"><div class="icon" style="padding-top:12px;font-size:24px">info</div></span> </div> <div style="margin:0 -4px 0 20px"> <button class="button css show-panel" style="margin-bottom:-4px"> <span class="icon-wrap"><div class="icon">code</div></span> <span>Show CSS</span> </button> </div> </div> <div class="info panel"> <div class="content"> <h3>COLRv1 plugin</h3> <p>This Figma plugin allows color fonts to be used in Figma, specifically fonts in the COLR format. Both COLRv0 (flat colour) and COLRv1 (includes gradients and compositing) versions are supported.</p> <p>Preloaded emoji fonts:</p> <ul class="emoji font-list"></ul> <p>Preloaded text fonts:</p> <ul class="font-list text"></ul> <hr> <p>The project is maintained at <a href="https://github.com/Lorp/figma-colrv1">GitHub: Figma-COLRv1 plugin</a>. Please raise any issues there.</p> </div> <div class="close"><span class="icon">cancel</span></div> </div> <div class="css panel"> <div class="content"></div> <div class="close"><span class="icon">cancel</span></div> </div> </div><div class="dropzone"></div><script>!function(){function e(t,o=document){return o.querySelector(t)}function t(e,o=document){return o.querySelectorAll(e)}function o(e,t,o,n){let a=document.createElement(e);if(t&&a.attr(t),o)for(let e in o)a[e]=o[e];if(n)for(let e in n)a.style[e]=n[e];return a}Element.prototype.attr=function(e){for(let t in e)this.setAttributeNS(null,t,e[t])};let n={emojiSVGs:{},emojiVariants:{},emojiVariantsDelay:650,emojiPerPageCount:63,emojiGroupLookup:{schedule:-1,mood:0,emoji_people:1,emoji_nature:2,emoji_food_beverage:3,emoji_transportation:4,emoji_events:5,emoji_objects:6,glyphs:7,emoji_flags:8},uiReady:!0,fontList:[],fontSizes:[6,7,8,9,10,11,12,14,16,18,20,24,28,36,48,60,72],axisDefaultOverrides:{wdth:100,wght:400,ital:0,opsz:12},timers:{}};function a(t){let o=t.target.closest(".select"),n=e(".current",o),a=e(".dropdown",o);t.target.classList.contains("dropdown-item")&&(n.value=t.target.textContent),n.value=Math.abs(parseFloat(n.value))+"px",a.style.display="none",d()}function s(e){let t={type:"palette-edit",paletteId:e.target.dataset.paletteId,entryId:e.target.dataset.entryId,color:e.target.value};parent.postMessage({pluginMessage:t},"*"),d()}function i(t){let o=t?t.target.closest(".mode"):document.querySelector(".mode");n.mode=o.classList.contains("emoji")?"emoji":"text",console.log("We set mode to ",n.mode),console.log(o),o.parentNode.querySelectorAll(".mode").forEach(e=>e.style.borderColor=o===e?"var(--blue-active)":"transparent"),o.classList.contains("emoji")?(e(".controls.emoji").style.display="block",e(".controls.text").style.display="none",e(".text-input input").placeholder="Emoji will insert as you select",e(".text-input input").style.fontFamily="Noto Color Emoji,Google Sans Text"):o.classList.contains("text")&&(e(".controls.text").style.display="block",e(".controls.emoji").style.display="none",e(".text-input input").placeholder="Text will update as you type",e(".text-input input").style.fontFamily="var(--ui-font-family)"),e(".text-input input").value="",l()}function l(t){let o="";if(t)o=t.target.textContent;else{let e=n.fontList.filter(e=>e.attributes.includes(n.mode));e.sort((e,t)=>{let o=e.priority||0,n=t.priority||0;return o<n?1:o>n||e.name<t.name?-1:e.name>t.name?1:0}),e[0],o=e[0].name}parent.postMessage({pluginMessage:{type:"fetch-font-by-name",name:o}},"*"),e(`.controls.${n.mode} .font .family.select .current`).value=o,t&&(t.target.closest(".dropdown").style.display="none")}function r(o){let a=n.fvar.instances.find(e=>e.name===o.target.textContent),s=t(".axes .axis",o.target.closest(".controls"));if(s.length===a.coordinates.length){let t=o.target.closest(".select");a.coordinates.forEach((e,t)=>s[t].querySelector(".numeric").value=s[t].querySelector(".slider").value=e),e(".current",t).value=o.target.textContent,e(".dropdown",t).style.display="none",d()}}function c(e){e.target,e.target.closest(".axis").querySelector(".numeric").value=e.target.value,d()}function d(o){console.log(`.controls.${n.mode} .size .current`),console.log(e(`.controls.${n.mode} .size .current`));let a={fvs:function(){let o={},a=t(".axis-controls .axis");return n?.fvar?.axes.length&&a.length===n.fvar.axes.length&&n.fvar.axes.forEach((t,n)=>o[t.axisTag]=parseFloat(e(".numeric",a[n]).value)),o}(),text:e(".text-input input").value,fontSize:parseFloat(e(`.controls.${n.mode} .size .current`).value)};if(n.CPAL){let t=e('input[name="palette-id"]:checked');t&&(a.paletteId=t.value)}parent.postMessage({pluginMessage:{type:"render",options:a}},"*");let s='@font-face {\n font-family: "'+n.fontFamily+'";\n src: url("'+n.fontURL+'");\n}\n\n';s+='.myClass {\n font-family: "'+n.fontFamily+'";\n\n}\n',e(".panel.css .content").textContent=s}function p(e,t,o,n=!1){let a=document.createElement("div");a.classList.add("emoji-cell"),a.innerHTML=o,a.dataset.string=t,e.append(a),n?a.onmouseup=m:(a.onmousedown=u,a.onclick=m)}function m(t){let o=t.target.closest(".emoji-cell"),n=e(".text-input input");n.value+=o.dataset.string,n.dispatchEvent(new Event("input"))}function u(t){let o=t.target.closest(".emoji-cell"),a=o.dataset.string;n.emojiVariants[a]&&(parent.postMessage({pluginMessage:{type:"fetch-emojis",emojiStrings:[a],getAlternates:!0,getBases:!1}},"*"),n.emojiVariantsTimer=setTimeout(function(){let t=o.closest(".emoji-grid"),s=e(".emoji-variants-grid");s.style.display="grid",s.innerHTML="";let i=Math.min(5,n.emojiVariants[a].length);s.style.display="grid",s.style.gridTemplateColumns=`repeat(${i}, 1fr)`,s.style.gridAutoRows="34px",s.style.left=`${o.offsetLeft}px`,s.style.top=`${o.offsetTop-34-t.scrollTop}px`,s.style.width=27*i+"px",n.emojiVariants[a].forEach(e=>p(s,e,n.emojiSVGs[e],!0)),n.emojiVariantsTimer=null},n.emojiVariantsDelay),document.onmouseup=f)}function f(t){clearTimeout(n.alternatesTimer),n.emojiVariantsTimer=null,document.removeEventListener("onmouseup",f),e(".emoji-variants-grid").style.display="none"}function g(o){let a=o.target,s=n.emojiGroupLookup[a.textContent];e(".emoji-grid").scrollTop="0px";let i={type:"fetch-emojis",emojiType:s,startIndex:0,count:n.emojiPerPageCount,includeAlternates:!1};parent.postMessage({pluginMessage:i},"*"),e("h2.emoji-group").innerText=n.emojiMetadata[s].group,t(".emoji-group-icon").forEach(e=>{e===a?(e.style.textDecoration="underline",e.classList.add("selected")):(e.style.textDecoration="none",e.classList.remove("selected"))})}t(".mode").forEach(e=>{e.onclick=i}),e(".text-input input").oninput=d,t(".emoji-group-icon").forEach(e=>{e.onclick=g}),t(".show-panel").forEach(t=>{if(console.log("setting up panel"),t.classList.contains("info")?t.dataset.panelName="info":t.classList.contains("css")&&(t.dataset.panelName="css"),t.dataset.panelName){let o=e(`.panel.${t.dataset.panelName}`);t.onclick=e=>{console.log("clicked panel"),o.style.top="0",o.style.display="block"},e(".close",o).onclick=e=>{o.style.top="100%",o.style.display="none"}}}),e("body").ondragover=t=>{t.preventDefault(),e(".dropzone").style.display="block"},e("body").ondragend=t=>{console.log("dragend"),t.preventDefault(),e(".dropzone").style.display="none"},e(".dropzone").ondrop=t=>{console.log("drop"),t.preventDefault(),e(".dropzone").style.display="none",t.dataTransfer.files[0].arrayBuffer().then(e=>{let t=new Uint8Array(e),o="";for(let n=0;n<e.byteLength;n++)o+=String.fromCharCode(t[n]);let n={type:"font-upload",fontData:btoa(o)};parent.postMessage({pluginMessage:n},"*")})},setInterval(()=>{let e=Math.round(1e7*Math.random());n.timers[e]={start:Date.now(),label:"ping"},parent.postMessage({pluginMessage:{type:"ping",id:e}},"*")},1e4),onmessage=m=>{console.log("UI received message");let u=m.data.pluginMessage;switch(u.type){case"pong":console.log(`Timer [${n.timers[u.id].label}]`,Date.now()-n.timers[u.id].start,"ms"),n.timers[u.id]=void 0;break;case"init":console.log("Got init message"),console.log(u);break;case"error":u.message&&alert(u.message);break;case"names":console.log("names switch"),alert("names");break;case"font-list":n.fontList.push(...u.fontList),function(){function s(){t(".dropdown").forEach(e=>e.style.display="none")}let r=e(".controls.emoji .font .family.select"),c=e(".controls.text .font .family.select");t(".select").forEach(t=>{let i=e(".current",t);i&&(i.onclick=o=>{let n=e(".dropdown",t);n&&(n.style.display="block",n.onmouseleave=()=>s())}),t.classList.contains("size")&&(e(".current",t).onchange=a,n.fontSizes.forEach(n=>{let s=o("div",{class:"dropdown-item"},{textContent:n+"px",onclick:a}),i=e(".dropdown",t);i&&i.append(s)})),t.onmouseleave=()=>s()}),n.fontList.forEach((t,n)=>{let a=o("div",{class:"dropdown-item"},{textContent:t.name,onclick:l});e(".dropdown",t.attributes.includes("text")?c:r).append(a)}),i()}(),["text","emoji"].forEach(t=>{let o="";n.fontList.filter(e=>e.attributes.includes(t)).forEach(e=>{let t=e.name;e.website&&(t=`<a href="${e.website}" target="_blank">${e.name}</a>`),["COLRv0","COLRv1"].forEach(o=>{e.attributes.includes(o)&&(t+=` (${o})`)}),o+=`<li>${t}</li>`}),e(`.panel.info .content .font-list.${t}`).innerHTML=o});break;case"render-complete":n.uiReady=!0;break;case"emoji-ordering":n.emojiMetadata=u.emojiMetadata,n.emojiVariants={},n.emojiMetadata.forEach(e=>{e.emoji.forEach(e=>{if(e.alternates.length>0){let t=String.fromCodePoint(...e.base);n.emojiVariants[t]=[],e.alternates.forEach(e=>{n.emojiVariants[t].push(String.fromCodePoint(...e))})}})});break;case"font-fetched":console.log("Font fetched"),n.fvar=void 0,n.CPAL=void 0,"emoji"===n.mode&&e(".emoji-group-icon.default").dispatchEvent(new Event("click"));break;case"font-data-delivered":d(),function(){console.log("populateAxes()");let t=e(".axes .axis-controls");n.fvar&&n.fvar.axes&&0!==n.fvar.axes.length?(t.innerHTML="",n.fvar.axes.forEach(e=>{let a=void 0===n.axisDefaultOverrides[e.axisTag]?e.defaultValue:Math.min(Math.max(n.axisDefaultOverrides[e.axisTag],e.minValue),e.maxValue),s=o("div",{class:"axis"});s.style.width="100%";let i=o("div"),l=o("div"),r=o("div",{title:e.name,class:"tag"},{textContent:e.axisTag}),d=o("input",{type:"text",class:"numeric",value:a},{oninput:c,readonly:!0},{fontFamily:"var(--ui-font-family)",textAlign:"left"}),p=o("input",{type:"range",class:"slider",min:e.minValue,max:e.maxValue,step:.01,value:a},{oninput:c});i.append(r,d),l.append(p),s.append(i,l),t.append(s)})):t.innerHTML="No variation axes found."}(),function(){let t=e(".palettes .palette-controls");n.CPAL&&n.CPAL.palettes&&0!==n.CPAL.palettes.length?(t.innerHTML="",n.CPAL.palettes.forEach((e,a)=>{let i=o("div",{class:"palette"});i.append(o("input",{type:"radio",name:"palette-id",value:a},{checked:0==a,onchange:d})),e.colors.forEach((e,t)=>{let l=o("div",{class:"frame"}),r=o("input",{type:"color",value:n.CPAL.hexColors[e],title:`Palette ${a}, entry ${t}: ${n.CPAL.hexColors[e]}`},{oninput:s});r.dataset.paletteId=a,r.dataset.entryId=t,t<18&&(l.append(r),i.append(l))}),t.append(i)})):t.innerHTML="No CPAL palettes found."}(),function(){console.log("populateInstances()",n.fvar?.instances.length),console.log(n.fvar?.instances);let t=e(`.controls.${n.mode} .style.select`),a=e(".current",t),s=e(".dropdown",t);a.value="Default",n.fvar?.instances.length&&"emoji"!==n.mode||(a.onclick=null),s.innerHTML="",n.fvar?.instances&&n.fvar.instances.forEach((e,t)=>{s.append(o("div",{class:"dropdown-item"},{textContent:e.name,onclick:r}))})}(),n.fontFamily=u.fontFamily,n.fontMetadata=n.fontList.find(e=>e.name===n.fontFamily),n.fontMetadata&&(n.fontMetadata.attributes.includes("emoji")?n.mode="emoji":n.fontMetadata.attributes.includes("text")?n.mode="text":n.mode="",n.mode);break;case"fvar":n.fvar=u.fvar;break;case"CPAL":n.CPAL=u.CPAL;break;case"emoji-svgs":{let t=e(".emoji-main .emoji-grid"),o=Date.now();if(u.emojiType>=0&&u.emojiType<n.emojiMetadata.length){let e=n.emojiMetadata[u.emojiType];if(Object.assign(n.emojiSVGs,u.svgs),0===u.startIndex){let e={type:"fetch-emojis",emojiType:u.emojiType,startIndex:n.emojiPerPageCount,includeAlternates:!1};parent.postMessage({pluginMessage:e},"*"),t.innerHTML=""}e.emoji.forEach(e=>{let o=String.fromCodePoint(...e.base);u.svgs[o]&&p(t,o,u.svgs[o])})}else u.emojiStrings?Object.assign(n.emojiSVGs,u.svgs):console.log("Error: emojiType out of range");console.log("Time to render emojis:",Date.now()-o,"ms")}}}}();</script>