<commit_before>// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function HomeViewModel(json_tags, json_docs) {
  var self = this;

  var ALL_DOCUMENTS = json_docs;
  self.tags = ko.mapping.fromJS(json_tags);
  self.documents = ko.observableArray([]);
  self.page = ko.observable(1);
  self.documentsPerPage = ko.observable(50);

  self.selectedTag = ko.observable({});
  self.selectedTagForDelete = ko.observable({
    name: ''
  });

  self.trash = ko.computed(function () {
    return self.tags.trash;
  });

  self.history = ko.computed(function () {
    return self.tags.history;
  });

  self.myTags = ko.computed(function () {
    return self.tags.mine();
  });

  self.sharedTags = ko.computed(function () {
    return self.tags.notmine();
  });

  self.allTags = ko.computed(function () {
    var _all = [];
    _all.push(self.tags.history);
    _all.push(self.tags.trash);
    _all = _all.concat(self.tags.mine());
    _all = _all.concat(self.tags.notmine());
    return _all;
  });

  self.renderableDocuments = ko.computed(function () {
    return self.documents().slice((self.page() * 1 - 1) * self.documentsPerPage(), (self.page() * self.documentsPerPage()) - 1);
  });

  self.totalPages = ko.computed(function () {
    return Math.ceil(self.documents().length / self.documentsPerPage());
  });

  self.hasPrevious = ko.computed(function () {
    return self.page() > 1;
  });

  self.hasNext = ko.computed(function () {
    return self.page() < self.totalPages();
  });

  self.page.subscribe(function (value) {
    if (isNaN(value * 1)) {
      self.page(1);
    }
    if (value > self.totalPages()) {
      self.page(self.totalPages());
    }
    if (value < 1) {
      self.page(1);
    }
  });

  self.nextPage = function () {
    if (self.hasNext()) {
      self.page(self.page() + 1);
    }
  }

  self.previousPage = function () {
    if (self.hasPrevious()) {
      self.page(self.page() - 1);
    }
  }

  self.documents.subscribe(function () {
    self.page(1);
  });

  self.getTagById = function (tagId) {
    var _tag = null;
    $.each(self.allTags(), function (id, tag) {
      if (tag.hasOwnProperty("id") && tag.id() == tagId) {
        _tag = tag;
      }
      if (tag.hasOwnProperty("projects")) {
        $.each(tag.projects(), function (iid, itag) {
          if (itag.hasOwnProperty("id") && itag.id() == tagId) {
            _tag = itag;
          }
        });
      }
    });
    return _tag;
  }

  self.getDocById = function (docId) {
    var _doc = null;
    $.each(ALL_DOCUMENTS, function (id, doc) {
      if (doc.id == docId) {
        _doc = doc;
      }
    });
    return _doc;
  }

  self.updateDoc = function (doc) {
    $.each(ALL_DOCUMENTS, function (id, iDoc) {
      if (iDoc.id == doc.id) {
        ALL_DOCUMENTS[id] = doc;

        $(self.tags.mine()).each(function (iCnt, tag) {
          var _removeDocFromTag = true;
          $(doc.tags).each(function (cnt, item) {
            if (tag.id() == item.id && tag.docs().indexOf(doc.id) == -1) {
              tag.docs().push(doc.id);
              tag.docs.valueHasMutated();
            }
            if (tag.docs().indexOf(doc.id) > -1 && tag.id() == item.id) {
              _removeDocFromTag = false;
            }
          });
          if (_removeDocFromTag) {
            tag.docs().splice(tag.docs().indexOf(doc.id), 1);
            tag.docs.valueHasMutated();
          }
        });
      }
    });
    self.filterDocs(self.selectedTag());
  }

  self.filterDocs = function (tag) {
    self.documents.removeAll();
    self.selectedTag(tag);
    var _docs = [];
    $.each(ALL_DOCUMENTS, function (id, doc) {
      if (tag.docs().indexOf(parseInt(id)) != -1) { // Beware, keys are strings in js
        _docs.push(doc);
      }
    });
    self.documents(_docs);
  }

  self.searchDocs = function (query) {
    self.documents.removeAll();
    var _docs = [];
    $.each(ALL_DOCUMENTS, function (id, doc) {
      if (self.selectedTag().docs().indexOf(parseInt(id)) != -1) { // Beware, keys are strings in js
        var _bigString = doc.name + doc.description + doc.owner + doc.lastModified;
        $.each(doc.tags, function (cnt, tag) {
          _bigString += tag.name;
        })
        if (_bigString.toLowerCase().indexOf($.trim(query.toLowerCase())) > -1) {
          _docs.push(doc);
        }
      }
    });
    self.documents(_docs);
  }

  self.createTag = function (tag_json) {
    var mapped_tag = ko.mapping.fromJS(tag_json);
    self.tags.mine.push(mapped_tag);
  }

  self.deleteTag = function (tag) {
    self.tags.mine.remove(tag);
  }
}
<commit_msg>[home] Errors in refreshing home page project document numbers<commit_after>// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function HomeViewModel(json_tags, json_docs) {
  var self = this;

  var ALL_DOCUMENTS = json_docs;
  self.tags = ko.mapping.fromJS(json_tags);
  self.documents = ko.observableArray([]);
  self.page = ko.observable(1);
  self.documentsPerPage = ko.observable(50);

  self.selectedTag = ko.observable({});
  self.selectedTagForDelete = ko.observable({
    name: ''
  });

  self.trash = ko.computed(function () {
    return self.tags.trash;
  });

  self.history = ko.computed(function () {
    return self.tags.history;
  });

  self.myTags = ko.computed(function () {
    return self.tags.mine();
  });

  self.sharedTags = ko.computed(function () {
    return self.tags.notmine();
  });

  self.allTags = ko.computed(function () {
    var _all = [];
    _all.push(self.tags.history);
    _all.push(self.tags.trash);
    _all = _all.concat(self.tags.mine());
    _all = _all.concat(self.tags.notmine());
    return _all;
  });

  self.renderableDocuments = ko.computed(function () {
    return self.documents().slice((self.page() * 1 - 1) * self.documentsPerPage(), (self.page() * self.documentsPerPage()) - 1);
  });

  self.totalPages = ko.computed(function () {
    return Math.ceil(self.documents().length / self.documentsPerPage());
  });

  self.hasPrevious = ko.computed(function () {
    return self.page() > 1;
  });

  self.hasNext = ko.computed(function () {
    return self.page() < self.totalPages();
  });

  self.page.subscribe(function (value) {
    if (isNaN(value * 1)) {
      self.page(1);
    }
    if (value > self.totalPages()) {
      self.page(self.totalPages());
    }
    if (value < 1) {
      self.page(1);
    }
  });

  self.nextPage = function () {
    if (self.hasNext()) {
      self.page(self.page() + 1);
    }
  }

  self.previousPage = function () {
    if (self.hasPrevious()) {
      self.page(self.page() - 1);
    }
  }

  self.documents.subscribe(function () {
    self.page(1);
  });

  self.getTagById = function (tagId) {
    var _tag = null;
    $.each(self.allTags(), function (id, tag) {
      if (tag.hasOwnProperty("id") && tag.id() == tagId) {
        _tag = tag;
      }
      if (tag.hasOwnProperty("projects")) {
        $.each(tag.projects(), function (iid, itag) {
          if (itag.hasOwnProperty("id") && itag.id() == tagId) {
            _tag = itag;
          }
        });
      }
    });
    return _tag;
  }

  self.getDocById = function (docId) {
    var _doc = null;
    $.each(ALL_DOCUMENTS, function (id, doc) {
      if (doc.id == docId) {
        _doc = doc;
      }
    });
    return _doc;
  }

  self.updateDoc = function (doc) {
    $.each(ALL_DOCUMENTS, function (id, iDoc) {
      if (iDoc.id == doc.id) {
        ALL_DOCUMENTS[id] = doc;

        $(self.tags.mine()).each(function (iCnt, tag) {
          var _removeDocFromTag = true;
          $(doc.tags).each(function (cnt, item) {
            if (tag.id() == item.id && tag.docs().indexOf(doc.id) == -1) {
              tag.docs().push(doc.id);
              tag.docs.valueHasMutated();
            }
            if (tag.docs().indexOf(doc.id) > -1 && tag.id() == item.id) {
              _removeDocFromTag = false;
            }
          });
          if (_removeDocFromTag) {
            if (tag.docs().indexOf(doc.id) != -1) {
              tag.docs().splice(tag.docs().indexOf(doc.id), 1);
              tag.docs.valueHasMutated();
            }
          }
        });
      }
    });
    self.filterDocs(self.selectedTag());
  }

  self.filterDocs = function (tag) {
    self.documents.removeAll();
    self.selectedTag(tag);
    var _docs = [];
    $.each(ALL_DOCUMENTS, function (id, doc) {
      if (tag.docs().indexOf(parseInt(id)) != -1) { // Beware, keys are strings in js
        _docs.push(doc);
      }
    });
    self.documents(_docs);
  }

  self.searchDocs = function (query) {
    self.documents.removeAll();
    var _docs = [];
    $.each(ALL_DOCUMENTS, function (id, doc) {
      if (self.selectedTag().docs().indexOf(parseInt(id)) != -1) { // Beware, keys are strings in js
        var _bigString = doc.name + doc.description + doc.owner + doc.lastModified;
        $.each(doc.tags, function (cnt, tag) {
          _bigString += tag.name;
        })
        if (_bigString.toLowerCase().indexOf($.trim(query.toLowerCase())) > -1) {
          _docs.push(doc);
        }
      }
    });
    self.documents(_docs);
  }

  self.createTag = function (tag_json) {
    var mapped_tag = ko.mapping.fromJS(tag_json);
    self.tags.mine.push(mapped_tag);
  }

  self.deleteTag = function (tag) {
    self.tags.mine.remove(tag);
  }
}
<|endoftext|>


