<commit_before>//= require "../chrome/storage"

var libraries = [
    {
        "url": "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js",
        "label": "jQuery latest",
        "group": "jQuery"
    },
    {
        "url": "http://code.jquery.com/jquery-git.js",
        "label": "jQuery WIP (via git)",
        "group": "jQuery"
    },
    {
        "url": "http://code.jquery.com/jquery-1.8.1.min.js",
        "label": "jQuery 1.8.1",
        "group": "jQuery"
    },
    {
        "url": "http://code.jquery.com/jquery-1.7.2.min.js",
        "label": "jQuery 1.7.2",
        "group": "jQuery"
    },
    {
        "url": [
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css",
            "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js",
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"
        ],
        "label": "jQuery UI latest",
        "group": "jQuery UI"
    },
    {
        "url": [
            "http://code.jquery.com/ui/jquery-ui-git.css",
            "http://code.jquery.com/jquery-git.js",
            "http://code.jquery.com/ui/jquery-ui-git.js"
        ],
        "label": "jQuery UI WIP (via git)",
        "group": "jQuery UI"
    },
    {
        "url": [
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/base/jquery-ui.css",
            "http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js",
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"
        ],
        "label": "jQuery UI 1.8.23",
        "group": "jQuery UI"
    },
    {
        "url": [
            "http://code.jquery.com/mobile/latest/jquery.mobile.css",
            "http://code.jquery.com/jquery-1.6.4.min.js",
            "http://code.jquery.com/mobile/latest/jquery.mobile.js"
        ],
        "label": "jQuery Mobile Latest",
        "group": "jQuery Mobile"
    },
    {
        "url": [
            "http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css",
            "http://code.jquery.com/jquery-1.6.4.min.js",
            "http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.js"
        ],
        "label": "jQuery Mobile 1.1.0",
        "group": "jQuery Mobile"
    },
    {
        "url": [
            "http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css",
            "http://code.jquery.com/jquery-1.6.4.min.js",
            "http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.1.min.js"
        ],
        "label": "jQuery Mobile 1.0.1",
        "group": "jQuery Mobile"
    },
    {
        "url": [
            "http://code.jquery.com/jquery.min.js",
            "http://twitter.github.com/bootstrap/assets/css/bootstrap.css",
            "http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css",
            "http://twitter.github.com/bootstrap/assets/js/bootstrap.js"
        ],
        "label": "Bootstrap latest",
        "group": "Bootstrap"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js",
        "label": "Prototype latest",
        "group": "Prototype"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/prototype/1.7.1/prototype.js",
        "label": "Prototype 1.7.1",
        "group": "Prototype"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js",
        "label": "Prototype 1.6.1.0",
        "group": "Prototype"
    },
    {
        "url": [
            "http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js",
            "http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js"
        ],
        "label": "script.aculo.us 1.8.3",
        "group": "Prototype"
    },
    {
        "url": "http://yui.yahooapis.com/3.7.2/build/yui/yui-min.js",
        "label": "YUI 3.7.2",
        "group": "YUI"
    },
    {
        "url": "http://yui.yahooapis.com/2.9.0/build/yuiloader/yuiloader-min.js",
        "label": "YUI 2.9.0",
        "group": "YUI"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-yui-compressed.js",
        "label": "MooTools 1.4.5",
        "group": "MooTools"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/mootools/1.3.2/mootools-yui-compressed.js",
        "label": "MooTools 1.3.2",
        "group": "MooTools"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js",
        "label": "Dojo 1.6.0",
        "group": "Dojo"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.4.1/dojo/dojo.xd.js",
        "label": "Dojo 1.4.1",
        "group": "Dojo"
    },
    {
        "url": [
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.common.min.css",
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.default.min.css",
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.dataviz.min.css",
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.mobile.all.min.css",
            "http://code.jquery.com/jquery-1.8.0.min.js",
            "http://cdn.kendostatic.com/2012.2.710/js/kendo.all.min.js"
        ],
        "label": "Kendo UI Q2 2012",
        "group": "Kendo UI"
    },
    {
        "url": [
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.common.min.css",
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.default.min.css",
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.dataviz.min.css",
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.mobile.all.min.css",
            "http://code.jquery.com/jquery-1.8.0.min.js",
            "http://cdn.kendostatic.com/2012.1.322/js/kendo.all.min.js"
        ],
        "label": "Kendo UI Q1 2012",
        "group": "Kendo UI"
    },
    {
        "url" : [
            "http://code.jquery.com/qunit/qunit-git.css",
            "http://code.jquery.com/qunit/qunit-git.js"
        ],
        "label": "QUnit",
        "group": "Testing"
    },
    {
        "url":"http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js",
        "label": "Angular 1.0.1"
    },
    {
        "url": [
            "http://documentcloud.github.com/underscore/underscore-min.js",
            "http://documentcloud.github.com/backbone/backbone-min.js"
        ],
        "label": "Backbone 0.9.2"
    },
    {
        "url": "http://jashkenas.github.com/coffee-script/extras/coffee-script.js",
        "label": "CoffeeScript"
    },
    {
        "url": "https://github.com/downloads/emberjs/ember.js/ember-0.9.8.1.min.js",
        "label": "Ember.js 0.9.8.1"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/es5-shim/1.2.4/es5-shim.min.js",
        "label": "ES5 shim 1.2.4"
    },
    {
        "url": [
            "http://extjs.cachefly.net/ext-3.1.0/resources/css/ext-all.css",
            "http://cdnjs.cloudflare.com/ajax/libs/ext-core/3.1.0/ext-core.js"
        ],
        "label": "ext-core 3.1.0"
    },
    {
        "url": "http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js",
        "label": "Knockout 2.1"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/less.js/1.1.3/less-1.1.3.min.js",
        "label": "Less 1.1.3"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.5.2/lodash.min.js",
        "label": "lodash 0.5.2"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.5.3/modernizr.min.js",
        "label": "Modernizr 2.5.3"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.6/prefixfree.min.js",
        "label": "Prefixfree 1.0.6"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/processing.js/1.3.6/processing-api.min.js",
        "label": "Processing 1.3.6"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/raphael/2.0.0/raphael-min.js",
        "label": "Raphaël 2.0.0"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/sammy.js/0.6.3/sammy.min.js",
        "label": "Sammy 0.6.3"
    },
    {
        "url": [
            "http://cdn.sencha.io/touch/1.1.0/resources/css/sencha-touch.css",
            "http://cdn.sencha.io/touch/1.1.0/sencha-touch.js"
        ],
        "label": "Sencha Touch"
    },
    {
        "url": [
            "http://traceur-compiler.googlecode.com/git/src/traceur.js",
            "http://traceur-compiler.googlecode.com/git/src/bootstrap.js"
        ],
        "label": "Traceur"
    },
    {
        "url": "http://remy.github.com/twitterlib/twitterlib.min.js",
        "label": "TwitterLib"
    },
    {
        "url": "http://documentcloud.github.com/underscore/underscore-min.js",
        "label": "underscore 1.3.1"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/zepto/0.7/zepto.min.js",
        "label": "Zepto 0.7"
    },
    {
        "url":[
            "http://code.jquery.com/jquery-1.7.1.min.js",
            " http://canjs.us/release/latest/can.jquery.js"
        ],
        "label": "CanJS 1.0.7 for jQuery"
    }
];

window.libraries = libraries; // expose a command line API

libraries.userSpecified = JSON.parse(localStorage.getItem('libraries') || "[]");
for (var i = 0; i < libraries.userSpecified.length; i++) {
  libraries.push(libraries.userSpecified[i]);
}

libraries.add = function (lib) {
  // save to localStorage
  lib.group = 'Custom';
  this.userSpecified.push(lib);
  try {
    localStorage.setItem('libraries', JSON.stringify(this.userSpecified));
  } catch (e) {} // just in case of DOM_22 error, makes me so sad to use this :(
  libraries.push(lib);
  $('#library').trigger('init');
};

libraries.clear = function () {
  libraries.userSpecified = [];
  localStorage.removeItem('libraries');
  var length = libraries.length;
  for (var i = 0; i < length; i++) {
    if (libraries[i].group === 'Custom') {
      libraries.splice(i, 1);
      length--;
    }
  }
  // force a refresh?
  $('#library').trigger('init');
};
<commit_msg>Updating Dojo versions, adding easy Dijit use<commit_after>//= require "../chrome/storage"

