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 2019/06/09 05:08:54 UTC

[incubator-annotator] branch master updated (4efbcd4 -> 93fc7ba)

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

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


    from 4efbcd4  Switch gitbox links to github
     new bc5e97d  Refactor API
     new 93fc7ba  Use prepublishOnly script instead of prepublish

The 2 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.


Summary of changes:
 demo/search.js                 | 27 ++++++++++++--------
 package.json                   |  2 +-
 packages/dom/src/index.js      | 11 +++-----
 packages/dom/src/text/quote.js | 15 +++++------
 packages/range/src/index.js    | 44 ++++++++++++++++----------------
 packages/selector/src/index.js | 57 +++++++++++++-----------------------------
 packages/text/src/index.js     | 42 ++++++++++++++-----------------
 7 files changed, 84 insertions(+), 114 deletions(-)


[incubator-annotator] 02/02: Use prepublishOnly script instead of prepublish

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

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

commit 93fc7bab064551e0f6cc1b1afe805e430ca0eb0f
Author: Randall Leeds <ra...@apache.org>
AuthorDate: Sat Jun 8 22:07:48 2019 -0700

    Use prepublishOnly script instead of prepublish
    
    The prepublish step is deprecated for npm scripts. The intention here is
    to run the build only before publishing the packages.
---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index c88a13d..b01a129 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
     "clean": "lerna exec -- rimraf LICENSE NOTICE esm lib",
     "lint": "eslint --fix --quiet .",
     "prepare": "lerna run prepare",
-    "prepublish": "yarn run build",
+    "prepublishOnly": "yarn run build",
     "start": "webpack-dev-server --hot --mode development",
     "test": "cross-env BABEL_ENV=test nyc mocha packages/*/test/**/*.js",
     "validate": "cross-env BABEL_ENV=test nyc mocha test/**/*.js"


[incubator-annotator] 01/02: Refactor API

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

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

commit bc5e97d0e2991fedcc9f7db76bf373e3b23c9e29
Author: Randall Leeds <ra...@apache.org>
AuthorDate: Sat Jun 8 21:57:40 2019 -0700

    Refactor API
    
    Refactor the API so that creating a selector results in a function that
    accepts a scope against which to match the selector.
---
 demo/search.js                 | 27 ++++++++++++--------
 packages/dom/src/index.js      | 11 +++-----
 packages/dom/src/text/quote.js | 15 +++++------
 packages/range/src/index.js    | 44 ++++++++++++++++----------------
 packages/selector/src/index.js | 57 +++++++++++++-----------------------------
 packages/text/src/index.js     | 42 ++++++++++++++-----------------
 6 files changed, 83 insertions(+), 113 deletions(-)

diff --git a/demo/search.js b/demo/search.js
index c51c1b8..150058f 100644
--- a/demo/search.js
+++ b/demo/search.js
@@ -13,29 +13,34 @@
  * the License.
  */
 
-import { createRangeSelector } from '@annotator/range';
-import { createAnySelectorCreator } from '@annotator/selector';
+import { makeRefinable } from '@annotator/selector';
+import { createRangeSelectorCreator } from '@annotator/range';
 import { createTextQuoteSelector } from '@annotator/text';
 
-const allSelectorTypes = {
-  TextQuoteSelector: createTextQuoteSelector,
-  RangeSelector: createRangeSelector,
-};
+const createSelector = makeRefinable(selector => {
+  const selectorCreator = {
+    TextQuoteSelector: createTextQuoteSelector,
+    RangeSelector: createRangeSelectorCreator(createSelector),
+  }[selector.type];
 
-const createSelector = createAnySelectorCreator(allSelectorTypes);
+  if (selectorCreator == null) {
+    throw new Error(`Unsupported selector type: ${selector.type}`);
+  }
+
+  return selectorCreator(selector);
+});
 
 /**
  * Locate a selector.
  * @param {Node} root node
- * @param {Selector} descriptor
+ * @param {Selector} selector
  * @return {Range}
  */
