<commit_before>import path from 'path';
import {CLIEngine, linter} from 'eslint';
import PackageJson from '../lib/package_json';

const project = PackageJson.load();
const baseConfig = linter.defaults();

const options = {
  ignorePath: path.resolve('.gitignore'),
  baseConfig: Object.assign({}, baseConfig, {
    parser: 'babel-eslint',
    plugins: [
      'babel'
    ],
    ecmaFeatures: Object.assign({}, baseConfig.ecmaFeatures, {
      // modules: true,
      regexYFlag: true,
      regexUFlag: true
    }),
    env: {
      es6: true,
      browser: true,
      worker: true,
      serviceworker: true,
      node: true,
      jasmine: project.dependsOn(/jasmine/)
    },
    rules: Object.assign({}, baseConfig.rules, {
      'babel/generator-star-spacing': [2, 'after'],
      'babel/new-cap': 2,
      'babel/object-curly-spacing': 2,
      'babel/object-shorthand': 2,
      'babel/arrow-parens': [2, 'as-needed'],

      'comma-dangle': 2,
      'no-cond-assign': 2,
      'no-console': 2,
      'no-constant-condition': 2,
      'no-control-regex': 2,
      'no-debugger': 2,
      'no-dupe-args': 2,
      'no-dupe-keys': 2,
      'no-duplicate-case': 2,
      'no-empty-character-class': 2,
      'no-empty': 2,
      'no-ex-assign': 2,
      'no-extra-boolean-cast': 2,
      'no-extra-parens': 2,
      'no-extra-semi': 2,
      'no-func-assign': 2,
      'no-inner-declarations': 2,
      'no-invalid-regexp': 2,
      'no-irregular-whitespace': 2,
      'no-negated-in-lhs': 2,
      'no-obj-calls': 2,
      'no-regex-spaces': 2,
      'no-sparse-arrays': 2,
      'no-unreachable': 2,
      'use-isnan': 2,
      'valid-jsdoc': 2,
      'valid-typeof': 2,
      'no-unexpected-multiline': 2,

      'accessor-pairs': 2,
      'block-scoped-var': 2,
      'complexity': [0, 11],
      'consistent-return': 2,
      'curly': 2,
      'default-case': 2,
      'dot-notation': 2,
      'dot-location': [2, 'property'],
      'eqeqeq': 2,
      'guard-for-in': 2,
      'no-alert': 2,
      'no-caller': 2,
      'no-div-regex': 0,
      'no-else-return': 2,
      'no-empty-label': 2,
      'no-eq-null': 2,
      'no-eval': 2,
      'no-extend-native': 2,
      'no-extra-bind': 2,
      'no-fallthrough': 2,
      'no-floating-decimal': 2,
      'no-implicit-coercion': 2,
      'no-implied-eval': 2,
      'no-invalid-this': 2,
      'no-iterator': 2,
      'no-labels': 2,
      'no-lone-blocks': 2,
      'no-loop-func': 2,
      'no-multi-spaces': [2, {exceptions: {Property: false}}],
      'no-multi-str': 2,
      'no-native-reassign': 2,
      'no-new-func': 2,
      'no-new-wrappers': 2,
      'no-new': 2,
      'no-octal-escape': 2,
      'no-octal': 2,
      'no-param-reassign': [2, {props: true}],
      'no-process-env': 2,
      'no-proto': 2,
      'no-redeclare': [2, {builtinGlobals: true}],
      'no-return-assign': 2,
      'no-script-url': 2,
      'no-self-compare': 2,
      'no-sequences': 2,
      'no-throw-literal': 2,
      'no-unused-expressions': 2,
      'no-useless-call': 2,
      'no-void': 2,
      'no-warning-comments': 2,
      'no-with': 2,
      'radix': 2,
      'vars-on-top': 2,
      'wrap-iife': 2,
      'yoda': 2,

      'strict': [2, 'never'],

      'init-declarations': 2,
      'no-catch-shadow': 0,
      'no-delete-var': 2,
      'no-label-var': 2,
      'no-shadow-restricted-names': 2,
      'no-shadow': 2,
      'no-undef-init': 2,
      'no-undef': 2,
      'no-undefined': 2,
      'no-unused-vars': 2,
      'no-use-before-define': 2,

      'callback-return': 2,
      'handle-callback-err': [2, '^(?:err|error)'],
      'no-mixed-requires': 2,
      'no-new-require': 2,
      'no-path-concat': 2,
      'no-process-exit': 2,
      'no-restricted-modules': 0,
      'no-sync': 2,

      'array-bracket-spacing': 2,
      'brace-style': 2,
      'camelcase': 2,
      'comma-spacing': 2,
      'comma-style': 2,
      'computed-property-spacing': 2,
      'consistent-this': [2, 'self'],
      'eol-last': 2,
      'func-names': 2,
      'func-style': [2, 'declaration'],
      'id-length': 2,
      'id-match': 0,
      'indent': [2, 2],
      'key-spacing': 2,
      'lines-around-comment': [2, {
        beforeBlockComment: true,
        beforeLineComment: true,
        allowBlockStart: true
      }],
      'linebreak-style': 2,
      'max-nested-callbacks': [2, 2],
      'new-cap': 0,
      'new-parens': 2,
      'newline-after-var': 2,
      'no-array-constructor': 2,
      'no-continue': 0,
      'no-inline-comments': 2,
      'no-lonely-if': 2,
      'no-mixed-spaces-and-tabs': 2,
      'no-multiple-empty-lines': [0, {max: 2}],
      'no-nested-ternary': 2,
      'no-new-object': 2,
      'no-spaced-func': 2,
      'no-ternary': 0,
      'no-trailing-spaces': 2,
      'no-underscore-dangle': 2,
      'no-unneeded-ternary': 2,
      'object-curly-spacing': 0,
      'one-var': 0,
      'operator-assignment': [2, 'always'],
      'operator-linebreak': 2,
      'padded-blocks': [2, 'never'],
      'quote-props': [2, 'consistent-as-needed'],
      'quotes': [2, 'single', 'avoid-escape'],
      'semi-spacing': 2,
      'semi': [2, 'always'],
      'sort-vars': 0,
      'space-after-keywords': 2,
      'space-before-blocks': 2,
      'space-before-function-paren': [2, 'never'],
      'space-in-parens': 2,
      'space-infix-ops': [2, {int32Hint: true}],
      'space-return-throw-case': 2,
      'space-unary-ops': 2,
      'spaced-comment': 2,
      'wrap-regex': 0,

      'arrow-parens': 0,
      'arrow-spacing': 2,
      'constructor-super': 2,
      'generator-star-spacing': 0,
      'no-class-assign': 2,
      'no-const-assign': 2,
      'no-this-before-super': 2,
      'no-var': 2,
      'object-shorthand': 0,
      'prefer-const': 2,
      'prefer-spread': 2,
      'prefer-reflect': 2,
      'require-yield': 2,
    })
  })
};

const cli = new CLIEngine(options);
const formatter = cli.getFormatter();
const report = cli.executeOnFiles(['.']);

if (report.errorCount > 0) {
  process.stderr.write(formatter(report.results));
  process.exit(1); // eslint-disable-line no-process-exit
}
<commit_msg>Disable `babel/arrow-parens` until it is released<commit_after>import path from 'path';
import {CLIEngine, linter} from 'eslint';
import PackageJson from '../lib/package_json';

const project = PackageJson.load();
const baseConfig = linter.defaults();

