display: standalone
serviceworker.js
self.addEventListener('fetch', event => {
event.respondWith(async function () {
// ...
}())
})
fetchEvent.respondWith()
const cahce = caches.open(cacheKey)
await cache.put(request, response)
const response = await caches.match(request)
assets-20200129-035507
image-2020-01-29
api-2020-01-29
prefetch
return
if (req.method !== GET) return
if (new URL(req.url).pathname === "/login") return
const { method, url } = event.request
if (method !== 'POST') return
if (new URL(url).pathname === '/serviceworker-upload') {
event.respondWith((async () => {
// POSTリクエストを発行する
})())
}
manifest.json
{
...
"share_target": {
"action": "/serviceworker-upload",
"method": "POST",
"enctype": "multipart/form-data",
"params": { ... }
const req = event.request
try {
// まずはnetworkから取得できるか試みる
return fetch(req.clone())
} catch (err) {
// 失敗したらCacheStorageから探す
return caches.match(req)
navigator.onLine
true
const res = await caches.match(req)
if (res) return res
req.credentials
req.redirect
req.mode
serviceweorker.js
const options = Object.create(null)
if (req.mode !== 'navigate') options.mode = req.mode
if (req.credentials) options.credentials = req.credentials
if (req.redirect) options.redirect = req.redirect
return fetch(req, options)
req.mode === "navigate"
cache.addAll()
cache.add()
Cache-Control: max-age=
javascript
res.ok == false
res.status == 0
res.body == null
request.destination === "image"
"audio"
"video"
request.destination === "video"
event.respondWith((async function () {
// キャッシュを探して...
// 最終的にnetworkから取得
if (req.destination === 'video') return
X-Serviceworker-Cache: true
async function prefetch (urls) {
const { controller } = await navigator.serviceWorker
return new Promise((resolve, reject) => {
const channel = new MessageChannel()
channel.port1.onmessage = event => { resolve(event.data) }
controller.postMessage({
title: 'prefetch',
body: { urls }
}, [channel.port2])
self.addEventListener('message', event => {
event.waitUntil(async function () {
const { urls } = event.data
// 各urlをfetchして cache.put() する
Promise.all(urls.map(async url => {
const response = await fetch(url)
// cache "prefetch" と "api" を更新する
event.ports[0].postMessage({ title: 'prefetch' })
X-Serviceworker-Cache
sw.js
async function findLatestCache (req) {
const cacheNames = await caches.keys()
for (const date of cacheNames.sort().reverse()) {
const cache = await caches.open(date)
const res = await cache.match(req, {ignoreSearch: true})
return null
cache.match(url, {ignoreSearch: true})
const { quota, usage } = await navigator.storage.estimate()
const cache = await caches.open('images')
const reqs = await cache.keys()
// requestを1個ずつ削除する
for (const req of reqs) {
await cache.delete(req.url)
// 仕上げにcache objectを削除
caches.delete("images")
response.ok
Cache-Control: no-store
window.open(url)
"noopener"
"noreferrer"
このプロジェクト外に置いている発表資料など
2018
/scrapbox-drinkup/Scrapbox機能拡張から本体開発へ (daiiz)
/scrapbox-drinkup/地図を埋め込もう (daiiz)
/scrapbox-drinkup/Scrapboxでウェブサイトをつくる (daiiz)
「daiiz-Gyazo」というScrapboxの個人プロジェクトを作って,Gyazoる度に画像を含む新規ページを作成していけば,タグ付けができたりコメントや説明とかを自由に書けてGyazoを拡張した気分になれる?
Gyazoるときに指定するtitleやdescriptionの単語を解析して自動でハッシュタグ化していけば,画像同士が勝手に繋がる便利さを味わえそう.Ivy Searchと組み合わさったらより凄いことになる?
title
description
2017年9月2日
実験してみたところ、使い勝手は良くなかった
リンクの繋がりにより関連する画像を推薦することができるが、画像整理のためだけにガッツリ本文を書きたくなかった
GyaPC::Asia Tokyo 2016
Scrapboxのリリースイベント
当日のメモが private project から発掘された
Scrapboxという新たなWikiでできる共同編集体験と同時に、本体の開発にも興味を持った
仮画像(サムネイル画像)をマウスオーバー(スマホではタップ)したときに,SVGなどのコンテンツをオーバーレイして表示する.
iframeで埋め込むよりも初回の読み込み量が少なく済む.
iframe
埋め込むものが画像なので,制限が少ない.
ifarmeをScrapboxに埋め込むことはできないが,サムネイル画像はいける.このサムネイルの上にメインコンテンツをオーバーレイすることは可能.
ifarme
ifarmeをSlackに埋め込むことはできないが,サムネイル画像はいける.
大量のポスト・イット (正方形の黄色い付箋メモ) を限りなく広い壁空間 (=Scrapbox) に貼り付けていくイメージ
リアルタイムで更新されて,関連度合いに応じて位置関係が張り替えられていく
ポスト・イットは、3M社の商標です.
#Scrapboxの感想
icon記法を使うとチェックリストを作れる
/help/アイコン記法
履修登録
DB論
OS論
tBoard
そのうちReactでやる?
daiiz-apps で管理
https://www.polymer-project.org/2.0/toolbox/
Polymer 2.0でAppをつくる
ページ下部の関連ページが,自分のプロジェクト枠を越えて広がっていくと面白いかもしれない
僕が「React」というページを作ったとする.世の中には僕よりも「React」に詳しい人はたくさんいるはず.そういった人たちが各々の公開プロジェクトでまとめた「React」のページを読んでみたい.
関連ページ機能の拡張
何か知らない単語に出くわしたらその単語のページを作ってみる.他のプロジェクトに既存ページがあれば検索せずとも情報が得られる.
検索 ⊆ 空ページを作る行為
ServiceWorkerの一機能
https://developers.google.com/web/updates/2015/12/background-sync
https://wicg.github.io/BackgroundSync/spec/
window.SyncManagerから使う
window.SyncManager
いまのところChromeのみが実装している
目的・概要
アイデア実験目的で開発しています.
各機能の継続提供や後方互換性が不安定なデモプロジェクトです.
DynamicGazoで作成したコンテンツは SVG Screenshotと共有されます
うまくいった機能はSVG Screenshotに搭載されるかもしれません
Gyazo
とりあえずGyazoっておけば後から整理できる
日常の雑多な画像やスクリーンショットをバンバン保存している
記録しておきたい情報を画像と関連づけて保存しておく
物事を整理できそうな画像ビューワ
コンセプト
画像を次々と眺めるのに適した仕組みを考えている
画像だけでウェブサイトを構築する
リンクの役割
詳しく知りたい範囲を示すためのツール