<commit_before>const url = require('url')
const request = require('request-promise')
const cheerio = require('cheerio')
const parseArticle = require('./parseArticle')

/**
 * A full article object
 *
 * @typedef {Object} Article
 * @property {string} title  - The title of the article
 * @property {string} html   - The content of the article in HTML
 * @property {string} image  - The heading image URI of the article
 */

/**
 * @private
 */
function getMedia (hostname) {
  const patterns = {
    abc: /abc\.es/,
    ara: /ara\.cat/,
    elconfidencial: /elconfidencial\.com/,
    eldiario: /eldiario\.es/,
    elespanol: /elespanol\.com/,
    elmundo: /elmundo\.es/,
    elpais: /elpais\.com/,
    elperiodico: /elperiodico\.com/,
    esdiario: /esdiario\.com/,
    europapress: /europapress\.es/,
    huffingtonpost: /huffingtonpost\.es/,
    lainformacion: /lainformacion\.com/,
    larazon: /larazon\.es/,
    lavanguardia: /lavanguardia\.com/,
    lavozdegalicia: /lavozdegalicia\.es/,
    libertaddigital: /libertaddigital\.com/,
    okdiario: /okdiario\.com/,
    publico: /publico\.es/
  }

  for (const id in patterns) {
    if (patterns[id].test(hostname)) {
      return id
    }
  }
  return null
}

/**
 * Get the data of an article given its URI
 *
 * @param {string} uri   URI of the news article
 *
 * @return {Promise<Article>} Promise of the article
 */
module.exports = function downloadArticle (uri) {
  const media = getMedia(url.parse(uri).hostname)

  if (!media) {
    console.warn('The provided URI do not match with any known media. It may fail')
    console.warn('Provided URI: %s', uri)
  }

  const options = {
    transform: function (body) {
      return cheerio.load(body)
    },
    uri
  }

  return request(options)
    .then(parseArticle)
}
<commit_msg>Updates JSDoc<commit_after>const url = require('url')
const request = require('request-promise')
const cheerio = require('cheerio')
const parseArticle = require('./parseArticle')

/**
 * A full article object
 *
 * @typedef {Object} Article
 * @property {string} title         - The title of the article
 * @property {string} html          - The content of the article in HTML
 * @property {string} image         - The heading image URI of the article
 * @property {Date}   publishedDate - The publishing date of the article
 * @property {object} json          - Raw JSON object obtained from the article
 */

/**
 * @private
 */
function getMedia (hostname) {
  const patterns = {
    abc: /abc\.es/,
    ara: /ara\.cat/,
    elconfidencial: /elconfidencial\.com/,
    eldiario: /eldiario\.es/,
    elespanol: /elespanol\.com/,
    elmundo: /elmundo\.es/,
    elpais: /elpais\.com/,
    elperiodico: /elperiodico\.com/,
    esdiario: /esdiario\.com/,
    europapress: /europapress\.es/,
    huffingtonpost: /huffingtonpost\.es/,
    lainformacion: /lainformacion\.com/,
    larazon: /larazon\.es/,
    lavanguardia: /lavanguardia\.com/,
    lavozdegalicia: /lavozdegalicia\.es/,
    libertaddigital: /libertaddigital\.com/,
    okdiario: /okdiario\.com/,
    publico: /publico\.es/
  }

  for (const id in patterns) {
    if (patterns[id].test(hostname)) {
      return id
    }
  }
  return null
}

/**
 * Get the data of an article given its URI
 *
 * @param {string} uri   URI of the news article
 *
 * @return {Promise<Article>} Promise of the article
 */
module.exports = function downloadArticle (uri) {
  const media = getMedia(url.parse(uri).hostname)

  if (!media) {
    console.warn('The provided URI do not match with any known media. It may fail')
    console.warn('Provided URI: %s', uri)
  }

  const options = {
    transform: function (body) {
      return cheerio.load(body)
    },
    uri
  }

  return request(options)
    .then(parseArticle)
}
<|endoftext|>


<commit_before>if (!window.localStorage) {
  window.localStorage = {
    getItem: function (sKey) {
      if (!sKey || !this.hasOwnProperty(sKey)) { return null; }
      return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
    },
    key: function (nKeyId) {
      return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
    },
    setItem: function (sKey, sValue) {
      if(!sKey) { return; }
      document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
      this.length = document.cookie.match(/\=/g).length;
    },
    length: 0,
    removeItem: function (sKey) {
      if (!sKey || !this.hasOwnProperty(sKey)) { return; }
      document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
      this.length--;
    },
    hasOwnProperty: function (sKey) {
      return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
    }
  };
  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
}
<commit_msg>Update localstorage.js<commit_after>define([], function() {
  "use strict";

  console.log('localStorage.');

  if (!window.localStorage) {
    window.localStorage = {
      getItem: function (sKey) {
        if (!sKey || !this.hasOwnProperty(sKey)) { return null; }
        return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
      },
      key: function (nKeyId) {
        return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
      },
      setItem: function (sKey, sValue) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
        this.length = document.cookie.match(/\=/g).length;
      },
      length: 0,
      removeItem: function (sKey) {
        if (!sKey || !this.hasOwnProperty(sKey)) { return; }
        document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
        this.length--;
      },
      hasOwnProperty: function (sKey) {
        return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
      }
    };
    window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
  }

  return window.localStorage;
});

<|endoftext|>


<commit_before>const { expect } = require('chai');
const sinon = require('sinon');
const mock = require('mock-require');

function resetModules() {
  Object.keys(require.cache).forEach(key => {
    delete require.cache[key];
  });
}

const parserEnd = sinon.spy();
const Parser = sinon.spy(function () {
  this.end = parserEnd;
});

const DomHandler = sinon.spy(function () {
  this.dom = [
    {
      type: 'tag',
      name: 'html',
      attribs: {},
      children: [],
      next: null,
      prev: null,
      parent: null
    }
  ];
});

const html = '<html>';

describe('server parser', () => {
  // before
  mock('htmlparser2/lib/Parser', Parser);
  mock('domhandler', DomHandler);
  const parse = require('../..');

  it('calls `domhandler` and `htmlparser2/lib/Parser`', () => {
    parse(html);
    expect(DomHandler.called).to.equal(true);
    expect(Parser.called).to.equal(true);
    expect(parserEnd.called).to.equal(true);
  });

  it('passes options to `domhandler` and arguments to `htmlparser2/lib/Parser`', () => {
    const options = { decodeEntities: true };
    parse(html, options);
    expect(DomHandler.calledWith(options)).to.equal(true);
    expect(Parser.calledWith(DomHandler, options));
  });

  it('passes html to `htmlparser2/lib/Parser` end', () => {
    parse(html);
    expect(parserEnd.calledWith(html)).to.equal(true);
  });

  it('returns `domhandler` dom', () => {
    expect(parse(html)).to.equal(DomHandler.lastCall.returnValue.dom);
  });

  // after
  mock.stopAll();
  resetModules();
});
<commit_msg>test(server): improve test names<commit_after>const { expect } = require('chai');
const sinon = require('sinon');
const mock = require('mock-require');

function resetModules() {
  Object.keys(require.cache).forEach(key => {
    delete require.cache[key];
  });
}

const parserEnd = sinon.spy();
const Parser = sinon.spy(function () {
  this.end = parserEnd;
});

const DomHandler = sinon.spy(function () {
  this.dom = [
    {
      type: 'tag',
      name: 'html',
      attribs: {},
      children: [],
      next: null,
      prev: null,
      parent: null
    }
  ];
});

const html = '<html>';

describe('server parser', () => {
  // before
  mock('htmlparser2/lib/Parser', Parser);
  mock('domhandler', DomHandler);
  const parse = require('../..');

  it('calls `DomHandler` and `Parser`', () => {
    parse(html);
    expect(DomHandler.called).to.equal(true);
    expect(Parser.called).to.equal(true);
    expect(parserEnd.called).to.equal(true);
  });

  it('passes options to `DomHandler` and `Parser`', () => {
    const options = { decodeEntities: true };
    parse(html, options);
    expect(DomHandler.calledWith(options)).to.equal(true);
    expect(Parser.calledWith(DomHandler, options));
  });

  it('passes html to `Parser` end', () => {
    parse(html);
    expect(parserEnd.calledWith(html)).to.equal(true);
  });

  it('returns `DomHandler` dom', () => {
    expect(parse(html)).to.equal(DomHandler.lastCall.returnValue.dom);
  });

  // after
  mock.stopAll();
  resetModules();
});
<|endoftext|>


