ðâïžãðâ€ïžðïŒððððïŒ
ã¿ã€ãã«æ¥æ¬èªèš³ïŒãçµµæåã®äžçãäœã£ã話ãïœh2oã®èšå®æ¹æ³ãšWeb Componentsïœ
äžã®æã®æ¥æ¬èªèš³ïŒãããã«ã¡ã¯ïŒãç§ã¯çµµæåã倧奜ããªã®ã§ãçµµæåã§ãŠã§ãããŒãžãäœã£ãŠã¿ãŸããã
ãåèªãðãçµµæå / ðšâð§ äœã / ð 話 / ð§ èšå®ãã / ð æžã / ððïŒãŸãã¯ðžïžðïŒ ãŠã§ãããŒãž
ãšããã®ã¯åè«ã§ãããå°ãåã«ä»¥äžã®ððãäœæããã®ã§ãå°ãã§ãããã®ãšãã®ç¥èŠãå ±æããããšæãèšäºãäœããŸããã
çºç«¯
çºç«¯ã¯ç§ã®ãã®ãã€ãŒãã§ãã
ã ãã ãæ¡åŒµåã®ååšæãèããªã£ãŠãããã®ãæäžã ããããããçµµæåãæ¡åŒµåã«ã§ããã®ã§ã¯ãªããïŒã
â ðïžãã²ðïžð (@uhyo_) 2018幎10æ20æ¥
index.ð
image.ðŒïž
settings.âïž
archive.ðŠ.ðïž
ã¿ãããªã®ãã§ïŒã
èŠããã«ãæ¡åŒµåãçµµæåã ã£ããé¢çœãããããïŒãçãªããšãèšã£ãããã§ãããæ°ãšããŠã¯å€ããªããã®ã®100RTãããããããšè¯å®çãªåå¿ãåŠå®çãªåå¿ãé£ãã§ããŸããããã§ããšãããããã£ãŠã¿ãã®ãåé ã§ç޹ä»ãããŠã§ãããŒãžã§ãã
ããŒãžã®ã¢ãã¬ã¹ã«æ³šç®ããŠã¿ãŠãã ããããããããŒãžã¯ããèŠããšãindex.ðãã§ããæ¡åŒµåãã.ðãã«ãªã£ãŠããŸããããŸãããœãŒã¹ãèŠãŠãããããšåããã®ã§ãããCSSãã¡ã€ã«ããstyles.ðããšãªã£ãŠããããç»åãã¡ã€ã«ããcard.ðŒïžããšãªã£ãŠãããããŸãã
ãã®èšäºã§ã¯ããã®ããã«çµµæåãæ¡åŒµåãšããŠäœ¿ããŠã§ããµãŒããŒã®èšå®ã玹ä»ããŸãã䜿çšãããŠã§ããµãŒããŒã¯H2Oã§ãããšãã£ãŠãããããªã«å€ãªããšããã£ãŠããããã§ã¯ãªãã®ã§H2Oã®èšå®æ¹æ³ç޹ä»ã¿ããã«ãªããŸããã
H2Oã¯HTTP2ã«ãã¡æ©ã察å¿ããæ°é²æ°éã®ãŠã§ããµãŒããŒãšããŠç¥ãããŠããŸããåé ã®ãµã€ããããã¡ããHTTP2ã§é ä¿¡ããŠããŸã1ããã®èšäºã®å 容ã¯ãH2OããŸã ã¡ãããšäœ¿ã£ãããšã®ãªãæ¹ãªãããŸããããªé¢šã«èšå®ãããã ããšããåèã«ã¯ãªãã®ã§ã¯ãªãããšæããŸãã
H2Oã®èšå®
ãŸãH2Oã®èšå®ãã¡ã€ã«ãèŒããŸãããããé¢é£ããèšå®ã®å šãŠã§ãã
reproxy: on
"xn--vg8h70c.uhyo.space:443":
listen:
port: 443
ssl:
<<: !file commons/ssl.yml
header.add: "Strict-Transport-Security: max-age=31536000"
file.index:
- "index.ð "
- "index.html"
paths:
"/":
mruby.handler-file: sites/xn--vg8h70c.uhyo.space/handler.rb
file.dir: /var/www/xn--vg8h70c.uhyo.space
"xn--vg8h70c.uhyo.space:80":
listen:
port: 80
paths:
"/":
redirect: "https://xn--vg8h70c.uhyo.space/"
lambda do |env|
if env["PATH_INFO"] == "/"
return [301, {
"location" => "/index.ð ",
}, []]
end
if env["PATH_INFO"] == "/index.html"
return [399, {
"link" => "</elements.%F0%9F%93%9C>; rel=preload, </styles.%F0%9F%92%84>; rel=preload"
}, []]
end
if /^(.*)\/([^\/]*)\.%F0%9F%93%84$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.html"}, []]
end
if /^(.*)\/([^\/]*)\.%F0%9F%93%9C$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.js"}, []]
end
if /^(.*)\/([^\/]*)\.%E2%9A%99(?:%EF%B8%8F)?$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.js"}, []]
end
if /^(.*)\/([^\/]*)\.%F0%9F%92%84$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.css"}, []]
end
if /^(.*)\/([^\/]*)\.%F0%9F%8E%A8$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.gif"}, []]
end
if /^(.*)\/([^\/]*)\.%F0%9F%93%B7$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.jpg"}, []]
end
if /^(.*)\/([^\/]*)\.%F0%9F%96%BC(?:%EF%B8%8F)?$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.png"}, []]
end
return [399, {}, []]
end
ã¡ã€ã³ã®YAMLãã¡ã€ã«ãšäœãRubyã®ã³ãŒããæžããŠãããã¡ã€ã«ã®2ã€ã«åãããŠããŸãããšããããRubyã®ã»ããé·ãã§ãããïŒããšã§èª¬æããŸãããæ£ç¢ºã«ã¯ããã¯Mrubyã®ã³ãŒãã§ããïŒ
punycode
ãŸãæåã«ããã¹ãåãxn--vg8h70c.uhyo.space
ãšãªã£ãŠããŸãããããã¯ASCIIæåã§ã¯ãªããã¡ã€ã³åã衚çŸããããã«äœ¿ãããpunycodeãšãããšã³ã³ãŒãã£ã³ã°ã§ãå®éããã¯ðð.uhyo.spaceã衚ããŠããŸãã
åºæ¬çã«ã¯ãµãŒããŒã®èšå®ãšãDNSã®èšå®ã¯å šéšpunycode衚çŸã§è¡ã£ãŠãå®éã®çµµæåãšpunycodeãšã®å€æã¯ãªãããã©ãŠã¶ãããæãã«ãã£ãŠãããŸãã
çµµæåã®å Žåãæ®å¿µãªããChromeãFirefoxã¯çµµæåã衚瀺ããã«punycodeãã®ãŸãŸã«ãªãããã§ããSafariã¯çµµæåã§ãã¡ã€ã³åã衚瀺ããŠãããŸãã
ã§ã¯ãèšå®ã®è§£èª¬ã«å ¥ããŸãã
å®ã¯ããã®ãŠã§ãããŒãžã§ã¯å°ããããããŠããŸããè£ã«çšæãããŠãããŠã§ããµã€ãã®ããŒã¿äžã¯ãã¡ã€ã«åã¯index.html
ãstyles.css
ãšãªã£ãŠãããçµµæåæ¡åŒµåã§ã¯ãããŸãããããã¯çµµæåæ¡åŒµåã«å¯ŸããŠãšãã£ã¿ã®èšå®ãªã©ãããã®ãé¢åãããã£ãã®ãäž»ãªçç±ã§ãã
ãããªããšããŠã§ããµãŒããŒïŒH2OïŒã«çµµæåæ¡åŒµåã®ãªã¯ãšã¹ããåãä»ããŠããã£ãŠãæ¡åŒµåãå ã«æ»ãïŒð â htmlïŒåŠçãè¡ã£ãŠãããã¡ã€ã«ãæ¢ãããšã«ãªããŸãããã®èšå®ã¯ããããURLã®æžãæãã§ãWebãµãŒããŒã«ãããŠã¯å®çªã®èšå®ã§ãã
H2Oã«ãããŠã¯ããã®ãããªããšãè¡ãããå Žåã¯Mrubyã®æãåããããšã«ãªããŸããèŠããã«ããªã¯ãšã¹ãã«å¯ŸããåŠçãMrubyã§æžããããã°ã©ã ã«ãããããšããããšã§ããäœã ãlua-nginx-moduleãæãåºããŸãããããããã£ãŠããã®ã¯mruby.handler-file: sites/xn--vg8h70c.uhyo.space/handler.rb
ãšãããšããã§ããããã¯ãã¡ã€ã«åãæå®ããŠèªã¿èŸŒãã§ããŸãããmruby.handler
ãã£ã¬ã¯ãã£ãã䜿ãããšã§ãMrubyã®ã³ãŒããYAMLãã¡ã€ã«å
ã«ãã¿æžãããããšãå¯èœã§ãã
H2Oã«ãããŠã¯Mrubyã®åºçªã¯çµæ§å€ãããã§ããäŸãã°ãåçŽãªã«ãŒãã£ã³ã°ãªãpaths
以äžã®èšå®ã§ã§ããŸãããURLã«å¯ŸããŠæ£èŠè¡šçŸã«ããããããè¡ãããå ŽåãMrubyã®åºçªãšãªããŸããä»åã¯"/":
以äžã«mruby.handler-file
ãã£ã¬ã¯ãã£ãããããããå
šãŠã®ãªã¯ãšã¹ãã«å¯ŸããŠãã®ãã³ãã©ãèµ°ãããšã«ãªããŸãã
handler.rb
ã«ç®ãåãããšãlambda
ã§Procãªããžã§ã¯ããäœã£ãŠããŸããïŒRubyã«ã¯è©³ãããªãã®ã§çšèªãéããããããŸãããèš±ããŠãã ãããïŒããèŠããšãããã¯1ã€ã®åŒæ°env
ãåãåã£ãŠ3ã€çµã®é
åãè¿ãããã«ãªã£ãŠããŸããããã¯Rackãšãã仿§ã«åŸã£ãŠããããã§ããèŠãŠããããšæããŸããã1ã€ç®ãã¹ããŒã¿ã¹ã³ãŒãã2ã€ç®ãããããŒã§ãã3ã€ç®ã¯ä»åã¯å
šéšç©ºã®é
åã«ãªã£ãŠããŸãããã¬ã¹ãã³ã¹æ¬æã§ãã
if env["PATH_INFO"] == "/"
return [301, {
"location" => "/index.ð ",
}, []]
end
ããã¯å
ã»ã©ã®èšå®ããæç²ããã³ãŒãã§ãããããã¯/
ã«ã¢ã¯ã»ã¹ããããšãã¯ã¹ããŒã¿ã¹ã³ãŒã301ã§/index.ð
ã«ãªãã€ã¬ã¯ããããšããæå³ã§ããããšãåãããŸããå®éã https://ðð.uhyo.space/ ã«ã¢ã¯ã»ã¹ãããšãhttps://ðð.uhyo.space/index.ð ã«ãªãã€ã¬ã¯ããããŸããä»åã®ãµã€ãã§ã¯ãåœåã®ç®çã§ããçµµæåæ¡åŒµåã匷調ããç®çã§ãã®èšå®ãããŠããŸãã
ãã®ããäžã®ãã€ã¯äžæŠé£ã°ããŠã2ã€äžããã¯äŒŒããããªifæããããã䞊ãã§ããŸã2ã
if /^(.*)\/([^\/]*)\.%F0%9F%93%84$/.match(env["PATH_INFO"])
return [307, {"x-reproxy-url" => "#{$1}/#{$2}.html"}, []]
end
ããã¯ããªã¯ãšã¹ãURLã®æåŸã®ã»ã°ã¡ã³ãã®æ¡åŒµåã%F0%9F%93%84
ãªãã°3ã¹ããŒã¿ã¹ã³ãŒã307ãè¿ãåŠçã«èŠããŸãããx-reproxy-url
ãšããããããä»å ããŠããã®ãç¹åŸŽçã§ãã
ããã¯reproxyãšãããã®ã§ãx-reproxy-url
ã«æå®ãããURLãH2Oããã§ããããŠãã®çµæãã¯ã©ã€ã¢ã³ãåŽã«éä¿¡ããŠããããšããæ©èœã§ããä»åã¯Mrubyã®ãã³ãã©ã«ãã£ãŠä»å ããŠããŸãããH2Oãã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãžã®ãªããŒã¹ãããã·ãšããŠå©çšããŠããå Žåããã®æ©èœã¯æå¹ã§ãã
ä»åã®å Žåã¯ã/index.ð
ãšãããªã¯ãšã¹ãã«å¯ŸããŠã¯X-Reproxy-URL: /index.html
ãšããããããçæãããããšã«ãªããŸãããã®å Žåã¯ããããå
éšãªãã€ã¬ã¯ãã®æåãšãªãã/index.html
ã®å
容ãè¿ãããããšã«ãªããŸãã
ãŸãšãããšãMrubyãçšããŠçµµæåæ¡åŒµåã®URLãæ¬æ¥ã®æ¡åŒµåã®URLã«å éšãªãã€ã¬ã¯ãããåŠçãè¡ãªãããŠããããšã«ãªããŸãã
ãã³ãã©ã®æ«å°Ÿã«ã¯return [399, {}, []]
ãšããã399ãšããæå³äžæãªã¹ããŒã¿ã¹ã³ãŒããè¿ãããŠããŸããå®ã¯ããã®ç¹æ®ãªã³ãŒããè¿ãããå Žåããªã¯ãšã¹ãã®åŠçãæ¬¡ã®ãã³ãã©ã«å§è²ãããšããæå³ã«ãªããŸããæ¬¡ã®ãã³ãã©ãšã¯äœããšããã®ã¯ãH2Oã®èšå®ãã¡ã€ã«ãã®äžèº«ãèŠè¿ãã°ããããŸãã
paths:
"/":
mruby.handler-file: sites/xn--vg8h70c.uhyo.space/handler.rb
file.dir: /var/www/xn--vg8h70c.uhyo.space
mruby.handler-file
ã®æ¬¡ã«file.dir
ããããŸãããããã¯ãæå®ãããã£ã¬ã¯ããªãããã¡ã€ã«ãé
ä¿¡ãããšããæå³ã§ããH2Oã¯ãã³ãã©ãæå®ãããé çªã«åŠçããããšããçŽ æµãªä»æ§ã«ãªã£ãŠããŸãã®ã§ãMrubyã®ãã³ãã©ã«ãã£ãŠåŠçãããªãã£ãïŒ399ãè¿ãããªãã£ãïŒãã®ã®ã¿ãã®ãã£ã¬ã¯ããªããé
ä¿¡ãããããšã«ãªããŸãã
äŸãã°/styles.ð
ã¯/styles.css
ã«å
éšãªãã€ã¬ã¯ããããŸããã/styles.css
ã¯Mrubyã®ãã³ãã©ã«ãã£ãŠåŠçãããŸãããããããã§æå®ããããã£ã¬ã¯ããªã®äžã®styles.css
ãç¡äºã«é
ä¿¡ãããããšã«ãªããŸãã
æåŸã«ãMrubyã®ãã³ãã©å ã§ãŸã 1ã€èª¬æããŠããªãéšåããããŸãããäžãã2çªç®ã®ifæã§ããã
if env["PATH_INFO"] == "/index.html"
return [399, {
"link" => "</elements.%F0%9F%93%9C>; rel=preload, </styles.%F0%9F%92%84>; rel=preload"
}, []]
end
ããã§ã¯ã399ãè¿ããŠããã®ã«ããããæå®ãããŠããŸãããããããšããããã远å ãã€ã€ãåŸãã®ãã³ãã©ã«åŠçãå§è²ããåäœãšãªããŸããã€ãŸã/var/www/xn--vg8h70c.uhyo.space
å
ã®index.html
ãé
ä¿¡ãã€ã€Link
ããããéä¿¡ããããšãã§ããã®ã§ãããããžã䟿å©ã§ããã
ãªããMrubyã«ã¯ããã©ã«ãã§ã¯æ£èŠè¡šçŸã®æ©èœã¯ãããŸããããH2Oã®Mrubyã§ã¯æ£èŠè¡šçŸãæ±ããããã«mgemã远å ãããŠããŸããRubyã®æ£èŠè¡šçŸãšã³ãžã³ãšããŠç¥ãããŠããOnigmoãMrubyçšã«ãããã®ãå©çšå¯èœãªããã§ããæ£èŠè¡šçŸã®æžãæ¹ã«å°ã£ããOnigmoã調ã¹ãŠã¿ããšãããããããŸããã
以äžãä»åã®H2Oã®èšå®ã®ãã¹ãŠã§ãããããŸã§èªãã æ¹ã¯ããããšã«ãæ°ã¥ããããããŸãããããã¯ãçŽã«https://ðð.uhyo.space/index.htmlã«ã¢ã¯ã»ã¹ããã°æ¡åŒµåãçµµæåã§ãªãçŸå®ã®äžçãèŠãããšãã§ããããšã§ãããããæåŠããèšå®ã¯å€åã§ãããšæããŸãããä»åã¯é¢åãªã®ã§ãã£ãŠããŸãããNginxãªãinternal;
ãšæžãã°ããã ããªã®ã§æ¥œãªãã§ããã
Web Componentsã®è©±
ããŠããããã話ã¯ããã£ãšå€ãããŸãããã®ãŠã§ãããŒãžã®ãœãŒã¹ãèŠããšãã ããããããªæãã«ãªã£ãŠããŸãã
<e-ð£ïž>
<e-1â£>ðð</e-1â£>
</e-ð£ïž>
e-ð£ïž
ãe-1â£
ãšãã£ãèŠæ
£ããªãèŠçŽ ã䜿ãããŠããŸãããèšããŸã§ããªããããCustom Elementsã§ãã
Custom Elementsã¯ãæ°ããèŠçŽ ãèªåã§å®çŸ©ã§ããæ©èœã§ãããã ãããã€ãã£ãã®HTMLèŠçŽ ãšåºå¥ããããã«ãååã«ã¯-
ãå¿
ãå
¥ããå¿
èŠããããŸãããŸããããŒãµãŒãšã®å
Œãåããããã¿ã°åã®æåã®æåã¯ã¢ã«ãã¡ãããã§ãªããã°ãããŸãããæ¬åœã¯å
šéšçµµæåã®ã¿ã°åã«ãããã£ãã®ã§ããããã®ãããªå¶éããe-ð£ïž
ã®ãããªååã«ãªã£ãŠããŸããã¡ãã£ãšèŠèŠããã§ãã仿¹ãããŸããã
ã©ã®ããã«Custom Elementsãå®çŸ©ããŠããã®ãã«ã€ããŠã¯ã詳ããã¯ã³ãŒããèŠãŠãã ãããæŠèŠãšããŠã¯ãããã§ã¯åçŽã«æ¢åã®HTMLèŠçŽ ã«å¯Ÿãããšã€ãªã¢ã¹ã«ãªãããã«ã«ã¹ã¿ã èŠçŽ ãå®çŸ©ããŠããŸããäŸãã°ãe-ð£ïž
ã¯header
èŠçŽ ã«çžåœããŸããe-ð£ïž
èŠçŽ ã¯ããã®shadowããªãŒã«<header><slot></slot></header>
ãšããæ§é ãæã¡ãŸããããã¯èŠããã«<e-ð£ïž></e-ð£ïž>
ã®äžã«å
¥ãããããã®ãå
šéš<header></header>
ã®äžã«çªã£èŸŒãã§è¡šç€ºãããšããããšã§ããããã«ãã£ãŠãe-ð£ïž
ãå®è³ªheader
ã®ããã«æ±ãããšãã§ããŠããŸããã³ãŒããšããŠã¯ä»¥äžã®ãããªæãã«ãªããŸãã
class CustomHeaderElement extends HTMLElement {
constructor() {
super();
// shadow rootããã®èŠçŽ ã«äœæ
this.attachShadow({mode: 'open'});
// shadow rootã®äžã«çœ®ãããã®hedaerèŠçŽ ãäœæ
const innerElement = this.innerElement = document.createElement('header');
// headerèŠçŽ ã®äžã«slotèŠçŽ ãèšçœ®
const slot = document.createElement('slot');
innerElement.appendChild(slot);
// headerèŠçŽ ãshadow rootå
ã«è¿œå
this.shadowRoot.appendChild(innerElement);
}
}
customElements.define('e-ð£ïž', CustomHeaderElement);
ãã€ã³ãã¯ãCustomHeaderElement
ãHTMLElement
ãç¶æ¿ããã¯ã©ã¹ã«ãªã£ãŠããç¹ã§ãããCustom Elementsã¯ãã®ããã«classæ§æãçšããŠäœã£ãã¯ã©ã¹ã§ãªããšåãä»ããããªãã®ã§ããã
å®éã®ã³ãŒãã¯ãã«ã¹ã¿ã èŠçŽ ã«æå®ããã屿§ãå éšã®èŠçŽ ã«äŒéããããã®ã³ãŒããªã©ã远å ãããŠå€å°è€éã«ãªã£ãŠããŸãïŒçŸåšã®ãšãããäŒéããã屿§ã®ååããã¿æžããããšããæ®å¿µãªæ§æãªã®ã§ããïŒã
ãšããã§ãã€ãæè¿ãªãªãŒã¹ãããFirefox 63ãCustom Elementsã«å¯Ÿå¿ãããšããå¬ãããã¥ãŒã¹ããããŸãããããã§ãäž»èŠãã©ãŠã¶ã®äžã§ãŸã 察å¿ããŠããªãã®ã¯Edgeãæ®ãã®ã¿ãšãªããŸãããïŒå®éã®ãšããã¯å¯Ÿå¿ãåºæã£ãŠããŠããã®ã¯äžéšã ãã§ãcustomized built-in elementsã¯ãŸã Chromeãã察å¿ããŠããŸããããïŒ
ãšã¯ããã察å¿ããŠããªããã©ãŠã¶ããããšããããšã§ããã®ãµã€ãã§ã¯Custom Elementsé察å¿ãã©ãŠã¶åãã®åŠçãæžããŠãããŸãïŒè©²åœéšåã®ã³ãŒãïŒã
Custom Elementsã«å¯ŸããPolyfillãšããŠã¯Polymerãæåãªããã«æããŸãããä»åã¯éçãµã€ãã§ããã®ãããããšã«ããããžãé©åœãªå®è£
ã«ãªã£ãŠããŸããããã¯ããããŒãžãèªã¿ããŸãããe-ð£ïž
ãªã©ã®èŠçŽ ãå
ã®èŠçŽ ïŒheader
ïŒã§çœ®æããããšãããã®ã§ããå®ã¯Custom Elementsã«å¯Ÿå¿ããŠããªããã©ãŠã¶ã§ãã<e-ð£ïž>
ã®èŠçŽ ã¯ãæªç¥ã®èŠçŽ ããšããŠæšæ§é äžã«æ®ããŸãããã®ã¹ã¯ãªããã¯ãã®ããšãå©çšããŠããã<e-ð£ïž> ... </e-ð£ïž>
ã®ãããªæ§é ã¯ã¹ã¯ãªããã«ãã£ãŠ<header> ... </header>
ã«çœ®æãããŸããããæ¹ã®é©åœãã¯ããŠãããŠãããã®æ¹æ³ã ãšéçºè
ããŒã«ã§ããŒãžã®æ§é ãèŠããšãã«çµµæåãæ¶ããŠããã®ãæ®å¿µã§ãããCustom Elementsãæå¹ãªãããŒãžã®æ§é å
ã«çµµæåãæ®ã£ãç¶æ
ã«ãªã£ãŠããŸãã
ãããè¡ãéã«ã¯ãCSSãä¿®æ£ããå¿ èŠããããŸããCSSã®ä¿®æ£ãããã¯ãèŠçŽ åã眮æããã ããšããé©åœãªå®è£ ã§ããCSSã¯æ¬¡ã®ããã«çœ®æãããŸãã
body e-ð£ïž e-1⣠{
margin: 1rem 0;
font-size: 4rem;
text-align: center;
}
/* âââââ */
body header h1 {
margin: 1rem 0;
font-size: 4rem;
text-align: center;
}
ãããè¡ã£ãŠããã³ãŒãã¯ãã®èŸºã§ããã³ãŒããèŠããšåãããŸãããCSSStyleRuleçã®selectorText
ã«å¯ŸããŠæåå眮æãè¡ã£ãŠæžãæããããã«ãªã£ãŠããŸãããã®ããã«CSSã®æšæ§é ã«èžã¿èŸŒãã§æžãæããè¡ãã³ãŒããæžãããšã¯ããŸããªããçããã®ã§ã¯ãªãããšæããŸããïŒããã«ããŠã¯ãã£ãŠããããšãé©åœã§ãã仿¹ãããŸãããïŒ
ãŸãšã
ä»åäœæããðð.uhyo.spaceã®äžèº«ã®è§£èª¬ã¯ä»¥äžã§ããç¹ã«ãH2Oã®èšå®ãšCustom Elementsã®å©çšãšãã2ã€ã®ãããã¯ã«è§ŠããŸããã
åŸè ã«ã€ããŠã¯templateãªã©ã䜵çšããã«çŽç²ãªCustom Elementsã®ã¿ãçšããäŸãšãªã£ãŠããŸãã®ã§ããããããåèã«ãªããããããŸããããŸããPolyfillã䜿ããªãïŒéåžžã«é©åœãªïŒæªå¯Ÿå¿ãã©ãŠã¶å¯Ÿå¿ã®äŸã瀺ããŸããã
äœè«ã§ãããðð.uhyo.spaceã®ã³ã³ãã³ãã1ããŒãžäœã£ããçæ°ãå°œããŠããŸããŸããã1ããŒãžã ãã ãšãŠã§ããµã€ããšããŠã¯å¯ããã®ã§ãã³ã³ãã³ããæ¡å ããŠãããæ¹ã¯åžžã«åéäžã§ããGitHubãªããžããªã¯ãã¡ãã§ãã
-
å®ã¯Cloudflareãéã«ã¯ããã§ããã®ã§H2Oãã©ããšãã¯ç¡é¢ä¿ãªãã§ããã â©
-
elsif
ã䜿ãããšããçªã£èŸŒã¿ãå ¥ããããªããããããŸããããããã°ã©ã ããifæãèªåçæããçµæãªã®ã§èš±ããŠãã ããã â© -
ããã¯ðãããããããŒã»ã³ããšã³ã³ãŒãã£ã³ã°ããçµæã§ããURLã®ææ³äžã¯çµµæåãªã©ã®æåã¯èš±ãããŠããããããŒã»ã³ããšã³ã³ãŒãã£ã³ã°ãããŠãããã®ããã©ãŠã¶ã§ããæãã«åŠçããŠãããšããããšã«ãªããŸããMrubyã®ãã³ãã©ã«ãããŠã¯ãããŒã»ã³ããšã³ã³ãŒãã£ã³ã°ããããŸãŸã®ç¶æ ã§æ±ãå¿ èŠãããããã§ãã â©