├── .ackrc ├── .gitignore ├── .jscsrc ├── .jshintignore ├── .jshintrc ├── .travis.yml ├── .tx └── config ├── AUTHORS ├── CHANGES.rst ├── HACKING.rst ├── LICENSE ├── LICENSE-GPL ├── LICENSE-MIT ├── Makefile ├── README.rst ├── browser.js ├── contrib ├── annotator_badge.png ├── bookmarklet │ ├── bookmarklet.js │ └── bookmarklet_spec.js └── chrome │ ├── background.js │ └── content.js ├── css └── annotator.css ├── demo.html ├── dev.html ├── doc ├── Makefile ├── _static │ └── .placeholder ├── api │ ├── app.rst │ ├── authz.rst │ ├── identity.rst │ ├── index.rst │ ├── notification.js │ ├── notification.rst │ ├── registry.rst │ ├── storage.rst │ ├── ui.rst │ └── ui │ │ ├── main.rst │ │ ├── markdown.rst │ │ └── tags.rst ├── changes.rst ├── conf.py ├── glossary.rst ├── index.rst ├── installing.rst ├── internationalization.rst ├── make.bat ├── module-development.rst ├── modules │ ├── authz.rst │ ├── identity.rst │ ├── index.rst │ ├── storage.rst │ └── ui.rst ├── requirements.txt ├── roadmap.rst ├── upgrading.rst └── usage.rst ├── img ├── annotator-glyph-sprite.png └── annotator-icon-sprite.png ├── index.js ├── karma.conf.js ├── locale ├── Makefile ├── annotator.pot ├── de_DE │ └── annotator.po ├── et │ └── annotator.po ├── fr │ └── annotator.po ├── ru │ └── annotator.po └── zh_CN │ └── annotator.po ├── manifest.json ├── package.json ├── src ├── app.js ├── authz.js ├── identity.js ├── notification.js ├── preamble.js ├── registry.js ├── storage.js ├── ui.js ├── ui │ ├── adder.js │ ├── editor.js │ ├── filter.js │ ├── highlighter.js │ ├── main.js │ ├── markdown.js │ ├── tags.js │ ├── textselector.js │ ├── viewer.js │ └── widget.js └── util.js ├── test ├── .jscsrc ├── .jshintrc ├── fixtures │ ├── adder.html │ ├── annotator.html │ ├── delegator.html │ └── viewer.html ├── helpers.js ├── init.js └── spec │ ├── app_spec.js │ ├── authz_spec.js │ ├── browser_spec.js │ ├── identity_spec.js │ ├── notification_spec.js │ ├── registry_spec.js │ ├── storage │ ├── httpstorage_spec.js │ └── storageadapter_spec.js │ ├── ui │ ├── adder_spec.js │ ├── editor_spec.js │ ├── filter_spec.js │ ├── highlighter_spec.js │ ├── main_spec.js │ ├── markdown_spec.js │ ├── tags_spec.js │ ├── textselector_spec.js │ ├── viewer_spec.js │ └── widget_spec.js │ └── util_spec.js └── tools ├── apidoc ├── authors ├── cssify.js ├── js2rst ├── lint ├── make_release ├── preamble ├── push_next └── serve /.ackrc: -------------------------------------------------------------------------------- 1 | --ignore-dir=lib 2 | --ignore-dir=pkg 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .deps/ 3 | doc/_build/ 4 | node_modules/ 5 | pkg/ 6 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "es3": true, 3 | "excludeFiles": [ 4 | "node_modules/**", 5 | "lib/**", 6 | "pkg/**", 7 | "src/bootstrap.js" 8 | ], 9 | "requireCurlyBraces": true, 10 | "requireSpaceAfterKeywords": true, 11 | "requireSpaceBeforeBlockStatements": true, 12 | "requireParenthesesAroundIIFE": true, 13 | "requireSpacesInConditionalExpression": true, 14 | "disallowPaddingNewlinesInBlocks": true, 15 | "disallowSpacesInsideObjectBrackets": true, 16 | "disallowSpacesInsideArrayBrackets": true, 17 | "disallowSpacesInsideParentheses": true, 18 | "disallowSpaceAfterObjectKeys": true, 19 | "requireSpaceBeforeObjectValues": true, 20 | "requireCommaBeforeLineBreak": true, 21 | "requireOperatorBeforeLineBreak": true, 22 | "disallowSpaceAfterPrefixUnaryOperators": true, 23 | "disallowSpaceBeforePostfixUnaryOperators": true, 24 | "requireSpaceBeforeBinaryOperators": true, 25 | "requireSpaceAfterBinaryOperators": true, 26 | "disallowImplicitTypeConversion": ["numeric", "boolean", "binary", "string"], 27 | "requireCamelCaseOrUpperCaseIdentifiers": true, 28 | "disallowMultipleLineStrings": true, 29 | "disallowMixedSpacesAndTabs": true, 30 | "disallowTrailingWhitespace": true, 31 | "disallowTrailingComma": true, 32 | "disallowKeywordsOnNewLine": ["else"], 33 | "maximumLineLength": { 34 | "value": 80, 35 | "allowUrlComments": true 36 | }, 37 | "requireDotNotation": true, 38 | "requireSpaceAfterLineComment": true, 39 | "disallowNewlineBeforeBlockStatements": true, 40 | "validateLineBreaks": "LF", 41 | "validateIndentation": 4, 42 | "validateParameterSeparator": ", ", 43 | "safeContextKeyword": ["self"] 44 | } 45 | 46 | -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | src/bootstrap.js 3 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "eqeqeq": true, 3 | "es3": true, 4 | "freeze": true, 5 | "latedef": "nofunc", 6 | "maxcomplexity": 10, 7 | "node": true, 8 | "strict": true, 9 | "undef": true, 10 | "unused": true, 11 | "predef": ["-Promise", "JSON"] 12 | } 13 | 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: '0.12' 3 | sudo: false 4 | addons: 5 | sauce_connect: true 6 | env: 7 | global: 8 | - secure: au7XtmQDR14Sbp/lvXkRWpW+WDtv1JnWkaxwnzsEAbE/49hPXvPi6LDMrexDPq4uc4ENHwgCJa/SR6yYBZmWSUS6TotxrRpSfi79V8AvB31lcQrHgtssOLcTJvOrSQPjWK+a9O9bdb/zS8s/5wnE9Y06A59vSHd482BR7FX9nCs= 9 | - secure: nJzTL/VeaVaqWg+qOrDOVzOq/zr0KcVli2AmL6JYpNfSLDMk5ZFR8Qs2ZUXkerJY36KEzrZnYQ9SDMkhYtTUf6SpH3MoMDcs79wOMVBWKHdYX5jf1aIuE+75pNU15HK0vwtT1wV5uZurrkx46K/EKobjspIOy0Qs/jAQ8AVKuoE= 10 | - COMMAND='npm run test' 11 | matrix: 12 | - BROWSER=PhantomJS PULL_REQUEST_SAFE=true 13 | - BROWSER=SL_Chrome 14 | - BROWSER=SL_Firefox 15 | - BROWSER=SL_Safari 16 | - BROWSER=SL_IE_8 17 | - BROWSER=SL_IE_9 18 | - BROWSER=SL_IE_10 19 | - BROWSER=SL_IE_11 20 | matrix: 21 | allow_failures: 22 | - env: BROWSER=SL_IE_8 23 | include: 24 | - env: COMMAND='npm run lint' PULL_REQUEST_SAFE=true 25 | script: 26 | - '[ "${TRAVIS_PULL_REQUEST}" != "false" -a "${PULL_REQUEST_SAFE}" != "true" ] && true || ${COMMAND}' 27 | cache: 28 | directories: 29 | - node_modules 30 | notifications: 31 | email: false 32 | irc: 33 | channels: 34 | - chat.freenode.net#annotator 35 | on_success: change 36 | on_failure: change 37 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.net 3 | 4 | [annotator.all-strings] 5 | file_filter = locale//annotator.po 6 | source_file = locale/annotator.pot 7 | source_lang = en 8 | 9 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Greg Bone 2 | Aron Carroll 3 | Deds Castillo 4 | Daniel Cebrián Robles 5 | Eric Collins 6 | Kristof Csillag 7 | Michael Donohoe 8 | Matthew Flaschen 9 | Bianca Gandolfo 10 | Jared Hirsch 11 | Alex Kessinger 12 | Randall Leeds 13 | Brian Long 14 | Jean-Bernard Marcon 15 | Chris Nitchie 16 | Rufus Pollock 17 | Mikhail Sobolev 18 | Nick Stenning 19 | Ed Summers 20 | Deepak Thukral 21 | Kevin Tran 22 | Benjamin Young 23 | Fernano Aramendi 24 | -------------------------------------------------------------------------------- /CHANGES.rst: -------------------------------------------------------------------------------- 1 | 2.0.0-alpha.3 2 | ============= 3 | 4 | Features 5 | -------- 6 | 7 | - The ``authz``, ``identity``, and ``notification`` modules are now 8 | exposed as public API on the ``annotator`` page global. 9 | 10 | - The ``notifier``, ``identityPolicy`` and ``authorizationPolicy`` are now 11 | retrieved from component registry. It should now be possible to register 12 | alternative implementations. 13 | 14 | - Performance of the highlighter should be slightly improved. 15 | 16 | - Showing the viewer with a mouse hover should be much faster when there are 17 | many overlapping highlights. (#520) 18 | 19 | - The ``getGlobal()`` function of the ``util`` module has been removed and 20 | Annotator should now work with Content Security Policy rules that prevent 21 | ``eval`` of code. 22 | 23 | - The ``markdown`` extension has been upgraded to require and support version 24 | 1.0 or greater of the Showdown library. 25 | 26 | Bug Fixes 27 | --------- 28 | 29 | - Fix a bug in the ``ui.filter`` extension so that the ``filters`` option 30 | now works as specified. 31 | 32 | - Make the highlighter work even when the global ``document`` symbol is not 33 | ``window.document``. 34 | 35 | - Fix an issue with the editor where adding custom fields could result in 36 | fields appearing more than once. (#533) 37 | 38 | - With the ``autoViewHighlights`` options of the ``viewer``, don't show the 39 | viewer while the primary mouse button is pressed. Before, this prevention 40 | applied to every button except the primary button, which was not the intended 41 | behavior. 42 | 43 | Documentation 44 | ------------- 45 | 46 | - Fix some broken links. 47 | 48 | - Fix some example syntax. 49 | 50 | - Add example markup in the documentation for the ``document`` extension. 51 | 52 | 2.0.0-alpha.2 (2015-04-24) 53 | ========================== 54 | 55 | - Started changelog. 56 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | Hacking on Annotator 2 | ==================== 3 | 4 | If you wish to develop Annotator, you'll need to have a working installation of 5 | `Node.js `__ (>= v0.10.x). Once installed (on most systems 6 | Node comes bundled with `NPM `__) you should run the 7 | following to install Annotator's development dependencies:: 8 | 9 | $ npm install . 10 | 11 | The Annotator source is found in ``src/``. You can use the ``tools/serve`` 12 | script while developing to serve bundle the source files. ``dev.html`` can be useful 13 | when developing. 14 | 15 | The tests can be found in ``test/`` and can be run with:: 16 | 17 | $ npm test 18 | 19 | 20 | Build 21 | ----- 22 | 23 | Building the packaged version of Annotator involves running the appropriate 24 | ``make`` task. To build everything, run:: 25 | 26 | $ make 27 | 28 | To build just the main Annotator bundle, run:: 29 | 30 | $ make pkg/annotator.min.js 31 | 32 | To build a standalone extension module, run:: 33 | 34 | $ make pkg/annotator.document.min.js 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # Annotator licensing terms 2 | 3 | Annotator is free software, and you may use it under the terms of either the 4 | MIT or the GNU GPL licenses: 5 | 6 | ## GNU GPLv3 7 | 8 | You can redistribute this program and/or modify it under the terms of the 9 | GNU General Public License as published by the Free Software Foundation, 10 | either version 3 of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. See LICENSE-GPL, or, if this file is missing, 19 | . 20 | 21 | ## MIT 22 | 23 | You may use the software under the terms of the MIT license, which can be 24 | found in LICENSE-MIT, or, if this file is missing, 25 | . -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BROWSERIFY := node_modules/.bin/browserify 2 | UGLIFYJS := node_modules/.bin/uglifyjs 3 | 4 | # Check that the user has run 'npm install' 5 | ifeq ($(shell which $(BROWSERIFY) >/dev/null 2>&1; echo $$?), 1) 6 | $(error The 'browserify' command was not found. Please ensure you have run 'npm install' before running make.) 7 | endif 8 | 9 | SRC := $(shell find src -type f -name '*.js') 10 | 11 | all: annotator 12 | annotator: pkg/annotator.min.js 13 | 14 | pkg/%.min.js: pkg/%.js 15 | @echo Writing $@ 16 | @$(UGLIFYJS) --preamble "$$(tools/preamble)" $< >$@ 17 | 18 | pkg/annotator.js: browser.js 19 | @echo Writing $@ 20 | @mkdir -p pkg/ .deps/ 21 | @$(BROWSERIFY) -s annotator $< >$@ 22 | @$(BROWSERIFY) --list $< | \ 23 | sed 's#^#$@: #' >.deps/annotator.d 24 | 25 | clean: 26 | rm -rf .deps pkg 27 | 28 | test: 29 | npm test 30 | 31 | develop: 32 | npm start 33 | 34 | doc: 35 | cd doc && $(MAKE) html 36 | 37 | apidoc: $(patsubst src/%.js,doc/api/%.rst,$(SRC)) 38 | 39 | doc/api/%.rst: src/%.js 40 | @mkdir -p $(@D) 41 | tools/apidoc $< $@ 42 | 43 | -include .deps/*.d 44 | 45 | .PHONY: all annotator clean test develop doc 46 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Annotator 2 | ========= 3 | 4 | |Build Status| |Version on NPM| |IRC Channel| 5 | 6 | |Build Matrix| 7 | 8 | Annotator is a JavaScript library for building annotation applications in 9 | browsers. It provides a set of interoperable tools for annotating content in 10 | webpages. For a simple demonstration, visit the `Annotator home page`_ or 11 | download a tagged release of Annotator from `the releases page`_ and open 12 | ``demo.html``. 13 | 14 | .. _Annotator home page: http://annotatorjs.org/ 15 | .. _the releases page: https://github.com/openannotation/annotator/releases 16 | 17 | Components within Annotator provide: 18 | 19 | - user interface: components to create, edit, and display annotations in a 20 | browser. 21 | - persistence: storage components help you save your annotations to a remote 22 | server. 23 | - authorization and identity: integrate Annotator with your application's login 24 | and permissions systems. 25 | 26 | .. _Dublin Core tags: http://dublincore.org/ 27 | .. _Facebook Open Graph: https://developers.facebook.com/docs/opengraph 28 | 29 | 30 | Usage 31 | ----- 32 | 33 | See Installing_ and `Configuring and using Annotator`_ from the documentation_. 34 | 35 | .. _Installing: http://docs.annotatorjs.org/en/latest/installing.html 36 | .. _Configuring and using Annotator: http://docs.annotatorjs.org/en/latest/usage.html 37 | .. _documentation: http://docs.annotatorjs.org/en/latest/ 38 | 39 | 40 | Writing a module 41 | ---------------- 42 | 43 | See `Module development`_. 44 | 45 | .. _Module development: http://docs.annotatorjs.org/en/latest/module-development.html 46 | 47 | 48 | Development 49 | ----------- 50 | 51 | See `HACKING.rst <./HACKING.rst>`__. 52 | 53 | 54 | Reporting a bug 55 | --------------- 56 | 57 | Please report bugs using the `GitHub issue tracker`_. Please be sure to use the 58 | search facility to see if anyone else has reported the same bug -- don't submit 59 | duplicates. 60 | 61 | Please endeavour to follow `good practice for reporting bugs`_ when you submit 62 | an issue. 63 | 64 | Lastly, if you need support or have a question about Annotator, please **do not 65 | use the issue tracker**. Instead, you are encouraged to email the `mailing 66 | list`_. 67 | 68 | .. _GitHub issue tracker: https://github.com/openannotation/annotator/issues 69 | .. _good practice for reporting bugs: http://www.chiark.greenend.org.uk/~sgtatham/bugs.html 70 | 71 | 72 | Community 73 | --------- 74 | 75 | The Annotator project has a `mailing list`_, ``annotator-dev``, which you're 76 | encouraged to use for any questions and discussions. It is archived for easy 77 | browsing and search at `gmane.comp.web.annotator`_. We can also be found in 78 | |IRC|_. 79 | 80 | .. _mailing list: https://lists.okfn.org/mailman/listinfo/annotator-dev 81 | .. _gmane.comp.web.annotator: http://dir.gmane.org/gmane.comp.web.annotator 82 | .. |IRC| replace:: the ``#annotator`` channel on Freenode 83 | .. _IRC: https://webchat.freenode.net/?channels=#annotator 84 | 85 | 86 | .. |Build Status| image:: https://secure.travis-ci.org/openannotation/annotator.svg?branch=master 87 | :target: http://travis-ci.org/openannotation/annotator 88 | .. |Version on NPM| image:: http://img.shields.io/npm/v/annotator.svg 89 | :target: https://www.npmjs.org/package/annotator 90 | .. |Build Matrix| image:: https://saucelabs.com/browser-matrix/hypothesisannotator.svg 91 | :target: https://saucelabs.com/u/hypothesisannotator 92 | .. |IRC Channel| image:: https://img.shields.io/badge/IRC-%23annotator-blue.svg 93 | :target: https://www.irccloud.com/invite?channel=%23annotator&hostname=irc.freenode.net&port=6697&ssl=1 94 | :alt: #hypothes.is IRC channel 95 | -------------------------------------------------------------------------------- /browser.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // Inject Annotator CSS 4 | var insertCss = require('insert-css'); 5 | var css = require('./css/annotator.css'); 6 | insertCss(css); 7 | 8 | var app = require('./src/app'); 9 | var util = require('./src/util'); 10 | 11 | // Core annotator components 12 | exports.App = app.App; 13 | 14 | // Access to libraries (for browser installations) 15 | exports.authz = require('./src/authz'); 16 | exports.identity = require('./src/identity'); 17 | exports.notification = require('./src/notification'); 18 | exports.storage = require('./src/storage'); 19 | exports.ui = require('./src/ui'); 20 | exports.util = util; 21 | 22 | // Ext namespace (for core-provided extension modules) 23 | exports.ext = {}; 24 | 25 | // If wicked-good-xpath is available, install it. This will not overwrite any 26 | // native XPath functionality. 27 | var wgxpath = global.wgxpath; 28 | if (typeof wgxpath !== "undefined" && 29 | wgxpath !== null && 30 | typeof wgxpath.install === "function") { 31 | wgxpath.install(); 32 | } 33 | 34 | // Store a reference to the current annotator object, if one exists. 35 | var _annotator = global.annotator; 36 | 37 | // Restores the Annotator property on the global object to it's 38 | // previous value and returns the Annotator. 39 | exports.noConflict = function noConflict() { 40 | global.annotator = _annotator; 41 | return this; 42 | }; 43 | -------------------------------------------------------------------------------- /contrib/annotator_badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openannotation/annotator/5ef5edf157fe728b2d6d95d01e26a55c508c0c44/contrib/annotator_badge.png -------------------------------------------------------------------------------- /contrib/chrome/background.js: -------------------------------------------------------------------------------- 1 | const STATE_DISABLED = 0 2 | const STATE_ENABLED = 1 3 | const STATE_ACTIVE = 2 4 | 5 | const ICON_SIZE = 48 6 | 7 | var enabled = false; 8 | var loaded = false; 9 | 10 | var canvas = document.createElement('canvas') 11 | var icon = new Image() 12 | icon.src = chrome.extension.getURL('img/annotator-icon-sprite.png') 13 | icon.alt = 'Annotate' 14 | icon.onload = setIcon 15 | 16 | function setIcon() { 17 | var state = (loaded && enabled) ? STATE_ENABLED : STATE_DISABLED; 18 | var ctx = canvas.getContext('2d'); 19 | ctx.drawImage(icon, ICON_SIZE * state, 0, ICON_SIZE, ICON_SIZE, 0, 0, 19, 19) 20 | chrome.browserAction.setIcon({ 21 | imageData: ctx.getImageData(0, 0, 19, 19) 22 | }) 23 | } 24 | 25 | chrome.browserAction.onClicked.addListener(function(tab) { 26 | var message = loaded ? (enabled ? 'hide' : 'show') : 'load' 27 | chrome.tabs.sendRequest(tab.id, {annotator: message}, function (response) { 28 | if (response.error) { 29 | throw response.error 30 | } else { 31 | if (!loaded) loaded = true 32 | enabled = !enabled; 33 | } 34 | setIcon() 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /contrib/chrome/content.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Listen for requests from the background scripts. Since the annotator code is 3 | * loaded in the page context, background events which interact with the 4 | * annotator user interface, such as showing or hiding the annotator need to be 5 | * handled here. 6 | */ 7 | chrome.extension.onRequest.addListener( 8 | function (request, sender, sendResponse) { 9 | var command = request.annotator 10 | if (command) { 11 | if (command === 'load') { 12 | $(document.body).annotator().annotator('setupPlugins') 13 | sendResponse({ok: true}) 14 | } else { 15 | sendResponse({error: new TypeError("not implemented: " + command)}) 16 | } 17 | } 18 | } 19 | ) 20 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Annotator demo 6 | 23 | 24 | 25 | 26 |
27 |