-export async function* search(root, descriptor) {
+export async function* search(root, selector) {
   for (const node of nodeIterator(root)) {
     if (!node.nodeValue) continue;
 
-    const selector = createSelector(node.nodeValue);
-    const matches = selector([descriptor]);
+    const matches = createSelector(selector)(node.nodeValue);
 
     for await (let match of matches) {
       const startIndex = match.index;
diff --git a/packages/dom/src/index.js b/packages/dom/src/index.js
index 80b1efd..a1d9cbd 100644
--- a/packages/dom/src/index.js
+++ b/packages/dom/src/index.js
@@ -15,11 +15,8 @@
 
 export * from './text';
 
-export function createCssSelector(context) {
-  async function* exec(descriptors) {
-    const cssSelector = descriptors.map(({ value }) => value).join(',');
-    yield* context.querySelectorAll(cssSelector);
-  }
-
-  return exec;
+export function createCssSelector(selector) {
+  return async function* matchAll(scope) {
+    yield* scope.querySelectorAll(selector.value);
+  };
 }
diff --git a/packages/dom/src/text/quote.js b/packages/dom/src/text/quote.js
index 13b6add..87c7926 100644
--- a/packages/dom/src/text/quote.js
+++ b/packages/dom/src/text/quote.js
@@ -30,7 +30,7 @@ export async function describeTextQuoteByRange({ range, context }) {
   const contextText = context.cloneContents().textContent;
   const exact = range.cloneContents().textContent;
 
-  const descriptor = {
+  const selector = {
     type: 'TextQuoteSelector',
     exact,
   };
@@ -46,11 +46,11 @@ export async function describeTextQuoteByRange({ range, context }) {
   ) {
     throw new Error(`Context not equal to range's container; not implemented.`);
   }
+
   const rangeIndex = range.startOffset;
   const rangeEndIndex = range.endOffset;
 
-  const selector = createTextQuoteSelector(contextText);
-  const matches = selector([descriptor]);
+  const matches = createTextQuoteSelector(selector)(contextText);
   const minSuffixes = [];
   const minPrefixes = [];
   for await (let match of matches) {
@@ -72,18 +72,15 @@ export async function describeTextQuoteByRange({ range, context }) {
   }
   const [minSuffix, minPrefix] = minimalSolution(minSuffixes, minPrefixes);
   if (minSuffix > 0) {
-    descriptor.suffix = contextText.substring(
+    selector.suffix = contextText.substring(
       rangeEndIndex,
       rangeEndIndex + minSuffix,
     );
   }
   if (minPrefix > 0) {
-    descriptor.prefix = contextText.substring(
-      rangeIndex - minPrefix,
-      rangeIndex,
-    );
+    selector.prefix = contextText.substring(rangeIndex - minPrefix, rangeIndex);
   }
-  return descriptor;
+  return selector;
 }
 
 function overlap(text1, text2) {
diff --git a/packages/range/src/index.js b/packages/range/src/index.js
index a9b8b82..4432423 100644
--- a/packages/range/src/index.js
+++ b/packages/range/src/index.js
@@ -15,32 +15,30 @@
 
 import { product } from './cartesian.js';
 
-export function createRangeSelector(context, createAnySelector) {
-  const startSelector = createAnySelector(context);
-  const endSelector = createAnySelector(context);
+export function createRangeSelectorCreator(createSelector) {
+  return function createRangeSelector(selector) {
+    const startSelector = createSelector(selector.startSelector);
+    const endSelector = createSelector(selector.endSelector);
 
-  async function* rangeSelector(descriptors) {
-    const descriptor = descriptors[0]; // TODO handle multiple descriptors
-    const startMatches = startSelector([descriptor.startSelector]);
-    const endMatches = endSelector([descriptor.endSelector]);
-    const pairs = product(startMatches, endMatches);
-    for await (let [start, end] of pairs) {
-      if (start.index > end.index) {
-        continue;
+    return async function* matchAll(scope) {
+      const startMatches = startSelector(scope);
+      const endMatches = endSelector(scope);
+      const pairs = product(startMatches, endMatches);
+      for await (let [start, end] of pairs) {
+        if (start.index > end.index) {
+          continue;
+        }
+        const text = rangeBetween({ start, end, scope });
+        const result = [text];
+        result.index = start.index;
+        result.input = scope;
+        yield result;
       }
-      const text = rangeBetween({ start, end, context });
-      const result = [text];
-      result.index = start.index;
-      result.input = context;
-      result.descriptor = descriptor;
-      yield result;
-    }
-  }
-
-  return rangeSelector;
+    };
+  };
 }
 
-function rangeBetween({ start, end, context }) {
-  const range = context.substring(start.index, end.index);
+function rangeBetween({ start, end, scope }) {
+  const range = scope.substring(start.index, end.index);
   return range;
 }
diff --git a/packages/selector/src/index.js b/packages/selector/src/index.js
index 17b79f1..86c6ef9 100644
--- a/packages/selector/src/index.js
+++ b/packages/selector/src/index.js
@@ -13,52 +13,30 @@
  * the License.
  */
 
-export function createAnySelectorCreator(selectorCreatorsByType) {
-  function selectSelector(context, type) {
-    const selectorCreatorForType = selectorCreatorsByType[type];
-    if (selectorCreatorForType === undefined) {
-      throw new Error(`Unsupported selector type: ${type}`);
-    }
-    let selector = selectorCreatorForType(context, selectorCreator);
-    selector = makeRefinable(selector, selectorCreator);
-    return selector;
-  }
-
-  function selectorCreator(context) {
-    async function* anySelector(descriptors) {
-      const descriptor = descriptors[0]; // TODO handle multiple descriptors
-      const selectorFunc = selectSelector(context, descriptor.type);
-      yield* selectorFunc([descriptor]);
-    }
-    return anySelector;
-  }
+export function makeRefinable(selectorCreator) {
+  return function createSelector(source) {
+    const selector = selectorCreator(source);
 
-  return selectorCreator;
-}
+    if (source.refinedBy) {
+      const refiningSelector = createSelector(source.refinedBy);
 
-export function makeRefinable(selector, selectorCreator) {
-  async function* refinableSelector(descriptors) {
-    const matches = selector(descriptors);
-    for await (let match of matches) {
-      const refiningDescriptor = match.descriptor.refinedBy;
-      if (refiningDescriptor) {
-        const refiningContext = matchAsContext(match);
-        const refiningSelector = selectorCreator(refiningContext);
-        const refiningMatches = refiningSelector([refiningDescriptor]);
-        for await (let refiningMatch of refiningMatches) {
-          const refinedMatch = composeMatches(refiningMatch, match);
-          yield refinedMatch;
+      return async function* matchAll(scope) {
+        const matches = selector(scope);
+        for await (let match of matches) {
+          const refiningScope = matchAsScope(match);
+          const refiningMatches = refiningSelector(refiningScope);
+          for await (let refiningMatch of refiningMatches) {
+            yield composeMatches(refiningMatch, match);
+          }
         }
-      } else {
-        yield match;
-      }
+      };
     }
-  }
 
-  return refinableSelector;
+    return selector;
+  };
 }
 
-function matchAsContext(match) {
+function matchAsScope(match) {
   return match[0];
 }
 
@@ -67,7 +45,6 @@ function composeMatches(...matches) {
     const refinedMatch = [...refiningMatch];
     refinedMatch.index = match.index + refiningMatch.index;
     refinedMatch.input = match.input;
-    refinedMatch.descriptor = match.descriptor;
     return refinedMatch;
   });
 }
diff --git a/packages/text/src/index.js b/packages/text/src/index.js
index fa69321..93e2825 100644
--- a/packages/text/src/index.js
+++ b/packages/text/src/index.js
@@ -13,32 +13,28 @@
  * the License.
  */
 
-export function createTextQuoteSelector(context) {
-  async function* exec(descriptors) {
-    for (let descriptor of descriptors) {
-      const prefix = descriptor.prefix || '';
-      const suffix = descriptor.suffix || '';
-      const pattern = prefix + descriptor.exact + suffix;
-      let lastIndex = 0;
-      let next = () => context.indexOf(pattern, lastIndex);
-      let match = next();
-      while (match !== -1) {
-        let result = [descriptor.exact];
-        result.index = match + prefix.length;
-        result.input = context;
-        result.descriptor = descriptor;
-        yield result;
-        lastIndex = match + 1;
-        match = next();
-      }
+export function createTextQuoteSelector(selector) {
+  return async function* matchAll(scope) {
+    const prefix = selector.prefix || '';
+    const suffix = selector.suffix || '';
+    const pattern = prefix + selector.exact + suffix;
+    let lastIndex = 0;
+    let next = () => scope.indexOf(pattern, lastIndex);
+    let match = next();
+    while (match !== -1) {
+      let result = [selector.exact];
+      result.index = match + prefix.length;
+      result.input = scope;
+      result.selector = selector;
+      yield result;
+      lastIndex = match + 1;
+      match = next();
     }
-  }
-
-  return exec;
+  };
 }
 
-export function describeTextQuote({ context, startIndex, endIndex }) {
-  const exact = context.substring(startIndex, endIndex);
+export function describeTextQuote({ scope, startIndex, endIndex }) {
+  const exact = scope.substring(startIndex, endIndex);
   return {
     type: 'TextQuoteSelector',
     exact,