<commit_before>(function($){
  // returns just the number (23 of image_23)
  $.fn.resourceId = function() {
    var obj = $(this);
    if ( (id = obj.attr('id')) && (m = id.match(/(\d+)$/))) {
      return(m[1]);
    } else if (
      (first_href = obj.children('a:first[@href!=#]').attr('href')) &&
      (m = first_href.match(/(\d+)$/))) {
      return(m[1]);
    } else if (
      (action = obj.attr('action')) &&
      (action.match(/(\d+)\D*$/))) {
      return(m[1]);
    } else if ( m = obj[0].className.match(/_(\d+)/)) {
      return(m[1])
    }
  };

  // Returns image_23
  $.fn.resourceIdentifier = function() {
    if ( m = $(this)[0].className.match(/([a-z_]+_\d+)/)) {
      return(m[1])
    }
  };

  // Returns { type: 'Image', id: 23 }
  $.fn.typeAndId = function() {
    if (match = $(this)[0].className.match(/(.+)_(\d+)/)) {
      return({
        type: $.string(match[1]).gsub(/_/,'-').capitalize().camelize().str,
        id: match[2]
      });
    }
  };

  $.fn.resourcefulLink = function(options) {
    var defaults = {
      start: function() { console.debug("no callback") }
    };
    var options = $.extend(defaults, options);

    return this.each(function(i, element) {
      var obj = $(element);
      obj.click(function(event) {
        event.preventDefault();
        options.start(event);
        meth = 'GET';
        data = '';
        if (obj.hasClass('create'))
          meth = 'POST';
        if (obj.hasClass('destroy')) {
          meth = 'DELETE';
          if (!confirm("Really delete?")) return false;
        };
        $.ajax({
          url: obj.attr('href'),
          type: meth, data: data
        });
      });
    });
  };

  $.fn.addRESTLinks = function(resource, options) {
    var defaults = {
      for: null,
      authToken: resource.find('span.rails-auth-token').text() || 'AuthTokenNotFoundIn-addRestLinks',
      url: null,
      wrap: 'li',
      class: ''
    };
    var options = $.extend(defaults, options);

    if (!options.url) options.url = resource.attr('href');

    if (m = options.url.match(/([^\/]+)s\/\d+$/)) { // ends with id
      options.class += ' ' + m[1];
      var actions = [
        { name: 'Edit', class: 'edit', url: options.url + '/edit' },
        { name: 'Delete', class: 'destroy' }
      ];
    }
    else if (m = options.url.match(/([^\/]+)s$/)) { // end with plural
      options.class += ' ' + m[1];
      var actions = [
        { name: 'Create', class: 'new' }
      ];
    }
    else return this;

    return this.each(function() {
      obj = $(this);
      $.each(actions, function(i,action) {
        if ( !obj.find('a').hasClass(action.class) ) {
          url = (action.url || options.url) + '?authenticity_token='+options.authToken;
          obj.appendDom([{
            tagName: options.wrap, childNodes: [{ tagName: 'a', href: url, class: action.class, innerHTML: action.name }]
          }]);
        }
      });
    });
  };
})(jQuery);
<commit_msg>fixed url for generated /new urls<commit_after>(function($){
  // returns just the number (23 of image_23)
  $.fn.resourceId = function() {
    var obj = $(this);
    if ( (id = obj.attr('id')) && (m = id.match(/(\d+)$/))) {
      return(m[1]);
    } else if (
      (first_href = obj.children('a:first[@href!=#]').attr('href')) &&
      (m = first_href.match(/(\d+)$/))) {
      return(m[1]);
    } else if (
      (action = obj.attr('action')) &&
      (action.match(/(\d+)\D*$/))) {
      return(m[1]);
    } else if ( m = obj[0].className.match(/_(\d+)/)) {
      return(m[1])
    }
  };

  // Returns image_23
  $.fn.resourceIdentifier = function() {
    if ( m = $(this)[0].className.match(/([a-z_]+_\d+)/)) {
      return(m[1])
    }
  };

  // Returns { type: 'Image', id: 23 }
  $.fn.typeAndId = function() {
    if (match = $(this)[0].className.match(/(.+)_(\d+)/)) {
      return({
        type: $.string(match[1]).gsub(/_/,'-').capitalize().camelize().str,
        id: match[2]
      });
    }
  };

  $.fn.resourcefulLink = function(options) {
    var defaults = {
      start: function() { console.debug("no callback") }
    };
    var options = $.extend(defaults, options);

    return this.each(function(i, element) {
      var obj = $(element);
      obj.click(function(event) {
        event.preventDefault();
        options.start(event);
        meth = 'GET';
        data = '';
        if (obj.hasClass('create'))
          meth = 'POST';
        if (obj.hasClass('destroy')) {
          meth = 'DELETE';
          if (!confirm("Really delete?")) return false;
        };
        $.ajax({
          url: obj.attr('href'),
          type: meth, data: data
        });
      });
    });
  };

  $.fn.addRESTLinks = function(resource, options) {
    var defaults = {
      for: null,
      authToken: resource.find('span.rails-auth-token').text() || 'AuthTokenNotFoundIn-addRestLinks',
      url: null,
      wrap: 'li',
      class: ''
    };
    var options = $.extend(defaults, options);

    if (!options.url) options.url = resource.attr('href');

    if (m = options.url.match(/([^\/]+)s\/\d+$/)) { // ends with id
      options.class += ' ' + m[1];
      var actions = [
        { name: 'Edit', class: 'edit', url: options.url + '/edit' },
        { name: 'Delete', class: 'destroy' }
      ];
    }
    else if (m = options.url.match(/([^\/]+)s$/)) { // end with plural
      options.class += ' ' + m[1];
      var actions = [
        { name: 'Create', class: 'new', url: options.url + '/new' }
      ];
    }
    else return this;

    return this.each(function() {
      obj = $(this);
      $.each(actions, function(i,action) {
        if ( !obj.find('a').hasClass(action.class) ) {
          url = (action.url || options.url) + '?authenticity_token='+options.authToken;
          obj.appendDom([{
            tagName: options.wrap, childNodes: [{ tagName: 'a', href: url, class: action.class, innerHTML: action.name }]
          }]);
        }
      });
    });
  };
})(jQuery);
<|endoftext|>


