1. 31 Mar, 2022 8 commits
    • Robert Knight's avatar
      Add test case for Cross-Origin-Opener-Policy header · 4ba76ac9
      Robert Knight authored
      Add a test case for pages served with the `Cross-Origin-Opener-Policy:
      same-origin` header, which currently breaks the client's login popup.
      
      This reproduces the issue from https://github.com/hypothesis/product-backlog/issues/1333.
      4ba76ac9
    • Robert Knight's avatar
      Add mechanism to specify custom headers for HTML test pages · f8100ac7
      Robert Knight authored
      Add support for specifying custom headers to serve test pages with via
      inline `<!-- Header: <Key>:<Value> -->` comments in the HTML/XML, and
      change the existing XHTML test case to use it.
      f8100ac7
    • Robert Knight's avatar
      Simplify login popup creation flow · 9bf96c31
      Robert Knight authored
      The process of creating and navigating the login popup used to involve two
      steps, first creating a blank window and then navigating it to the final
      authorization URL. This was needed because, in Firefox, the popup window had to
      be created in the same turn of the event loop as the user's click on the "Log
      in" button (otherwise the popup blocker would trigger) but generating the
      authorization URL involved an async "fetch" of API links.
      
      The major browsers have now all settled on a more flexible model for allowing
      popups in response to user gestures, where the popup must be opened within a
      certain time window of the gesture. In practice the timeout seems to be ~1000ms
      in Safari and longer than that in other browsers.
      
      In this context we expect the async delay between the user clicking the "Log in"
      button and us creating the popup to be ~0ms, since the API links should already
      have been fetched at this point and so we're just fetching locally cached values.
      
      Based on this assumption, the flow for creating the login popup window has been
      simplified to create the popup window at the final URL immediately, removing the
      need to open a blank window as a first step.
      
      Simplifying the code here will make it easier to change how the popup window and
      sidebar communicate, eg. to resolve an issue with the new
      Cross-Origin-Opener-Policy header [1].
      
      [1] https://github.com/hypothesis/product-backlog/issues/1333
      9bf96c31
    • Robert Knight's avatar
      Add missing types to annotation and route store modules · 13914b8d
      Robert Knight authored
       - Add state and action types to reducers
      
       - Replace Array.forEach calls with for..of loops to enable better type
         inference.
      
       - Replace plain objects used as sets with ES sets
      13914b8d
    • Robert Knight's avatar
      Determine type of sidebar store automatically · 31ac4c8a
      Robert Knight authored
      Avoid the need to manually create the `SidebarStore` type by inferring
      it automatically. This works as follows:
      
       1. The `modules` argument to `createStore` has been converted to a
          tuple type (`[ModuleA, ModuleB, ...]`)
       2. The type of a module that would result from merging all the
          individual modules (`ModuleA & ModuleB ...`) is computed
          using a `TupleToIntersection` utility type
       3. `StoreFromModule` is used to compute the type of the store that the
          merged module would produce
      31ac4c8a
    • Lyza Danger Gardner's avatar
      1326d1a9
    • Lyza Danger Gardner's avatar
      Extract StyledText and refactor props on related components · 5baa223b
      Lyza Danger Gardner authored
      Extract a StyledText component that can be used by MarkdownView and
      AnnotationQuote. Update some props on Markdown components to match
      conventions.
      5baa223b
    • Lyza Danger Gardner's avatar
      Add AnnotationActivityService · 17e990bb
      Lyza Danger Gardner authored
      Add new service to notify ancestor frame on annotation activity, if
      so configured.
      17e990bb
  2. 30 Mar, 2022 6 commits
  3. 29 Mar, 2022 5 commits
  4. 28 Mar, 2022 13 commits
  5. 25 Mar, 2022 2 commits
  6. 24 Mar, 2022 3 commits
    • Robert Knight's avatar
      Introduce a pattern for fully typed store modules · 9d40fff9
      Robert Knight authored
      Introduce a pattern for creating store modules which are fully typed,
      using the "activity" module as a test case / example. This allows
      TypeScript to check both external usage of the module, as well as
      internal consistency between the different elements of it (initial
      state, reducers, action creators, selectors).
      
      The elements of this pattern are:
      
       - A `State` type is defined in each module, which is typically whatever
         shape the module's initial state has.
      
       - Each function in the `reducers` map specifies the type of its `state`
         parameter as `State` and defines the fields of the action.
      
       - Action creators use a new `makeAction` helper, which ensures that the
         type of dispatched actions matches what the reducer expects
      
       - The `createStoreModule` helper ties all the elements of the module
         (reducers, actions, selectors) together and makes sure they are
         consistent with one another.
      
      The general structure of a typed store module, to which the various existing
      modules will converge, is:
      
      ```js
      import { createStoreModule, makeAction } from '../create-store';
      
      const initialState = { ... }
      
      /** @typedef {typeof initialState} State */
      
      const reducers = {
        /**
         * @param {State} state
         * @param {{ id: string }} action
         */
        SOME_ACTION(state, action) {
          ...
        }
      }
      
      /**
       * @param {string} id
       */
      function someAction(id) {
        return makeAction(reducers, 'SOME_ACTION', { id });
      }
      
      /**
       * @param {State}
       */
      function someSelector(state) {
        ...
      }
      
      export someModule = createStoreModule(initialState, {
        namespace: 'someModule',
        reducers,
        actionCreators: { someAction },
        selectors: { someSelector },
      });
      ```
      9d40fff9
    • Robert Knight's avatar
      Remove `DefaultIfAny` helper · 788697ec
      Robert Knight authored
      Remove a cryptic piece of code that is no longer needed given the ability to
      specify default values for template arguments [1]
      
      [1] https://github.com/microsoft/TypeScript/pull/45483
      788697ec
    • Lyza Danger Gardner's avatar
      a95447b1
  7. 23 Mar, 2022 3 commits