You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@annotator.apache.org by ra...@apache.org on 2020/04/03 01:30:45 UTC

[incubator-annotator] branch remove-fragment-identifier created (now d443458)

This is an automated email from the ASF dual-hosted git repository.

randall pushed a change to branch remove-fragment-identifier
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git.


      at d443458  Remove fragment-identifier package

This branch includes the following new commits:

     new d443458  Remove fragment-identifier package

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-annotator] 01/01: Remove fragment-identifier package

Posted by ra...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

randall pushed a commit to branch remove-fragment-identifier
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git

commit d4434589d0853e7a8b7db0e6f0493962cda288cd
Author: Randall Leeds <ra...@apache.org>
AuthorDate: Thu Apr 2 18:27:59 2020 -0700

    Remove fragment-identifier package
    
    Due to unresolved questions about the fragment identifier format and
    difficulties around parsing the fragment identifier correctly, remove
    the fragment-identifier package entirely for the time being.
    
    See also [w3c/web-annotation#443].
    
    Close #66.
    
    [w3c/web-annotation#443]: https://github.com/w3c/web-annotation/issues/443
---
 NOTICE                                          |  7 --
 packages/fragment-identifier/.gitignore         |  1 -
 packages/fragment-identifier/.npmignore         |  2 -
 packages/fragment-identifier/README.md          |  3 -
 packages/fragment-identifier/package.json       | 30 --------
 packages/fragment-identifier/src/fragment.pegjs | 71 ------------------
 packages/fragment-identifier/src/index.js       | 44 ------------
 web/demo/index.html                             | 46 +++++-------
 web/demo/index.js                               | 95 +++++++++++++++++++------
 9 files changed, 88 insertions(+), 211 deletions(-)

diff --git a/NOTICE b/NOTICE
index 10b80b9..ae82a60 100644
--- a/NOTICE
+++ b/NOTICE
@@ -3,10 +3,3 @@ Copyright 2016-2020 The Apache Software Foundation
 
 This product includes software developed at The Apache Software
 Foundation (http://www.apache.org/).
-
-This product includes material copied from or derived from
-Selectors and States (https://www.w3.org/TR/selectors-states/) and the
-accompanying code samples (https://github.com/w3c/web-annotation/).
-Copyright (c) 2016 W3C(R) (MIT, ERCIM, Keio, Beihang) and licensed under the
-"W3C Software and Document Notice and License"
-(https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document).
diff --git a/packages/fragment-identifier/.gitignore b/packages/fragment-identifier/.gitignore
deleted file mode 100644
index dac4690..0000000
--- a/packages/fragment-identifier/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/src/fragment.js
diff --git a/packages/fragment-identifier/.npmignore b/packages/fragment-identifier/.npmignore
deleted file mode 100644
index 281df39..0000000
--- a/packages/fragment-identifier/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-src
-test
diff --git a/packages/fragment-identifier/README.md b/packages/fragment-identifier/README.md
deleted file mode 100644
index dd0f4da..0000000
--- a/packages/fragment-identifier/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-This package is a part of the Apache Annotator (incubating) project.
-
-For docs and other useful info see the [website](https://annotator.apache.org/) or [GitHub repository](https://github.com/apache/incubator-annotator).
diff --git a/packages/fragment-identifier/package.json b/packages/fragment-identifier/package.json
deleted file mode 100644
index ad9f719..0000000
--- a/packages/fragment-identifier/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "name": "@annotator/fragment-identifier",
-  "version": "0.1.0",
-  "description": "Convert to and from Web Annotation fragment identifiers.",
-  "homepage": "https://annotator.apache.org",
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/apache/incubator-annotator.git"
-  },
-  "license": "Apache-2.0",
-  "author": "Apache Software Foundation",
-  "main": "lib/index.js",
-  "module": "esm/index.js",
-  "scripts": {
-    "prepare": "pegjs --format es --output src/fragment.js src/fragment.pegjs"
-  },
-  "dependencies": {
-    "@babel/runtime-corejs3": "^7.8.7",
-    "core-js": "^3.6.4"
-  },
-  "devDependencies": {
-    "pegjs": "^0.11.0-dev.273"
-  },
-  "engines": {
-    "node": ">=10.0.0"
-  },
-  "publishConfig": {
-    "access": "public"
-  }
-}
diff --git a/packages/fragment-identifier/src/fragment.pegjs b/packages/fragment-identifier/src/fragment.pegjs
deleted file mode 100644
index 871e94a..0000000
--- a/packages/fragment-identifier/src/fragment.pegjs
+++ /dev/null
@@ -1,71 +0,0 @@
-{
-    function collect() {
-      var ret = {};
-      var len = arguments.length;
-      for (var i=0; i<len; i++) {
-        for (var p in arguments[i]) {
-          if (arguments[i].hasOwnProperty(p)) {
-            ret[p] = arguments[i][p];
-          }
-        }
-      }
-      return ret;
-    }
-}
-
-
-start =
-    top
-
-top
-    = "state" "(" p:params ")"      { return { state: p } }
-    / "selector" "(" p:params ")"   { return { selector: p } }
-    / "state=" v:value              { return { state: v } }
-    / "selector=" v:value           { return { selector: v } }
-
-params
-    = k1: key_value_pair k2:("," key_value_pair)*
-        {
-            var f = k1;
-            for( var i = 0; i < k2.length; i++ ) {
-                f = collect(f, k2[i][1])
-            }
-            return f;
-        }
-
-key_value_pair
-    = "refinedBy=selector(" p:params ")"
-         {
-            return { refinedBy: p }
-         }
-    / "refinedBy=state(" p:params ")"
-         {
-            return { refinedBy: p }
-         }
-    / "startSelector=selector(" p:params ")"
-        {
-            return { startSelector: p };
-        }
-    / "endSelector=selector(" p:params ")"
-        {
-            return { endSelector: p };
-        }
-    / key:key "=" value:value
-        {
-            var f = {};
-            var num = Number(value);
-            f[key] = isNaN(num) ? decodeURIComponent(value): num;
-            return f;
-        }
-
-key
-    = atom
-
-value
-    = atom
-
-atom
-    = chars:validchar+ { return chars.join(""); }
-
-validchar
-    = [a-zA-Z0-9\<\>\/\[\]\:%+@.\-!\$\&\;*_]
diff --git a/packages/fragment-identifier/src/index.js b/packages/fragment-identifier/src/index.js
deleted file mode 100644
index 0ba2e4d..0000000
--- a/packages/fragment-identifier/src/index.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @license
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { SyntaxError, parse } from './fragment.js';
-
-/**
- * Convert a Selector or State into a fragment identifier string.
- * @param {(Selector|State)} resource
- * @return {string}
- */
-export function stringify(resource) {
-  const data = Object.keys(resource)
-    .map(key => {
-      let value = resource[key];
-      if (value instanceof Object) value = value.valueOf();
-      if (value instanceof Object) {
-        value = stringify(value);
-        return `${encodeURIComponent(key)}=${value}`;
-      }
-      return [key, value].map(encodeURIComponent).join('=');
-    })
-    .join(',');
-
-  if (/Selector$/.test(resource.type)) return `selector(${data})`;
-  if (/State$/.test(resource.type)) return `state(${data})`;
-  throw new TypeError('Resource must be a Selector or State');
-}
diff --git a/web/demo/index.html b/web/demo/index.html
index f941ffb..656dd7d 100644
--- a/web/demo/index.html
+++ b/web/demo/index.html
@@ -25,17 +25,17 @@ under the License.
   <title>Apache Annotator (incubating) demo</title>
   <link rel="stylesheet" href="../style.css"/>
   <style>
-    a[href^="#selector"]:before {
+    a[name="example"]:before {
       content: 'đŸ“Œ ';
     }
 
-    #selectable, #corpus {
+    #source, #target {
       padding: 1em;
       border: 1px solid lightgrey;
       background: white;
     }
 
-    #parsed {
+    #info {
       height: 15em;
       overflow: scroll;
       background: white;
@@ -59,53 +59,39 @@ under the License.
   <main>
     <h1>Selector Demonstration</h1>
 
-    <p>
-      This page demonstrates Web Annotation
+    <p>This page demonstrates Web Annotation
       <a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#selectors" target="_blank">Selectors</a>,
-      standardised JSON objects that describe a selection inside a document with sufficient information to find it back.
-     </p>
+      standardised JSON objects that describe a selection inside a document with sufficient information to find it back.</p>
 
     <div class="columns full-width">
       <div class="column">
         <h2>Select text here</h2>
-        <p id="selectable">Hello, annotated world! To annotate, or not to annotate, that is the question.</p>
-        <p>
-          Try selecting some text in this paragraph above.
+        <p id="source">Hello, annotated world! To annotate, or not to annotate, that is the question.</p>
+        <p>Try selecting some text in this paragraph above.
           Upon a change of selection, a
           <a rel="external" href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#text-quote-selector" target="_blank">TextQuoteSelector</a>
-          will be created, that describes what was selected.
-        </p>
+          will be created, that describes what was selected.</p>
       </div>
       <div class="column">
         <h2>Text is found here</h2>
-        <p id="corpus" contenteditable>Hello, annotated world! To annotate, or not to annotate, that is the question.</p>
-        <p>
-          The selector is ‘anchored’ here: the segment it describes is found and highlighted.
-        </p>
+        <p id="target" contenteditable>Hello, annotated world! To annotate, or not to annotate, that is the question.</p>
+        <p>The selector is ‘anchored’ here: the segment it describes is found and highlighted.</p>
       </div>
       <div class="column" style="min-width: 20em;">
         <h2>The selector as JSON:</h2>
-        <pre id="parsed"></pre>
+        <pre id="info"></pre>
       </div>
     </div>
-    <p>
-      Note that the selector is also serialised and shown in the window location, as the fragment identifier
-      (following <a rel="external" href="https://www.w3.org/TR/2017/NOTE-selectors-states-20170223/#frags" target="_blank">this specification</a>).
-      In fact, it is this fragment identifier that is parsed back into JSON and then anchored in the text above.
-    </p>
-    <p>
-      Here are other selectors you can anchor in the text above:
-    </p>
+    <p>Here are other selectors you can anchor in the text above:</p>
     <ul>
-      <li><a href="#selector(type=TextQuoteSelector,exact=not)">An ambiguous selector (i.e. with multiple matches)</a>
+      <li><a href="#" name="example">An ambiguous selector (i.e. with multiple matches)</a>
       <li>
-        <a href="#selector(type=RangeSelector,startSelector=selector(type=TextQuoteSelector,exact=ann),endSelector=selector(type=TextQuoteSelector,exact=!))">RangeSelector</a>
+        <a href="#" name="example">RangeSelector</a>
         (<a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#range-selector" target="_blank">spec</a>)
       <li>
-        <a href="#selector(type=TextQuoteSelector,exact=annotated%20world,refinedBy=selector(type=TextQuoteSelector,exact=tat))">Refining
-          a selector using another selector</a>
+        <a href="#" name="example">Refining a selector using another selector</a>
         (<a href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#refinement-of-selection" target="blank">spec</a>)
-      <li><a href="#selector(type=TextQuoteSelector,exact=To%20annotate%2C%20or%20not%20to%20annotate%2C,refinedBy=selector(type=RangeSelector,startSelector=selector(type=TextQuoteSelector,exact=To%20annotate,refinedBy=selector(type=TextQuoteSelector,exact=annotate)),endSelector=selector(type=TextQuoteSelector,exact=not%20to%20annotate,refinedBy=selector(type=TextQuoteSelector,exact=%20to)),refinedBy=selector(type=TextQuoteSelector,exact=o)))">Any deeper nesting of the above</a>
+      <li><a href="#" name="example">Any deeper nesting of the above</a>
     </ul>
   </main>
 </body>
diff --git a/web/demo/index.js b/web/demo/index.js
index 3e2332e..953464a 100644
--- a/web/demo/index.js
+++ b/web/demo/index.js
@@ -18,13 +18,9 @@
  * under the License.
  */
 
-/* global corpus, module, parsed, selectable */
+/* global info, module, source, target */
 
 import {
-  parse as parseFragment,
-  stringify as stringifyFragment,
-} from '@annotator/fragment-identifier';
-import {
   createRangeSelectorCreator,
   createTextQuoteSelector,
   describeTextQuote,
@@ -32,6 +28,59 @@ import {
 } from '@annotator/dom';
 import { makeRefinable } from '@annotator/selector';
 
+const EXAMPLE_SELECTORS = [
+  {
+    type: 'TextQuoteSelector',
+    exact: 'not',
+  },
+  {
+    type: 'RangeSelector',
+    startSelector: {
+      type: 'TextQuoteSelector',
+      exact: 'ann',
+    },
+    endSelector: {
+      type: 'TextQuoteSelector',
+      exact: '!',
+    },
+  },
+  {
+    type: 'TextQuoteSelector',
+    exact: 'annotated world',
+    refinedBy: {
+      type: 'TextQuoteSelector',
+      exact: 'tat',
+    },
+  },
+  {
+    type: 'TextQuoteSelector',
+    exact: 'To annotate, or not to annotate,',
+    refinedBy: {
+      type: 'RangeSelector',
+      startSelector: {
+        type: 'TextQuoteSelector',
+        exact: 'To annotate',
+        refinedBy: {
+          type: 'TextQuoteSelector',
+          exact: 'annotate',
+        },
+      },
+      endSelector: {
+        type: 'TextQuoteSelector',
+        exact: 'not to annotate',
+        refinedBy: {
+          type: 'TextQuoteSelector',
+          exact: ' to',
+        },
+      },
+      refinedBy: {
+        type: 'TextQuoteSelector',
+        exact: 'o',
+      },
+    },
+  },
+];
+
 const cleanupFunctions = [];
 
 function cleanup() {
@@ -39,7 +88,7 @@ function cleanup() {
   while ((removeHighlight = cleanupFunctions.shift())) {
     removeHighlight();
   }
-  corpus.normalize();
+  target.normalize();
 }
 
 const createSelector = makeRefinable(selector => {
@@ -55,17 +104,13 @@ const createSelector = makeRefinable(selector => {
   return selectorCreator(selector);
 });
 
-const refresh = async () => {
+const refresh = async selector => {
   cleanup();
 
-  const fragment = window.location.hash.slice(1);
-  if (!fragment) return;
-
-  const { selector } = parseFragment(fragment);
   const matchAll = createSelector(selector);
   const ranges = [];
 
-  for await (const range of matchAll(corpus)) {
+  for await (const range of matchAll(target)) {
     ranges.push(range);
   }
 
@@ -74,7 +119,7 @@ const refresh = async () => {
     cleanupFunctions.push(removeHighlight);
   }
 
-  parsed.innerText = JSON.stringify(selector, null, 2);
+  info.innerText = JSON.stringify(selector, null, 2);
 };
 
 async function describeSelection() {
@@ -85,7 +130,7 @@ async function describeSelection() {
   if (range.collapsed) return;
 
   const scope = document.createRange();
-  scope.selectNodeContents(selectable);
+  scope.selectNodeContents(source);
 
   if (!scope.isPointInRange(range.startContainer, range.startOffset)) return;
   if (!scope.isPointInRange(range.endContainer, range.endOffset)) return;
@@ -95,19 +140,22 @@ async function describeSelection() {
 
 async function onSelectionChange() {
   const selector = await describeSelection();
-  const fragment = selector ? stringifyFragment(selector) : '';
-  const url = new URL(window.location.href);
-  url.hash = fragment ? `#${fragment}` : '';
+  refresh(selector);
+}
 
-  if (url.href !== window.location.href) {
-    window.history.replaceState(selector, null, url.href);
-    refresh();
-  }
+function onSelectorExampleClick(event) {
+  if (event.target.getAttribute('name') !== 'example') return;
+  event.preventDefault();
+  const exampleAnchors = document.querySelectorAll('[name=example]');
+  const index = Array.from(exampleAnchors).indexOf(event.target);
+  const selector = EXAMPLE_SELECTORS[index];
+  refresh(selector);
 }
 
-window.addEventListener('popstate', refresh);
-document.addEventListener('DOMContentLoaded', refresh);
+window.addEventListener('popstate', () => refresh());
+document.addEventListener('DOMContentLoaded', () => refresh());
 document.addEventListener('selectionchange', onSelectionChange);
+document.addEventListener('click', onSelectorExampleClick);
 
 if (module.hot) {
   module.hot.accept();
@@ -115,5 +163,6 @@ if (module.hot) {
     window.removeEventListener('popstate', refresh);
     document.removeEventListener('DOMContentLoaded', refresh);
     document.removeEventListener('selectionchange', onSelectionChange);
+    document.removeEventListener('click', onSelectorExampleClick);
   });
 }