Annotator demonstration

28 |
29 | 30 |
31 |

32 | He was an old man who fished alone in a skiff in the Gulf Stream and he 33 | had gone eighty-four days now without taking a fish. In the first forty 34 | days a boy had been with him. But after forty days without a fish the 35 | boy's parents had told him that the old man was now definitely and 36 | finally salao, which is the worst form of unlucky, and the boy 37 | had gone at their orders in another boat which caught three good fish 38 | the first week. It made the boy sad to see the old man come in each day 39 | with his skiff empty and he always went down to help him carry either 40 | the coiled lines or the gaff and harpoon and the sail that was furled 41 | around the mast. The sail was patched with flour sacks and, furled, it 42 | looked like the flag of permanent defeat. 43 |

44 |

45 | The old man was thin and gaunt with deep wrinkles in the back of his 46 | neck. The brown blotches of the benevolent skin cancer the sun brings 47 | from its reflection on the tropic sea were on his cheeks. The blotches 48 | ran well down the sides of his face and his hands had the deep-creased 49 | scars from handling heavy fish on the cords. But none of these scars 50 | were fresh. They were as old as erosions in a fishless desert. 51 |

52 |

53 | Everything about him was old except his eyes and they were the same 54 | color as the sea and were cheerful and undefeated. 55 |