<commit_before>(function(){
    'use strict';

    var DIR                 = process.cwd() + '/',
        main                = require(DIR + 'lib/server/main'),

        Util                = main.util,

        CloudFunc           = main.cloudfunc,
        HTMLDIR             = main.HTMLDIR,

        TEMPLATEPATH        = HTMLDIR + 'file.html',
        PATHTEMPLATE_PATH   = HTMLDIR + 'path.html',
        EXPECT_PATH         = DIR + 'test/expect.html',

        Files               = [TEMPLATEPATH, PATHTEMPLATE_PATH, EXPECT_PATH],

        lJSON = [{
            "path": "/etc/X11/",
            "size": "dir"
        }, {
            "name": "applnk",
            "size": "dir",
            "uid": 0,
            "mode": "40755"
        },{
            "name": "prefdm",
            "size": 1328,
            "uid": 0,
            "mode": "100755"
        }],

        Expect =
            '
'                                                   +
                ''              +
                ''                                                       +
                ''+
                    ''                         +
                ''                                                        +
                    '/'                 +
                    ''               +
                        'etc'                                                   +
                    '/X11/'                                                 +
                ''                                                       +
            '
'                                                             +
            '
'                                              +
                ''                                 +
                'name'                                  +
                'size'                                  +
                'owner'                                +
                'mode'                                  +
            '
';

    main.readFiles(Files, function(pErrors, pFiles){
        if(pErrors)
            Util.log(pErrors);
        else{
            console.time('CloudFunc.buildFromJSON');

            var lTemplate       = pFiles[TEMPLATEPATH].toString(),
                lPathTemplate   = pFiles[PATHTEMPLATE_PATH].toString(),
                lExpect         = pFiles[EXPECT_PATH].toString(),

                lResult         = CloudFunc.buildFromJSON(lJSON, lTemplate, lPathTemplate);

                Expect          += lExpect;

                for(var i = 0, n = Expect.length; i < n; i++)
                    if(lResult[i] !== Expect[i]){
                        console.log('Error in char number: ' + i    + '\n' +
                                    'Expect: ' + Expect.substr(i)  + '\n' +
                                    'Result: ' + lResult.substr(i) );
                        break;
                    }

                    if(i===n)
                        console.log('CloudFunc.buildFromJSON: OK');

            console.timeEnd('CloudFunc.buildFromJSON');
        }
    });

})();
<commit_msg>test(test) main.readFile -> files.readFiles<commit_after>(function(){
    'use strict';

    var DIR                 = process.cwd() + '/',
        main                = require(DIR + 'lib/server/main'),

        Util                = main.util,

        CloudFunc           = main.cloudfunc,
        HTMLDIR             = main.HTMLDIR,
        files               = main.files,

        TEMPLATEPATH        = HTMLDIR + 'file.html',
        PATHTEMPLATE_PATH   = HTMLDIR + 'path.html',
        EXPECT_PATH         = DIR + 'test/expect.html',

        Files               = [TEMPLATEPATH, PATHTEMPLATE_PATH, EXPECT_PATH],

        lJSON = [{
            "path": "/etc/X11/",
            "size": "dir"
        }, {
            "name": "applnk",
            "size": "dir",
            "uid": 0,
            "mode": "40755"
        },{
            "name": "prefdm",
            "size": 1328,
            "uid": 0,
            "mode": "100755"
        }],

        Expect =
            '
'                                                   +
                ''              +
                ''                                                       +
                ''+
                    ''                         +
                ''                                                        +
                    '/'                 +
                    ''               +
                        'etc'                                                   +
                    '/X11/'                                                 +
                ''                                                       +
            '
'                                                             +
            '
'                                              +
                ''                                 +
                'name'                                  +
                'size'                                  +
                'owner'                                +
                'mode'                                  +
            '
';

    files.readFiles(Files, function(pErrors, pFiles){
        if(pErrors)
            Util.log(pErrors);
        else{
            console.time('CloudFunc.buildFromJSON');

            var lTemplate       = pFiles[TEMPLATEPATH].toString(),
                lPathTemplate   = pFiles[PATHTEMPLATE_PATH].toString(),
                lExpect         = pFiles[EXPECT_PATH].toString(),

                lResult         = CloudFunc.buildFromJSON(lJSON, lTemplate, lPathTemplate);

                Expect          += lExpect;

                for(var i = 0, n = Expect.length; i < n; i++)
                    if(lResult[i] !== Expect[i]){
                        console.log('Error in char number: ' + i    + '\n' +
                                    'Expect: ' + Expect.substr(i)  + '\n' +
                                    'Result: ' + lResult.substr(i) );
                        break;
                    }

                    if(i===n)
                        console.log('CloudFunc.buildFromJSON: OK');

            console.timeEnd('CloudFunc.buildFromJSON');
        }
    });

})();
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("./lib/oop");
var dom = require("./lib/dom");
var event = require("./lib/event");
var EventEmitter = require("./lib/event_emitter").EventEmitter;

/**
 *
 *
 * A set of methods for setting and retrieving the editor's scrollbar.
 * @class ScrollBar
 **/

/**
 * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.
 * @param {DOMElement} parent A DOM element
 *
 *
 *
 *
 * @constructor
 **/
var ScrollBar = function(parent) {
    this.element = dom.createElement("div");
    this.element.className = "ace_scrollbar";

    this.inner = dom.createElement("div");
    this.inner.className = "ace_scrollbar-inner";
    this.element.appendChild(this.inner);

    parent.appendChild(this.element);

    // in OSX lion the scrollbars appear to have no width. In this case resize
    // the to show the scrollbar but still pretend that the scrollbar has a width
    // of 0px
    // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
    // make element a little bit wider to retain scrollbar when page is zoomed
    this.width = dom.scrollbarWidth(parent.ownerDocument);
    this.element.style.width = (this.width || 15) + 5 + "px";

    event.addListener(this.element, "scroll", this.onScroll.bind(this));
};

(function() {
    oop.implement(this, EventEmitter);

    /**
     * Emitted when the scroll bar, well, scrolls.
     * @event scroll
     * @param {Object} e Contains one property, `"data"`, which indicates the current scroll top position
     *
     *
     *
     **/
    this.onScroll = function() {
        if (!this.skipEvent) {
            this.scrollTop = this.element.scrollTop;
            this._emit("scroll", {data: this.scrollTop});
        }
        this.skipEvent = false;
    };

    /**
     *
     * Returns the width of the scroll bar.
     * @returns {Number}
     **/
    this.getWidth = function() {
        return this.width;
    };

    /**
     * Sets the height of the scroll bar, in pixels.
     * @param {Number} height The new height
     *
     *
     *
     **/
    this.setHeight = function(height) {
        this.element.style.height = height + "px";
    };

    /**
     * Sets the inner height of the scroll bar, in pixels.
     * @param {Number} height The new inner height
     *
     *
     *
     **/
    this.setInnerHeight = function(height) {
        this.inner.style.height = height + "px";
    };

    // on chrome 17+ for small zoom levels after calling this function
    // this.element.scrollTop != scrollTop which makes page to scroll up.
    /**
     * Sets the scroll top of the scroll bar.
     * @param {Number} scrollTop The new scroll top
     *
     *
     *
     **/
    this.setScrollTop = function(scrollTop) {
        if (this.scrollTop != scrollTop) {
            this.skipEvent = true;
            this.scrollTop = this.element.scrollTop = scrollTop;
        }
    };

}).call(ScrollBar.prototype);

exports.ScrollBar = ScrollBar;
});
<commit_msg>cleanup<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("./lib/oop");
var dom = require("./lib/dom");
var event = require("./lib/event");
var EventEmitter = require("./lib/event_emitter").EventEmitter;

/**
 * A set of methods for setting and retrieving the editor's scrollbar.
 * @class ScrollBar
 **/

/**
 * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.
 * @param {DOMElement} parent A DOM element
 *
 * @constructor
 **/
var ScrollBar = function(parent) {
    this.element = dom.createElement("div");
    this.element.className = "ace_scrollbar";

    this.inner = dom.createElement("div");
    this.inner.className = "ace_scrollbar-inner";
    this.element.appendChild(this.inner);

    parent.appendChild(this.element);

    // in OSX lion the scrollbars appear to have no width. In this case resize the
    // element to show the scrollbar but still pretend that the scrollbar has a width
    // of 0px
    // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
    // make element a little bit wider to retain scrollbar when page is zoomed
    this.width = dom.scrollbarWidth(parent.ownerDocument);
    this.element.style.width = (this.width || 15) + 5 + "px";

    event.addListener(this.element, "scroll", this.onScroll.bind(this));
};

(function() {
    oop.implement(this, EventEmitter);

    /**
     * Emitted when the scroll bar, well, scrolls.
     * @event scroll
     * @param {Object} e Contains one property, `"data"`, which indicates the current scroll top position
     **/
    this.onScroll = function() {
        if (!this.skipEvent) {
            this.scrollTop = this.element.scrollTop;
            this._emit("scroll", {data: this.scrollTop});
        }
        this.skipEvent = false;
    };

    /**
     * Returns the width of the scroll bar.
     * @returns {Number}
     **/
    this.getWidth = function() {
        return this.width;
    };

    /**
     * Sets the height of the scroll bar, in pixels.
     * @param {Number} height The new height
     **/
    this.setHeight = function(height) {
        this.element.style.height = height + "px";
    };

    /**
     * Sets the inner height of the scroll bar, in pixels.
     * @param {Number} height The new inner height
     **/
    this.setInnerHeight = function(height) {
        this.inner.style.height = height + "px";
    };

    // on chrome 17+ for small zoom levels after calling this function
    // this.element.scrollTop != scrollTop which makes page to scroll up.
    /**
     * Sets the scroll top of the scroll bar.
     * @param {Number} scrollTop The new scroll top
     **/
    this.setScrollTop = function(scrollTop) {
        if (this.scrollTop != scrollTop) {
            this.skipEvent = true;
            this.scrollTop = this.element.scrollTop = scrollTop;
        }
    };

}).call(ScrollBar.prototype);

exports.ScrollBar = ScrollBar;
});
<|endoftext|>


<commit_before>/* jshint node:true */
"use strict";

var webpack = require('webpack');