<commit_before>/* Copyright 2009-2011 Hewlett-Packard Development Company, L.P. All rights reserved. */
enyo.kind({
	name: "EditorPanel",
	kind: enyo.HFlexBox,
	components: [
		{name: "slidingPane", kind: "HSlidingPane", flex: 1, components: [
			{name: "top", height: "100%", kind:"HSlidingView",
				components: [
					{kind: "Header", content:"Editor", },
					{kind: "BasicScroller",
						autoHorizontal: false,
						horizontal: false,
						className: "editor-scroller",
						components: [
							{kind: "BasicRichText",
								hint: "type something here",
								richContent: false,
								className: "editor-input",
								onblur: "generateMarkdown"
							}
						]
					}
			]},
			{name: "bottom", kind:"HSlidingView", height: "62px", flex:0, //peekHeight: 54,
				components: [
					{kind: "Header", pack: "center", className: "enyo-toolbar fake-toolbar", components: [
						{kind: "GrabButton", className: "HGrabButton"},
						{kind: "ToolButtonGroup", className: "enyo-toolbutton-dark", components: [
							{caption: "Headline"},
							{caption: "List"},
							{caption: "Image"},
							{caption: "Link"}
						]}
					]},
					{kind: "BasicScroller",
						autoHorizontal: false,
						horizontal: false,
						className: "output-scroller",
						components: [
							{kind: "HtmlContent", className: "output-preview"}
						]
					}
			]}
		]}
	],
	generateMarkdown: function() {
		var converter = new Showdown.converter();
		this.$.htmlContent.setContent(converter.makeHtml(this.$.basicRichText.value));
	}
});
<commit_msg>Multiview auch auf kleinen bildschirmen<commit_after>/* Copyright 2009-2011 Hewlett-Packard Development Company, L.P. All rights reserved. */
enyo.kind({
	name: "EditorPanel",
	kind: enyo.HFlexBox,
	components: [
		{name: "slidingPane", kind: "HSlidingPane", flex: 1, multiViewMinHeight:1, components: [
			{name: "top", height: "100%", kind:"HSlidingView",
				components: [
					{kind: "Header", content:"Editor", },
					{kind: "BasicScroller",
						autoHorizontal: false,
						horizontal: false,
						className: "editor-scroller",
						components: [
							{kind: "BasicRichText",
								hint: "type something here",
								richContent: false,
								className: "editor-input",
								onblur: "generateMarkdown"
							}
						]
					}
			]},
			{name: "bottom", kind:"HSlidingView", height: "62px", flex:0, //peekHeight: 54,
				components: [
					{kind: "Header", pack: "center", className: "enyo-toolbar fake-toolbar", components: [
						{kind: "GrabButton", className: "HGrabButton"},
						{kind: "ToolButtonGroup", className: "enyo-toolbutton-dark", components: [
							{caption: "Headline"},
							{caption: "List"},
							{caption: "Image"},
							{caption: "Link"}
						]}
					]},
					{kind: "BasicScroller",
						autoHorizontal: false,
						horizontal: false,
						className: "output-scroller",
						components: [
							{kind: "HtmlContent", className: "output-preview"}
						]
					}
			]}
		]}
	],
	generateMarkdown: function() {
		var converter = new Showdown.converter();
		this.$.htmlContent.setContent(converter.makeHtml(this.$.basicRichText.value));
	}
});
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2012  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// CellToolbar
//============================================================================

/**
 * A Module to control the per-cell toolbar.
 * @module IPython
 * @namespace IPython
 * @submodule CellToolbar
 */