var libraries = [
    {
        "url": "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js",
        "label": "jQuery latest",
        "group": "jQuery"
    },
    {
        "url": "http://code.jquery.com/jquery-git.js",
        "label": "jQuery WIP (via git)",
        "group": "jQuery"
    },
    {
        "url": "http://code.jquery.com/jquery-1.8.1.min.js",
        "label": "jQuery 1.8.1",
        "group": "jQuery"
    },
    {
        "url": "http://code.jquery.com/jquery-1.7.2.min.js",
        "label": "jQuery 1.7.2",
        "group": "jQuery"
    },
    {
        "url": [
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css",
            "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js",
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"
        ],
        "label": "jQuery UI latest",
        "group": "jQuery UI"
    },
    {
        "url": [
            "http://code.jquery.com/ui/jquery-ui-git.css",
            "http://code.jquery.com/jquery-git.js",
            "http://code.jquery.com/ui/jquery-ui-git.js"
        ],
        "label": "jQuery UI WIP (via git)",
        "group": "jQuery UI"
    },
    {
        "url": [
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/base/jquery-ui.css",
            "http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js",
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"
        ],
        "label": "jQuery UI 1.8.23",
        "group": "jQuery UI"
    },
    {
        "url": [
            "http://code.jquery.com/mobile/latest/jquery.mobile.css",
            "http://code.jquery.com/jquery-1.6.4.min.js",
            "http://code.jquery.com/mobile/latest/jquery.mobile.js"
        ],
        "label": "jQuery Mobile Latest",
        "group": "jQuery Mobile"
    },
    {
        "url": [
            "http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css",
            "http://code.jquery.com/jquery-1.6.4.min.js",
            "http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.js"
        ],
        "label": "jQuery Mobile 1.1.0",
        "group": "jQuery Mobile"
    },
    {
        "url": [
            "http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css",
            "http://code.jquery.com/jquery-1.6.4.min.js",
            "http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.1.min.js"
        ],
        "label": "jQuery Mobile 1.0.1",
        "group": "jQuery Mobile"
    },
    {
        "url": [
            "http://code.jquery.com/jquery.min.js",
            "http://twitter.github.com/bootstrap/assets/css/bootstrap.css",
            "http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css",
            "http://twitter.github.com/bootstrap/assets/js/bootstrap.js"
        ],
        "label": "Bootstrap latest",
        "group": "Bootstrap"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js",
        "label": "Prototype latest",
        "group": "Prototype"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/prototype/1.7.1/prototype.js",
        "label": "Prototype 1.7.1",
        "group": "Prototype"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js",
        "label": "Prototype 1.6.1.0",
        "group": "Prototype"
    },
    {
        "url": [
            "http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js",
            "http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js"
        ],
        "label": "script.aculo.us 1.8.3",
        "group": "Prototype"
    },
    {
        "url": "http://yui.yahooapis.com/3.7.2/build/yui/yui-min.js",
        "label": "YUI 3.7.2",
        "group": "YUI"
    },
    {
        "url": "http://yui.yahooapis.com/2.9.0/build/yuiloader/yuiloader-min.js",
        "label": "YUI 2.9.0",
        "group": "YUI"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-yui-compressed.js",
        "label": "MooTools 1.4.5",
        "group": "MooTools"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/mootools/1.3.2/mootools-yui-compressed.js",
        "label": "MooTools 1.3.2",
        "group": "MooTools"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.8.0/dojo/dojo.js",
        "label": "Dojo 1.8.0",
        "group": "Dojo"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.7.3/dojo/dojo.js",
        "label": "Dojo 1.7.3",
        "group": "Dojo"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js",
        "label": "Dojo 1.6.1",
        "group": "Dojo"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.8.0/dijit/themes/claro/claro.css",
        "label": "Dijit 1.8.0 (Claro)",
        "group": "Dijit"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.7.3/dijit/themes/claro/claro.css",
        "label": "Dijit 1.7.3 (Claro)",
        "group": "Dijit"
    },
    {
        "url": "http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dijit/themes/claro/claro.css",
        "label": "Dijit 1.6.1 (Claro)",
        "group": "Dijit"
    },
    {
        "url": [
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.common.min.css",
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.default.min.css",
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.dataviz.min.css",
            "http://cdn.kendostatic.com/2012.2.710/styles/kendo.mobile.all.min.css",
            "http://code.jquery.com/jquery-1.8.0.min.js",
            "http://cdn.kendostatic.com/2012.2.710/js/kendo.all.min.js"
        ],
        "label": "Kendo UI Q2 2012",
        "group": "Kendo UI"
    },
    {
        "url": [
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.common.min.css",
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.default.min.css",
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.dataviz.min.css",
            "http://cdn.kendostatic.com/2012.1.322/styles/kendo.mobile.all.min.css",
            "http://code.jquery.com/jquery-1.8.0.min.js",
            "http://cdn.kendostatic.com/2012.1.322/js/kendo.all.min.js"
        ],
        "label": "Kendo UI Q1 2012",
        "group": "Kendo UI"
    },
    {
        "url" : [
            "http://code.jquery.com/qunit/qunit-git.css",
            "http://code.jquery.com/qunit/qunit-git.js"
        ],
        "label": "QUnit",
        "group": "Testing"
    },
    {
        "url":"http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js",
        "label": "Angular 1.0.1"
    },
    {
        "url": [
            "http://documentcloud.github.com/underscore/underscore-min.js",
            "http://documentcloud.github.com/backbone/backbone-min.js"
        ],
        "label": "Backbone 0.9.2"
    },
    {
        "url": "http://jashkenas.github.com/coffee-script/extras/coffee-script.js",
        "label": "CoffeeScript"
    },
    {
        "url": "https://github.com/downloads/emberjs/ember.js/ember-0.9.8.1.min.js",
        "label": "Ember.js 0.9.8.1"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/es5-shim/1.2.4/es5-shim.min.js",
        "label": "ES5 shim 1.2.4"
    },
    {
        "url": [
            "http://extjs.cachefly.net/ext-3.1.0/resources/css/ext-all.css",
            "http://cdnjs.cloudflare.com/ajax/libs/ext-core/3.1.0/ext-core.js"
        ],
        "label": "ext-core 3.1.0"
    },
    {
        "url": "http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js",
        "label": "Knockout 2.1"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/less.js/1.1.3/less-1.1.3.min.js",
        "label": "Less 1.1.3"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.5.2/lodash.min.js",
        "label": "lodash 0.5.2"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.5.3/modernizr.min.js",
        "label": "Modernizr 2.5.3"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.6/prefixfree.min.js",
        "label": "Prefixfree 1.0.6"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/processing.js/1.3.6/processing-api.min.js",
        "label": "Processing 1.3.6"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/raphael/2.0.0/raphael-min.js",
        "label": "Raphaël 2.0.0"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/sammy.js/0.6.3/sammy.min.js",
        "label": "Sammy 0.6.3"
    },
    {
        "url": [
            "http://cdn.sencha.io/touch/1.1.0/resources/css/sencha-touch.css",
            "http://cdn.sencha.io/touch/1.1.0/sencha-touch.js"
        ],
        "label": "Sencha Touch"
    },
    {
        "url": [
            "http://traceur-compiler.googlecode.com/git/src/traceur.js",
            "http://traceur-compiler.googlecode.com/git/src/bootstrap.js"
        ],
        "label": "Traceur"
    },
    {
        "url": "http://remy.github.com/twitterlib/twitterlib.min.js",
        "label": "TwitterLib"
    },
    {
        "url": "http://documentcloud.github.com/underscore/underscore-min.js",
        "label": "underscore 1.3.1"
    },
    {
        "url": "http://cdnjs.cloudflare.com/ajax/libs/zepto/0.7/zepto.min.js",
        "label": "Zepto 0.7"
    },
    {
        "url":[
            "http://code.jquery.com/jquery-1.7.1.min.js",
            " http://canjs.us/release/latest/can.jquery.js"
        ],
        "label": "CanJS 1.0.7 for jQuery"
    }
];

window.libraries = libraries; // expose a command line API

libraries.userSpecified = JSON.parse(localStorage.getItem('libraries') || "[]");
for (var i = 0; i < libraries.userSpecified.length; i++) {
  libraries.push(libraries.userSpecified[i]);
}

libraries.add = function (lib) {
  // save to localStorage
  lib.group = 'Custom';
  this.userSpecified.push(lib);
  try {
    localStorage.setItem('libraries', JSON.stringify(this.userSpecified));
  } catch (e) {} // just in case of DOM_22 error, makes me so sad to use this :(
  libraries.push(lib);
  $('#library').trigger('init');
};

libraries.clear = function () {
  libraries.userSpecified = [];
  localStorage.removeItem('libraries');
  var length = libraries.length;
  for (var i = 0; i < length; i++) {
    if (libraries[i].group === 'Custom') {
      libraries.splice(i, 1);
      length--;
    }
  }
  // force a refresh?
  $('#library').trigger('init');
};
<|endoftext|>


<commit_before>/**
 * @name      ElkArte Forum
 * @copyright ElkArte Forum contributors
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
 *
 * @version 1.0 Beta
 *
 * This file contains javascript associated with the drafts auto function as it
 * relates to an sceditor invocation
 */

