dokieli documentation
- Identifier
- https://dokie.li/docs
- Published
- Modified
- License
- CC BY 4.0
Abstract
This documentation is intended to help brave developers and authors. It explains dokieli's principles, architectural and design patterns.
Document Status
Living document.
Principles
Towards improving the write dimension of the read-write Web, dokieli's design subscribes to the following principles: freedom of expression, interoperability, decentralisation, evolvability, universal access, separation of concerns, █ + █ > = █ █
.
Structure and Semantics
This section describes dokieli's practices, and offers some guidelines for developers and authors that would like to maintain uniformity in what they create. Consumers of dokieli should not treat the information here as a profile, or as a yet another super or subset of HTML+RDFa when they author or build new functionality. Creating articles, annotations, and notifications in dokieli is intended to be done through its UI, where it takes care of majority of the semantic content generation. The information here however can be useful for authors that would like to combine hand coding with the functionality that dokieli's UI provides. Takeaway what you find useful, there is no proprietary lock-in here.
dokieli adopts progressive enhancement strategy for the structural, presentational, and behavioural layers to allow content and base functionality to be accessible through different media and devices. The content in HTML+RDFa that dokieli produces is accessible (readable) without requiring any CSS or JavaScript, ie. text-browser safe. Breaking this "rule" in future development should be considered an anti-pattern (or a bug) in dokieli.
dokieli can serialise articles, annotations, and notifications in HTML+RDFa, Turtle, and JSON-LD, depending on server content-negotiation. Articles are represented in HTML+RDFa so that information is usable by both humans and machine consumers while maintaining lowest requirements for publishing, eg. a single URL with full payload in HTML+RDFa can be accessible from any HTTP server. No additional requirements necessary from clients (eg. JavaScript support and enabled) or servers (eg. additional RDF based content-negotiation). For annotations and notifications, dokieli first meets interoperability requirements (for protocols and vocabularies), and remains flexible about the serialisation that servers prefer. Similarly for consuming content, it can work with any of the serialisations as mentioned.
dokieli takes the approach of having all human-visible content in HTML, and all structured statements be made in context of their content in RDFa. This is optimal in avoiding data duplication in the same document which happens to be the case with the other serialisations in RDF. The approach also helps to avoid the creation and usage of multiple data islands, ie. separately for humans and machines. It is efficient in that it has no dependency on JavaScript in order to make the hidden machine-readable content be consumable from a human user interface. One exception to this rule is allowing authors to use the Embed Data feature to include Turtle, JSON-LD, or TriG data blocks for alternative reasons.
dokieli documents
Is there such thing as a "dokieli" document? Must there be?
- Article
- An article may contain RDF classes like schema:CreativeWork sioc:Post prov:Entity schema:Article, otherwise, there is no unique data that would indicate that it is a "dokieli" document. If the HTML+RDFa representation includes dokieli.js and the DOM is ready, the
DO
:Object { C: {…}, U: {…} }
will be available. - Annotation
- An annotation has the
oa:Annotation
class. It is possible to know that the article was rendered by dokieli:?s oa:renderedVia <https://dokie.li/>
, and we can assume that the annotation was created by it as well. This is not strictly true since that property could have been put there by something else. Annotations represented in HTML+RDFa do not include dokieli.js. - Notification
- A notification may have one of the following classes:
as:Announce
,as:Like
,as:Dislike
,as:Relationship
. Notifications represented in HTML+RDFa do not include dokieli.js.
HTML patterns
One of the goals of dokieli is not to impose arbitrary restrictions on type of nodes as well as the order they should be in HTML+RDFa. It has its own design patterns. It is an ongoing work to make dokieli as flexible as it can be on what it can consume. Ultimately, well-formed and valid HTML - along with accompanying RDFa, Turtle, JSON-LD, TriG etc - is the only requirement here. Take what you like:
- Markup syntax
- HTML5 Polyglot Markup is used to ensure that when content is processed or served as HTML or XHTML (
text/html
,application/xhtml+xml
), they can generally be used in both HTML and XML ecosystems without further intervention. See also getDocument (dokieli.js) for details on DOM normalisation. - Identifiers
- Unique identifiers (
@id
) may be placed on any element. Identifiers are auto-generated by normalising some input eg.section
s use their heading's text content as input,table
s fromcaption
. Anything of importance should have an identifier, and aimed to be included for common patterns out of the box.@id
values are reused in RDFa. See also generateAttributeId (dokieli.js) and its application in different places. - Outline
-
title
is used.main > article
(querySelector) is considered to be the location of the primary content.h1
is typically the first element node aftermain > article
- There is a resource type, eg.
schema:Article
that can be found inmain > article
which is about the article.body
may contain broad classes.
- Section
- Sectioning is declared with
section
and typically have a heading, eg.h2
as its first child. Subsections may appear as a child of parentsection
, or as a child ofdiv
(which is a child of parentsection
), ie.section section
orsection div section
. The headings of subsections are enumerated eg.section h2
would have a subsection withsection h3
. Sectionsid
s and heading text are used to dynamically build the table of contents. - Aside
aside
s can technically appear anywhere, but tend to appear as the last element node insection
, eg. for related content, footnotes. If theaside
is introduced to the DOM via JavaScript for like annotations, they have a similar structure tosection
.- Division
div
s withinsection
are used to wrap a block of arbitrary markup and content. See also RDFa below.- Figure
figure
s typically havefigcaptions
for things likeaudio
,canvas
,iframe
,img
,object
,pre
,video
,math
. For code scripts,figure class="listing"
is used, andpre
for the code itself withcode
Thelisting
class is intended to have a collection of figures, which could also have a unique presentation, for example with line numbers or have its caption be prefixed withListing
and counter.Comparison of systems d1 d2 d3 m1 Foo m o n 1 Bar k e y 2 Baz ! @ # 3 Table columns list the dimensions: d1, d2, d3, and the measure: m1. - Math
- For mathematical equations
figure class="equation"
can be used to hint at an equation display. MathML base equation with<math xmlns="http://www.w3.org/1998/Math/MathML">
root can be included here (see also source). Alternatively, if MathJax JavaScript is available in the document, (La)TeX, eg. \lim_{x \to \infty} \exp(-x) = 0 and ASCIIMath, eg. sum_(i=1)^n i^3=((n(n+1))/2)^2, syntaxes can be input within the authoring mode (via Edit). - Embedding Turtle, JSON-LD, and TriG
- Turtle, JSON-LD, and TriG syntaxes are placed within respective
script
blocks inhead
eg.<script id="meta-json-ld" type="application/ld+json" title="JSON-LD"></script>
. Data is enclosed inCDATA
sections. This pattern is detected, visible and editable from Embed Data in dokieli menu. See also showEmbedData (dokieli.js). - CSS
- Multiple stylesheets can be included with
@media
, and when accompanied with@title
, some user-agents can provide options for the user to switch between them, as well as from the dokieli menu, eg.<!-- Primary stylesheet -->
See also showViews (dokieli.js).<link href="media/css/basic.css" media="all" rel="stylesheet" title="Basic" />
<!-- Alternate stylesheet --><link href="media/css/acm.css" media="all" rel="stylesheet alternate" title="ACM" />
<!-- Applied by default--><link href="https://dokie.li/media/css/dokieli.css" media="all" rel="stylesheet" />
- RDFa
- dokieli can consume and produce RDFa Core 1.1 syntax.
- To preserve the order of content,
@inlist
is used eg.<section inlist=""
,<dd id="Sarven-Capadisli" inlist="" rel="bibo:authorList" resource="http://csarven.ca/#i">
. - A
section
s@id
value is used as part ofsection
's@resource
as a fragment, eg.<section id="introduction" rel="schema:hasPart" resource="#introduction">
. This allows the same identifier to be used for humans and machines, the value is derived from normalising its heading value as mentioned earlier. - Relating parts is done with
rel="schema:hasPart"
, eg. sections with subsection:<section id="structure-and-semantics" inlist="" rel="schema:hasPart" resource="#structure-and-semantics">
<section id="html-patterns" inlist="" rel="schema:hasPart" resource="#html-patterns">
div
s are used to hold a block of HTML markup and types of content together eg.<div datatype="rdf:HTML" property="schema:description" resource="#introduction" typeof="deo:Introduction">
makes it possible to declare that it contains HTML markup, and describes an introductory text.- Some of the prefixes (
@prefix
) on thebody
element are defined in the RDFa Core Initial Context. These prefixes are defined in dokieli for the purpose of being compact, robust, and to minimise potential errors for consumers.
Note
There is a work in progress to have a distribution version of dokeli, requiring only dokieli.css and dokieli.js in templates.
Servers should use UTF-8
character encoding in their HTTP responses to articles, annotations, and notifications. <meta charset="utf-8" />
is used in HTML.
Article
See also createNoteDataHTML (dokieli.js)
The subject of the following statements may be anywhere in a document. They tend to give some provenance level information and intended to bring more context and attract reuse of the document in different ways.
<dl id="document-identifier">
<dt>Identifier</dt>
<dd><a href="http://csarven.ca/dokieli-rww" rel="owl:sameAs">http://csarven.ca/dokieli-rww</a></dd>
</dl>
The owl:sameAs
indirectly gives this article, ie. any copy, an identifier. The identifier is typically where an article was originally made accessible from, so having this by default for copy distribution helps to keep its connection to source.
<dl id="document-inbox">
<dt>Notifications Inbox</dt>
<dd><a href="https://linkedresearch.org/inbox/csarven.ca/dokieli-rww/" rel="ldp:inbox">inbox/</a></dd>
</dl>
ldp:inbox
relation gives an article its own Inbox where it can receive notifications about eg. annotations or activities relevant to an article. The notifications can be consumed by applications to offer additional content and interactive possibilities. dokieli can both send and consume notifications by way of discovering an article's inbox. Notifications are created for activities like announcements, creating, (dis)liking, and consumed in order to be displayed in context of available content. The protocol to send and consume notifications in dokieli uses Linked Data Notifications.
<dl id="document-annotation-service">
<dt>Annotation Service</dt>
<dd><a href="https://linkedresearch.org/annotation/csarven.ca/dokieli-rww/" rel="oa:annotationService">annotation/</a></dd>
</dl>
An article may refer to an annotation service (oa:annotationService
) that conforms to the Web Annotation Protocol. See also DO.C.AnnotationService in dokieli.js
.
<dl id="document-in-reply-to">
<dt>In Reply To</dt>
<dd><a href="https://linkedresearch.org/calls" rel="as:inReplyTo">Call for Linked Research</a></dd>
</dl>
If an article is a reply to objects(s), it can have a property like as:inReplyTo
.
<dl id="document-published">
<dt>Published</dt>
<dd><time content="2017-02-27T00:00:00Z" datatype="xsd:dateTime" datetime="2017-02-27T00:00:00Z" property="schema:datePublished">2017-02-27</time></dd>
</dl>
<dl id="document-modified">
<dt>Modified</dt>
<dd><time content="2017-03-12T00:00:00Z" datatype="xsd:dateTime" datetime="2017-03-12T00:00:00Z" property="schema:dateModified">2017-03-18</time></dd>
</dl>
Dates, you know.. kinda useful. The example above duplicates the ISO date in @content
and @datetime
, but only one needs to be there, given that there parsers for different RDFa versions.
<dl id="document-license">
<dt>License</dt>
<dd><a href="https://creativecommons.org/licenses/by/4.0/" rel="schema:license" title="Creative Commons Attribution 4.0 Unported">CC BY 4.0</a></dd>
</dl>
Nice to declare a license or rights to signal under what conditions the document may be reused, reshared or remixed, eg. via Creative Commons license. Articles and notifications tend to use schema:license
and annotations use dcterms:rights
(given Web Annotation Vocabulary).
<dl id="document-derived-from">
<dt>Derived From</dt<
<dd><a href="https://dokie.li/" rel="prov:wasDerivedFrom">https://dokie.li/</a></dd>
</dl>
<dl id="document-derived-on">
<dt>Derived On</dt>
<dd><time datetime="2017-08-06T00:29:45.342Z">2017-08-06T00:29:45.342Z</time></dd>
</dl>
If a document is derived from another using the Save As operation, derived from and derived on information is declared.
The markup for an anonymous profile is like:
<span typeof="schema:Person">Lunatic Scholar</span>
The markup for a WebID profile including their name:
<span about="http://csarven.ca/#i" property="schema:name">Sarven Capadisli</span>
If they have an image:
<img alt="" height="48" rel="schema:image" src="http://csarven.ca/media/images/sarven-capadisli.jpg" width="48" />
Progressively described name, image, and URL is useful in templates:
<span about="http://csarven.ca/#i" typeof="schema:Person"><img alt="" height="48" rel="schema:image" src="http://csarven.ca/media/images/sarven-capadisli.jpg" width="48" /> <a href="http://csarven.ca/" rel="schema:url"><span about="http://csarven.ca/#i" property="schema:name">Sarven Capadisli</span></a></span>
Alternatively applying the DRY principle:
<a about="http://csarven.ca/#i" href="http://csarven.ca/" property="schema:name" rel="schema:url" typeof="schema:Person">Sarven Capadisli</a>
If they are one of the authors of a document, the profile can be wrapped like:
<dd id="Sarven-Capadisli" inlist="" rel="bibo:authorList" resource="http://csarven.ca/#i"><span about="" rel="schema:creator schema:publisher schema:author"><!-- profile --></span></dd>
See also getUserHTML (dokieli.js)
Annotation
Annotations have their own URL, fetched, parsed, and then introduced into the DOM. They are normally appended at the bottom of a node (section
) in which the annotation has a reference to. It is not required to introduce all of the annotation content into the DOM, nor all of it has to be human-visible. This is a run-time inclusion and typically included within <aside class="note do"></aside>
. Write operations like Save, Save As, Export will exclude this (class~="do"
) when it normalises the DOM to HTML.
Currently dokieli uses oa:replying, oa:commenting, oa:describing, oa:assessing, oa:bookmarking for motivations, and oa:describing and oa:tagging for annotation purpose.
See also createNoteDataHTML (dokieli.js)
Here is an annotation resource at https://linkedresearch.org/annotation/csarven.ca/dokieli-rww/b6738766-3ce5-4054-96a9-ced7f05b439f with all information human-visible and machine-readable (HTML+RDFa):
Its source:
<dl class="canonical">
<dt>Canonical</dt>
<dd rel="oa:canonical" resource="urn:uuid:48355bb0-0afd-4f73-9a18-f1e8b6fb415b">48355bb0-0afd-4f73-9a18-f1e8b6fb415b</dd>
</dl>
oa:canonical
refers to a canonical IRI that can be used to deduplicate the annotation. If an user chooses to store their annotation at their personal Webspace as well as when an annotation service (if offered), dokieli treats the resource at personal space as the canonical, and the resource at the annotation service as the copy where it refers to the personal space (oa:via
).
If an annotation resource is introduced to the article's DOM as part of an aside
, they have a structure similar to an article
, and may be displayed in different ways, eg. in marginalia:
<aside class="note do">
<blockquote cite="https://linkedresearch.org/annotation/csarven.ca/dokieli-rww/b6738766-3ce5-4054-96a9-ced7f05b439f">
<article about="i:" id="461819979" prefix="i: https://linkedresearch.org/annotation/csarven.ca/dokieli-rww/b6738766-3ce5-4054-96a9-ced7f05b439f" typeof="oa:Annotation">
<!-- Reconstruction of the original annotation (from RDF) -->
</article>
</blockquote>
</aside>
An inline reference to that annotation as aside would have a structure like:
<span class="ref do" rel="schema:hasPart" resource="#r-461819979" typeof="dctypes:Text"><mark id="r-461819979" property="schema:description">demonstrating advanced document authoring and interaction without a single point of control</mark><sup class="ref-annotation"><a rel="cito:hasReplyFrom" href="#461819979" resource="https://linkedresearch.org/annotation/csarven.ca/dokieli-rww/b6738766-3ce5-4054-96a9-ced7f05b439f">💬</a></sup></span>
Note that the human-visible anchor hyperlinks (#461819979) to the annotation aside id="461819979"
.
Notification
Notifications are discovered from LDN Inboxes. An article (or a fragment within) may have an inbox relation (ldp:inbox
) which helps dokieli to discover it, and then fetch the notifications.
Notifications are intended to be brief, giving sufficient information for consumers to decide if they want use to them. If the notifications are generated by dokieli, eg. via an annotation activity, they typically include some provenance level data like generation date, actor that triggered it, license, where the annotation can be found, what it annotated, and the motivation for it. Notifications will not include the annotation body, but consumers can fetch their URLs (as mentioned in the annotation section).
See also createNoteDataHTML (dokieli.js)
Here is a notification resource at https://linkedresearch.org/inbox/csarven.ca/dokieli-rww/b6738766-3ce5-4054-96a9-ced7f05b439f with all information human-visible and machine-readable (HTML+RDFa):
Its source:
User interface
Document modes
There UI adapts to the document mode the user is in: author, review, social. By default the social mode is engaged. The dokieli menu allows the user to engage the author mode through the Edit operation, and the review mode with Review. See also setDocumentMode (dokieli.js).
Accessibility, Usability, and Inclusion
Accessibility Statement
Measures to support accessibility
dokieli takes the following measures to ensure accessibility of dokieli:
- Include accessibility throughout our internal policies.
- Assign clear accessibility goals and responsibilities.
- Employ formal accessibility quality assurance methods.
Conformance status
The Web Content Accessibility Guidelines (WCAG) defines requirements for designers and developers to improve accessibility for people with disabilities. It defines three levels of conformance: Level A, Level AA, and Level AAA. dokieli is partially conformant with WCAG 2.1 level AA. Partially conformant means that some parts of the content do not fully conform to the accessibility standard.
Feedback
We welcome your feedback on the accessibility of dokieli. Please let us know if you encounter accessibility barriers on dokieli issues.
Technical specifications
Accessibility of dokieli relies on the following technologies to work with the particular combination of web browser and any assistive technologies or plugins installed on your computer:
- HTML
These technologies are relied upon for conformance with the accessibility standards used.
Assessment approach
dokieli assessed the accessibility of dokieli by the following approaches:
- Self-evaluation
HTTP operations
dokieli conforms to Linked Data Platform (LDP) protocol for create, update, and delete operations.
Article operations like New, Save, Save As, Reply use HTTP PUT
, Review and other annotation operations use HTTP POST
.
Notifications are sent with HTTP POST
. Save and Save As normalises the HTML before sending.
HTTP method(s) | Content-Type |
|
---|---|---|
Article | PUT | text/html |
Annotation | OPTIONS , POST | text/html , application/ld+json , text/turtle |
Notification | OPTIONS , POST | text/html , application/ld+json , text/turtle |
|
Due to Mixed Content implementations in Web browsers, ie. fetching of content over unencrypted or unauthenticated connections in the context of an encrypted and authenticated document
, is subject to being blocked by the Web browser. Hence, an https document (eg article at https) will not be able to use the contents of an http document (eg. an http WebID). As a workaround, dokieli uses a proxy endpoint by default in order to use the contents of an http resource. An https document fetching an https resource will not use the proxy.
Authentication
dokieli was originally intended to handle different authentication mechanisms. WebID-TLS is currently supported to authenticate with servers.
Storage
- Personal storage
- WebID's with
pim:storage
can get to use their personal online data storage with dokieli's read-write operations, eg all annotations, Reply, Review, New, Save As. - Local storage
- There is a Local Storage feature which uses user-agent's window.localStorage, with default 1m autosave.
Web Extension
The dokieli Web Extension is a minimal package of dokieli which contains the core CSS and JavaScript that works as a browser add-on. When user triggers it from their browser toolbar, it provides the same functionality as a single-page application, ie. initialised and rendered in the browser DOM.
Currently the extension works with Firefox and Chrome/Chromium browsers. Two ways to do this:
- Extensions are available from Add-ons for Firefox and Chrome Web Store.
- Clone https://github.com/linkeddata/dokieli and import directory:
- Firefox:
Load Temporary Add-on
from Add-ons (or go toabout:debugging
from addressbar) and import by selecting a file from the directory (eg manifest.json). See also temporary add-on installation. - Chrome/Chromium: Check the
developer more
option, under Extensions (or go tochrome://extensions/
from addressbar) and import the directory.
- Firefox:
Development
git clone https://github.com/linkeddata/dokieli
cd dokieli
# Install packages
npm install
# Build stuff eg. scripts/dokieli.js
npm run build
# or automatically rebuild when files change
npm run watch