<commit_before>/*globals define, WebGMEGlobal*/
/*jshint browser: true*/

/**
 * Generated by VisualizerGenerator 0.1.0 from webgme on Sat Apr 16 2016 08:51:41 GMT-0700 (PDT).
 */

define([
    // HTML
    'text!./CodeEditor.html',
    // Codemirror
    'rosmod/Libs/cm/lib/codemirror',
    // Syntax highlighting
    'rosmod/Libs/cm/mode/clike/clike',
    'rosmod/Libs/cm/mode/markdown/markdown',
    // Keymaps
    'rosmod/Libs/cm/keymap/emacs',
    'rosmod/Libs/cm/keymap/sublime',
    'rosmod/Libs/cm/keymap/vim',
    // Addons
    'rosmod/Libs/cm/addon/display/fullscreen',
    'rosmod/Libs/cm/addon/fold/foldcode',
    'rosmod/Libs/cm/addon/fold/foldgutter',
    'rosmod/Libs/cm/addon/fold/brace-fold',
    'rosmod/Libs/cm/addon/fold/xml-fold',
    'rosmod/Libs/cm/addon/fold/markdown-fold',
    'rosmod/Libs/cm/addon/fold/comment-fold',
    // CSS
    'css!./styles/CodeEditorWidget.css',
    'css!rosmod/Libs/cm/addon/display/fullscreen.css',
    'css!rosmod/Libs/cm/theme/night.css',
    'css!rosmod/Libs/cm/lib/codemirror.css',
    'css!rosmod/Libs/cm/theme/3024-day.css',
    'css!rosmod/Libs/cm/theme/3024-night.css',
    'css!rosmod/Libs/cm/theme/abcdef.css',
    'css!rosmod/Libs/cm/theme/ambiance.css',
    'css!rosmod/Libs/cm/theme/base16-dark.css',
    'css!rosmod/Libs/cm/theme/bespin.css',
    'css!rosmod/Libs/cm/theme/base16-light.css',
    'css!rosmod/Libs/cm/theme/blackboard.css',
    'css!rosmod/Libs/cm/theme/cobalt.css',
    'css!rosmod/Libs/cm/theme/colorforth.css',
    'css!rosmod/Libs/cm/theme/dracula.css',
    'css!rosmod/Libs/cm/theme/eclipse.css',
    'css!rosmod/Libs/cm/theme/elegant.css',
    'css!rosmod/Libs/cm/theme/erlang-dark.css',
    'css!rosmod/Libs/cm/theme/hopscotch.css',
    'css!rosmod/Libs/cm/theme/icecoder.css',
    'css!rosmod/Libs/cm/theme/isotope.css',
    'css!rosmod/Libs/cm/theme/lesser-dark.css',
    'css!rosmod/Libs/cm/theme/liquibyte.css',
    'css!rosmod/Libs/cm/theme/material.css',
    'css!rosmod/Libs/cm/theme/mbo.css',
    'css!rosmod/Libs/cm/theme/mdn-like.css',
    'css!rosmod/Libs/cm/theme/midnight.css',
    'css!rosmod/Libs/cm/theme/monokai.css',
    'css!rosmod/Libs/cm/theme/neat.css',
    'css!rosmod/Libs/cm/theme/neo.css',
    'css!rosmod/Libs/cm/theme/night.css',
    'css!rosmod/Libs/cm/theme/paraiso-dark.css',
    'css!rosmod/Libs/cm/theme/paraiso-light.css',
    'css!rosmod/Libs/cm/theme/pastel-on-dark.css',
    'css!rosmod/Libs/cm/theme/railscasts.css',
    'css!rosmod/Libs/cm/theme/rubyblue.css',
    'css!rosmod/Libs/cm/theme/seti.css',
    'css!rosmod/Libs/cm/theme/solarized.css',
    'css!rosmod/Libs/cm/theme/the-matrix.css',
    'css!rosmod/Libs/cm/theme/tomorrow-night-bright.css',
    'css!rosmod/Libs/cm/theme/tomorrow-night-eighties.css',
    'css!rosmod/Libs/cm/theme/ttcn.css',
    'css!rosmod/Libs/cm/theme/twilight.css',
    'css!rosmod/Libs/cm/theme/vibrant-ink.css',
    'css!rosmod/Libs/cm/theme/xq-dark.css',
    'css!rosmod/Libs/cm/theme/xq-light.css',
    'css!rosmod/Libs/cm/theme/yeti.css',
    'css!rosmod/Libs/cm/theme/zenburn.css',
    'css!rosmod/Libs/cm/addon/fold/foldgutter'
], function (
    CodeEditorHtml,
    CodeMirror,
    // Syntax Highlighting
    CodeMirrorModeClike,
    CodeMirrorModeMarkdown,
    // Keymaps
    CodeMirrorEmacsKeymap,
    CodeMirrorSublimeKeymap,
    CodeMirrorVimKeymap,
    // Addons
    CodeMirrorFullScreen,
    CodeMirrorFoldCode,
    CodeMirrorFoldGutter,
    CodeMirrorBraceFold,
    CodeMirrorXMLFold,
    CodeMirrorMarkdownFold,
    CodeMirrorCommentFold) {
    'use strict';

    var CodeEditorWidget,
    WIDGET_CLASS = 'code-editor',
    cmPercent = '94%';

    CodeEditorWidget = function (logger, container, client) {
        this._logger = logger.fork('Widget');
	this._client = client;
        this._el = container;

	$(this._el).css({
	    'padding': '0'
	});

        this.nodes = {};
        this._initialize();

        this._logger.debug('ctor finished');
    };

    CodeEditorWidget.prototype._initialize = function () {
        var width = this._el.width(),
        height = this._el.height(),
        self = this;

        // set widget class
        //this._el.addClass(WIDGET_CLASS);

        // Create the CodeEditor and options
	this._readOnly = this._client.isProjectReadOnly();
	this._fullscreen = false;
        this._el.append(CodeEditorHtml);
	this._container = this._el.find('#CODE_EDITOR_DIV').first();
	this._codearea = this._el.find('#codearea').first();
	this._title = this._el.find('#code_editor_title');
	this.selectedAttribute = '';
	this.selectedNode = '';

	var CodeMirrorEditorOptions = {
	    readOnly: this._readOnly,
	    lineNumbers: true,
	    matchBrackets: true,
	    //viewPortMargin: Infinity,
	    keyMap: 'sublime',
	    path: 'rosmod/Libs/cm/lib/',
	    theme: 'default',
	    fullscreen: false,
	    foldGutter: true,
	    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
	};
	this.editor = new CodeMirror.fromTextArea(
	    this._codearea.get(0),
	    CodeMirrorEditorOptions
	);

	this.editor.on(
	    'changes',
	    _.debounce(this.saveChanges.bind(this), 250) // make sure this doesn't fire more than every 250 ms
	);

	var self=this;
	this.editor.setOption("extraKeys", {
	    'F11': function(cm) {
		//cm.setOption('fullScreen', !cm.getOption('fullScreen'));
		self.fullScreen(!self._fullScreen);
	    },
	    'Esc': function(cm) {
		//cm.setOption('fullScreen', false);
		self.fullScreen(false);
	    },
	    "Ctrl-Q": function(cm){
		cm.foldCode(cm.getCursor());
	    }
	});

	this.editor.foldCode(CodeMirror.Pos(0, 0));
	// THEME SELECT
	this.theme_select = this._el.find("#theme_select").first();
	this.theme_select.on('change', this.selectTheme.bind(this));

	// KEY MAP SELECTION
	this.kb_select = this._el.find("#kb_select").first();
	this.kb_select.on('change', this.selectKeyBinding.bind(this));

	this.buffer_select = this._el.find("#buffer_select").first();
	this.buffer_select.on('change', this.selectBuffer.bind(this));

	this.text = '';
	this.docs = {};
	$('.CodeMirror').css({
	    height: cmPercent
	});
    };

    CodeEditorWidget.prototype.fullScreen = function(toFullScreen) {
	if (toFullScreen) {
	    var container = $(document).find('#CODE_EDITOR_DIV').first();
	    $(container).css({
		position: 'fixed',
		top: '0',
		left: '0',
		width: '100%',
		height: '100%'
	    });
	    $(container).zIndex(9999);
	    $(container).appendTo(document.body);
	    $('.CodeMirror').css({
		height: cmPercent
	    });
	    this.editor.focus();
	    this._fullScreen = true;
	}
	else {
	    var container = $(document).find('#CODE_EDITOR_DIV').first();
	    $(container).css({
		position: '',
		top: '',
		left: '',
		width: '100%',
		height: '100%'
	    });
	    $(container).zIndex('auto');
	    $(container).appendTo(this._el);
	    $('.CodeMirror').css({
		height: cmPercent
	    });
	    this.editor.focus();
	    this._fullScreen = false;
	}
	this.editor.refresh();
    };

    CodeEditorWidget.prototype.saveChanges = function(cm, changes) {
	try {
	    this._client.setAttributes(this.selectedNode, this.selectedAttribute, cm.getValue());
	}
	catch (e) {
	    this._logger.error('Saving META failed!');
	}
    };

    CodeEditorWidget.prototype.updateText = function(newText) {
	this.text = newText;
    };

    CodeEditorWidget.prototype.selectBuffer = function(event) {
	var buffer_select = event.target;
	var newAttribute = buffer_select.options[buffer_select.selectedIndex].textContent;
	if (newAttribute) {
	    var newDoc = this.docs[newAttribute];
	    this.docs[this.selectedAttribute] = this.editor.swapDoc(newDoc);
	    this.selectedAttribute = newAttribute;
	    this.editor.refresh();
	}
    };

    CodeEditorWidget.prototype.selectTheme = function(event) {
	var theme_select = event.target;
	var theme = theme_select.options[theme_select.selectedIndex].textContent;
	this.editor.setOption("theme", theme);
    };

    CodeEditorWidget.prototype.selectKeyBinding = function(event) {
	var kb_select = event.target;
	var binding = kb_select.options[kb_select.selectedIndex].textContent;
	this.editor.setOption("keyMap", binding);
    };

    CodeEditorWidget.prototype.onWidgetContainerResize = function (width, height) {
        console.log('Widget is resizing...');
    };

    // Adding/Removing/Updating items
    CodeEditorWidget.prototype.addNode = function (desc) {
	var self = this;
        if (desc) {
	    $(self._title).append(desc.name);
	    var attributeNames = Object.keys(desc.codeAttributes);
	    if (attributeNames.length > 0) {
		self.nodes[desc.id] = desc;
		self.selectedNode = desc.id;
		attributeNames.map(function(attributeName) {
		    // add the attributes to buffers
		    self.docs[attributeName] = new CodeMirror.Doc(desc.codeAttributes[attributeName].value,
								  desc.codeAttributes[attributeName].mode);
		    $(self.buffer_select).append(new Option(attributeName, attributeName));
		});
		// select the first attribute?
		self.selectedAttribute = attributeNames[0];
		self.editor.swapDoc(self.docs[self.selectedAttribute]);
		self.editor.refresh();
	    }
        }
    };

    CodeEditorWidget.prototype.removeNode = function (gmeId) {
        var desc = this.nodes[gmeId];
	// NEED TO MAKE SURE I HANDLE REMOVE NODE HERE
        delete this.nodes[gmeId];
    };

    CodeEditorWidget.prototype.updateNode = function (desc) {
        if (desc) {
            // console.log('Updating node:', desc);
	    // NEED TO UPDATE THE ATTRIBUTES HERE!
        }
    };

    /* * * * * * * * Visualizer event handlers * * * * * * * */

    CodeEditorWidget.prototype.onNodeClick = function (id) {
        // This currently changes the active node to the given id and
        // this is overridden in the controller.
    };

    /* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
    CodeEditorWidget.prototype.destroy = function () {
    };

    CodeEditorWidget.prototype.onActivate = function () {
        console.log('CodeEditorWidget has been activated');
    };

    CodeEditorWidget.prototype.onDeactivate = function () {
        console.log('CodeEditorWidget has been deactivated');
    };

    return CodeEditorWidget;
});
<commit_msg>added search/replace functionality to editor; highlights matches and has been tested with both sublime and emacs keybindings. closes #68  enjoy @pranav-srinivas-kumar<commit_after>/*globals define, WebGMEGlobal*/
/*jshint browser: true*/

/**
 * Generated by VisualizerGenerator 0.1.0 from webgme on Sat Apr 16 2016 08:51:41 GMT-0700 (PDT).
 */

define([
    // HTML
    'text!./CodeEditor.html',
    // Codemirror
    'rosmod/Libs/cm/lib/codemirror',
    // Syntax highlighting
    'rosmod/Libs/cm/mode/clike/clike',
    'rosmod/Libs/cm/mode/markdown/markdown',
    // Keymaps
    'rosmod/Libs/cm/keymap/emacs',
    'rosmod/Libs/cm/keymap/sublime',
    'rosmod/Libs/cm/keymap/vim',
    // Addons
    'rosmod/Libs/cm/addon/search/search',
    'rosmod/Libs/cm/addon/search/searchcursor',
    'rosmod/Libs/cm/addon/search/matchesonscrollbar',
    'rosmod/Libs/cm/addon/search/jump-to-line',
    'rosmod/Libs/cm/addon/scroll/annotatescrollbar',
    'rosmod/Libs/cm/addon/dialog/dialog',
    'rosmod/Libs/cm/addon/display/fullscreen',
    'rosmod/Libs/cm/addon/fold/foldcode',
    'rosmod/Libs/cm/addon/fold/foldgutter',
    'rosmod/Libs/cm/addon/fold/brace-fold',
    'rosmod/Libs/cm/addon/fold/xml-fold',
    'rosmod/Libs/cm/addon/fold/markdown-fold',
    'rosmod/Libs/cm/addon/fold/comment-fold',
    // CSS
    'css!./styles/CodeEditorWidget.css',
    'css!rosmod/Libs/cm/addon/search/matchesonscrollbar.css',
    'css!rosmod/Libs/cm/addon/dialog/dialog.css',
    'css!rosmod/Libs/cm/addon/display/fullscreen.css',
    'css!rosmod/Libs/cm/theme/night.css',
    'css!rosmod/Libs/cm/lib/codemirror.css',
    'css!rosmod/Libs/cm/theme/3024-day.css',
    'css!rosmod/Libs/cm/theme/3024-night.css',
    'css!rosmod/Libs/cm/theme/abcdef.css',
    'css!rosmod/Libs/cm/theme/ambiance.css',
    'css!rosmod/Libs/cm/theme/base16-dark.css',
    'css!rosmod/Libs/cm/theme/bespin.css',
    'css!rosmod/Libs/cm/theme/base16-light.css',
    'css!rosmod/Libs/cm/theme/blackboard.css',
    'css!rosmod/Libs/cm/theme/cobalt.css',
    'css!rosmod/Libs/cm/theme/colorforth.css',
    'css!rosmod/Libs/cm/theme/dracula.css',
    'css!rosmod/Libs/cm/theme/eclipse.css',
    'css!rosmod/Libs/cm/theme/elegant.css',
    'css!rosmod/Libs/cm/theme/erlang-dark.css',
    'css!rosmod/Libs/cm/theme/hopscotch.css',
    'css!rosmod/Libs/cm/theme/icecoder.css',
    'css!rosmod/Libs/cm/theme/isotope.css',
    'css!rosmod/Libs/cm/theme/lesser-dark.css',
    'css!rosmod/Libs/cm/theme/liquibyte.css',
    'css!rosmod/Libs/cm/theme/material.css',
    'css!rosmod/Libs/cm/theme/mbo.css',
    'css!rosmod/Libs/cm/theme/mdn-like.css',
    'css!rosmod/Libs/cm/theme/midnight.css',
    'css!rosmod/Libs/cm/theme/monokai.css',
    'css!rosmod/Libs/cm/theme/neat.css',
    'css!rosmod/Libs/cm/theme/neo.css',
    'css!rosmod/Libs/cm/theme/night.css',
    'css!rosmod/Libs/cm/theme/paraiso-dark.css',
    'css!rosmod/Libs/cm/theme/paraiso-light.css',
    'css!rosmod/Libs/cm/theme/pastel-on-dark.css',
    'css!rosmod/Libs/cm/theme/railscasts.css',
    'css!rosmod/Libs/cm/theme/rubyblue.css',
    'css!rosmod/Libs/cm/theme/seti.css',
    'css!rosmod/Libs/cm/theme/solarized.css',
    'css!rosmod/Libs/cm/theme/the-matrix.css',
    'css!rosmod/Libs/cm/theme/tomorrow-night-bright.css',
    'css!rosmod/Libs/cm/theme/tomorrow-night-eighties.css',
    'css!rosmod/Libs/cm/theme/ttcn.css',
    'css!rosmod/Libs/cm/theme/twilight.css',
    'css!rosmod/Libs/cm/theme/vibrant-ink.css',
    'css!rosmod/Libs/cm/theme/xq-dark.css',
    'css!rosmod/Libs/cm/theme/xq-light.css',
    'css!rosmod/Libs/cm/theme/yeti.css',
    'css!rosmod/Libs/cm/theme/zenburn.css',
    'css!rosmod/Libs/cm/addon/fold/foldgutter'
], function (
    CodeEditorHtml,
    CodeMirror,
    // Syntax Highlighting
    CodeMirrorModeClike,
    CodeMirrorModeMarkdown,
    // Keymaps
    CodeMirrorEmacsKeymap,
    CodeMirrorSublimeKeymap,
    CodeMirrorVimKeymap,
    // Addons
    CodeMirrorSearch,
    CodeMirrorSearchCursor,
    CodeMirrorMatchesOnScrollbar,
    CodeMirrorJumpToLine,
    CodeMirrorAnnotateScrollbar,
    CodeMirrorDialog,
    CodeMirrorFullScreen,
    CodeMirrorFoldCode,
    CodeMirrorFoldGutter,
    CodeMirrorBraceFold,
    CodeMirrorXMLFold,
    CodeMirrorMarkdownFold,
    CodeMirrorCommentFold) {
    'use strict';

    var CodeEditorWidget,
    WIDGET_CLASS = 'code-editor',
    cmPercent = '94%';

    CodeEditorWidget = function (logger, container, client) {
        this._logger = logger.fork('Widget');
	this._client = client;
        this._el = container;

	$(this._el).css({
	    'padding': '0'
	});

        this.nodes = {};
        this._initialize();

        this._logger.debug('ctor finished');
    };

    CodeEditorWidget.prototype._initialize = function () {
        var width = this._el.width(),
        height = this._el.height(),
        self = this;

        // set widget class
        //this._el.addClass(WIDGET_CLASS);

        // Create the CodeEditor and options
	this._readOnly = this._client.isProjectReadOnly();
	this._fullscreen = false;
        this._el.append(CodeEditorHtml);
	this._container = this._el.find('#CODE_EDITOR_DIV').first();
	this._codearea = this._el.find('#codearea').first();
	this._title = this._el.find('#code_editor_title');
	this.selectedAttribute = '';
	this.selectedNode = '';

	var CodeMirrorEditorOptions = {
	    readOnly: this._readOnly,
	    lineNumbers: true,
	    matchBrackets: true,
	    //viewPortMargin: Infinity,
	    keyMap: 'sublime',
	    path: 'rosmod/Libs/cm/lib/',
	    theme: 'default',
	    fullscreen: false,
	    foldGutter: true,
	    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
	};
	this.editor = new CodeMirror.fromTextArea(
	    this._codearea.get(0),
	    CodeMirrorEditorOptions
	);

	this.editor.on(
	    'changes',
	    _.debounce(this.saveChanges.bind(this), 250) // make sure this doesn't fire more than every 250 ms
	);

	var self=this;
	this.editor.setOption("extraKeys", {
	    'F11': function(cm) {
		//cm.setOption('fullScreen', !cm.getOption('fullScreen'));
		self.fullScreen(!self._fullScreen);
	    },
	    'Esc': function(cm) {
		//cm.setOption('fullScreen', false);
		self.fullScreen(false);
	    },
	    "Ctrl-Q": function(cm){
		cm.foldCode(cm.getCursor());
	    }
	});

	this.editor.foldCode(CodeMirror.Pos(0, 0));
	// THEME SELECT
	this.theme_select = this._el.find("#theme_select").first();
	this.theme_select.on('change', this.selectTheme.bind(this));

	// KEY MAP SELECTION
	this.kb_select = this._el.find("#kb_select").first();
	this.kb_select.on('change', this.selectKeyBinding.bind(this));

	this.buffer_select = this._el.find("#buffer_select").first();
	this.buffer_select.on('change', this.selectBuffer.bind(this));

	this.text = '';
	this.docs = {};
	$('.CodeMirror').css({
	    height: cmPercent
	});
    };

    CodeEditorWidget.prototype.fullScreen = function(toFullScreen) {
	if (toFullScreen) {
	    var container = $(document).find('#CODE_EDITOR_DIV').first();
	    $(container).css({
		position: 'fixed',
		top: '0',
		left: '0',
		width: '100%',
		height: '100%'
	    });
	    $(container).zIndex(9999);
	    $(container).appendTo(document.body);
	    $('.CodeMirror').css({
		height: cmPercent
	    });
	    this.editor.focus();
	    this._fullScreen = true;
	}
	else {
	    var container = $(document).find('#CODE_EDITOR_DIV').first();
	    $(container).css({
		position: '',
		top: '',
		left: '',
		width: '100%',
		height: '100%'
	    });
	    $(container).zIndex('auto');
	    $(container).appendTo(this._el);
	    $('.CodeMirror').css({
		height: cmPercent
	    });
	    this.editor.focus();
	    this._fullScreen = false;
	}
	this.editor.refresh();
    };

    CodeEditorWidget.prototype.saveChanges = function(cm, changes) {
	try {
	    this._client.setAttributes(this.selectedNode, this.selectedAttribute, cm.getValue());
	}
	catch (e) {
	    this._logger.error('Saving META failed!');
	}
    };

    CodeEditorWidget.prototype.updateText = function(newText) {
	this.text = newText;
    };

    CodeEditorWidget.prototype.selectBuffer = function(event) {
	var buffer_select = event.target;
	var newAttribute = buffer_select.options[buffer_select.selectedIndex].textContent;
	if (newAttribute) {
	    var newDoc = this.docs[newAttribute];
	    this.docs[this.selectedAttribute] = this.editor.swapDoc(newDoc);
	    this.selectedAttribute = newAttribute;
	    this.editor.refresh();
	}
    };

    CodeEditorWidget.prototype.selectTheme = function(event) {
	var theme_select = event.target;
	var theme = theme_select.options[theme_select.selectedIndex].textContent;
	this.editor.setOption("theme", theme);
    };

    CodeEditorWidget.prototype.selectKeyBinding = function(event) {
	var kb_select = event.target;
	var binding = kb_select.options[kb_select.selectedIndex].textContent;
	this.editor.setOption("keyMap", binding);
    };

    CodeEditorWidget.prototype.onWidgetContainerResize = function (width, height) {
        console.log('Widget is resizing...');
    };

    // Adding/Removing/Updating items
    CodeEditorWidget.prototype.addNode = function (desc) {
	var self = this;
        if (desc) {
	    $(self._title).append(desc.name);
	    var attributeNames = Object.keys(desc.codeAttributes);
	    if (attributeNames.length > 0) {
		self.nodes[desc.id] = desc;
		self.selectedNode = desc.id;
		attributeNames.map(function(attributeName) {
		    // add the attributes to buffers
		    self.docs[attributeName] = new CodeMirror.Doc(desc.codeAttributes[attributeName].value,
								  desc.codeAttributes[attributeName].mode);
		    $(self.buffer_select).append(new Option(attributeName, attributeName));
		});
		// select the first attribute?
		self.selectedAttribute = attributeNames[0];
		self.editor.swapDoc(self.docs[self.selectedAttribute]);
		self.editor.refresh();
	    }
        }
    };

    CodeEditorWidget.prototype.removeNode = function (gmeId) {
        var desc = this.nodes[gmeId];
	// NEED TO MAKE SURE I HANDLE REMOVE NODE HERE
        delete this.nodes[gmeId];
    };

    CodeEditorWidget.prototype.updateNode = function (desc) {
        if (desc) {
            // console.log('Updating node:', desc);
	    // NEED TO UPDATE THE ATTRIBUTES HERE!
        }
    };

    /* * * * * * * * Visualizer event handlers * * * * * * * */

    CodeEditorWidget.prototype.onNodeClick = function (id) {
        // This currently changes the active node to the given id and
        // this is overridden in the controller.
    };

    /* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
    CodeEditorWidget.prototype.destroy = function () {
    };

    CodeEditorWidget.prototype.onActivate = function () {
        console.log('CodeEditorWidget has been activated');
    };

    CodeEditorWidget.prototype.onDeactivate = function () {
        console.log('CodeEditorWidget has been deactivated');
    };

    return CodeEditorWidget;
});
<|endoftext|>


<commit_before>'use strict';
// Path = String[]
// Path -> String
const pathString = path =>
  `\`${path.join('.')}\``;

// PathError = Path -> Error
// String -> PathError
const pathError = (msg = 'Problem') => path =>
  `${msg} in ${pathString(path)}`;

// Rule[] -> Rule
const composeRules = rules => (data, path) =>
  rules.reduce((errors, rule) =>
    errors.concat(rule(data, path))
  , []);

// (Rule, Rule) -> Rule
const first = (preReq, rule) => (data, path) => {
  const preReqErrors = preReq(data, path);
  if (preReqErrors.length > 0) return preReqErrors;
  return rule(data, path);
};

// ((Data -> Bool), (Data -> PathError)) -> Rule
const checkBool = (checker, error) => (data, path) =>
  checker(data) ? [] : [error(data)(path)];

// Data = Any
// (Data, Exception) -> PathError
const failedCheckError = (data, ex) =>
  pathError(ex.message);

// ((Data -> Void), (Data -> PathError)) -> Rule
const checkThrow = (checker, error = failedCheckError) => (data, path) => {
  try {
    checker(data);
    return [];
  } catch (ex) {
    return [error(data, ex)(path)];
  }
};

// String -> Data -> PathError
const typeError = type => data =>
  pathError(`\`${JSON.stringify(data)}\` is not a valid ${type}`);

// (Any, (Data, Any) -> PathError) -> Rule
const checkType = (
  type, error = typeError
) => (data, path) => (
  data == null || data.constructor !== type ?
  [error(type.name)(data)(path)] :
  []
);

// (Regex, Data -> PathError) -> Rule
const checkRegex = (
  regex, error = () => pathError()
) => first(checkType(String), (data, path) =>
  regex.test(data) ? [] : [error(data)(path)]
);

// Rule -> Rule
const optional = rule => (data, path) =>
  data === undefined ? [] : rule(data, path);

// PathError
const missingKeyError = pathError('Missing required value');

// Rule = (Data, Path) -> Error[]
// (Rule, PathError) -> Rule
const required = (rule, error = missingKeyError) => (data, path) =>
  data === undefined ? [error(path)] : rule(data, path);

// String[] -> PathError
const invalidKeyError = invalidKeys =>
  pathError(`Invalid keys \`${invalidKeys.join('\`, \`')}\` found`);

// (String[] -> (String -> PathError), (Data -> PathError)) -> Rule
const restrictToKeys = (keys, error = invalidKeyError, objectError) =>
  first(checkType(Object, objectError), (data, path) => {
    const invalidKeys = Object.keys(data).filter(key => !keys.includes(key));
    return invalidKeys.length === 0 ? [] : [error(invalidKeys)(path)];
  });

// Schema = {String: Rule}
// (Schema, (Data -> PathError)) -> Rule
const hasSchema = (schema, objectError) => first(checkType(Object, objectError), (data, path) =>
  Object.keys(schema).reduce((errors, key) =>
    errors.concat(schema[key](data[key], path.concat([key])))
  , [])
);

// (Schema, (Data -> PathError), (String -> PathError)) -> Rule
const restrictToSchema = (schema, objectError, invalidKeyError) =>
  first(checkType(Object, objectError), composeRules([
    hasSchema(schema),
    restrictToKeys(Object.keys(schema), invalidKeyError)
  ]));

// (Rule, (Data -> PathError)) -> Rule
const restrictToCollection = (
  rule, error
) => first(checkType(Array, error), (data, path) =>
  data.reduce((errors, elem, index) =>
    errors.concat(rule(index)(elem, path.concat([index])))
  , [])
);

module.exports = {
  pathString,
  pathError,
  typeError,
  composeRules,
  first,
  checkBool,
  checkThrow,
  checkType,
  checkRegex,
  optional,
  required,
  restrictToKeys,
  hasSchema,
  restrictToSchema,
  restrictToCollection,
};
<commit_msg>Fixes code climate issues.<commit_after>'use strict';
// Path = String[]
// Path -> String
const pathString = path =>
  `\`${path.join('.')}\``;

// PathError = Path -> Error
// String -> PathError
const pathError = (msg = 'Problem') => path =>
  `${msg} in ${pathString(path)}`;

// Rule[] -> Rule
const composeRules = rules => (data, path) =>
  rules.reduce((errors, rule) =>
    errors.concat(rule(data, path))
  , []);

// (Rule, Rule) -> Rule
const first = (preReq, rule) => (data, path) => {
  const preReqErrors = preReq(data, path);
  if (preReqErrors.length > 0) return preReqErrors;
  return rule(data, path);
};

// ((Data -> Bool), (Data -> PathError)) -> Rule
const checkBool = (checker, error) => (data, path) =>
  checker(data) ? [] : [error(data)(path)];

// Data = Any
// (Data, Exception) -> PathError
const failedCheckError = (data, ex) =>
  pathError(ex.message);

// ((Data -> Void), (Data -> PathError)) -> Rule
const checkThrow = (checker, error = failedCheckError) => (data, path) => {
  try {
    checker(data);
    return [];
  } catch (ex) {
    return [error(data, ex)(path)];
  }
};

// String -> Data -> PathError
const typeError = type => data =>
  pathError(`\`${JSON.stringify(data)}\` is not a valid ${type}`);

// (Any, (Data, Any) -> PathError) -> Rule
const checkType = (
  type, error = typeError
) => (data, path) => (
  data === undefined || data === null || data.constructor !== type ?
  [error(type.name)(data)(path)] :
  []
);

// (Regex, Data -> PathError) -> Rule
const checkRegex = (
  regex, error = () => pathError()
) => first(checkType(String), (data, path) =>
  regex.test(data) ? [] : [error(data)(path)]
);

// Rule -> Rule
const optional = rule => (data, path) =>
  data === undefined ? [] : rule(data, path);

// PathError
const missingKeyError = pathError('Missing required value');

// Rule = (Data, Path) -> Error[]
// (Rule, PathError) -> Rule
const required = (rule, error = missingKeyError) => (data, path) =>
  data === undefined ? [error(path)] : rule(data, path);

// String[] -> PathError
const invalidKeyError = invalidKeys =>
  pathError(`Invalid keys \`${invalidKeys.join('\`, \`')}\` found`);

// (String[] -> (String -> PathError), (Data -> PathError)) -> Rule
const restrictToKeys = (keys, error = invalidKeyError, objectError) =>
  first(checkType(Object, objectError), (data, path) => {
    const invalidKeys = Object.keys(data).filter(key => !keys.includes(key));
    return invalidKeys.length === 0 ? [] : [error(invalidKeys)(path)];
  });

// Schema = {String: Rule}
// (Schema, (Data -> PathError)) -> Rule
const hasSchema = (schema, objectError) => first(checkType(Object, objectError), (data, path) =>
  Object.keys(schema).reduce((errors, key) =>
    errors.concat(schema[key](data[key], path.concat([key])))
  , [])
);

// (Schema, (Data -> PathError), (String -> PathError)) -> Rule
const restrictToSchema = (schema, objectError, invalidKeyError) =>
  first(checkType(Object, objectError), composeRules([
    hasSchema(schema),
    restrictToKeys(Object.keys(schema), invalidKeyError),
  ]));

// (Rule, (Data -> PathError)) -> Rule
const restrictToCollection = (
  rule, error
) => first(checkType(Array, error), (data, path) =>
  data.reduce((errors, elem, index) =>
    errors.concat(rule(index)(elem, path.concat([index])))
  , [])
);

module.exports = {
  pathString,
  pathError,
  typeError,
  composeRules,
  first,
  checkBool,
  checkThrow,
  checkType,
  checkRegex,
  optional,
  required,
  restrictToKeys,
  hasSchema,
  restrictToSchema,
  restrictToCollection,
};
<|endoftext|>


<commit_before>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const titleSelector = 'h3';
const contentTableSelector = '.tse-content table';

moduleForComponent('light-table-pagination', 'Integration | Component | light table pagination', {
  integration: true,

  beforeEach() {
    this.doNothing = function() {};
    this.set('columns', Ember.A([
      Ember.Object.create({
        displayName: 'Product Name',
        fieldName: 'name',
        order: 0
      }), Ember.Object.create({
        displayName: 'Price',
        fieldName: 'price',
        order: 1
      })
    ]));
    this.set('items', Ember.A([
      {
        id: 1,
        name: 'Watch 1',
        price: 50
      }, {
        id: 2,
        name: 'Bike 1',
        price: 500
      }
    ]));
  }
});

test('it renders correct data', function(assert) {
  this.render(hbs`{{light-table-pagination content=items columns=columns noFiltering=true changePage=(action this.doNothing)}}`);

  assert.equal(this.$(titleSelector).text().trim(), 'title');
  assert.equal(this.$(contentTableSelector).text().trim().replace(/\s+/g, ' '), 'Watch 1 50 Bike 1 500');
});

test('it renders with custom action-cell width', function(assert) {
  this.render(hbs`{{light-table-pagination actionsCellWidth="120px" content=items columns=columns noFiltering=true changePage=(action this.doNothing)}}`);

  const $headerRow = this.$(`${contentTableSelector} tr:first`);
  assert.equal($headerRow.find('td').length, 3, 'Three cells in first row (1 for actions, next 2 for content)');
  assert.equal($headerRow.find('td:first').outerWidth(), 120, 'Action cell is 120px');
});

test('it renders without action columns', function(assert) {
  this.render(hbs`{{light-table-pagination hideActionsColumn=true content=items columns=columns noFiltering=true changePage=(action this.doNothing)}}`);

  const $headerRow = this.$(`${contentTableSelector} tr:first`);
  assert.equal($headerRow.find('td').length, 2, 'Two cells in first row (no actions)');
});
<commit_msg>Add tests for light-table-pagination editCondition<commit_after>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const titleSelector = 'h3';
const contentTableSelector = '.tse-content table';

moduleForComponent('light-table-pagination', 'Integration | Component | light table pagination', {
  integration: true,

  beforeEach() {
    this.doNothing = function() {};
    this.set('columns', Ember.A([
      Ember.Object.create({
        displayName: 'Product Name',
        fieldName: 'name',
        order: 0
      }), Ember.Object.create({
        displayName: 'Price',
        fieldName: 'price',
        order: 1
      })
    ]));
    this.set('items', Ember.A([
      {
        id: 1,
        name: 'Watch 1',
        price: 50
      }, {
        id: 2,
        name: 'Bike 1',
        price: 500
      }
    ]));
  }
});

test('it renders correct data', function(assert) {
  this.render(hbs`{{light-table-pagination content=items columns=columns noFiltering=true changePage=(action this.doNothing)}}`);

  assert.equal(this.$(titleSelector).text().trim(), 'title');
  assert.equal(this.$(contentTableSelector).text().trim().replace(/\s+/g, ' '), 'Watch 1 50 Bike 1 500');
});

test('it renders with custom action-cell width', function(assert) {
  this.render(hbs`{{light-table-pagination actionsCellWidth="120px" content=items columns=columns noFiltering=true changePage=(action this.doNothing)}}`);

  const $headerRow = this.$(`${contentTableSelector} tr:first`);
  assert.equal($headerRow.find('td').length, 3, 'Three cells in first row (1 for actions, next 2 for content)');
  assert.equal($headerRow.find('td:first').outerWidth(), 120, 'Action cell is 120px');
});

test('it renders without action columns', function(assert) {
  this.render(hbs`{{light-table-pagination hideActionsColumn=true content=items columns=columns noFiltering=true changePage=(action this.doNothing)}}`);

  const $headerRow = this.$(`${contentTableSelector} tr:first`);
  assert.equal($headerRow.find('td').length, 2, 'Two cells in first row (no actions)');
});

test('it renders with edit actions in all rows', function(assert) {
  this.set('editCondition', function() {
    return true;
  });
  this.render(hbs`{{light-table-pagination content=items columns=columns noFiltering=true editAction=(action this.doNothing) editCondition=(action this.editCondition) changePage=(action this.doNothing)}}`);

  assert.equal(this.$(contentTableSelector).find('.fa-pencil').length, 2, 'Two edit buttons');

});

test('it renders with edit actions in first row', function(assert) {
  this.set('editCondition', function(row) {
    return row.id == 1;
  });
  this.render(hbs`{{light-table-pagination content=items columns=columns noFiltering=true editAction=(action this.doNothing) editCondition=(action this.editCondition) changePage=(action this.doNothing)}}`);

  assert.equal(this.$(contentTableSelector).find('.fa-pencil').length, 1, 'Edit buttons only in first row');
});<|endoftext|>


<commit_before>module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      prod: {
        src: ['app/assets/js/main.js'],
        dest: 'build/js/main.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      prod: {
        src: ['build/js/main.js'],
        dest: 'build/js/main.min.js',
        compress: true
      }
    },
    less: {
      dev: {
        options: {
          paths: ["app/assets/stylesheets"]
        },
        files: {
          "build/stylesheets/main.css" : "app/assets/stylesheets/main.less"
        }
      },
      prod: {
        options: {
          paths: ["app/assets/stylesheets"]
        },
        files: {
          "build/stylesheets/main.min.css" : "app/assets/stylesheets/main.less"
        },
        compress: true,
        cleancss: true,
        strictimports: true,
      }
    },
    copy: {
      dev: {
        files: [
          {expand: true, src: "app/views/**", dest: "build/", flatten: true, filter: "isFile"},
          {expand: true, src: "app/assets/js/*.js", dest: "build/js/", flatten: true},
          {expand: true, src: "app/assets/images/*", dest: "build/images/", flatten: true},
          {expand: true, src: "bower_components/jquery/dist/jquery.min.js", dest: "build/js/libs", flatten: true}
        ]
      },
      prod: {
        files: [
          {expand: true, src: "app/views/**", dest: "build/", flatten: true, filter: "isFile"},
          {expand: true, src: "app/assets/images/*", dest: "build/images/", flatten: true},
          {expand: true, src: "bower_components/jquery/dist/jquery.min.js", dest: "build/js/libs", flatten: true}
        ]
      }
    },
    processhtml: {
      prod: {
        files: {
          'build/index.html': ['app/views/index.html'],
          'build/codeofconduct.html': ['app/views/codeofconduct.html'],
          'build/opensource.html': ['app/views/opensource.html']
        }
      }
    },
    replace: {
      prod: {
        src: ["build/*.html"],
        overwrite: true,
        replacements: [
          { from: "stylesheets/main.css",
            to: "stylesheets/main.min.css"
          },
          { from: "js/libs/main.js",
            to: "js/libs/main.min.js"
          }
        ]
      }
    },
    clean: ["build/"],
    aws: grunt.file.readJSON('grunt-aws.json'),
    s3: {
      options: {
        key: '<%= aws.key %>',
        secret: '<%= aws.secret %>',
        bucket: '<%= aws.bucket %>',
        access: 'private',
        gzip: true,
        gzipExclude: ['.jpg', '.jpeg', '.png']
      },
      prod: {
        upload: [
          {
            src: 'build/*',
            dest: ''
          },
          {
            src: 'build/js/*.min.js',
            dest: 'js/'
          },
          {
            src: 'build/js/libs/*.min.js',
            dest: 'js/libs/'
          },
          {
            src: 'build/stylesheets/*',
            dest: 'stylesheets/'
          },
          {
            src: 'build/images/*',
            dest: 'images/'
          }
        ]
      }
    },
    'http-server': {
      dev: {
        // the server root directory
        root: "build/",
        port: 8282,
        host: "127.0.0.1",

        cache: 500,
        showDir : true,
        autoIndex: true,
        ext: ["html", "js"],
        runInBackground: false
      }
    },
    watch: {
      coffee: {
        files: ['app/assets/stylesheets/*', 'app/assets/js/*.js', 'app/views/*.html'],
        tasks: ['dev']
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-text-replace');
  grunt.loadNpmTasks('grunt-s3');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-processhtml');
  grunt.loadNpmTasks('grunt-http-server');

  // Default task(s).
  grunt.registerTask('default', 'Building a production build',
    ['clean',
     'concat:prod',
     'uglify:prod',
     'less:prod',
     'copy:prod',
     'processhtml:prod',
     'replace:prod']);

  grunt.registerTask('dev', 'Generating a development build',
    ['clean',
     'less:dev',
     'copy:dev']);

  grunt.registerTask('deploy', 'Uploading to S3',
    ['default',
     's3:prod']);
};<commit_msg>added another page to the commit script<commit_after>module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      prod: {
        src: ['app/assets/js/main.js'],
        dest: 'build/js/main.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      prod: {
        src: ['build/js/main.js'],
        dest: 'build/js/main.min.js',
        compress: true
      }
    },
    less: {
      dev: {
        options: {
          paths: ["app/assets/stylesheets"]
        },
        files: {
          "build/stylesheets/main.css" : "app/assets/stylesheets/main.less"
        }
      },
      prod: {
        options: {
          paths: ["app/assets/stylesheets"]
        },
        files: {
          "build/stylesheets/main.min.css" : "app/assets/stylesheets/main.less"
        },
        compress: true,
        cleancss: true,
        strictimports: true,
      }
    },
    copy: {
      dev: {
        files: [
          {expand: true, src: "app/views/**", dest: "build/", flatten: true, filter: "isFile"},
          {expand: true, src: "app/assets/js/*.js", dest: "build/js/", flatten: true},
          {expand: true, src: "app/assets/images/*", dest: "build/images/", flatten: true},
          {expand: true, src: "bower_components/jquery/dist/jquery.min.js", dest: "build/js/libs", flatten: true}
        ]
      },
      prod: {
        files: [
          {expand: true, src: "app/views/**", dest: "build/", flatten: true, filter: "isFile"},
          {expand: true, src: "app/assets/images/*", dest: "build/images/", flatten: true},
          {expand: true, src: "bower_components/jquery/dist/jquery.min.js", dest: "build/js/libs", flatten: true}
        ]
      }
    },
    processhtml: {
      prod: {
        files: {
          'build/index.html': ['app/views/index.html'],
          'build/codeofconduct.html': ['app/views/codeofconduct.html'],
          'build/opensource.html': ['app/views/opensource.html'],
          'build/workshops.html': ['app/views/workshops.html']
        }
      }
    },
    replace: {
      prod: {
        src: ["build/*.html"],
        overwrite: true,
        replacements: [
          { from: "stylesheets/main.css",
            to: "stylesheets/main.min.css"
          },
          { from: "js/libs/main.js",
            to: "js/libs/main.min.js"
          }
        ]
      }
    },
    clean: ["build/"],
    aws: grunt.file.readJSON('grunt-aws.json'),
    s3: {
      options: {
        key: '<%= aws.key %>',
        secret: '<%= aws.secret %>',
        bucket: '<%= aws.bucket %>',
        access: 'private',
        gzip: true,
        gzipExclude: ['.jpg', '.jpeg', '.png']
      },
      prod: {
        upload: [
          {
            src: 'build/*',
            dest: ''
          },
          {
            src: 'build/js/*.min.js',
            dest: 'js/'
          },
          {
            src: 'build/js/libs/*.min.js',
            dest: 'js/libs/'
          },
          {
            src: 'build/stylesheets/*',
            dest: 'stylesheets/'
          },
          {
            src: 'build/images/*',
            dest: 'images/'
          }
        ]
      }
    },
    'http-server': {
      dev: {
        // the server root directory
        root: "build/",
        port: 8282,
        host: "127.0.0.1",

        cache: 500,
        showDir : true,
        autoIndex: true,
        ext: ["html", "js"],
        runInBackground: false
      }
    },
    watch: {
      coffee: {
        files: ['app/assets/stylesheets/*', 'app/assets/js/*.js', 'app/views/*.html'],
        tasks: ['dev']
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-text-replace');
  grunt.loadNpmTasks('grunt-s3');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-processhtml');
  grunt.loadNpmTasks('grunt-http-server');

  // Default task(s).
  grunt.registerTask('default', 'Building a production build',
    ['clean',
     'concat:prod',
     'uglify:prod',
     'less:prod',
     'copy:prod',
     'processhtml:prod',
     'replace:prod']);

  grunt.registerTask('dev', 'Generating a development build',
    ['clean',
     'less:dev',
     'copy:dev']);

  grunt.registerTask('deploy', 'Uploading to S3',
    ['default',
     's3:prod']);
};
<|endoftext|>


<commit_before>'use strict';

var paths = {
  js: ['*.js', 'test/**/*.js', '!test/coverage/**', '!bower_components/**', 'packages/**/*.js', '!packages/**/node_modules/**', '!packages/contrib/**/*.js', '!packages/contrib/**/node_modules/**'],
  html: ['packages/**/public/**/views/**', 'packages/**/server/views/**'],
  css: ['!bower_components/**', 'packages/**/public/**/css/*.css', '!packages/contrib/**/public/**/css/*.css']
};

module.exports = function(grunt) {

  if (process.env.NODE_ENV !== 'production') {
    require('time-grunt')(grunt);
  }

  // Project Configuration
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    assets: grunt.file.readJSON('config/assets.json'),
    clean: ['bower_components/build'],
    watch: {
      js: {
        files: paths.js,
        tasks: ['jshint'],
        options: {
          livereload: true
        }
      },
      html: {
        files: paths.html,
        options: {
          livereload: true,
          interval: 500
        }
      },
      css: {
        files: paths.css,
        tasks: ['csslint'],
        options: {
          livereload: true
        }
      }
    },
    jshint: {
      all: {
        src: paths.js,
        options: {
          jshintrc: true
        }
      }
    },
    uglify: {
      core: {
        options: {
          mangle: false
        },
        files: '<%= assets.core.js %>'
      }
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      src: paths.css
    },
    cssmin: {
      core: {
        files: '<%= assets.core.css %>'
      }
    },
    nodemon: {
      dev: {
        script: 'server.js',
        options: {
          args: [],
          ignore: ['node_modules/**'],
          ext: 'js,html',
          nodeArgs: ['--debug'],
          delayTime: 1,
          cwd: __dirname
        }
      }
    },
    concurrent: {
      tasks: ['nodemon', 'watch'],
      options: {
        logConcurrentOutput: true
      }
    },
    mochaTest: {
      options: {
        reporter: 'spec',
        require: [
          'server.js',
          function() {
            require('meanio/lib/util').preload(__dirname + '/packages/**/server', 'model');
          }
        ]
      },
      src: ['packages/**/server/tests/**/*.js']
    },
    env: {
      test: {
        NODE_ENV: 'test'
      }
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js'
      }
    }
  });

  //Load NPM tasks
  require('load-grunt-tasks')(grunt);

  //Default task(s).
  if (process.env.NODE_ENV === 'production') {
    grunt.registerTask('default', ['clean', 'cssmin', 'uglify', 'concurrent']);
  } else {
    grunt.registerTask('default', ['clean', 'jshint', 'csslint', 'concurrent']);
  }

  //Test task.
  grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);

  // For Heroku users only.
  // Docs: https://github.com/linnovate/mean/wiki/Deploying-on-Heroku
  grunt.registerTask('heroku:production', ['clean', 'mincss', 'uglify']);
  grunt.registerTask('heroku:development', ['clean', 'mincss']);
};
<commit_msg>I hate you Gruntfile again<commit_after>'use strict';

