1. 11 Dec, 2020 6 commits
    • Robert Knight's avatar
      5d43b47b
    • Robert Knight's avatar
      772a73c8
    • Robert Knight's avatar
      Use new quote matching algorithm for quote anchoring · 2a1e14c9
      Robert Knight authored
      Use the new matching algorithm for anchoring text quote selectors. This
      is faster than the existing one when many quote selectors fail to exactly match
      and gives us more insight into and control over the fuzzy matching
      process.
      
       - Use the `matchQuote` function to do find the best match for the quote
         in the text, replacing the `dom-anchor-text-quote` library.
      
         This resolves a problem where the browser could become unresponsive
         for a significant period of time when anchoring large numbers of
         annotations (hundreds) on pages where there have been significant
         changes in the content.
      
         In the "Public" group on http://www.americanyawp.com/text/01-the-new-world/
         for example the client spends a total of ~2.4 seconds running JS in between starting
         the client and anchoring completing compared to ~11 seconds with the
         previous implementation.
      
         The new implementation also provides more control over the degree of
         mismatch between quote selector and document text that is allowed.
         The current settings provide higher recall (larger proportion of
         "correct" approximate matches found) than the previous
         implementation. On http://www.americanyawp.com/text/01-the-new-world/
         for example the number of orphans dropped from 137 to 63.
      
         Finally the new library is also smaller. The minified `annotator.bundle.js`
         size is reduced by 15% (25KB).
      
       - Change `TextQuoteAnchor.fromSelector(...)` to generate the selector
         directly rather than delegating to `dom-anchor-text-quote`. This
         gives us more control over how quote selectors are generated and more
         easily change factors such as the amount of context included.
      2a1e14c9
    • Robert Knight's avatar
      Remove old `useStore` hook · d9e99916
      Robert Knight authored
      All consumers now use the replacement `useStoreProxy` hook.
      d9e99916
    • Robert Knight's avatar
      Add new fuzzy quote matching implementation · d2e9f195
      Robert Knight authored
      Implement a `matchQuote` function which will be used to replace
      `dom-anchor-text-quote` for finding the best match for annotation quotes
      in the document text.
      
      The new implementation is based on the `approx-string-match` library and
      provides several improvements over the existing one:
      
       - Better performance when there are many differences between the quote
         and closest document text
      
       - It will be easier for us to tune the degree of mismatch allowed
         between the quote and document text and how candidate matches are
         ranked
      d2e9f195
    • dependabot-preview[bot]'s avatar
      [Security] Bump ini from 1.3.5 to 1.3.7 · f9ae90c0
      dependabot-preview[bot] authored
      Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7. **This update includes a security fix.**
      - [Release notes](https://github.com/isaacs/ini/releases)
      - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)
      Signed-off-by: 's avatardependabot-preview[bot] <support@dependabot.com>
      f9ae90c0
  2. 10 Dec, 2020 2 commits
  3. 09 Dec, 2020 12 commits
    • Robert Knight's avatar
      Improve several variable names and comments · 5bcdd787
      Robert Knight authored
      Make several improvements following PR review.
      5bcdd787
    • Robert Knight's avatar
      Implement `useStoreProxy` hook · 8108f0fc
      Robert Knight authored
      Implement a new `useStoreProxy` hook that provides access to read and
      update the store in UI components. This will replace the existing
      `useStore` hook.
      
      The new hook has a more ergonomic API which should also prevent some of the
      common mistakes made when using the previous hook.
      
      `useStoreProxy` returns an ES proxy for the store. The UI component can
      use the proxy as if it were using the store directly. The proxy however
      tracks and caches the results of store selector calls. When the store
      state changes the proxy checks whether any of the cached calls would
      return different results and if so invalidates the cache and re-renders
      the component.
      8108f0fc
    • Robert Knight's avatar
      Avoid traversing object tree in `immutable` if already frozen · bcabf15f
      Robert Knight authored
      This makes store updates faster in debug builds when a lot of data is
      loaded into the client. In this case most sub-trees in the store are
      already frozen after an update (since they are objects from the previous
      state) and only the new parts need to be frozen.
      bcabf15f
    • Robert Knight's avatar
      Replace remaining uses of `store.getState()` in UI components · 36e03af8
      Robert Knight authored
      Replace remaining uses of `store.getState()` in UI components with
      selectors. This will avoid unnecessary re-rendering after we change
      components to use the new `useStoreProxy` hook for reading from the
      store. It also simplifies the tests.
      36e03af8
    • Robert Knight's avatar
      Remove unnecessary `requestAnimationFrame` callbacks in `Guest` · 2a4045de
      Robert Knight authored
      Profiling anchoring of large numbers of annotations in Chrome showed
      that there was significant overhead for scheduling and
      executing `requestAnimationFrame` callbacks. In the case of `Guest.anchor`, the
      callback often did nothing (it called `removeHighlights` with an empty
      array).
      
      There isn't a need for this any more AFAICS so just invoke the logic
      synchronously, which is much cheaper.
      2a4045de
    • Robert Knight's avatar
      Optimize `sortKeys` selector · 817d82f4
      Robert Knight authored
      This was recomputing frequently even though the result only changes when
      the selected tab changes.
      817d82f4
    • Lyza Danger Gardner's avatar
      Refactor `useRootThread` to memoize correctly · 945825da
      Lyza Danger Gardner authored
      Also convert `selectionState` to use `createSelector` to avoid it
      returning a different reference on each call.
      945825da
    • Lyza Danger Gardner's avatar
      Remove unused selector · 04a98682
      Lyza Danger Gardner authored
      Remove unused selector and tidy up reference ordering
      04a98682
    • Lyza Danger Gardner's avatar
      Refactor `hasAppliedFilter` · 9fb70f45
      Lyza Danger Gardner authored
      Refactor selectors for evaluating `hasAppliedFilter`
      to remove cross-module state dependencies.
      9fb70f45
    • Lyza Danger Gardner's avatar
      Remove `threadState`, add supporting selectors · 6c2fe0f4
      Lyza Danger Gardner authored
      Eliminate the enormous `threadState` `rootSelector`
      and re-implement as multiple selectors. Refactor
      `useRootThread` and threading integration tests
      to account for these changes.
      6c2fe0f4
    • Lyza Danger Gardner's avatar
      Remove `filterState`; add `focusState` · 8999cc4b
      Lyza Danger Gardner authored
      Refactor the computation of "filter state", that
      is, all of the store state that impacts what
      constitutes applied filters on annotations.
      8999cc4b
    • Lyza Danger Gardner's avatar
      Split `selection` store into `selection`, `filters` · e9b81457
      Lyza Danger Gardner authored
      The `selection` store module has become overlong and
      its responsibilities aren't clear. We know we'll be
      adding some more filtering capabilities to the app
      in the next short while, and that would make
      `selection` even more complex and heavy.
      
      Split into two store modules: `selection` and
      `filters`.
      
      Temporarily re-implement `rootSelector`s that
      are needed for generating thread and filter
      state for components.
      e9b81457
  4. 08 Dec, 2020 2 commits
    • Robert Knight's avatar
      Rename `dir` option to `direction` · 899a2831
      Robert Knight authored
      The name `dir` is arguably ambiguous in this context.
      899a2831
    • Robert Knight's avatar
      Handle start or end element with no text in `TextRange.toRange` · 3d36ecee
      Robert Knight authored
      When resolving a `TextRange` to a DOM `Range` there is an edge case
      where the `start` or `end` position have an `offset` of `0` and the
      element contains no text nodes.
      
      Before this commit `toRange` would throw an `Offset exceeds text length`
      error. A more useful behavior though is:
      
       - For the `start` position, to resolve it to the start of the next text node after
         `this.start.element`
      
       - For the `end` position, to resolve it to the end of the previous text
         node before `this.end.element`
      
      This commit implements this behavior by first adding a `dir` option to
      `TextPosition.resolve` to control what happens when the position's
      offset is 0 and the element has no text and then specifying this option
      when calling `this.{start, end}.resolve` in `TextRange.toRange`.
      3d36ecee
  5. 07 Dec, 2020 9 commits
  6. 04 Dec, 2020 1 commit
  7. 03 Dec, 2020 8 commits
    • Lyza Danger Gardner's avatar
      Correctly select Orphan tab when viewing direct-linked orphan · d7c316ea
      Lyza Danger Gardner authored
      Previously, tab selection for direct-linked annotations was happening
      before anchoring was complete—that means that orphaned annotations had
      not yet been marked as being orphans (`$orphan`). Make sure that
      direct-linked tab selection is checked any time the direct-linked
      annotation changes.
      
      Also fix a UI confusion in which the "Show All" button would show
      the count of all annotations in this (direct-linked) state, which is
      confusing because orphans don't count toward "All annotations" (nor do
      page notes, FWIW).
      
      Fixes #2686
      d7c316ea
    • Eduardo Sanz García's avatar
      Find annotation.css in a more robust way · 1ccf10d4
      Eduardo Sanz García authored
      As indicated by @robertknight `document.styleSheets` is complete only when stylessheets are processed. This can take a while for certain heavy pages.
      
      The alternative approach presented here to find `annotation.css` is warranted to find the url when the code is run.
      
      Closes #2752
      1ccf10d4
    • Robert Knight's avatar
      Address minor PR feedback · 91f36486
      Robert Knight authored
       - Add comment to explain purpose of `index.js`
       - Use a template string for readability
      91f36486
    • Robert Knight's avatar
      Remove obsolete `experimental.pdfSideBySide` config · f651eb3b
      Robert Knight authored
      This feature is now enabled by default.
      f651eb3b
    • Robert Knight's avatar
      Extract logic for "Unload client" button out of `serve-dev.js` · e115dcec
      Robert Knight authored
      Per discussion on the PR, it is preferable to put markup and JS in the
      dev server in external files rather than as string literals in
      `serve-dev.js`. This enables them to be edited without having to restart
      the dev server.
      
       - Extract shared functions for loading and unloading client into
         `scripts/util.js`
      
       - Move logic specific to the index template into `scripts/index.js`.
      e115dcec
    • Robert Knight's avatar
      Change `hypothesis-asset` attribute to `data-hypothesis-asset` · 388838e6
      Robert Knight authored
      Adding a custom attribute without a `data-` prefix could potentially
      cause headaches for publishers running their code through HTML
      validation tools.
      388838e6
    • Robert Knight's avatar
      Fix client load on dev server pages without toggle button · ddfe8eab
      Robert Knight authored
      The toggle button only exists on the index page. Also I fixed an issue
      where an incorrect variable name went unnoticed due to DOM element IDs
      creating global variables (sigh).
      ddfe8eab
    • Robert Knight's avatar
      Add "Load client" / "Unload client" toggle button to dev server · eedbfdda
      Robert Knight authored
      Add a button to the dev server to facilitate easy testing of unloading
      and re-loading the client, as done by the browser extension and also
      some third-party pages.
      eedbfdda