(function($, window, document) {
	'use strict';

	function elk_Drafts(options) {
		// All the passed options and defaults are loaded to the opts object
		this.opts = $.extend({}, this.defaults, options);
	};

	/**
	 * Make the call to save this draft in the background
	 * - returns if nothing has changed since the last save or there is nothing to save
	 * - updates the display to show we are saving
	 * - loads the form data and makes the ajax request
	 * - calls onDraftDone to process the xml response, yes XML :P
	 */
	elk_Drafts.prototype.draftSave = function() {
		// No change since the last save, or form submitted
		if (!this.opts._bCheckDraft || elk_formSubmitted)
			return false;

		// Still saving the last one or other?
		if (this.opts._bInDraftMode === true)
			this.draftCancel();

		// Get the editor text, either from sceditor or from the quicktext textarea
		var sPostdata = base.val();

		// Nothing to save?
		if (isEmptyText(sPostdata))
			return false;

		// Flag that we are saving a draft
		document.getElementById('throbber').style.display = '';
		this.opts._bInDraftMode = true;

		// Get the form elements that we want to save
		var aSections = [
			'topic=' + parseInt(document.forms.postmodify.elements['topic'].value),
			'id_draft=' + parseInt(document.forms.postmodify.elements['id_draft'].value),
			'subject=' + escape(document.forms.postmodify['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'message=' + escape(sPostdata.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'icon=' + escape(document.forms.postmodify['icon'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'save_draft=true',
			elk_session_var + '=' + elk_session_id
		];

		// Get the locked an/or sticky values if they have been selected or set that is
		if (this.opts.sType && this.opts.sType === 'post')
		{
			var oLock = document.getElementById('check_lock'),
				oSticky = document.getElementById('check_sticky'),
				oSmile = document.getElementById('check_smileys');

			if (oLock && oLock.checked)
				aSections[aSections.length] = 'lock=1';

			if (oSticky && oSticky.checked)
				aSections[aSections.length] = 'sticky=1';

			if (oSmile && oSmile.checked)
				aSections[aSections.length] = 'ns=1';
		}

		// Keep track of source or wysiwyg when using the full editor
		aSections[aSections.length] = 'message_mode=' + (base.inSourceMode() ? '1' : '0');

		// Send in document for saving and hope for the best
		sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + "action=post2;board=" + this.opts.iBoard + ";xml", aSections.join("&"), this.onDraftDone);

		// Set the flag off so we don't save again (until a keypress indicates they changed the text)
		this.opts._bCheckDraft = false;
	};

	/**
	 * Make the call to save this PM draft in the background
	 * - returns if nothing has changed since the last save or there is nothing to save
	 * - updates the display to show we are saving
	 * - loads the form data and makes the ajax request
	 * - calls onDraftDone to process the xml response, yes XML :P
	 */
	elk_Drafts.prototype.draftPMSave = function ()
	{
		// No change since the last PM save, or elk is doing its thing
		if (!this.opts._bCheckDraft || elk_formSubmitted)
			return false;

		// Still saving the last one or some other?
		if (this.opts._bInDraftMode === true)
			this.draftCancel();

		// Nothing to save
		var sPostdata = base.val();
		if (isEmptyText(sPostdata))
			return false;

		// Flag that we are saving the PM
		document.getElementById('throbber').style.display = '';
		this.opts._bInDraftMode = true;

		// Get the to and bcc values
		var aTo = this.draftGetRecipient('recipient_to[]'),
			aBcc = this.draftGetRecipient('recipient_bcc[]');

		// Get the rest of the form elements that we want to save, and load them up
		var aSections = [
			'replied_to=' + parseInt(document.forms.pmFolder.elements['replied_to'].value),
			'id_pm_draft=' + parseInt(document.forms.pmFolder.elements['id_pm_draft'].value),
			'subject=' + escape(document.forms.pmFolder['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'message=' + escape(sPostdata.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'recipient_to=' + aTo,
			'recipient_bcc=' + aBcc,
			'save_draft=true',
			elk_session_var + '=' + elk_session_id
		];

		// Account for wysiwyg
		if (this.opts.sType && this.opts.sType === 'post')
			aSections[aSections.length] = 'message_mode=' + (base.inSourceMode() ? '1' : '0');

		// Send in (post) the document for saving
		sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + "action=pm;sa=send2;xml", aSections.join("&"), this.onDraftDone);

		// Set the flag as updated
		this.opts._bCheckDraft = false;
	};

	/**
	 * Function to retrieve the to and bcc values from the pseudo arrays
	 *  - Accounts for either a single or multiple to/bcc recipients
	 *
	 * @param {string} sField name of the form elements we are getting
	 */
	elk_Drafts.prototype.draftGetRecipient = function (sField)
	{
		var oRecipient = document.forms.pmFolder.elements[sField],
			aRecipient = [];

		if (typeof(oRecipient) !== 'undefined')
		{
			// Just one recipient
			if ('value' in oRecipient)
				aRecipient.push(parseInt(oRecipient.value));
			else
			{
				// Or many !
				for (var i = 0, n = oRecipient.length; i < n; i++)
					aRecipient.push(parseInt(oRecipient[i].value));
			}
		}

		return aRecipient;
	};

	/**
	 * If another auto save came in with one still pending we cancel out
	 */
	elk_Drafts.prototype.draftCancel = function () {
		// can we do anything at all ... do we want to (e.g. sequence our async events?)
		this.opts._bInDraftMode = false;
		document.getElementById('throbber').style.display = 'none';
	};

	/**
	 * Process the XML response that our save request generated
	 * - updates the display to show last saved on
	 * - closes the draft last saved info box from a "manual" save draft click
	 * - hides the ajax saving icon
	 * - turns off _bInDraftMode so another save request can fire
	 */
	elk_Drafts.prototype.onDraftDone = function (XMLDoc) {
		// If it is not valid then clean up
		if (!XMLDoc || !XMLDoc.getElementsByTagName('draft')[0])
			return this.draftCancel();

		// Grab the returned draft id and saved time from the response
		this.opts._sCurDraftId = XMLDoc.getElementsByTagName('draft')[0].getAttribute('id');
		this.opts._sLastSaved = XMLDoc.getElementsByTagName('draft')[0].childNodes[0].nodeValue;

		// Update the form to show we finished, if the id is not set, then set it
		document.getElementById(this.opts.sLastID).value = this.opts._sCurDraftId;
		document.getElementById(this.opts.sLastNote).innerHTML = this.opts._sLastSaved;

		// Hide the saved draft successbox in the event they pressed the save draft button at some point
		var draft_section = document.getElementById('draft_section');
		if (draft_section)
			draft_section.style.display = 'none';

		// Thank you sir, may I have another
		this.opts._bInDraftMode = false;
		document.getElementById('throbber').style.display = 'none';
	};

	/**
	 * Private draft vars to keep track of what/where/why
	 */
	elk_Drafts.prototype.defaults = {
		/**
		 * If we are currently in draft saving mode
		 * @type {Boolean}
		 */
		_bInDraftMode: false,

		/**
		 * The id of the draft so it save/appends
		 * @type {String}
		 */
		_sCurDraftId: null,

		/**
		 * How often we are going to save a draft in the background
		 * @type {Integer}
		 */
		_interval_id: null,

		/**
		 * The text to place in the last saved Div, comes from the xml response
		 * @type {String}
		 */
		_sLastSaved: null,

		/**
		 * If the user has pressed a key since the last save
		 * @type {String}
		 */
		_bCheckDraft: false
	};

	/**
	 * Holds all  current draft options (defaults + passed options)
	 */
	elk_Drafts.prototype.opts = {};

	/**
	 * Starts the autosave timer for the current instance of the elk_draft object
	 */
	elk_Drafts.prototype.startSaver = function () {
		var oInstance = this;
		if (this.opts.bPM)
			this.opts._interval_id = setInterval(function(){oInstance.draftPMSave();}, this.opts.iFreq);
		else
			this.opts._interval_id = setInterval(function(){oInstance.draftSave();}, this.opts.iFreq);
	};

	/**
	 * Draft plugin interface to SCEditor
	 *  - Called from the editor as a plugin
	 *  - Monitors events so we control the elk_draft autosaver (on/off/change)
	 */
	$.sceditor.plugins.draft = function() {
		var base = this,
			oDrafts;

		/**
		 * Initialize, called when sceditor starts and initializes plugins
		 */
		base.init = function() {
			// Init the draft instance, load in the options
			oDrafts = new elk_Drafts(this.opts.draftOptions);
			oDrafts.opts.bPM = oDrafts.opts.bPM ? true : false;

			// Start the autosave timer
			if (oDrafts.opts.iFreq > 0)
				oDrafts.startSaver();
		};

		/**
		 * Used to ensure the autosave timer is running when the editor window
		 * (wiz or source) re-gains focus
		 */
		base.signalFocusEvent = function() {
			if (oDrafts.opts._interval_id === "")
				oDrafts.startSaver();
		};

		/**
		 * Moved away from the editor, where did you go?
		 * - Turns off the autosave timer when the user moves the focus away
		 * - Saves the current content before turning off the autosaver
		 */
		base.signalBlurEvent = function() {
			if (oDrafts.opts.bPM)
				oDrafts.draftPMSave();
			else
				oDrafts.draftSave();

			// turn it off if we can, mark it as such
			if (oDrafts.opts._interval_id !== "")
				clearInterval(oDrafts.opts._interval_id);
			oDrafts.opts._interval_id = "";
		};

		/**
		 * Informs the autosave function that some activity has occurred in the
		 * editor window since the last save ... activity being any keypress
		 * in the editor which we assume means they changed it
		 */
		base.signalKeypressEvent = function() {
			oDrafts.opts._bCheckDraft = true;
		};
	};

})(jQuery, window, document);<commit_msg>! missing doc block param<commit_after>/**
 * @name      ElkArte Forum
 * @copyright ElkArte Forum contributors
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
 *
 * @version 1.0 Beta
 *
 * This file contains javascript associated with the drafts auto function as it
 * relates to an sceditor invocation
 */

(function($, window, document) {
	'use strict';

	function elk_Drafts(options) {
		// All the passed options and defaults are loaded to the opts object
		this.opts = $.extend({}, this.defaults, options);
	}

	/**
	 * Make the call to save this draft in the background
	 * - returns if nothing has changed since the last save or there is nothing to save
	 * - updates the display to show we are saving
	 * - loads the form data and makes the ajax request
	 * - calls onDraftDone to process the xml response, yes XML :P
	 */
	elk_Drafts.prototype.draftSave = function() {
		// No change since the last save, or form submitted
		if (!this.opts._bCheckDraft || elk_formSubmitted)
			return false;

		// Still saving the last one or other?
		if (this.opts._bInDraftMode === true)
			this.draftCancel();

		// Get the editor text, either from sceditor or from the quicktext textarea
		var sPostdata = base.val();

		// Nothing to save?
		if (isEmptyText(sPostdata))
			return false;

		// Flag that we are saving a draft
		document.getElementById('throbber').style.display = '';
		this.opts._bInDraftMode = true;

		// Get the form elements that we want to save
		var aSections = [
			'topic=' + parseInt(document.forms.postmodify.elements['topic'].value),
			'id_draft=' + parseInt(document.forms.postmodify.elements['id_draft'].value),
			'subject=' + escape(document.forms.postmodify['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'message=' + escape(sPostdata.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'icon=' + escape(document.forms.postmodify['icon'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'save_draft=true',
			elk_session_var + '=' + elk_session_id
		];

		// Get the locked an/or sticky values if they have been selected or set that is
		if (this.opts.sType && this.opts.sType === 'post')
		{
			var oLock = document.getElementById('check_lock'),
				oSticky = document.getElementById('check_sticky'),
				oSmile = document.getElementById('check_smileys');

			if (oLock && oLock.checked)
				aSections[aSections.length] = 'lock=1';

			if (oSticky && oSticky.checked)
				aSections[aSections.length] = 'sticky=1';

			if (oSmile && oSmile.checked)
				aSections[aSections.length] = 'ns=1';
		}

		// Keep track of source or wysiwyg when using the full editor
		aSections[aSections.length] = 'message_mode=' + (base.inSourceMode() ? '1' : '0');

		// Send in document for saving and hope for the best
		sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + "action=post2;board=" + this.opts.iBoard + ";xml", aSections.join("&"), this.onDraftDone);

		// Set the flag off so we don't save again (until a keypress indicates they changed the text)
		this.opts._bCheckDraft = false;
	};

	/**
	 * Make the call to save this PM draft in the background
	 * - returns if nothing has changed since the last save or there is nothing to save
	 * - updates the display to show we are saving
	 * - loads the form data and makes the ajax request
	 * - calls onDraftDone to process the xml response, yes XML :P
	 */
	elk_Drafts.prototype.draftPMSave = function ()
	{
		// No change since the last PM save, or elk is doing its thing
		if (!this.opts._bCheckDraft || elk_formSubmitted)
			return false;

		// Still saving the last one or some other?
		if (this.opts._bInDraftMode === true)
			this.draftCancel();

		// Nothing to save
		var sPostdata = base.val();
		if (isEmptyText(sPostdata))
			return false;

		// Flag that we are saving the PM
		document.getElementById('throbber').style.display = '';
		this.opts._bInDraftMode = true;

		// Get the to and bcc values
		var aTo = this.draftGetRecipient('recipient_to[]'),
			aBcc = this.draftGetRecipient('recipient_bcc[]');

		// Get the rest of the form elements that we want to save, and load them up
		var aSections = [
			'replied_to=' + parseInt(document.forms.pmFolder.elements['replied_to'].value),
			'id_pm_draft=' + parseInt(document.forms.pmFolder.elements['id_pm_draft'].value),
			'subject=' + escape(document.forms.pmFolder['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'message=' + escape(sPostdata.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
			'recipient_to=' + aTo,
			'recipient_bcc=' + aBcc,
			'save_draft=true',
			elk_session_var + '=' + elk_session_id
		];

		// Account for wysiwyg
		if (this.opts.sType && this.opts.sType === 'post')
			aSections[aSections.length] = 'message_mode=' + (base.inSourceMode() ? '1' : '0');

		// Send in (post) the document for saving
		sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + "action=pm;sa=send2;xml", aSections.join("&"), this.onDraftDone);

		// Set the flag as updated
		this.opts._bCheckDraft = false;
	};

	/**
	 * Function to retrieve the to and bcc values from the pseudo arrays
	 *  - Accounts for either a single or multiple to/bcc recipients
	 *
	 * @param {string} sField name of the form elements we are getting
	 */
	elk_Drafts.prototype.draftGetRecipient = function (sField)
	{
		var oRecipient = document.forms.pmFolder.elements[sField],
			aRecipient = [];

		if (typeof(oRecipient) !== 'undefined')
		{
			// Just one recipient
			if ('value' in oRecipient)
				aRecipient.push(parseInt(oRecipient.value));
			else
			{
				// Or many !
				for (var i = 0, n = oRecipient.length; i < n; i++)
					aRecipient.push(parseInt(oRecipient[i].value));
			}
		}

		return aRecipient;
	};

	/**
	 * If another auto save came in with one still pending we cancel out
	 */
	elk_Drafts.prototype.draftCancel = function () {
		// can we do anything at all ... do we want to (e.g. sequence our async events?)
		this.opts._bInDraftMode = false;
		document.getElementById('throbber').style.display = 'none';
	};

	/**
	 * Process the XML response that our save request generated
	 * - updates the display to show last saved on
	 * - closes the draft last saved info box from a "manual" save draft click
	 * - hides the ajax saving icon
	 * - turns off _bInDraftMode so another save request can fire
	 *
	 * @param {xml object} XMLDoc
	 */
	elk_Drafts.prototype.onDraftDone = function (XMLDoc) {
		// If it is not valid then clean up
		if (!XMLDoc || !XMLDoc.getElementsByTagName('draft')[0])
			return this.draftCancel();

		// Grab the returned draft id and saved time from the response
		this.opts._sCurDraftId = XMLDoc.getElementsByTagName('draft')[0].getAttribute('id');
		this.opts._sLastSaved = XMLDoc.getElementsByTagName('draft')[0].childNodes[0].nodeValue;

		// Update the form to show we finished, if the id is not set, then set it
		document.getElementById(this.opts.sLastID).value = this.opts._sCurDraftId;
		document.getElementById(this.opts.sLastNote).innerHTML = this.opts._sLastSaved;

		// Hide the saved draft successbox in the event they pressed the save draft button at some point
		var draft_section = document.getElementById('draft_section');
		if (draft_section)
			draft_section.style.display = 'none';

		// Thank you sir, may I have another
		this.opts._bInDraftMode = false;
		document.getElementById('throbber').style.display = 'none';
	};

	/**
	 * Private draft vars to keep track of what/where/why
	 */
	elk_Drafts.prototype.defaults = {
		/**
		 * If we are currently in draft saving mode
		 * @type {Boolean}
		 */
		_bInDraftMode: false,

		/**
		 * The id of the draft so it save/appends
		 * @type {String}
		 */
		_sCurDraftId: null,

		/**
		 * How often we are going to save a draft in the background
		 * @type {Integer}
		 */
		_interval_id: null,

		/**
		 * The text to place in the last saved Div, comes from the xml response
		 * @type {String}
		 */
		_sLastSaved: null,

		/**
		 * If the user has pressed a key since the last save
		 * @type {String}
		 */
		_bCheckDraft: false
	};

	/**
	 * Holds all  current draft options (defaults + passed options)
	 */
	elk_Drafts.prototype.opts = {};

	/**
	 * Starts the autosave timer for the current instance of the elk_draft object
	 */
	elk_Drafts.prototype.startSaver = function () {
		var oInstance = this;
		if (this.opts.bPM)
			this.opts._interval_id = setInterval(function(){oInstance.draftPMSave();}, this.opts.iFreq);
		else
			this.opts._interval_id = setInterval(function(){oInstance.draftSave();}, this.opts.iFreq);
	};

	/**
	 * Draft plugin interface to SCEditor
	 *  - Called from the editor as a plugin
	 *  - Monitors events so we control the elk_draft autosaver (on/off/change)
	 */
	$.sceditor.plugins.draft = function() {
		var base = this,
			oDrafts;

		/**
		 * Initialize, called when sceditor starts and initializes plugins
		 */
		base.init = function() {
			// Init the draft instance, load in the options
			oDrafts = new elk_Drafts(this.opts.draftOptions);
			oDrafts.opts.bPM = oDrafts.opts.bPM ? true : false;

			// Start the autosave timer
			if (oDrafts.opts.iFreq > 0)
				oDrafts.startSaver();
		};

		/**
		 * Used to ensure the autosave timer is running when the editor window
		 * (wiz or source) re-gains focus
		 */
		base.signalFocusEvent = function() {
			if (oDrafts.opts._interval_id === "")
				oDrafts.startSaver();
		};

		/**
		 * Moved away from the editor, where did you go?
		 * - Turns off the autosave timer when the user moves the focus away
		 * - Saves the current content before turning off the autosaver
		 */
		base.signalBlurEvent = function() {
			if (oDrafts.opts.bPM)
				oDrafts.draftPMSave();
			else
				oDrafts.draftSave();

			// turn it off if we can, mark it as such
			if (oDrafts.opts._interval_id !== "")
				clearInterval(oDrafts.opts._interval_id);
			oDrafts.opts._interval_id = "";
		};

		/**
		 * Informs the autosave function that some activity has occurred in the
		 * editor window since the last save ... activity being any keypress
		 * in the editor which we assume means they changed it
		 */
		base.signalKeypressEvent = function() {
			oDrafts.opts._bCheckDraft = true;
		};
	};

})(jQuery, window, document);<|endoftext|>


<commit_before>var PageApp = new Backbone.Marionette.Application();

PageApp.commands.setHandler("postContents", function(){
  var ce = $("
").html($("#content").html());
  if($.browser.webkit)
    ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
  if($.browser.msie)
    ce.find("p").replaceWith(function() { return this.innerHTML + "
"; });
  if($.browser.mozilla || $.browser.opera ||$.browser.msie )
    ce.find("br").replaceWith("\n");

  page = new Page({
    name: $("#pagenameinput").val(),
    content: ce.text()
  });
  page.url = function(){ return $("#contents").attr("action"); };
  page.save();
});

PageApp.addRegions({
  titleRegion: "#pagetitle",
  contentRegion: "#content"
});

var Page = Backbone.Model.extend({
  urlRoot: '/pages',

  initialize: function(){
    this.on("change:name", function(){
      localStorage.setItem("recentPages", JSON.stringify(this));
    });
  }
});

$("#pagenameform").submit(function(e){
  PageApp.execute("postContents");
  $("#pagename").text($("#pagenameinput").val());
  $("#pagename").show();
  $("#pagenameform").hide();
  return false;
});

$("#contents").submit(function(e){
  PageApp.execute("postContents");
  return false;
});

var PageNameView = Marionette.ItemView.extend({
  el: '#pagename',

  template: false,

  initialize: function(){
    this.model.set("name", $("#pagenameinput").val());
    this.listenTo(this.model, "change:name", this.modelNameChanged);
  },

  events: {
    'click': 'showPageForm'
  },

  modelNameChanged: function(model, value){
    this.$el.html(value);
  },

  showPageForm: function(){
    this.$el.hide();
    var that = this;
    $("#pagenameform").show().focusout(function(){
      that.model.set("name", $("#pagenameinput").val());
      $("#pagenameform").hide();
      that.$el.show();
    }).click(function(){ return false; });
    setTimeout(function(){
      $("#pagenameinput").focus();
    }, 0);
  }
});

var PageNameFormView = Marionette.ItemView.extend({
  el: '#pagenameform',

  template: false
});

var PageContentView = Marionette.ItemView.extend({
  el: '#content',

  template: false,

  focus: function() {
    this.$el.focus();
  }
});

$(function (){
  var recentPage = localStorage.getItem("recentPages");
  if(recentPage !== null){
    $("#seen ul").append("
"+JSON.parse(recentPage).name+"
");
  }

  PageApp.titleRegion.attachView(new PageNameView({
    model: new Page()
  }));
  PageApp.titleRegion.attachView(new PageNameFormView());
  var pageContentView = new PageContentView();
  pageContentView.focus();
  PageApp.contentRegion.attachView(pageContentView);

  $("body").click(function(){
    pageContentView.focus();
  });
});
<commit_msg>don't create new Page for each time page will be saved<commit_after>var PageApp = new Backbone.Marionette.Application();

PageApp.model = new Page();

PageApp.commands.setHandler("postContents", function(){
  var ce = $("
").html($("#content").html());
  if($.browser.webkit)
    ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
  if($.browser.msie)
    ce.find("p").replaceWith(function() { return this.innerHTML + "
"; });
  if($.browser.mozilla || $.browser.opera ||$.browser.msie )
    ce.find("br").replaceWith("\n");

  PageApp.model.set({
    name: $("#pagenameinput").val(),
    content: ce.text()
  });
  PageApp.model.url = function(){ return $("#contents").attr("action"); };
  PageApp.model.save();
});

PageApp.addRegions({
  titleRegion: "#pagetitle",
  contentRegion: "#content"
});

var Page = Backbone.Model.extend({
  urlRoot: '/pages',

  initialize: function(){
    this.on("change:name", function(){
      localStorage.setItem("recentPages", JSON.stringify(this));
    });
  }
});

$("#pagenameform").submit(function(e){
  PageApp.execute("postContents");
  $("#pagename").text($("#pagenameinput").val());
  $("#pagename").show();
  $("#pagenameform").hide();
  return false;
});

$("#contents").submit(function(e){
  PageApp.execute("postContents");
  return false;
});

var PageNameView = Marionette.ItemView.extend({
  el: '#pagename',

  template: false,

  initialize: function(){
    this.model.set("name", $("#pagenameinput").val());
    this.listenTo(this.model, "change:name", this.modelNameChanged);
  },

  events: {
    'click': 'showPageForm'
  },

  modelNameChanged: function(model, value){
    this.$el.html(value);
  },

  showPageForm: function(){
    this.$el.hide();
    var that = this;
    $("#pagenameform").show().focusout(function(){
      that.model.set("name", $("#pagenameinput").val());
      $("#pagenameform").hide();
      that.$el.show();
    }).click(function(){ return false; });
    setTimeout(function(){
      $("#pagenameinput").focus();
    }, 0);
  }
});

var PageNameFormView = Marionette.ItemView.extend({
  el: '#pagenameform',

  template: false
});

var PageContentView = Marionette.ItemView.extend({
  el: '#content',

  template: false,

  focus: function() {
    this.$el.focus();
  }
});

$(function (){
  var recentPage = localStorage.getItem("recentPages");
  if(recentPage !== null){
    $("#seen ul").append("
"+JSON.parse(recentPage).name+"
");
  }

  PageApp.titleRegion.attachView(new PageNameView({
    model: new Page()
  }));
  PageApp.titleRegion.attachView(new PageNameFormView());
  var pageContentView = new PageContentView();
  pageContentView.focus();
  PageApp.contentRegion.attachView(pageContentView);

  $("body").click(function(){
    pageContentView.focus();
  });
});
<|endoftext|>


<commit_before>/**
 * garp.welcomepanel.js
 *
 * Convenience Class, creates a panel with a message from HTML markup in de view.
 *
 * @class Garp.WelcomePanel
 * @extends Panel
 * @author Peter
 */

Garp.WelcomePanel = function(cfg){
	this.html = Ext.getDom('welcome-panel-content').innerHTML;
	Garp.WelcomePanel.superclass.constructor.call(this, cfg);
};

Ext.extend(Garp.WelcomePanel, Ext.Container, {
	border: true
	/*,
	hideButtonArr: ['fileMenu', 'editMenu', 'viewMenu'],
	listeners: {
		'render': function(){
			Ext.each(this.hideButtonArr, function(item){
				Garp.toolbar[item].hide();
			});
			this.getEl().fadeIn({duration:2.2});
			if (Garp.viewport && Garp.viewport.formPanelCt) {
				Garp.viewport.formPanelCt.hide();
			}
		},
		'destroy': function(){
			Ext.each(this.hideButtonArr, function(item){
				Garp.toolbar[item].show();
			});
			if (Garp.viewport && Garp.viewport.formPanelCt) {
				Garp.viewport.formPanelCt.show();
			}
		}
	}*/
});<commit_msg>Hide new / delete button on welcome page<commit_after>/**
 * garp.welcomepanel.js
 *
 * Convenience Class, creates a panel with a message from HTML markup in de view.
 *
 * @class Garp.WelcomePanel
 * @extends Panel
 * @author Peter
 */

Garp.WelcomePanel = function(cfg){
	this.html = Ext.getDom('welcome-panel-content').innerHTML;
	Garp.WelcomePanel.superclass.constructor.call(this, cfg);
};

Ext.extend(Garp.WelcomePanel, Ext.Container, {
	border: true,
	hideButtonArr: ['newButton', 'deleteButton', 'separator'],
	listeners: {
		'render': function () {
			Ext.each(this.hideButtonArr, function(item){
				Garp.toolbar[item].hide();
			});
		},
		'destroy': function () {
			Ext.each(this.hideButtonArr, function(item){
				Garp.toolbar[item].show();
			});
		}
	}
});
<|endoftext|>


<commit_before>/** Рейтинг заметок в виде звезд jquery.rating.js
 *  http://biznesguide.ru/coding/156.html
 *  Copyright (c) 2011 Шамшур Иван (http://twitter.com/ivanshamshur)
 *  Dual licensed under the MIT and GPL licenses
 */

;(function ($) {

    $.ratingReviews = function (e, o) {

        this.options = $.extend({
            fx: 'float',
            image: '/images/stars.png',
            stars: 5,
            minimal: 0,
            titles: ['голос', 'голоса', 'голосов'],
            readOnly: false,
            url: '',
            type: 'post',
            loader: '/images/ajax-loader.gif',
            click: function () {
            },
            callback: function () {
            }
        }, o || {});

        this.el = $(e);
        this.left = 0;
        this.width = 0;
        this.height = 0;
        this._data = {};

        var self = this;

        this.el.find(':hidden').each(function () {

            var $this = $(this);
            self._data[$this.attr('name')] = $this.val();

        });

        this._data.val = parseFloat(this._data.val) || 0;
        this._data.votes = parseFloat(this._data.votes) || '';

        if (this._data.val > this.options.stars) this._data.val = this.options.stars;
        if (this._data.val < 0) this._data.val = 0;

        this.old = this._data.val;

        this.vote_wrap = $('

');
        this.vote_block = $('

');
        this.vote_hover = $('

');
        this.vote_stars = $('

');
        this.vote_active = $('

');
        this.vote_result = $('

');
        this.vote_success = $('

');
        this.loader = $('');

        this.el.html(this.loader);

        //Загружаем изображение звезд и высчитываем ширину и высоту одной звезды
        var img = new Image();
        img.src = this.options.image;
        img.onload = function () {
            self.width = this.width; //Ширина одной звезды
            self.height = this.height / 3; //Высота одной звезды
            self.init();
        };

    };

    var $r = $.ratingReviews;

    $r.fn = $r.prototype = {
        ratingReviews: '2.0'
    };

    $r.fn.extend = $r.extend = $.extend;

    $r.fn.extend({

        init: function () {

            this.render();

            if (this.options.readOnly) return;

            var self = this, left = 0, width = 0;

            this.vote_hover.bind('mousemove mouseover', function (e) {

                if (self.options.readOnly) return;

                var $this = $(this),
                    score = 0;

                left = e.clientX > 0 ? e.clientX : e.pageX;
                width = left - $this.offset().left - 2;

                var max = self.width * self.options.stars,
                    min = self.options.minimal * self.width;

                if (width > max) width = max;
                if (width < min) width = min;

                score = Math.round(width / self.width * 10) / 10; //округляем до 1 знака после запятой

                if (self.options.fx == 'half') {
                    width = Math.ceil(width / self.width * 2) * self.width / 2;
                }
                else if (self.options.fx != 'float') {
                    width = Math.ceil(width / self.width) * self.width;
                }

                score = Math.round(width / self.width * 10) / 10;

                self.vote_active.css({
                    'width': width,
                    'background-position': 'left center'
                });

            })
                .bind('mouseout', function () {
                    if (self.options.readOnly) return;
                    self.reset();
                    self.vote_success.empty();
                }).bind('click.ratingReviews', function () {

                if (self.options.readOnly) return;

                var score = Math.round(width / self.width * 10) / 10;

                if (score > self.options.stars) score = self.options.stars;
                if (score < 0) score = 0;

                self.old = self._data.val;
                self._data.val = (self._data.val * self._data.votes + score) / (self._data.votes + 1);
                self._data.val = Math.round(self._data.val * 100) / 100;
                self._data.score = score;
                $("#modal__ratingReviews").val(score);
                self.options.readOnly = true;
                self.options.click.apply(this, [score]);
            });

        },
        set: function () {
            this.vote_active.css({
                'width': this._data.val * this.width,
                'background-position': 'left bottom'
            });
        },
        reset: function () {
            this.vote_active.css({
                'width': this.old * this.width,
                'background-position': 'left bottom'
            });
        },
        setvoters: function () {
            this.vote_result.html(this.declOfNum(this._data.votes));
        },
        render: function () {

            this.el.html(this.vote_wrap.append(
                this.vote_hover.css({
                    padding: '0 4px',
                    height: this.height,
                    width: this.width * this.options.stars
                }),
                this.vote_result.text(this.declOfNum(this._data.votes)),
                this.vote_success
            ));

            this.vote_block.append(
                this.vote_stars.css({
                    height: this.height,
                    width: this.width * this.options.stars,
                    background: "url('" + this.options.image + "') left top"
                }),
                this.vote_active.css({
                    height: this.height,
                    width: this._data.val * this.width,
                    background: "url('" + this.options.image + "') left bottom"
                })
            ).appendTo(this.vote_hover);

        },
        send: function (score) {

            var self = this;
            this.vote_result.html(this.loader);

            this._data.votes++;

            $.ajax({
                url: self.options.url,
                type: self.options.type,
                data: this._data,
                dataType: 'json',
                success: function (data) {
                    if (data.status == 'OK') {

                        self.set();
                    }
                    else {
                        self._data.votes--;
                        self.reset();
                    }

                    self.setvoters();

                    if (data.msg)self.vote_success.html(data.msg);

                    if (typeof self.options.callback == 'function') {

                        self.options.callback.apply(self, [data]);
                    }
                }
            });

        },
        declOfNum: function (number) {
            if (number <= 0) return '';
            number = Math.abs(Math.floor(number));
            cases = [2, 0, 1, 1, 1, 2];
            return number + ' ' + this.options.titles[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];
        }
    });

    $.fn.ratingReviews = function (o) {

        if (typeof o == 'string') {
            var instance = $(this).data('ratingReviews'), args = Array.prototype.slice.call(arguments, 1);
            return instance[o].apply(instance, args);
        } else {
            return this.each(function () {
                var instance = $(this).data('ratingReviews');
                if (instance) {
                    if (o) {
                        $.extend(instance.options, o);
                    }

                    instance.init();

                } else {

                    $(this).data('ratingReviews', new $r(this, o));
                }
            });
        }
    };

})(jQuery);<commit_msg>fixed<commit_after>/** Рейтинг заметок в виде звезд jquery.rating.js
 *  http://biznesguide.ru/coding/156.html
 *  Copyright (c) 2011 Шамшур Иван (http://twitter.com/ivanshamshur)
 *  Dual licensed under the MIT and GPL licenses
 */

;(function ($) {

    $.ratingReviews = function (e, o) {

        this.options = $.extend({
            fx: 'float',
            image: '/images/stars.png',
            stars: 5,
            minimal: 0,
            titles: ['голос', 'голоса', 'голосов'],
            readOnly: false,
            url: '',
            type: 'post',
            loader: '/images/ajax-loader.gif',
            click: function () {
            },
            callback: function () {
            }
        }, o || {});

        this.el = $(e);
        this.left = 0;
        this.width = 0;
        this.height = 0;
        this._data = {};

        var self = this;

        this.el.find(':hidden').each(function () {

            var $this = $(this);
            self._data[$this.attr('name')] = $this.val();

        });

        this._data.val = parseFloat(this._data.val) || 0;
        this._data.votes = parseFloat(this._data.votes) || '';

        if (this._data.val > this.options.stars) this._data.val = this.options.stars;
        if (this._data.val < 0) this._data.val = 0;

        this.old = this._data.val;

        this.vote_wrap = $('

');
        this.vote_block = $('

');
        this.vote_hover = $('

');
        this.vote_stars = $('

');
        this.vote_active = $('

');
        this.vote_result = $('

');
        this.vote_success = $('

');
        this.loader = $('');

        this.el.html(this.loader);

        //Загружаем изображение звезд и высчитываем ширину и высоту одной звезды
        var img = new Image();
        img.src = this.options.image;
        img.onload = function () {
            self.width = this.width; //Ширина одной звезды
            self.height = this.height / 3; //Высота одной звезды
            self.init();
        };

    };

    var $r = $.ratingReviews;

    $r.fn = $r.prototype = {
        ratingReviews: '2.0'
    };

    $r.fn.extend = $r.extend = $.extend;

    $r.fn.extend({

        init: function () {

            this.render();

            if (this.options.readOnly) return;

            var self = this, left = 0, width = 0;
        },
        set: function () {
            this.vote_active.css({
                'width': this._data.val * this.width,
                'background-position': 'left bottom'
            });
        },
        reset: function () {
            this.vote_active.css({
                'width': this.old * this.width,
                'background-position': 'left bottom'
            });
        },
        setvoters: function () {
            this.vote_result.html(this.declOfNum(this._data.votes));
        },
        render: function () {

            this.el.html(this.vote_wrap.append(
                this.vote_hover.css({
                    padding: '0 4px',
                    height: this.height,
                    width: this.width * this.options.stars
                }),
                this.vote_result.text(this.declOfNum(this._data.votes)),
                this.vote_success
            ));

            this.vote_block.append(
                this.vote_stars.css({
                    height: this.height,
                    width: this.width * this.options.stars,
                    background: "url('" + this.options.image + "') left top"
                }),
                this.vote_active.css({
                    height: this.height,
                    width: this._data.val * this.width,
                    background: "url('" + this.options.image + "') left bottom"
                })
            ).appendTo(this.vote_hover);

        },
        send: function (score) {

            var self = this;
            this.vote_result.html(this.loader);

            this._data.votes++;

            $.ajax({
                url: self.options.url,
                type: self.options.type,
                data: this._data,
                dataType: 'json',
                success: function (data) {
                    if (data.status == 'OK') {

                        self.set();
                    }
                    else {
                        self._data.votes--;
                        self.reset();
                    }

                    self.setvoters();

                    if (data.msg)self.vote_success.html(data.msg);

                    if (typeof self.options.callback == 'function') {

                        self.options.callback.apply(self, [data]);
                    }
                }
            });

        },
        declOfNum: function (number) {
            if (number <= 0) return '';
            number = Math.abs(Math.floor(number));
            cases = [2, 0, 1, 1, 1, 2];
            return number + ' ' + this.options.titles[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];
        }
    });

    $.fn.ratingReviews = function (o) {

        if (typeof o == 'string') {
            var instance = $(this).data('ratingReviews'), args = Array.prototype.slice.call(arguments, 1);
            return instance[o].apply(instance, args);
        } else {
            return this.each(function () {
                var instance = $(this).data('ratingReviews');
                if (instance) {
                    if (o) {
                        $.extend(instance.options, o);
                    }

                    instance.init();

                } else {

                    $(this).data('ratingReviews', new $r(this, o));
                }
            });
        }
    };

})(jQuery);<|endoftext|>


<commit_before>var WO = WO || {};

WO.SynthFactory = function(){

    var synthOptions = {
        "portamento" : 0.05,
        "oscillator" : {
            "type" : "square"
        },
        "filter": {
            "Q": 6,
            "type": "lowpass",
            "rolloff": -24
        },
        "envelope": {
            "attack": 0.005,
            "decay": 0.01,
            "sustain": 0.9,
            "release": 0.001
        },
        "filterEnvelope": {
            "attack": 0.006,
            "decay": 0.02,
            "sustain": 0.5,
            "release": 0.001,
            "min": 10,
            "max": 4000
        }
    };

    var synth = new Tone.MonoSynth(synthOptions);

    synth.octave = 4;
    synth.setVolume(-25);
    synth.toMaster();

    return synth;
};<commit_msg>change to polysynth<commit_after>var WO = WO || {};

WO.SynthFactory = function(){

    var synthOptions = {
        "portamento" : 0.05,
        "oscillator" : {
            "type" : "square"
        },
        "filter": {
            "Q": 6,
            "type": "lowpass",
            "rolloff": -24
        },
        "envelope": {
            "attack": 0.005,
            "decay": 0.01,
            "sustain": 0.9,
            "release": 0.001
        },
        "filterEnvelope": {
            "attack": 0.006,
            "decay": 0.02,
            "sustain": 0.5,
            "release": 0.001,
            "min": 10,
            "max": 4000
        }
    };

    var synth = new Tone.PolySynth(6, Tone.MonoSynth);
    synth.set(synthOptions);

    synth.octave = 4;
    synth.setVolume(-25);
    synth.toMaster();

    return synth;
};<|endoftext|>


<commit_before>define(['jquery', 'd3', 'util/dragbox'], function ($, d3, DragBox) {
    var MAX_CELLS = 24000;
    var MIN_CELL_SIZE = 3;
    var MAX_CELL_SIZE = 12;
    var DEFAULT_BORDER_WIDTH = 0.5;
	function Heatmap(options) {
        var self = this;
        options = (options || {});
        options.borderWidth = (options.borderWidth || DEFAULT_BORDER_WIDTH);
        options.colorscheme = (options.colorscheme || 'RdYlBu');
        var element = $(options.element);

        var matrix = [];
        var rowIndex = {}; var numRows = 0;
        var colIndex = {}; var numCols = 0;

        var cellSize = options.cellSize || 5;

	    var width = element.width();
	    var height = element.height();
        var minDim = Math.min(width, height);

        self.setData = function (data) {
            if (data == null) return;
            function requiredProperty(prop) {
                if (!data.hasOwnProperty(prop)) {
                    throw new Error("setData(): Required property '"
                        + prop + "' not found");
                }
            }
            requiredProperty('matrix');
            requiredProperty('rows');
            rows = data.rows;
            if (!data.hasOwnProperty('columns')) {
                columns = rows;
            }
            matrix = data.matrix;
            if (matrix.length > MAX_CELLS) {
                throw new Error("Too many cells");
            }
        };

        function adjustedDim(arr) {
            return Math.floor(arr.length *
                (cellSize + options.borderWidth));
        }
        self.display = function () {
            element.css("position", "relative");
            cellSize = Math.min(MAX_CELL_SIZE,
                Math.max(MIN_CELL_SIZE,
                    (minDim - options.borderWidth * (rows.length+1)) /
                         rows.length)
                );
            var adjWidth  = adjustedDim(columns);
            var adjHeight = adjustedDim(rows);
            var containerId = element.attr('id') + "-container";
            var container = $("<div>").attr("id", containerId)
                .css("position", "relative")
                .width(adjWidth)
                .height(adjHeight);
            element.append(container);
    	    var svg  = d3.select("#" + containerId).append("svg")
    	        .attr("class", options.colorscheme)
    	        .attr("width", adjWidth)
    	        .attr("height", adjHeight);
    	    var quantize = d3.scale
                .quantile().domain([0, 1]).range(d3.range(9));
            var dragbox = new DragBox(container);
            dragbox.textHandler(function (x, y, w, h) {
                return [w, h].join(" ");
            })

            for (var i = 0; i < matrix.length; i++) {
                var cell = matrix[i];
                var row = cell[0];
                var col = cell[1];
                svg.append("rect")
                    .attr("width", cellSize).attr("height", cellSize)
                    .attr("x", options.borderWidth * (row + 1) + cellSize * row)
                    .attr("y", options.borderWidth * (col + 1) + cellSize * col)
                    .attr("class", "q" + quantize(cell[2]) + "-9")
                    .append("title").text(cell[2]);
            }
            var schemeIndex = 0;
            var schemes = 'RdYlBu Spectral BrBG YlGnBu'.split(" ");
            for (var i in schemes) {
                if (schemes[i] == options.colorscheme) {
                    schemes.splice(i, 1);
                    break;
                }
            }
            schemes.unshift(options.colorscheme);
            // element.append($("<button>")
            //     .addClass("btn btn-mini").text("Change Scheme")
            //     .on('click', function () {
            //         schemeIndex = (schemeIndex + 1) % schemes.length;
            //         svg.attr("class", schemes[schemeIndex]);
            //     }
            // ));
        }
        return self;
	}
	return Heatmap;
});<commit_msg>More refactoring. Almost there.<commit_after>define(['jquery', 'd3', 'util/dragbox'], function ($, d3, DragBox) {
    var MAX_CELLS = 24000;
    var MIN_CELL_SIZE = 3;
    var MAX_CELL_SIZE = 12;
    var DEFAULT_BORDER_WIDTH = 0.5;
	function Heatmap(options) {
        var self = this;
        options = (options || {});
        options.borderWidth = (options.borderWidth || DEFAULT_BORDER_WIDTH);
        options.colorscheme = (options.colorscheme || 'RdYlBu');
        var element = $(options.element);

        var matrix = [];
        var rowIndex = {}; var numRows = 0;
        var colIndex = {}; var numCols = 0;

        var cellSize = options.cellSize || 5;

	    var width = element.width();
	    var height = element.height();
        var minDim = Math.min(width, height);

        self.setData = function (data) {
            if (data == null) return;
            function requiredProperty(prop) {
                if (!data.hasOwnProperty(prop)) {
                    throw new Error("setData(): Required property '"
                        + prop + "' not found");
                }
            }
            requiredProperty('matrix');
            requiredProperty('rows');
            rows = data.rows;
            if (!data.hasOwnProperty('columns')) {
                columns = rows;
            }
            matrix = data.matrix;
            if (matrix == null) {
                throw new Error("Empty matrix");
            }
            if (matrix.length > MAX_CELLS) {
                throw new Error("Too many cells");
            }
        };

        function adjustedDim(arr) {
            return Math.floor(arr.length *
                (cellSize + options.borderWidth));
        }
        self.display = function () {
            element.css("position", "relative");
            cellSize = Math.min(MAX_CELL_SIZE,
                Math.max(MIN_CELL_SIZE,
                    (minDim - options.borderWidth * (rows.length+1)) /
                         rows.length)
                );
            var adjWidth  = adjustedDim(columns);
            var adjHeight = adjustedDim(rows);
            var containerId = element.attr('id') + "-container";
            var container = $("<div>").attr("id", containerId)
                .css("position", "relative")
                .width(adjWidth)
                .height(adjHeight);
            element.append(container);
    	    var svg  = d3.select("#" + containerId).append("svg")
    	        .attr("class", options.colorscheme)
    	        .attr("width", adjWidth)
    	        .attr("height", adjHeight);
    	    var quantize = d3.scale
                .quantile().domain([0, 1]).range(d3.range(9));
            var dragbox = new DragBox(container);
            dragbox.textHandler(function (x, y, w, h) {
                return [w, h].join(" ");
            })

            for (var i = 0; i < matrix.length; i++) {
                var cell = matrix[i];
                var row = cell[0];
                var col = cell[1];
                svg.append("rect")
                    .attr("width", cellSize).attr("height", cellSize)
                    .attr("x", options.borderWidth * (row + 1) + cellSize * row)
                    .attr("y", options.borderWidth * (col + 1) + cellSize * col)
                    .attr("class", "q" + quantize(cell[2]) + "-9")
                    .append("title").text(cell[2]);
            }
            var schemeIndex = 0;
            var schemes = 'RdYlBu Spectral BrBG YlGnBu'.split(" ");
            for (var i in schemes) {
                if (schemes[i] == options.colorscheme) {
                    schemes.splice(i, 1);
                    break;
                }
            }
            schemes.unshift(options.colorscheme);
            // element.append($("<button>")
            //     .addClass("btn btn-mini").text("Change Scheme")
            //     .on('click', function () {
            //         schemeIndex = (schemeIndex + 1) % schemes.length;
            //         svg.attr("class", schemes[schemeIndex]);
            //     }
            // ));
        }
        return self;
	}
	return Heatmap;
});<|endoftext|>


<commit_before>/*
* PurrJS JavaScript library.
* (c) 2016-2017, happyCoda.
* MIT License.
* https://github.com/happyCoda/purrjs
*/

import Stream from './stream';
import EventBus from './bus';
import Mistake from './mistake';
import CONFIG from './config';

let Utils = (function () {

  // let _bus = EventBus();

  function _getKind(thing) {
    let toStr = Object.prototype.toString;

    if (thing === undefined) {
      Mistake().throw(CONFIG.LIB_ERRORS.NO_STREAM);
    }

    return toStr.call(thing).replace(/\[|\]/g, '').split(' ')[1];
  }

  function _size(something) {
    let somethingType = _getKind.call(this, something);

    if (somethingType === 'String' || somethingType === 'Array') {
      return something.length;
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.UNSIZEABLE);
    }
  }

  function _legacy(something) {
    return something.constructor ? something.constructor.name : null;
  }

  function _makeArray(arrayLike) {
    let arrayLikeType = _getKind.call(this, arrayLike);

    if (arrayLikeType === 'Array') {
      return arrayLikeType;
    } else if (arrayLikeType === 'Object') {
      return Object.keys(arrayLike).map((key) => {
        return arrayLike[key];
      });
    } else if (arrayLikeType === 'String') {
      return arrayLikeType.split('');
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY_OR_STRING);
    }
  }

  function _each(iterable, callback) {
    let iterableType = _getKind.call(this, iterable);

    if (iterableType === 'Array') {
      iterable.forEach(callback);
    } else if (iterableType === 'Object') {
      Object.keys(iterable).forEach((key) => {
        callback(iterable[key], key);
      });
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY);
    }
  }

  function _reduce(iterable, ...args) {
    let iterableType = _getKind.call(this, iterable);

    if (iterableType === 'Array') {
      return iterable.reduce(...args);
    } else if (iterableType === 'Object') {
      // TODO: operates on Array of Object values, keys are missing. refactor this to gain keys
      return _makeArray.call(this, iterable).reduce(...args);
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY);
    }
  }

  function _filter(iterable, ...args) {
    let iterableType = _getKind.call(this, iterable);

    if (iterableType === 'Array') {
      return iterable.filter(...args);
    } else if (iterableType === 'Object') {
      // TODO: same as reduce
      return _makeArray.call(this, iterable).filter(...args);
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY);
    }
  }

  function _contains(box, item) {
    let boxType = _getKind.call(this, box),
      result = false;

    if (boxType === 'Array') {
      if (box.indexOf(item) !== -1) {
        result = true;
      }
    } else if (boxType === 'Object') {
      // TODO: make search in objects deep
      for (let prop in box) {
        if (box[prop] === item) {
          result = true;
          break;
        }
      }
    } else {
      Mistake().throw('Search item must be of type Array or Object, not – ' + boxType);
    }

    return result;
  }

  function _inspect(obj, deeper) {
    let objType = _getKind.call(this, obj),
      stringified;

      if (objType === 'Object') {
        stringified = '{';
      } else if (objType === 'Array') {
        stringified = '[';
      } else {
        return obj.toString();
      }

    function callback(objType, val, prop) {
      let propType = _getKind.call(this, val);

      if (objType === 'Array') {
        if (propType === 'Object' || propType === 'Array') {
          stringified += this.inspect(val, true);
        } else {
          stringified += '"' + val + '", ';
        }
      } else {
        if (propType === 'Object') {
          stringified += '"' + prop + '": ';
          stringified += this.inspect(val, true);
        } else if (propType === 'Array') {
          stringified += '"' + prop + '": ';
          stringified += this.inspect(val, true);
        } else {
          stringified += '"' + prop + '": "' + val + '", ';
        }
      }
    }
    _each.call(this, val, callback.bind(this, objType));
    stringified = stringified.replace(/(,\s)$/, '');
    stringified += stringified.substr(0, 1) === '{' ? '}' : ']';

    if (deeper) {
      stringified += ', ';
    }

    return stringified;
  }

  function _extend(target, source) {
    _each.call(this, source, (val, prop) => {
      target[prop] = val;
    });
  }

  function _mixin(target, ...sources) {
    _each.call(this, sources, (mixin) => {
      _extend.call(this, target, mixin);
    });
  }

  function _expose(global, item, name) {
    global.__exposed = global.__exposed || {};
    global.__exposed[name] = item;
  }

  return Object.defineProperties({}, {
    name: {
      value: 'Utils',
      enumerable: true,
      writable: false
    },

    take: {
      value(flow) {
        this._stream = Stream(flow);

        return this;
      },
      enumerable: true,
      writable: false
    },

    getKind: {
      value(thing) {
        _getKind.call(this, thing);
      },
      enumerable: true,
      writable: false
    },

    size: {
      value(something) {
        _size.call(this, something);
      },
      enumerable: true,
      writable: false
    },

    legacy: {
      value(something) {
        _legacy.call(this, something);
      },
      enumerable: true,
      writable: false
    },

    makeArray: {
      value(arrayLike) {
        return _makeArray.call(this, arrayLike);
      },
      enumerable: true,
      writable: false
    },

    each: {
      value(iterable, callback) {
        _each.call(this, iterable, callback);
      },
      enumerable: true,
      writable: false
    },

    reduce: {
      value(iterable, ...args) {
        return _reduce.call(this, iterable, ...args);
      },
      enumerable: true,
      writable: false
    },

    filter: {
      value(iterable, ...args) {
        return _filter.call(this, iterable, ...args);
      },
      enumerable: true,
      writable: false
    },

    inspect: {
      value(obj, deeper) {
        return _inspect.call(this, obj, deeper);
      },
      enumerable: true,
      writable: false
    },

    unique: {
      value(nonUnique) {
        let i = 0,
          j,
          len = nonUnique.length,
          unique = [];

          for (; i < len; i += 1) {
            for (j = 0; j <= i; j += 1) {
              if (unique[j] === nonUnique[i]) {
                break;
              } else if (j === i) {
                unique.push(nonUnique[i]);
              }
            }
          }

        return unique;
      },
      enumerable: true,
      writable: false
    },

    contains: {
      value(box, item) {
        // TODO: refactor this method to make it checking for multiple items
        return _contains.call(this, box, item);
      },
      enumerable: true,
      writable: false
    },

    /*
    * Extends one object by another.
    *
    * @param {Object} extendable Object which will be extended.
    * @param {Object} extension Object by which will be do extension.
    * @return {Object} extendable Extended object.
    */
    extend: {
      value(target, source) {
        _extend.call(this, target, source);
      },
      enumerable: true,
      writable: false
    },

    // extendDeep: function (extendable, extension) {
    //
    //   this.each(extension, function (val, prop) {
    //
    //     var propType = this.take(val).type();
    //
    //     if (propType === 'Array') {
    //
    //       extendable[prop] = [];
    //
    //       this.extendDeep(extendable[prop], val);
    //
    //     } else if (propType === 'Object') {
    //
    //       extendable[prop] = {};
    //
    //       this.extendDeep(extendable[prop], val);
    //     } else {
    //
    //       extendable[prop] = val;
    //
    //     }
    //   }, this);
    // },

    /*
    * Extends object by the given functionality. Multiple inheritance.
    *
    * @param {Object} any Any number of arguments with object type.
    * @return {Object} extendable Object extended with mixins.
    */
    mixin: {
      value(target, ...sources) {
        _mixin.call(this, target, ...sources);
      },
      enumerable: true,
      writable: false
    },

    /*
    * Makes any object available in global scope
    *
    * @param {Object} global Any global object to include exposable
    * @param {Any} item Entity for expose
    * @param {String} name The name of the exposed entity
    */
    expose: {
      value(global, item, name) {
        _expose.call(this, global, item, name);
      },
      enumerable: true,
      writable: false
    },

    /*
    * Generates random number
    *
    * @param {Number} min Minimum number boundary.
    * @param {Number} max Maximum number boundary.
    * @return {Number} randNum Random number generated.
    */
    randomNum: {
      value(min, max) {
      	let randNum = Math.random() * max;

      	randNum = Math.round(randNum);

      	if (randNum <= max && randNum >= min) {
      		return randNum;
      	}

      	return this.randomNum(min, max);
      },
      enumerable: true,
      writable: false
    }
  });
}());

export default Utils;
<commit_msg>- debounce method added<commit_after>/*
* PurrJS JavaScript library.
* (c) 2016-2017, happyCoda.
* MIT License.
* https://github.com/happyCoda/purrjs
*/

import Stream from './stream';
import EventBus from './bus';
import Mistake from './mistake';
import CONFIG from './config';

let Utils = (function () {

  // let _bus = EventBus();

  function _getKind(thing) {
    let toStr = Object.prototype.toString;

    if (thing === undefined) {
      Mistake().throw(CONFIG.LIB_ERRORS.NO_STREAM);
    }

    return toStr.call(thing).replace(/\[|\]/g, '').split(' ')[1];
  }

  function _size(something) {
    let somethingType = _getKind.call(this, something);

    if (somethingType === 'String' || somethingType === 'Array') {
      return something.length;
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.UNSIZEABLE);
    }
  }

  function _legacy(something) {
    return something.constructor ? something.constructor.name : null;
  }

  function _makeArray(arrayLike) {
    let arrayLikeType = _getKind.call(this, arrayLike);

    if (arrayLikeType === 'Array') {
      return arrayLikeType;
    } else if (arrayLikeType === 'Object') {
      return Object.keys(arrayLike).map((key) => {
        return arrayLike[key];
      });
    } else if (arrayLikeType === 'String') {
      return arrayLikeType.split('');
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY_OR_STRING);
    }
  }

  function _each(iterable, callback) {
    let iterableType = _getKind.call(this, iterable);

    if (iterableType === 'Array') {
      iterable.forEach(callback);
    } else if (iterableType === 'Object') {
      Object.keys(iterable).forEach((key) => {
        callback(iterable[key], key);
      });
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY);
    }
  }

  function _reduce(iterable, ...args) {
    let iterableType = _getKind.call(this, iterable);

    if (iterableType === 'Array') {
      return iterable.reduce(...args);
    } else if (iterableType === 'Object') {
      // TODO: operates on Array of Object values, keys are missing. refactor this to gain keys
      return _makeArray.call(this, iterable).reduce(...args);
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY);
    }
  }

  function _filter(iterable, ...args) {
    let iterableType = _getKind.call(this, iterable);

    if (iterableType === 'Array') {
      return iterable.filter(...args);
    } else if (iterableType === 'Object') {
      // TODO: same as reduce
      return _makeArray.call(this, iterable).filter(...args);
    } else {
      Mistake().throw(CONFIG.LIB_ERRORS.OBJECT_OR_ARRAY);
    }
  }

  function _contains(box, item) {
    let boxType = _getKind.call(this, box),
      result = false;

    if (boxType === 'Array') {
      if (box.indexOf(item) !== -1) {
        result = true;
      }
    } else if (boxType === 'Object') {
      // TODO: make search in objects deep
      for (let prop in box) {
        if (box[prop] === item) {
          result = true;
          break;
        }
      }
    } else {
      Mistake().throw('Search item must be of type Array or Object, not – ' + boxType);
    }

    return result;
  }

  function _inspect(obj, deeper) {
    let objType = _getKind.call(this, obj),
      stringified;

      if (objType === 'Object') {
        stringified = '{';
      } else if (objType === 'Array') {
        stringified = '[';
      } else {
        return obj.toString();
      }

    function callback(objType, val, prop) {
      let propType = _getKind.call(this, val);

      if (objType === 'Array') {
        if (propType === 'Object' || propType === 'Array') {
          stringified += this.inspect(val, true);
        } else {
          stringified += '"' + val + '", ';
        }
      } else {
        if (propType === 'Object') {
          stringified += '"' + prop + '": ';
          stringified += this.inspect(val, true);
        } else if (propType === 'Array') {
          stringified += '"' + prop + '": ';
          stringified += this.inspect(val, true);
        } else {
          stringified += '"' + prop + '": "' + val + '", ';
        }
      }
    }
    _each.call(this, val, callback.bind(this, objType));
    stringified = stringified.replace(/(,\s)$/, '');
    stringified += stringified.substr(0, 1) === '{' ? '}' : ']';

    if (deeper) {
      stringified += ', ';
    }

    return stringified;
  }

  function _extend(target, source) {
    _each.call(this, source, (val, prop) => {
      target[prop] = val;
    });
  }

  function _mixin(target, ...sources) {
    _each.call(this, sources, (mixin) => {
      _extend.call(this, target, mixin);
    });
  }

  function _expose(global, item, name) {
    global.__exposed = global.__exposed || {};
    global.__exposed[name] = item;
  }

  function _debounce(fn, wait, asap) {
    let timeout;

    return (..args) => {
      function delay() {
        if (!asap) {
          delay.apply(null, args);
        }
        timeout = null;
      }

      if (timeout) {
        clearTimeout(timeout);
      } else if (asap) {
        delay.apply(null, args);
      }

      timeout = setTimeout(delay, wait || 100);
    }
  }

  return Object.defineProperties({}, {
    name: {
      value: 'Utils',
      enumerable: true,
      writable: false
    },

    take: {
      value(flow) {
        this._stream = Stream(flow);

        return this;
      },
      enumerable: true,
      writable: false
    },

    getKind: {
      value(thing) {
        _getKind.call(this, thing);
      },
      enumerable: true,
      writable: false
    },

    size: {
      value(something) {
        _size.call(this, something);
      },
      enumerable: true,
      writable: false
    },

    legacy: {
      value(something) {
        _legacy.call(this, something);
      },
      enumerable: true,
      writable: false
    },

    makeArray: {
      value(arrayLike) {
        return _makeArray.call(this, arrayLike);
      },
      enumerable: true,
      writable: false
    },

    each: {
      value(iterable, callback) {
        _each.call(this, iterable, callback);
      },
      enumerable: true,
      writable: false
    },

    reduce: {
      value(iterable, ...args) {
        return _reduce.call(this, iterable, ...args);
      },
      enumerable: true,
      writable: false
    },

    filter: {
      value(iterable, ...args) {
        return _filter.call(this, iterable, ...args);
      },
      enumerable: true,
      writable: false
    },

    inspect: {
      value(obj, deeper) {
        return _inspect.call(this, obj, deeper);
      },
      enumerable: true,
      writable: false
    },

    unique: {
      value(nonUnique) {
        let i = 0,
          j,
          len = nonUnique.length,
          unique = [];

          for (; i < len; i += 1) {
            for (j = 0; j <= i; j += 1) {
              if (unique[j] === nonUnique[i]) {
                break;
              } else if (j === i) {
                unique.push(nonUnique[i]);
              }
            }
          }

        return unique;
      },
      enumerable: true,
      writable: false
    },

    contains: {
      value(box, item) {
        // TODO: refactor this method to make it checking for multiple items
        return _contains.call(this, box, item);
      },
      enumerable: true,
      writable: false
    },

    /*
    * Extends one object by another.
    *
    * @param {Object} extendable Object which will be extended.
    * @param {Object} extension Object by which will be do extension.
    * @return {Object} extendable Extended object.
    */
    extend: {
      value(target, source) {
        _extend.call(this, target, source);
      },
      enumerable: true,
      writable: false
    },

    // extendDeep: function (extendable, extension) {
    //
    //   this.each(extension, function (val, prop) {
    //
    //     var propType = this.take(val).type();
    //
    //     if (propType === 'Array') {
    //
    //       extendable[prop] = [];
    //
    //       this.extendDeep(extendable[prop], val);
    //
    //     } else if (propType === 'Object') {
    //
    //       extendable[prop] = {};
    //
    //       this.extendDeep(extendable[prop], val);
    //     } else {
    //
    //       extendable[prop] = val;
    //
    //     }
    //   }, this);
    // },

    /*
    * Extends object by the given functionality. Multiple inheritance.
    *
    * @param {Object} any Any number of arguments with object type.
    * @return {Object} extendable Object extended with mixins.
    */
    mixin: {
      value(target, ...sources) {
        _mixin.call(this, target, ...sources);
      },
      enumerable: true,
      writable: false
    },

    /*
    * Makes any object available in global scope
    *
    * @param {Object} global Any global object to include exposable
    * @param {Any} item Entity for expose
    * @param {String} name The name of the exposed entity
    */
    expose: {
      value(global, item, name) {
        _expose.call(this, global, item, name);
      },
      enumerable: true,
      writable: false
    },

    debounce: {
      value(...args) {
        _debounce.call(this, ...args);
      },
      enumerable: true,
      writable: false
    },

    /*
    * Generates random number
    *
    * @param {Number} min Minimum number boundary.
    * @param {Number} max Maximum number boundary.
    * @return {Number} randNum Random number generated.
    */
    randomNum: {
      value(min, max) {
      	let randNum = Math.random() * max;

      	randNum = Math.round(randNum);

      	if (randNum <= max && randNum >= min) {
      		return randNum;
      	}

      	return this.randomNum(min, max);
      },
      enumerable: true,
      writable: false
    }
  });
}());

export default Utils;
<|endoftext|>


<commit_before>window.SearchView = function(options) {
    var el = options['el'];
    var type = 'type' in options ? options['type'] : 'server';
    var pagination = 'pagination' in options ? options['pagination'] : false;
    var collection = options['collection'];
    var page_size = options['page_size'] || 10;
    var type = 'type' in options ? options['type'] : 'server';
    var facets = options['facets'] || [];
    var query_obj = {};

    el.html(template.mediasearch({type: type, pagination: pagination}));
    console.log('Render: SearchView');

    switch(pagination) {
        case 'traditional':
            collection.switchMode('server', {fetch: false});
            collection.setPageSize(page_size,{fetch:false, first: true});
            renderBootstrapPaginator();
            break;
        case 'endless':
            var offset = 100;
            var wait = 100;
            collection.switchMode('endless', {fetch: false});
            collection.setPageSize(page_size,{fetch: false, first: true});
            var scroll_callback = function () {
                if ($(window).scrollTop() >= ( $(document).height() - $(window).height() - offset)
                     && collection.hasNext() ){
                    collection.getNextPage();
                }
            };

            var throttled = _.throttle(scroll_callback, wait);
            $(window).scroll(throttled);
            break;

        case false: break;
        default:
    }

    switch(type) {
        case 'server':
            var visualSearch = VS.init({
                container : $('.visual_search'),
                query     : '',
                showFacets: true,
                callbacks : {
                    clearSearch: function(clear_cb) {
                        clear_cb();
                        query_obj = {};
                        searchOnServer();
                    },
                    search: function(query, searchCollection) {
                        query_obj = _.object(searchCollection.pluck('category'), searchCollection.pluck('value'));
                        searchOnServer();
                    },
                    facetMatches : function(callback) {
                        callback(facets);
                    },
                    valueMatches : function(facet, searchTerm, callback) {
                        Backbone.sync('read', collection, {
                            silent: true,
                            data: { fields: facets },
                            success: function(res) {
                                var f = _.compact(_.uniq(_.pluck(res[1], facet)));
                                callback(f);
                            }
                        });
                    },
                    focus: function() {
                    },
                    blur: function() {
                    }
                }
            });
            break;
        case 'client': break;
        default:
    }

    function renderBootstrapPaginator() {
        $(".pagination", el).html("");
        if(collection.state.totalPages > 1) {
            var pag_options = { currentPage: 1,
                totalPages: collection.state.totalPages ,
                size: 'mini',
                onPageClicked: function(e, originalEvent, type, page) {
                    collection.getPage((page-1));
                }
            };
            $(".pagination", el).bootstrapPaginator(pag_options);
        }
    }

    function searchOnServer() {
        collection.setQuery(query_obj, page_size);
        collection.fetch({ success: function() {
            if( pagination == 'traditional') {
                renderBootstrapPaginator();
            }
        }});
    }

    return;
}

<commit_msg>SearchView: Avoid querying everytime tag is selected<commit_after>window.SearchView = function(options) {
    var el = options['el'];
    var type = 'type' in options ? options['type'] : 'server';
    var pagination = 'pagination' in options ? options['pagination'] : false;
    var collection = options['collection'];
    var page_size = options['page_size'] || 10;
    var type = 'type' in options ? options['type'] : 'server';
    var facets = options['facets'] || [];
    var query_obj = {};

    var parseFacets = function (loaded_facets, facet) {
        return _.map(_.compact(_.uniq(_.pluck(loaded_facets, facet))), function(val) { return String(val); });
    }

    el.html(template.mediasearch({type: type, pagination: pagination}));
    console.log('Render: SearchView');

    switch(pagination) {
        case 'traditional':
            collection.switchMode('server', {fetch: false});
            collection.setPageSize(page_size,{fetch:false, first: true});
            renderBootstrapPaginator();
            break;
        case 'endless':
            var offset = 100;
            var wait = 100;
            collection.switchMode('endless', {fetch: false});
            collection.setPageSize(page_size,{fetch: false, first: true});
            var scroll_callback = function () {
                if ($(window).scrollTop() >= ( $(document).height() - $(window).height() - offset)
                     && collection.hasNext() ){
                    collection.getNextPage();
                }
            };

            var throttled = _.throttle(scroll_callback, wait);
            $(window).scroll(throttled);
            break;

        case false: break;
        default:
    }

    switch(type) {
        case 'server':
            var loaded_facets = {};
            var searchBox = $('.visual_search', el);
            var visualSearch = VS.init({
                container : searchBox,
                query     : '',
                showFacets: true,
                placeholder: '',
                callbacks : {
                    clearSearch: function(clear_cb) {
                        clear_cb();
                        query_obj = {};
                        searchOnServer();
                    },
                    search: function(query, searchCollection) {
                        query_obj = _.object(searchCollection.pluck('category'), searchCollection.pluck('value'));
                        searchOnServer();
                    },
                    facetMatches : function(callback) {
                        callback(facets);
                    },
                    valueMatches : function(facet, searchTerm, callback) {
                        var options = {preserveOrder: true};
                        if (!loaded_facets.length) {
                            Backbone.sync('read', collection, {
                                silent: true,
                                data: { fields: facets },
                                success: function(res) {
                                    loaded_facets = res[1];
                                    var f = parseFacets(loaded_facets, facet);
                                    callback(f, options);
                                }
                            });
                        } else {
                            var f = parseFacets(loaded_facets, facet);
                            callback(f, options);
                        }
                    },
                    focus: function() {
                    },
                    blur: function() {
                    }
                }
            });
            break;
        case 'client': break;
        default:
    }

    function renderBootstrapPaginator() {
        $(".pagination", el).html("");
        if(collection.state.totalPages > 1) {
            var pag_options = { currentPage: 1,
                totalPages: collection.state.totalPages ,
                size: 'mini',
                onPageClicked: function(e, originalEvent, type, page) {
                    collection.getPage((page-1));
                }
            };
            $(".pagination", el).bootstrapPaginator(pag_options);
        }
    }

    function searchOnServer() {
        collection.setQuery(query_obj, page_size);
        collection.fetch({ success: function() {
            if( pagination == 'traditional') {
                renderBootstrapPaginator();
            }
        }});
    }

    return;
}

<|endoftext|>