var paths = {
  js: ['*.js', 'test/**/*.js', '!test/coverage/**', '!bower_components/**', 'packages/**/*.js', '!packages/**/node_modules/**', '!packages/contrib/**/*.js', '!packages/contrib/**/node_modules/**'],
  html: ['packages/**/public/**/views/**', 'packages/**/server/views/**'],
  css: ['!bower_components/**', 'packages/**/public/**/css/*.css', '!packages/contrib/**/public/**/css/*.css']
};

module.exports = function(grunt) {

  if (process.env.NODE_ENV !== 'production') {
    require('time-grunt')(grunt);
  }

  // Project Configuration
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    assets: grunt.file.readJSON('config/assets.json'),
    clean: ['bower_components/build'],
    watch: {
      js: {
        files: paths.js,
        tasks: ['jshint'],
        options: {
          livereload: true
        }
      },
      html: {
        files: paths.html,
        options: {
          livereload: true,
          interval: 500
        }
      },
      css: {
        files: paths.css,
        tasks: ['csslint'],
        options: {
          livereload: true
        }
      }
    },
    jshint: {
      all: {
        src: paths.js,
        options: {
          jshintrc: true
        }
      }
    },
    uglify: {
      core: {
        options: {
          mangle: false
        },
        files: '<%= assets.core.js %>'
      }
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      src: paths.css
    },
    cssmin: {
      core: {
        files: '<%= assets.core.css %>'
      }
    },
    nodemon: {
      dev: {
        script: 'server.js',
        options: {
          args: [],
          ignore: ['node_modules/**'],
          ext: 'js,html',
          nodeArgs: ['--debug'],
          delayTime: 1,
          cwd: __dirname
        }
      }
    },
    concurrent: {
      tasks: ['nodemon', 'watch'],
      options: {
        logConcurrentOutput: true
      }
    },
    mochaTest: {
      options: {
        reporter: 'spec',
        require: [
          'server.js',
          function() {
            require('meanio/lib/util').preload(__dirname + '/packages/**/server', 'model');
          }
        ]
      },
      src: ['packages/**/server/tests/**/*.js']
    },
    env: {
      test: {
        NODE_ENV: 'test'
      }
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js'
      }
    }
  });

  //Load NPM tasks
  require('load-grunt-tasks')(grunt);

  //Default task(s).
  if (process.env.NODE_ENV === 'production') {
    grunt.registerTask('default', ['clean', 'cssmin', 'uglify', 'concurrent']);
  } else {
    grunt.registerTask('default', ['clean', 'jshint', 'csslint', 'concurrent']);
  }

  //Test task.
  grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);

  // For Heroku users only.
  // Docs: https://github.com/linnovate/mean/wiki/Deploying-on-Heroku
  grunt.registerTask('heroku:production', ['clean', 'cssmin', 'uglify']);
  grunt.registerTask('heroku:development', ['clean', 'cssmin']);
};
<|endoftext|>