var IPython = (function (IPython) {
    "use strict";

    /**
     * @constructor
     * @class CellToolbar
     * @param {The cell to attach the metadata UI to} cell
     */
    var CellToolbar = function (cell) {
        CellToolbar._instances.push(this);
        this.cell = cell;
        this.create_element();
        this.rebuild();
        return this;
    };

    CellToolbar.prototype.create_element = function () {
        this.inner_element = $('<div/>').addClass('celltoolbar')
        this.element = $('<div/>').addClass('ctb_hideshow')
            .append(this.inner_element);
        this.show();
    };

    // The default css style for the outer celltoolbar div
    // (ctb_hideshow) is display: none.
    // To show the cell toolbar, *both* of the following conditions must be met:
    // - A parent container has class `ctb_global_show`
    // - The celltoolbar has the class `ctb_show`
    // This allows global show/hide, as well as per-cell show/hide.

    CellToolbar.global_hide = function () {
        $('body').removeClass('ctb_global_show');
    };

    CellToolbar.global_show = function () {
        $('body').addClass('ctb_global_show');
    };

    CellToolbar.prototype.hide = function () {
        this.element.removeClass('ctb_show');
    };

    CellToolbar.prototype.show = function () {
        this.element.addClass('ctb_show');
    };

    /**
     * Class variable that should contain a dict of all available callback
     * we need to think of wether or not we allow nested namespace
     * @property _callback_dict
     * @private
     * @static
     * @type Dict
     */
    CellToolbar._callback_dict = {};

    /**
     * Class variable that should contain the reverse order list of the button
     * to add to the toolbar of each cell
     * @property _ui_controls_list
     * @private
     * @static
     * @type List
     */
    CellToolbar._ui_controls_list = [];

    /**
     * Class variable that should contain the CellToolbar instances for each
     * cell of the notebook
     *
     * @private
     * @property _instances
     * @static
     * @type List
     */
    CellToolbar._instances = [];

    /**
     * keep a list of all the available presets for the toolbar
     * @private
     * @property _presets
     * @static
     * @type Dict
     */
    CellToolbar._presets = {};

    // this is by design not a prototype.
    /**
     * Register a callback to create an UI element in a cell toolbar.
     * @method register_callback
     * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
     * for easier sorting and avoid collision
     * @param  callback {function(div, cell)} callback that will be called to generate the ui element
     *
     *
     * The callback will receive the following element :
     *
     *    * a div in which to add element.
     *    * the cell it is responsible from
     *
     * @example
     *
     * Example that create callback for a button that toggle between `true` and `false` label,
     * with the metadata under the key 'foo' to reflect the status of the button.
     *
     *      // first param reference to a DOM div
     *      // second param reference to the cell.
     *      var toggle =  function(div, cell) {
     *          var button_container = $(div)
     *
     *          // let's create a button that show the  current value of the metadata
     *          var button = $('<div/>').button({label:String(cell.metadata.foo)});
     *
     *          // On click, change the metadata value and update the button label
     *          button.click(function(){
     *                      var v = cell.metadata.foo;
     *                      cell.metadata.foo = !v;
     *                      button.button("option", "label", String(!v));
     *                  })
     *
     *          // add the button to the DOM div.
     *          button_container.append(button);
     *      }
     *
     *      // now we register the callback under the name `foo` to give the
     *      // user the ability to use it later
     *      CellToolbar.register_callback('foo', toggle);
     */
    CellToolbar.register_callback = function(name, callback){
        // Overwrite if it already exists.
        CellToolbar._callback_dict[name] = callback;
    };

    /**
     * Register a preset of UI element in a cell toolbar.
     * Not supported Yet.
     * @method register_preset
     * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
     * for easier sorting and avoid collision
     * @param  preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
     *          should correspond to a name of a registerd callback.
     *
     * @private
     * @example
     *
     *      CellToolbar.register_callback('foo.c1', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c2', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c3', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c4', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c5', function(div, cell){...});
     *
     *      CellToolbar.register_preset('foo.foo_preset1', ['foo.c1', 'foo.c2', 'foo.c5'])
     *      CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
     */
    CellToolbar.register_preset = function(name, preset_list) {
        CellToolbar._presets[name] = preset_list;
        $([IPython.events]).trigger('preset_added.CellToolbar', {name: name});
    };

    /**
     * List the names of the presets that are currently registered.
     *
     * @method list_presets
     * @static
     */
    CellToolbar.list_presets = function() {
        var keys = [];
        for (var k in CellToolbar._presets) {
            keys.push(k);
        }
        return keys;
    };

    /**
     * Activate an UI preset from `register_preset`
     *
     * This does not update the selection UI.
     *
     * @method activate_preset
     * @param preset_name {String} string corresponding to the preset name
     *
     * @static
     * @private
     * @example
     *
     *      CellToolbar.activate_preset('foo.foo_preset1');
     */
    CellToolbar.activate_preset = function(preset_name){
        var preset = CellToolbar._presets[preset_name];

        if(preset !== undefined){
            CellToolbar._ui_controls_list = preset;
            CellToolbar.rebuild_all();
        }
    };

    /**
     * This should be called on the class and not on a instance as it will trigger
     * rebuild of all the instances.
     * @method rebuild_all
     * @static
     *
     */
    CellToolbar.rebuild_all = function(){
        for(var i=0; i < CellToolbar._instances.length; i++){
            CellToolbar._instances[i].rebuild();
        }
    };

    /**
     * Rebuild all the button on the toolbar to update its state.
     * @method rebuild
     */
    CellToolbar.prototype.rebuild = function(){
        // strip evrything from the div
        // which is probably inner_element
        // or this.element.
        this.inner_element.empty();

        var callbacks = CellToolbar._callback_dict;
        var preset = CellToolbar._ui_controls_list;
        // Yes we iterate on the class variable, not the instance one.
        for (var i=0; i < preset.length; i++) {
            var key = preset[i];
            var callback = callbacks[key];
            if (!callback) continue;

            var local_div = $('<div/>').addClass('button_container');
            try {
                callback(local_div, this.cell, this);
            } catch (e) {
                console.log("Error in cell toolbar callback " + key, e);
                continue;
            }
            // only append if callback succeeded.
            this.inner_element.append(local_div);
        }
    };

    /**
     */
    CellToolbar.utils = {};

    /**
     * A utility function to generate bindings between a checkbox and cell/metadata
     * @method utils.checkbox_ui_generator
     * @static
     *
     * @param name {string} Label in front of the checkbox
     * @param setter {function( cell, newValue )}
     *        A setter method to set the newValue
     * @param getter {function( cell )}
     *        A getter methods which return the current value.
     *
     * @return callback {function( div, cell )} Callback to be passed to `register_callback`
     *
     * @example
     *
     * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
     *
     *     var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
     *          // setter
     *          function(cell, value){
     *              // we check that the slideshow namespace exist and create it if needed
     *              if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
     *              // set the value
     *              cell.metadata.slideshow.isSectionStart = value
     *              },
     *          //geter
     *          function(cell){ var ns = cell.metadata.slideshow;
     *              // if the slideshow namespace does not exist return `undefined`
     *              // (will be interpreted as `false` by checkbox) otherwise
     *              // return the value
     *              return (ns == undefined)? undefined: ns.isSectionStart
     *              }
     *      );
     *
     *      CellToolbar.register_callback('newSlide', newSlide);
     *
     */
    CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
        return function(div, cell, celltoolbar) {
            var button_container = $(div);

            var chkb = $('<input/>').attr('type', 'checkbox');
            var lbl = $('<label/>').append($('<span/>').text(name));
            lbl.append(chkb);
            chkb.attr("checked", getter(cell));

            chkb.click(function(){
                        var v = getter(cell);
                        setter(cell, !v);
                        chkb.attr("checked", !v);
            });
            button_container.append($('<div/>').append(lbl));
        };
    };

    /**
     * A utility function to generate bindings between a dropdown list cell
     * @method utils.select_ui_generator
     * @static
     *
     * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
     *        subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
     *        and second the corresponding value to  be passed to setter/return by getter. the corresponding value
     *        should not be "undefined" or behavior can be unexpected.
     * @param setter {function( cell, newValue )}
     *        A setter method to set the newValue
     * @param getter {function( cell )}
     *        A getter methods which return the current value of the metadata.
     * @param [label=""] {String} optionnal label for the dropdown menu
     *
     * @return callback {function( div, cell )} Callback to be passed to `register_callback`
     *
     * @example
     *
     *      var select_type = CellToolbar.utils.select_ui_generator([
     *              ["<None>"       , "None"      ],
     *              ["Header Slide" , "header_slide" ],
     *              ["Slide"        , "slide"        ],
     *              ["Fragment"     , "fragment"     ],
     *              ["Skip"         , "skip"         ],
     *              ],
     *              // setter
     *              function(cell, value){
     *                  // we check that the slideshow namespace exist and create it if needed
     *                  if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
     *                  // set the value
     *                  cell.metadata.slideshow.slide_type = value
     *                  },
     *              //geter
     *              function(cell){ var ns = cell.metadata.slideshow;
     *                  // if the slideshow namespace does not exist return `undefined`
     *                  // (will be interpreted as `false` by checkbox) otherwise
     *                  // return the value
     *                  return (ns == undefined)? undefined: ns.slide_type
     *                  }
     *      CellToolbar.register_callback('slideshow.select', select_type);
     *
     */
    CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label, cell_types){
        label = label || "";
        return function(div, cell, celltoolbar) {
            var button_container = $(div);
            var lbl = $("<label/>").append($('<span/>').text(label));
            var select = $('<select/>').addClass('ui-widget ui-widget-content');
            for(var i=0; i < list_list.length; i++){
                var opt = $('<option/>')
                    .attr('value', list_list[i][1])
                    .text(list_list[i][0]);
                select.append(opt);
            }
            select.val(getter(cell));
            select.change(function(){
                        setter(cell, select.val());
                    });
            button_container.append($('<div/>').append(lbl).append(select));
            if (cell_types && cell_types.indexOf(cell.cell_type) == -1) {
                celltoolbar.hide();
            } else {
                celltoolbar.show();
            }

        };
    };

    IPython.CellToolbar = CellToolbar;

    return IPython;
}(IPython));
<commit_msg>Added an optional parameter to "CellToolbar.register_callback".<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2012  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// CellToolbar
//============================================================================

/**
 * A Module to control the per-cell toolbar.
 * @module IPython
 * @namespace IPython
 * @submodule CellToolbar
 */
