A place to cache linked articles (think custom and personal wayback machine)
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.html 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Web of Documents (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f0f0ea">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f0f0ea">
  26. <!-- Documented, feel free to shoot an email. -->
  27. <link rel="stylesheet" href="/static/david/css/style_2020-06-19.css">
  28. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  29. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <script type="text/javascript">
  36. function toggleTheme(themeName) {
  37. document.documentElement.classList.toggle(
  38. 'forced-dark',
  39. themeName === 'dark'
  40. )
  41. document.documentElement.classList.toggle(
  42. 'forced-light',
  43. themeName === 'light'
  44. )
  45. }
  46. const selectedTheme = localStorage.getItem('theme')
  47. if (selectedTheme !== 'undefined') {
  48. toggleTheme(selectedTheme)
  49. }
  50. </script>
  51. <meta name="robots" content="noindex, nofollow">
  52. <meta content="origin-when-cross-origin" name="referrer">
  53. <!-- Canonical URL for SEO purposes -->
  54. <link rel="canonical" href="http://blog.danieljanus.pl/2019/10/07/web-of-documents/">
  55. <body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick">
  56. <article>
  57. <header>
  58. <h1>Web of Documents</h1>
  59. </header>
  60. <nav>
  61. <p class="center">
  62. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  63. <a href="http://blog.danieljanus.pl/2019/10/07/web-of-documents/" title="Lien vers le contenu original">Source originale</a>
  64. </p>
  65. </nav>
  66. <hr>
  67. <main>
  68. <p>In 1960, Ted Nelson envisioned a&nbsp;web of documents.</p>
  69. <p>It was called <a href='https://en.wikipedia.org/wiki/Project_Xanadu'>Xanadu</a>. It was a&nbsp;grand, holistic vision: of documents that, once published, are available basically forever; of bidirectional links that could glue together not just documents, but parts thereof; of managing copyright and royalties. It was complex. And it never really came to&nbsp;fruition.</p>
  70. <p>But thirty-one years later, another web of documents took off. A&nbsp;much more modest undertaking than Xanadu, with a&nbsp;simple markup language, simple protocol to&nbsp;retrieve the documents, unidirectional, ever-rotting links, and not much else. The World Wide Web. It was prototyped by one man in a&nbsp;few months. And then its popularity exploded.</p>
  71. <p>As the WWW spread, it grew features. Soon, it was not enough for the documents to&nbsp;contain just text: support for images was added. People wanted to&nbsp;customize the look of the documents, so HTML gained presentational markup abilities, eventually obsoleted by CSS. It was not enough to&nbsp;be able to&nbsp;view the menu of your local pizza store – people wanted to&nbsp;actually order a&nbsp;pizza: the need for sessions yielded cookies and non-idempotent HTTP methods. And people wanted the pages to&nbsp;be interactive, so they became scriptable.</p>
  72. <p>All these features were good. They helped the Web meet actual needs. But having them has a&nbsp;significant consequence, one that is seldom realized:</p>
  73. <p>We&nbsp;don’t have a&nbsp;Web of Documents anymore.</p>
  74. <p>Let me pause at this point. I’ve been using the word “document” intuitively and vaguely so far, so let’s try to&nbsp;pinpoint it. I&nbsp;don’t have a&nbsp;precise definition in mind, but I’ll share some examples. A&nbsp;book is a&nbsp;document, to&nbsp;me. So is a&nbsp;picture, an illustrated text, a&nbsp;scientific paper, a&nbsp;MP3 song, or a&nbsp;video. By contrast, a&nbsp;page that lets you play Tetris isn’t. The essence of this distinction seems to&nbsp;be that documents have well-defined <i>content</i> that does not change between viewings and does not depend on the state of the outside world. A&nbsp;document is stateless. It exists in and of itself; it is its own microcosm. It may be experienced interactively, but only insofar as it enables the experiencer to&nbsp;focus their attention on the part of their own choosing; the potential state of that interaction is external to&nbsp;the document, not part of itself.</p>
  75. <p>Obviously, this is not very accurate: there are border cases. For example, does a&nbsp;film DVD with a&nbsp;menu qualify as a&nbsp;document? Or how about a&nbsp;choose-your-own-adventure book? Or a&nbsp;HTML page with links to&nbsp;other pages? On the surface, the latter does provide out-of-microcosm interactivity; but viewed from another angle, it is no different than putting a&nbsp;reference in a&nbsp;book. The browser just makes it very easy to&nbsp;go to&nbsp;a&nbsp;shelf and pick another book.</p>
  76. <p>The distinction is there, and it’s important. And with it in mind, let me reiterate:</p>
  77. <p><i>We&nbsp;don’t have a&nbsp;Web of Documents anymore.</i></p>
  78. <p>These days, the WWW is mostly a&nbsp;<i>Web of Applications</i>. An application is a&nbsp;broader concept: it can display text or images, but also lets you interact not just with itself, but with the world at large. And that’s all well and good, as long as you consciously intend these interactions to&nbsp;happen.</p>
  79. <p>A&nbsp;document is safe. A&nbsp;book is safe: it will not explode in your hands, it will not magically alter its contents tomorrow, and if it happens to&nbsp;be illegal to&nbsp;possess, it will not call the authorities to&nbsp;denounce you. You can implicitly trust a&nbsp;document by virtue of it being one. An application, not so much.</p>
  80. <p>I&nbsp;don’t want to&nbsp;name names, but it’s all too easy these days to&nbsp;follow a&nbsp;link to&nbsp;a&nbsp;news site, expecting an article, only to&nbsp;be greeted with “You have read N articles this month, please register to&nbsp;continue”. Definitely an application-y thing to&nbsp;say, not a&nbsp;document-y one. Now, the purveyors of such sites typically have legitimate economic interest in doing so—but once you sign up, they are able to&nbsp;record your actions, link them with your identity and build your shadow profile. This way, we&nbsp;have applications actively <i>masquerading</i> as documents, when in reality they <i>do&nbsp;non-documenty things</i> without telling you.</p>
  81. <p>Legislation such as the EU Cookie Law and the GDPR (insofar as it requires disclosure of data processing) tries to&nbsp;remedy this. But the more I&nbsp;think about it, the more sense it makes to&nbsp;me to&nbsp;attack the problem closer to&nbsp;its root: to&nbsp;decomplect the notions of a&nbsp;document and an application; to&nbsp;keep the Web of Applications as it is, and to&nbsp;recreate a&nbsp;Web of Documents—either parallel to&nbsp;it, or as its sub-web.</p>
  82. <p>To&nbsp;do&nbsp;this, we&nbsp;need to&nbsp;take a&nbsp;step back. (Or do&nbsp;a&nbsp;clean start and invent a&nbsp;whole new technology, but this is unlikely to&nbsp;succeed). Fortunately, we&nbsp;don’t have to&nbsp;travel all the way back to&nbsp;1992, when the WWW was still a&nbsp;Web of Documents. (I&nbsp;still remember table-based layouts and spacer gifs, and the very memory makes me shudder). I&nbsp;think we&nbsp;can base the new Web of Documents on ol’ trusty HTTP (or, better, HTTPS), HTML and CSS as we&nbsp;know them today, with just three restraints:</p>
  83. <ol><li><i>No methods other than GET</i> (and perhaps HEAD). POST, PUT, DELETE and friends just have no place in a&nbsp;world of documents. They are not idempotent; they potentially modify the state of the world, which documents should not be able to&nbsp;do. (I&nbsp;was also thinking “no forms”, but with #1 in place, it seems like an unnecessary refinement. After all, forms that translate to&nbsp;GET requests just facilitate creating URLs: a&nbsp;user could just as well have typed the resulting URL by hand.)</li><li><i>No scripts of any kind.</i> Not JavaScript, not WebAssembly. Not even to&nbsp;enrich a&nbsp;document, such as syntax-highlight the code snippets. This one may seem too stringent, but I&nbsp;think it’s better to&nbsp;err on the safe side, and it’s very easy to&nbsp;enforce.</li><li><i>No cookies.</i> Cookies by themselves aren’t interactive, but having them makes it all too easy to&nbsp;abuse the semantics of HTTP to&nbsp;recreate sessions, and on top of them reinvent the app-wheel and eventually forfeit the Web of Documents again.</li></ol>
  84. <p>Again, there may be corner cases that may have escaped me. But if a&nbsp;WWW page conforms to&nbsp;these restrictions, I&nbsp;think it may be pretty safe to&nbsp;call it a&nbsp;“document” and make it a&nbsp;part of the Web of Documents.</p>
  85. <p>How do&nbsp;we&nbsp;achieve this? I&nbsp;don’t know, really. I&nbsp;don’t have a&nbsp;concrete proposal. Perhaps we&nbsp;could have dedicated browsers for the WoD; perhaps we&nbsp;could make existing browsers prominently advertise to&nbsp;the user whether they are browsing a&nbsp;document or an application. On top of all the technical decisions to&nbsp;make, there’ll be significant campaigning and lobbying needed if the idea is ever to&nbsp;take off.</p>
  86. <p>I&nbsp;don’t dare dream that it ever will. My intent in this article is to&nbsp;provide food for thought. All I&nbsp;ask from you, my reader, is consideration and attention. And if you got this far, chances are I&nbsp;got them. I’m grateful.</p>
  87. <p>This page is a&nbsp;document. Thank you for reading it.</p>
  88. </main>
  89. </article>
  90. <hr>
  91. <footer>
  92. <p>
  93. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  94. <a href="/david/log/" title="Accès au flux RSS">🤖</a> •
  95. <a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> •
  96. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> •
  97. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr>
  98. </p>
  99. <template id="theme-selector">
  100. <form>
  101. <fieldset>
  102. <legend>Thème</legend>
  103. <label>
  104. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  105. </label>
  106. <label>
  107. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  108. </label>
  109. <label>
  110. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  111. </label>
  112. </fieldset>
  113. </form>
  114. </template>
  115. </footer>
  116. <script type="text/javascript">
  117. function loadThemeForm(templateName) {
  118. const themeSelectorTemplate = document.querySelector(templateName)
  119. const form = themeSelectorTemplate.content.firstElementChild
  120. themeSelectorTemplate.replaceWith(form)
  121. form.addEventListener('change', (e) => {
  122. const chosenColorScheme = e.target.value
  123. localStorage.setItem('theme', chosenColorScheme)
  124. toggleTheme(chosenColorScheme)
  125. })
  126. const selectedTheme = localStorage.getItem('theme')
  127. if (selectedTheme && selectedTheme !== 'undefined') {
  128. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  129. }
  130. }
  131. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  132. window.addEventListener('load', () => {
  133. let hasDarkRules = false
  134. for (const styleSheet of Array.from(document.styleSheets)) {
  135. let mediaRules = []
  136. for (const cssRule of styleSheet.cssRules) {
  137. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  138. continue
  139. }
  140. // WARNING: Safari does not have/supports `conditionText`.
  141. if (cssRule.conditionText) {
  142. if (cssRule.conditionText !== prefersColorSchemeDark) {
  143. continue
  144. }
  145. } else {
  146. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  147. continue
  148. }
  149. }
  150. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  151. }
  152. // WARNING: do not try to insert a Rule to a styleSheet you are
  153. // currently iterating on, otherwise the browser will be stuck
  154. // in a infinite loop…
  155. for (const mediaRule of mediaRules) {
  156. styleSheet.insertRule(mediaRule.cssText)
  157. hasDarkRules = true
  158. }
  159. }
  160. if (hasDarkRules) {
  161. loadThemeForm('#theme-selector')
  162. }
  163. })
  164. </script>
  165. </body>
  166. </html>