<commit_before>var debug = false;
if ( debug == true ) {
    $.ajaxSetup({"error":function(XMLHttpRequest,textStatus, errorThrown) {
            alert(textStatus);
            alert(errorThrown);
            alert(XMLHttpRequest.responseText);
        }
    });
}

$(document).ready(function(){

    getIssueList('new');
    getIssueList('popular');
    getIssueList('controversial');
    // hook click event to title
    $("div.title").live("click", function(){
        //find the body whose title was clicked
        var body = $(this).parent().children("div.body");
        //slide the panel
        body.slideToggle();
    });
    // hook click event to abstain vote button
    $("div.abstain").live("click", function(){
        //find the body whose title was clicked
        var body = $(this).parent().parent().parent().children("div.abstainvotes");
        //slide the panel
        body.slideToggle();
    });
    // hook the vote clicks
    $("div.for").live("click", function(){
        isv = $(this).parent().parent().find(".my_vote_issue").attr("value");
        process_vote(isv, 1);
        //find the body whose title was clicked
        var body = $(this).parent().parent().parent().children("div.abstainvotes");
        //slide the panel
        body.slideUp();
    });
    $("div.against").live("click", function(){
        isv = $(this).parent().parent().find(".my_vote_issue").attr("value");
        process_vote(isv, -1);
        //find the body whose title was clicked
        var body = $(this).parent().parent().parent().children("div.abstainvotes");
        //slide the panel
        body.slideUp();
    });
    $("div.abs").live("click", function(){
        votec = $(this).attr('class').split(' ')
        for( var i in votec ) {
            if(votec[i].substr(0,5) == 'vabs-') {
                vote = votec[i].replace(/vabs-/i,"");
            }
        }
        isv = $(this).parent().parent().find(".my_vote_issue").attr("value");
        process_vote(isv, vote);
        $(this).parent().parent().find("div.abstainvotes").hide();
    });
});