const options = {
  ignorePath: path.resolve('.gitignore'),
  baseConfig: Object.assign({}, baseConfig, {
    parser: 'babel-eslint',
    plugins: [
      'babel'
    ],
    ecmaFeatures: Object.assign({}, baseConfig.ecmaFeatures, {
      // modules: true,
      regexYFlag: true,
      regexUFlag: true
    }),
    env: {
      es6: true,
      browser: true,
      worker: true,
      serviceworker: true,
      node: true,
      jasmine: project.dependsOn(/jasmine/)
    },
    rules: Object.assign({}, baseConfig.rules, {
      'babel/generator-star-spacing': [2, 'after'],
      'babel/new-cap': 2,
      'babel/object-curly-spacing': 2,
      'babel/object-shorthand': 2,
      // 'babel/arrow-parens': [2, 'as-needed'],

      'comma-dangle': 2,
      'no-cond-assign': 2,
      'no-console': 2,
      'no-constant-condition': 2,
      'no-control-regex': 2,
      'no-debugger': 2,
      'no-dupe-args': 2,
      'no-dupe-keys': 2,
      'no-duplicate-case': 2,
      'no-empty-character-class': 2,
      'no-empty': 2,
      'no-ex-assign': 2,
      'no-extra-boolean-cast': 2,
      'no-extra-parens': 2,
      'no-extra-semi': 2,
      'no-func-assign': 2,
      'no-inner-declarations': 2,
      'no-invalid-regexp': 2,
      'no-irregular-whitespace': 2,
      'no-negated-in-lhs': 2,
      'no-obj-calls': 2,
      'no-regex-spaces': 2,
      'no-sparse-arrays': 2,
      'no-unreachable': 2,
      'use-isnan': 2,
      'valid-jsdoc': 2,
      'valid-typeof': 2,
      'no-unexpected-multiline': 2,

      'accessor-pairs': 2,
      'block-scoped-var': 2,
      'complexity': [0, 11],
      'consistent-return': 2,
      'curly': 2,
      'default-case': 2,
      'dot-notation': 2,
      'dot-location': [2, 'property'],
      'eqeqeq': 2,
      'guard-for-in': 2,
      'no-alert': 2,
      'no-caller': 2,
      'no-div-regex': 0,
      'no-else-return': 2,
      'no-empty-label': 2,
      'no-eq-null': 2,
      'no-eval': 2,
      'no-extend-native': 2,
      'no-extra-bind': 2,
      'no-fallthrough': 2,
      'no-floating-decimal': 2,
      'no-implicit-coercion': 2,
      'no-implied-eval': 2,
      'no-invalid-this': 2,
      'no-iterator': 2,
      'no-labels': 2,
      'no-lone-blocks': 2,
      'no-loop-func': 2,
      'no-multi-spaces': [2, {exceptions: {Property: false}}],
      'no-multi-str': 2,
      'no-native-reassign': 2,
      'no-new-func': 2,
      'no-new-wrappers': 2,
      'no-new': 2,
      'no-octal-escape': 2,
      'no-octal': 2,
      'no-param-reassign': [2, {props: true}],
      'no-process-env': 2,
      'no-proto': 2,
      'no-redeclare': [2, {builtinGlobals: true}],
      'no-return-assign': 2,
      'no-script-url': 2,
      'no-self-compare': 2,
      'no-sequences': 2,
      'no-throw-literal': 2,
      'no-unused-expressions': 2,
      'no-useless-call': 2,
      'no-void': 2,
      'no-warning-comments': 2,
      'no-with': 2,
      'radix': 2,
      'vars-on-top': 2,
      'wrap-iife': 2,
      'yoda': 2,

      'strict': [2, 'never'],

      'init-declarations': 2,
      'no-catch-shadow': 0,
      'no-delete-var': 2,
      'no-label-var': 2,
      'no-shadow-restricted-names': 2,
      'no-shadow': 2,
      'no-undef-init': 2,
      'no-undef': 2,
      'no-undefined': 2,
      'no-unused-vars': 2,
      'no-use-before-define': 2,

      'callback-return': 2,
      'handle-callback-err': [2, '^(?:err|error)'],
      'no-mixed-requires': 2,
      'no-new-require': 2,
      'no-path-concat': 2,
      'no-process-exit': 2,
      'no-restricted-modules': 0,
      'no-sync': 2,

      'array-bracket-spacing': 2,
      'brace-style': 2,
      'camelcase': 2,
      'comma-spacing': 2,
      'comma-style': 2,
      'computed-property-spacing': 2,
      'consistent-this': [2, 'self'],
      'eol-last': 2,
      'func-names': 2,
      'func-style': [2, 'declaration'],
      'id-length': 2,
      'id-match': 0,
      'indent': [2, 2],
      'key-spacing': 2,
      'lines-around-comment': [2, {
        beforeBlockComment: true,
        beforeLineComment: true,
        allowBlockStart: true
      }],
      'linebreak-style': 2,
      'max-nested-callbacks': [2, 2],
      'new-cap': 0,
      'new-parens': 2,
      'newline-after-var': 2,
      'no-array-constructor': 2,
      'no-continue': 0,
      'no-inline-comments': 2,
      'no-lonely-if': 2,
      'no-mixed-spaces-and-tabs': 2,
      'no-multiple-empty-lines': [0, {max: 2}],
      'no-nested-ternary': 2,
      'no-new-object': 2,
      'no-spaced-func': 2,
      'no-ternary': 0,
      'no-trailing-spaces': 2,
      'no-underscore-dangle': 2,
      'no-unneeded-ternary': 2,
      'object-curly-spacing': 0,
      'one-var': 0,
      'operator-assignment': [2, 'always'],
      'operator-linebreak': 2,
      'padded-blocks': [2, 'never'],
      'quote-props': [2, 'consistent-as-needed'],
      'quotes': [2, 'single', 'avoid-escape'],
      'semi-spacing': 2,
      'semi': [2, 'always'],
      'sort-vars': 0,
      'space-after-keywords': 2,
      'space-before-blocks': 2,
      'space-before-function-paren': [2, 'never'],
      'space-in-parens': 2,
      'space-infix-ops': [2, {int32Hint: true}],
      'space-return-throw-case': 2,
      'space-unary-ops': 2,
      'spaced-comment': 2,
      'wrap-regex': 0,

      'arrow-parens': 0,
      'arrow-spacing': 2,
      'constructor-super': 2,
      'generator-star-spacing': 0,
      'no-class-assign': 2,
      'no-const-assign': 2,
      'no-this-before-super': 2,
      'no-var': 2,
      'object-shorthand': 0,
      'prefer-const': 2,
      'prefer-spread': 2,
      'prefer-reflect': 2,
      'require-yield': 2,
    })
  })
};

const cli = new CLIEngine(options);
const formatter = cli.getFormatter();
const report = cli.executeOnFiles(['.']);

if (report.errorCount > 0) {
  process.stderr.write(formatter(report.results));
  process.exit(1); // eslint-disable-line no-process-exit
}
<|endoftext|>


