Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Service Workers — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <!-- Canonical URL for SEO purposes -->
  28. <link rel="canonical" href="https://larlet.fr/david/stream/2015/11/24/">
  29. <style>
  30. /* http://meyerweb.com/eric/tools/css/reset/ */
  31. html, body, div, span,
  32. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  33. a, abbr, address, big, cite, code,
  34. del, dfn, em, img, ins,
  35. small, strike, strong, tt, var,
  36. dl, dt, dd, ol, ul, li,
  37. fieldset, form, label, legend,
  38. table, caption, tbody, tfoot, thead, tr, th, td,
  39. article, aside, canvas, details, embed,
  40. figure, figcaption, footer, header, hgroup,
  41. menu, nav, output, ruby, section, summary,
  42. time, mark, audio, video {
  43. margin: 0;
  44. padding: 0;
  45. border: 0;
  46. font-size: 100%;
  47. font: inherit;
  48. vertical-align: baseline;
  49. }
  50. /* HTML5 display-role reset for older browsers */
  51. article, aside, details, figcaption, figure,
  52. footer, header, hgroup, menu, nav, section { display: block; }
  53. body { line-height: 1; }
  54. blockquote, q { quotes: none; }
  55. blockquote:before, blockquote:after,
  56. q:before, q:after {
  57. content: '';
  58. content: none;
  59. }
  60. table {
  61. border-collapse: collapse;
  62. border-spacing: 0;
  63. }
  64. /* http://practicaltypography.com/equity.html */
  65. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  66. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  67. @font-face {
  68. font-family: 'EquityTextB';
  69. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  70. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  71. font-weight: 300;
  72. font-style: normal;
  73. font-display: swap;
  74. }
  75. @font-face {
  76. font-family: 'EquityTextB';
  77. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  78. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  79. font-weight: 300;
  80. font-style: italic;
  81. font-display: swap;
  82. }
  83. @font-face {
  84. font-family: 'EquityTextB';
  85. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  86. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  87. font-weight: 700;
  88. font-style: normal;
  89. font-display: swap;
  90. }
  91. @font-face {
  92. font-family: 'TriplicateT4c';
  93. src: url('/static/david/css/fonts/Triplicate-T4-Code-Regular-webfont.woff2') format('woff2'),
  94. url('/static/david/css/fonts/Triplicate-T4-Code-Regular-webfont.woff') format('woff');
  95. font-weight: 300;
  96. font-style: normal;
  97. font-display: swap;
  98. }
  99. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  100. body {
  101. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  102. font-family: "EquityTextB", Palatino, serif;
  103. background-color: #f0f0ea;
  104. color: #07486c;
  105. font-kerning: normal;
  106. -moz-osx-font-smoothing: grayscale;
  107. -webkit-font-smoothing: subpixel-antialiased;
  108. text-rendering: optimizeLegibility;
  109. font-variant-ligatures: common-ligatures contextual;
  110. font-feature-settings: "kern", "liga", "clig", "calt";
  111. }
  112. pre, code, kbd, samp, var, tt {
  113. font-family: 'TriplicateT4c', monospace;
  114. }
  115. em {
  116. font-style: italic;
  117. color: #323a45;
  118. }
  119. strong {
  120. font-weight: bold;
  121. color: black;
  122. }
  123. nav {
  124. background-color: #323a45;
  125. color: #f0f0ea;
  126. display: flex;
  127. justify-content: space-around;
  128. padding: 1rem .5rem;
  129. }
  130. nav:first-child {
  131. border-top: 1vh solid #2d7474;
  132. }
  133. nav:last-child {
  134. border-bottom: 1vh solid #2d7474;
  135. }
  136. nav a {
  137. color: #f0f0ea;
  138. }
  139. nav abbr {
  140. border-bottom: 1px dotted white;
  141. }
  142. h1 {
  143. border-bottom: .2vh solid #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 2rem 0 1rem;
  148. width: 100%;
  149. }
  150. h2 {
  151. margin: 4rem 0 1rem;
  152. border-top: .2vh solid #2d7474;
  153. }
  154. h3 {
  155. text-align: center;
  156. margin: 3rem 0 .75em;
  157. }
  158. hr {
  159. height: .4rem;
  160. width: .4rem;
  161. border-radius: .4rem;
  162. background: #07486c;
  163. margin: 2.5rem auto;
  164. }
  165. time {
  166. display: bloc;
  167. background-color: #2d7474;
  168. color: #e3e1e1;
  169. padding: .29rem 1rem;
  170. float: right;
  171. }
  172. ul, ol {
  173. margin: 2rem;
  174. }
  175. ul {
  176. list-style-type: square;
  177. }
  178. a {
  179. text-decoration-skip-ink: auto;
  180. }
  181. article {
  182. max-width: 50rem;
  183. display: flex;
  184. flex-direction: column;
  185. margin: 3rem auto 1rem auto;
  186. }
  187. article p:last-child {
  188. margin-bottom: 1rem;
  189. }
  190. p {
  191. padding: 0 .5rem;
  192. }
  193. p + p {
  194. margin-top: 2rem;
  195. }
  196. blockquote {
  197. background-color: #e3e1e1;
  198. border-left: .5vw solid #2d7474;
  199. display: flex;
  200. flex-direction: column;
  201. align-items: center;
  202. padding: 1rem;
  203. margin: 1.5rem;
  204. }
  205. blockquote cite {
  206. font-style: italic;
  207. }
  208. figure {
  209. border-top: .2vh solid #2d7474;
  210. background-color: #e3e1e1;
  211. text-align: center;
  212. padding: 1.5rem 0;
  213. margin: 1rem 0 0;
  214. font-size: 1.5rem;
  215. width: 100%;
  216. }
  217. figure img {
  218. width: 250px;
  219. height: 250px;
  220. border: .5vw solid #323a45;
  221. padding: 1px;
  222. }
  223. figcaption {
  224. padding: 1rem;
  225. line-height: 1.4;
  226. }
  227. aside {
  228. display: flex;
  229. flex-direction: column;
  230. background-color: #e3e1e1;
  231. padding: 1rem 0;
  232. border-bottom: .2vh solid #07486c;
  233. }
  234. aside p {
  235. max-width: 50rem;
  236. margin: 0 auto;
  237. }
  238. /* https://fvsch.com/code/css-locks/ */
  239. p, li, pre, code, kbd, samp, var, tt, time {
  240. font-size: .95rem;
  241. line-height: calc( 1.5em + 0.2 * 1rem );
  242. }
  243. h1 {
  244. font-size: 1.7rem;
  245. line-height: calc( 1.2em + 0.2 * 1rem );
  246. }
  247. h2 {
  248. font-size: 1.6rem;
  249. line-height: calc( 1.3em + 0.2 * 1rem );
  250. }
  251. h3 {
  252. font-size: 1.35rem;
  253. line-height: calc( 1.4em + 0.2 * 1rem );
  254. }
  255. @media (min-width: 20em) {
  256. /* The (100vw - 20rem) / (50 - 20) part
  257. resolves to 0-1rem, depending on the
  258. viewport width (between 20em and 50em). */
  259. p, li, pre, code, kbd, samp, var, tt, time {
  260. font-size: calc( .95rem + .6 * (100vw - 20rem) / (50 - 20) );
  261. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  262. }
  263. h1 {
  264. font-size: calc( 1.7rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  265. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  266. }
  267. h2 {
  268. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  269. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  270. }
  271. h3 {
  272. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  273. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  274. }
  275. }
  276. @media (min-width: 50em) {
  277. /* The right part of the addition *must* be a
  278. rem value. In this example we *could* change
  279. the whole declaration to font-size:2.5rem,
  280. but if our baseline value was not expressed
  281. in rem we would have to use calc. */
  282. p, li, pre, code, kbd, samp, var, tt, time {
  283. font-size: calc( .95rem + .6 * 1rem );
  284. line-height: 1.5em;
  285. }
  286. h1 {
  287. font-size: calc( 1.7rem + 1.5 * 1rem );
  288. line-height: 1.2em;
  289. }
  290. h2 {
  291. font-size: calc( 1.5rem + 1.5 * 1rem );
  292. line-height: 1.3em;
  293. }
  294. h3 {
  295. font-size: calc( 1.35rem + 1.5 * 1rem );
  296. line-height: 1.4em;
  297. }
  298. figure img {
  299. width: 500px;
  300. height: 500px;
  301. }
  302. blockquote {
  303. margin-left: -1.5rem;
  304. }
  305. }
  306. figure.unsquared {
  307. margin-bottom: 1.5rem;
  308. }
  309. figure.unsquared img {
  310. height: inherit;
  311. }
  312. /* https://github.com/richleland/pygments-css */
  313. .codehilite{
  314. background-color: #fdf6e3;
  315. margin: 1rem auto;
  316. padding: 1rem;
  317. overflow-x:auto;
  318. box-shadow:inset 0 0 2px rgba(0,0,0,0.2)
  319. }
  320. .codehilite .t{color:#586e75}
  321. .codehilite .w{color:#073642}
  322. .codehilite .err{color:#cb4b16}
  323. .codehilite .k{color:#859900}
  324. .codehilite .kc{color:#2aa198}
  325. .codehilite .kd{color:#268bd2}
  326. .codehilite .kn{color:#b58900}
  327. .codehilite .kp{color:#859900}
  328. .codehilite .kr{color:#073642}
  329. .codehilite .kt{color:#b58900}
  330. .codehilite .n{color:#586e75}
  331. .codehilite .na{color:#2aa198}
  332. .codehilite .nb{color:#268bd2}
  333. .codehilite .nc{color:#268bd2}
  334. .codehilite .ne{color:#cb4b16}
  335. .codehilite .no{color:#2aa198}
  336. .codehilite .nd{color:#2aa198}
  337. .codehilite .ni{color:#2aa198;font-weight:bold}
  338. .codehilite .nf{color:#268bd2}
  339. .codehilite .nn{color:#586e75}
  340. .codehilite .nt{color:#2aa198;font-weight:bold}
  341. .codehilite .nv{color:#cb4b16}
  342. .codehilite .b{color:#859900}
  343. .codehilite .bp{color:#586e75}
  344. .codehilite .v{color:#586e75}
  345. .codehilite .vc{color:#586e75}
  346. .codehilite .vg{color:#268bd2}
  347. .codehilite .vi{color:#268bd2}
  348. .codehilite .m{color:#268bd2}
  349. .codehilite .mf{color:#268bd2}
  350. .codehilite .mh{color:#268bd2}
  351. .codehilite .mi{color:#268bd2}
  352. .codehilite .mo{color:#268bd2}
  353. .codehilite .s{color:#2aa198}
  354. .codehilite .sb{color:#2aa198}
  355. .codehilite .sc{color:#2aa198}
  356. .codehilite .sd{color:#2aa198}
  357. .codehilite .s2{color:#2aa198}
  358. .codehilite .se{color:#cb4b16}
  359. .codehilite .sh{color:#2aa198}
  360. .codehilite .si{color:#cb4b16}
  361. .codehilite .sx{color:#2aa198}
  362. .codehilite .sr{color:#cb4b16}
  363. .codehilite .s1{color:#2aa198}
  364. .codehilite .ss{color:#cb4b16}
  365. .codehilite .il{color:#268bd2}
  366. .codehilite .o{color:#586e75}
  367. .codehilite .ow{color:#859900}
  368. .codehilite .p{color:#586e75}
  369. .codehilite .c{color:#93a1a1;font-style:italic}
  370. .codehilite .cm{color:#93a1a1}
  371. .codehilite .cp{color:#93a1a1}
  372. .codehilite .c1{color:#93a1a1}
  373. .codehilite .cs{color:#93a1a1}
  374. .codehilite .hll{background-color:#dc322f}
  375. .codehilite .g{color:#586e75}
  376. .codehilite .gd{color:#586e75}
  377. .codehilite .ge{font-style:italic}
  378. .codehilite .gr{color:#586e75}
  379. .codehilite .gh{color:#586e75;font-weight:bold}
  380. .codehilite .gi{color:#586e75}
  381. .codehilite .go{color:#586e75}
  382. .codehilite .gp{color:#586e75}
  383. .codehilite .gs{font-weight:bold}
  384. .codehilite .gu{color:#586e75;font-weight:bold}
  385. .codehilite .gt{color:#586e75}
  386. @media print {
  387. body { font-size: 100%; }
  388. a:after { content: " (" attr(href) ")"; }
  389. a, a:link, a:visited, a:after {
  390. text-decoration: underline;
  391. text-shadow: none !important;
  392. background-image: none !important;
  393. background: white;
  394. color: black;
  395. }
  396. abbr[title] { border-bottom: 0; }
  397. abbr[title]:after { content: " (" attr(title) ")"; }
  398. img { page-break-inside: avoid; }
  399. @page { margin: 2cm .5cm; }
  400. h1, h2, h3 { page-break-after: avoid; }
  401. p3 { orphans: 3; widows: 3; }
  402. img {
  403. max-width: 250px !important;
  404. max-height: 250px !important;
  405. }
  406. nav, aside { display: none; }
  407. }
  408. /* Dark theme */
  409. [lang=en] body {
  410. background: #323a45;
  411. }
  412. [lang=en] article,
  413. [lang=en] article em,
  414. [lang=en] article strong {
  415. color: #f0f0ea;
  416. }
  417. [lang=en] article a {
  418. color: #ffbd2b;
  419. }
  420. [lang=en] article a:visited {
  421. color: #ff6b03;
  422. }
  423. [lang=en] blockquote,
  424. [lang=en] figure {
  425. background: #111930;
  426. color: #ccc;
  427. }
  428. </style>
  429. <nav>
  430. <p>
  431. <a href="/david/" title="Profil public">David&nbsp;Larlet</a> partage ses <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et sa <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a>.
  432. </p>
  433. </nav>
  434. <h1>Service Workers</h1>
  435. <time>2015-11-24</time>
  436. <article>
  437. <blockquote>
  438. <p>A service worker is a script that is run by your browser in the background, separate from a web page, opening the door to features which don’t need a web page or user interaction. Today, they already include features like <a href="https://developers.google.com/web/updates/2015/03/push-notifications-on-the-open-web">push notifications</a> and in the future it will include other things like, background sync, or geofencing. The core feature discussed in this tutorial is the ability to intercept and handle network requests, including programmatically managing a cache of responses.</p>
  439. <p>The reason this is such an exciting API is that it allows you to support offline experiences, giving developers complete control over what exactly that experience is.</p>
  440. <p><cite><em><a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">Introduction to Service Worker</a></em> (<a href="/david/cache/64fd51915364724e3489270d05a68907/">cache</a>)</cite></p>
  441. </blockquote>
  442. <p><a href="/david/stream/2015/11/08/">Il y a quinze jours</a> je commençais à m’intéresser sérieusement aux <em>Service Workers</em> et depuis <a href="https://adactio.com/journal/9775">Jeremy Keith</a> (<a href="/david/cache/c730e6d1352203b60f954d9850a0dfce/">cache</a>) puis <a href="https://brandonrozek.com/2015/11/service-workers/">Brandon Rozek</a> (<a href="/david/cache/8bd7ed4d765d27a4455c9979db78f203/">cache</a>) ont implémenté leurs premières itérations suivis de près par <a href="https://hacks.mozilla.org/2015/11/offline-service-workers/">une annonce de David Walsh</a> (<a href="/david/cache/855debdfdc494d53ccf8e1939ea85362/">cache</a>) sur le lancement de <a href="https://serviceworke.rs/">serviceworke.rs</a> par Mozilla. Au-delà de l’aspect <em>offline</em> <a href="https://www.theguardian.com/info/developer-blog/2015/nov/04/building-an-offline-page-for-theguardiancom">décrit par le Guardian</a> (<a href="/david/cache/6123a07505f79305c1a46f13131917af/">cache</a>) et <a href="https://css-tricks.com/serviceworker-for-offline/">CSS Tricks</a> (<a href="/david/cache/cafe9b16715f3da507547bbde95f89ac/">cache</a>), on peut aller plus loin comme faire du <a href="https://www.aaron-gustafson.com/notebook/speeding-things-up-with-service-worker-resource-hints-and-more/">chargement dynamique d’images en fonction du support par le navigateur</a> (<a href="/david/cache/3d972c32b16f08bca1aec9f23c059ed0/">cache</a>) ! Même si c’est <a href="http://caniuse.com/#feat=serviceworkers">peu supporté pour l’instant</a>, ça donne envie d’essayer pour ceux qui en ont la capacité (sans effets de bords pour les autres).</p>
  443. <p><strong>Les Service Workers ouvrent clairement une autre dimensions dans le développement web.</strong> Et pourtant, je ne peux m’empêcher de voir les risques associés. Peu de contrôle est laissé à l’utilisateur pour gérer son cache — cette responsabilité étant <a href="https://adactio.com/journal/9844">laissée aux développeurs</a> (<a href="/david/cache/dfe747a193bf51d2fa8680797ab29d7f/">cache</a>) — ce qui signifie que chaque requête coûte potentiellement beaucoup plus que le contenu affiché. Aucun article sus-cité ne mentionne le surcoût en terme de bande passante de télécharger des pages dans le dos de l’utilisateur et pourtant cette pratique va se généraliser. Bientôt des extensions pour limiter un tel usage ?</p>
  444. <p>Si je vais au bout de mon implémentation, je ferais en sorte de laisser le choix au visiteur concernant la taille et le nombre de requêtes à effectuer via les <em>Service Workers</em>. C’est la moindre des choses. <strong>Asynchrone ne veut pas dire gratuit, l’anticipation d’une déconnexion doit rester un choix explicite.</strong> Au passage, j’ai découvert <a href="https://www.talater.com/upup/">upup</a>.</p>
  445. </article>
  446. <nav>
  447. <p>
  448. <a rel=prev href="/david/stream/2015/11/23/">← Écriture et régularité</a> | <a href="/david/stream/2015/" title="Retour à la liste complète">↑</a> | <a rel=next href="/david/stream/2015/11/25/">Pas de favoritisme →</a>
  449. </p>
  450. </nav>
  451. <aside>
  452. <p>
  453. Articles choisis :
  454. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  455. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  456. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  457. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  458. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  459. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  460. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  461. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  462. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  463. <a href="/david/blog/2015/travail-transition/" title="Accéder à l’article complet">Travail en transition</a>,
  464. <a href="/david/blog/2015/pairmutation-travail/" title="Accéder à l’article complet">La pairmutation du travail</a>,
  465. <a href="/david/blog/2015/principes-web/" title="Accéder à l’article complet">Principes Web</a>,
  466. <a href="/david/blog/2015/travail-transition/" title="Accéder à l’article complet">Travail en transition</a>,
  467. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  468. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  469. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  470. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  471. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  472. </p>
  473. </aside>
  474. <nav>
  475. <p>
  476. <abbr title="Lieu de vie et de potentielles rencontres actuel">Montréal</abbr> ·
  477. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">Contact</a> ·
  478. <a href="http://larlet.com" title="Identité professionnelle">[Travailler ensemble ?]</a> ·
  479. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">Hébergeur</abbr> ·
  480. <a href="/david/log/" title="S’abonner aux publications via RSS">Flux</a>
  481. </p>
  482. </nav>
  483. <script>
  484. /* Service workers */
  485. if (navigator.serviceWorker) {
  486. window.addEventListener('load', function () {
  487. var selector = 'a[href^="/david/cache/"], a[rel=prev], a[rel=next]'
  488. function sendLinks (selector) {
  489. var links = [].slice.call(document.querySelectorAll(selector)).map(function (link) {
  490. return link.getAttribute('href')
  491. })
  492. links.push(location.pathname) // Put the current page in cache too.
  493. navigator.serviceWorker.controller.postMessage({ links: links })
  494. }
  495. navigator.serviceWorker.getRegistration()
  496. .then(function (registration) {
  497. if (!registration || !navigator.serviceWorker.controller) {
  498. return navigator.serviceWorker.register('/serviceworker.js')
  499. .then(navigator.serviceWorker.ready)
  500. .then(function () {
  501. console.log('[ServiceWorker] Ready to go!')
  502. })
  503. .catch(console.error.bind(console))
  504. } else {
  505. console.log('[ServiceWorker] Send links via registration')
  506. sendLinks(selector)
  507. }
  508. })
  509. navigator.serviceWorker.addEventListener('controllerchange', function () {
  510. console.log('[ServiceWorker] Send links via controller change')
  511. sendLinks(selector)
  512. })
  513. navigator.serviceWorker.addEventListener('message', function (event) {
  514. var link = document.querySelector('a[href="' + event.data.link + '"]')
  515. if (event.data.status && link) {
  516. link.style.backgroundColor = '#2d7474'
  517. link.style.color = '#f0f0ea'
  518. link.setAttribute('title', 'En cache pour consultation sans connexion')
  519. }
  520. })
  521. })
  522. } else {
  523. console.warn('[ServiceWorker] No cache for old browsers.')
  524. }
  525. </script>