56 |

57 | "Santiago," the boy said to him as they climbed the bank from 58 | where the skiff was hauled up. "I could go with you again. We've 59 | made some money." 60 |

61 |

The old man had taught the boy to fish and the boy loved him.

62 |

63 | "No," the old man said. "You're with a lucky boat. Stay 64 | with them." 65 |

66 |

67 | "But remember how you went eighty-seven days without fish and then 68 | we caught big ones every day for three weeks." 69 |

70 |

71 | "I remember," the old man said. "I know you did not leave 72 | me because you doubted." 73 |

74 |

75 | "It was papa made me leave. I am a boy and I must obey him." 76 |

77 |

78 | "I know," the old man said. "It is quite normal." 79 |

80 |

"He hasn't much faith."

81 |

82 | "No," the old man said. "But we have. Haven't we?" 83 |

84 |

85 | "Yes," the boy said. "Can I offer you a beer on the 86 | Terrace and then we'll take the stuff home." 87 |

88 |

89 | "Why not?" the old man said. "Between fishermen." 90 |

91 |

92 | They sat on the Terrace and many of the fishermen made fun of the old 93 | man and he was not angry. Others, of the older fishermen, looked at him 94 | and were sad. But they did not show it and they spoke politely about the 95 | current and the depths they had drifted their lines at and the steady 96 | good weather and of what they had seen. The successful fishermen of that 97 | day were already in and had butchered their marlin out and carried them 98 | laid full length across two planks, with two men staggering at the end 99 | of each plank, to the fish house where they waited for the ice truck to 100 | carry them to the market in Havana. Those who had caught sharks had 101 | taken them to the shark factory on the other side of the cove where they 102 | were hoisted on a block and tackle, their livers removed, their fins cut 103 | off and their hides skinned out and their flesh cut into strips for 104 | salting. 105 |

106 |

107 | When the wind was in the east a smell came across the harbour from the 108 | shark factory; but today there was only the faint edge of the odour 109 | because the wind had backed into the north and then dropped off and it 110 | was pleasant and sunny on the Terrace. 111 |

112 |
113 | 114 | 115 | 116 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Annotator development 6 | 48 | 49 | 50 | 51 |
52 |

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

53 | 54 |

Header Level 2

55 | 56 |
    57 |
  1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  2. 58 |
  3. Aliquam tincidunt mauris eu risus.
  4. 59 |
60 | 61 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.

62 | 63 |

Here's an interesting one. This is absolutely positioned content. If we can't get the adder positioning right on this one then we're screwed.

64 | 65 |

And the same but with position: fixed; Make the window smaller and scroll to make sure that adder/viewer/editor positioning is still correct.

66 | 67 |

Header Level 3

68 | 69 |
    70 |
  • Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  • 71 |
  • Aliquam tincidunt mauris eu risus.
  • 72 |
73 | 74 |

 75 |       #header h1 a {
 76 |         display: block;
 77 |         width: 300px;
 78 |         height: 80px;
 79 |       }
 80 |       