function process_vote(issue, new_vote) {
    $old_vote_txt = $("div.i-"+issue).find(".my_vote").val();
    if($old_vote_txt == "None") {
        old_vote = -10;
    }
    else {
        old_vote = parseInt($old_vote_txt);
    }
    if(old_vote == new_vote) {
        return
    }
    else {
        $.post('/ajax/vote/cast/', {
            issue : issue,
            vote : new_vote,
            keep_private : false
        }, function(data) {
            if(data.status=="success"){
                $.get("/totals/"+issue+"/", function(totals) {
                    $("div.i-"+issue).each(function() {
                        $(this).find("div.votes").replaceWith(totals);
                        $("div.i-"+issue).find(".my_vote").html(""+new_vote);
                        render_bars(issue, new_vote);
                    });
                });
            // fix layouts here
            } else if(data.status=="debug") {
                if(debug) {
                    alert(data.error);
                }
            } else {
                handle_errors(data.error);
            }
        }, "json");
    }
}

function render_abs(issue, vote) {
    $(".abs-"+issue).each(function() {
        $(this).children().removeClass('absselected');
    });
    $(".abs-"+issue).find(".vabs-"+vote).addClass('absselected');
}

function render_bars(issue, new_vote){
    var old_vote = parseInt($(".i-"+issue).find(".my_vote").val());
    vote = old_vote;
    // reset the bar colors to their unvoted colors
    $(".i-"+issue).find("div.for").removeClass('forselected');
    $(".i-"+issue).find("div.abstain").removeClass('abstainselected');
    $(".i-"+issue).find("div.against").removeClass('againstselected');
    if(new_vote!=null) {
        vote = new_vote;
    }
    // set voted color, if any
    if(vote ==1) {
        $(".i-"+issue).find("div.for").addClass('forselected');
    }
    if(vote >=10) {
        $(".i-"+issue).find("div.abstain").addClass('abstainselected');
    }
    if(vote ==-1) {
        $(".i-"+issue).find("div.against").addClass('againstselected');
    }
    render_abs(issue, vote);
    // get vote totals
    var vfor = parseInt($(".i-"+issue).find("div.for").html());
    var vabs = parseInt($(".i-"+issue).find("div.abstain").html());
    var vaga = parseInt($(".i-"+issue).find("div.against").html());
    //alert (vfor+" "+vabs+" "+vaga);
    // update vote totals, subtract from old vote totals and reset colors.
    if(new_vote != null) {
        $(".i-"+issue).find("div.for").html(""+vfor);
        $(".i-"+issue).find("div.abstain").html(""+vabs);
        $(".i-"+issue).find("div.against").html(""+vaga);
        $(".i-"+issue).find(".my_vote").val(new_vote);
    }
    var total = vfor + vabs + vaga;
    var per = new Array();
    per['for'] = vfor / total;
    per['abs'] = vabs / total;
    per['aga'] = vaga / total;
    var biggest = "none";
    var big = 0;
    for (var i in per) {
        if(per[i] > big) {
            big = per[i];
            biggest = i;
        }
    }
    for (var i in per) {
        if(per[i] < 0.1) {
            per[biggest] -= (0.1 - per[i]);
            per[i] = 0.1;
        }
    }
    for (var i in per) {
        per[i] = per[i]*100;
    }
    $(".i-"+issue).find("div.for").width(per['for']+"%");
    $(".i-"+issue).find("div.abstain").width(per['abs']+"%");
    $(".i-"+issue).find("div.against").width(per['aga']+"%");
}