module.exports = function(grunt) {
  // Load tasks & measure timing
  require('time-grunt')(grunt);
  require('load-grunt-tasks')(grunt);

  // Configure Grunt tasks
  grunt.initConfig({
    /**
     * Clean the `dist/` folder between builds.
     */
    clean: {
      'dist': ['dist/']
    },

    /**
     * Copy assets into `dist/` directory.
     */
    copy: {
      assets: {
        files: [
          {expand: true, src: ["images/**"], dest: "dist/"}
        ]
      }
    },

    /**
     * Pre-process CSS with LibSass.
     */
    sass: {
      // On production builds, minify and remove comments.
      prod: {
        files: {
          'dist/app.min.css': 'scss/app.scss'
        },
        options: {
          outputStyle: 'compressed'
        }
      },

      // On development builds, include source maps & do not minify.
      debug: {
        files: {
          'dist/app.min.css': 'scss/app.scss'
        },
        options: {
          sourceMap: true
        }
      }
    },

    /**
     * Post-process CSS with PostCSS.
     *
     * We use Autoprefixer to automatically add vendor-prefixes for appropriate
     * browsers. We use CSS-MQPacker to concatenate all media queries at the
     * end of our built stylesheets.
     */
    postcss: {
      options: {
        processors: [
          require('autoprefixer-core')({
            browsers: ['last 4 versions', 'Firefox ESR', 'Opera 12.1']
          }).postcss,
          require('css-mqpacker').postcss
        ]
      },

      // On production builds, omit source maps.
      prod: {
        src: ['dist/app.min.css'],
        options: {
          map: false
        }
      },

      // On development builds, include source maps.
      debug: {
        src: ['dist/app.min.css']
      }
    },

    /**
     * Build JavaScript with Webpack.
     */
    webpack: {
      options: {
        entry: {
          app: './js/app.js',
          lib: './js/lib.js'
        },
        output: {
          filename: 'dist/app.js'
        },
        resolve: {
          root: require('path').resolve(__dirname, './js')
        },
        module: {
          loaders: [
            { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
            { test: /\.html$/, exclude: /node_modules/, loader: 'raw-loader'}
          ]
        }
      },

      // On production builds, disable source maps & set production flags
      prod: {
        plugins: [
          new webpack.DefinePlugin({
            DEBUG: false,
            PRODUCTION: true
          }),
          new webpack.optimize.CommonsChunkPlugin({
            name: "lib",
            filename: "dist/lib.js"
          }),
          new webpack.optimize.UglifyJsPlugin({
            compress: {
              warnings: false,
              drop_console: true,
              drop_debugger: true,
              dead_code: true
            }
          })
        ]
      },

      // On development builds, include source maps & set debug flags
      debug: {
        devtool: '#inline-source-map',
        plugins: [
          new webpack.DefinePlugin({
            DEBUG: true,
            PRODUCTION: false
          }),
          new webpack.optimize.CommonsChunkPlugin({
            name: "lib",
            filename: "dist/lib.js"
          })
        ]
      }
    },

    /**
     * Create custom Modernizr build based on referenced CSS
     * classes and JavaScript Modernizr checks.
     */
    modernizr: {
      all: {
        "devFile": "remote",
        "outputFile": "dist/modernizr.js",
        "files" : {
          "src": [
            "js/**/*.js",
            "scss/**/*.scss",
            "node_modules/dosomething-neue/js/**/*.js",
            "!node_modules/dosomething-neue/js/modernizr/**/*.js",
            "node_modules/dosomething-neue/scss/**/*.scss",
            "node_modules/dosomething-modal/src/**/*.js",
            "node_modules/dosomething-validation/src/**/*.js"
          ]
        },
        extensibility : {
          // We prefix all Modernizr classes with `modernizr-` to avoid class conflicts.
          "cssclassprefix": "modernizr-"
        },
        "extra" : {
          "addtest": true,
          "shiv" : false,
          "teststyles": true,
          "printshiv" : false,
          "load" : true,
          "mq" : false,
          "video": false
        },
        "matchCommunityTests": true,
        "customTests": [
          "node_modules/dosomething-neue/js/modernizr/checked.js",
          "node_modules/dosomething-neue/js/modernizr/label-click.js"
        ]
      }
    },

    /**
     * Lint JavaScript using ESLint.
     */
    eslint: {
      target: ["js/**/*.js"]
    },

    /**
     * Watch files for changes, and trigger relevant tasks.
     */
    watch: {
      sass: {
        files: ["scss/**/*.scss"],
        tasks: ["sass:debug", "postcss:debug"]
      },
      js: {
        files: ["js/**/*.js"],
        tasks: ["webpack:debug", "jshint"]
      },
      assets: {
        files: ["images/**/*"],
        tasks: ["copy:assets"]
      }
    }
  });

  /**
   * Register Grunt aliases.
   */

  // > grunt
  // Build for development & watch for changes.
  grunt.registerTask('default', ['build:debug', 'test', 'watch']);

  // > grunt build
  // Build for production.
  grunt.registerTask('build', ['clean:dist', 'copy:assets', 'sass:prod', 'postcss:prod', 'webpack:prod', 'modernizr:all']);

  // > grunt build:debug
  // Build for development.
  grunt.registerTask('build:debug', ['clean:dist', 'copy:assets', 'sass:debug', 'postcss:debug', 'webpack:debug', 'modernizr:all']);

  // > grunt test
  // Run included unit tests and linters.
  grunt.registerTask('test', ['eslint']);

};

<commit_msg>Update watch task to use ESLint.<commit_after>/* eslint-disable */
"use strict";

var webpack = require('webpack');

module.exports = function(grunt) {
  // Load tasks & measure timing
  require('time-grunt')(grunt);
  require('load-grunt-tasks')(grunt);

  // Configure Grunt tasks
  grunt.initConfig({
    /**
     * Clean the `dist/` folder between builds.
     */
    clean: {
      'dist': ['dist/']
    },

    /**
     * Copy assets into `dist/` directory.
     */
    copy: {
      assets: {
        files: [
          {expand: true, src: ["images/**"], dest: "dist/"}
        ]
      }
    },

    /**
     * Pre-process CSS with LibSass.
     */
    sass: {
      // On production builds, minify and remove comments.
      prod: {
        files: {
          'dist/app.min.css': 'scss/app.scss'
        },
        options: {
          outputStyle: 'compressed'
        }
      },

      // On development builds, include source maps & do not minify.
      debug: {
        files: {
          'dist/app.min.css': 'scss/app.scss'
        },
        options: {
          sourceMap: true
        }
      }
    },

    /**
     * Post-process CSS with PostCSS.
     *
     * We use Autoprefixer to automatically add vendor-prefixes for appropriate
     * browsers. We use CSS-MQPacker to concatenate all media queries at the
     * end of our built stylesheets.
     */
    postcss: {
      options: {
        processors: [
          require('autoprefixer-core')({
            browsers: ['last 4 versions', 'Firefox ESR', 'Opera 12.1']
          }).postcss,
          require('css-mqpacker').postcss
        ]
      },

      // On production builds, omit source maps.
      prod: {
        src: ['dist/app.min.css'],
        options: {
          map: false
        }
      },

      // On development builds, include source maps.
      debug: {
        src: ['dist/app.min.css']
      }
    },

    /**
     * Build JavaScript with Webpack.
     */
    webpack: {
      options: {
        entry: {
          app: './js/app.js',
          lib: './js/lib.js'
        },
        output: {
          filename: 'dist/app.js'
        },
        resolve: {
          root: require('path').resolve(__dirname, './js')
        },
        module: {
          loaders: [
            { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
            { test: /\.html$/, exclude: /node_modules/, loader: 'raw-loader'}
          ]
        }
      },

      // On production builds, disable source maps & set production flags
      prod: {
        plugins: [
          new webpack.DefinePlugin({
            DEBUG: false,
            PRODUCTION: true
          }),
          new webpack.optimize.CommonsChunkPlugin({
            name: "lib",
            filename: "dist/lib.js"
          }),
          new webpack.optimize.UglifyJsPlugin({
            compress: {
              warnings: false,
              drop_console: true,
              drop_debugger: true,
              dead_code: true
            }
          })
        ]
      },

      // On development builds, include source maps & set debug flags
      debug: {
        devtool: '#inline-source-map',
        plugins: [
          new webpack.DefinePlugin({
            DEBUG: true,
            PRODUCTION: false
          }),
          new webpack.optimize.CommonsChunkPlugin({
            name: "lib",
            filename: "dist/lib.js"
          })
        ]
      }
    },

    /**
     * Create custom Modernizr build based on referenced CSS
     * classes and JavaScript Modernizr checks.
     */
    modernizr: {
      all: {
        "devFile": "remote",
        "outputFile": "dist/modernizr.js",
        "files" : {
          "src": [
            "js/**/*.js",
            "scss/**/*.scss",
            "node_modules/dosomething-neue/js/**/*.js",
            "!node_modules/dosomething-neue/js/modernizr/**/*.js",
            "node_modules/dosomething-neue/scss/**/*.scss",
            "node_modules/dosomething-modal/src/**/*.js",
            "node_modules/dosomething-validation/src/**/*.js"
          ]
        },
        extensibility : {
          // We prefix all Modernizr classes with `modernizr-` to avoid class conflicts.
          "cssclassprefix": "modernizr-"
        },
        "extra" : {
          "addtest": true,
          "shiv" : false,
          "teststyles": true,
          "printshiv" : false,
          "load" : true,
          "mq" : false,
          "video": false
        },
        "matchCommunityTests": true,
        "customTests": [
          "node_modules/dosomething-neue/js/modernizr/checked.js",
          "node_modules/dosomething-neue/js/modernizr/label-click.js"
        ]
      }
    },

    /**
     * Lint JavaScript using ESLint.
     */
    eslint: {
      target: ["js/**/*.js"]
    },

    /**
     * Watch files for changes, and trigger relevant tasks.
     */
    watch: {
      sass: {
        files: ["scss/**/*.scss"],
        tasks: ["sass:debug", "postcss:debug"]
      },
      js: {
        files: ["js/**/*.js"],
        tasks: ["webpack:debug", "eslint"]
      },
      assets: {
        files: ["images/**/*"],
        tasks: ["copy:assets"]
      }
    }
  });

  /**
   * Register Grunt aliases.
   */

  // > grunt
  // Build for development & watch for changes.
  grunt.registerTask('default', ['build:debug', 'test', 'watch']);

  // > grunt build
  // Build for production.
  grunt.registerTask('build', ['clean:dist', 'copy:assets', 'sass:prod', 'postcss:prod', 'webpack:prod', 'modernizr:all']);

  // > grunt build:debug
  // Build for development.
  grunt.registerTask('build:debug', ['clean:dist', 'copy:assets', 'sass:debug', 'postcss:debug', 'webpack:debug', 'modernizr:all']);

  // > grunt test
  // Run included unit tests and linters.
  grunt.registerTask('test', ['eslint']);

};

<|endoftext|>


<commit_before>// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
---
description: Keyboard shortcuts for Desktop
provides: [CCS.Desktop.Keys]
requires: [More/Keyboard.Extras, Widgets/ART.Popup, More/HtmlTable, More/Element.Shortcuts]
script: CCS.Desktop.Keys.js

...
*/
/*
	adds window level keys to desktop as well as a method to display the active keys in use.
*/
(function(){

	var keyShower;

	//prevent accidental scrolling
	var stopper = function(e) {
		if (e.target.tagName.toLowerCase() == 'html') e.stop();
	};
	Keyboard.manager.addEvents({
		'space': stopper,
		'down': stopper,
		'pagedown': stopper,
		'end': stopper,
		'keydown:backspace': stopper
	});

	Keyboard.manager.addShortcuts({
		'Previous Window': {
			keys: 'ctrl+left',
			shortcut: 'control (or alt) + left',
			handler: function(e){
				ART.Popup.DefaultManager.cycle('back', 'default');
				Keyboard.stop(e);
			},
			description: 'Bring the previous window to the foreground.'
		},
		'Next Window': {
			keys: 'ctrl+right',
			shortcut: 'control (or alt) + right',
			handler: function(e){
				ART.Popup.DefaultManager.cycle('forward', 'default');
				Keyboard.stop(e);
			},
			description: 'Bring the next window to the foreground.'
		},
		'New Window': {
			keys: 'ctrl+shift+n',
			shortcut: 'control (or alt) + shift + n',
			handler: function(e){
				var app = CCS.Desktop.getAppComponentName(ART.Popup.DefaultManager.focused);
				if (app) CCS.Desktop.launch(app);
				Keyboard.stop(e);
			},
			description: 'Launch a new window for the current application (if it allows it).'
		},
		'Close Window': {
			keys: 'ctrl+shift+w',
			shortcut: 'control (or alt) + shift + w',
			handler: function(e){
				if (ART.Popup.DefaultManager.focused) ART.Popup.DefaultManager.focused.hide();
				Keyboard.stop(e);
			},
			description: 'Close the current window.'
		},
		'Show Shortcuts': {
			keys: 'ctrl+shift+/',
			shortcut: 'control + "?" (shift + "/")',
			handler: function(e){
				keyShower.toggle();
				Keyboard.stop(e);
			},
			description: 'Show a list of all active shortcuts.'
		}
	});
	Keyboard.manager.addEvents({
		'alt+left': function(e){
			ART.Popup.DefaultManager.cycle('back', 'default');
			Keyboard.stop(e);
		},
		'alt+right': function(e){
			ART.Popup.DefaultManager.cycle('forward', 'default');
			Keyboard.stop(e);
		},
		'alt+shift+n': function(e){
			var app = CCS.Desktop.getAppComponentName(ART.Popup.DefaultManager.focused);
			if (app) CCS.Desktop.launch(app);
			Keyboard.stop(e);
		},
		'alt+shift+w': function(e){
			if (ART.Popup.DefaultManager.focused) ART.Popup.DefaultManager.focused.hide();
			Keyboard.stop(e);
		}
	});

	//functionality to display the shortcuts to the user.
	ART.Popup.DefaultManager.setLayer('shortcuts', 150);

	CCS.KeyList = new Class({

		Implements: Events,

		initialize: function(){
			//create a table for the active shortcuts
			this.table = new HtmlTable({
				headers: ['Key', 'Shortcut Name', 'Description'],
				properties: {
					'data-filters':'HtmlTable'
				}
			});
			//a holder for styling
			this.win = new Element('div', {
				'id':'ccs-shortcut_list',
				styles: {
					display: 'none'
				}
			}).inject(document.body).adopt(this.table);
			//a local instance of Mask for the document
			this.mask = new Mask(document.body, {
				hideOnClick: true,
				onHide: this.hide.bind(this, true)
			});
		},

		//show the shortcut list
		show: function(){
			if (this.win.isDisplayed()) return;
			this.fill();
			this.mask.show();
			this.win.show().position();
			this.fireEvent('show');
		},

		//hide the shortcut list
		hide: function(dontHideMask){
			if (!this.win.isDisplayed()) return;
			if (dontHideMask) {
				this.win.hide();
				this.fireEvent('hide');
			} else {
				this.mask.hide();
			}
		},

		//toggle visibility of the shortcut list
		toggle: function(){
			if (this.win.isDisplayed()) this.hide();
			else this.show();
		},

		//fills the shortcut element with a list of active shortcuts
		fill: function(){
			var keys = Keyboard.getActiveShortcuts();
			this.table.empty();
			var wname;
			keys.reverse().each(function(key){
				var widget = key.getKeyboard().widget;
				var widgetName = widget ? CCS.Desktop.getAppName(CCS.Desktop.getAppComponentName(widget)) : "Desktop";
				if (wname != widgetName) {
					wname = widgetName;
					this.table.push([{
						content: wname,
						properties: {
							colspan: 3,
							styles: {
								'font-weight': 'bold'
							}
						}
					}]);
				}
				this.table.push([key.shortcut, key.name, key.description || ""]);
			}, this);
		}

	});

	window.addEvent('domready', function(){
		keyShower = new CCS.KeyList();
		$('hotkeys').addEvent('click', function(){
			keyShower.show();
		});
	});

})();
<commit_msg>HUE-104. Keyboard window shortcuts should use alt for all OSes<commit_after>// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
---
description: Keyboard shortcuts for Desktop
provides: [CCS.Desktop.Keys]
requires: [More/Keyboard.Extras, Widgets/ART.Popup, More/HtmlTable, More/Element.Shortcuts]
script: CCS.Desktop.Keys.js

...
*/
/*
	adds window level keys to desktop as well as a method to display the active keys in use.
*/
(function(){

	var keyShower;

	//prevent accidental scrolling
	var stopper = function(e) {
		if (e.target.tagName.toLowerCase() == 'html') e.stop();
	};
	Keyboard.manager.addEvents({
		'space': stopper,
		'down': stopper,
		'pagedown': stopper,
		'end': stopper,
		'keydown:backspace': stopper
	});

	Keyboard.manager.addShortcuts({
		'Previous Window': {
			keys: 'alt+left',
			shortcut: 'alt + left',
			handler: function(e){
				ART.Popup.DefaultManager.cycle('back', 'default');
				Keyboard.stop(e);
				e.stop();
			},
			description: 'Bring the previous window to the foreground.'
		},
		'Next Window': {
			keys: 'alt+right',
			shortcut: 'alt + right',
			handler: function(e){
				ART.Popup.DefaultManager.cycle('forward', 'default');
				Keyboard.stop(e);
				e.stop();
			},
			description: 'Bring the next window to the foreground.'
		},
		'New Window': {
			keys: 'alt+shift+n',
			shortcut: 'alt + shift + n',
			handler: function(e){
				var app = CCS.Desktop.getAppComponentName(ART.Popup.DefaultManager.focused);
				if (app) CCS.Desktop.launch(app);
				Keyboard.stop(e);
			},
			description: 'Launch a new window for the current application (if it allows it).'
		},
		'Close Window': {
			keys: 'alt+shift+w',
			shortcut: 'alt + shift + w',
			handler: function(e){
				if (ART.Popup.DefaultManager.focused) ART.Popup.DefaultManager.focused.hide();
				Keyboard.stop(e);
			},
			description: 'Close the current window.'
		},
		'Show/Hide Shortcuts': {
			keys: 'alt+/',
			shortcut: 'alt + /',
			handler: function(e){
				keyShower.toggle();
				Keyboard.stop(e);
			},
			description: 'Show or hide the list of all active shortcuts.'
		}
	});
	Keyboard.manager.addEvents({
		'esc': function(e){
			keyShower.hide();
		}
	});

	//functionality to display the shortcuts to the user.
	ART.Popup.DefaultManager.setLayer('shortcuts', 150);

	CCS.KeyList = new Class({

		Implements: Events,

		initialize: function(){
			//create a table for the active shortcuts
			this.table = new HtmlTable({
				headers: ['Key', 'Shortcut Name', 'Description'],
				properties: {
					'data-filters':'HtmlTable'
				}
			});
			//a holder for styling
			this.win = new Element('div', {
				'id':'ccs-shortcut_list',
				styles: {
					display: 'none'
				}
			}).inject(document.body).adopt(this.table);
			//a local instance of Mask for the document
			this.mask = new Mask(document.body, {
				hideOnClick: true,
				onHide: this.hide.bind(this, true)
			});
		},

		//show the shortcut list
		show: function(){
			if (this.win.isDisplayed()) return;
			this.fill();
			this.mask.show();
			this.win.show().position();
			this.fireEvent('show');
		},

		//hide the shortcut list
		hide: function(dontHideMask){
			if (!this.win.isDisplayed()) return;
			if (dontHideMask) {
				this.win.hide();
				this.fireEvent('hide');
			} else {
				this.mask.hide();
			}
		},

		//toggle visibility of the shortcut list
		toggle: function(){
			if (this.win.isDisplayed()) this.hide();
			else this.show();
		},

		//fills the shortcut element with a list of active shortcuts
		fill: function(){
			var keys = Keyboard.getActiveShortcuts();
			this.table.empty();
			var wname;
			keys.reverse().each(function(key){
				var widget = key.getKeyboard().widget;
				var widgetName = widget ? CCS.Desktop.getAppName(CCS.Desktop.getAppComponentName(widget)) : "Desktop";
				if (wname != widgetName) {
					wname = widgetName;
					this.table.push([{
						content: wname,
						properties: {
							colspan: 3,
							styles: {
								'font-weight': 'bold'
							}
						}
					}]);
				}
				this.table.push([key.shortcut, key.name, key.description || ""]);
			}, this);
		}

	});

	window.addEvent('domready', function(){
		keyShower = new CCS.KeyList();
		$('hotkeys').addEvent('click', function(){
			keyShower.show();
		});
	});

})();
<|endoftext|>


<commit_before>'use strict';

const assert = require('assert');
const ApiUser = require('../../apps/app/model').ApiUser;

let api;

beforeEach(done => {
  ApiUser.findOne({ provider: 'FOO' }).then(user => {
    api = user;
    done();
  }).catch(done);
});

describe('appSchema', () => {
  describe('slugg', () => {
    it('returns URL safe slug for simple name', () => {
      const app = api.apps.create({ name: 'My App' });
      assert.equal(app.slugg, 'my-app');
    });

    it('returns URL safe slug for complex name', () => {
      const app = api.apps.create({ name: 'My Awesome App $%#' });
      assert.equal(app.slugg, 'my-awesome-app----');
    });
  });

  describe('slackAttachment()', () => {
    it('returns app as Slack attachment', () => {
      assert.deepEqual(api.apps[0].slackAttachment(), {
        author_name: 'Foo Bar (FOO)',
        title: 'Foo App',
        title_link: undefined,
        text: 'Ingen Beskrivelse',
        fallback: 'Foo App av Foo Bar (FOO). Ingen Beskrivelse ',
        color: '#2ab27b',
        fields: [{
          title: 'Epost',
          value: 'foo.bar@example.com',
          short: true,
        }, {
          title: 'Telefon',
          value: 'Ukjent',
          short: true,
        }],
      });
    });
  });

  describe('slackRequestApproval()', () => {
    it('returns Slack attachment for request approval', () => {
      assert.deepEqual(api.apps[0].slackRequestApproval(), {
        title: 'Godkjenning kreves for Foo App',
        title_link: 'https://developer.nasjonalturbase.no/admin/requests',
        text: 'Denne applikasjonen krever admin godkjenning før den blir aktiv',
        fallback: 'Denne applikasjonen krever admin godkjenning før den blir aktiv: https://developer.nasjonalturbase.no/admin/requests',
        color: '#3AA3E3',
        callback_id: 'requests/000000000000000000000000/000000000000000000000001',
        actions: [{
          name: 'approve',
          text: 'Godkjenn',
          type: 'bytton',
          style: 'primary',
          value: 'true',
        }, {
          name: 'approve',
          text: 'Avvis',
          type: 'button',
          value: 'false',
        }],
      });
    });
  });

  describe('slackLimitApproval()', () => {
    it('returns Slack attachment for limit approval', () => {
      assert.deepEqual(api.apps[0].slackLimitApproval(), {
        title: 'Godkjenning kreves for Foo App',
        title_link: 'https://developer.nasjonalturbase.no/admin/limits',
        text: 'Ny grense 500 (prod) og 500 (dev) krever admin godkjenning',
        fallback: 'Ny grense 500 (prod) og 500 (dev) krever admin godkjenning: https://developer.nasjonalturbase.no/admin/limits',
        color: '#3AA3E3',
        callback_id: 'limits/000000000000000000000000/000000000000000000000001',
        actions: [{
          name: 'approve',
          text: 'Godkjenn',
          type: 'bytton',
          style: 'primary',
          value: 'true',
        }, {
          name: 'approve',
          text: 'Avvis',
          type: 'button',
          value: 'false',
        }],
      });
    });
  });
});
<commit_msg>fix(slack): correct type for action button<commit_after>'use strict';

const assert = require('assert');
const ApiUser = require('../../apps/app/model').ApiUser;

let api;

beforeEach(done => {
  ApiUser.findOne({ provider: 'FOO' }).then(user => {
    api = user;
    done();
  }).catch(done);
});

describe('appSchema', () => {
  describe('slugg', () => {
    it('returns URL safe slug for simple name', () => {
      const app = api.apps.create({ name: 'My App' });
      assert.equal(app.slugg, 'my-app');
    });

    it('returns URL safe slug for complex name', () => {
      const app = api.apps.create({ name: 'My Awesome App $%#' });
      assert.equal(app.slugg, 'my-awesome-app----');
    });
  });

  describe('slackAttachment()', () => {
    it('returns app as Slack attachment', () => {
      assert.deepEqual(api.apps[0].slackAttachment(), {
        author_name: 'Foo Bar (FOO)',
        title: 'Foo App',
        title_link: undefined,
        text: 'Ingen Beskrivelse',
        fallback: 'Foo App av Foo Bar (FOO). Ingen Beskrivelse ',
        color: '#2ab27b',
        fields: [{
          title: 'Epost',
          value: 'foo.bar@example.com',
          short: true,
        }, {
          title: 'Telefon',
          value: 'Ukjent',
          short: true,
        }],
      });
    });
  });

  describe('slackRequestApproval()', () => {
    it('returns Slack attachment for request approval', () => {
      assert.deepEqual(api.apps[0].slackRequestApproval(), {
        title: 'Godkjenning kreves for Foo App',
        title_link: 'https://developer.nasjonalturbase.no/admin/requests',
        text: 'Denne applikasjonen krever admin godkjenning før den blir aktiv',
        fallback: 'Denne applikasjonen krever admin godkjenning før den blir aktiv: https://developer.nasjonalturbase.no/admin/requests',
        color: '#3AA3E3',
        callback_id: 'requests/000000000000000000000000/000000000000000000000001',
        actions: [{
          name: 'approve',
          text: 'Godkjenn',
          type: 'button',
          style: 'primary',
          value: 'true',
        }, {
          name: 'approve',
          text: 'Avvis',
          type: 'button',
          value: 'false',
        }],
      });
    });
  });

  describe('slackLimitApproval()', () => {
    it('returns Slack attachment for limit approval', () => {
      assert.deepEqual(api.apps[0].slackLimitApproval(), {
        title: 'Godkjenning kreves for Foo App',
        title_link: 'https://developer.nasjonalturbase.no/admin/limits',
        text: 'Ny grense 500 (prod) og 500 (dev) krever admin godkjenning',
        fallback: 'Ny grense 500 (prod) og 500 (dev) krever admin godkjenning: https://developer.nasjonalturbase.no/admin/limits',
        color: '#3AA3E3',
        callback_id: 'limits/000000000000000000000000/000000000000000000000001',
        actions: [{
          name: 'approve',
          text: 'Godkjenn',
          type: 'bytton',
          style: 'primary',
          value: 'true',
        }, {
          name: 'approve',
          text: 'Avvis',
          type: 'button',
          value: 'false',
        }],
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var Question = require('mongoose').model('Question');

exports.getQuestions = function (req, res) {
    Question.find(req.query).exec(function (err, collection) {
        res.send(collection);
    });
};

exports.getQuestionByID = function (req, res) {
    Question.findOne({_id: req.params.id}).exec(function (err, question) {
        res.send(question);
    });
};

exports.getQuestionTextByID = function (req, res) {
    Question.findOne({_id: req.params.id}).select({ "question_text": 1}).exec(function (err, question) {
        res.send(question);
    });
};

var
    processError = function(err, res) {
        res.status(400);
        return res.send({ reason: err.toString() });
    },
    getCloseConnectionHandler = function(res) {
        return function (err) {
            if (err) {
                return res.end();
            }
        };
    };

exports.createQuestions = function (req, res) {
    req.body.forEach(function(new_question) {
        Question.create(new_question, function (err) {
            if (err) {
                return processError(err, res);
            }
        });
    });

    res.send();
};

exports.updateQuestion = function (req, res) {
    var updatedData = req.body;

    if (!req.user.hasRole('supervisor')) {
        res.status(404);
        return getCloseConnectionHandler(res)(true);
    }

    if (updatedData['0']) {
        var getCallback = function(assessments) {
            return function (err, question) {
                if (err) {
                    return processError(err, res);
                }

                question.question_v = question.question_v + 1;
                question.assessments = assessments;
                question.save(getCloseConnectionHandler(res));
            };
        };

        for(var i = 0; i < updatedData.length; i++) {
            Question.findOne({_id: updatedData[String(i)]._id}).exec(getCallback(updatedData[String(i)].assessments));
        }
    } else {
        Question.findOne({_id: updatedData._id})
            .exec(function (err, question) {
                if (err) {
                    return processError(err, res);
                }

                [
                    'question_use',
                    'question_order',
                    'question_type',
                    'question_label',
                    'precept',
                    'component',
                    'indicator',
                    'dejure',
                    'question_text',
                    'dependant',
                    'question_criteria',
                    'question_guidance_text',
                    'question_dependancies',
                    'comments',
                    'linkedOption'
                ].forEach(function(field) {
                        question[field] = updatedData[field];
                });

                var component = updatedData.component;
                if(component !== undefined) {
                    question.component_text = (component[0].toUpperCase() + component.substr(1)).replace('_', ' ');
                }

                question.last_modified = {modified_by: req.user._id, modified_date: new Date().toISOString()};
                question.question_v = question.question_v + 1;
                question.save(getCloseConnectionHandler(res));
            });
    }

    res.send();
};

exports.deleteQuestion = function (req, res) {
    Question.remove({_id: req.params.id}, function (err) {
        res.send(err ? {reason: err.toString()} : undefined);
    });
};
<commit_msg>refactor the back-end `questions` module using the `general-response` module<commit_after>'use strict';

var Question = require('mongoose').model('Question');
var generalResponse = require('./general-response');

exports.getQuestions = function (req, res) {
    Question.find(req.query).exec(function (err, collection) {
        res.send(collection);
    });
};

exports.getQuestionByID = function (req, res) {
    Question.findOne({_id: req.params.id}).exec(function (err, question) {
        res.send(question);
    });
};

exports.getQuestionTextByID = function (req, res) {
    Question.findOne({_id: req.params.id}).select({ "question_text": 1}).exec(function (err, question) {
        res.send(question);
    });
};

var getCloseConnectionHandler = function(res) {
    return function (err) {
        if (err) {
            return res.end();
        }
    };
};

exports.createQuestions = function (req, res) {
    req.body.forEach(function(new_question) {
        Question.create(new_question, function (err) {
            if (err) {
                return generalResponse.respondError(err, res);
            }
        });
    });

    res.send();
};

exports.updateQuestion = function (req, res) {
    var updatedData = req.body;

    if (!req.user.hasRole('supervisor')) {
        res.status(404);
        return getCloseConnectionHandler(res)(true);
    }

    if (updatedData['0']) {
        var getCallback = function(assessments) {
            return function (err, question) {
                if (err) {
                    return generalResponse.respondError(err, res);
                }

                question.question_v = question.question_v + 1;
                question.assessments = assessments;
                question.save(getCloseConnectionHandler(res));
            };
        };

        for(var i = 0; i < updatedData.length; i++) {
            Question.findOne({_id: updatedData[String(i)]._id}).exec(getCallback(updatedData[String(i)].assessments));
        }
    } else {
        Question.findOne({_id: updatedData._id})
            .exec(function (err, question) {
                if (err) {
                    return generalResponse.respondError(err, res);
                }

                [
                    'question_use',
                    'question_order',
                    'question_type',
                    'question_label',
                    'precept',
                    'component',
                    'indicator',
                    'dejure',
                    'question_text',
                    'dependant',
                    'question_criteria',
                    'question_guidance_text',
                    'question_dependancies',
                    'comments',
                    'linkedOption'
                ].forEach(function(field) {
                        question[field] = updatedData[field];
                });

                var component = updatedData.component;
                if(component !== undefined) {
                    question.component_text = (component[0].toUpperCase() + component.substr(1)).replace('_', ' ');
                }

                question.last_modified = {modified_by: req.user._id, modified_date: new Date().toISOString()};
                question.question_v = question.question_v + 1;
                question.save(getCloseConnectionHandler(res));
            });
    }

    res.send();
};

exports.deleteQuestion = function (req, res) {
    Question.remove({_id: req.params.id}, function (err) {
        res.send(err ? {reason: err.toString()} : undefined);
    });
};
<|endoftext|>


<commit_before>socket.on('connect', function() {
    socket.emit('join', 'messageboard');
});

function send(message) {
    socket.emit('broadcast', message);
    console.log(message);
}

var classes_label = "label-primary label-default label-info label-success label-danger label-warning";

/*
 ***** Master Buttons *****
 */

$("#reloadButton").click(function() {
    send({ event: 'reload' });
});
$("#hideMsgButton").click(function() {
    message = { event: 'hide-messages' };
    send(message);
    $("#showMsgButton").show();
    $("#hideMsgButton").hide();
});
$("#showMsgButton").click(function() {
    message = { event: 'show-messages' };
    send(message);
    $("#hideMsgButton").show();
    $("#showMsgButton").hide();
});

/*
 ***** SubTitle *****
 */

$("#subtitleText").click(function() {
    message = { event: 'value', data: { id: "subtitle1", text: $("#subtitle1").val() } };
    message = { event: 'value', data: { id: "subtitle2", text: $("#subtitle2").val() } };
    $("[data-group='subtitle-pills']").removeClass("active");
    $(this).addClass("active");
    $("#subtitle1").parent().parent().addClass("has-success");
    $("#subtitle2").parent().parent().addClass("has-success");
    send(message);
});
$("#subtitleAFKBreak").click(function() {
    message = { event: 'value', data: { id: "subtitle1", text: "Away From Keyboard" } };
    message = { event: 'value', data: { id: "subtitle2", text: "On Break" } };
    $("[data-group='subtitle-pills']").removeClass("active");
    $(this).addClass("active");
    $("#subtitle1").parent().parent().removeClass("has-success");
    $("#subtitle2").parent().parent().removeClass("has-success");
    send(message);
});
$("#subtitleAFKCustom").click(function() {
    message = { event: 'value', data: { id: "subtitle1", text: "Away From Keyboard" } };
    message = { event: 'value', data: { id: "subtitle2", text: $("#subtitle2").val() } };
    $("[data-group='subtitle-pills']").removeClass("active");
    $(this).addClass("active");
    $("#subtitle1").parent().parent().removeClass("has-success");
    $("#subtitle2").parent().parent().addClass("has-success");
    send(message);
});

/*
 ***** Toggle Pills *****
 */

$("[data-group='toggle-pills']").click(function() {
    var set = $(this).attr('data-set');
    var partner = $(this).attr('data-partner');
    var value = $(this).attr('data-value');
    var label = "success"

    if (partner == "Show") { label == "danger" }

    message = { event: 'action', data: { id: set+'_container', action: 'ignore', value: value } };
    send(message);
    $("#"+set+partner).show();
    $(this).hide();
    $("#label-"+set).removeClass(classes_label).addClass("label-"+label);
});

/*
 ***** Voice *****
 */

//  $('#voice1-picture-select option:eq(' + parseInt($("#voice1-text").val().toLowerCase(), 36) % 33 + ')').attr('selected', 'selected');
//  $('#voice1-picture-select').change();

/*
 ***** Crawl *****
 */

$("#crawl-text").blur(function() {
    message = { event: 'value', data: { id: "crawl-text", text: $("#crawl-text").val() } };
    send(message);
});

$("#crawlDisable").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-default");
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "hide" }});
});

$("#crawlBlack").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-primary");
    send({ event: 'action', data: { id: "mainview_footer_marquee", action: "class", value: "marquee-black" }});
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "show" }});
});

