Beispiel #1
0
    code: (event)=>{
      const range = Dom.getRange();
      const editor = Dom.getClosest(range.startContainer, '.input');
      if (editor === null) return;

      const ctx = Dom.myCtx(editor.parentNode);

      let {startContainer: sc, endContainer: ec, collapsed} = range;

      if (sc.nodeType === TEXT_NODE && DomNav.rangeIsInline(range)) {
        if (! collapsed) {
          if (range.startOffset == sc.nodeValue.length)
            sc = DomNav.nextNode(sc);
          if (ec.nodeType === TEXT_NODE && range.endOffset == 0)
            ec = DomNav.previousNode(ec);
        }
        const fn = fontNode(editor, sc),
              fnFont = (ctx.override && ctx.override.font) || fn.style.getPropertyValue('font-family');
        const efnFont = collapsed || ctx.override
              ? fnFont : fontNode(editor, ec).style.getPropertyValue('font-family');
        let font = 'monospace';
        if (fnFont ===  efnFont && fnFont === 'monospace') {
          let pn = fn;
          while (pn !== editor) {
            pn = fontNode(editor, fn.previousSibling || fn.parentNode);
            font = pn.style.getPropertyValue('font-family');
            if (font !== 'monospace') break;
          }
          if (font === 'monospace' || font === '') font = RichText.fontIdToFace[0];
        }
        execCommand('fontName', font);
        notify(ctx, 'force', collapsed && {font});
      } else {
        if (collapsed) {
          const pre = EMPTY_PRE.cloneNode(true);
          const cn = DomNav.containingNode(range);
          if (cn.tagName === 'BR') {
            range.selectNode(cn);
            Dom.setRange(range);
          }
          insertNode(pre, pre, 0);
        } else {
          const pre = RichText.fromToHtml(Dom.h({pre: range.extractContents()})).firstChild;
          insertNode(pre);
          range.selectNodeContents(pre);
          Dom.setRange(range);
        }
        ctx.mode = codeMode;
        ensureLangues(ctx);
        notify(ctx, 'force');
      }
    },
isClient && define(function (require, exports, module) {
  const Dom = require('koru/dom');
  const TH  = require('ui/test-helper');

  const sut  = require('./notify-bar');
  var v;

  TH.testCase(module, {
    setUp() {
      v = {};
    },

    tearDown() {
      Dom.removeId('myNotification');
      TH.tearDown();
      v = null;
    },

    "test notify survives destory"() {
      const myNotification = Dom.h({id: 'myNotification'});
      const ctx = Dom.setCtx(myNotification);

      document.body.appendChild(sut.$autoRender());

      sut.notify(myNotification);

      assert.dom('#NotifyBar:not(.on) #myNotification');

      Dom.removeId('NotifyBar');
      Dom.addClass(myNotification, 'show');
      document.body.appendChild(sut.$autoRender());

      assert.dom('#NotifyBar.on #myNotification');
      assert.same(Dom.myCtx(myNotification), ctx);
    },

    "test change"() {
      document.body.appendChild(sut.$autoRender());
      assert.dom('#NotifyBar:not(.on)', elm => {
        const myElm = Dom.h({id: "myNotification", class: 'show'});
        sut.notify(myElm);
        assert.className(elm, 'on');
        Dom.removeClass(myElm, 'show');
        sut.change();
        refute.className(elm, 'on');
      });
    },
  });
});
Beispiel #3
0
  const display = ({message, transient, type='notice'})=>{
    message = ResourceString.text(message);
    let flash = document.getElementById('Flash');
    if (flash) {

      Dom.removeClass(flash, 'remElm');

      Dom.forEach(flash, '#Flash>.m.transient:not(.remElm)',
                  elm => {Dom.hideAndRemove(elm)});
    } else {
      flash = Tpl.$autoRender();
      document.body.appendChild(flash);
    }

    const classes = `m ${type}${transient ? ' transient' : ''}`;
    const elm = Message.$autoRender({classes, message});
    const ctx = Dom.myCtx(elm);
    flash.appendChild(elm);
    transient && ctx.onDestroy(koru.afTimeout(() => {close(elm)}, 7000));
    return elm;
  };
Beispiel #4
0
  const focusInput = (event)=>{
    const elm = event.currentTarget;
    const parent = elm.parentNode;
    const pCtx = Dom.myCtx(parent);
    if (pCtx == null) return;

    const focusout = event.type === 'focusout' && ! parent.contains(document.activeElement);

    if (focusout) {
      if (currentDialog(elm))
        return;
      document.removeEventListener('selectionchange', pCtx.selectionchange);
      const data = pCtx.data;
      data.options.focusout && data.options.focusout.call(elm, event);
    } else {
      pCtx && pCtx.lastElm === undefined &&
        setMode(pCtx);
      execCommand('styleWithCSS', true);
      document.addEventListener('selectionchange', pCtx.selectionchange);
    }
    Dom.setClass('focus', ! focusout, parent);
  };