function handle_errors(error) {
    if(error == "Must be logged in.") {
        window.location = "/login/";
    }
    if(error == "Must have access token.") {
        window.location = "/oauth/auth/";
    }
}
function getIssueList(sortorder) {
    $.getJSON("/ajax/issues/"+sortorder+"/", function(data) {
        for( var i in data ) {
            id = url2id(data[i][0]);
            getIssue(sortorder, id);
        }
    });
    $("div.abstainvotes").hide();
    $("div#"+sortorder)
        .hide();
    $("div."+sortorder).mouseup(function() {
        var body = $(this).parent().find("div#"+sortorder);
        body.slideToggle();
    });
}

function getIssue(sortorder, issueid) {
    // get the issue content
    $.get("/issue/"+issueid+"/", function(issue) {
        $(issue).appendTo("div#"+sortorder);
        // get user's current vote.
        $.get("/myvote/"+issueid+"/", function (myvote) {
            $("div#"+sortorder)
                .find("div.p-"+issueid)
                .append(myvote);
            mv = $(".my_vote",myvote).attr('value');
            if(mv != "None") {
                $.get("/totals/"+issueid+"/", function (totals) {
                    $("div#"+sortorder)
                        .find(".v-"+issueid)
                        .replaceWith(totals);
                    render_bars(issueid, null);
                });
            }
        });
        $("div#"+sortorder).find(".i-"+issueid).find("div.body").hide();
        $("div#"+sortorder).find(".i-"+issueid).find("div.abstainvotes").hide();
    });
}