$("#crawlBlue").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-info");
    send({ event: 'action', data: { id: "mainview_footer_marquee", action: "class", value: "marquee-blue" }});
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "show" }});
});

$("#crawlRed").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-danger");
    send({ event: 'action', data: { id: "mainview_footer_marquee", action: "class", value: "marquee-red" }});
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "show" }});
});

/*
 ****** Selects and Inputs *****
 */

$("select").change(function() {
    message = { event: 'value', data: { id: $(this).attr("data-for"), text: $("#" + $(this).attr("id") + " option:selected").text() } };
    send(message);
});

// Increment or decrement value fields with up/down arrows
$("input[data-group='value']").keydown( function( event ) {
    if ( event.which == 13 ) {
        event.preventDefault();
    }
    switch( event.keyCode ) {
        case 38: //up
            $(this).val(parseInt($(this).val())+1);
            break;
        case 40: //down
            $(this).val(parseInt($(this).val())-1);
            break;
    }
});

// Process input of value field
//   perform maths if needed
//   send if good input
$("input[data-group='value']").blur(function() {
    result = $(this).val();
    if (result.indexOf("/") > 0) {
        console.log(result);
        pattern = new RegExp(/[0-9]\//);
        if (pattern.test(result)) {
            result = parseInt(eval(result)*100);
            console.log(result);
        } else {
            return 0;
        }
    }
    if ($.isNumeric(parseInt(result))) {
        $(this).val(parseInt(result));
        message = { event: 'value', data: { id: $(this).attr("id"), text: $(this).val() } };
        send(message);
    }
});

$("input[data-group='text']").blur(function() {
    result = $(this).val();
    pattern = new RegExp(/[a-zA-Z0-9 \'\"\!\@\#\$\%\^\&\*\(\)\-\_\+\=\[\]]/);
    if (pattern.test(result) || result == "") {
        message = { event: 'value', data: { id: $(this).attr("id"), text: $(this).val() } };
        send(message);
    }
});

// Catch ESC anywhere to blur the element, which should process the input
$(document).keyup(function(e) {
    if (e.keyCode == 27) { $(document.activeElement).blur(); }   // escape key maps to keycode `27`
});

socket.on('action', function(data) {
    console.log(data);

    if (data.action == 'ignore') {
        // Toggles
        $.each( $("[data-element='"+data.id+"']"), function(val, obj) {
            if ($(this).attr('data-value') == data.value) {
                var set = $(this).attr('data-set');
                var partner = $(obj).attr('data-partner');
                var label = "success"

                if (partner == "Show") { label = "danger"; }
                $("#"+set+partner).show();
                $(this).hide();
                $("#label-"+set).removeClass(classes_label).addClass("label-"+label);
            }
        });
    }
});

socket.on('value', function(data) {
    console.log(data);

    // Admin helper functions
    if (typeof $('#'+data.id).prop('type') !== undefined) {
        switch ($('#'+data.id).prop('type')) {
            case "text":
                $("#"+data.id).val(data.text);
                break;
            case "select-one":
                    $('#'+data.id + ' option[value=' + data.text + ']').prop('selected', true);
                break;
            default:
                console.log($('#'+data.id).prop('type'));
        }
    }

});
<commit_msg>fix - correct "undefined"<commit_after>socket.on('connect', function() {
    socket.emit('join', 'messageboard');
});

function send(message) {
    socket.emit('broadcast', message);
    console.log(message);
}

var classes_label = "label-primary label-default label-info label-success label-danger label-warning";

/*
 ***** Master Buttons *****
 */

$("#reloadButton").click(function() {
    send({ event: 'reload' });
});
$("#hideMsgButton").click(function() {
    message = { event: 'hide-messages' };
    send(message);
    $("#showMsgButton").show();
    $("#hideMsgButton").hide();
});
$("#showMsgButton").click(function() {
    message = { event: 'show-messages' };
    send(message);
    $("#hideMsgButton").show();
    $("#showMsgButton").hide();
});

/*
 ***** SubTitle *****
 */

$("#subtitleText").click(function() {
    message = { event: 'value', data: { id: "subtitle1", text: $("#subtitle1").val() } };
    message = { event: 'value', data: { id: "subtitle2", text: $("#subtitle2").val() } };
    $("[data-group='subtitle-pills']").removeClass("active");
    $(this).addClass("active");
    $("#subtitle1").parent().parent().addClass("has-success");
    $("#subtitle2").parent().parent().addClass("has-success");
    send(message);
});
$("#subtitleAFKBreak").click(function() {
    message = { event: 'value', data: { id: "subtitle1", text: "Away From Keyboard" } };
    message = { event: 'value', data: { id: "subtitle2", text: "On Break" } };
    $("[data-group='subtitle-pills']").removeClass("active");
    $(this).addClass("active");
    $("#subtitle1").parent().parent().removeClass("has-success");
    $("#subtitle2").parent().parent().removeClass("has-success");
    send(message);
});
$("#subtitleAFKCustom").click(function() {
    message = { event: 'value', data: { id: "subtitle1", text: "Away From Keyboard" } };
    message = { event: 'value', data: { id: "subtitle2", text: $("#subtitle2").val() } };
    $("[data-group='subtitle-pills']").removeClass("active");
    $(this).addClass("active");
    $("#subtitle1").parent().parent().removeClass("has-success");
    $("#subtitle2").parent().parent().addClass("has-success");
    send(message);
});

/*
 ***** Toggle Pills *****
 */

$("[data-group='toggle-pills']").click(function() {
    var set = $(this).attr('data-set');
    var partner = $(this).attr('data-partner');
    var value = $(this).attr('data-value');
    var label = "success"

    if (partner == "Show") { label == "danger" }

    message = { event: 'action', data: { id: set+'_container', action: 'ignore', value: value } };
    send(message);
    $("#"+set+partner).show();
    $(this).hide();
    $("#label-"+set).removeClass(classes_label).addClass("label-"+label);
});

/*
 ***** Voice *****
 */

//  $('#voice1-picture-select option:eq(' + parseInt($("#voice1-text").val().toLowerCase(), 36) % 33 + ')').attr('selected', 'selected');
//  $('#voice1-picture-select').change();

/*
 ***** Crawl *****
 */

$("#crawl-text").blur(function() {
    message = { event: 'value', data: { id: "crawl-text", text: $("#crawl-text").val() } };
    send(message);
});

$("#crawlDisable").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-default");
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "hide" }});
});

