Example #1
0
File: main.ts Project: ornicar/lila
export default function LichessChat(element: Element, opts: ChatOpts): {
  preset: PresetCtrl
} {
  const patch = init([klass, attributes]);

  const container = element.parentNode as HTMLElement;

  let vnode: VNode, ctrl: Ctrl

  function redraw() {
    vnode = patch(vnode, view(ctrl));
  }

  ctrl = makeCtrl(opts, redraw);

  const blueprint = view(ctrl);
  element.innerHTML = '';
  vnode = patch(element, blueprint);

  window.Mousetrap.bind('c', () => {
    (container.querySelector('.mchat__say') as HTMLElement).focus();
    return false;
  });

  return ctrl;
};
Example #2
0
export function init<A>(emit: (_: A) => void): (old: VNode<A> | Element, vnode: VNode<A>) => VNode<A> {
  return S.init([
    ClassModule,
    PropsModule,
    AttrsModule,
    StyleModule,
    DatasetModule,
    createModuleListener(emit)
  ]) as any;
}
Example #3
0
function makeDOMDriver(
  container: string | Element | DocumentFragment,
  options?: DOMDriverOptions,
): Driver<Stream<VNode>, MainDOMSource> {
  if (!options) {
    options = {};
  }
  const modules = options.modules || defaultModules;
  const isolateModule = new IsolateModule();
  const patch = init([isolateModule.createModule()].concat(modules));
  const rootElement = getValidNode(container) || document.body;
  const vnodeWrapper = new VNodeWrapper(rootElement);
  const delegators = new MapPolyfill<string, EventDelegator>();
  makeDOMDriverInputGuard(modules);

  function DOMDriver(vnode$: Stream<VNode>, name = 'DOM'): MainDOMSource {
    domDriverInputGuard(vnode$);
    const sanitation$ = xs.create<null>();
    const rootElement$ = xs
      .merge(vnode$.endWhen(sanitation$), sanitation$)
      .map(vnode => vnodeWrapper.call(vnode))
      .fold(patch, toVNode(rootElement))
      .drop(1)
      .map(unwrapElementFromVNode)
      .compose(dropCompletion) // don't complete this stream
      .startWith(rootElement as any);

    // Start the snabbdom patching, over time
    const listener = {error: reportSnabbdomError};
    if (document.readyState === 'loading') {
      document.addEventListener('readystatechange', () => {
        if (document.readyState === 'interactive') {
          rootElement$.addListener(listener);
        }
      });
    } else {
      rootElement$.addListener(listener);
    }

    return new MainDOMSource(
      rootElement$,
      sanitation$,
      [],
      isolateModule,
      delegators,
      name,
    );
  }

  return DOMDriver as any;
}
Example #4
0
export function app(opts: RoundOpts): RoundApi {

  const patch = init([klass, attributes]);

  let vnode: VNode, ctrl: RoundController;

  function redraw() {
    vnode = patch(vnode, view(ctrl));
  }

  ctrl = new RoundController(opts, redraw);

  const blueprint = view(ctrl);
  opts.element.innerHTML = '';
  vnode = patch(opts.element, blueprint);

  return {
    socketReceive: ctrl.socket.receive,
    moveOn: ctrl.moveOn
  };
};
export default function injectUI(streamContainer: Element) {
	var nfeContainer = document.createElement('div');
	nfeContainer.id = 'nfe-container';
	streamContainer.appendChild(nfeContainer);

	const patch = init([propsModule, attrsModule, eventsModule]);

	let vnode = toVNode(nfeContainer);

	storePromise
		.then(store => {
			const render = () => {
				const newVnode = h('div#nfe-container', [NewsFeedEradicator(store)]);

				patch(vnode, newVnode);
				vnode = newVnode;
			};

			render();
			store.subscribe(render);
		})
		.catch(handleError);
}
Example #6
0
/// <reference types="types/lichess" />

import { init } from 'snabbdom';
import { VNode } from 'snabbdom/vnode'

import makeCtrl from './ctrl';
import view from './view';
import { NotifyOpts, Ctrl } from './interfaces'

import klass from 'snabbdom/modules/class';
import attributes from 'snabbdom/modules/attributes';

const patch = init([klass, attributes]);

export default function LichessNotify(element: Element, opts: NotifyOpts) {

  let vnode: VNode, ctrl: Ctrl

  function redraw() {
    vnode = patch(vnode, view(ctrl));
  }

  ctrl = makeCtrl(opts, redraw);

  vnode = patch(element, view(ctrl));

  if (opts.data) ctrl.update(opts.data, opts.incoming);
  else ctrl.loadPage(1);

  return {
    update: ctrl.update,
Example #7
0
function makeDOMDriver(
  container: string | Element | DocumentFragment,
  options?: DOMDriverOptions
): Driver<Stream<VNode>, MainDOMSource> {
  if (!options) {
    options = {};
  }
  checkValidContainer(container);
  const modules = options.modules || defaultModules;
  makeDOMDriverInputGuard(modules);
  const isolateModule = new IsolateModule();
  const patch = init([isolateModule.createModule()].concat(modules));
  const domReady$ = makeDOMReady$();
  let vnodeWrapper: VNodeWrapper;
  let mutationObserver: MutationObserver;
  const mutationConfirmed$ = xs.create<null>({
    start(listener) {
      mutationObserver = new MutationObserver(() => listener.next(null));
    },
    stop() {
      mutationObserver.disconnect();
    },
  });

  function DOMDriver(vnode$: Stream<VNode>, name = 'DOM'): MainDOMSource {
    domDriverInputGuard(vnode$);
    const sanitation$ = xs.create<null>();

    const firstRoot$ = domReady$.map(() => {
      const firstRoot = getValidNode(container) || document.body;
      vnodeWrapper = new VNodeWrapper(firstRoot);
      return firstRoot;
    });

    // We need to subscribe to the sink (i.e. vnode$) synchronously inside this
    // driver, and not later in the map().flatten() because this sink is in
    // reality a SinkProxy from @cycle/run, and we don't want to miss the first
    // emission when the main() is connected to the drivers.
    // Read more in issue #739.
    const rememberedVNode$ = vnode$.remember();
    rememberedVNode$.addListener({});

    // The mutation observer internal to mutationConfirmed$ should
    // exist before elementAfterPatch$ calls mutationObserver.observe()
    mutationConfirmed$.addListener({});

    const elementAfterPatch$ = firstRoot$
      .map(
        firstRoot =>
          xs
            .merge(rememberedVNode$.endWhen(sanitation$), sanitation$)
            .map(vnode => vnodeWrapper.call(vnode))
            .startWith(addRootScope(toVNode(firstRoot)))
            .fold(patch, toVNode(firstRoot))
            .drop(1)
            .map(unwrapElementFromVNode)
            .startWith(firstRoot as any)
            .map(el => {
              mutationObserver.observe(el, {
                childList: true,
                attributes: true,
                characterData: true,
                subtree: true,
                attributeOldValue: true,
                characterDataOldValue: true,
              });
              return el;
            })
            .compose(dropCompletion) // don't complete this stream
      )
      .flatten();

    const rootElement$ = concat(domReady$, mutationConfirmed$)
      .endWhen(sanitation$)
      .compose(sampleCombine(elementAfterPatch$))
      .map(arr => arr[1])
      .remember();

    // Start the snabbdom patching, over time
    rootElement$.addListener({error: reportSnabbdomError});

    const delegator = new EventDelegator(rootElement$, isolateModule);

    return new MainDOMSource(
      rootElement$,
      sanitation$,
      [],
      isolateModule,
      delegator,
      name
    );
  }

  return DOMDriver as any;
}