Example #1
1
const interpolateTransitionWith = /*::<model>*/
  ( easing/*:Easing*/
  , interpolation/*:Interpolation<model>*/
  , transition/*:Transition<model>*/
  , elapsed/*:Time*/
  , now/*:Time*/
  )/*:[Model<model>, Effects<Action>]*/ =>
  ( elapsed >= transition.duration
  ? [ new Model(transition.to, null)
    , Effects.receive(End(now))
    ]
  : [ new Model
      ( ease
        ( easing
        , interpolation
        , transition.from
        , transition.to
        , transition.duration
        , elapsed
        )
      , new Transition
        ( transition.from
        , transition.to
        , now
        , elapsed
        , transition.duration
        )
      )
    , Effects.perform
      (Task.requestAnimationFrame().map(Tick))
    ]
  )
Example #2
0
  (model:Model, action:Action):[Model, Effects<Action>] =>
  ( action.type === "Press"
  ? [ merge(model, {isChecked: !model.isChecked})
    , ( model.isChecked
      ? Effects.perform(Task.succeed(Uncheck))
      : Effects.perform(Task.succeed(Check))
      )
    ]

  : action.type === "Check"
  ? [ merge(model, {isChecked: true })
    , Effects.none
    ]
  : action.type === "Uncheck"
  ? [ merge(model, {isChecked: false })
    , Effects.none
    ]
  : action.type === "Button"
  ? mapFX(ButtonAction, Button.update(model, action.button))
  : action.type === "Target"
  ? mapFX(TargetAction, Target.update(model, action.target))
  : action.type === "Focusable"
  ? mapFX(FocusableAction, Focusable.update(model, action.focusable))
  : Unknown.update(model, action)
  );
Example #3
0
 (model, url, canGoBackValue, canGoForwardValue) =>
 // In the case where LocationChanged carries information about
 // canGoBack and canGoForward, we update the model with the new info.
 // This scenario will be hit in Servo.
 ( ( canGoBackValue != null && canGoForwardValue != null )
 ? [ new Model
     ( model.ref
     , canGoBackValue
     , canGoForwardValue
     , url
     )
   , Effects.none
   ]
 // Otherwise, update the currentURI and create a task to read
 // canGoBack, canGoForward from the iframe.
 // This scenario will be hit in Gecko.
 : [ new Model
     ( model.ref
     , model.canGoBack
     , model.canGoForward
     , url
     )
   , Effects.batch
     ( [ Effects
         .perform(canGoBack(model.ref))
         .map(CanGoBackChanged)
       , Effects
         .perform(canGoForward(model.ref))
         .map(CanGoForwardChanged)
       ]
     )
   ]
 );
Example #4
0
  (model/*:Model*/, action/*:Action*/)/*:[Model, Effects<Action>]*/ =>
  ( action.type === "Press"
  ? [ merge(model, {isChecked: !model.isChecked})
    , ( model.isChecked
      ? Effects.perform(Task.succeed(Uncheck))
      : Effects.perform(Task.succeed(Check))
      )
    ]

  : action.type === "Check"
  ? [ merge(model, {isChecked: true })
    , Effects.none
    ]
  : action.type === "Uncheck"
  ? [ merge(model, {isChecked: false })
    , Effects.none
    ]
  : action.type === "Button"
  ? updateButton(model, action.action)
  : action.type === "Target"
  ? updateTarget(model, action.action)
  : action.type === "Focusable"
  ? updateFocusable(model, action.action)
  : Unknown.update(model, action)
  );
Example #5
0
 (model:Model):[Model, Effects<Action>] =>
 ( model.isChecked
 ? [ new Model(false, model.button)
   , Effects.perform(Task.succeed(Uncheck))
   ]
 : [ new Model(true, model.button)
   , Effects.perform(Task.succeed(Check))
   ]
 )
Example #6
0
  (model, query) =>
  ( model.query === query
  ? [ model, Effects.none ]
  : [ merge(model, {query, queryID: model.queryID + 1 })
    , Effects.batch
      ( [ Effects.perform(abort(model.queryID))
          .map(Abort)

        , Effects.perform
          (search(model.queryID + 1, query, model.limit))
          .map(UpdateMatches)
        ]
      )
    ]
  );