$("#crawlBlack").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-primary");
    send({ event: 'action', data: { id: "mainview_footer_marquee", action: "class", value: "marquee-black" }});
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "show" }});
});

$("#crawlBlue").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-info");
    send({ event: 'action', data: { id: "mainview_footer_marquee", action: "class", value: "marquee-blue" }});
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "show" }});
});

$("#crawlRed").click(function() {
    $("[data-group='crawl-pills']").removeClass("active");
    $(this).addClass("active");
    $("#label-crawl").removeClass(classes_label).addClass("label-danger");
    send({ event: 'action', data: { id: "mainview_footer_marquee", action: "class", value: "marquee-red" }});
    send({ event: 'action', data: { id: "mainview_footer", action: "visible", value: "show" }});
});

/*
 ****** Selects and Inputs *****
 */

$("select").change(function() {
    message = { event: 'value', data: { id: $(this).attr("data-for"), text: $("#" + $(this).attr("id") + " option:selected").text() } };
    send(message);
});

// Increment or decrement value fields with up/down arrows
$("input[data-group='value']").keydown( function( event ) {
    if ( event.which == 13 ) {
        event.preventDefault();
    }
    switch( event.keyCode ) {
        case 38: //up
            $(this).val(parseInt($(this).val())+1);
            break;
        case 40: //down
            $(this).val(parseInt($(this).val())-1);
            break;
    }
});