var IPython = (function (IPython) {
    "use strict";

    /**
     * @constructor
     * @class CellToolbar
     * @param {The cell to attach the metadata UI to} cell
     */
    var CellToolbar = function (cell) {
        CellToolbar._instances.push(this);
        this.cell = cell;
        this.create_element();
        this.rebuild();
        return this;
    };

    CellToolbar.prototype.create_element = function () {
        this.inner_element = $('<div/>').addClass('celltoolbar')
        this.element = $('<div/>').addClass('ctb_hideshow')
            .append(this.inner_element);
        this.show();
    };

    // The default css style for the outer celltoolbar div
    // (ctb_hideshow) is display: none.
    // To show the cell toolbar, *both* of the following conditions must be met:
    // - A parent container has class `ctb_global_show`
    // - The celltoolbar has the class `ctb_show`
    // This allows global show/hide, as well as per-cell show/hide.

    CellToolbar.global_hide = function () {
        $('body').removeClass('ctb_global_show');
    };

    CellToolbar.global_show = function () {
        $('body').addClass('ctb_global_show');
    };

    CellToolbar.prototype.hide = function () {
        this.element.removeClass('ctb_show');
    };

    CellToolbar.prototype.show = function () {
        this.element.addClass('ctb_show');
    };

    /**
     * Class variable that should contain a dict of all available callback
     * we need to think of wether or not we allow nested namespace
     * @property _callback_dict
     * @private
     * @static
     * @type Dict
     */
    CellToolbar._callback_dict = {};

    /**
     * Class variable that should contain the reverse order list of the button
     * to add to the toolbar of each cell
     * @property _ui_controls_list
     * @private
     * @static
     * @type List
     */
    CellToolbar._ui_controls_list = [];

    /**
     * Class variable that should contain the CellToolbar instances for each
     * cell of the notebook
     *
     * @private
     * @property _instances
     * @static
     * @type List
     */
    CellToolbar._instances = [];

    /**
     * keep a list of all the available presets for the toolbar
     * @private
     * @property _presets
     * @static
     * @type Dict
     */
    CellToolbar._presets = {};

    // this is by design not a prototype.
    /**
     * Register a callback to create an UI element in a cell toolbar.
     * @method register_callback
     * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
     * for easier sorting and avoid collision
     * @param callback {function(div, cell)} callback that will be called to generate the ui element
     * @param [cell_types] {List of String|undefined} optional list of cell types. If present the UI element
     * will be added only to cells of types in the list.
     *
     *
     * The callback will receive the following element :
     *
     *    * a div in which to add element.
     *    * the cell it is responsible from
     *
     * @example
     *
     * Example that create callback for a button that toggle between `true` and `false` label,
     * with the metadata under the key 'foo' to reflect the status of the button.
     *
     *      // first param reference to a DOM div
     *      // second param reference to the cell.
     *      var toggle =  function(div, cell) {
     *          var button_container = $(div)
     *
     *          // let's create a button that show the  current value of the metadata
     *          var button = $('<div/>').button({label:String(cell.metadata.foo)});
     *
     *          // On click, change the metadata value and update the button label
     *          button.click(function(){
     *                      var v = cell.metadata.foo;
     *                      cell.metadata.foo = !v;
     *                      button.button("option", "label", String(!v));
     *                  })
     *
     *          // add the button to the DOM div.
     *          button_container.append(button);
     *      }
     *
     *      // now we register the callback under the name `foo` to give the
     *      // user the ability to use it later
     *      CellToolbar.register_callback('foo', toggle);
     */
    CellToolbar.register_callback = function(name, callback, cell_types) {
        // Overwrite if it already exists.
        CellToolbar._callback_dict[name] = cell_types ? {callback: callback, cell_types: cell_types} : callback;
    };

    /**
     * Register a preset of UI element in a cell toolbar.
     * Not supported Yet.
     * @method register_preset
     * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
     * for easier sorting and avoid collision
     * @param  preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
     *          should correspond to a name of a registerd callback.
     *
     * @private
     * @example
     *
     *      CellToolbar.register_callback('foo.c1', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c2', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c3', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c4', function(div, cell){...});
     *      CellToolbar.register_callback('foo.c5', function(div, cell){...});
     *
     *      CellToolbar.register_preset('foo.foo_preset1', ['foo.c1', 'foo.c2', 'foo.c5'])
     *      CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
     */
    CellToolbar.register_preset = function(name, preset_list) {
        CellToolbar._presets[name] = preset_list;
        $([IPython.events]).trigger('preset_added.CellToolbar', {name: name});
    };

    /**
     * List the names of the presets that are currently registered.
     *
     * @method list_presets
     * @static
     */
    CellToolbar.list_presets = function() {
        var keys = [];
        for (var k in CellToolbar._presets) {
            keys.push(k);
        }
        return keys;
    };

    /**
     * Activate an UI preset from `register_preset`
     *
     * This does not update the selection UI.
     *
     * @method activate_preset
     * @param preset_name {String} string corresponding to the preset name
     *
     * @static
     * @private
     * @example
     *
     *      CellToolbar.activate_preset('foo.foo_preset1');
     */
    CellToolbar.activate_preset = function(preset_name){
        var preset = CellToolbar._presets[preset_name];

        if(preset !== undefined){
            CellToolbar._ui_controls_list = preset;
            CellToolbar.rebuild_all();
        }
    };

    /**
     * This should be called on the class and not on a instance as it will trigger
     * rebuild of all the instances.
     * @method rebuild_all
     * @static
     *
     */
    CellToolbar.rebuild_all = function(){
        for(var i=0; i < CellToolbar._instances.length; i++){
            CellToolbar._instances[i].rebuild();
        }
    };

    /**
     * Rebuild all the button on the toolbar to update its state.
     * @method rebuild
     */
    CellToolbar.prototype.rebuild = function(){
        // strip evrything from the div
        // which is probably inner_element
        // or this.element.
        this.inner_element.empty();

        var callbacks = CellToolbar._callback_dict;
        var preset = CellToolbar._ui_controls_list;
        // Yes we iterate on the class variable, not the instance one.
        for (var i=0; i < preset.length; i++) {
            var key = preset[i];
            var callback = callbacks[key];
            if (!callback) continue;

            if (typeof callback === 'object') {
                if (callback.cell_types.indexOf(this.cell.cell_type) === -1) continue;
                callback = callback.callback;
            }

            var local_div = $('<div/>').addClass('button_container');
            try {
                callback(local_div, this.cell, this);
            } catch (e) {
                console.log("Error in cell toolbar callback " + key, e);
                continue;
            }
            // only append if callback succeeded.
            this.inner_element.append(local_div);
        }
    };

    /**
     */
    CellToolbar.utils = {};

    /**
     * A utility function to generate bindings between a checkbox and cell/metadata
     * @method utils.checkbox_ui_generator
     * @static
     *
     * @param name {string} Label in front of the checkbox
     * @param setter {function( cell, newValue )}
     *        A setter method to set the newValue
     * @param getter {function( cell )}
     *        A getter methods which return the current value.
     *
     * @return callback {function( div, cell )} Callback to be passed to `register_callback`
     *
     * @example
     *
     * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
     *
     *     var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
     *          // setter
     *          function(cell, value){
     *              // we check that the slideshow namespace exist and create it if needed
     *              if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
     *              // set the value
     *              cell.metadata.slideshow.isSectionStart = value
     *              },
     *          //geter
     *          function(cell){ var ns = cell.metadata.slideshow;
     *              // if the slideshow namespace does not exist return `undefined`
     *              // (will be interpreted as `false` by checkbox) otherwise
     *              // return the value
     *              return (ns == undefined)? undefined: ns.isSectionStart
     *              }
     *      );
     *
     *      CellToolbar.register_callback('newSlide', newSlide);
     *
     */
    CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
        return function(div, cell, celltoolbar) {
            var button_container = $(div);

            var chkb = $('<input/>').attr('type', 'checkbox');
            var lbl = $('<label/>').append($('<span/>').text(name));
            lbl.append(chkb);
            chkb.attr("checked", getter(cell));

            chkb.click(function(){
                        var v = getter(cell);
                        setter(cell, !v);
                        chkb.attr("checked", !v);
            });
            button_container.append($('<div/>').append(lbl));
        };
    };

    /**
     * A utility function to generate bindings between a dropdown list cell
     * @method utils.select_ui_generator
     * @static
     *
     * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
     *        subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
     *        and second the corresponding value to  be passed to setter/return by getter. the corresponding value
     *        should not be "undefined" or behavior can be unexpected.
     * @param setter {function( cell, newValue )}
     *        A setter method to set the newValue
     * @param getter {function( cell )}
     *        A getter methods which return the current value of the metadata.
     * @param [label=""] {String} optionnal label for the dropdown menu
     *
     * @return callback {function( div, cell )} Callback to be passed to `register_callback`
     *
     * @example
     *
     *      var select_type = CellToolbar.utils.select_ui_generator([
     *              ["<None>"       , "None"      ],
     *              ["Header Slide" , "header_slide" ],
     *              ["Slide"        , "slide"        ],
     *              ["Fragment"     , "fragment"     ],
     *              ["Skip"         , "skip"         ],
     *              ],
     *              // setter
     *              function(cell, value){
     *                  // we check that the slideshow namespace exist and create it if needed
     *                  if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
     *                  // set the value
     *                  cell.metadata.slideshow.slide_type = value
     *                  },
     *              //geter
     *              function(cell){ var ns = cell.metadata.slideshow;
     *                  // if the slideshow namespace does not exist return `undefined`
     *                  // (will be interpreted as `false` by checkbox) otherwise
     *                  // return the value
     *                  return (ns == undefined)? undefined: ns.slide_type
     *                  }
     *      CellToolbar.register_callback('slideshow.select', select_type);
     *
     */
    CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label, cell_types){
        label = label || "";
        return function(div, cell, celltoolbar) {
            var button_container = $(div);
            var lbl = $("<label/>").append($('<span/>').text(label));
            var select = $('<select/>').addClass('ui-widget ui-widget-content');
            for(var i=0; i < list_list.length; i++){
                var opt = $('<option/>')
                    .attr('value', list_list[i][1])
                    .text(list_list[i][0]);
                select.append(opt);
            }
            select.val(getter(cell));
            select.change(function(){
                        setter(cell, select.val());
                    });
            button_container.append($('<div/>').append(lbl).append(select));
            if (cell_types && cell_types.indexOf(cell.cell_type) == -1) {
                celltoolbar.hide();
            } else {
                celltoolbar.show();
            }

        };
    };

    IPython.CellToolbar = CellToolbar;

    return IPython;
}(IPython));
<|endoftext|>