Example #7
0
const updateTick = (model) => {
  const series = model.series;
  const revA = series.rev;
  // Advance series to now
  series.tick(Date.now());
  const revB = series.rev;
  const shouldUpdate = revA !== revB;

  const effect = Effects.perform(Task.sleep(CHART_TICK_MS)).map(AlwaysTick);

  if (shouldUpdate) {
    const next = new Model(
      series,
      model.markers,
      model.recipeStart,
      model.recipeEnd,
      model.width,
      model.height,
      model.scrubber,
      model.xhairAt
    );

    return [next, effect];
  }
  else {
    return [model, effect];
  }
}
Example #8
0
export const init = () => {
  const width = calcChartWidth(window.innerWidth);
  const height = calcChartHeight(window.innerHeight);

  const [scrubber, scrubberFx] = Draggable.init(false, [width, height]);
  const series = Series.fromConfigs(CHART);

  const model = new Model(
    series,
    [],
    null,
    null,
    width,
    height,
    scrubber,
    0.5,
    true
  );

  const TickEffect = Effects.perform(Task.sleep(CHART_TICK_MS)).map(AlwaysTick);

  return [
    model,
    Effects.batch([
      TickEffect,
      scrubberFx.map(ScrubberAction)
    ])
  ];
}
Example #9
0
const interpolateTransitionWith = <model>
  ( easing:Easing
  , interpolation:Interpolation<model>
  , transition:Transition<model>
  , elapsed:Time
  , now:Time
  ):[Model<model>, Effects<Action>] =>
  ( elapsed >= transition.duration
  ? [ new Model(transition.to, null)
    , Effects.receive(End(now))
    ]
  : [ new Model
      ( ease
        ( easing
        , interpolation
        , transition.from
        , transition.to
        , transition.duration
        , elapsed
        )
      , new Transition
        ( transition.from
        , transition.to
        , now
        , elapsed
        , transition.duration
        )
      )
    , Effects.perform
      (Task.requestAnimationFrame().map(Tick))
    ]
  )
Example #10
0
 ( model, isFocused ) =>
 ( model.isFocused === isFocused
 ? [ model, Effects.none ]
 : [ new Model
     ( model.ref
     , model.zoom
     , model.isVisible
     , isFocused
     )
   , Effects.perform
     ( isFocused
     ? focus(model.ref).recover(Panic)
     : blur(model.ref).recover(Panic)
     )
   ]
 )
Example #11
0
 (uri/*:URI*/)/*:Task<Never, ?Theme>*/ =>
 Task.future(() => {
   const hostname = getDomainName(uri);
   return Promise.resolve
     ( hostname == null
     ? null
     : curated[hostname]
     );
 });
Example #12
0
export const requestCuratedColor/*:type.requestCuratedColor*/ = uri =>
  Task.future(() => {
    const hostname = URI.getDomainName(uri);
    return Promise.resolve
      ( hostname == null
      ? null
      : curated[hostname]
      );
  });
Example #13
0
const endTransition = /*::<model>*/
  ( model/*:Model<model>*/
  )/*:[Model<model>, Effects<Action>]*/ =>
  [ new Model
    ( model.state
    , null
    )
  , Effects.perform
    (Task.requestAnimationFrame().map(End))
  ]
Example #14
0
const alertDismissable = (model, message) => [
  (
    (model.mode !== DISMISSABLE || model.message !== message) ?
    new Model(DISMISSABLE, message, isWarning) :
    model
  ),
  // After the timeout, hide banner
  Effects.perform(Task.sleep(TIMEOUT)).map(AlwaySuppress)
];
Example #15
0
const showAlert = (model, message) => [
  (
    (model.mode !== SHOW || model.message !== message) ?
    new Model(SHOW, message, isWarning) :
    model
  ),
  // After the timeout, hide banner
  Effects.perform(Task.sleep(TIMEOUT)).map(AlwaySuppress)
];
Example #16
0
const endTransition = <model>
  ( model:Model<model>
  ):[Model<model>, Effects<Action>] =>
  [ new Model
    ( model.state
    , null
    )
  , Effects.perform
    (Task.requestAnimationFrame().map(End))
  ]
Example #17
0
  (model, error) => {
    const action = AlertBanner(error);

    return [
      model,
      Effects.batch([
        // Wait for a bit, then try to get backlog again.
        Effects.perform(Task.sleep(RETRY_TIMEOUT)).map(constant(GetBacklog)),
        Effects.receive(action)
      ])
    ];
  }
Example #18
0
 (id/*:ID*/, code/*:string*/)/*:Task<Never, EvaluationResult>*/ =>
 Task.future(() => new Promise(resolve => {
   try {
     const out = executeWith(evalContext, () => window.eval(code));
     evalContext.out[id] = out;
     resolve(ok(out));
   }
   catch (exception) {
     evalContext.out[id] = exception;
     resolve(error(exception));
   }
 }))
Example #19
0
 (model:Model, action:Action):[Model, Effects<Action>] =>
 ( action.type === "End"
 ? [ null, Effects.none ]
 : action.type === "Start"
 ? [ null, Effects.perform(Task.requestAnimationFrame().map(Tick)) ]
 : action.type === "Tick"
 ? ( model == null
   ? [ {
         time: action.time,
         elapsed: 0
       }
     , Effects.perform(Task.requestAnimationFrame().map(Tick))
     ]
   : [ merge(model, {
         time: action.time,
         elapsed: model.elapsed + (action.time - model.time)
       })
     , Effects.perform(Task.requestAnimationFrame().map(Tick))
     ]
   )
 : Unknown.update(model, action)
 );
