<commit_before>define(['xaml!sprd/view/svg/PatternRenderer'], function(PatternRenderer) {

    return PatternRenderer.inherit("sprd.view.svg.DesignConfigurationRendererClass", {

        defaults: {
            tagName: "g",
            maskId: null,
            "data-mask-id": "{configuration.afterEffect.id}",
            isSpecialFlex: "{isSpecialFlex()}",
            isFlock: "{isFlock()}",
            largeSize: "{largeSize()}",
            filter: "{filter()}",
            loadedLayers: {},
            viewer: null,
            loading: "{configuration.loading}",
            allLayersLoaded: "{allLayersLoaded()}"
        },

        $classAttributes: ["x", "y", "width", "height", "loadedLayers"],

        url: function() {

            if (this.$.imageService && this.$.configuration && this.$.configuration.$.design && this.$.configuration.$.printColors && !this.$.configuration.$.design.isVectorDesign()) {

                var maxSize = Math.min(this.$._width, 600),
                    options = {},
                    design = this.$.configuration.$.design;

                if (this.$.width >= this.$.height) {
                    options.width = maxSize;
                } else {
                    options.height = maxSize;
                }

                options.printColors = this.$.configuration.getPrintColorsAsRGB();
                options.version = design.$.version;
                options.watermark = false;

                return this.$.configuration.$.processedImage || design.$.localImage || this.$.imageService.designImageFromCache(design.$.wtfMbsId, options);

            }

            return null;
        }.onChange("design", "_width", "_height", "configuration.processedImage").on(["configuration.printColors", "reset"]),

        maskUrl: function(layerIndex) {

            if (this.$.imageService && this.$.configuration && this.$.configuration.$.design) {

                var maxSize = Math.min(this.$._width, 600),
                    options = {},
                    design = this.$.configuration.$.design;

                if (this.$.width >= this.$.height) {
                    options.width = maxSize;
                } else {
                    options.height = maxSize;
                }

                var colors = this.$.configuration.$.printColors.size(),
                    printColors = [];
                for (var i = 0; i < colors; i++) {
                    printColors.push("none");
                }

                printColors[layerIndex] = "FFFFFF";

                options.printColors = printColors;
                options.version = design.$.version;
                options.layerIndex = layerIndex;
                options.watermark = false;

                if (!design.isVectorDesign()) {
                    return this.$.configuration.$.processedImage || design.$.localImage || this.$.imageService.designImageFromCache(design.$.wtfMbsId, options);
                } else {
                    return this.$.imageService.designImageFromCache(design.$.wtfMbsId, options);
                }

            }

            return null;
        }.onChange("design", "_width", "_height").on(["configuration.printColors", "reset"]),

        handleLoad: function(index) {
            var loadedLayers = this.get("loadedLayers") || {};
            loadedLayers[index] = true;
            this.set("loadedLayers", loadedLayers, {update: true, force: true});
        },

        allLayersLoaded: function() {
            var loadedLayers = this.get("loadedLayers");
            var length = Object.keys(loadedLayers).length;

            return length == this.get("configuration.printColors.length");
        }.onChange("loadedLayers").on(["configuration.printColors", "reset"]),

        fillUrl: function(layerIndex) {
            //there are some designs where the layer order needs to be switched
            var fixedLayerIndex = this.get("configuration.design.colors.$items")[layerIndex].$.layer;

            if (this.isSpecialColor(fixedLayerIndex)) {
                return "url(#p" + this.$.maskId + "-" + fixedLayerIndex + ")";
            }

            var printColors = this.get("configuration.printColors.$items");
            return printColors[fixedLayerIndex].color().toString();
        },

        fillColor: function(layerIndex) {
            var fixedLayerIndex = this.get("configuration.design.colors.$items")[layerIndex].$.layer;
            var printColors = this.get("configuration.printColors.$items");
            return printColors[fixedLayerIndex].color().toString();
        },

        loaderSize: function() {
            return Math.min(this.$.height, this.$.width) * 0.5;
        }.onChange("width", "height"),

        loaderPos: function() {
            var s = this.loaderSize() * 0.5;
            return {
                x: this.$.width * 0.5 - s,
                y: this.$.height * 0.5 - s
            }
        }.onChange("width", "height"),

        maskId: function(maskId, index) {
            return maskId + "-" + index;
        }.onChange("maskId"),

        //MS Edge fix (do not build strings with multiple bindings in the .xml)
        maskIdURL: function(maskId, index) {
            return "url(#" + this.maskId(maskId, index) + ")";
        }.onChange("maskId")
    })
});<commit_msg>added sameOrigin option<commit_after>define(['xaml!sprd/view/svg/PatternRenderer'], function(PatternRenderer) {

    return PatternRenderer.inherit("sprd.view.svg.DesignConfigurationRendererClass", {

        defaults: {
            tagName: "g",
            maskId: null,
            "data-mask-id": "{configuration.afterEffect.id}",
            isSpecialFlex: "{isSpecialFlex()}",
            isFlock: "{isFlock()}",
            largeSize: "{largeSize()}",
            filter: "{filter()}",
            loadedLayers: {},
            viewer: null,
            loading: "{configuration.loading}",
            allLayersLoaded: "{allLayersLoaded()}"
        },

        $classAttributes: ["x", "y", "width", "height", "loadedLayers"],

        url: function() {

            if (this.$.imageService && this.$.configuration && this.$.configuration.$.design && this.$.configuration.$.printColors && !this.$.configuration.$.design.isVectorDesign()) {

                var maxSize = Math.min(this.$._width, 600),
                    options = {},
                    design = this.$.configuration.$.design;

                if (this.$.width >= this.$.height) {
                    options.width = maxSize;
                } else {
                    options.height = maxSize;
                }

                options.printColors = this.$.configuration.getPrintColorsAsRGB();
                options.version = design.$.version;
                options.watermark = false;

                return this.$.configuration.$.processedImage || design.$.localImage || this.$.imageService.designImageFromCache(design.$.wtfMbsId, options);

            }

            return null;
        }.onChange("design", "_width", "_height", "configuration.processedImage").on(["configuration.printColors", "reset"]),

        maskUrl: function(layerIndex) {

            if (this.$.imageService && this.$.configuration && this.$.configuration.$.design) {

                var maxSize = Math.min(this.$._width, 600),
                    options = {},
                    design = this.$.configuration.$.design;

                if (this.$.width >= this.$.height) {
                    options.width = maxSize;
                } else {
                    options.height = maxSize;
                }

                var colors = this.$.configuration.$.printColors.size(),
                    printColors = [];
                for (var i = 0; i < colors; i++) {
                    printColors.push("none");
                }

                printColors[layerIndex] = "FFFFFF";

                options.printColors = printColors;
                options.version = design.$.version;
                options.layerIndex = layerIndex;
                options.watermark = false;
                options.sameOrigin = true;

                if (!design.isVectorDesign()) {
                    return this.$.configuration.$.processedImage || design.$.localImage || this.$.imageService.designImageFromCache(design.$.wtfMbsId, options);
                } else {
                    return this.$.imageService.designImageFromCache(design.$.wtfMbsId, options);
                }

            }

            return null;
        }.onChange("design", "_width", "_height").on(["configuration.printColors", "reset"]),

        handleLoad: function(index) {
            var loadedLayers = this.get("loadedLayers") || {};
            loadedLayers[index] = true;
            this.set("loadedLayers", loadedLayers, {update: true, force: true});
        },

        allLayersLoaded: function() {
            var loadedLayers = this.get("loadedLayers");
            var length = Object.keys(loadedLayers).length;

            return length == this.get("configuration.printColors.length");
        }.onChange("loadedLayers").on(["configuration.printColors", "reset"]),

        fillUrl: function(layerIndex) {
            //there are some designs where the layer order needs to be switched
            var fixedLayerIndex = this.get("configuration.design.colors.$items")[layerIndex].$.layer;

            if (this.isSpecialColor(fixedLayerIndex)) {
                return "url(#p" + this.$.maskId + "-" + fixedLayerIndex + ")";
            }

            var printColors = this.get("configuration.printColors.$items");
            return printColors[fixedLayerIndex].color().toString();
        },

        fillColor: function(layerIndex) {
            var fixedLayerIndex = this.get("configuration.design.colors.$items")[layerIndex].$.layer;
            var printColors = this.get("configuration.printColors.$items");
            return printColors[fixedLayerIndex].color().toString();
        },

        loaderSize: function() {
            return Math.min(this.$.height, this.$.width) * 0.5;
        }.onChange("width", "height"),

        loaderPos: function() {
            var s = this.loaderSize() * 0.5;
            return {
                x: this.$.width * 0.5 - s,
                y: this.$.height * 0.5 - s
            }
        }.onChange("width", "height"),

        maskId: function(maskId, index) {
            return maskId + "-" + index;
        }.onChange("maskId"),

        //MS Edge fix (do not build strings with multiple bindings in the .xml)
        maskIdURL: function(maskId, index) {
            return "url(#" + this.maskId(maskId, index) + ")";
        }.onChange("maskId")
    })
});<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