<commit_before>sap.ui.define([
	"com/sap/sapmentors/sitreg/events/controller/BaseController",
	"sap/ui/model/json/JSONModel",
	"com/sap/sapmentors/sitreg/events/model/formatter",
	"sap/m/MessageBox"

], function(BaseController, JSONModel, formatter, MessageBox) {
	"use strict";

	return BaseController.extend("com.sap.sapmentors.sitreg.events.controller.CreateEntity", {

		formatter: formatter,

		_oBinding: {},

		/* =========================================================== */
		/* lifecycle methods                                           */
		/* =========================================================== */

		onInit: function() {
			var that = this;
			this.getRouter().getTargets().getTarget("create").attachDisplay(null, this._onDisplay, this);
			this._oODataModel = this.getOwnerComponent().getModel();
			this._oResourceBundle = this.getResourceBundle();
			this._oViewModel = new JSONModel({
				enableCreate: false,
				delay: 0,
				busy: false,
				mode: "create",
				viewTitle: ""
			});
			this.setModel(this._oViewModel, "viewModel");

			// Register the view with the message manager
			sap.ui.getCore().getMessageManager().registerObject(this.getView(), true);
			var oMessagesModel = sap.ui.getCore().getMessageManager().getMessageModel();
			this._oBinding = new sap.ui.model.Binding(oMessagesModel, "/", oMessagesModel.getContext("/"));
			this._oBinding.attachChange(function(oEvent) {
				var aMessages = oEvent.getSource().getModel().getData();
				for (var i = 0; i < aMessages.length; i++) {
					if (aMessages[i].type === "Error" && !aMessages[i].technical) {
						that._oViewModel.setProperty("/enableCreate", false);
					}
				}
			});
		},

		/* =========================================================== */
		/* event handlers                                              */
		/* =========================================================== */

		/**
		 * Event handler (attached declaratively) for the view save button. Saves the changes added by the user.
		 * @function
		 * @public
		 */
		onSave: function() {
			var that = this,
				oModel = this.getModel(),
				oView = this.getView();

			var oContext = oView.getBindingContext();
			var sPathVisible = oContext.getPath() + "/Visible";
			var bVisible = oView.byId("Visible_id").getState();
			if(bVisible) {
				oModel.setProperty(sPathVisible, "Y");
			} else {
				oModel.setProperty(sPathVisible, "N");
			}
			var sEventType = oView.byId("idEventType").getSelectedKey();
			oModel.setProperty(oContext.getPath() + "/Type", sEventType);
			// Adjust Date to Timezone
			var timezoneOffset = new Date().getTimezoneOffset() * 60 * 1000; // Offset returns minutes * 60 seconds * 1000 ms
			var noon = 12 * 60 * 60 * 1000; // Use noon in the Timezone (12 hours * 60 minutes * 60 seconds * 1000 ms)
			timezoneOffset = noon - timezoneOffset;
			var EventDate = oModel.getProperty(oContext.getPath() + "/EventDate");
			EventDate.setTime(EventDate.getTime() + timezoneOffset);
			oModel.setProperty(oContext.getPath() + "/EventDate", EventDate);
			// abort if the  model has not been changed
			if (!oModel.hasPendingChanges()) {
				MessageBox.information(
					this._oResourceBundle.getText("noChangesMessage"), {
						id: "noChangesInfoMessageBox",
						styleClass: that.getOwnerComponent().getContentDensityClass()
					}
				);
				return;
			}
			this.getModel("appView").setProperty("/busy", true);
			if (this._oViewModel.getProperty("/mode") === "edit") {
				// attach to the request completed event of the batch
				oModel.attachEventOnce("batchRequestCompleted", function(oEvent) {
					var oParams = oEvent.getParameters();
					if (oParams.success) {
						that._fnUpdateSuccess();
					} else {
						that._fnEntityCreationFailed();
					}
				});
			}
			oModel.submitChanges();
		},

		/**
		 * Event handler (attached declaratively) for the view cancel button. Asks the user confirmation to discard the changes.
		 * @function
		 * @public
		 */
		onCancel: function() {
			// check if the model has been changed
			if (this.getModel().hasPendingChanges()) {
				// get user confirmation first
				this._showConfirmQuitChanges(); // some other thing here....
			} else {
				this.getModel("appView").setProperty("/addEnabled", true);
				// cancel without confirmation
				this._navBack();
			}
		},

		/* =========================================================== */
		/* Internal functions
		/* =========================================================== */
		/**
		 * Navigates back in the browser history, if the entry was created by this app.
		 * If not, it navigates to the Details page
		 * @private
		 */
		_navBack: function() {
			var oHistory = sap.ui.core.routing.History.getInstance(),
				sPreviousHash = oHistory.getPreviousHash();

			this.getView().unbindObject();
			if (sPreviousHash !== undefined) {
				// The history contains a previous entry
				history.go(-1);
			} else {
				this.getRouter().getTargets().display("object");
			}
		},

		/**
		 * Opens a dialog letting the user either confirm or cancel the quit and discard of changes.
		 * @private
		 */
		_showConfirmQuitChanges: function() {
			var oComponent = this.getOwnerComponent(),
				oModel = this.getModel();
			var that = this;
			MessageBox.confirm(
				this._oResourceBundle.getText("confirmCancelMessage"), {
					styleClass: oComponent.getContentDensityClass(),
					onClose: function(oAction) {
						if (oAction === sap.m.MessageBox.Action.OK) {
							that.getModel("appView").setProperty("/addEnabled", true);
							oModel.resetChanges();
							that._navBack();
						}
					}
				}
			);
		},

		/**
		 * Prepares the view for editing the selected object
		 * @param {sap.ui.base.Event} oEvent the  display event
		 * @private
		 */
		_onEdit: function(oEvent) {
			var oData = oEvent.getParameter("data"),
				oView = this.getView();
			this._oViewModel.setProperty("/mode", "edit");
			this._oViewModel.setProperty("/enableCreate", true);
			this._oViewModel.setProperty("/viewTitle", this._oResourceBundle.getText("editViewTitle"));

			oView.bindElement({
				path: oData.objectPath
			});
		},

		/**
		 * Prepares the view for creating new object
		 * @param {sap.ui.base.Event} oEvent the  display event
		 * @private
		 */

		_onCreate: function(oEvent) {
			if (oEvent.getParameter("name") && oEvent.getParameter("name") !== "create") {
				this._oViewModel.setProperty("/enableCreate", false);
				this.getRouter().getTargets().detachDisplay(null, this._onDisplay, this);
				this.getView().unbindObject();
				return;
			}

			this._oViewModel.setProperty("/viewTitle", this._oResourceBundle.getText("createViewTitle"));
			this._oViewModel.setProperty("/mode", "create");
			var oContext = this._oODataModel.createEntry("Events", {
				success: this._fnEntityCreated.bind(this),
				error: this._fnEntityCreationFailed.bind(this)
			});
			this.getView().setBindingContext(oContext);
		},

		/**
		 * Checks if the save button can be enabled
		 * @private
		 */
		_validateSaveEnablement: function() {
			var aInputControls = this._getFormFields(this.byId("newEntitySimpleForm"));
			var oControl;
			for (var m = 0; m < aInputControls.length; m++) {
				oControl = aInputControls[m].control;
				if (aInputControls[m].required) {
					var sValue = oControl.getValue();
					if (!sValue) {
						this._oViewModel.setProperty("/enableCreate", false);
						return;
					}
				}
			}
			this._checkForErrorMessages();
		},

		/**
		 * Checks if there is any wrong inputs that can not be saved.
		 * @private
		 */

		_checkForErrorMessages: function() {
			var aMessages = this._oBinding.oModel.oData;
			if (aMessages.length > 0) {
				var bEnableCreate = true;
				for (var i = 0; i < aMessages.length; i++) {
					if (aMessages[i].type === "Error" && !aMessages[i].technical) {
						bEnableCreate = false;
						break;
					}
				}
				this._oViewModel.setProperty("/enableCreate", bEnableCreate);
			} else {
				this._oViewModel.setProperty("/enableCreate", true);
			}
		},

		/**
		 * Handles the success of updating an object
		 * @private
		 */
		_fnUpdateSuccess: function() {
			this.getModel("appView").setProperty("/busy", false);
			this.getView().unbindObject();
			this.getRouter().getTargets().display("object");
		},

		/**
		 * Handles the success of creating an object
		 *@param {object} oData the response of the save action
		 * @private
		 */
		_fnEntityCreated: function(oData) {
			var sObjectPath = this.getModel().createKey("Events", oData);
			this.getModel("appView").setProperty("/itemToSelect", "/" + sObjectPath); //save last created
			this.getModel("appView").setProperty("/busy", false);
			this.getRouter().getTargets().display("object");
		},

		/**
		 * Handles the failure of creating/updating an object
		 * @private
		 */
		_fnEntityCreationFailed: function() {
			this.getModel("appView").setProperty("/busy", false);
		},

		/**
		 * Handles the onDisplay event which is triggered when this view is displayed
		 * @param {sap.ui.base.Event} oEvent the on display event
		 * @private
		 */
		_onDisplay: function(oEvent) {
			var oData = oEvent.getParameter("data");
			if (oData && oData.mode === "update") {
				this._onEdit(oEvent);
			} else {
				this._onCreate(oEvent);
			}
		}
	});

});<commit_msg>Change of event date in controller not needed for #2<commit_after>sap.ui.define([
	"com/sap/sapmentors/sitreg/events/controller/BaseController",
	"sap/ui/model/json/JSONModel",
	"com/sap/sapmentors/sitreg/events/model/formatter",
	"sap/m/MessageBox"

], function(BaseController, JSONModel, formatter, MessageBox) {
	"use strict";

	return BaseController.extend("com.sap.sapmentors.sitreg.events.controller.CreateEntity", {

		formatter: formatter,

		_oBinding: {},

		/* =========================================================== */
		/* lifecycle methods                                           */
		/* =========================================================== */

		onInit: function() {
			var that = this;
			this.getRouter().getTargets().getTarget("create").attachDisplay(null, this._onDisplay, this);
			this._oODataModel = this.getOwnerComponent().getModel();
			this._oResourceBundle = this.getResourceBundle();
			this._oViewModel = new JSONModel({
				enableCreate: false,
				delay: 0,
				busy: false,
				mode: "create",
				viewTitle: ""
			});
			this.setModel(this._oViewModel, "viewModel");

			// Register the view with the message manager
			sap.ui.getCore().getMessageManager().registerObject(this.getView(), true);
			var oMessagesModel = sap.ui.getCore().getMessageManager().getMessageModel();
			this._oBinding = new sap.ui.model.Binding(oMessagesModel, "/", oMessagesModel.getContext("/"));
			this._oBinding.attachChange(function(oEvent) {
				var aMessages = oEvent.getSource().getModel().getData();
				for (var i = 0; i < aMessages.length; i++) {
					if (aMessages[i].type === "Error" && !aMessages[i].technical) {
						that._oViewModel.setProperty("/enableCreate", false);
					}
				}
			});
		},

		/* =========================================================== */
		/* event handlers                                              */
		/* =========================================================== */

		/**
		 * Event handler (attached declaratively) for the view save button. Saves the changes added by the user.
		 * @function
		 * @public
		 */
		onSave: function() {
			var that = this,
				oModel = this.getModel(),
				oView = this.getView();

			var oContext = oView.getBindingContext();
			var sPathVisible = oContext.getPath() + "/Visible";
			var bVisible = oView.byId("Visible_id").getState();
			if(bVisible) {
				oModel.setProperty(sPathVisible, "Y");
			} else {
				oModel.setProperty(sPathVisible, "N");
			}
			var sEventType = oView.byId("idEventType").getSelectedKey();
			oModel.setProperty(oContext.getPath() + "/Type", sEventType);
			// abort if the  model has not been changed
			if (!oModel.hasPendingChanges()) {
				MessageBox.information(
					this._oResourceBundle.getText("noChangesMessage"), {
						id: "noChangesInfoMessageBox",
						styleClass: that.getOwnerComponent().getContentDensityClass()
					}
				);
				return;
			}
			this.getModel("appView").setProperty("/busy", true);
			if (this._oViewModel.getProperty("/mode") === "edit") {
				// attach to the request completed event of the batch
				oModel.attachEventOnce("batchRequestCompleted", function(oEvent) {
					var oParams = oEvent.getParameters();
					if (oParams.success) {
						that._fnUpdateSuccess();
					} else {
						that._fnEntityCreationFailed();
					}
				});
			}
			oModel.submitChanges();
		},

		/**
		 * Event handler (attached declaratively) for the view cancel button. Asks the user confirmation to discard the changes.
		 * @function
		 * @public
		 */
		onCancel: function() {
			// check if the model has been changed
			if (this.getModel().hasPendingChanges()) {
				// get user confirmation first
				this._showConfirmQuitChanges(); // some other thing here....
			} else {
				this.getModel("appView").setProperty("/addEnabled", true);
				// cancel without confirmation
				this._navBack();
			}
		},

		/* =========================================================== */
		/* Internal functions
		/* =========================================================== */
		/**
		 * Navigates back in the browser history, if the entry was created by this app.
		 * If not, it navigates to the Details page
		 * @private
		 */
		_navBack: function() {
			var oHistory = sap.ui.core.routing.History.getInstance(),
				sPreviousHash = oHistory.getPreviousHash();

			this.getView().unbindObject();
			if (sPreviousHash !== undefined) {
				// The history contains a previous entry
				history.go(-1);
			} else {
				this.getRouter().getTargets().display("object");
			}
		},

		/**
		 * Opens a dialog letting the user either confirm or cancel the quit and discard of changes.
		 * @private
		 */
		_showConfirmQuitChanges: function() {
			var oComponent = this.getOwnerComponent(),
				oModel = this.getModel();
			var that = this;
			MessageBox.confirm(
				this._oResourceBundle.getText("confirmCancelMessage"), {
					styleClass: oComponent.getContentDensityClass(),
					onClose: function(oAction) {
						if (oAction === sap.m.MessageBox.Action.OK) {
							that.getModel("appView").setProperty("/addEnabled", true);
							oModel.resetChanges();
							that._navBack();
						}
					}
				}
			);
		},

		/**
		 * Prepares the view for editing the selected object
		 * @param {sap.ui.base.Event} oEvent the  display event
		 * @private
		 */
		_onEdit: function(oEvent) {
			var oData = oEvent.getParameter("data"),
				oView = this.getView();
			this._oViewModel.setProperty("/mode", "edit");
			this._oViewModel.setProperty("/enableCreate", true);
			this._oViewModel.setProperty("/viewTitle", this._oResourceBundle.getText("editViewTitle"));

			oView.bindElement({
				path: oData.objectPath
			});
		},

		/**
		 * Prepares the view for creating new object
		 * @param {sap.ui.base.Event} oEvent the  display event
		 * @private
		 */

		_onCreate: function(oEvent) {
			if (oEvent.getParameter("name") && oEvent.getParameter("name") !== "create") {
				this._oViewModel.setProperty("/enableCreate", false);
				this.getRouter().getTargets().detachDisplay(null, this._onDisplay, this);
				this.getView().unbindObject();
				return;
			}

			this._oViewModel.setProperty("/viewTitle", this._oResourceBundle.getText("createViewTitle"));
			this._oViewModel.setProperty("/mode", "create");
			var oContext = this._oODataModel.createEntry("Events", {
				success: this._fnEntityCreated.bind(this),
				error: this._fnEntityCreationFailed.bind(this)
			});
			this.getView().setBindingContext(oContext);
		},

		/**
		 * Checks if the save button can be enabled
		 * @private
		 */
		_validateSaveEnablement: function() {
			var aInputControls = this._getFormFields(this.byId("newEntitySimpleForm"));
			var oControl;
			for (var m = 0; m < aInputControls.length; m++) {
				oControl = aInputControls[m].control;
				if (aInputControls[m].required) {
					var sValue = oControl.getValue();
					if (!sValue) {
						this._oViewModel.setProperty("/enableCreate", false);
						return;
					}
				}
			}
			this._checkForErrorMessages();
		},

		/**
		 * Checks if there is any wrong inputs that can not be saved.
		 * @private
		 */

		_checkForErrorMessages: function() {
			var aMessages = this._oBinding.oModel.oData;
			if (aMessages.length > 0) {
				var bEnableCreate = true;
				for (var i = 0; i < aMessages.length; i++) {
					if (aMessages[i].type === "Error" && !aMessages[i].technical) {
						bEnableCreate = false;
						break;
					}
				}
				this._oViewModel.setProperty("/enableCreate", bEnableCreate);
			} else {
				this._oViewModel.setProperty("/enableCreate", true);
			}
		},

		/**
		 * Handles the success of updating an object
		 * @private
		 */
		_fnUpdateSuccess: function() {
			this.getModel("appView").setProperty("/busy", false);
			this.getView().unbindObject();
			this.getRouter().getTargets().display("object");
		},

		/**
		 * Handles the success of creating an object
		 *@param {object} oData the response of the save action
		 * @private
		 */
		_fnEntityCreated: function(oData) {
			var sObjectPath = this.getModel().createKey("Events", oData);
			this.getModel("appView").setProperty("/itemToSelect", "/" + sObjectPath); //save last created
			this.getModel("appView").setProperty("/busy", false);
			this.getRouter().getTargets().display("object");
		},

		/**
		 * Handles the failure of creating/updating an object
		 * @private
		 */
		_fnEntityCreationFailed: function() {
			this.getModel("appView").setProperty("/busy", false);
		},

		/**
		 * Handles the onDisplay event which is triggered when this view is displayed
		 * @param {sap.ui.base.Event} oEvent the on display event
		 * @private
		 */
		_onDisplay: function(oEvent) {
			var oData = oEvent.getParameter("data");
			if (oData && oData.mode === "update") {
				this._onEdit(oEvent);
			} else {
				this._onCreate(oEvent);
			}
		}
	});

});<|endoftext|>