Example #20
0
  (id/*:ID*/, isVisible/*:boolean*/)/*:Task<Never, Result<Error, boolean>>*/ =>
  Task.future(() => {
    const target = document.getElementById(`web-view-${id}`);
    const result
      = target == null
      ? error(Error(`WebView with id web-view-${id} not found`))
      : typeof(target.setVisible) !== 'function'
      ? error(Error(`.setVisible is not supported by runtime`))
      : ok(isVisible);

    if (result.isOk) {
      // @FlowIssue: Flow can't infer enough to tell it's function here.
      target.setVisible(isVisible);
    }

    return Promise.resolve(result);
  });
Example #21
0
const setZoom = (id, level) =>
  Task.future(() => {
    const target = document.getElementById(`web-view-${id}`);
    const result
      = target == null
      ? error(Error(`WebView with id web-view-${id} not found`))
      : typeof(target.zoom) !== 'function'
      ? error(Error(`.zoom is not supported by runtime`))
      : ok(level);

    if (result.isOk) {
      // @FlowIssue: Flow can't infer enough to tell it's function here.
      target.zoom(level)
    }

    return Promise.resolve(result)
  });
Example #22
0
const startTransition = /*::<model>*/
  ( from/*:model*/
  , to/*:model*/
  , elapsed/*:Time*/
  , duration/*:Time*/
  )/*:[Model<model>, Effects<Action>]*/ =>
  [ new Model
    ( from
    , new Transition
      ( from
      , to
      , 0
      , elapsed
      , duration
      )
    )
  , Effects.perform
    (Task.requestAnimationFrame().map(Tick))
  ]
Example #23
0
const startTransition = <model>
  ( from:model
  , to:model
  , elapsed:Time
  , duration:Time
  ):[Model<model>, Effects<Action>] =>
  [ new Model
    ( from
    , new Transition
      ( from
      , to
      , 0
      , elapsed
      , duration
      )
    )
  , Effects.perform
    (Task.requestAnimationFrame().map(Tick))
  ]
Example #24
0
 .capture(reason => Task.succeed(error(reason)))
Example #25
0
  (model:Model, action:Action):[Model, Effects<Action>] => {
    switch (action.type) {
      case "ZoomIn":
        return [
          model
          , Effects
            .perform
              ( zoomIn(model.ref, model.zoom)
                .map(ok)
                .capture(reason => Task.succeed(error(reason)))
              )
            .map(ZoomChanged)
          ];
      case "ZoomOut":
        return [
          model
          , Effects
              .perform
              ( zoomOut(model.ref, model.zoom)
                .map(ok)
                .capture(reason => Task.succeed(error(reason)))
              )
              .map(ZoomChanged)
          ];
      case "ResetZoom":
        return [
          model
          , Effects
              .perform
              ( resetZoom(model.ref)
                .map(ok)
                .capture(reason => Task.succeed(error(reason)))
              )
              .map(ZoomChanged)
          ];
      case "MakeVisible":
        return [
          model
          , Effects
              .perform
              ( setVisibility(model.ref, true)
                .map(ok)
                .capture(reason => Task.succeed(error(reason)))
              )
              .map(VisibilityChanged)
          ];
      case "MakeNotVisible":
        return [
          model
          , Effects
            .perform
            ( setVisibility(model.ref, false)
              .map(ok)
              .capture(reason => Task.succeed(error(reason)))
            )
            .map(VisibilityChanged)
          ];
      case "VisibilityChanged":
        return (
          action.visibilityChanged.isOk
        ? updateVisibility(model, action.visibilityChanged.value)
        : [ model
          , Effects
            .perform(warn(action.visibilityChanged.error))
          ]
        );
      case "ZoomChanged":
        return (
          action.zoomChanged.isOk
        ? updateZoom(model, action.zoomChanged.value)
        : [ model
          , Effects
            .perform(warn(action.zoomChanged.error))
          ]
        );

  // Delegate
      case "Focus":

        return updateFocus(model, true);
      case "Blur":
        return updateFocus(model, false);

      case "Panic":
        return [model, Effects.perform(warn(action.panic))];

      default:
        return [model, Effects.none];
    }
  };
Example #26
0
 (ref:Ref.Model):Task<Error, number> =>
 setZoom(ref, 1);
Example #27
0
 (ref:Ref.Model, zoom:number):Task<Error, number> =>
 setZoom(ref, Math.max(ZOOM_MIN, zoom - ZOOM_STEP));
Example #28
0
 (ref:Ref.Model, zoom:number):Task<Error, number> =>
 setZoom(ref, Math.min(ZOOM_MAX, zoom + ZOOM_STEP));
Example #29
0
export const respond = /*::<message>*/
  (message/*:message*/)/*:Task<Never, message>*/ =>
  Task.future(() => Promise.resolve(message));
Example #30
0
export const schedule = (action, time) =>
  Effects.task(Task.sleep(time)).map(constant(action));