// Process input of value field
//   perform maths if needed
//   send if good input
$("input[data-group='value']").blur(function() {
    result = $(this).val();
    if (result.indexOf("/") > 0) {
        console.log(result);
        pattern = new RegExp(/[0-9]\//);
        if (pattern.test(result)) {
            result = parseInt(eval(result)*100);
            console.log(result);
        } else {
            return 0;
        }
    }
    if ($.isNumeric(parseInt(result))) {
        $(this).val(parseInt(result));
        message = { event: 'value', data: { id: $(this).attr("id"), text: $(this).val() } };
        send(message);
    }
});

$("input[data-group='text']").blur(function() {
    result = $(this).val();
    pattern = new RegExp(/[a-zA-Z0-9 \'\"\!\@\#\$\%\^\&\*\(\)\-\_\+\=\[\]]/);
    if (pattern.test(result) || result == "") {
        message = { event: 'value', data: { id: $(this).attr("id"), text: $(this).val() } };
        send(message);
    }
});

// Catch ESC anywhere to blur the element, which should process the input
$(document).keyup(function(e) {
    if (e.keyCode == 27) { $(document.activeElement).blur(); }   // escape key maps to keycode `27`
});

socket.on('action', function(data) {
    console.log(data);

    if (data.action == 'ignore') {
        // Toggles
        $.each( $("[data-element='"+data.id+"']"), function(val, obj) {
            if ($(this).attr('data-value') == data.value) {
                var set = $(this).attr('data-set');
                var partner = $(obj).attr('data-partner');
                var label = "success"

                if (partner == "Show") { label = "danger"; }
                $("#"+set+partner).show();
                $(this).hide();
                $("#label-"+set).removeClass(classes_label).addClass("label-"+label);
            }
        });
    }
});

socket.on('value', function(data) {
    console.log(data);

    // Admin helper functions
    if (typeof $('#'+data.id).prop('type') !== "undefined") {
        switch ($('#'+data.id).prop('type')) {
            case "text":
                $("#"+data.id).val(data.text);
                break;
            case "select-one":
                    $('#'+data.id + ' option[value=' + data.text + ']').prop('selected', true);
                break;
            default:
                console.log($('#'+data.id).prop('type'));
        }
    }

});
<|endoftext|>