<commit_before>(function(){

    "use strict";

    XMOT.namespace("XMOT.interaction.geometry");

    /** The tree of this geometry looks like this:
     *  o graph root
     *      o widget container
     *          o xaxis
     *          o yaxis
     *          o zaxis
     *
     *  The axes can be retrieved by their name using getGeo().
     */
    XMOT.interaction.geometry.RotateGizmo = new XMOT.Class(
        XMOT.interaction.geometry.ViewedConstantSizeGeometry, {

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @param {XMOT.interaction.widgets.Widget} widget
         *  @param {Object=} options
         */
        initialize: function(widget, options)
        {
            if(!options)
                options = {};

            if(!options.scale)
                options.scale = new XML3DVec3(0.08, 0.08, 0.08);

            this.callSuper(widget, options);
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @override
         *  @protected
         */
        onCreateDefsElements: function()
        {
            this.callSuper();

            this._halfSize = 0.3;
            var xTransl = "0 " + this._halfSize + " " + this._halfSize;
            this._createAxisDefsElements("xAxis", xTransl, "0 1 0 1.57", "0 1 0");

            var yTransl = this._halfSize + " 0 " + this._halfSize;
            this._createAxisDefsElements("yAxis", yTransl, "1 0 0 1.57", "1 0 0");

            var zTransl = this._halfSize + " " + this._halfSize + " 0";
            this._createAxisDefsElements("zAxis", zTransl, "0 0 1 0", "0 0 1");
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @override
         *  @protected
         */
        onCreateGraph: function()
        {
            this.callSuper();

            this.setGeo("xaxis", this._createAxisGroup("xAxis"));
            this.setGeo("yaxis", this._createAxisGroup("yAxis"));
            this.setGeo("zaxis", this._createAxisGroup("zAxis"));

            this.geo.addToGraphRoot([
                this.getGeo("xaxis"),
                this.getGeo("yaxis"),
                this.getGeo("zaxis")
            ]);
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @private
         *
         *  @param {string} id
         *  @param {string} translation
         *  @param {string} rotation
         *  @param {string} color
         */
        _createAxisDefsElements: function(id, translation, rotation, color)
        {
            var scale = this._halfSize + " " + this._halfSize + " " + this._halfSize;
            this.geo.addTransforms("t_" + id, {
                translation: translation,
                rotation: rotation,
                scale: scale
            });

            this.geo.addShaders("s_" + id, {
                diffCol: color,
                ambInt: "1"
            });
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @private
         *
         *  @param {string} id
         */
        _createAxisGroup: function(id)
        {
            return XMOT.creation.element("group", {
                transform: "#" + this.geo.globalID("t_" + id),
                shader: "#" + this.geo.globalID("s_" + id),
                children: [
                    XMOT.creation.rectangle(this.geo.xml3d)
                ]
            });
        }
    });
}());
<commit_msg>interaction-rotategizmo: rewrote to take quarter-discs as geometry<commit_after>(function(){

    "use strict";

    XMOT.namespace("XMOT.interaction.geometry");

    /** The tree of this geometry looks like this:
     *  o graph root
     *      o widget container
     *          o xaxis
     *          o yaxis
     *          o zaxis
     *
     *  The axes can be retrieved by their name using getGeo().
     */
    XMOT.interaction.geometry.RotateGizmo = new XMOT.Class(
        XMOT.interaction.geometry.ViewedConstantSizeGeometry, {

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @param {XMOT.interaction.widgets.Widget} widget
         *  @param {Object=} options
         */
        initialize: function(widget, options)
        {
            if(!options)
                options = {};

            if(!options.scale)
                options.scale = new XML3DVec3(0.05, 0.05, 0.05);

            this.callSuper(widget, options);
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @override
         *  @protected
         */
        onCreateDefsElements: function()
        {
            this.callSuper();

            this._createAxisDefsElements("xAxis", "0 1 0", "0 1 0 -1.57");
            this._createAxisDefsElements("yAxis", "1 0 0", "1 0 0 1.57");
            this._createAxisDefsElements("zAxis", "0 0 1");
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @override
         *  @protected
         */
        onCreateGraph: function()
        {
            this.callSuper();

            this.setGeo("xaxis", this._createAxisGroup("xAxis"));
            this.setGeo("yaxis", this._createAxisGroup("yAxis"));
            this.setGeo("zaxis", this._createAxisGroup("zAxis"));

            this.geo.addToGraphRoot([
                this.getGeo("xaxis"),
                this.getGeo("yaxis"),
                this.getGeo("zaxis")
            ]);
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @private
         *
         *  @param {string} id
         *  @param {string} color
         *  @param {string=} rotation
         */
        _createAxisDefsElements: function(id, color, rotation)
        {
            if(!rotation)
                rotation = "0 0 1 0";

            this.geo.addTransforms("t_" + id, {
                rotation: rotation
            });

            this.geo.addShaders("s_" + id, {
                diffCol: color,
                ambInt: "1"
            });
        },

        /**
         *  @this {XMOT.interaction.geometry.RotateGizmo}
         *  @private
         *
         *  @param {string} id
         */
        _createAxisGroup: function(id)
        {
            return XMOT.creation.element("group", {
                transform: "#" + this.geo.globalID("t_" + id),
                shader: "#" + this.geo.globalID("s_" + id),
                children: [
                    XMOT.creation.quarterDisc(this.geo.xml3d)
                ]
            });
        }
    });
}());
<|endoftext|>


<commit_before>var fs = require("fs");

if (!fs.existsSync("./watchlist.json")) {
    fs.writeFile("./watchlist.json", "{}", {flag: 'wx'},  (err) => {
        if (err) console.error(err);
    });
}<commit_msg>Updated watchfile<commit_after>var fs = require("fs");

console.log(fs.existsSync("./watchlist.json"));
if (!fs.existsSync("./watchlist.json")) {
    fs.writeFile("./watchlist.json", "{}", {flag: 'wx'},  (err) => {
        if (err) console.error(err);
    });
}<|endoftext|>


<commit_before>define(function (require) {
    var App = require('app/app');
    var Backbone = require('util/backbone-helper');
    var LoadingView = require('util/promise-loading-view');
    var CourseList = require('course/course-list');
    var CourseListView = require('course/view/course-list-view');
    var NavCourseFilterView = require('course/nav/filter-list-view');
    var NavCreateCourseView = require('course/nav/new-course-button-view');
    var NavModifyCourseView = require('course/nav/modify-course-button-view');
    var NavClassDropdownView = require('course/nav/class-dropdown-view');
    var NavStudentDropdownView = require('course/nav/student-dropdown-view');
    var NavAssignmentDropdownView = require('course/nav/assignment-dropdown-view');
    var Radio = require('backbone.radio');
    var userChannel = require('user/module');
    var pageChannel = Radio.channel('page');
    var courseChannel = Radio.channel('course');
    var Course = require('course/course');
    var GradeBookView = require('course/view/gradebook-view');

    var Registry = Backbone.Collection.extend({
         constructor: function Registery() {
             Backbone.Collection.apply(this);
         }
     });

    var registry = window.regestery = new Registry();
    courseChannel.comply('register', function(doc) {
        registry.add(doc);
    });

    var NavItemsCollectionView = Marionette.CollectionView.extend({
        tagName: 'ul',
        className: 'nav navbar-nav grader-navbar-left',
        getChildView: function(item) {
            return item.get('viewClass');
        }
    });

    var navBarViews = new Backbone.Collection([
        new Backbone.Model({
            viewClass: NavClassDropdownView
        }),
        new Backbone.Model({
            viewClass: NavStudentDropdownView
        }),
        new Backbone.Model({
            viewClass: NavAssignmentDropdownView
        }),
        new Backbone.Model({
            viewClass: NavCourseFilterView
        }),
        new Backbone.Model({
            viewClass: NavCreateCourseView
        }),
        new Backbone.Model({
            viewClass: NavModifyCourseView
        })
    ]);

    var controller = {
        allCoursesPage: function() {
            var courseList = new CourseList();
            var coursesPromise = courseList.fetch()
            var mainRegion = pageChannel.request('mainRegion');
            mainRegion.show(new LoadingView({
                promise: coursesPromise
            }));
            coursesPromise.then(function() {
                var navRegion = pageChannel.request('navRegion');
                navRegion.show(new NavItemsCollectionView({
                    collection: navBarViews
                }));
                mainRegion.show(new CourseListView({
                    collection: courseList
                }));
                courseChannel.comply('updateCourses', function(){
                    courseList.fetch();
                    courseList.sort();
                });
                App.go('/courses', {trigger:false, replace: true});
            });

        },
        userCoursesPage: function() {
            var loginPromise = userChannel.request('user');
            loginPromise.then(function(user) {
                var userCoursesPromise = userChannel.request('user:courses');
                var mainRegion = pageChannel.request('mainRegion');

                mainRegion.show(new LoadingView({
                    promise: userCoursesPromise
                }));
                userCoursesPromise.then(function(userCourses) {
                    var navRegion = pageChannel.request('navRegion');
                    navRegion.show(new NavItemsCollectionView({
                        collection: navBarViews
                    }));
                    mainRegion.show(new CourseListView({
                        collection: userCourses
                    }));
                    courseChannel.comply('updateCourses', function(){
                        userCourses.fetch();
                        userCourses.sort();
                    });
                    App.go('/user/courses', {
                        trigger:false,
                        replace: true

                    });
                });
            });

        },
        loadCoursePage: function(path) {
            registry.reset();
            var course = new Course({
                colloquialUrl: path
            });
            course.fetch({populate: true}).then(function(c) {
                courseChannel.respond('current:course', function() {
                    return course;
                })
                var mainRegion = pageChannel.request('mainRegion');
                mainRegion.show(new GradeBookView(course));
                console.dir(course);
                console.log('in load course page',path);
                window.x = course;
            })

        }
    }

    courseChannel.comply('showUserCourses', function() {
        controller.userCoursesPage();
    });

    courseChannel.comply('showAllCourses', function() {
        controller.allCoursesPage();
    });

    App.Router.processAppRoutes(controller, {
        "(/)": "allCoursesPage",
        "courses(/)": "allCoursesPage",
        "user/courses(/)": "userCoursesPage",
        "courses/:path(/)": "loadCoursePage"
    });

    userChannel.on('logout', function() {
        App.go('/', {trigger:true, replace: true});
    });
});<commit_msg>Updated module.js<commit_after>define(function (require) {
    var App = require('app/app');
    var Backbone = require('util/backbone-helper');
    var LoadingView = require('util/promise-loading-view');
    var CourseList = require('course/course-list');
    var CourseListView = require('course/view/course-list-view');
    var NavCourseFilterView = require('course/nav/filter-list-view');
    var NavCreateCourseView = require('course/nav/new-course-button-view');
    var NavModifyCourseView = require('course/nav/modify-course-button-view');
    var NavClassDropdownView = require('course/nav/class-dropdown-view');
    var NavStudentDropdownView = require('course/nav/student-dropdown-view');
    var NavAssignmentDropdownView = require('course/nav/assignment-dropdown-view');
    var Radio = require('backbone.radio');
    var userChannel = require('user/module');
    var pageChannel = Radio.channel('page');
    var courseChannel = Radio.channel('course');
    var Course = require('course/course');
    var GradeBookView = require('course/view/gradebook-view');

    var Registry = Backbone.Collection.extend({
         constructor: function Registery() {
             Backbone.Collection.apply(this);
         }
     });

    var registry = window.regestery = new Registry();
    courseChannel.comply('register', function(doc) {
        registry.add(doc);
    });

    var NavItemsCollectionView = Marionette.CollectionView.extend({
        tagName: 'ul',
        className: 'nav navbar-nav grader-navbar-left',
        getChildView: function(item) {
            return item.get('viewClass');
        }
    });

    var navBarAllCoursesViews = new Backbone.Collection([
        new Backbone.Model({
            viewClass: NavCourseFilterView
        }),
        new Backbone.Model({
            viewClass: NavCreateCourseView
        }),
        new Backbone.Model({
            viewClass: NavModifyCourseView
        })
    ]);

    var navBarCourseSpecificViews = new Backbone.Collection([
        new Backbone.Model({
            viewClass: NavClassDropdownView
        }),
        new Backbone.Model({
            viewClass: NavStudentDropdownView
        }),
        new Backbone.Model({
            viewClass: NavAssignmentDropdownView
        })
    ]);

    var controller = {
        allCoursesPage: function() {
            var courseList = new CourseList();
            var coursesPromise = courseList.fetch()
            var mainRegion = pageChannel.request('mainRegion');
            mainRegion.show(new LoadingView({
                promise: coursesPromise
            }));
            coursesPromise.then(function() {
                var navRegion = pageChannel.request('navRegion');
                navRegion.show(new NavItemsCollectionView({
                    collection: navBarAllCoursesViews
                }));
                mainRegion.show(new CourseListView({
                    collection: courseList
                }));
                courseChannel.comply('updateCourses', function(){
                    courseList.fetch();
                    courseList.sort();
                });
                App.go('/courses', {trigger:false, replace: true});
            });

        },
        userCoursesPage: function() {
            var loginPromise = userChannel.request('user');
            loginPromise.then(function(user) {
                var userCoursesPromise = userChannel.request('user:courses');
                var mainRegion = pageChannel.request('mainRegion');

                mainRegion.show(new LoadingView({
                    promise: userCoursesPromise
                }));
                userCoursesPromise.then(function(userCourses) {
                    var navRegion = pageChannel.request('navRegion');
                    navRegion.show(new NavItemsCollectionView({
                        collection: navBarAllCoursesViews
                    }));
                    mainRegion.show(new CourseListView({
                        collection: userCourses
                    }));
                    courseChannel.comply('updateCourses', function(){
                        userCourses.fetch();
                        userCourses.sort();
                    });
                    App.go('/user/courses', {
                        trigger:false,
                        replace: true

                    });
                });
            });

        },
        loadCoursePage: function(path) {
            registry.reset();
            var course = new Course({
                colloquialUrl: path
            });
            course.fetch({populate: true}).then(function(c) {
                courseChannel.respond('current:course', function() {
                    return course;
                })
                var mainRegion = pageChannel.request('mainRegion');
                mainRegion.show(new GradeBookView(course));
                console.dir(course);
                console.log('in load course page',path);
                window.x = course;
            })

        }
    }

    courseChannel.comply('showUserCourses', function() {
        controller.userCoursesPage();
    });

    courseChannel.comply('showAllCourses', function() {
        controller.allCoursesPage();
    });

    App.Router.processAppRoutes(controller, {
        "(/)": "allCoursesPage",
        "courses(/)": "allCoursesPage",
        "user/courses(/)": "userCoursesPage",
        "courses/:path(/)": "loadCoursePage"
    });

    userChannel.on('logout', function() {
        App.go('/', {trigger:true, replace: true});
    });
});<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var connect = require('connect'),
    helpers = require('./helpers'),
    assert = require('assert'),
    http = require('http');

// Session

var Session = require('connect/middleware/session/session');

// Stores

var MemoryStore = require('connect/middleware/session/memory');

module.exports = {
    'test MemoryStore': function(){
        var n = 0, sid;
        var server = helpers.run(
            connect.cookieDecoder(),
            connect.session({ store: new MemoryStore({ reapInterval: -1 }) }),
            function(req, res, next){
                assert.ok(req.sessionStore, 'Test req.sessionStore');
                assert.ok(req.sessionHash, 'Test req.sessionHash');
                switch (n++) {
                    case 0:
                        assert.eql(['id', 'lastAccess'], Object.keys(req.session),
                            'Test MemoryStore session initialization');
                        break;
                    case 1:
                        req.sessionStore.length(function(err, len){
                            assert.equal(2, len, 'Test MemoryStore#length()');
                        });
                        assert.eql(['id', 'lastAccess'], Object.keys(req.session),
                            'Test MemoryStore session initialization with invalid sid');
                        assert.notEqual('123123', req.session.id, 'Test MemoryStore sid regeneration');
                        break;
                    case 2:
                        lastAccess = req.session.lastAccess;
                        break;
                    case 3:
                        assert.equal(sid, req.session.id, 'Test MemoryStore persistence');
                        assert.notEqual(lastAccess, req.session.lastAccess, 'Test MemoryStore lastAccess update');
                        break;
                    case 4:
                        assert.notEqual(sid, req.session.id, 'Test MemoryStore User-Agent fingerprint');
                        break;
                    case 5:
                        req.sessionStore.destroy(req.sessionHash, function(err, destroyed){
                            assert.ok(!err);
                            assert.ok(destroyed, 'Test MemoryStore#destroy() when present');
                        });
                        break;
                    case 6:
                        req.sessionStore.destroy(req, function(err, destroyed){
                            assert.ok(!err);
                            assert.ok(!destroyed, 'Test MemoryStore#destroy()');
                        });
                        var sess = new Session(req, '12323');
                        assert.eql(['id', 'lastAccess'], Object.keys(sess), 'Test new Session(req, sid)');
                        assert.equal(req, sess.req, 'Test Session#req');

                        var sess = new Session(req, { id: '12323', name: 'tj', lastAccess: +new Date });
                        assert.eql(['id', 'name', 'lastAccess'], Object.keys(sess));
                        assert.equal(req, sess.req, 'Test Session#req');
                        break;
                    case 7:
                        req.sessionStore.get(req.sessionHash, function(err, sess){
                            assert.ok(sess, 'Test MemoryStore#get() when present');
                            req.session.destroy(function(err){
                                assert.ok(!err);
                                req.sessionStore.get(req.sessionHash, function(err, sess){
                                    assert.ok(!sess, 'Test MemoryStore#get() when not present');
                                });
                            });
                        });
                        break;
                    case 8:
                        var prev = req.session;
                        req.session.regenerate(function(err){
                            assert.ok(!err);
                            assert.notEqual(prev.id, req.session.id, 'Test Session#regenerate()');
                        });
                        break;
                    case 9:
                        req.session.destroy(function(err){
                            assert.ok(!err);
                            assert.ok(!req.session, 'Test Session#destroy()');
                        });
                        break;
                }
                next();
            }
        );

        server.pending = 10;
        server.request('GET', '/').end();
        server.request('GET', '/', { 'Cookie': 'connect.sid=123123' }).end();

        var req = server.request('GET', '/', { 'User-Agent': 'foo' });
        req.addListener('response', function(res){
            var setCookie = res.headers['set-cookie'];
            sid = setCookie.match(/connect\.sid=([^;]+)/)[1];
            assert.ok(setCookie.indexOf('connect.sid=') === 0, 'Test MemoryStore Set-Cookie connect.sid');
            assert.ok(setCookie.indexOf('httpOnly') !== -1, 'Test MemoryStore Set-Cookie httpOnly');
            assert.ok(setCookie.indexOf('expires=') !== -1, 'Test MemoryStore Set-Cookie expires');
            setTimeout(function(){
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'bar' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
            }, 30);
        });
        req.end();
    }
};<commit_msg>Added MemoryStore#clear() test<commit_after>
/**
 * Module dependencies.
 */

var connect = require('connect'),
    helpers = require('./helpers'),
    assert = require('assert'),
    http = require('http');

// Session

var Session = require('connect/middleware/session/session');

// Stores

var MemoryStore = require('connect/middleware/session/memory');

module.exports = {
    'test MemoryStore': function(){
        var n = 0, sid;
        var server = helpers.run(
            connect.cookieDecoder(),
            connect.session({ store: new MemoryStore({ reapInterval: -1 }) }),
            function(req, res, next){
                assert.ok(req.sessionStore, 'Test req.sessionStore');
                assert.ok(req.sessionHash, 'Test req.sessionHash');
                switch (n++) {
                    case 0:
                        assert.eql(['id', 'lastAccess'], Object.keys(req.session),
                            'Test MemoryStore session initialization');
                        break;
                    case 1:
                        req.sessionStore.length(function(err, len){
                            assert.equal(2, len, 'Test MemoryStore#length()');
                        });
                        assert.eql(['id', 'lastAccess'], Object.keys(req.session),
                            'Test MemoryStore session initialization with invalid sid');
                        assert.notEqual('123123', req.session.id, 'Test MemoryStore sid regeneration');
                        break;
                    case 2:
                        lastAccess = req.session.lastAccess;
                        break;
                    case 3:
                        assert.equal(sid, req.session.id, 'Test MemoryStore persistence');
                        assert.notEqual(lastAccess, req.session.lastAccess, 'Test MemoryStore lastAccess update');
                        break;
                    case 4:
                        assert.notEqual(sid, req.session.id, 'Test MemoryStore User-Agent fingerprint');
                        break;
                    case 5:
                        req.sessionStore.destroy(req.sessionHash, function(err, destroyed){
                            assert.ok(!err);
                            assert.ok(destroyed, 'Test MemoryStore#destroy() when present');
                        });
                        break;
                    case 6:
                        req.sessionStore.destroy(req, function(err, destroyed){
                            assert.ok(!err);
                            assert.ok(!destroyed, 'Test MemoryStore#destroy()');
                        });
                        var sess = new Session(req, '12323');
                        assert.eql(['id', 'lastAccess'], Object.keys(sess), 'Test new Session(req, sid)');
                        assert.equal(req, sess.req, 'Test Session#req');

                        var sess = new Session(req, { id: '12323', name: 'tj', lastAccess: +new Date });
                        assert.eql(['id', 'name', 'lastAccess'], Object.keys(sess));
                        assert.equal(req, sess.req, 'Test Session#req');
                        break;
                    case 7:
                        req.sessionStore.get(req.sessionHash, function(err, sess){
                            assert.ok(sess, 'Test MemoryStore#get() when present');
                            req.session.destroy(function(err){
                                assert.ok(!err);
                                req.sessionStore.get(req.sessionHash, function(err, sess){
                                    assert.ok(!sess, 'Test MemoryStore#get() when not present');
                                });
                            });
                        });
                        break;
                    case 8:
                        var prev = req.session;
                        req.session.regenerate(function(err){
                            assert.ok(!err);
                            assert.notEqual(prev.id, req.session.id, 'Test Session#regenerate()');
                        });
                        break;
                    case 9:
                        req.session.destroy(function(err){
                            assert.ok(!err);
                            assert.ok(!req.session, 'Test Session#destroy()');
                        });
                        req.sessionStore.clear(function(err){
                            assert.ok(!err);
                            req.sessionStore.length(function(err, len){
                                assert.equal(0, len, 'Test MemoryStore#clear()');
                            });
                        });
                        break;
                }
                next();
            }
        );

        server.pending = 10;
        server.request('GET', '/').end();
        server.request('GET', '/', { 'Cookie': 'connect.sid=123123' }).end();

        var req = server.request('GET', '/', { 'User-Agent': 'foo' });
        req.addListener('response', function(res){
            var setCookie = res.headers['set-cookie'];
            sid = setCookie.match(/connect\.sid=([^;]+)/)[1];
            assert.ok(setCookie.indexOf('connect.sid=') === 0, 'Test MemoryStore Set-Cookie connect.sid');
            assert.ok(setCookie.indexOf('httpOnly') !== -1, 'Test MemoryStore Set-Cookie httpOnly');
            assert.ok(setCookie.indexOf('expires=') !== -1, 'Test MemoryStore Set-Cookie expires');
            setTimeout(function(){
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'bar' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
                server.request('GET', '/', { 'Cookie': 'connect.sid=' + sid, 'User-Agent': 'foo' }).end();
            }, 30);
        });
        req.end();
    }
};<|endoftext|>


<commit_before>fabric.ElementsParser = function(elements, callback, options, reviver) {
  this.elements = elements;
  this.callback = callback;
  this.options = options;
  this.reviver = reviver;
};

fabric.ElementsParser.prototype.parse = function() {
  this.instances = new Array(this.elements.length);
  this.numElements = this.elements.length;

  this.createObjects();
};

fabric.ElementsParser.prototype.createObjects = function() {
  for (var i = 0, len = this.elements.length; i < len; i++) {
    (function(_this, i) {
      setTimeout(function() {
        _this.createObject(_this.elements[i], i);
      }, 0);
    })(this, i);
  }
};

fabric.ElementsParser.prototype.createObject = function(el, index) {
  var klass = fabric[fabric.util.string.capitalize(el.tagName)];
  if (klass && klass.fromElement) {
    try {
      this._createObject(klass, el, index);
    }
    catch (err) {
      fabric.log(err);
    }
  }
  else {
    this.checkIfDone();
  }
};

fabric.ElementsParser.prototype._createObject = function(klass, el, index) {
  if (klass.async) {
    klass.fromElement(el, this.createCallback(index, el), this.options);
  }
  else {
    var obj = klass.fromElement(el, this.options);
    this.resolveGradient(obj);
    this.reviver && this.reviver(el, obj);
    this.instances[index] = obj;
    this.checkIfDone();
  }
};

fabric.ElementsParser.prototype.createCallback = function(index, el) {
  var _this = this;
  return function(obj) {
    _this.resolveGradient(obj);
    _this.reviver && _this.reviver(el, obj);
    _this.instances[index] = obj;
    _this.checkIfDone();
  };
};

fabric.ElementsParser.prototype.resolveGradient = function(obj) {

    var instanceFillValue = obj.get('fill');
    if (!(/^url\(/).test(instanceFillValue)) {
      return;
    }
    var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1);
    if (fabric.gradientDefs[gradientId]) {
      obj.set('fill',
        fabric.Gradient.fromElement(fabric.gradientDefs[gradientId], obj));
    }
};

fabric.ElementsParser.prototype.checkIfDone = function() {
  if (--this.numElements === 0) {
    this.instances = this.instances.filter(function(el) {
      return el != null;
    });
    this.callback(this.instances);
  }
};
<commit_msg>Update elements_parser.js<commit_after>fabric.ElementsParser = function(elements, callback, options, reviver) {
  this.elements = elements;
  this.callback = callback;
  this.options = options;
  this.reviver = reviver;
};

fabric.ElementsParser.prototype.parse = function() {
  this.instances = new Array(this.elements.length);
  this.numElements = this.elements.length;

  this.createObjects();
};

fabric.ElementsParser.prototype.createObjects = function() {
  for (var i = 0, len = this.elements.length; i < len; i++) {
    (function(_this, i) {
      setTimeout(function() {
        _this.createObject(_this.elements[i], i);
      }, 0);
    })(this, i);
  }
};

fabric.ElementsParser.prototype.createObject = function(el, index) {
  var klass = fabric[fabric.util.string.capitalize(el.tagName)];
  if (klass && klass.fromElement) {
    try {
      this._createObject(klass, el, index);
    }
    catch (err) {
      fabric.log(err);
    }
  }
  else {
    this.checkIfDone();
  }
};

fabric.ElementsParser.prototype._createObject = function(klass, el, index) {
  if (klass.async) {
    klass.fromElement(el, this.createCallback(index, el), this.options);
  }
  else {
    var obj = klass.fromElement(el, this.options);
    this.resolveGradient(obj,'fill');
    this.resolveGradient(obj,'stroke');
    this.reviver && this.reviver(el, obj);
    this.instances[index] = obj;
    this.checkIfDone();
  }
};

fabric.ElementsParser.prototype.createCallback = function(index, el) {
  var _this = this;
  return function(obj) {
    _this.resolveGradient(obj,'fill');
    _this.resolveGradient(obj,'stroke');
    _this.reviver && _this.reviver(el, obj);
    _this.instances[index] = obj;
    _this.checkIfDone();
  };
};

fabric.ElementsParser.prototype.resolveGradient = function(obj,property) {

    var instanceFillValue = obj.get(property);
    if (!(/^url\(/).test(instanceFillValue)) {
      return;
    }
    var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1);
    if (fabric.gradientDefs[gradientId]) {
      obj.set(property,
        fabric.Gradient.fromElement(fabric.gradientDefs[gradientId], obj));
    }
};

fabric.ElementsParser.prototype.checkIfDone = function() {
  if (--this.numElements === 0) {
    this.instances = this.instances.filter(function(el) {
      return el != null;
    });
    this.callback(this.instances);
  }
};
<|endoftext|>


<commit_before>import {
    action,
    computed,
    observable }            from 'mobx';
import BaseStore            from './base_store';
import { MAX_MOBILE_WIDTH } from '../Constants/ui';

export default class UIStore extends BaseStore {
    @observable is_portfolio_drawer_on     = false;
    @observable is_main_drawer_on          = false;
    @observable is_notifications_drawer_on = false;
    @observable screen_width               = window.innerWidth;

    @observable is_settings_dialog_on = false;
    @observable is_language_dialog_on = false;
    @observable is_dark_mode_on = true;

    // Purchase Controls
    @observable is_purchase_confirm_on = false;
    @observable is_purchase_lock_on = false;

    // SmartCharts Controls
    @observable is_chart_layout_default = false;
    @observable is_chart_asset_info_visible = true;
    @observable is_chart_countdown_visible = false;

    constructor() {
        const local_storage_properties = ['is_portfolio_drawer_on'];

        super(null, local_storage_properties);
        window.addEventListener('resize', this.updateScreenWidth);
    }

    @action.bound
    updateScreenWidth() {
        this.screen_width = window.innerWidth;
    }

    @computed
    get is_mobile() {
        return this.screen_width <= MAX_MOBILE_WIDTH;
    }

    @action.bound
    toggleChartLayout() {
        this.is_chart_layout_default = !this.is_chart_layout_default;
    };

    @action.bound
    toggleChartAssetInfo() {
        this.is_chart_asset_info_visible = !this.is_chart_asset_info_visible;
    }

    @action.bound
    toggleChartCountdown() {
        this.is_chart_countdown_visible = !this.is_chart_countdown_visible;
    }

    @action.bound
    togglePurchaseLock() {
        this.is_purchase_lock_on = !this.is_purchase_lock_on;
    }

    @action.bound
    togglePurchaseConfirmation() {
        this.is_purchase_confirm_on = !this.is_purchase_confirm_on;
    }

    @action.bound
    toggleDarkMode() {
        this.is_dark_mode_on = !this.is_dark_mode_on;
    }

    @action.bound
    toggleSettingsDialog() {
        this.is_settings_dialog_on = !this.is_settings_dialog_on;
        if (!this.is_settings_dialog_on) this.is_language_dialog_on = false;
    }

    @action.bound
    showLanguageDialog() {
        this.is_language_dialog_on = true;
    }

    @action.bound
    hideLanguageDialog() {
        this.is_language_dialog_on = false;
    }

    @action.bound
    togglePortfolioDrawer() { // show and hide Portfolio Drawer
        this.is_portfolio_drawer_on = !this.is_portfolio_drawer_on;
    };

    @action.bound
    showMainDrawer() { // show main Drawer
        this.is_main_drawer_on = true;
    };

    @action.bound
    showNotificationsDrawer() { // show nofitications Drawer
        this.is_notifications_drawer_on = true;
    };

    @action.bound
    hideDrawers() { // hide both menu drawers
        this.is_main_drawer_on = false;
        this.is_notifications_drawer_on = false;
    };
};
<commit_msg>Defined user settings' items which should be saved in localstorage<commit_after>import {
    action,
    computed,
    observable }            from 'mobx';
import BaseStore            from './base_store';
import { MAX_MOBILE_WIDTH } from '../Constants/ui';

export default class UIStore extends BaseStore {
    @observable is_portfolio_drawer_on     = false;
    @observable is_main_drawer_on          = false;
    @observable is_notifications_drawer_on = false;
    @observable screen_width               = window.innerWidth;

    @observable is_settings_dialog_on = false;
    @observable is_language_dialog_on = false;
    @observable is_dark_mode_on = true;

    // Purchase Controls
    @observable is_purchase_confirm_on = false;
    @observable is_purchase_lock_on = false;

    // SmartCharts Controls
    @observable is_chart_layout_default = false;
    @observable is_chart_asset_info_visible = true;
    @observable is_chart_countdown_visible = false;

    constructor() {
        const local_storage_properties = [
            'is_chart_asset_info_visible',
            'is_chart_countdown_visible',
            'is_chart_layout_default',
            'is_dark_mode_on',
            'is_portfolio_drawer_on',
            'is_purchase_confirm_on',
            'is_purchase_lock_on',
        ];

        super(null, local_storage_properties);
        window.addEventListener('resize', this.updateScreenWidth);
    }

    @action.bound
    updateScreenWidth() {
        this.screen_width = window.innerWidth;
    }

    @computed
    get is_mobile() {
        return this.screen_width <= MAX_MOBILE_WIDTH;
    }

    @action.bound
    toggleChartLayout() {
        this.is_chart_layout_default = !this.is_chart_layout_default;
    };

    @action.bound
    toggleChartAssetInfo() {
        this.is_chart_asset_info_visible = !this.is_chart_asset_info_visible;
    }

    @action.bound
    toggleChartCountdown() {
        this.is_chart_countdown_visible = !this.is_chart_countdown_visible;
    }

    @action.bound
    togglePurchaseLock() {
        this.is_purchase_lock_on = !this.is_purchase_lock_on;
    }

    @action.bound
    togglePurchaseConfirmation() {
        this.is_purchase_confirm_on = !this.is_purchase_confirm_on;
    }

    @action.bound
    toggleDarkMode() {
        this.is_dark_mode_on = !this.is_dark_mode_on;
    }

    @action.bound
    toggleSettingsDialog() {
        this.is_settings_dialog_on = !this.is_settings_dialog_on;
        if (!this.is_settings_dialog_on) this.is_language_dialog_on = false;
    }

    @action.bound
    showLanguageDialog() {
        this.is_language_dialog_on = true;
    }

    @action.bound
    hideLanguageDialog() {
        this.is_language_dialog_on = false;
    }

    @action.bound
    togglePortfolioDrawer() { // show and hide Portfolio Drawer
        this.is_portfolio_drawer_on = !this.is_portfolio_drawer_on;
    };

    @action.bound
    showMainDrawer() { // show main Drawer
        this.is_main_drawer_on = true;
    };

    @action.bound
    showNotificationsDrawer() { // show nofitications Drawer
        this.is_notifications_drawer_on = true;
    };

    @action.bound
    hideDrawers() { // hide both menu drawers
        this.is_main_drawer_on = false;
        this.is_notifications_drawer_on = false;
    };
};
<|endoftext|>