function url2id(url) {
    return url.split(/\//)[4];
}

<commit_msg>fixed the bars with a simpler solution.<commit_after>var debug = false;
if ( debug == true ) {
    $.ajaxSetup({"error":function(XMLHttpRequest,textStatus, errorThrown) {
            alert(textStatus);
            alert(errorThrown);
            alert(XMLHttpRequest.responseText);
        }
    });
}

$(document).ready(function(){

    getIssueList('new');
    getIssueList('popular');
    getIssueList('controversial');
    // hook click event to title
    $("div.title").live("click", function(){
        //find the body whose title was clicked
        var body = $(this).parent().children("div.body");
        //slide the panel
        body.slideToggle();
    });
    // hook click event to abstain vote button
    $("div.abstain").live("click", function(){
        //find the body whose title was clicked
        var body = $(this).parent().parent().parent().children("div.abstainvotes");
        //slide the panel
        body.slideToggle();
    });
    // hook the vote clicks
    $("div.for").live("click", function(){
        isv = $(this).parent().parent().find(".my_vote_issue").attr("value");
        process_vote(isv, 1);
        //find the body whose title was clicked
        var body = $(this).parent().parent().parent().children("div.abstainvotes");
        //slide the panel
        body.slideUp();
    });
    $("div.against").live("click", function(){
        isv = $(this).parent().parent().find(".my_vote_issue").attr("value");
        process_vote(isv, -1);
        //find the body whose title was clicked
        var body = $(this).parent().parent().parent().children("div.abstainvotes");
        //slide the panel
        body.slideUp();
    });
    $("div.abs").live("click", function(){
        votec = $(this).attr('class').split(' ')
        for( var i in votec ) {
            if(votec[i].substr(0,5) == 'vabs-') {
                vote = votec[i].replace(/vabs-/i,"");
            }
        }
        isv = $(this).parent().parent().find(".my_vote_issue").attr("value");
        process_vote(isv, vote);
        $(this).parent().parent().find("div.abstainvotes").hide();
    });
});

function process_vote(issue, new_vote) {
    $old_vote_txt = $("div.i-"+issue).find(".my_vote").val();
    if($old_vote_txt == "None") {
        old_vote = -10;
    }
    else {
        old_vote = parseInt($old_vote_txt);
    }
    if(old_vote == new_vote) {
        return
    }
    else {
        $.post('/ajax/vote/cast/', {
            issue : issue,
            vote : new_vote,
            keep_private : false
        }, function(data) {
            if(data.status=="success"){
                $.get("/totals/"+issue+"/", function(totals) {
                    $("div.i-"+issue).each(function() {
                        $(this).find("div.votes").replaceWith(totals);
                        $("div.i-"+issue).find(".my_vote").html(""+new_vote);
                        render_bars(issue, new_vote);
                    });
                });
            // fix layouts here
            } else if(data.status=="debug") {
                if(debug) {
                    alert(data.error);
                }
            } else {
                handle_errors(data.error);
            }
        }, "json");
    }
}

function render_abs(issue, vote) {
    $(".abs-"+issue).each(function() {
        $(this).children().removeClass('absselected');
    });
    $(".abs-"+issue).find(".vabs-"+vote).addClass('absselected');
}

function render_bars(issue, new_vote){
    var old_vote = parseInt($(".i-"+issue).find(".my_vote").val());
    vote = old_vote;
    // reset the bar colors to their unvoted colors
    $(".i-"+issue).find("div.for").removeClass('forselected');
    $(".i-"+issue).find("div.abstain").removeClass('abstainselected');
    $(".i-"+issue).find("div.against").removeClass('againstselected');
    if(new_vote!=null) {
        vote = new_vote;
    }
    // set voted color, if any
    if(vote ==1) {
        $(".i-"+issue).find("div.for").addClass('forselected');
    }
    if(vote >=10) {
        $(".i-"+issue).find("div.abstain").addClass('abstainselected');
    }
    if(vote ==-1) {
        $(".i-"+issue).find("div.against").addClass('againstselected');
    }
    render_abs(issue, vote);
    // get vote totals
    var vfor = parseInt($(".i-"+issue).find("div.for").html());
    var vabs = parseInt($(".i-"+issue).find("div.abstain").html());
    var vaga = parseInt($(".i-"+issue).find("div.against").html());
    // Get the percentages to make the bars the right size.
    var total = vfor + vabs + vaga;
    var per = new Array();
    per['for'] = vfor / total;
    per['abs'] = vabs / total;
    per['aga'] = vaga / total;
    // The following is not a graceful solution... the minimum width is never
    // 10% unless the vote total of one of the votes is 0. I would like to see
    // a nicer solution for an arbitrary set of values (more than 3 types)
    //
    // Please mail, if you find one: Conrado Buhrer - conrado@buhrer.net
    for (var i in per) {
        per[i] = 10+ (per[i]*70);
    }
    $(".i-"+issue).find("div.for").width(per['for']+"%");
    $(".i-"+issue).find("div.abstain").width(per['abs']+"%");
    $(".i-"+issue).find("div.against").width(per['aga']+"%");
}

function handle_errors(error) {
    if(error == "Must be logged in.") {
        window.location = "/login/";
    }
    if(error == "Must have access token.") {
        window.location = "/oauth/auth/";
    }
}
function getIssueList(sortorder) {
    $.getJSON("/ajax/issues/"+sortorder+"/", function(data) {
        for( var i in data ) {
            id = url2id(data[i][0]);
            getIssue(sortorder, id);
        }
    });
    $("div.abstainvotes").hide();
    $("div#"+sortorder)
        .hide();
    $("div."+sortorder).mouseup(function() {
        var body = $(this).parent().find("div#"+sortorder);
        body.slideToggle();
    });
}

function getIssue(sortorder, issueid) {
    // get the issue content
    $.get("/issue/"+issueid+"/", function(issue) {
        $(issue).appendTo("div#"+sortorder);
        // get user's current vote.
        $.get("/myvote/"+issueid+"/", function (myvote) {
            $("div#"+sortorder)
                .find("div.p-"+issueid)
                .append(myvote);
            mv = $(".my_vote",myvote).attr('value');
            if(mv != "None") {
                $.get("/totals/"+issueid+"/", function (totals) {
                    $("div#"+sortorder)
                        .find(".v-"+issueid)
                        .replaceWith(totals);
                    render_bars(issueid, null);
                });
            }
        });
        $("div#"+sortorder).find(".i-"+issueid).find("div.body").hide();
        $("div#"+sortorder).find(".i-"+issueid).find("div.abstainvotes").hide();
    });
}

function url2id(url) {
    return url.split(/\//)[4];
}

<|endoftext|>


<commit_before>'use strict';

var path = require('path');

module.exports = function (grunt) {

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  var conf = require('./Gruntfile.conf.js');

  grunt.initConfig({

    // Load Config
    config: conf,

    // Testing
    karma: {
      options: {
        configFile: 'karma.conf.js',
        files: [
          'bower_components/es5-shim/es5-shim.js',
          'bower_components/angular/angular.js',
          'bower_components/angular-mocks/angular-mocks.js',
          conf.src,
          conf.unit
        ]
      },
      unit: {
        options: {
          browsers: [
            'Chrome'
          ]
        },
        background: true
      },
      continuous: {
        options: {
          browsers: [
            'PhantomJS'
          ]
        },
        singleRun: true
      }
    },

    // Validation
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= config.src %>',
        '<%= config.unit %>',
        '<%= config.e2e %>'
      ]
    },

    // Developing
    watch: {
      gruntfile: {
        files: ['Gruntfile.js'],
        tasks: ['build']
      },
      js: {
        files: ['<%= config.src %>', '<%= config.unit %>'],
        tasks: ['concat', 'karma:unit:run', 'jshint']
      },
      less: {
        files: ['<%= config.less %>'],
        tasks: ['less:dev']
      },
      livereload: {
        options: {
          livereload: true
        },
        files: ['<%= config.dist %>', 'src/**/*.css']
      }
    },

    express: {
      server: {
        options: {
          hostname: '*',
          debug: true,
          livereload: true,
          port: 9001,
          server: path.resolve('./example/server')
        }
      }
    },

    // Building
    clean: {
      dist: {
        files: '<%= config.dist %>'
      }
    },

    concat: {
      dev: {
        files: {
          '<%= config.dist %>': '<%= config.src %>'
        }
      }
    },

    ngmin: {
      dist: {
        files: {
          '<%= config.dist %>': '<%= config.dist %>'
        }
      }
    },

    uglify: {
      dist: {
        files: {
          '<%= config.minified %>': '<%= config.dist %>'
        },
        options: {
          compress: true
        }
      }
    },

    less: {
      dev: {
        files: [{
          expand: true,
          ext: '.min.css',
          src: ['<%= config.less %>']
        }]
      },
      dist: {
        options: {
          yuicompress: true
        },
        files: [{
          expand: true,
          ext: '.min.css',
          src: ['<%= config.less %>']
        }]
      }
    },

    // Releasing
    bump: {
      options: {
        files: [
          'package.json',
          'bower.json'
        ],
        updateConfigs: [],
        commit: true,
        commitMessage: 'Cut %VERSION%',
        commitFiles: [
          'CHANGELOG.md',
          'src/directives/btnUpload.less',
          'src/directives/btnUpload.min.css',
          'angular-upload.js',
          'angular-upload.min.js'
        ],
        createTag: true,
        tagName: '%VERSION%',
        tagMessage: 'Version %VERSION%',
        push: true,
        pushTo: 'origin',
        gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
      }
    }
  });

  grunt.registerTask('test', [
    'jshint',
    'karma:continuous'
  ]);

  grunt.registerTask('webserver', [
    'concat',
    'less:dev',
    'jshint',
    'express',
    'watch',
  ]);

  grunt.registerTask('autotest', [
    'concat',
    'karma:unit',
    'karma:unit:run',
    'watch'
  ]);

  grunt.registerTask('package', [
    'clean:dist',
    'concat',
    'ngmin:dist',
    'uglify:dist',
    'less:dist'
  ]);

  grunt.registerTask('default', [
    'package',
    'test'
  ]);

  grunt.registerTask('travis', [
    'jshint',
    'test'
  ]);

  grunt.registerTask('release', [
    'package',
    'bump'
  ])

};
<commit_msg>More Grunt bump<commit_after>'use strict';