<commit_before>React.BackboneMixin = {
    componentDidMount: function(domNode) {
      // Whenever there may be a change in the Backbone data, trigger a reconcile.
      var model = this.getModel();
      // Detect if it's a collection
      if (model instanceof Backbone.Collection) {
          model.on('add remove reset sort', function () { this.forceUpdate(); }, this);
      }
      else if (model) {
          var changeOptions = this.changeOptions || "change";
          model.on(changeOptions, (this.onModelChange || function () { this.forceUpdate(); }), this);
      }
  },
  componentWillUnmount: function() {
      // Ensure that we clean up any dangling references when the component is destroyed.
      this.getModel() && this.getModel().off(null, null, this);
  }
};

React.createBackboneClass = function(spec) {
    var currentMixins = spec.mixins || [];
    _.extend(spec, {
        mixins: currentMixins.concat([React.BackboneMixin]),
        getModel: function() {
            return this.props.model;
        },
        model: function() {
            return this.getModel();
        },
        el: function() {
            return this._rootNode && this.getDOMNode();
        }
    });
    return React.createClass(spec);
};
<commit_msg>Make things more consistent, fix changing props<commit_after>React.BackboneMixin = {
    _subscribe: function(model) {
        if (!model) {
            return;
        }
        // Detect if it's a collection
        if (model instanceof Backbone.Collection) {
            model.on('add remove reset sort', function () { this.forceUpdate(); }, this);
        }
        else if (model) {
            var changeOptions = this.changeOptions || 'change';
            model.on(changeOptions, (this.onModelChange || function () { this.forceUpdate(); }), this);
        }
    },
    _unsubscribe: function(model) {
        if (!model) {
            return;
        }
        model.off(null, null, this);
    },
    componentDidMount: function() {
        // Whenever there may be a change in the Backbone data, trigger a reconcile.
        this._subscribe(this.props.model);
    },
    componentWillReceiveProps: function(nextProps) {
        if (this.props.model !== nextProps.model) {
            this._unsubscribe(this.props.model);
            this._subscribe(nextProps.model);
        }
    },
    componentWillUnmount: function() {
        // Ensure that we clean up any dangling references when the component is destroyed.
        this._unsubscribe(this.props.model);
    }
};

React.createBackboneClass = function(spec) {
    var currentMixins = spec.mixins || [];

    spec.mixins = currentMixins.concat([React.BackboneMixin]);
    spec.getModel = function() {
        return this.props.model;
    };
    spec.model = function() {
        return this.getModel();
    };
    spec.el = function() {
        return this.isMounted() && this.getDOMNode();
    };
    return React.createClass(spec);
};
<|endoftext|>


<commit_before>/**
 * General CRUD Controller
 * @module controllers/CRUD
 */
import Sequelize from 'sequelize';
import * as errors from '../components/errors';
import url from 'url'
import lodash from 'lodash'

class CRUD {

    constructor(model, resourceName) {
        this.Model = model;
        this.resourceName = resourceName;

        // Bind this to methods
        this.list = this.list.bind(this);
        this.search = this.search.bind(this)
        this.retrieve = this.retrieve.bind(this);
        this.destroy = this.destroy.bind(this);
        this.update = this.update.bind(this);
        this.create = this.create.bind(this);
    }

    /**
     * list - List all objects in the database
     *
     * @function list
     * @memberof  module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    list(req, res, next) {
        this.Model.findAll()
        .then(res.json.bind(res))
        .catch(next);
    }

    /**
     * search - search all objects in the database
     *
     * @function search
     * @memberof  module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    search(req, res, next) {

      const createSql = (describeData) => {
        const { query } = url.parse(req.url, true);
        const validFields = Object.keys(describeData) || [];
        const queryKeys = Object.keys(query)
        const allFields = lodash.flatMap(queryKeys, key => key.split('|'))
        const unknownFields = allFields.filter(name => !validFields.includes(name))
        if(unknownFields.length > 0) {
          return res.status(400).json({error:`Unkown field(s): ${unknownFields}`, validFields: validFields});
        }

        const andKeys = queryKeys.filter(key => !key.includes('|'))
        const orKeys = queryKeys.filter(key => key.includes('|'))

        const andClauses = andKeys.reduce((initalValue, key) => {
          return Object.assign(initalValue, createFieldStatement(describeData, query, key))
        }, {});

        const orClauses = orKeys.reduce((initalValue, key) => {
          return Object.assign(initalValue, createOr(describeData, query, key))
        }, {});

        const whereClause =  { where: Object.assign({}, andClauses, orClauses), limit: 10 }
        console.log(whereClause);

        this.Model.findAll(whereClause)
        .then(res.json.bind(res))
        .catch(next);
      }

      this.Model.describe()
       .then(createSql)
       .catch(next);

    }

    /**
     * retrieve - Retrieves a single item by ID.
     *
     * @function retrieve
     * @memberof module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    retrieve(req, res, next) {
        this.Model.findOne({
            where: {
                id: req.params.id
            }
        })
        .then(item => {
            if (!item) throw new errors.ResourceNotFoundError(this.resourceName);
            res.json(item);
        })
        .catch(next);
    }

    /**
     * update - Updates a single item given ID and that it exists.
     *
     * @function update
     * @memberof module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    update(req, res, next) {
        this.Model.findOne({
            where: {
                id: req.params.id
            }
        })
        .then(item => {
            if (!item) throw new errors.ResourceNotFoundError(this.resourceName);
            return this.Model.update(req.body, {
                where: {
                    id: req.params.id
                }
            });
        })
        .then(() => res.sendStatus(204))
        .catch(Sequelize.ValidationError, err => {
            throw new errors.ValidationError(err);
        })
        .catch(Sequelize.DatabaseError, err => {
            throw new errors.DatabaseError(err);
        })
        .catch(next);
    }

    /**
     * create - creates a new entity.
     *
     * @function create
     * @memberof module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    create(req, res, next) {
        this.Model.create(req.body)
        .then(item => res.status(201).json(item))
        .catch(Sequelize.ValidationError, err => {
            throw new errors.ValidationError(err);
        })
        .catch(next);
    }

    /**
     * destroy - Deletes an item given id and that the item exists
     *
     * @function destroy
     * @memberof module:controllers/crudController
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    destroy(req, res, next) {
        this.Model.destroy({
            where: {
                id: req.params.id
            }
        })
        .then(count => {
            if (!count) throw new errors.ResourceNotFoundError(this.resourceName);
            res.sendStatus(204);
        })
        .catch(next);
    }
}

export default CRUD;

function censor(censor) {
  var i = 0;

  return function(key, value) {
    if(i !== 0 && typeof(censor) === 'object' && typeof(value) == 'object' && censor == value)
      return '[Circular]';

    if(i >= 29) // seems to be a harded maximum of 30 serialized objects?
      return '[Unknown]';

    ++i; // so we know we aren't using the original object anymore

    return value;
  }
}

function createOr(describeData, query, key) {
  const orKeys = key.split('|');
  const orQuery = orKeys.map(key => createFieldStatement(describeData, query, key))
  return { $or: orQuery }
}

function createFieldStatement(describeData, query, key) {
  console.log('key', key);
  if(describeData[key].type == "INTEGER") {
    return { [key]: query[key] }
  } else {
    // assume text field
    return {
      [key]: {
        $iLike : `%${query[key]}%`
      }
    }
  }
}
<commit_msg>Added logging<commit_after>/**
 * General CRUD Controller
 * @module controllers/CRUD
 */
import Sequelize from 'sequelize';
import * as errors from '../components/errors';
import url from 'url'
import lodash from 'lodash'

import debug form 'debugæ

const log = debug('controllers:CRUD');

class CRUD {