81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
Heading OneHeading TwoHeading Three
Side OneLorem ipsum dolor sit amet, consectetuer adipiscing elit.Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Side TwoLorem ipsum dolor sit amet, consectetuer adipiscing elit.Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Side ThreeLorem ipsum dolor sit amet, consectetuer adipiscing elit.Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Side FourLorem ipsum dolor sit amet, consectetuer adipiscing elit.Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
113 |
114 | 115 | 116 | 117 | 118 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Annotator.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Annotator.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Annotator" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Annotator" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /doc/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openannotation/annotator/5ef5edf157fe728b2d6d95d01e26a55c508c0c44/doc/_static/.placeholder -------------------------------------------------------------------------------- /doc/api/app.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator package 4 | ================= 5 | 6 | .. class:: annotator.App() 7 | 8 | App is the coordination point for all annotation functionality. App instances 9 | manage the configuration of a particular annotation application, and are the 10 | starting point for most deployments of Annotator. 11 | 12 | 13 | .. function:: annotator.App.prototype.include(module[, options]) 14 | 15 | Include an extension module. If an `options` object is supplied, it will be 16 | passed to the module at initialisation. 17 | 18 | If the returned module instance has a `configure` function, this will be 19 | called with the application registry as a parameter. 20 | 21 | :param Object module: 22 | :param Object options: 23 | :returns: Itself. 24 | :rtype: App 25 | 26 | 27 | .. function:: annotator.App.prototype.start() 28 | 29 | Tell the app that configuration is complete. This binds the various 30 | components passed to the registry to their canonical names so they can be 31 | used by the rest of the application. 32 | 33 | Runs the 'start' module hook. 34 | 35 | :returns: A promise, resolved when all module 'start' hooks have completed. 36 | :rtype: Promise 37 | 38 | 39 | .. function:: annotator.App.prototype.destroy() 40 | 41 | Destroy the App. Unbinds all event handlers and runs the 'destroy' module 42 | hook. 43 | 44 | :returns: A promise, resolved when destroyed. 45 | :rtype: Promise 46 | 47 | 48 | .. function:: annotator.App.prototype.runHook(name[, args]) 49 | 50 | Run the named module hook and return a promise of the results of all the hook 51 | functions. You won't usually need to run this yourself unless you are 52 | extending the base functionality of App. 53 | 54 | Optionally accepts an array of argument (`args`) to pass to each hook 55 | function. 56 | 57 | :returns: A promise, resolved when all hooks are complete. 58 | :rtype: Promise 59 | 60 | 61 | .. function:: annotator.App.extend(object) 62 | 63 | Create a new object that inherits from the App class. 64 | 65 | For example, here we create a ``CustomApp`` that will include the 66 | hypothetical ``mymodules.foo.bar`` module depending on the options object 67 | passed into the constructor:: 68 | 69 | var CustomApp = annotator.App.extend({ 70 | constructor: function (options) { 71 | App.apply(this); 72 | if (options.foo === 'bar') { 73 | this.include(mymodules.foo.bar); 74 | } 75 | } 76 | }); 77 | 78 | var app = new CustomApp({foo: 'bar'}); 79 | 80 | :returns: The subclass constructor. 81 | :rtype: Function 82 | 83 | 84 | -------------------------------------------------------------------------------- /doc/api/authz.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.authz package 4 | ======================= 5 | 6 | .. function:: annotator.authz.acl() 7 | 8 | A module that configures and registers an instance of 9 | :class:`annotator.identity.AclAuthzPolicy`. 10 | 11 | 12 | .. class:: annotator.authz.AclAuthzPolicy() 13 | 14 | An authorization policy that permits actions based on access control lists. 15 | 16 | 17 | .. function:: annotator.authz.AclAuthzPolicy.prototype.permits(action, \ 18 | context, identity) 19 | 20 | Determines whether the user identified by `identity` is permitted to 21 | perform the specified action in the given context. 22 | 23 | If the context has a "permissions" object property, then actions will 24 | be permitted if either of the following are true: 25 | 26 | a) permissions[action] is undefined or null, 27 | b) permissions[action] is an Array containing the authorized userid 28 | for the given identity. 29 | 30 | If the context has no permissions associated with it then all actions 31 | will be permitted. 32 | 33 | If the annotation has a "user" property, then actions will be permitted 34 | only if `identity` matches this "user" property. 35 | 36 | If the annotation has neither a "permissions" property nor a "user" 37 | property, then all actions will be permitted. 38 | 39 | :param String action: The action to perform. 40 | :param context: The permissions context for the authorization check. 41 | :param identity: The identity whose authorization is being checked. 42 | 43 | :returns Boolean: Whether the action is permitted in this context for this 44 | identity. 45 | 46 | 47 | .. function:: annotator.authz.AclAuthzPolicy.prototype.authorizedUserId( \ 48 | identity) 49 | 50 | Returns the authorized userid for the user identified by `identity`. 51 | 52 | 53 | -------------------------------------------------------------------------------- /doc/api/identity.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.identity package 4 | ========================== 5 | 6 | .. function:: annotator.identity.simple() 7 | 8 | A module that configures and registers an instance of 9 | :class:`annotator.identity.SimpleIdentityPolicy`. 10 | 11 | 12 | .. class:: annotator.identity.SimpleIdentityPolicy 13 | 14 | A simple identity policy that considers the identity to be an opaque 15 | identifier. 16 | 17 | 18 | .. data:: annotator.identity.SimpleIdentityPolicy.identity 19 | 20 | Default identity. Defaults to `null`, which disables identity-related 21 | functionality. 22 | 23 | This is not part of the identity policy public interface, but provides a 24 | simple way for you to set a fixed current user:: 25 | 26 | app.ident.identity = 'bob'; 27 | 28 | 29 | .. function:: annotator.identity.SimpleIdentityPolicy.prototype.who() 30 | 31 | Returns the current user identity. 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/api/index.rst: -------------------------------------------------------------------------------- 1 | API documentation 2 | ================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | app 8 | registry 9 | storage 10 | authz 11 | identity 12 | notification 13 | ui 14 | -------------------------------------------------------------------------------- /doc/api/notification.js: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.notifier package 4 | ========================== 5 | 6 | .. function:: annotator.notifier.banner(message[, severity=notification.INFO]) 7 | 8 | Creates a user-visible banner notification that can be used to display 9 | information, warnings and errors to the user. 10 | 11 | :param String message: The notice message text. 12 | :param severity: 13 | The severity of the notice (one of `notification.INFO`, 14 | `notification.SUCCESS`, or `notification.ERROR`) 15 | 16 | :returns: 17 | An object with a `close` method which can be used to close the banner. 18 | 19 | 20 | -------------------------------------------------------------------------------- /doc/api/notification.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.notifier package 4 | ========================== 5 | 6 | .. function:: annotator.notifier.banner(message[, severity=notification.INFO]) 7 | 8 | Creates a user-visible banner notification that can be used to display 9 | information, warnings and errors to the user. 10 | 11 | :param String message: The notice message text. 12 | :param severity: 13 | The severity of the notice (one of `notification.INFO`, 14 | `notification.SUCCESS`, or `notification.ERROR`) 15 | 16 | :returns: 17 | An object with a `close` method that can be used to close the banner. 18 | 19 | 20 | -------------------------------------------------------------------------------- /doc/api/registry.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.registry package 4 | ========================== 5 | 6 | .. class:: annotator.registry.Registry() 7 | 8 | `Registry` is an application registry. It serves as a place to register and 9 | find shared components in a running :class:`annotator.App`. 10 | 11 | You won't usually create your own `Registry` -- one will be created for you 12 | by the :class:`~annotator.App`. If you are writing an Annotator module, you 13 | can use the registry to provide or override a component of the Annotator 14 | application. 15 | 16 | For example, if you are writing a module that overrides the "storage" 17 | component, you will use the registry in your module's `configure` function to 18 | register your component:: 19 | 20 | function myStorage () { 21 | return { 22 | configure: function (registry) { 23 | registry.registerUtility(this, 'storage'); 24 | }, 25 | ... 26 | }; 27 | } 28 | 29 | 30 | .. function:: annotator.registry.Registry.prototype.registerUtility(component, iface) 31 | 32 | Register component `component` as an implementer of interface `iface`. 33 | 34 | :param component: The component to register. 35 | :param string iface: The name of the interface. 36 | 37 | 38 | .. function:: annotator.registry.Registry.prototype.getUtility(iface) 39 | 40 | Get component implementing interface `iface`. 41 | 42 | :param string iface: The name of the interface. 43 | :returns: Component matching `iface`. 44 | :throws LookupError: If no component is found for interface `iface`. 45 | 46 | 47 | .. function:: annotator.registry.Registry.prototype.queryUtility(iface) 48 | 49 | Get component implementing interface `iface`. Returns `null` if no matching 50 | component is found. 51 | 52 | :param string iface: The name of the interface. 53 | :returns: Component matching `iface`, if found; `null` otherwise. 54 | 55 | 56 | .. class:: annotator.registry.LookupError(iface) 57 | 58 | The error thrown when a registry component lookup fails. 59 | 60 | 61 | -------------------------------------------------------------------------------- /doc/api/ui.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.ui package 4 | ==================== 5 | 6 | .. include:: ui/main.rst 7 | :start-line: 5 8 | 9 | .. include:: ui/markdown.rst 10 | :start-line: 5 11 | 12 | .. include:: ui/tags.rst 13 | :start-line: 5 14 | -------------------------------------------------------------------------------- /doc/api/ui/main.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.ui package 4 | ==================== 5 | 6 | .. function:: annotator.ui.main([options]) 7 | 8 | A module that provides a default user interface for Annotator that allows 9 | users to create annotations by selecting text within (a part of) the 10 | document. 11 | 12 | Example:: 13 | 14 | app.include(annotator.ui.main); 15 | 16 | :param Object options: 17 | 18 | .. attribute:: options.element 19 | 20 | A DOM element to which event listeners are bound. Defaults to 21 | ``document.body``, allowing annotation of the whole document. 22 | 23 | .. attribute:: options.editorExtensions 24 | 25 | An array of editor extensions. See the 26 | :class:`~annotator.ui.editor.Editor` documentation for details of editor 27 | extensions. 28 | 29 | .. attribute:: options.viewerExtensions 30 | 31 | An array of viewer extensions. See the 32 | :class:`~annotator.ui.viewer.Viewer` documentation for details of viewer 33 | extensions. 34 | -------------------------------------------------------------------------------- /doc/api/ui/markdown.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.ui.markdown package 4 | ============================= 5 | 6 | .. function:: annotator.ui.markdown.render(annotation) 7 | 8 | Render an annotation to HTML, converting annotation text from Markdown if 9 | Showdown is available in the page. 10 | 11 | :returns: Rendered HTML. 12 | :rtype: String 13 | 14 | 15 | .. function:: annotator.ui.markdown.viewerExtension(viewer) 16 | 17 | An extension for the :class:`~annotator.ui.viewer.Viewer`. Allows the viewer 18 | to interpret annotation text as `Markdown`_ and uses the `Showdown`_ library 19 | if present in the page to render annotations with Markdown text as HTML. 20 | 21 | .. _Markdown: https://daringfireball.net/projects/markdown/ 22 | .. _Showdown: https://github.com/showdownjs/showdown 23 | 24 | **Usage**:: 25 | 26 | app.include(annotator.ui.main, { 27 | viewerExtensions: [annotator.ui.markdown.viewerExtension] 28 | }); 29 | -------------------------------------------------------------------------------- /doc/api/ui/tags.rst: -------------------------------------------------------------------------------- 1 | .. default-domain: js 2 | 3 | annotator.ui.tags package 4 | ========================= 5 | 6 | .. function:: annotator.ui.tags.viewerExtension(viewer) 7 | 8 | An extension for the :class:`~annotator.ui.viewer.Viewer` that displays any 9 | tags stored as an array of strings in the annotation's ``tags`` property. 10 | 11 | **Usage**:: 12 | 13 | app.include(annotator.ui.main, { 14 | viewerExtensions: [annotator.ui.tags.viewerExtension] 15 | }) 16 | 17 | 18 | .. function:: annotator.ui.tags.editorExtension(editor) 19 | 20 | An extension for the :class:`~annotator.ui.editor.Editor` that allows 21 | editing a set of space-delimited tags, retrieved from and saved to the 22 | annotation's ``tags`` property. 23 | 24 | **Usage**:: 25 | 26 | app.include(annotator.ui.main, { 27 | editorExtensions: [annotator.ui.tags.editorExtension] 28 | }) 29 | -------------------------------------------------------------------------------- /doc/changes.rst: -------------------------------------------------------------------------------- 1 | Annotator Change History 2 | ~~~~~~~~~~~~~~~~~~~~~~~~ 3 | 4 | All notable changes to this project are documented here. This project 5 | endeavours to adhere to `Semantic Versioning`_. 6 | 7 | .. _Semantic Versioning: http://semver.org/ 8 | 9 | .. include:: ../CHANGES.rst 10 | -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Annotator documentation build configuration file 4 | 5 | import json 6 | import os 7 | 8 | # By default, we do not want to use the RTD theme 9 | sphinx_rtd_theme = None 10 | 11 | # If the docs are built on readthedocs, it will be used by default 12 | if os.environ.get('READTHEDOCS') != 'True': 13 | try: 14 | import sphinx_rtd_theme 15 | except ImportError: 16 | # Now we know for sure we do not have it 17 | pass 18 | 19 | 20 | # -- General configuration 21 | 22 | # The suffix of source filenames. 23 | source_suffix = '.rst' 24 | 25 | # The master toctree document. 26 | master_doc = 'index' 27 | 28 | # General information about the project. 29 | project = u'Annotator' 30 | copyright = u'2014, The Annotator project contributors' 31 | 32 | # The version info for the project you're documenting, acts as replacement for 33 | # |version| and |release|, also used in various other places throughout the 34 | # built documents. 35 | # 36 | # The short X.Y version. 37 | version = json.load(open('../package.json'))['version'] 38 | # The full version, including alpha/beta/rc tags. 39 | release = version 40 | 41 | # The language for content autogenerated by Sphinx. Refer to documentation 42 | # for a list of supported languages. 43 | language = 'en' 44 | 45 | # List of patterns, relative to source directory, that match files and 46 | # directories to ignore when looking for source files. 47 | exclude_patterns = ['_build'] 48 | 49 | # The name of the Pygments (syntax highlighting) style to use. 50 | pygments_style = 'sphinx' 51 | 52 | # The default language to highlight source code in. This should be a valid 53 | # Pygments lexer name. 54 | highlight_language = 'javascript' 55 | 56 | 57 | # -- Sphinx extension configuration 58 | 59 | # Add any Sphinx extension module names here, as strings. They can be 60 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 61 | # ones. 62 | extensions = [ 63 | 'sphinx.ext.extlinks', 64 | 'sphinx.ext.todo', 65 | 'sphinxcontrib.httpdomain', 66 | ] 67 | 68 | # A dictionary of external sites, mapping unique short alias names to a base 69 | # URL and a prefix. 70 | extlinks = { 71 | 'gh': ('https://github.com/openannotation/annotator/%s', ''), 72 | 'issue': ('https://github.com/openannotation/annotator/issues/%s', 73 | 'issue '), 74 | } 75 | 76 | # If this is True, todo and todolist produce output, else they produce nothing. 77 | todo_include_todos = os.environ.get('SPHINX_TODOS') is not None 78 | 79 | 80 | # -- Options for HTML output 81 | 82 | # The theme to use for HTML and HTML Help pages. See the documentation for 83 | # a list of builtin themes. 84 | html_theme = 'sphinx_rtd_theme' if sphinx_rtd_theme else 'default' 85 | 86 | # Add any paths that contain custom themes here, relative to this directory. 87 | if sphinx_rtd_theme: 88 | html_theme_path = [ 89 | sphinx_rtd_theme.get_html_theme_path() 90 | ] 91 | -------------------------------------------------------------------------------- /doc/glossary.rst: -------------------------------------------------------------------------------- 1 | .. _glossary: 2 | 3 | Glossary 4 | ======== 5 | 6 | .. glossary:: 7 | :sorted: 8 | 9 | application 10 | An application is an instance of :class:`annotator.App`. It is the primary 11 | object that coordinates annotation activities. It can be extended by 12 | passing a :term:`module` reference to its 13 | :func:`~annotator.App.prototype.include` method. Typically, you will 14 | create at least one application when using Annotator. See the API 15 | documentation for :class:`annotator.App` for details on construction and 16 | methods. 17 | 18 | hook 19 | A function that handles work delegated to a :term:`module` by the 20 | :term:`application`. A hook function can return a value or a 21 | :term:`Promise`. The arguments to hook functions can vary. See 22 | :ref:`module-hooks` for a description of the core hooks provided by 23 | Annotator. 24 | 25 | module 26 | A module extends the functionality of an :term:`application`, primarily 27 | through :term:`hook` functions. See the section :doc:`module-development` 28 | for details about writing modules. 29 | 30 | Promise 31 | An object used for deferred and asynchronous computations. 32 | See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise 33 | for more information. 34 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | Annotator Documentation 3 | ======================= 4 | 5 | .. warning:: Beware: rapidly changing documentation! 6 | 7 | This is the bleeding-edge documentation for Annotator that will be changing 8 | rapidly as we home in on Annotator v2.0. Information here may be inaccurate, 9 | prone to change, and otherwise unreliable. You may well want to consult `the 10 | stable documentation`_ instead. 11 | 12 | .. _the stable documentation: http://docs.annotatorjs.org/en/v1.2.x/ 13 | 14 | .. highlight:: js 15 | 16 | Welcome to the documentation for Annotator, an open-source JavaScript library 17 | for building annotation systems on the web. At its simplest, Annotator 18 | enables textual annotations of any web page. You can deploy it using just a 19 | few lines of code. 20 | 21 | Annotator is also a library of composable tools for capturing and manipulating 22 | DOM selections; storing, persisting and retrieving annotations; and creating 23 | user interfaces for annotation. You may use few or many of these components 24 | together to build your own custom annotation-based :term:`application`. 25 | 26 | Continue reading to learn about installing and deploying Annotator: 27 | 28 | 29 | .. toctree:: 30 | :maxdepth: 2 31 | 32 | installing 33 | usage 34 | upgrading 35 | modules/index 36 | module-development 37 | 38 | internationalization 39 | 40 | roadmap 41 | api/index 42 | 43 | 44 | .. todolist:: 45 | 46 | Change History 47 | ============== 48 | 49 | .. toctree:: 50 | :maxdepth: 1 51 | 52 | changes 53 | 54 | Glossary and Index 55 | ================== 56 | 57 | * :ref:`glossary` 58 | * :ref:`genindex` 59 | 60 | 61 | .. toctree:: 62 | :hidden: 63 | 64 | glossary 65 | -------------------------------------------------------------------------------- /doc/installing.rst: -------------------------------------------------------------------------------- 1 | Installing 2 | ========== 3 | 4 | Annotator is a JavaScript library, and there are two main approaches to using 5 | it. You can either use the standalone packaged files, or you can install it from 6 | the npm_ package repository and integrate the source code into your own 7 | browserify_ or webpack_ toolchain. 8 | 9 | .. _npm: https://www.npmjs.com/ 10 | .. _browserify: http://browserify.org/ 11 | .. _webpack: https://webpack.github.io/ 12 | 13 | 14 | Built packages 15 | -------------- 16 | 17 | :gh:`Releases ` are published on :gh:`our GitHub repository <>`. The 18 | released zip file will contain minified, production-ready JavaScript files that 19 | you can include in your application. 20 | 21 | To load Annotator with the default set of components, place the following 22 | `` 27 | 28 | npm package 29 | ----------- 30 | 31 | We also publish an ``annotator`` package to npm. This package is not particularly 32 | useful in a Node.js context, but can be used by browserify_ or webpack_. Please 33 | see the documentation for these packages for more information on using them. 34 | -------------------------------------------------------------------------------- /doc/internationalization.rst: -------------------------------------------------------------------------------- 1 | Internationalisation and localisation (I18N, L10N) 2 | ================================================== 3 | 4 | Annotator has rudimentary support for localisation of its interface. 5 | 6 | For users 7 | --------- 8 | 9 | If you wish to use a provided translation, you need to add a ``link`` 10 | tag pointing to the ``.po`` file, as well as include ``gettext.js`` 11 | before you load the Annotator. For example, for a French translation: 12 | 13 | :: 14 | 15 | 16 | 17 | 18 | This should be all you need to do to get the Annotator interface 19 | displayed in French. 20 | 21 | For translators 22 | --------------- 23 | 24 | We now use `Transifex `__ to manage localisation 25 | efforts on Annotator. If you wish to contribute a translation you'll 26 | first need to sign up for a free account at 27 | 28 | https://www.transifex.net/plans/signup/free/ 29 | 30 | Once you're signed up, you can go to 31 | 32 | https://www.transifex.net/projects/p/annotator/ 33 | 34 | and get translating! 35 | 36 | For developers 37 | -------------- 38 | 39 | Any localisable string in the core of Annotator should be wrapped with a 40 | call to the gettext function, ``_t``, e.g. 41 | 42 | :: 43 | 44 | console.log(_t("Hello, world!")) 45 | 46 | Any localisable string in an Annotator plugin should be wrapped with a 47 | call to the gettext function, ``Annotator._t``, e.g. 48 | 49 | :: 50 | 51 | console.log(Annotator._t("Hello from a plugin!")) 52 | 53 | To update the localisation template (``locale/annotator.pot``), you 54 | should run the ``i18n:update`` Cake task: 55 | 56 | :: 57 | 58 | cake i18n:update 59 | 60 | You should leave it up to individual translators to update their 61 | individual ``.po`` files with the ``locale/l10n-update`` tool. 62 | -------------------------------------------------------------------------------- /doc/module-development.rst: -------------------------------------------------------------------------------- 1 | Module development 2 | ================== 3 | 4 | The basics 5 | ---------- 6 | 7 | An Annotator :term:`module` is a function that can be passed to 8 | :func:`~annotator.App.prototype.include` in order to extend the functionality of 9 | an Annotator application. 10 | 11 | The simplest possible Annotator module looks like this:: 12 | 13 | function myModule() { 14 | return {}; 15 | } 16 | 17 | This clearly won't do very much, but we can include it in an application:: 18 | 19 | app.include(myModule); 20 | 21 | If we want to do something more interesting, we have to provide some module 22 | functionality. There are two ways of doing this: 23 | 24 | 1. module hooks 25 | 2. component registration 26 | 27 | Use module hooks unless you are replacing core functionality of Annotator. 28 | Module hooks are functions that will be run by the :class:`~annotator.App` when 29 | important things happen. For example, here's a module that will say 30 | ``Hello, world!`` to the user when the application starts:: 31 | 32 | function helloWorld() { 33 | return { 34 | start: function (app) { 35 | app.notify("Hello, world!"); 36 | } 37 | }; 38 | } 39 | 40 | Just as before, we can include it in an application using 41 | :func:`~annotator.App.prototype.include`:: 42 | 43 | app.include(helloWorld); 44 | 45 | Now, when you run ``app.start();``, this module will send a notification with 46 | the words ``Hello, world!``. 47 | 48 | Or, here's another example that uses the `HTML5 Audio API`_ to play a sound 49 | every time a new annotation is made [#1]_:: 50 | 51 | function fanfare(options) { 52 | options = options || {}; 53 | options.url = options.url || 'trumpets.mp3'; 54 | 55 | return { 56 | annotationCreated: function (annotation) { 57 | var audio = new Audio(options.url); 58 | audio.play(); 59 | } 60 | }; 61 | } 62 | 63 | Here we've added an ``options`` argument to the module function so we can 64 | configure the module when it's included in our application:: 65 | 66 | app.include(fanfare, { 67 | url: "brass_band.wav" 68 | }); 69 | 70 | You may have noticed that the :func:`annotationCreated` module hook function 71 | here receives one argument, ``annotation``. Similarly, the :func:`start` module 72 | hook function in the previous example receives an ``app`` argument. A complete 73 | reference of arguments and hooks is covered in the :ref:`module-hooks` section. 74 | 75 | .. _HTML5 Audio API: https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API 76 | 77 | 78 | Loading custom modules 79 | ---------------------- 80 | 81 | When you write a custom module, you'll end up with a JavaScript function that 82 | you need to reference when you build your application. In the examples above 83 | we've just defined a function and then used it straight away. This is probably 84 | fine for small examples, but when things get a bit more complicated you might 85 | want to put your modules in a namespace. 86 | 87 | For example, if you were working on an application for annotating Shakespeare's 88 | plays, you might put all your modules in a namespace called ``shakespeare``:: 89 | 90 | var shakespeare = {}; 91 | shakespeare.fanfare = function fanfare(options) { 92 | ... 93 | }; 94 | shakespeare.addSceneData = function addSceneData(options) { 95 | ... 96 | }; 97 | 98 | You get the idea. You can now :func:`~annotator.App.prototype.include` these 99 | modules directly from the namespace:: 100 | 101 | app.include(shakespeare.fanfare, { 102 | url: "elizabethan_sackbuts.mp3" 103 | }); 104 | app.include(shakespeare.addSceneData); 105 | 106 | .. _module-hooks: 107 | 108 | Module hooks 109 | ------------ 110 | 111 | Hooks are called by the application in order to delegate work to registered 112 | modules. This is a list of module hooks, when they are called, and what 113 | arguments they receive. 114 | 115 | It is possible to add your own hooks to your application by invoking the 116 | :func:`~annotator.App.prototype.runHook` method on the application instance. 117 | The return value is a :term:`Promise` that resolves to an ``Array`` of the 118 | results of the functions registered for that hook (the order of which is 119 | undefined). 120 | 121 | Hook functions may return a value or a :term:`Promise`. The latter is sometimes 122 | useful for delaying actions. For example, you may wish to return a 123 | :term:`Promise` from the ``beforeAnnotationCreated`` hook when an asynchronous 124 | task must complete before the annotation data can be saved. 125 | 126 | 127 | .. function:: configure(registry) 128 | 129 | Called when the plugin is included. If you are going to register components 130 | with the registry, you should do so in the `configure` module hook. 131 | 132 | :param Registry registry: The application registry. 133 | 134 | 135 | .. function:: start(app) 136 | 137 | Called when :func:`~annotator.App.prototype.start` is called. 138 | 139 | :param App app: The configured application. 140 | 141 | 142 | .. function:: destroy() 143 | 144 | Called when :func:`~annotator.App.prototype.destroy` is called. If your 145 | module needs to do any cleanup, such as unbinding events or disposing of 146 | elements injected into the DOM, it should do so in the `destroy` hook. 147 | 148 | 149 | .. function:: annotationsLoaded(annotations) 150 | 151 | Called with annotations retrieved from storage using 152 | :func:`~annotator.storage.StorageAdapter.load`. 153 | 154 | :param Array[Object] annotations: The annotation objects loaded. 155 | 156 | 157 | .. function:: beforeAnnotationCreated(annotation) 158 | 159 | Called immediately before an annotation is created. Modules may use this 160 | hook to modify the annotation before it is saved. 161 | 162 | :param Object annotation: The annotation object. 163 | 164 | 165 | .. function:: annotationCreated(annotation) 166 | 167 | Called when a new annotation is created. 168 | 169 | :param Object annotation: The annotation object. 170 | 171 | 172 | .. function:: beforeAnnotationUpdated(annotation) 173 | 174 | Called immediately before an annotation is updated. Modules may use this 175 | hook to modify the annotation before it is saved. 176 | 177 | :param Object annotation: The annotation object. 178 | 179 | 180 | .. function:: annotationUpdated(annotation) 181 | 182 | Called when an annotation is updated. 183 | 184 | :param Object annotation: The annotation object. 185 | 186 | 187 | .. function:: beforeAnnotationDeleted(annotation) 188 | 189 | Called immediately before an annotation is deleted. Use if you need to 190 | conditionally cancel deletion, for example. 191 | 192 | :param Object annotation: The annotation object. 193 | 194 | 195 | .. function:: annotationDeleted(annotation) 196 | 197 | Called when an annotation is deleted. 198 | 199 | :param Object annotation: The annotation object. 200 | 201 | 202 | .. rubric:: Footnotes 203 | 204 | .. [#1] Yes, this might be quite annoying. Probably not an example to copy 205 | wholesale into your real application... 206 | -------------------------------------------------------------------------------- /doc/modules/authz.rst: -------------------------------------------------------------------------------- 1 | ``annotator.authz.acl`` 2 | ======================= 3 | 4 | This module configures an authorization policy that grants or denies permission 5 | on objects (especially annotations) based on the presence of ``permissions`` or 6 | ``user`` properties on the objects. 7 | 8 | See :func:`annotator.authz.acl` for full API documentation. 9 | -------------------------------------------------------------------------------- /doc/modules/identity.rst: -------------------------------------------------------------------------------- 1 | ``annotator.identity.simple`` 2 | ============================= 3 | 4 | This module configures an identity policy that considers the identity of the 5 | current user to be an opaque identifier. By default the identity is 6 | unconfigured, but can be set. 7 | 8 | Example 9 | ------- 10 | 11 | :: 12 | 13 | app.include(annotator.identity.simple); 14 | app 15 | .start() 16 | .then(function () { 17 | app.ident.identity = 'joebloggs'; 18 | }); 19 | 20 | See :func:`annotator.identity.simple` for full API documentation. 21 | -------------------------------------------------------------------------------- /doc/modules/index.rst: -------------------------------------------------------------------------------- 1 | Modules 2 | ======= 3 | 4 | A great deal of functionality in Annotator is provided by modules. These pages 5 | document these modules and how they work together. 6 | 7 | .. toctree:: 8 | :glob: 9 | :maxdepth: 1 10 | 11 | * 12 | -------------------------------------------------------------------------------- /doc/modules/ui.rst: -------------------------------------------------------------------------------- 1 | ``annotator.ui.main`` 2 | ===================== 3 | 4 | This module provides a user interface for the application, allowing users to 5 | make annotations on a document or an element within the document. It can be used 6 | as follows:: 7 | 8 | app.include(annotator.ui.main); 9 | 10 | By default, the module will set up event listeners on the document ``body`` so 11 | that when the user makes a selection they will be prompted to create an 12 | annotation. It is also possible to ask the module to only allow creation of 13 | annotations within a specific element on the page:: 14 | 15 | app.include(annotator.ui.main, { 16 | element: document.querySelector('#main') 17 | }); 18 | 19 | 20 | The module provides just one possible configuration of the various components in 21 | the `annotator.ui` package, and users with more advanced needs may wish to 22 | create their own modules that use those components (which include 23 | :class:`~annotator.ui.textselector.TextSelector`, 24 | :class:`~annotator.ui.adder.Adder`, 25 | :class:`~annotator.ui.highlighter.Highlighter`, 26 | :class:`~annotator.ui.viewer.Viewer`, and :class:`~annotator.ui.editor.Editor`). 27 | 28 | Viewer/editor extensions 29 | ------------------------ 30 | 31 | The `annotator.ui` package contains a number of extensions for the 32 | :class:`~annotator.ui.viewer.Viewer` and :class:`~annotator.ui.editor.Editor`, 33 | which extend the functionality. These include: 34 | 35 | - :func:`annotator.ui.tags.viewerExtension`: A viewer extension that displays 36 | any tags stored on annotations. 37 | 38 | - :func:`annotator.ui.tags.editorExtension`: An editor extension that provides 39 | a field for editing annotation tags. 40 | 41 | - :func:`annotator.ui.markdown.viewerExtension`: A viewer extension that 42 | depends on Showdown_, and makes the viewer render Markdown_ annotation 43 | bodies. 44 | 45 | .. _Showdown: https://github.com/showdownjs/showdown 46 | .. _Markdown: https://daringfireball.net/projects/markdown/ 47 | 48 | These can be used by passing them to the relevant options of 49 | ``annotator.ui.main``:: 50 | 51 | app.include(annotator.ui.main, { 52 | editorExtensions: [annotator.ui.tags.editorExtension], 53 | viewerExtensions: [ 54 | annotator.ui.markdown.viewerExtension, 55 | annotator.ui.tags.viewerExtension 56 | ] 57 | }); 58 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinxcontrib-httpdomain 2 | -------------------------------------------------------------------------------- /doc/roadmap.rst: -------------------------------------------------------------------------------- 1 | Annotator Roadmap 2 | ================= 3 | 4 | This document lays out the planned schedule and roadmap for the future 5 | development of Annotator. 6 | 7 | For each release below, the planned features reflect what the core team intend 8 | to work on, but are not an exhaustive list of what could be in the release. From 9 | the release of Annotator 2.0 onwards, we will operate a time-based release 10 | process, and any features merged by the relevant cutoff dates will be in the 11 | release. 12 | 13 | .. note:: This is a living document. Nothing herein constitutes a guarantee that 14 | a given Annotator release will contain a given feature, or that a 15 | release will happen on a specified date. 16 | 17 | 2.0 18 | +++ 19 | 20 | What will be in 2.0 21 | ------------------- 22 | 23 | - Improved internal API 24 | - UI component library (the UI was previously "baked in" to Annotator) 25 | - Support (for most features) for Internet Explorer 8 and up 26 | - Internal data model consistent with `Open Annotation`_ 27 | - A (beta-quality) storage component that speaks OA JSON-LD 28 | - Core code translated from CoffeeScript to JavaScript 29 | 30 | .. _Open Annotation: http://www.openannotation.org/ 31 | 32 | Schedule 33 | -------- 34 | 35 | The following dates are subject to change as needed. 36 | 37 | ================== ============================================ 38 | April 25, 2015 Annotator 2.0 alpha; major feature freeze 39 | August 1, 2015 Annotator 2.0 beta; complete feature freeze 40 | September 15, 2015 Annotator 2.0 RC1; translation string freeze 41 | 2 weeks after RC1 Annotator 2.0 final (or RC2 if needed) 42 | ================== ============================================ 43 | 44 | The long period between a beta release and RC1 takes account of time for other 45 | developers to test and report bugs. 46 | 47 | 48 | 2.1 49 | +++ 50 | 51 | The main goals for this release, which we aim to ship by Jan 1, 2016 (with a 52 | major feature freeze on Nov 15): 53 | 54 | - Support for selections made using the keyboard 55 | - Support in the core for annotation on touch devices 56 | - Support for multiple typed selectors in annotations 57 | - Support for components that resolve ('reanchor') an annotation's selectors 58 | into a form suitable for display in the page 59 | 60 | 61 | 2.2 62 | +++ 63 | 64 | The main goals for this release, which we aim to ship by Apr 1, 2016 (with a 65 | major feature freeze on Feb 15): 66 | 67 | - Support for annotation of additional media types (images, possibly video) in 68 | the core 69 | 70 | 2.3 71 | +++ 72 | 73 | The main goals for this release, which we aim to ship by Jul 1, 2016 (with a 74 | major feature freeze on May 15): 75 | 76 | - Improved highlight rendering (faster, doesn't modify underlying DOM) 77 | - Replace existing XPath-based selector code with Rangy_ 78 | 79 | .. _Rangy: https://github.com/timdown/rangy 80 | -------------------------------------------------------------------------------- /doc/usage.rst: -------------------------------------------------------------------------------- 1 | Configuring and using Annotator 2 | =============================== 3 | 4 | This document assumes you have already downloaded and installed Annotator. 5 | If you have not done so, please read :doc:`installing` before continuing. 6 | 7 | The basics 8 | ---------- 9 | 10 | .. |App| replace:: :class:`~annotator.App` 11 | 12 | When Annotator is loaded into the page, it exposes a single object, 13 | ``annotator``, which provides access to the main :class:`annotator.App` object 14 | and all other included components. To use Annotator, you must configure and 15 | start an |App|. At its simplest, that looks like this:: 16 | 17 | var app = new annotator.App(); 18 | app.start(); 19 | 20 | You probably want to keep reading if you want your Annotator installation to be 21 | useful straight away, as by default an |App| is extremely minimal. You can can 22 | easily add functionality from an Annotator :term:`module`, an independent 23 | components that you can load into your :term:`application`. For example, here 24 | we create an |App| that uses the default Annotator user interface 25 | (:func:`annotator.ui.main`), and the :func:`annotator.storage.http` storage 26 | component in order to save annotations to a remote server:: 27 | 28 | var app = new annotator.App(); 29 | app.include(annotator.ui.main); 30 | app.include(annotator.storage.http); 31 | app.start(); 32 | 33 | This is how most Annotator deployments will look: create an |App|, configure it 34 | with :func:`~annotator.App.prototype.include`, and then run it using 35 | :func:`~annotator.App.prototype.start`. 36 | 37 | If you want to do something (for example, load annotations from storage) when 38 | the |App| has started, you can take advantage of the fact that 39 | :func:`~annotator.App.prototype.start` returns a :term:`Promise`. Extending our 40 | example above:: 41 | 42 | var app = new annotator.App(); 43 | app.include(annotator.ui.main); 44 | app.include(annotator.storage.http); 45 | app 46 | .start() 47 | .then(function () { 48 | app.annotations.load(); 49 | }); 50 | 51 | 52 | This example calls :func:`~annotator.storage.StorageAdapter.prototype.load` on 53 | the ``annotations`` property of the |App|. This will load annotations from 54 | whatever storage component you have configured. 55 | 56 | Most functionality in Annotator comes from these modules, so you should 57 | familiarise yourself with what's available to you in order to make the most of 58 | Annotator. Next we talk about how to configure modules when you add them to your 59 | |App|. 60 | 61 | 62 | Configuring modules 63 | ------------------- 64 | 65 | Once you have a basic Annotator application working, you can begin to customize 66 | it. Some modules can be configured, and you can find out what options they 67 | accept in the relevant :doc:`api/index`. 68 | 69 | For example, here are the options accepted by the :func:`annotator.storage.http` 70 | module: :data:`annotator.storage.HttpStorage.options`. Let's say we have an 71 | `annotator-store server`_ running at ``http://example.com/api``. We can 72 | configure the :func:`~annotator.storage.http` module to address it like so:: 73 | 74 | app.include(annotator.storage.http, { 75 | prefix: 'http://example.com/api' 76 | }); 77 | 78 | .. _annotator-store server: https://github.com/openannotation/annotator-store 79 | 80 | 81 | Writing modules 82 | --------------- 83 | 84 | If you've looked through the available :doc:`modules` and haven't found what you 85 | want, you can write your own module. Read more about that in 86 | :doc:`module-development`. 87 | -------------------------------------------------------------------------------- /img/annotator-glyph-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openannotation/annotator/5ef5edf157fe728b2d6d95d01e26a55c508c0c44/img/annotator-glyph-sprite.png -------------------------------------------------------------------------------- /img/annotator-icon-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openannotation/annotator/5ef5edf157fe728b2d6d95d01e26a55c508c0c44/img/annotator-icon-sprite.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./src/app'); 2 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (karma) { 2 | karma.set({ 3 | frameworks: ["mocha", "browserify"], 4 | 5 | files: [ 6 | // Fixtures 7 | {pattern: 'test/fixtures/*.html', included: false}, 8 | 9 | // IE-specific shims 10 | {pattern: 'node_modules/wgxpath/wgxpath.install.js', watched: false}, 11 | 12 | // Test harness 13 | {pattern: 'node_modules/sinon/pkg/sinon.js', watched: false}, 14 | {pattern: 'node_modules/sinon/pkg/sinon-ie.js', watched: false}, 15 | 'test/init.js', 16 | 17 | // Test suites 18 | 'test/spec/**/*_spec.js' 19 | ], 20 | 21 | preprocessors: { 22 | 'node_modules/wgxpath/wgxpath.install.js': 'browserify', 23 | 'test/**/*.js': 'browserify' 24 | }, 25 | 26 | browserify: { 27 | debug: true, 28 | configure: function (bundle) { 29 | bundle.require('.', {expose: 'annotator'}); 30 | } 31 | }, 32 | 33 | browsers: ['PhantomJS'], 34 | 35 | reporters: ['dots'], 36 | 37 | customLaunchers: { 38 | 'SL_Chrome': { 39 | base: 'SauceLabs', 40 | browserName: 'chrome', 41 | version: '41' 42 | }, 43 | 'SL_Firefox': { 44 | base: 'SauceLabs', 45 | browserName: 'firefox', 46 | version: '36' 47 | }, 48 | 'SL_Safari': { 49 | base: 'SauceLabs', 50 | browserName: 'safari', 51 | platform: 'OS X 10.10', 52 | version: '8' 53 | }, 54 | 'SL_IE_8': { 55 | base: 'SauceLabs', 56 | browserName: 'internet explorer', 57 | platform: 'Windows 7', 58 | version: '8' 59 | }, 60 | 'SL_IE_9': { 61 | base: 'SauceLabs', 62 | browserName: 'internet explorer', 63 | platform: 'Windows 7', 64 | version: '9' 65 | }, 66 | 'SL_IE_10': { 67 | base: 'SauceLabs', 68 | browserName: 'internet explorer', 69 | platform: 'Windows 8', 70 | version: '10' 71 | }, 72 | 'SL_IE_11': { 73 | base: 'SauceLabs', 74 | browserName: 'internet explorer', 75 | platform: 'Windows 8.1', 76 | version: '11' 77 | } 78 | } 79 | }); 80 | 81 | if (process.env.TRAVIS) { 82 | var buildLabel = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')'; 83 | 84 | karma.sauceLabs = { 85 | build: buildLabel, 86 | startConnect: false, 87 | testName: 'Annotator', 88 | tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER 89 | }; 90 | 91 | // Travis/Sauce runs frequently time out before data starts coming back 92 | // from Sauce. This ups the timeout from 10 to 30 seconds. 93 | karma.browserNoActivityTimeout = 30 * 1000; 94 | 95 | karma.browsers = [process.env.BROWSER]; 96 | karma.reporters = ['dots', 'saucelabs']; 97 | } 98 | }; 99 | -------------------------------------------------------------------------------- /locale/Makefile: -------------------------------------------------------------------------------- 1 | annotator.pot: 2 | make -C ../pkg locales 3 | -------------------------------------------------------------------------------- /locale/annotator.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2013-07-08 19:52+0200\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=CHARSET\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: lib/util.js:24 21 | msgid "Annotator requires jQuery: have you included lib/vendor/jquery.js?" 22 | msgstr "" 23 | 24 | #: lib/util.js:28 25 | msgid "" 26 | "Annotator requires a JSON implementation: have you included lib/vendor/json2." 27 | "js?" 28 | msgstr "" 29 | 30 | #: lib/console.js:20 31 | msgid "Not implemented:" 32 | msgstr "" 33 | 34 | #: lib/range.js:16 35 | msgid "Could not sniff range type" 36 | msgstr "" 37 | 38 | #: lib/range.js:100 39 | msgid "You may only call normalize() once on a BrowserRange!" 40 | msgstr "" 41 | 42 | #: lib/annotator.js:20 43 | msgid "Annotate" 44 | msgstr "" 45 | 46 | #: lib/annotator.js:88 47 | msgid "No Comment" 48 | msgstr "" 49 | 50 | #: lib/annotator.js:103 51 | msgid "Comments" 52 | msgstr "" 53 | 54 | #: lib/annotator.js:306 55 | msgid "Can't dump annotations without Store plugin." 56 | msgstr "" 57 | 58 | #: lib/annotator.js:345 59 | msgid "You cannot have more than one instance of any plugin." 60 | msgstr "" 61 | 62 | #: lib/annotator.js:355 63 | msgid "Could not load " 64 | msgstr "" 65 | 66 | #: lib/annotator.js:355 67 | msgid " plugin. Have you included the appropriate