var path = require('path');

module.exports = function (grunt) {

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  var conf = require('./Gruntfile.conf.js');

  grunt.initConfig({

    // Load Config
    config: conf,

    // Testing
    karma: {
      options: {
        configFile: 'karma.conf.js',
        files: [
          'bower_components/es5-shim/es5-shim.js',
          'bower_components/angular/angular.js',
          'bower_components/angular-mocks/angular-mocks.js',
          conf.src,
          conf.unit
        ]
      },
      unit: {
        options: {
          browsers: [
            'Chrome'
          ]
        },
        background: true
      },
      continuous: {
        options: {
          browsers: [
            'PhantomJS'
          ]
        },
        singleRun: true
      }
    },

    // Validation
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= config.src %>',
        '<%= config.unit %>',
        '<%= config.e2e %>'
      ]
    },

    // Developing
    watch: {
      gruntfile: {
        files: ['Gruntfile.js'],
        tasks: ['build']
      },
      js: {
        files: ['<%= config.src %>', '<%= config.unit %>'],
        tasks: ['concat', 'karma:unit:run', 'jshint']
      },
      less: {
        files: ['<%= config.less %>'],
        tasks: ['less:dev']
      },
      livereload: {
        options: {
          livereload: true
        },
        files: ['<%= config.dist %>', 'src/**/*.css']
      }
    },

    express: {
      server: {
        options: {
          hostname: '*',
          debug: true,
          livereload: true,
          port: 9001,
          server: path.resolve('./example/server')
        }
      }
    },

    // Building
    clean: {
      dist: {
        files: '<%= config.dist %>'
      }
    },

    concat: {
      dev: {
        files: {
          '<%= config.dist %>': '<%= config.src %>'
        }
      }
    },

    ngmin: {
      dist: {
        files: {
          '<%= config.dist %>': '<%= config.dist %>'
        }
      }
    },

    uglify: {
      dist: {
        files: {
          '<%= config.minified %>': '<%= config.dist %>'
        },
        options: {
          compress: true
        }
      }
    },

    less: {
      dev: {
        files: [{
          expand: true,
          ext: '.min.css',
          src: ['<%= config.less %>']
        }]
      },
      dist: {
        options: {
          yuicompress: true
        },
        files: [{
          expand: true,
          ext: '.min.css',
          src: ['<%= config.less %>']
        }]
      }
    },

    // Releasing
    bump: {
      options: {
        files: [
          'package.json',
          'bower.json'
        ],
        updateConfigs: [],
        commit: true,
        commitMessage: '%VERSION%',
        commitFiles: [
          'CHANGELOG.md',
          'package.json',
          'bower.json',
          'src/directives/btnUpload.less',
          'src/directives/btnUpload.min.css',
          'angular-upload.js',
          'angular-upload.min.js'
        ],
        createTag: true,
        tagName: '%VERSION%',
        tagMessage: 'Version %VERSION%',
        push: true,
        pushTo: 'origin',
        gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
      }
    }
  });

  grunt.registerTask('test', [
    'jshint',
    'karma:continuous'
  ]);

  grunt.registerTask('webserver', [
    'concat',
    'less:dev',
    'jshint',
    'express',
    'watch',
  ]);

  grunt.registerTask('autotest', [
    'concat',
    'karma:unit',
    'karma:unit:run',
    'watch'
  ]);

  grunt.registerTask('package', [
    'clean:dist',
    'concat',
    'ngmin:dist',
    'uglify:dist',
    'less:dist'
  ]);

  grunt.registerTask('default', [
    'package',
    'test'
  ]);

  grunt.registerTask('travis', [
    'jshint',
    'test'
  ]);

  grunt.registerTask('release', [
    'package',
    'bump'
  ])

};
<|endoftext|>


<commit_before>var shelljs = require('shelljs');

