[annotator-dev] Port of Factlink's paragraph icons to Annotator.js

Jan Paul Posma janpaul at factlink.com
Sun May 17 04:54:40 UTC 2015


Alright, made it per your suggestion, and also made it mobile friendly
(touch = hover).

Didn't do a module pattern / AMD / UMD, since I've found that that can
be quite a pain to work with sometimes, and most module loaders have
some functionality to wrap "legacy" libraries in a module pattern.

Only major thing I didn't do yet was reloading when content on the
page changes, if someone needs this, let me know, I'd be happy to
implement it.

Also, if any of you uses this, please let me know, I'd love to see
this in the wild. :)

— JP

On Mon, May 4, 2015 at 10:32 PM, Jan Paul Posma <janpaul at factlink.com> wrote:
> Yep, that all makes a lot of sense. Thanks for the pointers. I'll find
> some time soon to implement that, and also get rid of some
> Factlink-specific stuff to make it more understandable for other
> developers. :-)
>
> On Mon, May 4, 2015 at 2:44 PM, Randall Leeds <tilgovi at hypothes.is> wrote:
>> Rough sketch of how I would want to use this as an application developer:
>>
>> var app = new annotator.App();
>> app.include(annotatorParagraphs);
>> app.include(function (registry) {
>>   return {
>>     createFromParagraph: function (p) {
>>        var targetText = p.textContent;
>>        var annotation = {
>>            target: // mySerializedParagraphIdentifier(p);
>>            // add other data here
>>        };
>>        app.annotations.create(annotation);
>>     }
>>   }
>> });
>>
>> On Mon, May 4, 2015 at 2:40 PM, Randall Leeds <tilgovi at hypothes.is> wrote:
>>>
>>> Ahh, I should have looked closer. I see in your index.html
>>> "app.include(window.paragraphUi);"
>>>
>>> It would certainly be nicer if this were packaged as a module so that it
>>> is possible to import it without it modifying the global object, but that's
>>> a nice-to-have.
>>>
>>> To answer your question, I think you do not want to expect the storage
>>> object. You want to fire hooks. Grab a reference to the application in your
>>> start hook and then use it later as follows:
>>>
>>>     app.runHook('create', [annotation])
>>>
>>> Probably, some of these will graduate to the level of deserving their own
>>> API, but we want to move slowly on adding API.
>>>
>>> However, I will say that these hooks are for creating annotations when
>>> your code is essentially about creating targets for potentially annotating.
>>> It is best for extensibility that you not encode assumptions about the
>>> structure of annotations into your hooks since that is where application
>>> developers need to have freedom. As such, it's far better to fire your own
>>> hooks providing just the data you need to and let application developers
>>> listen to those hooks and decide how to include that information into a new
>>> annotation and when to call the create hook themselves.
>>>
>>> If I were you, I would:
>>>
>>> - Expose _onClick in ParagraphIconButtonContainer to be public "onClick"
>>> and configurable.
>>>
>>> - Make sure this option is accessible from the way you construct the
>>> component in the Annotator "start" hook.
>>>
>>> - When you construct the component, construct it with an onClick that
>>> calls `app.runHook('myCustomHook', [data])`.
>>>
>>> - Your data should be about the paragraph button that was clicked and the
>>> paragraph it corresponds to. In particular:
>>>
>>>   - Don't make assumptions about how text should be extracted, or if it
>>> needs to be at all.
>>>
>>>   - Don't make assumptions about how to address that paragraph in a
>>> persistent way or attempt to provide that information.
>>>
>>>   - Do make enough of the raw event data available that the application
>>> developer can do these things for themselves.
>>>
>>> Thanks, JP. This looks great and I'd love to help you make this more
>>> accessible to the community.
>>>
>>>
>>>
>>>
>>>
>>> On Mon, May 4, 2015 at 2:27 PM, Randall Leeds <tilgovi at hypothes.is> wrote:
>>>>
>>>> Thanks, JP!
>>>>
>>>> On Sun, May 3, 2015 at 10:36 PM, Jan Paul Posma <janpaul at factlink.com>
>>>> wrote:
>>>>>
>>>>> For those of you who are interested in icons next to paragraphs that
>>>>> automatically integrate with a host website (paragraph detection,
>>>>> colour/size adjustment, style/script isolation, etc), I ported our
>>>>> code from Factlink to Annotator.js.
>>>>
>>>>
>>>> Aside from getting jQuery from annotator.util, does this use Annotator at
>>>> all or implement its extension module pattern?
>>>>
>>>> http://docs.annotatorjs.org/en/latest/module-development.html
>>>>
>>>>>
>>>>> Code: https://github.com/Factlink/annotator-paragraph-icons
>>>>> Demo: http://factlink.github.io/annotator-paragraph-icons/
>>>>>
>>>>> Main advantages are that this interface is easier to discover, could
>>>>> be made to work well on mobile (show icon when touching a paragraph),
>>>>> and could be used to group annotations instead of highlights or a more
>>>>> complicated sidebar as Hypothes.is has (though this grouping is
>>>>> currently not implemented).
>>>>>
>>>>> Only thing missing is the actual saving of the annotation, that seemed
>>>>> a bit tricky for me to figure out, and not really documented. If
>>>>> someone from the Annotator team could fill this in, that would be
>>>>> awesome:
>>>>> https://github.com/Factlink/annotator-paragraph-icons/blob/784bf4c60db28e0612d2ae711abcb0c1b9f90972/app/icon_buttons.coffee#L136
>>>>
>>>>
>>>> The `start` hook receives the `App` as an argument.
>>>>
>>>> It's probably reasonable to expect that instance to have a property,
>>>> `annotations` conforming to the Storage interface. The details of this are
>>>> not 100% settled and the robustness of using the application instance to get
>>>> these properties is not known yet, until we see more applications built.
>>>>
>>>> The absolute best thing you can do to start with is to make sure your
>>>> code has a public interface. One should be able to instantiate it, likely
>>>> given a root element under which to act, and it should provide some way for
>>>> the user to be notified about events that your code handles, for instance by
>>>> providing an `onClick` option to the constructor.
>>>>
>>>> From there, wrapping it as an Annotator module and including it in an
>>>> application should be straightforward. However, crucially, the core of what
>>>> you've done becomes independent of Annotator or any other annotation
>>>> application/framework.
>>>>
>>>
>>



More information about the annotator-dev mailing list