Beispiel #5
0
    onBaseEntry: (page, pageRoute, callback)=>{
      const elm = Tpl.$autoRender({});
      pageRoute.eventId &&
        Dom.myCtx(elm).onDestroy(Event.observeId(
          pageRoute.eventId, dc => Dom.setTitle(dc.doc.displayName)));

      document.body.appendChild(elm);
      const currentSub = eventSub;

      const pageTitle = document.getElementById('PageTitle');
      if (pageTitle)
        pageTitle.href = `#${pageRoute.orgSN}/event/${pageRoute.eventId}/show`;

      if (pageRoute.eventId) {
        if (! Tpl.event || Tpl.event._id !== pageRoute.eventId) {
          if (Tpl.event =  Event.findById(pageRoute.eventId)) {
            observeScores();

            eventSub && eventSub.stop();
            eventSub = App.subscribe('Event', pageRoute.eventId, ()=>{callback()});
          }
        }
      }

      if (Tpl.event) {
        pageRoute.eventId = Tpl.event._id;
        Route.title = Tpl.event.displayName;
      } else
        Dom.addClass(elm, 'noEvent');

      if (eventSub === currentSub)
        callback();

      Tpl.stopNotify = Route.onChange(pageChange).stop;
      pageChange(page, pageRoute);
    },
Beispiel #6
0
 $.ctx.onDestroy(Tpl.scoreCounts.onChange((cat_id)=>{
   const elm = document.getElementById('cat_'+cat_id);
   elm === null || Dom.myCtx(elm).updateAllTags();
 }));