    constructor(model, resourceName) {
        this.Model = model;
        this.resourceName = resourceName;

        // Bind this to methods
        this.list = this.list.bind(this);
        this.search = this.search.bind(this)
        this.retrieve = this.retrieve.bind(this);
        this.destroy = this.destroy.bind(this);
        this.update = this.update.bind(this);
        this.create = this.create.bind(this);
    }

    /**
     * list - List all objects in the database
     *
     * @function list
     * @memberof  module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    list(req, res, next) {
        this.Model.findAll()
        .then(res.json.bind(res))
        .catch(next);
    }

    /**
     * search - search all objects in the database
     *
     * @function search
     * @memberof  module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    search(req, res, next) {

      const createSql = (describeData) => {
        const { query } = url.parse(req.url, true);
        const validFields = Object.keys(describeData) ;
        const queryKeys = Object.keys(query)
        const allFields = lodash.flatMap(queryKeys, key => key.split('|'))
        log(validFields);
        const unknownFields = allFields.filter(name => !validFields.includes(name))
        if(unknownFields.length > 0) {
          return res.status(400).json({error:`Unkown field(s): ${unknownFields}`, validFields: validFields});
        }

        const andKeys = queryKeys.filter(key => !key.includes('|'))
        const orKeys = queryKeys.filter(key => key.includes('|'))

        const andClauses = andKeys.reduce((initalValue, key) => {
          return Object.assign(initalValue, createFieldStatement(describeData, query, key))
        }, {});

        const orClauses = orKeys.reduce((initalValue, key) => {
          return Object.assign(initalValue, createOr(describeData, query, key))
        }, {});

        const whereClause =  { where: Object.assign({}, andClauses, orClauses), limit: 10 }

        this.Model.findAll(whereClause)
        .then(res.json.bind(res))
        .catch(next);
      }

      this.Model.describe()
       .then(createSql)
       .catch(next);

    }

    /**
     * retrieve - Retrieves a single item by ID.
     *
     * @function retrieve
     * @memberof module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    retrieve(req, res, next) {
        this.Model.findOne({
            where: {
                id: req.params.id
            }
        })
        .then(item => {
            if (!item) throw new errors.ResourceNotFoundError(this.resourceName);
            res.json(item);
        })
        .catch(next);
    }

    /**
     * update - Updates a single item given ID and that it exists.
     *
     * @function update
     * @memberof module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    update(req, res, next) {
        this.Model.findOne({
            where: {
                id: req.params.id
            }
        })
        .then(item => {
            if (!item) throw new errors.ResourceNotFoundError(this.resourceName);
            return this.Model.update(req.body, {
                where: {
                    id: req.params.id
                }
            });
        })
        .then(() => res.sendStatus(204))
        .catch(Sequelize.ValidationError, err => {
            throw new errors.ValidationError(err);
        })
        .catch(Sequelize.DatabaseError, err => {
            throw new errors.DatabaseError(err);
        })
        .catch(next);
    }

    /**
     * create - creates a new entity.
     *
     * @function create
     * @memberof module:controllers/CRUD
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    create(req, res, next) {
        this.Model.create(req.body)
        .then(item => res.status(201).json(item))
        .catch(Sequelize.ValidationError, err => {
            throw new errors.ValidationError(err);
        })
        .catch(next);
    }

    /**
     * destroy - Deletes an item given id and that the item exists
     *
     * @function destroy
     * @memberof module:controllers/crudController
     * @param  {Object} req  Express request object
     * @param  {Object} res  Express response object
     * @param  {Function} next Express next middleware function
     */
    destroy(req, res, next) {
        this.Model.destroy({
            where: {
                id: req.params.id
            }
        })
        .then(count => {
            if (!count) throw new errors.ResourceNotFoundError(this.resourceName);
            res.sendStatus(204);
        })
        .catch(next);
    }
}

export default CRUD;

function censor(censor) {
  var i = 0;

  return function(key, value) {
    if(i !== 0 && typeof(censor) === 'object' && typeof(value) == 'object' && censor == value)
      return '[Circular]';

    if(i >= 29) // seems to be a harded maximum of 30 serialized objects?
      return '[Unknown]';

    ++i; // so we know we aren't using the original object anymore

    return value;
  }
}

function createOr(describeData, query, key) {
  const orKeys = key.split('|');
  const orQuery = orKeys.map(key => createFieldStatement(describeData, query, key))
  return { $or: orQuery }
}

function createFieldStatement(describeData, query, key) {
  console.log('key', key);
  if(describeData[key].type == "INTEGER") {
    return { [key]: query[key] }
  } else {
    // assume text field
    return {
      [key]: {
        $iLike : `%${query[key]}%`
      }
    }
  }
}
<|endoftext|>


<commit_before>import path from 'path';
import fs from 'fs';
import { promisify, promisifyAll, fromNode as promiseFromNode } from 'bluebird';
import nunjucks from 'nunjucks';
import permalinks from 'permalinks';
import MkMeta from 'marked-metadata';
import mkdirp from 'mkdirp';
import { ncp } from 'ncp';
import rimraf from 'rimraf';
import stylus from 'stylus';
import less from 'less';
import { rootdir, postspath, pagespath } from './config';
import { cliColor, getConfig } from './helpers';
import Theme from './theme';
promisifyAll(fs);
const mkdirpAsync = promisify(mkdirp);
const ncpAsync = promisify(ncp);
const rimrafAsync = promisify(rimraf);

const clc = cliColor();
const rMarkdownExt = /\.(?:md|markdown)$/;

const Helper = {

    sort: function _sort(a, b) {
        return new Date(b.date) - new Date(a.date);
    },

    sortPosts: function(posts) {
        var p,
            newPosts = {};

        for (p in posts) {
            posts[p].sort(Helper.sort);
            newPosts[p] = posts[p];
        }
        return newPosts;
    },

    normalizeMetaData: function(data) {
        data.title = data.title.replace(/\"/g, '');
        return data;
    },

    normalizeContent: function(data) {
        return data;
    }
};

export default class Harmonic {

    constructor(sitePath, { quiet = true } = {}) {
        this.sitePath = path.resolve(sitePath);
        this.quiet = !!quiet;

        const config = getConfig(this.sitePath);
        this.theme = new Theme(config.theme, this.sitePath);

        if (fs.existsSync(path.join(this.theme.themePath, 'config.json'))) {
            Object.assign(config, JSON.parse(this.theme.getFileContents('config.json')));
        }

        this.config = config;
        this.nunjucksEnv = nunjucks.configure(this.theme.themePath, { watch: false });
    }

    async clean() {
        console.log(clc.warn('Cleaning up...'));
        await rimrafAsync(path.join(this.sitePath, 'public'), { maxBusyTries: 20 });
    }

    async compileCSS() {
        const currentCSSCompiler = this.config.preprocessor;
        if (!currentCSSCompiler) return;

        const compiler = {

            less: async () => {
                const lessIndexPath = path.join(this.theme.themePath, 'resources/_less/index.less');
                const cssDir = path.join(this.sitePath, 'public/css');

                const lessInput = await fs.readFileAsync(lessIndexPath, { encoding: 'utf8' });
                const { css } = await less.render(lessInput, { filename: lessIndexPath });

                await mkdirpAsync(cssDir);
                await fs.writeFileAsync(path.join(cssDir, 'main.css'), css);

                console.log(clc.info('Successfully generated CSS with LESS preprocessor'));
            },

            stylus: async () => {
                const stylDir = path.join(this.theme.themePath, 'resources/_stylus');
                const stylIndexPath = path.join(stylDir, 'index.styl');
                const cssDir = path.join(this.sitePath, 'public/css');

                const stylInput = await fs.readFileAsync(stylIndexPath, { encoding: 'utf8' });
                const css = await promiseFromNode((cb) => {
                    stylus(stylInput)
                        .set('filename', stylIndexPath)
                        .set('paths', [path.join(stylDir, 'engine'), path.join(stylDir, 'partials')])
                        .render(cb);
                });

                await mkdirpAsync(cssDir);
                await fs.writeFileAsync(path.join(cssDir, 'main.css'), css);

                console.log(clc.info('Successfully generated CSS with Stylus preprocessor'));
            }
        };

        if (!compiler.hasOwnProperty(currentCSSCompiler)) {
            throw new Error(`Unsupported CSS preprocessor: ${currentCSSCompiler}`);
        }

        await compiler[currentCSSCompiler]();
    }

    async compileJS(postsMetadata, pagesMetadata) {
        const harmonicClient = (await fs.readFileAsync(`${rootdir}/bin/client/harmonic-client.js`, { encoding: 'utf8' }))
            .replace(/__HARMONIC\.POSTS__/g, JSON.stringify(Helper.sortPosts(postsMetadata)))
            .replace(/__HARMONIC\.PAGES__/g, JSON.stringify(pagesMetadata))
            .replace(/__HARMONIC\.CONFIG__/g, JSON.stringify(this.config));

        await fs.writeFileAsync(path.join(this.sitePath, 'public/harmonic.js'), harmonicClient);
    }

    generateTagsPages(postsMetadata) {
        var postsByTag = {},
            nunjucksEnv = this.nunjucksEnv,
            tagTemplate = this.theme.getFileContents('index.html'),
            tagTemplateNJ = nunjucks.compile(tagTemplate, nunjucksEnv),
            tagPath = null,
            lang, i, tags, y, tag, tagContent,
            config = this.config;

        for (lang in postsMetadata) {
            for (i = 0; i < postsMetadata[lang].length; i += 1) {
                tags = postsMetadata[lang][i].categories;
                for (y = 0; y < tags.length; y += 1) {
                    tag = tags[y]
                    .toLowerCase()
                    .trim()
                    .split(' ')
                    .join('-');

                    if (Array.isArray(postsByTag[tag])) {
                        postsByTag[tag].push(postsMetadata[lang][i]);
                    } else {
                        postsByTag[tag] = [postsMetadata[lang][i]];
                    }
                }
            }

            for (i in postsByTag) {
                tagContent = tagTemplateNJ.render({
                    posts: postsByTag[i].filter((post) => post.lang === lang),
                    config,
                    category: i
                });

                // If is the default language, generate in the root path
                if (config.i18n.default === lang) {
                    tagPath = path.join(this.sitePath, 'public/categories', i);
                } else {
                    tagPath = path.join(this.sitePath, 'public/categories', lang, i);
                }

                mkdirp.sync(tagPath);
                fs.writeFileSync(path.join(tagPath, 'index.html'), tagContent);
                console.log(
                    clc.info(`Successfully generated tag[${i}] archive html file`)
                );
            }
        }
    }

    generateIndex(postsMetadata, pagesMetadata) {
        var lang,
            _posts = null,
            nunjucksEnv = this.nunjucksEnv,
            indexTemplate = this.theme.getFileContents('index.html'),
            indexTemplateNJ = nunjucks.compile(indexTemplate, nunjucksEnv),
            indexContent = '',
            indexPath = null,
            config = this.config;

        for (lang in postsMetadata) {
            postsMetadata[lang].sort(Helper.sort);

            _posts = postsMetadata[lang].slice(0, config.index_posts || 10);

            indexContent = indexTemplateNJ.render({
                posts: _posts,
                config: config,
                pages: pagesMetadata
            });

            if (config.i18n.default === lang) {
                indexPath = path.join(this.sitePath, 'public');
            } else {
                indexPath = path.join(this.sitePath, 'public', lang);
            }
            mkdirp.sync(indexPath);
            fs.writeFileSync(path.join(indexPath, 'index.html'), indexContent);
            console.log(clc.info(`${lang}/index file successfully created`));
        }
    }

    async copyThemeResources() {
        await ncpAsync(path.join(this.theme.themePath, 'resources'), path.join(this.sitePath, 'public'), { stopOnErr: true });
        console.log(clc.info('Theme resources copied'));
    }

    async copyUserResources() {
        const userResourcesPath = path.join(this.sitePath, 'resources');
        await mkdirpAsync(userResourcesPath);
        await ncpAsync(userResourcesPath, path.join(this.sitePath, 'public'), { stopOnErr: true });
        console.log(clc.info(`User resources copied`));
    }

    async generatePosts(files) {
        var langs = Object.keys(files),
            config = this.config,
            posts = {},
            currentDate = new Date(),
            nunjucksEnv = this.nunjucksEnv,
            postsTemplate = this.theme.getFileContents('post.html'),
            postsTemplateNJ = nunjucks.compile(postsTemplate, nunjucksEnv),
            tokens = [
                config.header_tokens ? config.header_tokens[0] : '<!--',
                config.header_tokens ? config.header_tokens[1] : '-->'
            ];

        await* [].concat(...langs.map((lang) => files[lang].map(async (file) => {
            var metadata, post, postCropped, filename, checkDate, postPath, categories,
                _post, postHTMLFile, postDate, month, year, options,
                md = new MkMeta(path.join(this.sitePath, postspath, lang, file));

            md.defineTokens(tokens[0], tokens[1]);
            metadata = Helper.normalizeMetaData(md.metadata());
            post = Helper.normalizeContent(md.markdown());
            postCropped = md.markdown({
                crop: '<!--more-->'
            });

            filename = path.extname(file) === '.md' ?
                path.basename(file, '.md') :
                path.basename(file, '.markdown');

            checkDate = new Date(filename.substr(0, 10));

            filename = isNaN(checkDate.getDate()) ?
                filename :
                filename.substr(11, filename.length);

            postPath = null;
            categories = metadata.categories.split(',');
            postDate = new Date(metadata.date);
            year = postDate.getFullYear();
            month = ('0' + (postDate.getMonth() + 1)).slice(-2);

            // If is the default language, generate in the root path
            options = {
                replacements: [{
                    pattern: ':year',
                    replacement: year
                },
                {
                    pattern: ':month',
                    replacement: month
                },
                {
                    pattern: ':title',
                    replacement: filename
                },
                {
                    pattern: ':language',
                    replacement: lang
                }]
            };
            if (config.i18n.default === lang && config.posts_permalink.match(':language')) {
                options.structure = config.posts_permalink.split(':language/')[1];
                postPath = permalinks(options);
            } else {
                options.structure = config.posts_permalink;
                postPath = permalinks(options);
            }

            metadata.categories = categories;
            metadata.content = postCropped;
            metadata.file = postspath + file;
            metadata.filename = filename;
            metadata.link = postPath;
            metadata.lang = lang;
            metadata.default_lang = config.i18n.default === lang ? false : true;
            metadata.date = new Date(metadata.date);

            _post = {
                content: post,
                metadata: metadata
            };

            postHTMLFile = postsTemplateNJ
                .render({
                    post: _post,
                    config: config
                })
                .replace(/<!--[\s\S]*?-->/g, '');

            if (metadata.published && metadata.published === 'false') {
                return;
            }

            if (metadata.date && metadata.date > currentDate) {
                console.log(clc.info(`Skipping future post ${metadata.filename}`));
                return;
            }

            await mkdirpAsync(path.join(this.sitePath, 'public', postPath));

            // write post html file
            await fs.writeFileAsync(path.join(this.sitePath, 'public', postPath, 'index.html'), postHTMLFile);
            console.log(clc.info('Successfully generated post ' + postPath));

            posts[lang] = posts[lang] || [];
            posts[lang].push(metadata);
        })));
        return posts;
    }

    async generatePages(files) {
        const langs = Object.keys(files);
        const config = this.config;
        const tokens = [
            config.header_tokens ? config.header_tokens[0] : '<!--',
            config.header_tokens ? config.header_tokens[1] : '-->'
        ];
        const pages = [];

        await* [].concat(...langs.map((lang) => files[lang].map(async (file) => {
            var metadata, pagePermalink, _page, pageHTMLFile,
                pagePath = path.join(this.sitePath, pagespath, lang, file),
                pageTpl = this.theme.getFileContents('page.html'),
                pageTplNJ = nunjucks.compile(pageTpl, this.nunjucksEnv),
                md = new MkMeta(pagePath),
                pageSrc = '',
                filename = path.extname(file) === '.md' ?
                    path.basename(file, '.md') :
                    path.basename(file, '.markdown');

            md.defineTokens(tokens[0], tokens[1]);

            // Markdown extra
            metadata = md.metadata();
            pagePermalink = permalinks(config.pages_permalink, {
                title: filename
            });

            _page = {
                content: md.markdown(),
                metadata: metadata
            };

            pageHTMLFile = pageTplNJ.render({
                page: _page,
                config: config
            });

            // Removing header metadata
            pageHTMLFile = pageHTMLFile.replace(/<!--[\s\S]*?-->/g, '');

            metadata.content = pageHTMLFile;
            metadata.file = postspath + file; // TODO check whether this needs sitePath
            metadata.filename = filename;
            metadata.link = `/${filename}.html`;
            metadata.date = new Date(metadata.date);
            pageSrc = path.join(this.sitePath, 'public', pagePermalink, 'index.html');

            pages.push(metadata);

            await mkdirpAsync(path.join(this.sitePath, 'public', pagePermalink));

            // write page html file
            await fs.writeFileAsync(pageSrc, pageHTMLFile);
            console.log(clc.info(`Successfully generated page ${pagePermalink}`));
        })));
        return pages;
    }

    async getPostFiles() {
        const files = {};

        for (const lang of this.config.i18n.languages) {
            files[lang] = (await fs.readdirAsync(path.join(this.sitePath, postspath, lang)))
                .filter((p) => rMarkdownExt.test(p));
        }

        return files;
    }

    async getPageFiles() {
        const files = {};

        for (const lang of this.config.i18n.languages) {
            const langPath = path.join(this.sitePath, pagespath, lang);
            await mkdirpAsync(langPath);
            files[lang] = (await fs.readdirAsync(langPath)).filter((p) => rMarkdownExt.test(p));
        }

        return files;
    }

    async generateRSS(postsMetadata, pagesMetadata) {
        var _posts = null,
            nunjucksEnv = this.nunjucksEnv,
            rssTemplate = await fs.readFileAsync(`${__dirname}/resources/rss.xml`),
            rssTemplateNJ = nunjucks.compile(rssTemplate.toString(), nunjucksEnv),
            rssContent = '',
            rssPath = null,
            rssLink = '',
            rssAuthor = '',
            config = this.config,
            lang;

        for (lang in postsMetadata) {
            postsMetadata[lang].sort(Helper.sort);
            _posts = postsMetadata[lang].slice(0, config.index_posts || 10);

            if (config.author_email) {
                rssAuthor = `${config.author_email} ( ${config.author} )`;
            } else {
                rssAuthor = config.author;
            }

            if (config.i18n.default === lang) {
                rssPath = path.join(this.sitePath, 'public');
                rssLink = `${config.domain}/rss.xml`;
            } else {
                rssPath = path.join(this.sitePath, 'public', lang);
                rssLink = `${config.domain}/${lang}/rss.xml`;
            }

            rssContent = rssTemplateNJ.render({
                rss: {
                    date: new Date().toUTCString(),
                    link: rssLink,
                    author: rssAuthor,
                    lang: lang
                },
                posts: _posts,
                config: config,
                pages: pagesMetadata
            });

            await mkdirpAsync(rssPath);
            await fs.writeFileAsync(`${rssPath}/rss.xml`, rssContent);
            console.log(clc.info(`${lang}/rss.xml file successfully created`));
        }
    }
}
<commit_msg>clean up<commit_after>import path from 'path';
import fs from 'fs';
import { promisify, promisifyAll, fromNode as promiseFromNode } from 'bluebird';
import nunjucks from 'nunjucks';
import permalinks from 'permalinks';
import MkMeta from 'marked-metadata';
import mkdirp from 'mkdirp';
import { ncp } from 'ncp';
import rimraf from 'rimraf';
import stylus from 'stylus';
import less from 'less';
import { rootdir, postspath, pagespath } from './config';
import { cliColor, getConfig } from './helpers';
import Theme from './theme';
promisifyAll(fs);
const mkdirpAsync = promisify(mkdirp);
const ncpAsync = promisify(ncp);
const rimrafAsync = promisify(rimraf);

const clc = cliColor();
const rMarkdownExt = /\.(?:md|markdown)$/;

const Helper = {

    sort(a, b) {
        return new Date(b.date) - new Date(a.date);
    },

    sortPosts: function(posts) {
        Object.values(posts).forEach((postsArray) => postsArray.sort(Helper.sort));
        return posts;
    },

    normalizeMetaData(data) {
        data.title = data.title.replace(/\"/g, '');
        return data;
    },

    normalizeContent(data) {
        return data;
    }
};

export default class Harmonic {

    constructor(sitePath, { quiet = true } = {}) {
        this.sitePath = path.resolve(sitePath);
        this.quiet = !!quiet;

        const config = getConfig(this.sitePath);
        this.theme = new Theme(config.theme, this.sitePath);

        if (fs.existsSync(path.join(this.theme.themePath, 'config.json'))) {
            Object.assign(config, JSON.parse(this.theme.getFileContents('config.json')));
        }

        this.config = config;
        this.nunjucksEnv = nunjucks.configure(this.theme.themePath, { watch: false });
    }

    async clean() {
        console.log(clc.warn('Cleaning up...'));
        await rimrafAsync(path.join(this.sitePath, 'public'), { maxBusyTries: 20 });
    }

    async compileCSS() {
        const currentCSSCompiler = this.config.preprocessor;
        if (!currentCSSCompiler) return;

        const compiler = {

            less: async () => {
                const lessIndexPath = path.join(this.theme.themePath, 'resources/_less/index.less');
                const cssDir = path.join(this.sitePath, 'public/css');

                const lessInput = await fs.readFileAsync(lessIndexPath, { encoding: 'utf8' });
                const { css } = await less.render(lessInput, { filename: lessIndexPath });

                await mkdirpAsync(cssDir);
                await fs.writeFileAsync(path.join(cssDir, 'main.css'), css);

                console.log(clc.info('Successfully generated CSS with LESS preprocessor'));
            },

            stylus: async () => {
                const stylDir = path.join(this.theme.themePath, 'resources/_stylus');
                const stylIndexPath = path.join(stylDir, 'index.styl');
                const cssDir = path.join(this.sitePath, 'public/css');

                const stylInput = await fs.readFileAsync(stylIndexPath, { encoding: 'utf8' });
                const css = await promiseFromNode((cb) => {
                    stylus(stylInput)
                        .set('filename', stylIndexPath)
                        .set('paths', [path.join(stylDir, 'engine'), path.join(stylDir, 'partials')])
                        .render(cb);
                });

                await mkdirpAsync(cssDir);
                await fs.writeFileAsync(path.join(cssDir, 'main.css'), css);

                console.log(clc.info('Successfully generated CSS with Stylus preprocessor'));
            }
        };

        if (!compiler.hasOwnProperty(currentCSSCompiler)) {
            throw new Error(`Unsupported CSS preprocessor: ${currentCSSCompiler}`);
        }

        await compiler[currentCSSCompiler]();
    }

    async compileJS(postsMetadata, pagesMetadata) {
        const harmonicClient = (await fs.readFileAsync(`${rootdir}/bin/client/harmonic-client.js`, { encoding: 'utf8' }))
            .replace(/__HARMONIC\.POSTS__/g, JSON.stringify(postsMetadata))
            .replace(/__HARMONIC\.PAGES__/g, JSON.stringify(pagesMetadata))
            .replace(/__HARMONIC\.CONFIG__/g, JSON.stringify(this.config));

        await fs.writeFileAsync(path.join(this.sitePath, 'public/harmonic.js'), harmonicClient);
    }

    generateTagsPages(postsMetadata) {
        var postsByTag = {},
            nunjucksEnv = this.nunjucksEnv,
            tagTemplate = this.theme.getFileContents('index.html'),
            tagTemplateNJ = nunjucks.compile(tagTemplate, nunjucksEnv),
            tagPath = null,
            lang, i, tags, y, tag, tagContent,
            config = this.config;

        for (lang in postsMetadata) {
            for (i = 0; i < postsMetadata[lang].length; i += 1) {
                tags = postsMetadata[lang][i].categories;
                for (y = 0; y < tags.length; y += 1) {
                    tag = tags[y]
                    .toLowerCase()
                    .trim()
                    .split(' ')
                    .join('-');

                    if (Array.isArray(postsByTag[tag])) {
                        postsByTag[tag].push(postsMetadata[lang][i]);
                    } else {
                        postsByTag[tag] = [postsMetadata[lang][i]];
                    }
                }
            }

            for (i in postsByTag) {
                tagContent = tagTemplateNJ.render({
                    posts: postsByTag[i].filter((post) => post.lang === lang),
                    config,
                    category: i
                });

                // If is the default language, generate in the root path
                if (config.i18n.default === lang) {
                    tagPath = path.join(this.sitePath, 'public/categories', i);
                } else {
                    tagPath = path.join(this.sitePath, 'public/categories', lang, i);
                }

                mkdirp.sync(tagPath);
                fs.writeFileSync(path.join(tagPath, 'index.html'), tagContent);
                console.log(
                    clc.info(`Successfully generated tag[${i}] archive html file`)
                );
            }
        }
    }

    generateIndex(postsMetadata, pagesMetadata) {
        var lang,
            _posts = null,
            nunjucksEnv = this.nunjucksEnv,
            indexTemplate = this.theme.getFileContents('index.html'),
            indexTemplateNJ = nunjucks.compile(indexTemplate, nunjucksEnv),
            indexContent = '',
            indexPath = null,
            config = this.config;

        for (lang in postsMetadata) {
            postsMetadata[lang].sort(Helper.sort);

            _posts = postsMetadata[lang].slice(0, config.index_posts || 10);

            indexContent = indexTemplateNJ.render({
                posts: _posts,
                config: config,
                pages: pagesMetadata
            });

            if (config.i18n.default === lang) {
                indexPath = path.join(this.sitePath, 'public');
            } else {
                indexPath = path.join(this.sitePath, 'public', lang);
            }
            mkdirp.sync(indexPath);
            fs.writeFileSync(path.join(indexPath, 'index.html'), indexContent);
            console.log(clc.info(`${lang}/index file successfully created`));
        }
    }

    async copyThemeResources() {
        await ncpAsync(path.join(this.theme.themePath, 'resources'), path.join(this.sitePath, 'public'), { stopOnErr: true });
        console.log(clc.info('Theme resources copied'));
    }

    async copyUserResources() {
        const userResourcesPath = path.join(this.sitePath, 'resources');
        await mkdirpAsync(userResourcesPath);
        await ncpAsync(userResourcesPath, path.join(this.sitePath, 'public'), { stopOnErr: true });
        console.log(clc.info(`User resources copied`));
    }

    async generatePosts(files) {
        var langs = Object.keys(files),
            config = this.config,
            posts = {},
            currentDate = new Date(),
            nunjucksEnv = this.nunjucksEnv,
            postsTemplate = this.theme.getFileContents('post.html'),
            postsTemplateNJ = nunjucks.compile(postsTemplate, nunjucksEnv),
            tokens = [
                config.header_tokens ? config.header_tokens[0] : '<!--',
                config.header_tokens ? config.header_tokens[1] : '-->'
            ];

        await* [].concat(...langs.map((lang) => files[lang].map(async (file) => {
            var metadata, post, postCropped, filename, checkDate, postPath, categories,
                _post, postHTMLFile, postDate, month, year, options,
                md = new MkMeta(path.join(this.sitePath, postspath, lang, file));

            md.defineTokens(tokens[0], tokens[1]);
            metadata = Helper.normalizeMetaData(md.metadata());
            post = Helper.normalizeContent(md.markdown());
            postCropped = md.markdown({
                crop: '<!--more-->'
            });

            filename = path.extname(file) === '.md' ?
                path.basename(file, '.md') :
                path.basename(file, '.markdown');

            checkDate = new Date(filename.substr(0, 10));

            filename = isNaN(checkDate.getDate()) ?
                filename :
                filename.substr(11, filename.length);

            postPath = null;
            categories = metadata.categories.split(',');
            postDate = new Date(metadata.date);
            year = postDate.getFullYear();
            month = ('0' + (postDate.getMonth() + 1)).slice(-2);

            // If is the default language, generate in the root path
            options = {
                replacements: [{
                    pattern: ':year',
                    replacement: year
                },
                {
                    pattern: ':month',
                    replacement: month
                },
                {
                    pattern: ':title',
                    replacement: filename
                },
                {
                    pattern: ':language',
                    replacement: lang
                }]
            };
            if (config.i18n.default === lang && config.posts_permalink.match(':language')) {
                options.structure = config.posts_permalink.split(':language/')[1];
                postPath = permalinks(options);
            } else {
                options.structure = config.posts_permalink;
                postPath = permalinks(options);
            }

            metadata.categories = categories;
            metadata.content = postCropped;
            metadata.file = postspath + file;
            metadata.filename = filename;
            metadata.link = postPath;
            metadata.lang = lang;
            metadata.default_lang = config.i18n.default === lang ? false : true;
            metadata.date = new Date(metadata.date);

            _post = {
                content: post,
                metadata: metadata
            };

            postHTMLFile = postsTemplateNJ
                .render({
                    post: _post,
                    config: config
                })
                .replace(/<!--[\s\S]*?-->/g, '');

            if (metadata.published && metadata.published === 'false') {
                return;
            }

            if (metadata.date && metadata.date > currentDate) {
                console.log(clc.info(`Skipping future post ${metadata.filename}`));
                return;
            }

            await mkdirpAsync(path.join(this.sitePath, 'public', postPath));

            // write post html file
            await fs.writeFileAsync(path.join(this.sitePath, 'public', postPath, 'index.html'), postHTMLFile);
            console.log(clc.info('Successfully generated post ' + postPath));

            posts[lang] = posts[lang] || [];
            posts[lang].push(metadata);
        })));
        return Helper.sortPosts(posts);
    }

    async generatePages(files) {
        const langs = Object.keys(files);
        const config = this.config;
        const tokens = [
            config.header_tokens ? config.header_tokens[0] : '<!--',
            config.header_tokens ? config.header_tokens[1] : '-->'
        ];
        const pages = [];

        await* [].concat(...langs.map((lang) => files[lang].map(async (file) => {
            var metadata, pagePermalink, _page, pageHTMLFile,
                pagePath = path.join(this.sitePath, pagespath, lang, file),
                pageTpl = this.theme.getFileContents('page.html'),
                pageTplNJ = nunjucks.compile(pageTpl, this.nunjucksEnv),
                md = new MkMeta(pagePath),
                pageSrc = '',
                filename = path.extname(file) === '.md' ?
                    path.basename(file, '.md') :
                    path.basename(file, '.markdown');

            md.defineTokens(tokens[0], tokens[1]);

            // Markdown extra
            metadata = md.metadata();
            pagePermalink = permalinks(config.pages_permalink, {
                title: filename
            });

            _page = {
                content: md.markdown(),
                metadata: metadata
            };

            pageHTMLFile = pageTplNJ.render({
                page: _page,
                config: config
            });

            // Removing header metadata
            pageHTMLFile = pageHTMLFile.replace(/<!--[\s\S]*?-->/g, '');

            metadata.content = pageHTMLFile;
            metadata.file = postspath + file; // TODO check whether this needs sitePath
            metadata.filename = filename;
            metadata.link = `/${filename}.html`;
            metadata.date = new Date(metadata.date);
            pageSrc = path.join(this.sitePath, 'public', pagePermalink, 'index.html');

            pages.push(metadata);

            await mkdirpAsync(path.join(this.sitePath, 'public', pagePermalink));

            // write page html file
            await fs.writeFileAsync(pageSrc, pageHTMLFile);
            console.log(clc.info(`Successfully generated page ${pagePermalink}`));
        })));
        return pages;
    }

    async getPostFiles() {
        const files = {};

        for (const lang of this.config.i18n.languages) {
            files[lang] = (await fs.readdirAsync(path.join(this.sitePath, postspath, lang)))
                .filter((p) => rMarkdownExt.test(p));
        }

        return files;
    }

    async getPageFiles() {
        const files = {};

        for (const lang of this.config.i18n.languages) {
            const langPath = path.join(this.sitePath, pagespath, lang);
            await mkdirpAsync(langPath);
            files[lang] = (await fs.readdirAsync(langPath)).filter((p) => rMarkdownExt.test(p));
        }

        return files;
    }

    async generateRSS(postsMetadata, pagesMetadata) {
        var _posts = null,
            nunjucksEnv = this.nunjucksEnv,
            rssTemplate = await fs.readFileAsync(`${__dirname}/resources/rss.xml`),
            rssTemplateNJ = nunjucks.compile(rssTemplate.toString(), nunjucksEnv),
            rssContent = '',
            rssPath = null,
            rssLink = '',
            rssAuthor = '',
            config = this.config,
            lang;

        for (lang in postsMetadata) {
            postsMetadata[lang].sort(Helper.sort);
            _posts = postsMetadata[lang].slice(0, config.index_posts || 10);

            if (config.author_email) {
                rssAuthor = `${config.author_email} ( ${config.author} )`;
            } else {
                rssAuthor = config.author;
            }

            if (config.i18n.default === lang) {
                rssPath = path.join(this.sitePath, 'public');
                rssLink = `${config.domain}/rss.xml`;
            } else {
                rssPath = path.join(this.sitePath, 'public', lang);
                rssLink = `${config.domain}/${lang}/rss.xml`;
            }

            rssContent = rssTemplateNJ.render({
                rss: {
                    date: new Date().toUTCString(),
                    link: rssLink,
                    author: rssAuthor,
                    lang: lang
                },
                posts: _posts,
                config: config,
                pages: pagesMetadata
            });

            await mkdirpAsync(rssPath);
            await fs.writeFileAsync(`${rssPath}/rss.xml`, rssContent);
            console.log(clc.info(`${lang}/rss.xml file successfully created`));
        }
    }
}
<|endoftext|>


<commit_before>/*global describe, it, browser, beforeEach, require */

describe('buttons', function () {
    'use strict';

    var options = {},
        common;

    beforeEach(function (done) {
        common = require('../common');
        common.initWebdriverCss(browser, options, done);
    });

    it('should match the baseline buttons screenshot', function (done) {
        var result;

        result = browser.url('/buttons/fixtures/test.full.html');

        common.compareScreenshot({
            browserResult: result,
            prefix: options.prefix,
            screenshotName: 'buttons',
            selector: '#screenshot-buttons',
            done: done
        });
    });

    function getSelector(type, prefix) {
        var selector = (prefix !== undefined ? ('.' + prefix + '-') : '.') + 'btn-' + type;
        return selector;
    }

    function clickTest(type, done, prefix) {
        var result,
            selector = getSelector(type, prefix);

        result = browser.url('/buttons/fixtures/test.full.html').
                    click(selector);

        common.compareScreenshot({
            browserResult: result,
            prefix: options.prefix,
            screenshotName: ('button_' + type + '_click'),
            selector: selector,
            done: done
        });
    }

    it('should match the baseline screenshot while clicking a default button', function (done) {
        clickTest('default', done);
    });

    it('should match the baseline screenshot while clicking a primary button', function (done) {
        clickTest('primary', done);
    });

    it('should match the baseline screenshot while clicking a secondary button', function (done) {
        clickTest('secondary', done, 'bb');
    });

    it('should match the baseline screenshot while clicking a success button', function (done) {
        clickTest('success', done);
    });

    it('should match the baseline screenshot while clicking an info button', function (done) {
        clickTest('info', done);
    });

    it('should match the baseline screenshot while clicking a warning button', function (done) {
        clickTest('warning', done);
    });

    it('should match the baseline screenshot while clicking a danger button', function (done) {
        clickTest('danger', done);
    });

    it('should match the baseline screenshot while clicking a link button', function (done) {
        clickTest('link', done);
    });

});
<commit_msg>get correct selector for button click tests<commit_after>/*global describe, it, browser, beforeEach, require */

describe('buttons', function () {
    'use strict';

    var options = {},
        common;

    beforeEach(function (done) {
        common = require('../common');
        common.initWebdriverCss(browser, options, done);
    });

    it('should match the baseline buttons screenshot', function (done) {
        var result;

        result = browser.url('/buttons/fixtures/test.full.html');

        common.compareScreenshot({
            browserResult: result,
            prefix: options.prefix,
            screenshotName: 'buttons',
            selector: '#screenshot-buttons',
            done: done
        });
    });

    function getSelector(type, prefix) {
        var selector = (prefix !== undefined ? ('.' + prefix + '-') : '.') + 'btn-' + type;
        return selector;
    }

    function clickTest(type, done, prefix) {
        var result,
            selector = getSelector(type, prefix);

        result = browser.url('/buttons/fixtures/test.full.html').
                    click(selector);

        common.compareScreenshot({
            browserResult: result,
            prefix: options.prefix,
            screenshotName: ('button_' + type + '_click'),
            selector: ('#screenshots-buttons-' + type),
            done: done
        });
    }

    it('should match the baseline screenshot while clicking a default button', function (done) {
        clickTest('default', done);
    });

    it('should match the baseline screenshot while clicking a primary button', function (done) {
        clickTest('primary', done);
    });

    it('should match the baseline screenshot while clicking a secondary button', function (done) {
        clickTest('secondary', done, 'bb');
    });

    it('should match the baseline screenshot while clicking a success button', function (done) {
        clickTest('success', done);
    });

    it('should match the baseline screenshot while clicking an info button', function (done) {
        clickTest('info', done);
    });

    it('should match the baseline screenshot while clicking a warning button', function (done) {
        clickTest('warning', done);
    });

    it('should match the baseline screenshot while clicking a danger button', function (done) {
        clickTest('danger', done);
    });

    it('should match the baseline screenshot while clicking a link button', function (done) {
        clickTest('link', done);
    });

});
<|endoftext|>