define(function(require, exports, module) {

var Inputter = require('gcli/ui/inputter').Inputter;
var ArgFetcher = require('gcli/ui/arg_fetch').ArgFetcher;
var CommandMenu = require('gcli/ui/menu').CommandMenu;
var FocusManager = require('gcli/ui/focus').FocusManager;

/**
 * Console is responsible for generating the UI for GCLI, this implementation
 * is a special case for use inside Firefox
 */
function Console(options) {
  this.hintElement = options.hintElement;
  this.gcliTerm = options.gcliTerm;
  this.consoleWrap = options.consoleWrap;
  this.requisition = options.requisition;

  // Create a FocusManager for the various parts to register with
  this.focusManager = new FocusManager({ document: options.chromeDocument });
  this.focusManager.onFocus.add(this.gcliTerm.show, this.gcliTerm);
  this.focusManager.onBlur.add(this.gcliTerm.hide, this.gcliTerm);
  this.focusManager.addMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');

  this.inputter = new Inputter({
    document: options.contentDocument,
    requisition: options.requisition,
    inputElement: options.inputElement,
    completeElement: options.completeElement,
    completionPrompt: '',
    backgroundElement: options.backgroundElement,
    focusManager: this.focusManager
  });

  this.menu = new CommandMenu({
    document: options.contentDocument,
    requisition: options.requisition,
    menuClass: 'gcliterm-menu'
  });
  this.hintElement.appendChild(this.menu.element);

  this.argFetcher = new ArgFetcher({
    document: options.contentDocument,
    requisition: options.requisition,
    argFetcherClass: 'gcliterm-argfetcher'
  });
  this.hintElement.appendChild(this.argFetcher.element);

  this.chromeWindow = options.chromeDocument.defaultView;
  this.resizer = this.resizer.bind(this);
  this.chromeWindow.addEventListener('resize', this.resizer, false);
  this.requisition.commandChange.add(this.resizer, this);
}

/**
 * Avoid memory leaks
 */
Console.prototype.destroy = function() {
  this.chromeWindow.removeEventListener('resize', this.resizer, false);
  delete this.resizer;
  delete this.chromeWindow;
  delete this.consoleWrap;

  this.hintElement.removeChild(this.menu.element);
  this.menu.destroy();
  this.hintElement.removeChild(this.argFetcher.element);
  this.argFetcher.destroy();

  this.inputter.destroy();

  this.focusManager.removeMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');
  this.focusManager.onFocus.remove(this.gcliTerm.show, this.gcliTerm);
  this.focusManager.onBlur.remove(this.gcliTerm.hide, this.gcliTerm);
  this.focusManager.destroy();

  delete this.gcliTerm;
  delete this.hintElement;
};

/**
 * Called on chrome window resize, or on divider slide
 */
Console.prototype.resizer = function() {
  // Bug 705109: There are several numbers hard-coded in this function.
  // This is simpler than calculating them, but error-prone when the UI setup,
  // the styling or display settings change.

  var parentRect = this.consoleWrap.getBoundingClientRect();
  // Magic number: 64 is the size of the toolbar above the output area
  var parentHeight = parentRect.bottom - parentRect.top - 64;

  // Magic number: 100 is the size at which we decide the hints are too small
  // to be useful, so we hide them
  if (parentHeight < 100) {
    this.hintElement.classList.add('gcliterm-hint-nospace');
  }
  else {
    this.hintElement.classList.remove('gcliterm-hint-nospace');

    var isMenuVisible = this.menu.element.style.display !== 'none';
    if (isMenuVisible) {
      this.menu.setMaxHeight(parentHeight);

      // Magic numbers: 19 = height of a menu item, 22 = total vertical padding
      // of container
      var idealMenuHeight = (19 * this.menu.items.length) + 22;
      if (idealMenuHeight > parentHeight) {
        this.hintElement.classList.add('gcliterm-hint-scroll');
      }
      else {
        this.hintElement.classList.remove('gcliterm-hint-scroll');
      }
    }
    else {
      this.argFetcher.setMaxHeight(parentHeight);

      this.hintElement.style.overflowY = null;
      this.hintElement.style.borderBottomColor = 'white';
    }
  }
};

exports.Console = Console;

});
<commit_msg>Bug 704184 (wcscroll): chromeDoc is for element creation and that's why these components wanted access to a document<commit_after>/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

define(function(require, exports, module) {

var Inputter = require('gcli/ui/inputter').Inputter;
var ArgFetcher = require('gcli/ui/arg_fetch').ArgFetcher;
var CommandMenu = require('gcli/ui/menu').CommandMenu;
var FocusManager = require('gcli/ui/focus').FocusManager;

/**
 * Console is responsible for generating the UI for GCLI, this implementation
 * is a special case for use inside Firefox
 */
function Console(options) {
  this.hintElement = options.hintElement;
  this.gcliTerm = options.gcliTerm;
  this.consoleWrap = options.consoleWrap;
  this.requisition = options.requisition;

  // Create a FocusManager for the various parts to register with
  this.focusManager = new FocusManager({ document: options.chromeDocument });
  this.focusManager.onFocus.add(this.gcliTerm.show, this.gcliTerm);
  this.focusManager.onBlur.add(this.gcliTerm.hide, this.gcliTerm);
  this.focusManager.addMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');

  this.inputter = new Inputter({
    document: options.chromeDocument,
    requisition: options.requisition,
    inputElement: options.inputElement,
    completeElement: options.completeElement,
    completionPrompt: '',
    backgroundElement: options.backgroundElement,
    focusManager: this.focusManager
  });

  this.menu = new CommandMenu({
    document: options.chromeDocument,
    requisition: options.requisition,
    menuClass: 'gcliterm-menu'
  });
  this.hintElement.appendChild(this.menu.element);

  this.argFetcher = new ArgFetcher({
    document: options.chromeDocument,
    requisition: options.requisition,
    argFetcherClass: 'gcliterm-argfetcher'
  });
  this.hintElement.appendChild(this.argFetcher.element);

  this.chromeWindow = options.chromeDocument.defaultView;
  this.resizer = this.resizer.bind(this);
  this.chromeWindow.addEventListener('resize', this.resizer, false);
  this.requisition.commandChange.add(this.resizer, this);
}

/**
 * Avoid memory leaks
 */
Console.prototype.destroy = function() {
  this.chromeWindow.removeEventListener('resize', this.resizer, false);
  delete this.resizer;
  delete this.chromeWindow;
  delete this.consoleWrap;

  this.hintElement.removeChild(this.menu.element);
  this.menu.destroy();
  this.hintElement.removeChild(this.argFetcher.element);
  this.argFetcher.destroy();

  this.inputter.destroy();

  this.focusManager.removeMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');
  this.focusManager.onFocus.remove(this.gcliTerm.show, this.gcliTerm);
  this.focusManager.onBlur.remove(this.gcliTerm.hide, this.gcliTerm);
  this.focusManager.destroy();

  delete this.gcliTerm;
  delete this.hintElement;
};

/**
 * Called on chrome window resize, or on divider slide
 */
Console.prototype.resizer = function() {
  // Bug 705109: There are several numbers hard-coded in this function.
  // This is simpler than calculating them, but error-prone when the UI setup,
  // the styling or display settings change.

  var parentRect = this.consoleWrap.getBoundingClientRect();
  // Magic number: 64 is the size of the toolbar above the output area
  var parentHeight = parentRect.bottom - parentRect.top - 64;

  // Magic number: 100 is the size at which we decide the hints are too small
  // to be useful, so we hide them
  if (parentHeight < 100) {
    this.hintElement.classList.add('gcliterm-hint-nospace');
  }
  else {
    this.hintElement.classList.remove('gcliterm-hint-nospace');

    var isMenuVisible = this.menu.element.style.display !== 'none';
    if (isMenuVisible) {
      this.menu.setMaxHeight(parentHeight);

      // Magic numbers: 19 = height of a menu item, 22 = total vertical padding
      // of container
      var idealMenuHeight = (19 * this.menu.items.length) + 22;
      if (idealMenuHeight > parentHeight) {
        this.hintElement.classList.add('gcliterm-hint-scroll');
      }
      else {
        this.hintElement.classList.remove('gcliterm-hint-scroll');
      }
    }
    else {
      this.argFetcher.setMaxHeight(parentHeight);

      this.hintElement.style.overflowY = null;
      this.hintElement.style.borderBottomColor = 'white';
    }
  }
};

exports.Console = Console;

});
<|endoftext|>


<commit_before><commit_msg>Change edge style of convergence plot from arrow to line<commit_after><|endoftext|>


<commit_before>import CompositeClosureHelper from '../../../Common/Core/CompositeClosureHelper';

// ----------------------------------------------------------------------------
// Annotation Store Provider
// ----------------------------------------------------------------------------

const dupNameRegex = /^(.+)\s\(([\d]+)\)$/;