module.exports = function(grunt) {
    grunt.initConfig({
        compass: {
            compile: { },
            dev: {
                options: {
                    outputStyle: 'expanded'
                }
            },
            options: {
                bundleExec: true,
                config: 'assets/scss/compass_config.rb'
            }
        },
        jshint: {
            all: ['assets/js/**/*.js', 'assets/js-test/**/*.js']
        },
        karma: {
            unit: {
                configFile: 'assets/js-test/karma.conf.js'
            }
        },
        requirejs: {
            compile: {
                options: {
                    optimize: 'uglify2',
                    generateSourceMaps: true,
                    preserveLicenseComments: false
                }
            },
            dev: {
                options: {
                    optimize: 'none'
                }
            },
            options: {
                baseUrl: 'assets/js/',
                name: 'project/main',
                out: 'deploy/site-cookbooks/manchesterio/files/default/static/scripts/project.js',
                paths: {
                    requireLib: '../../bower_components/requirejs/require'
                },
                include: ['requireLib']
            }
        },
        scsslint: {
            all: ['assets/scss/**/*.scss'],
            options: {
                bundleExec: true
            }
        },
        watch: {
            grunt: {
                files: ['Gruntfile.js'],
                options: { reload: true }
            },
            gemfile: {
                files: ['Gemfile'],
                tasks: ['boostrap-compass']
            },
            bower: {
                files: ['bower.json'],
                tasks: ['bower']
            },
            scripts: {
                files: ['assets/js/**/*.js', 'assets/js-test/**/*.js'],
                tasks: ['scripts-dev']
            },
            styles: {
                files: ['assets/scss/compass_config.rb', 'assets/scss/**/*.scss'],
                tasks: ['styles-dev']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-requirejs');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-scss-lint');

    grunt.registerTask('bower', function() {
        shelljs.exec('node_modules/bower/bin/bower install');
    });

    grunt.registerTask('bootstrap-compass', function() {
        shelljs.exec('bundle install');
    });

    grunt.registerTask('default', ['bower', 'bootstrap-compass', 'styles', 'scripts']);
    grunt.registerTask('dev', ['bower', 'bootstrap-compass', 'styles-dev', 'scripts-dev', 'watch']);

    grunt.registerTask('scripts', ['karma:unit', 'requirejs:compile', 'jshint:all']);
    grunt.registerTask('scripts-dev', ['karma:unit', 'requirejs:dev', 'jshint:all']);

    grunt.registerTask('styles', ['compass:compile', 'scsslint:all']);
    grunt.registerTask('styles-dev', ['compass:dev', 'scsslint:all']);

};
<commit_msg>Fix Grunt errors<commit_after>var shelljs = require('shelljs');

module.exports = function(grunt) {
    grunt.initConfig({
        compass: {
            compile: { },
            dev: {
                options: {
                    outputStyle: 'expanded'
                }
            },
            options: {
                bundleExec: true,
                config: 'assets/scss/compass_config.rb'
            }
        },
        jshint: {
            all: ['assets/js/**/*.js', 'assets/js-test/**/*.js']
        },
        karma: {
            unit: {
                configFile: 'assets/js-test/karma.conf.js'
            }
        },
        requirejs: {
            compile: {
                options: {
                    optimize: 'uglify2',
                    generateSourceMaps: true,
                    preserveLicenseComments: false
                }
            },
            dev: {
                options: {
                    optimize: 'none'
                }
            },
            options: {
                baseUrl: 'assets/js/',
                name: 'manchesterio/main',
                out: 'deploy/site-cookbooks/manchesterio/files/default/static/scripts/manchesterio.js',
                paths: {
                    requireLib: '../../bower_components/requirejs/require'
                },
                include: ['requireLib']
            }
        },
        scsslint: {
            all: ['assets/scss/**/*.scss'],
            options: {
                bundleExec: true,
                config: undefined
            }
        },
        watch: {
            grunt: {
                files: ['Gruntfile.js'],
                options: { reload: true }
            },
            gemfile: {
                files: ['Gemfile'],
                tasks: ['boostrap-compass']
            },
            bower: {
                files: ['bower.json'],
                tasks: ['bower']
            },
            scripts: {
                files: ['assets/js/**/*.js', 'assets/js-test/**/*.js'],
                tasks: ['scripts-dev']
            },
            styles: {
                files: ['assets/scss/compass_config.rb', 'assets/scss/**/*.scss'],
                tasks: ['styles-dev']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-requirejs');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-scss-lint');

    grunt.registerTask('bower', function() {
        shelljs.exec('node_modules/bower/bin/bower install');
    });

    grunt.registerTask('bootstrap-compass', function() {
        shelljs.exec('bundle install');
    });

    grunt.registerTask('default', ['bower', 'bootstrap-compass', 'styles', 'scripts']);
    grunt.registerTask('dev', ['bower', 'bootstrap-compass', 'styles-dev', 'scripts-dev', 'watch']);

    grunt.registerTask('scripts', ['karma:unit', 'requirejs:compile', 'jshint:all']);
    grunt.registerTask('scripts-dev', ['karma:unit', 'requirejs:dev', 'jshint:all']);

    grunt.registerTask('styles', ['compass:compile', 'scsslint:all']);
    grunt.registerTask('styles-dev', ['compass:dev', 'scsslint:all']);

};
<|endoftext|>


<commit_before>var React = require('react');
var stringify = require('json-stringify-pretty-compact');

function isDefaultProp(defaultProps, key, value) {
  if (!defaultProps) {
    return false;
  }
  return defaultProps[key] === value;
}

function jsxToString(component, options) {

  let componentData = {
    name: component.type.displayName || component.type.name || component.type
  };

  let opts = Object.assign({
    spacing: 0,
    keyValueOverride: {},
    ignoreProps: []
  }, options);

  if (component.props) {
    componentData.props = Object.keys(component.props).map(
      (key) => {
        if (key === 'children' ||
          isDefaultProp(component.type.defaultProps, key, component.props[key]) ||
          opts.ignoreProps.includes(key)) {
          return '';
        } else {
          let value = component.props[key];
          if (typeof value === 'string') {
            return ` ${key}="${value}"`;
          } else if (React.isValidElement(value)) {
            value = jsxToString(value, opts);
          } else if (typeof value === 'object') {
            value = stringify(value);
          } else if (typeof value === 'function') {
            value = '...';
          }
          return ` ${key}={${opts.keyValueOverride[key] || value}}`
        }
      }
    ).join('');
  }

  if (component.props.children) {
    opts.spacing += 2;
    let indentation = new Array(opts.spacing + 1).join(' ');
    if (typeof component.props.children === 'string') {
      componentData.children = component.props.children;
    } else if (typeof component.props.children === 'object' &&
      !Array.isArray(component.props.children)) {
      componentData.children = jsxToString(component.props.children, opts);
    } else {
      componentData.children = component.props.children.map((child) => {
        if (typeof child === 'string') {
          return child;
        } else {
          return jsxToString(child, opts);
        }
      }).join(`\n${indentation}`);
    }
    return `<${componentData.name}${componentData.props}>\n${indentation}${componentData.children}\n${indentation.slice(0, -2)}</${componentData.name}>`;
  } else {
    return `<${componentData.name}${componentData.props} />`;
  }
};

export default jsxToString;
<commit_msg>Replace [].includes with [].indexOf<commit_after>var React = require('react');
var stringify = require('json-stringify-pretty-compact');

function isDefaultProp(defaultProps, key, value) {
  if (!defaultProps) {
    return false;
  }
  return defaultProps[key] === value;
}

function jsxToString(component, options) {

  let componentData = {
    name: component.type.displayName || component.type.name || component.type
  };

  let opts = Object.assign({
    spacing: 0,
    keyValueOverride: {},
    ignoreProps: []
  }, options);

  if (component.props) {
    componentData.props = Object.keys(component.props).map(
      (key) => {
        if (key === 'children' ||
          isDefaultProp(component.type.defaultProps, key, component.props[key]) ||
            opts.ignoreProps.indexOf(key) > -1) {
          return '';
        } else {
          let value = component.props[key];
          if (typeof value === 'string') {
            return ` ${key}="${value}"`;
          } else if (React.isValidElement(value)) {
            value = jsxToString(value, opts);
          } else if (typeof value === 'object') {
            value = stringify(value);
          } else if (typeof value === 'function') {
            value = '...';
          }
          return ` ${key}={${opts.keyValueOverride[key] || value}}`
        }
      }
    ).join('');
  }

  if (component.props.children) {
    opts.spacing += 2;
    let indentation = new Array(opts.spacing + 1).join(' ');
    if (typeof component.props.children === 'string') {
      componentData.children = component.props.children;
    } else if (typeof component.props.children === 'object' &&
      !Array.isArray(component.props.children)) {
      componentData.children = jsxToString(component.props.children, opts);
    } else {
      componentData.children = component.props.children.map((child) => {
        if (typeof child === 'string') {
          return child;
        } else {
          return jsxToString(child, opts);
        }
      }).join(`\n${indentation}`);
    }
    return `<${componentData.name}${componentData.props}>\n${indentation}${componentData.children}\n${indentation.slice(0, -2)}</${componentData.name}>`;
  } else {
    return `<${componentData.name}${componentData.props} />`;
  }
};

export default jsxToString;
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  var browsers = [
    {
      browserName: 'googlechrome',
      platform: 'Windows 8.1',
      version: '32'
    }
  ];

  var buildLabel;
  var tunnelIdentifier;
  if (process.env.TRAVIS) {
    buildLabel = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')';
    tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
  }

  grunt.initConfig({
    connect: {
      test: {
        options: {
          base: 'tmp/test',
          port: 9999
        }
      }
    },

    'saucelabs-mocha': {
      options: {
        urls: ['http://127.0.0.1:9999/'],
        tunnelTimeout: 5,
        build: buildLabel,
        concurrency: 3,
        browsers: browsers,
        testname: 'Blip',
        tags: []
      },
      local: {
        options: {
          testname: 'Blip (local)'
        }
      },
      travis: {
        options: {
          // WARNING: if `identifier` is set to null or undefined,
          // grunt task will fail
          identifier: tunnelIdentifier
        }
      }
    }
  });

  // Loading dependencies
  for (var key in grunt.file.readJSON('package.json').devDependencies) {
    if (key !== 'grunt' && key.indexOf('grunt') === 0) grunt.loadNpmTasks(key);
  }

  grunt.registerTask('test-server', ['connect:test:keepalive']);
  grunt.registerTask('test-saucelabs-local', ['connect', 'saucelabs-mocha:local']);
  grunt.registerTask('test-saucelabs-travis', ['connect', 'saucelabs-mocha:travis']);
};<commit_msg>Add tags to sauce labs test<commit_after>module.exports = function(grunt) {
  var browsers = [
    {
      browserName: 'googlechrome',
      platform: 'Windows 8.1',
      version: '32'
    }
  ];

  var buildLabel;
  var tunnelIdentifier;
  if (process.env.TRAVIS) {
    buildLabel = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')';
    tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
  }

  grunt.initConfig({
    connect: {
      test: {
        options: {
          base: 'tmp/test',
          port: 9999
        }
      }
    },

    'saucelabs-mocha': {
      options: {
        urls: ['http://127.0.0.1:9999/'],
        tunnelTimeout: 5,
        build: buildLabel,
        concurrency: 3,
        browsers: browsers,
        testname: 'Blip'
      },
      local: {
        options: {
          testname: 'Blip (local)',
          tags: ['unit', 'local']
        }
      },
      travis: {
        options: {
          // WARNING: if `identifier` is set to null or undefined,
          // grunt task will fail
          identifier: tunnelIdentifier,
          tags: ['unit', 'ci']
        }
      }
    }
  });

  // Loading dependencies
  for (var key in grunt.file.readJSON('package.json').devDependencies) {
    if (key !== 'grunt' && key.indexOf('grunt') === 0) grunt.loadNpmTasks(key);
  }

  grunt.registerTask('test-server', ['connect:test:keepalive']);
  grunt.registerTask('test-saucelabs-local', ['connect', 'saucelabs-mocha:local']);
  grunt.registerTask('test-saucelabs-travis', ['connect', 'saucelabs-mocha:travis']);
};<|endoftext|>


<commit_before>/**
 *  Created by Sebastien Couture on 2014-7-8.
 *  Copyright (c) 2014 Sebastien Couture. All rights reserved.
 *
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use,
 *  copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following
 *  conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *  OTHER DEALINGS IN THE SOFTWARE.
 */

(function() {
    "use strict";

    var Recurve = window.Recurve = window.Recurve || {};

    Recurve.GlobalErrorHandler =
    {
        /**
         *
         * @param onError callback declaration: onError(description, error), error will be undefined if not supported by browser
         * @param enabled, default true
         * @param preventBrowserHandle, default true
         */
        init: function(onError, enabled, preventBrowserHandle) {
            if (undefined === enabled) {
                enabled = true;
            }

            if (undefined === preventBrowserHandle) {
                preventBrowserHandle = true;
            }

            this._enabled = enabled;
            this._preventBrowserHandle = preventBrowserHandle;
            this._onError = onError;

            window.onerror = this._errorHandler.bind(this);
        },

        protectedInvoke: function(method) {
            try {
                var args = Recurve.ArrayUtils.argumentsToArray(arguments, 1);
                method.apply(null, args);
            }
            catch (error) {
                var description = this.describeError(error);
                this.handleError(error, description);
            }
        },

        handleError: function(error, description) {
            if (this._onError)
            {
                this._onError(error, description);
            }

            return this._preventBrowserHandle;
        },

        describeError: function(error) {
            if (!error) {
                return null;
            }

            var description;

            if (Recurve.ObjectUtils.isString(error)) {
                description = error;
            }
            else if (Recurve.ObjectUtils.isError(error)) {
                description = error.message + "\n" + error.stack;
            }
            else if (Recurve.ObjectUtils.isObject(error)) {
                description = JSON.stringify(error);
            }
            else
            {
                description = error.toString();
            }

            return description;
        },

        _errorHandler: function(message, filename, line, column, error) {
            if (!this._enabled) {
                return;
            }

            var description = Recurve.StringUtils.format(
                "message: {0}, file: {1}, line: {2}", message, filename, line);

            if (error)
            {
                description += Recurve.StringUtils.format(", stack: {0}", error.stack);
            }

            if (this._onError)
            {
                this._onError(error, description);
            }

            return this._preventBrowserHandle;
        }
    };
})();<commit_msg>switched over to be instance based instead of static<commit_after>/**
 *  Created by Sebastien Couture on 2014-7-8.
 *  Copyright (c) 2014 Sebastien Couture. All rights reserved.
 *
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use,
 *  copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following
 *  conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *  OTHER DEALINGS IN THE SOFTWARE.
 */

(function() {
    "use strict";

    var Recurve = window.Recurve = window.Recurve || {};

    Recurve.GlobalErrorHandler = Recurve.Proto.define([

        /**
         * NOTE, If your JS is hosted on a CDN then the browser will sanitize and exclude all error output
         * unless explicitly enabled. See TODO TBD tutorial link
         *
         * @param onError, callback declaration: onError(description, error), error will be undefined if not supported by browser
         * @param enabled, default true
         * @param preventBrowserHandle, default true
         */
        function ctor(onError, enabled, preventBrowserHandle) {
            if (undefined === enabled) {
                enabled = true;
            }

            if (undefined === preventBrowserHandle) {
                preventBrowserHandle = true;
            }

            this._enabled = enabled;
            this._preventBrowserHandle = preventBrowserHandle;
            this._onError = onError;

            window.onerror = this._errorHandler.bind(this);
        },

        {
            /**
             * Wrap method in try..catch and handle error without raising uncaught error
             *
             * @param method
             * @param [, arg2, ..., argN], list of arguments for method
             */
            protectedInvoke: function(method) {
                try {
                    var args = Recurve.ArrayUtils.argumentsToArray(arguments, 1);
                    method.apply(null, args);
                }
                catch (error) {
                    var description = this.describeError(error);
                    this.handleError(error, description);
                }
            },

            /**
             * Handle error as would be done for uncaught global error
             *
             * @param error, any type of error (string, object, Error)
             * @param description
             */
            handleError: function(error, description) {
                if (this._onError)
                {
                    this._onError(error, description);
                }

                return this._preventBrowserHandle;
            },

            describeError: function(error) {
                if (!error) {
                    return null;
                }

                var description;

                if (Recurve.ObjectUtils.isString(error)) {
                    description = error;
                }
                else if (Recurve.ObjectUtils.isError(error)) {
                    description = error.message + "\n" + error.stack;
                }
                else if (Recurve.ObjectUtils.isObject(error)) {
                    description = JSON.stringify(error);
                }
                else
                {
                    description = error.toString();
                }

                return description;
            },

            _errorHandler: function(message, filename, line, column, error) {
                if (!this._enabled) {
                    return;
                }

                var description = Recurve.StringUtils.format(
                    "message: {0}, file: {1}, line: {2}", message, filename, line);

                if (error)
                {
                    description += Recurve.StringUtils.format(", stack: {0}", error.stack);
                }

                if (this._onError)
                {
                    this._onError(error, description);
                }

                return this._preventBrowserHandle;
            }
        }
    ]);
})();<|endoftext|>