Beispiel #7
0
define(function(require, exports, module) {
  const koru        = require('koru');
  const Dom         = require('koru/dom');
  const session     = require('koru/session');
  const Dialog      = require('koru/ui/dialog');
  const Form        = require('koru/ui/form');
  const Route       = require('koru/ui/route');
  const util        = require('koru/util');
  const Category    = require('models/category');
  const Climber     = require('models/climber');
  const Event       = require('models/event');
  const Series      = require('models/series');
  const Team        = require('models/team');
  const TeamType    = require('models/team-type');
  const PrintHelper = require('ui/print-helper');
  const TeamHelper  = require('ui/team-helper');

  const Tpl = Dom.newTemplate(module, require('koru/html!./series'));
  const $ = Dom.current;

  const base = Route.root.addBase(module, Tpl, {
    focus: true,
    routeVar: 'seriesId',
  });

  const commonPageOptions = {
    data: seriesFromRouteVar,
    afterRendered: tabOpened,
  };

  function seriesFromRouteVar(page, pageRoute) {
    return Series.findById(pageRoute.seriesId);
  }

  base.addTemplate(module, Tpl.Events, Object.create(commonPageOptions));
  base.addTemplate(module, Tpl.Edit, Object.create(commonPageOptions));

  function tabOpened(elm, pageRoute) {
    const button = document.querySelector(`#Series .tab[name="${this.name}"]`);
    const ctx = Dom.ctx(elm);
    ctx.tabButton = button;
    Dom.addClass(button, 'selected');
  }

  function tabClosed(ctx) {
    Dom.removeClass(ctx.tabButton, 'selected');
  }

  const ResultsBodyBase = base.addBase(module, Tpl.Results);
  ResultsBodyBase.async = true;

  ResultsBodyBase.addTemplate(module, Tpl.CatResult, {
    data(page, pageRoute) {
      return pageRoute;
    },
    insertPage(elm) {
      const parent = Tpl.Results.$ctx(elm).element();
      parent.insertBefore(elm, parent.firstChild);
    },
  });

  base.addTemplate(module, Tpl.TeamResults, Object.create(commonPageOptions, {
    defaultPage: {value: true}
  }));

  const sortByDate = util.compareByField('date', -1);

  Tpl.$events({
    'click button.tab'(event) {
      Dom.stopEvent();

      Route.replacePage(Tpl[this.getAttribute('name')]);
    },
  });

  Tpl.$extend({
    onBaseEntry(page, pageRoute) {
      const series = Series.findById(pageRoute.seriesId);
      if (! series) Route.abortPage('/'+pageRoute.orgSN+'/events/#series');
      Route.title = series.name;
      const elm = Tpl.$autoRender();
      const ctx = Dom.myCtx(elm);
      document.body.appendChild(elm);
      ctx.onDestroy(Series.observeId(series._id, dc => Dom.setTitle(dc.doc.name)));
    },

    onBaseExit() {
      Dom.removeId('Series');
      Route.title = null;
    },
  });

  Tpl.Events.$helpers({
    list(each) {
      return {
        query: Event.where({series_id: this._id}),
        compare: sortByDate,
      };
    },
  });

  Tpl.Events.$events({
    'click [name=addEvent]'() {
      Dom.stopEvent();

      const series = $.ctx.data;
      let event = Event.build({org_id: series.org_id, series_id: series._id, teamType_ids: series.teamType_ids});

      Dialog.open(Tpl.AddEvent.$autoRender(event));
    },
  });

  Tpl.AddEvent.$events({
    'click [name=cancel]'() {
      Dom.stopEvent();
      Dialog.close();
    },
    'click [type=submit]': Form.submitFunc('AddEvent', () => Dialog.close()),
  });

  Tpl.Events.$extend({
    $destroyed: tabClosed,
  });

  Tpl.Events.Row.$events({
    'click'(event) {
      Dom.stopEvent();

      Route.gotoPage(Dom.Event.Show, {eventId: $.ctx.data._id});
    },
  });

  Tpl.Edit.$events({
    'click [name=cancel]': cancel,
    'click [type=submit]': Form.submitFunc('Edit', doc => {
      Route.replacePage(Tpl);
    }),
  });

  Tpl.Edit.$extend({
    $destroyed: tabClosed,
  });

  Tpl.Results.$helpers({
    content() {
      const selected = document.querySelector('#Results>.categories>.cat.selected');
      if (selected)
        return Dom.h([{button: "Print selection", class: 'link printResults'},
                      {button: "Clear selection", class: 'link clearSelected'}]);
      return "Select categories to print";
    },
  });

  Tpl.Results.$events({
    'click .select': PrintHelper.clickSelect(function (me, selected, parent) {
      Dom.forEach(parent, '.heading.selected',
                  elm => Dom.removeClass(elm, 'selected'));

      const action = parent.getElementsByClassName('action')[0];

      $.ctx.updateAllTags();
    }),

    'click .clearSelected'(event) {
      Dom.stopEvent();
      var parent = event.currentTarget;
      var selected = parent.getElementsByClassName('selected');
      while (selected.length)
        Dom.removeClass(selected[0], 'selected');
    },

    'click .printResults'(event) {
      Dom.stopEvent();
      var parent = event.currentTarget;
      var selected = parent.getElementsByClassName('selected');

      var elm = Dom.h({section: '', class: 'print-only'});
      for(var i = 0; i < selected.length; ++i) {
        elm.appendChild(Tpl.CatResult.$render({append: $.data(selected[i])._id}));
      }
      parent.parentNode.appendChild(elm);
      Dom.addClass(parent, 'no-print');

      window.print();

      Dom.remove(elm);
      Dom.removeClass(parent, 'no-print');
    },

  });

  Tpl.Results.$extend({
    onBaseEntry(page, pageRoute, callback) {
      const series = Series.findById(pageRoute.seriesId);
      const elm = Tpl.Results.$autoRender({});
      const parent = document.querySelector('#Series .tabBody');
      parent.insertBefore(elm, parent.firstChild);
      tabOpened.call(Tpl.Results, elm, pageRoute);
      const ctx = Dom.myCtx(elm);
      session.rpc("Ranking.seriesResult", series._id, (err, results) => {
        if (err) {
          koru.globalErrorCatch(err);
          return;
        }
        Dom.removeClass(elm, 'loading');
        ctx.results = results;
        elm.insertBefore(renderCategories(ctx), elm.firstChild);
        callback();
      });

    },

    onBaseExit() {Dom.removeId('Results')},

    $destroyed: tabClosed,
  });

  Tpl.CatList.$events({
    'click .name'(event) {
      Dom.stopEvent();
      const series = Series.findById(Route.currentPageRoute.seriesId);
      const cat = $.ctx.data;

      Route.gotoPage(Tpl.CatResult, {seriesId: series._id, append: cat._id});
    },
  });

  Tpl.CatResult.$helpers({
    category() {
      return Category.findById(this.category_id);
    },
    events(each) {
      return this.events;
    },
    climbers(each) {
      return this.climbers;
    },
  });

  Tpl.CatResult.$extend({
    $created(ctx, elm) {
      const resultsBody = document.getElementById('Results');
      const resultsCtx = Dom.ctx(resultsBody);
      ctx.parentCtx = resultsCtx;

      const {results} = resultsCtx;

      const climberMap = {};

      const category_id = ctx.data.append;
      const climbers = [];
      const events = [];

      ctx.data = {climbers, events, category_id};

      if (results) for (let ev of results) {
        events.push(Event.findById(ev.event_id));
        for (let cat of ev.cats) {
          if (cat.category_id === category_id) {
            for (let [climber_id, points] of cat.results) {
              let climber = climberMap[climber_id];
              if (! climber)
                climbers.push(climber = climberMap[climber_id] = {
                  _id: climber_id,
                  climber: Climber.findById(climber_id),
                  total: 0,
                  events: {},
                });
              climber.total += points;
              climber.events[ev.event_id] = points;
            }
          }
        }
      }

      events.sort(sortByDate);
      climbers.sort(util.compareByField('total', -1));
    },
  });

  Tpl.CatResult.Row.$helpers({
    events(each) {
      const eventMap = this.events;

      each.clear();
      for (let row of $.ctx.parentCtx.data.events)
        each.append({_id: row._id, points: eventMap[row._id]});
    },
  });

  function renderCategories(ctx) {
    const {results} = ctx;
    const compareCats = util.compareByFields('type', 'name');
    const table = Dom.h({table: '', class: 'categories'});
    if (results) {
      const catMap = {};
      for (let {event_id, cats} of results) {
        for (let {category_id} of cats) {
          catMap[category_id] || (catMap[category_id] = Category.findById(category_id));
        }
      }
      let type;
      for (let cat of util.values(catMap).sort(compareCats)) {
        if (type !== cat.type) {
          type = cat.type;
          table.appendChild(Dom.h({tr: {td: '', $colspan: '2'}, class: 'heading fmt '+type}));
        }
        table.appendChild(Tpl.CatList.$autoRender(cat, ctx));
      }
    }

    return table;
  }


  Tpl.TeamResults.$helpers({
    events(each) {
      return this.events || [];
    },

    teams(each) {
      each.clear();
      if (this.teams) for (let row of this.teams) {
        if (row.team.teamType_id === TeamHelper.teamType_id)
          each.append(row);
      }
    },
  });

  Tpl.TeamResults.$events({
    'menustart [name=selectTeamType]': TeamHelper.chooseTeamTypeEvent(teamTypeList),
  });

  function teamTypeList(ctx) {
    return TeamType.where({_id: ctx.data.series.teamType_ids}).fetch();
  }


  Tpl.TeamResults.$extend({
    $created(ctx, elm) {
      const series = ctx.data;
      ctx.data = {};
      TeamHelper.setSeriesTeamType(series);

      const parent = document.querySelector('#Series .tabBody');
      parent.insertBefore(elm, parent.firstChild);
      session.rpc("Ranking.teamResults", series._id, (err, results) => {
        if (err) {
          koru.globalErrorCatch(err);
          return;
        }
        Dom.removeClass(elm, 'loading');

        const teams = [];
        const teamMap = {};
        const events = results.map(row => {
          for (let ttid in row.scores) {
            const tScores = row.scores[ttid];
            for (let team_id in tScores) {
              let team = teamMap[team_id];
              if (! team) {
                teams.push(team = teamMap[team_id] = {
                  _id: team_id,
                  team: Team.findById(team_id),
                  total: 0,
                  events: {},
                });
              }
              const points = tScores[team_id];
              team.total += points;
              team.events[row.event_id] = points;
            }
          }
          return Event.findById(row.event_id);
        });

        teams.sort(util.compareByField('total', -1));
        events.sort(util.compareByField('date', -1));

        ctx.updateAllTags({events, teams, series});
      });
    },

    $destroyed: tabClosed,
  });

  Tpl.TeamResults.Header.$events({
    'click th.event'(event) {
      Dom.stopEvent();
      Route.gotoPage(Dom.Event.Show, {eventId: $.ctx.data._id});
    },
  });

  Tpl.TeamResults.Row.$helpers({
    events(each) {
      const eventMap = this.events;
      const {events} = $.ctx.parentCtx.data;
      each.clear();
      for (let event of events) {
        each.append({_id: event._id, event, points: eventMap[event._id]});
      }
    },
  });

  Tpl.Form.$helpers({
    teamTypes: TeamHelper.eachTeamTypes,
  });

  function cancel(event) {
    Dom.stopEvent();
    Route.history.back();
  }



  return Tpl;
});
Beispiel #8
0
 const currentDialog = (me)=>{
   const ctx = Dom.myCtx(me.parentNode);
   return ctx && ctx.openDialog;
 };
Beispiel #9
0
 function setHtml(value) {
   const {inputElm} = Dom.myCtx(this);
   Tpl.clear(inputElm);
   value && inputElm.appendChild(value);
 }
Beispiel #10
0
 function getHtml() {return Dom.myCtx(this).inputElm.cloneNode(true)}