function annotationStoreProvider(publicAPI, model) {
  if (!model.annotationStore) {
    model.annotationStore = {};
  }

  publicAPI.getStoredAnnotationNames = () => {
    const val = Object.keys(model.annotationStore).map(id => model.annotationStore[id].name);
    val.sort();
    return val;
  };

  publicAPI.getNextStoredAnnotationName = name => {
    const allNames = publicAPI.getStoredAnnotationNames();
    let newName = name;
    if (!name || name.length === 0) {
      newName = model.defaultEmptyAnnotationName;
    }

    if (allNames.indexOf(newName) === -1) {
      return newName;
    }

    const [, base, countStr] = dupNameRegex.exec(newName) || [newName, newName, '0'];
    let count = Number(countStr) || 0;

    while (allNames.indexOf(newName) !== -1) {
      newName = `${base} (${++count})`;
    }

    return newName;
  };

  publicAPI.getStoredAnnotation = (id) => model.annotationStore[id];

  publicAPI.getStoredAnnotations = () => model.annotationStore;

  publicAPI.setStoredAnnotation = (id, annotation) => {
    model.annotationStore[id] = annotation;
    publicAPI.fireStoreAnnotationChange(id, annotation);
  };

  publicAPI.deleteStoredAnnotation = id => {
    delete model.annotationStore[id];
    publicAPI.fireStoreAnnotationChange(id);
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  // annotationStore: null,
  defaultEmptyAnnotationName: 'Empty',
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  CompositeClosureHelper.destroy(publicAPI, model);
  CompositeClosureHelper.isA(publicAPI, model, 'AnnotationStoreProvider');
  CompositeClosureHelper.event(publicAPI, model, 'StoreAnnotationChange');
  CompositeClosureHelper.setGet(publicAPI, model, ['defaultEmptyAnnotationName']);

  annotationStoreProvider(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = CompositeClosureHelper.newInstance(extend);

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<commit_msg>fix(AnnotationStoreProvider): Fix set/get composite helper<commit_after>import CompositeClosureHelper from '../../../Common/Core/CompositeClosureHelper';

// ----------------------------------------------------------------------------
// Annotation Store Provider
// ----------------------------------------------------------------------------

const dupNameRegex = /^(.+)\s\(([\d]+)\)$/;

function annotationStoreProvider(publicAPI, model) {
  if (!model.annotationStore) {
    model.annotationStore = {};
  }

  publicAPI.getStoredAnnotationNames = () => {
    const val = Object.keys(model.annotationStore).map(id => model.annotationStore[id].name);
    val.sort();
    return val;
  };

  publicAPI.getNextStoredAnnotationName = name => {
    const allNames = publicAPI.getStoredAnnotationNames();
    let newName = name;
    if (!name || name.length === 0) {
      newName = model.defaultEmptyAnnotationName;
    }

    if (allNames.indexOf(newName) === -1) {
      return newName;
    }

    const [, base, countStr] = dupNameRegex.exec(newName) || [newName, newName, '0'];
    let count = Number(countStr) || 0;

    while (allNames.indexOf(newName) !== -1) {
      newName = `${base} (${++count})`;
    }

    return newName;
  };

  publicAPI.getStoredAnnotation = (id) => model.annotationStore[id];

  publicAPI.getStoredAnnotations = () => model.annotationStore;

  publicAPI.setStoredAnnotation = (id, annotation) => {
    model.annotationStore[id] = annotation;
    publicAPI.fireStoreAnnotationChange(id, annotation);
  };

  publicAPI.deleteStoredAnnotation = id => {
    delete model.annotationStore[id];
    publicAPI.fireStoreAnnotationChange(id);
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  // annotationStore: null,
  defaultEmptyAnnotationName: 'Empty',
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  CompositeClosureHelper.destroy(publicAPI, model);
  CompositeClosureHelper.isA(publicAPI, model, 'AnnotationStoreProvider');
  CompositeClosureHelper.event(publicAPI, model, 'StoreAnnotationChange');
  CompositeClosureHelper.set(publicAPI, model, ['defaultEmptyAnnotationName']);
  CompositeClosureHelper.get(publicAPI, model, ['defaultEmptyAnnotationName']);

  annotationStoreProvider(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = CompositeClosureHelper.newInstance(extend);

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<|endoftext|>


<commit_before>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 5/9/13
 * Time: 11:48 AM
 */

define([
    'plugins/plugin.element'
], function defineDemoChatElement(PluginElement) {

    /**
     * Define DemoChat Element
     * @param view
     * @param opts
     * @returns {DemoChatElement}
     * @constructor
     * @class DemoChatElement
     * @extends PluginElement
     */
    var DemoChatElement = function DemoChatElement(view, opts) {

        this._config(view, opts, $('
')).build({
            $container: opts.$container,
            destroy: true
        });

        this.addCSS('demo.chat', {resource: '/widgets'});

        return this;
    };

    return DemoChatElement.extend('DemoChatElement', {

        /**
         * Render Embedded content
         * @memberOf DemoChatElement
         */
       renderEmbeddedContent: function renderEmbeddedContent() {
            this.addContent([
'
'+
  '
'+
       '
'+
            '
'+
                '
'+
                   '  Chat'+
               '
'+
           '
'+
               '
'+
                    '
'+
                        '
'+
                            ''+
                      '  '+
                            '
'+
                                '
'+
                                   'ronaldo7 '+
                                    '30 mins ago'+
                               '
'+
                               '
Hello, Please join this game..
'+
                           '
'+
                       '
'+
                        '
'+
                           ''+
                        ''+
                           '
'+
                               '
'+
                                   ' 21 mins ago'+
                                    'Mesi'+
                               '
'+
                                '
Hi ronaldo7. Nice to meet you. waiting to start to play.
'+
                           '
'+
                       '
'+
                       '
'+
                          '  '+
                        ''+
                            '
'+
                               '
'+
                                    'ronaldo7 '+
                                    16 mins ago'+
                               '
'+
                              '
Welcome mesi.
'+
                           '
'+
                       '
'+
                       '
'+
                          '  '+
                       ' '+
                           '
'+
                              '
'+
                                  '  10 mins ago'+
                                  '  wonder woman'+
                               '
'+
                               '
Hello meet you shortly.
'+
                           '
'+
                       '
'+
                    '
'+
               '
'+
                '

                        <input id="btn-input" type="text" class="form-control input-sm" placeholder="Type your message here..." />

                            <button class="btn btn-warning btn-sm" id="btn-chat">
                                Send</button>

'+
           '
'+
      '
'+
  '
'+
'
'
].join(''))
		}

    }, PluginElement.prototype);
});
<commit_msg>Update demo.chat.element.js<commit_after>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 5/9/13
 * Time: 11:48 AM
 */

define([
    'plugins/plugin.element'
], function defineDemoChatElement(PluginElement) {

    /**
     * Define DemoChat Element
     * @param view
     * @param opts
     * @returns {DemoChatElement}
     * @constructor
     * @class DemoChatElement
     * @extends PluginElement
     */
    var DemoChatElement = function DemoChatElement(view, opts) {

        this._config(view, opts, $('
')).build({
            $container: opts.$container,
            destroy: true
        });

        this.addCSS('demo.chat', {resource: '/widgets'});

        return this;
    };

    return DemoChatElement.extend('DemoChatElement', {

        /**
         * Render Embedded content
         * @memberOf DemoChatElement
         */
       renderEmbeddedContent: function renderEmbeddedContent() {
            this.addContent([
			'
'+
			  '
'+
			       '
'+
			            '
'+
			                '
'+
			                   '  Chat'+
			               '
'+
			           '
'+
			               '
'+
			                    '
'+
			                        '
'+
			                            ''+
			                      '  '+
			                            '
'+
			                                '
'+
			                                   'ronaldo7 '+
			                                    '30 mins ago'+
			                               '
'+
			                               '
Hello, Please join this game..
'+
			                           '
'+
			                       '
'+
			                        '
'+
			                           ''+
			                        ''+
			                           '
'+
			                               '
'+
			                                   ' 21 mins ago'+
			                                    'Mesi'+
			                               '
'+
			                                '
Hi ronaldo7. Nice to meet you. waiting to start to play.
'+
			                           '
'+
			                       '
'+
			                       '
'+
			                          '  '+
			                        ''+
			                            '
'+
			                               '
'+
			                                    'ronaldo7 '+
			                                    16 mins ago'+
			                               '
'+
			                              '
Welcome mesi.
'+
			                           '
'+
			                       '
'+
			                       '
'+
			                          '  '+
			                       ' '+
			                           '
'+
			                              '
'+
			                                  '  10 mins ago'+
			                                  '  wonder woman'+
			                               '
'+
			                               '
Hello meet you shortly.
'+
			                           '
'+
			                       '
'+
			                    '
'+
			               '
'+
			                '

			                        <input id="btn-input" type="text" class="form-control input-sm" placeholder="Type your message here..." />

			                            <button class="btn btn-warning btn-sm" id="btn-chat">
			                                Send</button>

'+
			           '
'+
			      '
'+
			  '
'+
			'
'
		].join(''))
	}

    }, PluginElement.prototype);
});
<|endoftext|>


<commit_before>var express = require('express');
var request = require('superagent');
var dbUtils = require('../utils/dbUtils');
var qiniuUtils = require('../utils/qiniuUtils');
var config = require('../configs/config');
var cookie = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36' };

var router = express.Router();

/**
 * v1 默认返回最新的bing壁纸信息
 */
router.get('/', function(req, res, next) {
    v1(req, res, next);
});
router.post('/', function(req, res, next) {
    v1(req, res, next);
});

var v1 = function(req, res, next) {
    var d = req.query.d || req.body.d;
    var w = req.query.w || req.body.w || '1366';
    var h = req.query.h || req.body.h || '768';
    var t = req.query.type || req.body.type;
    var size = w + 'x' + h;
    var cb = req.query.callback;
    console.log(size)
    var enddate = 0;
    if (!isNaN(d)) {
        var date = new Date().getTime() - parseInt(d) * 1000 * 60 * 60 * 24;
        var newDate = new Date(date);
        enddate = newDate.getFullYear() + '' + ((newDate.getMonth() + 1) > 9 ? (newDate.getMonth() + 1) : '0' + (newDate.getMonth() + 1)) + '' + (newDate.getDate() > 9 ? newDate.getDate() : '0' + newDate.getDate());
    }
    var params = {
        page: {
            no: 1,
            size: 1
        },
        body: {}
    };
    if (!!enddate) {
        params['body'] = {
            enddate: enddate
        }
    }
    dbUtils.get('bing', params, function(rows) {
        if (rows.length > 0) {
            var data = rows[0];
            if (t === 'json' || !!cb) {
                var output = {
                    data: {
                        enddate: data.enddate,
                        url: data.url,
                        bmiddle_pic: data.bmiddle_pic,
                        original_pic: data.original_pic,
                        thumbnail_pic: data.thumbnail_pic,
                    },
                    status: {
                        code: 200,
                        message: ''
                    }
                };
                if (cb) {
                    res.jsonp(output);
                } else {
                    res.json(output);
                }
            } else {

                if (config.resolutions.indexOf(size) > -1) {
                    data['url'] = config.global_http() + '/bing/' + data.qiniu_url + '_' + size + '.jpg';
                }
                var qiniu_url = /^(http|https)/.test(data.url) ? data.url : qiniuUtils.imageView(data.qiniu_url, w, h);
                request.get(qiniu_url)
                    .set({
                        'user-agent': req.headers['user-agent'],
                        'referer': req.headers['host']
                    })
                    .end(function(err, response) {
                        if (err) {
                            res.send(err)
                        } else {
                            res.header('content-type', 'image/jpg');
                            res.send(response.body);
                        }
                    });
            }
        } else {
            res.json({
                data: {},
                status: {
                    code: -1,
                    message: '好厉害啊，这么隐秘的地方都被你发现了n(*≧▽≦*)n，我已经通知主人咯♪(＾∀＾●)ﾉ，请您稍后再来试一下吧(❤´艸｀❤)!'
                }
            });
        }
    });
}

/**
 * 获得随机图片
 */
router.get('/rand', function(req, res, next) {
    random(req, res, next);
});
router.post('/rand', function(req, res, next) {
    random(req, res, next);
});

var random = function(req, res, next) {
    var t = req.query.type || req.body.type;
    var w = req.query.w || req.body.w || '1366';
    var h = req.query.h || req.body.h || '768';
    var size = w + 'x' + h;
    var callback = req.query.callback || req.body.callback;
    dbUtils.getCount('bing', {}, function(rows) {
        if (rows.length > 0) {
            var sum = Number(rows[0].sum);
            var rand = Math.floor(Math.random() * (sum - 1) + 1);
            dbUtils.get('bing', {
                id: rand
            }, function(rs) {
                if (rs.length > 0) {
                    var data = rs[0];
                    if (t === 'json' || !!callback) {
                        var output = {
                            data: {
                                enddate: data.enddate,
                                url: data.url,
                                bmiddle_pic: data.bmiddle_pic,
                                original_pic: data.original_pic,
                                thumbnail_pic: data.thumbnail_pic,
                            },
                            status: {
                                code: 200,
                                message: ''
                            }
                        };
                        if (callback) {
                            res.jsonp(output);
                        } else {
                            res.json(output);
                        }
                    } else {
                        var data = rs[0];
                        if (config.resolutions.indexOf(size) > -1) {
                            data['url'] = config.global_http() + '/bing/' + data.qiniu_url + '_' + size + '.jpg';
                        }
                        var qiniu_url = /^(http|https)/.test(data.url) ? data.url : qiniuUtils.imageView(data.qiniu_url, w, h);
                        //console.log(qiniu_url)
                        request.get(qiniu_url)
                            .set({
                                'user-agent': req.headers['user-agent'],
                                'referer': req.headers['host']
                            })
                            .end(function(err, response) {
                                if (err) {
                                    res.send(err)
                                } else {
                                    res.header('content-type', 'image/jpeg');
                                    res.send(response.body);
                                }
                            });
                    }
                } else {
                    var parmas = '?';
                    params += !!t ? '&t=' + t : '';
                    params += !!w ? '&w=' + w : '';
                    params += !!h ? '&h=' + h : '';
                    params += !!callback ? '&callback=' + callback : '';
                    res.redirect('/v1/rand' + params);
                }
            });
        } else {
            var parmas = '?';
            params += !!t ? '&t=' + t : '';
            params += !!w ? '&w=' + w : '';
            params += !!h ? '&h=' + h : '';
            params += !!callback ? '&callback=' + callback : '';
            res.redirect('/v1/rand' + params);
        }
    });
}

/**
 * 获取高斯模糊图片
 */
router.get('/blur', function(req, res, next) {
    blur(req, res, next);
});
router.post('/blur', function(req, res, next) {
    blur(req, res, next);
});

var blur = function(req, res, next) {
    var d = req.query.d || req.body.d;
    var w = req.query.w || req.body.w || 1366;
    var h = req.query.h || req.body.h || 768;
    var r = req.query.r || req.body.r;
    r = isNaN(r) ? 10 : parseInt(r) > 50 ? 50 : parseInt(r) <= 0 ? 1 : r;
    var size = w + 'x' + h;
    var enddate = 0;
    if (!isNaN(d)) {
        var date = new Date().getTime() - parseInt(d) * 1000 * 60 * 60 * 24;
        var newDate = new Date(date);
        enddate = newDate.getFullYear() + '' + ((newDate.getMonth() + 1) > 9 ? (newDate.getMonth() + 1) : '0' + (newDate.getMonth() + 1)) + '' + (newDate.getDate() > 9 ? newDate.getDate() : '0' + newDate.getDate());
    }
    var params = {
        page: {
            no: 1,
            size: 1
        },
        body: {}
    };
    if (!!enddate) {
        params.body = {
            enddate: enddate
        }
    }
    dbUtils.get('bing', params, function(rows) {
        if (rows.length > 0) {
            var data = rows[0];
            var base = config.global_http() + '/bing/';
            if (config.resolutions.indexOf(size) > -1) {
                data['url'] = base + data.qiniu_url + '_' + size + '.jpg';
            }
            var qiniu_url = /^(http|https)/.test(data.url) ? data.url : base + data.qiniu_url + '_1920x1080.jpg';
            qiniu_url += '?imageMogr2/blur/' + r + 'x50'
            request.get(qiniu_url)
                .set({
                    'user-agent': req.headers['user-agent'],
                    'referer': req.headers['host']
                })
                .end(function(err, response) {
                    if (err) {
                        res.send(err)
                    } else {
                        res.header('content-type', 'image/jpg');
                        res.send(response.body);
                    }
                });
        } else {
            res.json({
                data: {},
                status: {
                    code: -1,
                    message: '好厉害啊，这么隐秘的地方都被你发现了n(*≧▽≦*)n，我已经通知主人咯♪(＾∀＾●)ﾉ，请您稍后再来试一下吧(❤´艸｀❤)!'
                }
            });
        }
    });
}

module.exports = router;<commit_msg>get base data<commit_after>var express = require('express');
var request = require('superagent');
var dbUtils = require('../utils/dbUtils');
var qiniuUtils = require('../utils/qiniuUtils');
var config = require('../configs/config');
var cookie = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36' };

var router = express.Router();

/**
 * v1 默认返回最新的bing壁纸信息
 */
router.get('/', function(req, res, next) {
    v1(req, res, next);
});
router.post('/', function(req, res, next) {
    v1(req, res, next);
});

var v1 = function(req, res, next) {
    var d = req.query.d || req.body.d;
    var w = req.query.w || req.body.w || '1366';
    var h = req.query.h || req.body.h || '768';
    var t = req.query.type || req.body.type;
    var size = w + 'x' + h;
    var cb = req.query.callback;
    var enddate = 0;
    if (!isNaN(d)) {
        var date = new Date().getTime() - parseInt(d) * 1000 * 60 * 60 * 24;
        var newDate = new Date(date);
        enddate = newDate.getFullYear() + '' + ((newDate.getMonth() + 1) > 9 ? (newDate.getMonth() + 1) : '0' + (newDate.getMonth() + 1)) + '' + (newDate.getDate() > 9 ? newDate.getDate() : '0' + newDate.getDate());
    }
    var params = {
        page: {
            no: 1,
            size: 1
        },
        body: {}
    };
    if (!!enddate) {
        params['body'] = {
            enddate: enddate
        }
    }
    dbUtils.get('bing', params, function(rows) {
        if (rows.length > 0) {
            var data = rows[0];
            if (t === 'json' || !!cb) {
                var output = {
                    data: {
                        enddate: data.enddate,
                        url: data.url,
                        bmiddle_pic: data.bmiddle_pic,
                        original_pic: data.original_pic,
                        thumbnail_pic: data.thumbnail_pic,
                    },
                    status: {
                        code: 200,
                        message: ''
                    }
                };
                if (cb) {
                    res.jsonp(output);
                } else {
                    res.json(output);
                }
            } else {

                if (config.resolutions.indexOf(size) > -1) {
                    data['url'] = config.global_http() + '/bing/' + data.qiniu_url + '_' + size + '.jpg';
                }
                console.log(data)
                var qiniu_url = /^(http|https)/.test(data.url) ? data.url : qiniuUtils.imageView(data.qiniu_url, w, h);
                request.get(qiniu_url)
                    .set({
                        'user-agent': req.headers['user-agent'],
                        'referer': req.headers['host']
                    })
                    .end(function(err, response) {
                        if (err) {
                            res.send(err)
                        } else {
                            res.header('content-type', 'image/jpg');
                            res.send(response.body);
                        }
                    });
            }
        } else {
            res.json({
                data: {},
                status: {
                    code: -1,
                    message: '好厉害啊，这么隐秘的地方都被你发现了n(*≧▽≦*)n，我已经通知主人咯♪(＾∀＾●)ﾉ，请您稍后再来试一下吧(❤´艸｀❤)!'
                }
            });
        }
    });
}

/**
 * 获得随机图片
 */
router.get('/rand', function(req, res, next) {
    random(req, res, next);
});
router.post('/rand', function(req, res, next) {
    random(req, res, next);
});

var random = function(req, res, next) {
    var t = req.query.type || req.body.type;
    var w = req.query.w || req.body.w || '1366';
    var h = req.query.h || req.body.h || '768';
    var size = w + 'x' + h;
    var callback = req.query.callback || req.body.callback;
    dbUtils.getCount('bing', {}, function(rows) {
        if (rows.length > 0) {
            var sum = Number(rows[0].sum);
            var rand = Math.floor(Math.random() * (sum - 1) + 1);
            dbUtils.get('bing', {
                id: rand
            }, function(rs) {
                if (rs.length > 0) {
                    var data = rs[0];
                    if (t === 'json' || !!callback) {
                        var output = {
                            data: {
                                enddate: data.enddate,
                                url: data.url,
                                bmiddle_pic: data.bmiddle_pic,
                                original_pic: data.original_pic,
                                thumbnail_pic: data.thumbnail_pic,
                            },
                            status: {
                                code: 200,
                                message: ''
                            }
                        };
                        if (callback) {
                            res.jsonp(output);
                        } else {
                            res.json(output);
                        }
                    } else {
                        var data = rs[0];
                        if (config.resolutions.indexOf(size) > -1) {
                            data['url'] = config.global_http() + '/bing/' + data.qiniu_url + '_' + size + '.jpg';
                        }
                        var qiniu_url = /^(http|https)/.test(data.url) ? data.url : qiniuUtils.imageView(data.qiniu_url, w, h);
                        //console.log(qiniu_url)
                        request.get(qiniu_url)
                            .set({
                                'user-agent': req.headers['user-agent'],
                                'referer': req.headers['host']
                            })
                            .end(function(err, response) {
                                if (err) {
                                    res.send(err)
                                } else {
                                    res.header('content-type', 'image/jpeg');
                                    res.send(response.body);
                                }
                            });
                    }
                } else {
                    var parmas = '?';
                    params += !!t ? '&t=' + t : '';
                    params += !!w ? '&w=' + w : '';
                    params += !!h ? '&h=' + h : '';
                    params += !!callback ? '&callback=' + callback : '';
                    res.redirect('/v1/rand' + params);
                }
            });
        } else {
            var parmas = '?';
            params += !!t ? '&t=' + t : '';
            params += !!w ? '&w=' + w : '';
            params += !!h ? '&h=' + h : '';
            params += !!callback ? '&callback=' + callback : '';
            res.redirect('/v1/rand' + params);
        }
    });
}

/**
 * 获取高斯模糊图片
 */
router.get('/blur', function(req, res, next) {
    blur(req, res, next);
});
router.post('/blur', function(req, res, next) {
    blur(req, res, next);
});

var blur = function(req, res, next) {
    var d = req.query.d || req.body.d;
    var w = req.query.w || req.body.w || 1366;
    var h = req.query.h || req.body.h || 768;
    var r = req.query.r || req.body.r;
    r = isNaN(r) ? 10 : parseInt(r) > 50 ? 50 : parseInt(r) <= 0 ? 1 : r;
    var size = w + 'x' + h;
    var enddate = 0;
    if (!isNaN(d)) {
        var date = new Date().getTime() - parseInt(d) * 1000 * 60 * 60 * 24;
        var newDate = new Date(date);
        enddate = newDate.getFullYear() + '' + ((newDate.getMonth() + 1) > 9 ? (newDate.getMonth() + 1) : '0' + (newDate.getMonth() + 1)) + '' + (newDate.getDate() > 9 ? newDate.getDate() : '0' + newDate.getDate());
    }
    var params = {
        page: {
            no: 1,
            size: 1
        },
        body: {}
    };
    if (!!enddate) {
        params.body = {
            enddate: enddate
        }
    }
    dbUtils.get('bing', params, function(rows) {
        if (rows.length > 0) {
            var data = rows[0];
            var base = config.global_http() + '/bing/';
            if (config.resolutions.indexOf(size) > -1) {
                data['url'] = base + data.qiniu_url + '_' + size + '.jpg';
            }
            var qiniu_url = /^(http|https)/.test(data.url) ? data.url : base + data.qiniu_url + '_1920x1080.jpg';
            qiniu_url += '?imageMogr2/blur/' + r + 'x50'
            request.get(qiniu_url)
                .set({
                    'user-agent': req.headers['user-agent'],
                    'referer': req.headers['host']
                })
                .end(function(err, response) {
                    if (err) {
                        res.send(err)
                    } else {
                        res.header('content-type', 'image/jpg');
                        res.send(response.body);
                    }
                });
        } else {
            res.json({
                data: {},
                status: {
                    code: -1,
                    message: '好厉害啊，这么隐秘的地方都被你发现了n(*≧▽≦*)n，我已经通知主人咯♪(＾∀＾●)ﾉ，请您稍后再来试一下吧(❤´艸｀❤)!'
                }
            });
        }
    });
}

module.exports = router;<|endoftext|>


<commit_before>/**
 * Created by opdah023 on 10/9/14.
 */
'use strict';

angular.module('umm3601ursamajorApp')
    .filter('isntempty', function(){
        return function(item, title){
            if(typeof(item) == "object"){
                if(item.length > 0){
                    return title + " " + item;
                }
            } else if (item !== "" && item !== null){
                return title + " " + item;
            }
        }
    })

    .controller('SublistCtrl', function ($scope, $http, socket, $modal, Modal, Auth) {
        $scope.submissions = [];

        $scope.isAdmin = Auth.isAdmin;

        $http.get('/api/submissions').success(function(submissions) {
            $scope.submissions = submissions;
            socket.syncUpdates('submission', $scope.submissions);
        });

        $scope.statusColorTab = function(status){
            switch(status){
                case "Pending Review":
                    return {'border-left': '4px solid rgba(255, 220, 10, 1)'};
                    break;
                case "Awaiting Revisions":
                    return {'border-left': '4px solid rgba(0, 100, 255, 1)'};
                    break;
                case "Approved":
                    return {'border-left': '4px solid rgba(0, 255, 0, 1)'};
                    break;
                case "Awaiting Adviser Approval":
                    return {'border-left': '4px solid rgba(255, 0, 0, 1)'};
                    break;
            }
        };

        $scope.statusColorBody = function(status){
            switch(status){
                case "Pending Review":
                    return {'background-color': 'rgba(255, 220, 10, 1)'};
                    break;
                case "Awaiting Revisions":
                    return {'background-color': 'rgba(0, 100, 255, 1)'};
                    break;
                case "Approved":
                    return {'background-color': 'rgba(0, 255, 0, 1)'};
                    break;
                case "Awaiting Adviser Approval":
                    return {'background-color': 'rgba(255, 0, 0, 1)'};
                    break;
            }
        };

        // Controlling selection of submission for detail view
        $scope.selection = {selected: false, item: null};

        $scope.selectItem = function(itemIndex){
            console.log("setting index " + itemIndex + " as active item");
            $scope.selection.selected = true;
            $scope.selection.item = $scope.submissions[itemIndex];
            $scope.resetTemps();
        };

        $scope.resetSelection = function(){
            $scope.selection.selected = false;
            $scope.resetTemps();
        };

        $scope.deleteSubmissionConfirm = function(item){
            Modal.confirm.delete($scope.deleteSubmission)(item.title, item);
        };

        $scope.deleteSubmission = function(item){
            console.log("Deleting submission: " + item.title);
            $http.delete('/api/submissions/' + item._id);
            $scope.resetSelection();
        };

        // Controlling editing of status in details view
        $scope.statusEdit = {
            editing: false,
            options: ["Awaiting Adviser Approval", "Approved", "Awaiting Revisions", "Pending Review"],
            temp: {strict: "", text: ""}
        };

        $scope.resetTemps = function() {
            if($scope.selection.item != null){
                $scope.statusEdit.temp.strict = $scope.selection.item.status.strict;
                $scope.statusEdit.temp.text = $scope.selection.item.status.text;
            }
        };

        $scope.resetTemps();

        $scope.editStatus = function(){
            $scope.statusEdit.editing = !$scope.statusEdit.editing;
            $scope.resetTemps();
        };

        $scope.submitStatusEdit = function(){
            $http.patch('api/submissions/' + $scope.selection.item._id,
                {status: {strict: $scope.statusEdit.temp.strict, text: $scope.statusEdit.temp.text}}
            ).success(function(){
                    console.log("Successfully updated status of submission");
            });

            if($scope.selection.item.approval && $scope.statusEdit.temp.strict === "Awaiting Adviser Approval"){
                $http.patch('api/submissions/' + $scope.selection.item._id,
                    {approval: false}
                ).success(function(){
                    $scope.selection.item.approval = false;
                    console.log("Successfully updated approval of submission (un-approved)");
                });
            } else if(!$scope.selection.item.approval && $scope.statusEdit.temp.strict !== "Awaiting Adviser Approval"){
                $http.patch('api/submissions/' + $scope.selection.item._id,
                    {approval: true}
                ).success(function(){
                    $scope.selection.item.approval = true;
                    console.log("Successfully updated approval of submission (approved)");
                });
            }
            $scope.selection.item.status.strict = $scope.statusEdit.temp.strict;
            $scope.selection.item.status.text = $scope.statusEdit.temp.text;
            $scope.resetTemps();
            $scope.editStatus();
        };

        $scope.approvalWordChange = function(approval){
             if(approval){
                 return "Yes";
                 }
             else{
                 return "No";
                 }
             };

    });<commit_msg>Email templates for admit submission edit<commit_after>/**
 * Created by opdah023 on 10/9/14.
 */
'use strict';

angular.module('umm3601ursamajorApp')
    .filter('isntempty', function(){
        return function(item, title){
            if(typeof(item) == "object"){
                if(item.length > 0){
                    return title + " " + item;
                }
            } else if (item !== "" && item !== null){
                return title + " " + item;
            }
        }
    })

    .controller('SublistCtrl', function ($scope, $http, socket, $modal, Modal, Auth) {
        $scope.submissions = [];

        $scope.isAdmin = Auth.isAdmin;
        $scope.getCurrentUser = Auth.getCurrentUser;
        $scope.email = Auth.getCurrentUser().email;
//        $scope.presenterEmail = presenterInfo().email;

        $http.get('/api/submissions').success(function(submissions) {
            $scope.submissions = submissions;
            socket.syncUpdates('submission', $scope.submissions);
        });

        var sendGmail = function(opts){
            var str = 'http://mail.google.com/mail/?view=cm&fs=1'+
                '&to=' + opts.to +
                '&su=' + opts.subject +
                '&body=' + opts.message +
                '&ui=1';
            location.href = str;
        };
        $scope.statusColorTab = function(status){
            switch(status){
                case "Pending Review":
                    return {'border-left': '4px solid rgba(255, 220, 10, 1)'};
                    break;
                case "Awaiting Revisions":
                    return {'border-left': '4px solid rgba(0, 100, 255, 1)'};
                    break;
                case "Approved":
                    return {'border-left': '4px solid rgba(0, 255, 0, 1)'};
                    break;
                case "Awaiting Adviser Approval":
                    return {'border-left': '4px solid rgba(255, 0, 0, 1)'};
                    break;
            }
        };

        $scope.statusColorBody = function(status){
            switch(status){
                case "Pending Review":
                    return {'background-color': 'rgba(255, 220, 10, 1)'};
                    break;
                case "Awaiting Revisions":
                    return {'background-color': 'rgba(0, 100, 255, 1)'};
                    break;
                case "Approved":
                    return {'background-color': 'rgba(0, 255, 0, 1)'};
                    break;
                case "Awaiting Adviser Approval":
                    return {'background-color': 'rgba(255, 0, 0, 1)'};
                    break;
            }
        };

        // Controlling selection of submission for detail view
        $scope.selection = {selected: false, item: null};

        $scope.selectItem = function(itemIndex){
            console.log("setting index " + itemIndex + " as active item");
            $scope.selection.selected = true;
            $scope.selection.item = $scope.submissions[itemIndex];
            $scope.resetTemps();
        };

        $scope.resetSelection = function(){
            $scope.selection.selected = false;
            $scope.resetTemps();
        };

        $scope.deleteSubmissionConfirm = function(item){
            Modal.confirm.delete($scope.deleteSubmission)(item.title, item);
        };

        $scope.deleteSubmission = function(item){
            console.log("Deleting submission: " + item.title);
            $http.delete('/api/submissions/' + item._id);
            $scope.resetSelection();
        };

        // Controlling editing of status in details view
        $scope.statusEdit = {
            editing: false,
            options: ["Awaiting Adviser Approval", "Approved", "Awaiting Revisions", "Pending Review"],
            temp: {strict: "", text: ""}
        };

        $scope.resetTemps = function() {
            if($scope.selection.item != null){
                $scope.statusEdit.temp.strict = $scope.selection.item.status.strict;
                $scope.statusEdit.temp.text = $scope.selection.item.status.text;
            }
        };

        $scope.resetTemps();

        $scope.editStatus = function(){
            $scope.statusEdit.editing = !$scope.statusEdit.editing;
            $scope.resetTemps();
        };

        $scope.submitStatusEdit = function(){
            $http.patch('api/submissions/' + $scope.selection.item._id,
                {status: {strict: $scope.statusEdit.temp.strict, text: $scope.statusEdit.temp.text}}
            ).success(function(){
                    console.log("Successfully updated status of submission");
            });

            if($scope.selection.item.approval && $scope.statusEdit.temp.strict === "Awaiting Adviser Approval"){
                $http.patch('api/submissions/' + $scope.selection.item._id,
                    {approval: false}
                ).success(function(){
                    $scope.selection.item.approval = false;
                    console.log("Successfully updated approval of submission (un-approved)");
                });
            } else if(!$scope.selection.item.approval && $scope.statusEdit.temp.strict !== "Awaiting Adviser Approval"){
                $http.patch('api/submissions/' + $scope.selection.item._id,
                    {approval: true}
                ).success(function(){
                    $scope.selection.item.approval = true;
                    console.log("Successfully updated approval of submission (approved)");
                });
            }
            sendGmail({
                to: $scope.selection.item.presenterInfo.email,
                subject: 'URS Submission Test',
                message: ''
            });

            $scope.selection.item.status.strict = $scope.statusEdit.temp.strict;
            $scope.selection.item.status.text = $scope.statusEdit.temp.text;
            $scope.resetTemps();
            $scope.editStatus();
        };

        $scope.approvalWordChange = function(approval){
             if(approval){
                 return "Yes";
                 }
             else{
                 return "No";
                 }
             };

    });<|endoftext|>


<commit_before>var io = require("socket.io-client");
var mqtt = require("mqtt");
var util = require('util');
var EventEmitter = require('events').EventEmitter;

function Connection(opt){
  EventEmitter.call(this);
  this.options = opt || {};
  this.socket = io.connect(this.options.host || "http://skynet.im", {
    port: this.options.port || 80
  });

  // mqttclient connection
  if (this.options.protocol == "mqtt") {
    this.mqttsettings = {
      keepalive: 1000,
      protocolId: 'MQIsdp',
      protocolVersion: 3,
      clientId: this.options.uuid
    }

    if (this.options.qos == undefined){
      this.options.qos = 0;
    }

    try {
      this.mqttclient = mqtt.createClient(this.options.mqttport || 1883, this.options.mqtthost || 'mqtt.skynet.im', this.mqttsettings);

      this.mqttclient.subscribe(this.options.uuid, {qos: this.options.qos});
      this.mqttclient.subscribe('broadcast', {qos: this.options.qos});
    } catch(err) {
      console.log(err);
    }
  }

  this.setup();
}

util.inherits(Connection, EventEmitter);

Connection.prototype.setup = function(){
  this.socket.once('connect', function(){
    this.emit('connect');

    if (this.options.protocol == "mqtt"){
      this.mqttclient.on('message', this.emit.bind(this, 'message'));
    } else {
      this.socket.on('message', this.emit.bind(this, 'message'));
    }

    this.socket.on('config', this.emit.bind(this, 'config'));
    this.socket.on('disconnect', this.emit.bind(this, 'disconnect'));
    this.socket.on('identify', this.identify.bind(this));
    this.socket.on('ready', this.emit.bind(this, 'ready'));
    this.socket.on('notReady', this.emit.bind(this, 'notReady'));

  }.bind(this));

  return this;
};

Connection.prototype.identify = function(){
  this.socket.emit('identity', {
    uuid: this.options.uuid,
    token: this.options.token
  });
  return this;
};

// Connection.prototype.send = function(data) {
Connection.prototype.message = function(data) {

  // Send the API request to Skynet
  if (typeof data !== 'object'){
    data = JSON.parse(data);
  }
  data.protocol = this.options.protocol;

  this.socket.emit('message', JSON.stringify(data));

  if (this.options.protocol == "mqtt"){
    // Publish to MQTT
    if(data.devices == "all" || data.devices == "*"){
      this.mqttclient.publish('broadcast', JSON.stringify(data.message), {qos: this.options.qos});
    } else {

      if( typeof data.devices === 'string' ) {
        devices = [ data.devices ];
      } else {
        devices = data.devices;
      };

      for (var i = 0; i < devices.length; i++) {
        this.mqttclient.publish(devices[i], JSON.stringify(data.message), {qos: this.options.qos});
      };

    }
  }

  return this;
};

Connection.prototype.config = function(data, fn) {
  this.socket.emit('gatewayConfig', data, fn);
  return this;
};

Connection.prototype.update = function(data, fn) {
  this.socket.emit('update', data, fn);
  return this;
};

Connection.prototype.register = function(data, fn) {
  this.socket.emit('register', data, fn);
  return this;
};

Connection.prototype.unregister = function(data, fn) {
  this.socket.emit('unregister', data, fn);
  return this;
};

Connection.prototype.whoami = function(data, fn) {
  this.socket.emit('whoami', data, fn);
  return this;
};

Connection.prototype.devices = function(data, fn) {
  this.socket.emit('devices', data, fn);
  return this;
};

Connection.prototype.gatewayConfig = function(data, fn) {
  this.socket.emit('gatewayConfig', data, fn);
  return this;
};

Connection.prototype.status = function(data) {
  this.socket.emit('status', data);
  return this;
};

Connection.prototype.subscribe = function(data, fn) {
  this.socket.emit('subscribe', data, fn);
  if (this.options.protocol == "mqtt") {
    this.mqttclient.subscribe(data.uuid, {qos: this.options.qos});
  }
  return this;
};

Connection.prototype.unsubscribe = function(data, fn) {
  this.socket.emit('unsubscribe', data, fn);
  if (this.options.protocol == "mqtt") {
    this.mqttclient.subscribe(data.uuid);
  }
  return this;
};

Connection.prototype.authenticate = function(data, fn) {
  this.socket.emit('authenticate', data, fn);
  return this;
};

Connection.prototype.events = function(data, fn) {
  this.socket.emit('events', data, fn);
  return this;
};

Connection.prototype.close = function(){
  return this;
};

module.exports = Connection;<commit_msg>added protocol to indentity<commit_after>var io = require("socket.io-client");
var mqtt = require("mqtt");
var util = require('util');
var EventEmitter = require('events').EventEmitter;

function Connection(opt){
  EventEmitter.call(this);
  this.options = opt || {};
  this.socket = io.connect(this.options.host || "http://skynet.im", {
    port: this.options.port || 80
  });

  // mqttclient connection
  if (this.options.protocol == "mqtt") {
    this.mqttsettings = {
      keepalive: 1000,
      protocolId: 'MQIsdp',
      protocolVersion: 3,
      clientId: this.options.uuid
    }

    if (this.options.qos == undefined){
      this.options.qos = 0;
    }

    try {
      this.mqttclient = mqtt.createClient(this.options.mqttport || 1883, this.options.mqtthost || 'mqtt.skynet.im', this.mqttsettings);

      this.mqttclient.subscribe(this.options.uuid, {qos: this.options.qos});
      this.mqttclient.subscribe('broadcast', {qos: this.options.qos});
    } catch(err) {
      console.log(err);
    }
  }

  this.setup();
}

util.inherits(Connection, EventEmitter);

Connection.prototype.setup = function(){
  this.socket.once('connect', function(){
    this.emit('connect');

    if (this.options.protocol == "mqtt"){
      this.mqttclient.on('message', this.emit.bind(this, 'message'));
    } else {
      this.socket.on('message', this.emit.bind(this, 'message'));
    }

    this.socket.on('config', this.emit.bind(this, 'config'));
    this.socket.on('disconnect', this.emit.bind(this, 'disconnect'));
    this.socket.on('identify', this.identify.bind(this));
    this.socket.on('ready', this.emit.bind(this, 'ready'));
    this.socket.on('notReady', this.emit.bind(this, 'notReady'));

  }.bind(this));

  return this;
};

Connection.prototype.identify = function(){
  this.socket.emit('identity', {
    uuid: this.options.uuid,
    token: this.options.token,
    protocol: this.options.protocol
  });
  return this;
};

// Connection.prototype.send = function(data) {
Connection.prototype.message = function(data) {

  // Send the API request to Skynet
  if (typeof data !== 'object'){
    data = JSON.parse(data);
  }
  data.protocol = this.options.protocol;

  this.socket.emit('message', JSON.stringify(data));

  if (this.options.protocol == "mqtt"){
    // Publish to MQTT
    if(data.devices == "all" || data.devices == "*"){
      this.mqttclient.publish('broadcast', JSON.stringify(data.message), {qos: this.options.qos});
    } else {

      if( typeof data.devices === 'string' ) {
        devices = [ data.devices ];
      } else {
        devices = data.devices;
      };

      for (var i = 0; i < devices.length; i++) {
        this.mqttclient.publish(devices[i], JSON.stringify(data.message), {qos: this.options.qos});
      };

    }
  }

  return this;
};

Connection.prototype.config = function(data, fn) {
  this.socket.emit('gatewayConfig', data, fn);
  return this;
};

Connection.prototype.update = function(data, fn) {
  this.socket.emit('update', data, fn);
  return this;
};

Connection.prototype.register = function(data, fn) {
  this.socket.emit('register', data, fn);
  return this;
};

Connection.prototype.unregister = function(data, fn) {
  this.socket.emit('unregister', data, fn);
  return this;
};

Connection.prototype.whoami = function(data, fn) {
  this.socket.emit('whoami', data, fn);
  return this;
};

Connection.prototype.devices = function(data, fn) {
  this.socket.emit('devices', data, fn);
  return this;
};

Connection.prototype.gatewayConfig = function(data, fn) {
  this.socket.emit('gatewayConfig', data, fn);
  return this;
};

Connection.prototype.status = function(data) {
  this.socket.emit('status', data);
  return this;
};

Connection.prototype.subscribe = function(data, fn) {
  this.socket.emit('subscribe', data, fn);
  if (this.options.protocol == "mqtt") {
    this.mqttclient.subscribe(data.uuid, {qos: this.options.qos});
  }
  return this;
};

Connection.prototype.unsubscribe = function(data, fn) {
  this.socket.emit('unsubscribe', data, fn);
  if (this.options.protocol == "mqtt") {
    this.mqttclient.subscribe(data.uuid);
  }
  return this;
};

Connection.prototype.authenticate = function(data, fn) {
  this.socket.emit('authenticate', data, fn);
  return this;
};

Connection.prototype.events = function(data, fn) {
  this.socket.emit('events', data, fn);
  return this;
};

Connection.prototype.close = function(){
  return this;
};

module.exports = Connection;<|endoftext|>


<commit_before>var Settings = {
    //The url that points to team city
    teamCityUrl: 'https://ci.travcorpservices.com',

    //The main branch to show the master build status on the right hand panel on the screen. Leave empty to show the first failed one.
    mainBranch: '',

    //Proxy to handle the cross domain ajax request.
    // This will need to be hosted on the relevant server e.g. proxy-node.js on Node.js or proxy-aspnet.ashx on IIS
    // You could write your own proxy just so long as it is hosted form the same domain as the rest of the app
    proxy: '',

    // If your TeamCity is set up for guest access, you can just use it. Otherwise, the moment that tc-radiate sends first request to TC, TC will
    // ask the user for basic http credentials. Your browser may even offer you to save them.
    useTeamCityGuest: false,

    //How often to call the TeamCity webservices and update the screen
    checkIntervalMs: 5000, //5000 ms = 5 seconds

    //How often to refresh the build image;
    buildImageIntervalMs: 15/*mins*/ * 60*60,

    //use this to stop the screen from updating automatically e.g. if you manually refresh it.
    enableAutoUpdate: true,
}

//Allow the settings to be overridden by querystring parameters
//(url parameters are currently only treated as strings)
jQuery.extend(Settings, UrlParams);

var authType = Settings.useTeamCityGuest ? 'guestAuth' : 'httpAuth';

//----------------------
// TEAM CITY URLS
//----------------------

Settings.restApiBaseUrl = Settings.proxy + Settings.teamCityUrl + '/' + authType + '/app/rest';
//The url for the list of all builds on the left hand side of the screen
Settings.buildsUrl = Settings.restApiBaseUrl + '/builds?locator=running:any,branch:branched:any,count:20';

//The url for the list of build types (used for mapping the build id (e.g. bt11) to the name (e.g. Website Tests)
Settings.buildTypesUrl = Settings.restApiBaseUrl + '/buildTypes';

function getBuildStatusUrlForBranch(branchName) {
    return Settings.restApiBaseUrl + '/builds/branch:' + branchName + ',running:any,canceled:any';
}

function getBuildStatusUrlForBuildId(buildId) {
    return Settings.restApiBaseUrl + '/builds/id:' + buildId;
}<commit_msg>Refresh the image every 15 minutes instead of 15 seconds - Omission in 26656ed6b1f5d74b75a7468ac0481210593199f1<commit_after>var Settings = {
    //The url that points to team city
    teamCityUrl: 'https://ci.travcorpservices.com',

    //The main branch to show the master build status on the right hand panel on the screen. Leave empty to show the first failed one.
    mainBranch: '',

    //Proxy to handle the cross domain ajax request.
    // This will need to be hosted on the relevant server e.g. proxy-node.js on Node.js or proxy-aspnet.ashx on IIS
    // You could write your own proxy just so long as it is hosted form the same domain as the rest of the app
    proxy: '',

    // If your TeamCity is set up for guest access, you can just use it. Otherwise, the moment that tc-radiate sends first request to TC, TC will
    // ask the user for basic http credentials. Your browser may even offer you to save them.
    useTeamCityGuest: false,

    //How often to call the TeamCity webservices and update the screen
    checkIntervalMs: 5000, //5000 ms = 5 seconds

    //How often to refresh the build image;
    buildImageIntervalMs: 15/*mins*/ * 60*60 *1000,

    //use this to stop the screen from updating automatically e.g. if you manually refresh it.
    enableAutoUpdate: true,
}

//Allow the settings to be overridden by querystring parameters
//(url parameters are currently only treated as strings)
jQuery.extend(Settings, UrlParams);

var authType = Settings.useTeamCityGuest ? 'guestAuth' : 'httpAuth';

//----------------------
// TEAM CITY URLS
//----------------------

Settings.restApiBaseUrl = Settings.proxy + Settings.teamCityUrl + '/' + authType + '/app/rest';
//The url for the list of all builds on the left hand side of the screen
Settings.buildsUrl = Settings.restApiBaseUrl + '/builds?locator=running:any,branch:branched:any,count:20';

//The url for the list of build types (used for mapping the build id (e.g. bt11) to the name (e.g. Website Tests)
Settings.buildTypesUrl = Settings.restApiBaseUrl + '/buildTypes';

function getBuildStatusUrlForBranch(branchName) {
    return Settings.restApiBaseUrl + '/builds/branch:' + branchName + ',running:any,canceled:any';
}

function getBuildStatusUrlForBuildId(buildId) {
    return Settings.restApiBaseUrl + '/builds/id:' + buildId;
}<|endoftext|>


<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    uglify: {
      options: {
        banner: '/*! <%= pkg.name.replace(".js", "") %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          'dist/<%= pkg.name.replace(".js", "") %>.min.js': ['dist/<%= pkg.name %>']
        }
      }
    },

    browserify: {
      'dist/radiotag.js': ['src/main.js'],
      options: {
        bundleOptions: {
          standalone: '<%= pkg.name.replace(".js", "") %>'
        }
      }
    },

    jsdoc: {
      dist: {
        src: ['src/*.js', 'src/utils/*.js', 'src/radiotag/*.js'],
        options: {
          destination: 'doc'
        }
      }
    },

    jshint: {
      files: ['src/*.js', 'src/utils/*.js', 'src/radiotag/*.js'],
      options: {
        globals: {
          console: true,
          module: true,
          document: true
        },
        jshintrc: '.jshintrc'
      }
    },

    mocha: {
      test: {
        src: ['test/**/*.html'],
        options: {
          run: true
        }
      }
    },

    watch: {
      files: ['src/*', 'src/utils/*', 'src/radiotag/*.js', 'test/*.js'],
      tasks: ['jshint', 'browserify', 'uglify', 'mocha']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-mocha');
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-jsdoc');

  grunt.registerTask('test', ['jshint', 'mocha']);
  grunt.registerTask('default', ['browserify', 'jshint', 'uglify']);
};
<commit_msg>Fixed grunt test task<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    uglify: {
      options: {
        banner: '/*! <%= pkg.name.replace(".js", "") %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          'dist/<%= pkg.name.replace(".js", "") %>.min.js': ['dist/<%= pkg.name %>']
        }
      }
    },

    browserify: {
      'dist/radiotag.js': ['src/main.js'],
      options: {
        bundleOptions: {
          standalone: '<%= pkg.name.replace(".js", "") %>'
        }
      }
    },

    jsdoc: {
      dist: {
        src: ['src/*.js', 'src/utils/*.js', 'src/radiotag/*.js'],
        options: {
          destination: 'doc'
        }
      }
    },

    jshint: {
      files: ['src/*.js', 'src/utils/*.js', 'src/radiotag/*.js'],
      options: {
        globals: {
          console: true,
          module: true,
          document: true
        },
        jshintrc: '.jshintrc'
      }
    },

    mocha: {
      test: {
        src: ['test/**/*.html'],
        options: {
          run: true
        }
      }
    },

    watch: {
      files: ['src/*', 'src/utils/*', 'src/radiotag/*.js', 'test/*.js'],
      tasks: ['jshint', 'browserify', 'uglify', 'mocha']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-mocha');
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-jsdoc');

  grunt.registerTask('build', ['jshint', 'browserify', 'uglify']);
  grunt.registerTask('test', ['build', 'mocha']);
  grunt.registerTask('default', ['test']);
};
<|endoftext|>


<commit_before>// Components are the smallest unit of event handling and logic
// Components may contain sub-components, but (as of may 12th 2012),
// they are responsible for calling render on those elements
Mast.Component =
{
	/**
         * attributes: properties to be added directly to the component
         *              i.e. accessible from component as:
         *                  this.someThing
         *                  this.someThingElse
         *
         * modelAttributes: properties to be added directly to the component's Model
         *              i.e. accessible from component as:
         *                  this.get('someThing')
         *                  this.get('someThingElse')
         *
         * dontRender: whether or not to render this component when it is instantiated
         *              default: false
         */
	initialize: function(attributes,modelAttributes,dontRender){

		// Bind context
		_.bindAll(this);

		_.extend(this,attributes);

		// Build pattern
		if (!this.pattern) {
			if (!this.template) {
				throw new Error ("No pattern or template selector specified for component!");
			}
			else {
				this.pattern = new Mast.Pattern({
					template: this.template,
					model: this.model ? this.model : new Mast.Model
				});
			}
		}
		else {
			if (this.template || this.model) {
				debug.warn ('A template selector and/or model was specified '+
					' even though a pattern was also specified!! \n'+
					'Ignoring extra attributes and using the specified pattern...');
			}
		}

		// If this belongs to another component, disable autorender
		if (this.parent) {
			this.autorender = false;
		}

		// Maintain dictionary of subcomponents
		this.children = {};

		// Extend model with properties specified
		var me = this;
		_.each(modelAttributes,function(val,key){
			me.pattern.set(key,val);
		});

		// Watch for changes to pattern
		this.pattern.on('change',this.render);

		// Register any subcomponents
		_.each(this.subcomponents,function(properties,key) {
			this.registerSubcomponent(properties,key);
		},this);

		// Trigger init event
		_.result(this,'init');

		// Watch for and announce statechange events
		this.on('afterRender',this.afterRender);
		this.on('beforeRender',this.beforeRender);

		// Autorender is on by default
		// Default render type is "append", but you can also specify "replaceOutlet""
		if (!dontRender && this.autorender!==false) {
			if (this.replaceOutlet) {
				this.replace()
			}
			else {
				this.append();
			}
		}

		// Listen for when the socket is live
		// (unless it's already live)
		if (Mast.Socket) {

			if (!Mast.Socket.connected) {
				Mast.Socket.off('connect', this.afterConnect);
				Mast.Socket.on('connect', this.afterConnect);
			}
			else {
				Mast.Socket.off('connect', this.afterConnect);
				this.afterConnect();
			}
		}
	},

	// Append the pattern to the outlet
	append: function (outlet) {
		var $outlet = this._verifyOutlet(outlet,
			this.parent && this.parent.$el);

		this.render();
		$outlet.append && $outlet.append(this.$el);

		return this;
	},

	// Replace the outlet with the rendered pattern
	replace: function (outlet) {
		var $outlet = this._verifyOutlet(outlet);

		this.setElement($outlet);
		this.render();
		return this;
	},

	// Render the pattern in-place
	render: function (silent) {
		var self = this;
		this.trigger('beforeRender');

		var $element = this.generate();
		this.$el.replaceWith($element);
		this.setElement($element);

		this.renderSubcomponents();

		_.defer(function() {
			if (!silent) {
				self.trigger('afterRender');
			}
		});

		return this;
	},

	renderSubcomponents: function () {
		// If any subcomponents exist,
		_.each(this.children,function(subcomponent,key) {

			// append them to the appropriate outlet
			_.defer(function() {
				subcomponent.append();
			})

		},this);
	},

	// Use pattern to generate a DOM element
	generate: function (data) {
		data = this._normalizeData(data);
		return $(this.pattern.generate(data));
	},

	// Register a new subcomponent from a definition
	registerSubcomponent: function(options,key) {
		var Subcomponent;

		if (!options.component) {
			throw new Error("Cannot register subcomponent because 'component' was not defined!");
		}
		else if ( typeof Mast.components[options.component] == "undefined" ) {
			throw new Error("Cannot register subcomponent because specified component, '"+options.component+"', does not exist!");
		}
		else {
			Subcomponent = options.component;
		}

		// Provision prototype for subcomponent
		Subcomponent = this._provisionPrototype(Subcomponent,Mast.components,Mast.Component)

		// Build property list with specified pieces
		var plist = {
			parent: this,
			outlet: options.outlet
		};
		// Remove stuff from definition that shouldn't be transfered as params
		_.each(options,function(val,key) {
			if (key!='component' && key!='outlet') {
				plist[key]=val;
			}
		});

		// Instantiate subcomponent, but don't append/render it yet
		var subcomponent = new Subcomponent(plist,plist);
		this.children[key] = subcomponent;
	},

	// Free the memory for this component and remove it from the DOM
	destroy: function () {
		// Remove models from modelCache
		this.pattern.model.cid && delete Mast.modelCache[this.pattern.model.cid];
		this.collection && this.collection.cid && delete Mast.modelCache[this.collection.cid];

		this.undelegateEvents();
		this.$el.remove();
	},

	// Set pattern's template selector
	setTemplate: function (selector,options){
		options = _.defaults(options || {}, {
			render: true
		});

		// If a render function is specified, use that
		if (_.isFunction(options.render)) {
			// call custom render function with current and new elements (in the proper scope)
			_.bind(options.render,this);
			options.render(this.$el,this.generate());
		}
		// Otherwise just do a basic render by triggering the default behavior
		else {
			this.pattern.setTemplate(selector,options);
		}
		return this.$el;
	},

	// Set pattern's model attribute
	set: function (attribute,value,options){
		var outcome;
		options = _.defaults(options || {}, {
			render: true
		});

		// If a render function is specified, use that
		if (_.isFunction(options.render)) {
			// call custom render function with current and new elements (in the proper scope)
			this.pattern.set(attribute,value,_.extend(options,{silent:true}));
			_.bind(options.render,this);
			options.render(this.$el,this.generate());
			outcome = true;
		}
		// Otherwise just do a basic render by triggering the default behavior
		else {
			outcome = this.pattern.set(attribute,value,options);
		}
		return outcome;
	},

	save: function () {
		this.pattern.model.save({silent:true});
	},

	get: function(attribute) {
		return this.pattern.get(attribute);
	},

	beforeRender: function(){
	// stub
	},

	afterRender: function(){
	// stub
	},

	afterConnect: function(){
	// stub
	},

	// Default HTML to display if table is empty and no emptytemplate
	// is specified
	emptyHTML: "There are no rows available.",

	// Determine the proper outlet selector and ensure that it is valid
	_verifyOutlet: function (outlet,context) {
		// If a parent component exists, render into that by default
		outlet = outlet || this.outlet || (this.parent && this.parent.$el);

		if (!outlet && !this.parent) {
			throw new Error("No outlet selector specified to render into!");
			return false;
		}

		var $outlet;
		if (_.isString(outlet)) {
			$outlet = (context && context.find(outlet)) || $(outlet);
		}
		else {
			$outlet = outlet;
		}

		if ($outlet.length != 1) {

			//			debug.debug($outlet,outlet,this.parent.$el);
			debug.warn(
				(($outlet.length > 1)?"More than one ":"No ")+
				(($outlet.length > 1)?"element exists ":"elements exist ")+
				(context?"in this template context ("+context+ ")":"") +
				"for the specified "+
				(context?"child ":"") +
				"outlet selector! ('"+outlet+"')");
			return false;
		}

		return $outlet;
	},

	// Accept direct reference to prototype or a string and return a prototype
	_provisionPrototype: function (identity, identitySet, identityPrototype) {

		if (identity && _.isObject(identity) && _.isFunction(identity)) {
			return identity;
		}
		else if (_.isString(identity)) {
			// A string component name
			if (!(identity = (identitySet[identity]))) {
				throw new Error("No identity with that name ("+identity+") exists!");
			}
		}
		else {
			throw new Error ("Invalid identity provided: " + identity);
		}
		return identity;
	},

	// Used for debugging
	_test: function() {
		debug.debug("TEST FUNCTION FIRED!",arguments,this);
	}
}<commit_msg>Bug with Component.save fixed.<commit_after>// Components are the smallest unit of event handling and logic
// Components may contain sub-components, but (as of may 12th 2012),
// they are responsible for calling render on those elements
Mast.Component =
{
	/**
         * attributes: properties to be added directly to the component
         *              i.e. accessible from component as:
         *                  this.someThing
         *                  this.someThingElse
         *
         * modelAttributes: properties to be added directly to the component's Model
         *              i.e. accessible from component as:
         *                  this.get('someThing')
         *                  this.get('someThingElse')
         *
         * dontRender: whether or not to render this component when it is instantiated
         *              default: false
         */
	initialize: function(attributes,modelAttributes,dontRender){

		// Bind context
		_.bindAll(this);

		_.extend(this,attributes);

		// Build pattern
		if (!this.pattern) {
			if (!this.template) {
				throw new Error ("No pattern or template selector specified for component!");
			}
			else {
				this.pattern = new Mast.Pattern({
					template: this.template,
					model: this.model ? this.model : new Mast.Model
				});
			}
		}
		else {
			if (this.template || this.model) {
				debug.warn ('A template selector and/or model was specified '+
					' even though a pattern was also specified!! \n'+
					'Ignoring extra attributes and using the specified pattern...');
			}
		}

		// If this belongs to another component, disable autorender
		if (this.parent) {
			this.autorender = false;
		}

		// Maintain dictionary of subcomponents
		this.children = {};

		// Extend model with properties specified
		var me = this;
		_.each(modelAttributes,function(val,key){
			me.pattern.set(key,val);
		});

		// Watch for changes to pattern
		this.pattern.on('change',this.render);

		// Register any subcomponents
		_.each(this.subcomponents,function(properties,key) {
			this.registerSubcomponent(properties,key);
		},this);

		// Trigger init event
		_.result(this,'init');

		// Watch for and announce statechange events
		this.on('afterRender',this.afterRender);
		this.on('beforeRender',this.beforeRender);

		// Autorender is on by default
		// Default render type is "append", but you can also specify "replaceOutlet""
		if (!dontRender && this.autorender!==false) {
			if (this.replaceOutlet) {
				this.replace()
			}
			else {
				this.append();
			}
		}

		// Listen for when the socket is live
		// (unless it's already live)
		if (Mast.Socket) {

			if (!Mast.Socket.connected) {
				Mast.Socket.off('connect', this.afterConnect);
				Mast.Socket.on('connect', this.afterConnect);
			}
			else {
				Mast.Socket.off('connect', this.afterConnect);
				this.afterConnect();
			}
		}
	},

	// Append the pattern to the outlet
	append: function (outlet) {
		var $outlet = this._verifyOutlet(outlet,
			this.parent && this.parent.$el);

		this.render();
		$outlet.append && $outlet.append(this.$el);

		return this;
	},

	// Replace the outlet with the rendered pattern
	replace: function (outlet) {
		var $outlet = this._verifyOutlet(outlet);

		this.setElement($outlet);
		this.render();
		return this;
	},

	// Render the pattern in-place
	render: function (silent) {
		var self = this;
		this.trigger('beforeRender');

		var $element = this.generate();
		this.$el.replaceWith($element);
		this.setElement($element);

		this.renderSubcomponents();

		_.defer(function() {
			if (!silent) {
				self.trigger('afterRender');
			}
		});

		return this;
	},

	renderSubcomponents: function () {
		// If any subcomponents exist,
		_.each(this.children,function(subcomponent,key) {

			// append them to the appropriate outlet
			_.defer(function() {
				subcomponent.append();
			})

		},this);
	},

	// Use pattern to generate a DOM element
	generate: function (data) {
		data = this._normalizeData(data);
		return $(this.pattern.generate(data));
	},

	// Register a new subcomponent from a definition
	registerSubcomponent: function(options,key) {
		var Subcomponent;

		if (!options.component) {
			throw new Error("Cannot register subcomponent because 'component' was not defined!");
		}
		else if ( typeof Mast.components[options.component] == "undefined" ) {
			throw new Error("Cannot register subcomponent because specified component, '"+options.component+"', does not exist!");
		}
		else {
			Subcomponent = options.component;
		}

		// Provision prototype for subcomponent
		Subcomponent = this._provisionPrototype(Subcomponent,Mast.components,Mast.Component)

		// Build property list with specified pieces
		var plist = {
			parent: this,
			outlet: options.outlet
		};
		// Remove stuff from definition that shouldn't be transfered as params
		_.each(options,function(val,key) {
			if (key!='component' && key!='outlet') {
				plist[key]=val;
			}
		});

		// Instantiate subcomponent, but don't append/render it yet
		var subcomponent = new Subcomponent(plist,plist);
		this.children[key] = subcomponent;
	},

	// Free the memory for this component and remove it from the DOM
	destroy: function () {
		// Remove models from modelCache
		this.pattern.model.cid && delete Mast.modelCache[this.pattern.model.cid];
		this.collection && this.collection.cid && delete Mast.modelCache[this.collection.cid];

		this.undelegateEvents();
		this.$el.remove();
	},

	// Set pattern's template selector
	setTemplate: function (selector,options){
		options = _.defaults(options || {}, {
			render: true
		});

		// If a render function is specified, use that
		if (_.isFunction(options.render)) {
			// call custom render function with current and new elements (in the proper scope)
			_.bind(options.render,this);
			options.render(this.$el,this.generate());
		}
		// Otherwise just do a basic render by triggering the default behavior
		else {
			this.pattern.setTemplate(selector,options);
		}
		return this.$el;
	},

	// Set pattern's model attribute
	set: function (attribute,value,options){
		var outcome;
		options = _.defaults(options || {}, {
			render: true
		});

		// If a render function is specified, use that
		if (_.isFunction(options.render)) {
			// call custom render function with current and new elements (in the proper scope)
			this.pattern.set(attribute,value,_.extend(options,{silent:true}));
			_.bind(options.render,this);
			options.render(this.$el,this.generate());
			outcome = true;
		}
		// Otherwise just do a basic render by triggering the default behavior
		else {
			outcome = this.pattern.set(attribute,value,options);
		}
		return outcome;
	},

	save: function () {
		this.pattern.model.save(null,{silent:true});
	},

	get: function(attribute) {
		return this.pattern.get(attribute);
	},

	beforeRender: function(){
	// stub
	},

	afterRender: function(){
	// stub
	},

	afterConnect: function(){
	// stub
	},

	// Default HTML to display if table is empty and no emptytemplate
	// is specified
	emptyHTML: "There are no rows available.",

	// Determine the proper outlet selector and ensure that it is valid
	_verifyOutlet: function (outlet,context) {
		// If a parent component exists, render into that by default
		outlet = outlet || this.outlet || (this.parent && this.parent.$el);

		if (!outlet && !this.parent) {
			throw new Error("No outlet selector specified to render into!");
			return false;
		}

		var $outlet;
		if (_.isString(outlet)) {
			$outlet = (context && context.find(outlet)) || $(outlet);
		}
		else {
			$outlet = outlet;
		}

		if ($outlet.length != 1) {

			//			debug.debug($outlet,outlet,this.parent.$el);
			debug.warn(
				(($outlet.length > 1)?"More than one ":"No ")+
				(($outlet.length > 1)?"element exists ":"elements exist ")+
				(context?"in this template context ("+context+ ")":"") +
				"for the specified "+
				(context?"child ":"") +
				"outlet selector! ('"+outlet+"')");
			return false;
		}

		return $outlet;
	},

	// Accept direct reference to prototype or a string and return a prototype
	_provisionPrototype: function (identity, identitySet, identityPrototype) {

		if (identity && _.isObject(identity) && _.isFunction(identity)) {
			return identity;
		}
		else if (_.isString(identity)) {
			// A string component name
			if (!(identity = (identitySet[identity]))) {
				throw new Error("No identity with that name ("+identity+") exists!");
			}
		}
		else {
			throw new Error ("Invalid identity provided: " + identity);
		}
		return identity;
	},

	// Used for debugging
	_test: function() {
		debug.debug("TEST FUNCTION FIRED!",arguments,this);
	}
}<|endoftext|>