A chrome extension for tagging words with semantic information.
Find a file
Nils Norman Haukås 1dc2c1a247 Add material design and settings page.
Squashed commit of the following:

commit 8eaac39b94663e32659e41dde211a197cfdf567f
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Sun Aug 7 13:46:56 2016 +0200

    Prepare new feature for plugification

    Menu.tpl.html now references chrome plugin file resources for material design.
    Adjusted build step to copy material design styles and such. Whitelisted web accessible resources in
    manifest.json. Bump version number.

commit a2662042904ee69613b75fc1bebb188c9783f414
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Sun Aug 7 12:54:27 2016 +0200

    Use parameter properties

commit 888e3511212eca705585651f4d9286502b5c05b6
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Sun Aug 7 12:45:51 2016 +0200

    Post tags to configurable endpoint

    User can now specify the url where tags should be posted.

commit f4adda15223bba3044184d4a0780387051828958
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Sun Aug 7 07:06:30 2016 +0200

    Rename to settings service

commit 5646a8dabab740267181d0d87ec369bbdabe42e5
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Sun Aug 7 07:02:36 2016 +0200

    Reworked settings

    Replaced index.Appconfig.ts with appConfig.service. This paves way for an adjustable settingspage.

commit 63c7d5bfa2029702ba5e4eafa462436f5e547afa
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Sun Aug 7 07:01:57 2016 +0200

    Update angular.js version to 1.5.8

commit bcee26ccda036abdb90a98121dab3bd1e0e39fcc
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Thu Jul 14 22:00:26 2016 +0200

    removed browsersync notification

commit 71b0c3a1c735c1b2293c21a756f0bf05f85ccacc
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Thu Jul 14 21:58:12 2016 +0200

    Added spinner, started settings page

commit fd0b16a146c7f633f354ed4f8c69754d9b66cfdd
Author: Nils Norman Haukås <nils@thunki.com>
Date:   Mon Jun 27 21:50:50 2016 +0200

    Include material-design-lite, started building settings page.
2016-08-07 13:49:33 +02:00
src Add material design and settings page. 2016-08-07 13:49:33 +02:00
test Add material design and settings page. 2016-08-07 13:49:33 +02:00
typings Squashed commit of the following: 2016-06-25 20:16:17 +02:00
.gitignore Squashed commit of the following: 2016-06-25 20:16:17 +02:00
build.sh Add material design and settings page. 2016-08-07 13:49:33 +02:00
config.js Add material design and settings page. 2016-08-07 13:49:33 +02:00
package.json Add material design and settings page. 2016-08-07 13:49:33 +02:00
README.md Update readme and build script 2016-06-25 20:54:32 +02:00
tsconfig.json Squashed commit of the following: 2016-06-25 20:16:17 +02:00
typings.json Squashed commit of the following: 2016-06-25 20:16:17 +02:00

tag-youre-it

A chrome extension for tagging words with semantic information.

Development

What you need to do to get started developing this plugin.

Prerequisites:

  1. git clone this project.
  2. Run npm install
  3. Run npm start to serve up the prototype for live development. To configure what browser is started please see the npm start command found in the package.json file.

Please note: A workaround for CORS is needed for allowing the live development version to talk to the server.

Chrome testing

  1. Run npm run build to generate a dist/ folder.
  2. Inside chrome go to settings -> Extensions.
  3. Select Load unpacked extension and select the project's generated dist/ folder.
  4. You should now see a new browser icon. Go to a page and start tagging.
  5. In case of error: Press "f12" and have a look at the console log output.

What's happening under the hood?

Technology stack (roughly): Jspm, Typings, Angular.js, Typescript, Lodash and Rangy.js.

How is the plugin loaded? Manifest.json adds an icon and defines an event page called background.js. The event page adds a click listener to the plugin's browser icon. When triggered it will first load jquery and then inject the html menu in an iframe as well as create an iframe for housing the page content. The plugin is in fact reloading the page inside an iframe on the page. It will then continue loading dependencies before finally calling tagit.init() on the plugin which makes angular initialize itself making it possible to interact with the injected menu. When loading the plugin it will check localstorage for previously made tags and add them to the page. The plugin will also add click listeners to the iframe(s) containing the content to be tagged.

Why iframes? I originally tried to just inject the menu into the page to tag. This was the source of a number of issues. Tags need to be related to the original page structure but was disturbed by the injected non-static plugin menu. CSS was also quite unmanageable as the original page's css would disturb the plugin menu and vice versa. In really bad cases the content to be tagged would seep out of its containing <div></div> element and overlap the plugin menu. All things considered iframes seem like a decent approach since they shield our menu and the taggable content from each other.

How does tagging happen? After the plugin has been loaded it will have added click listeners to the iframe(s) containing the taggable content. When a click is registered the plugin will check if a word was selected. If a new word has been selected it will query a backend service (url endpoint) for possible definitions to tag the word with and display them in the menu. When the user selects a definition the plugin tags the word, saves the tag in localstorage and posts the result back to the backend service.

Particularities to tagging: When tagging a selection the plugin must always relate the tag position to the original DOM object (original web page structure). Thus the plugin will remove all tags and selections before saving a word selection or saving a tag. Tags also need to be loaded in a bottom up order so that their range.startOffset is always in relation to the original DOM. StartOffset is simply a position number of where the node (html element etc.) is located within the DOM tree-structure that starts with 0 (document root).

Even more particularities to tagging: When a word is selected rangy.js adds invisible selection markers (spans) to the page which safeguards against accidentally unselecting the word we are trying to tag or accidentally tagging the wrong word. The selection markers will be removed when loading the selection again (making the right word selected in blue on the page). After loading the selection we tag the word by wrapping it in a span that contains tagging information and style information which highlights the tagged word. A button element is also added inside the span for removing the tag.

Licensed under the MIT License

Copyright (c) 2016 Nils Norman Haukås

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.