<commit_before>/** @jsx etch.dom */
/* eslint react/no-unknown-property: "off" */

import {TextEditor} from 'atom';
import {CompositeDisposable} from 'event-kit';

import etch from 'etch';
import {autobind} from 'core-decorators';
import cx from 'classnames';

import {shortenSha} from '../helpers';

export default class CommitView {
  static focus = {
    EDITOR: Symbol('commit-editor'),
    ABORT_MERGE_BUTTON: Symbol('commit-abort-merge-button'),
    AMEND_BOX: Symbol('commit-amend-box'),
    COMMIT_BUTTON: Symbol('commit-button'),
  };

  constructor(props) {
    this.props = props;

    etch.initialize(this);

    this.editor = this.refs.editor;
    // FIXME Use props-injected view registry instead of the Atom global
    this.editorElement = atom.views.getView(this.editor);
    this.editor.setText(this.props.message || '');
    this.subscriptions = new CompositeDisposable(
      this.editor.onDidChange(() => this.props.onChangeMessage && this.props.onChangeMessage(this.editor.getText())),
      this.editor.onDidChangeCursorPosition(() => { etch.update(this); }),
      props.commandRegistry.add('atom-workspace', {
        'github:commit': this.commit,
        'github:toggle-expanded-commit-message-editor': this.toggleExpandedCommitMessageEditor,
      }),
    );
  }

  destroy() {
    this.subscriptions.dispose();
    etch.destroy(this);
  }

  update(props) {
    const previousMessage = this.props.message;
    this.props = {...this.props, ...props};
    const newMessage = this.props.message;
    if (this.editor && previousMessage !== newMessage && this.editor.getText() !== newMessage) {
      this.editor.setText(newMessage);
    }
    return etch.update(this);
  }

  render() {
    let remainingCharsClassName = '';
    if (this.getRemainingCharacters() < 0) {
      remainingCharsClassName = 'is-error';
    } else if (this.getRemainingCharacters() < this.props.maximumCharacterLimit / 4) {
      remainingCharsClassName = 'is-warning';
    }

    const showAbortMergeButton = this.props.isMerging || null;
    const showAmendBox = (
      !this.props.isMerging &&
      this.props.lastCommit.isPresent() &&
      !this.props.lastCommit.isUnbornRef()
    ) || null;

    return (

          <TextEditor
            ref="editor"
            softWrapped={true}
            placeholderText="Commit message"
            lineNumberGutterVisible={false}
            showInvisibles={false}
            autoHeight={false}
            scrollPastEnd={false}
          />
          <button className="github-CommitView-expandButton icon icon-screen-full"
            onClick={this.toggleExpandedCommitMessageEditor}
          />

          {showAbortMergeButton &&
            <button ref="abortMergeButton" className="btn github-CommitView-button is-secondary"
              onclick={this.abortMerge}>Abort Merge</button>
          }
          {showAmendBox &&

              <input
                ref="amend"
                className="input-checkbox"
                type="checkbox"
                onclick={this.handleAmendBoxClick}
                checked={this.props.isAmending}
              /> Amend

          }
          <button ref="commitButton" className="btn github-CommitView-button"
            onclick={this.commit}
            disabled={!this.isCommitButtonEnabled()}>{this.commitButtonText()}</button>
          <div ref="remainingCharacters"
            className={`github-CommitView-remaining-characters ${remainingCharsClassName}`}>
            {this.getRemainingCharacters()}

    );
  }

  @autobind
  abortMerge() {
    this.props.abortMerge();
  }

  @autobind
  handleAmendBoxClick() {
    this.props.setAmending(this.refs.amend.checked);
  }

  @autobind
  async commit() {
    if (await this.props.prepareToCommit() && this.isCommitButtonEnabled()) {
      try {
        await this.props.commit(this.editor.getText());
      } catch (e) {
        // do nothing
      }
    } else {
      this.setFocus(CommitView.focus.EDITOR);
    }
  }

  getRemainingCharacters() {
    if (this.editor != null) {
      if (this.editor.getCursorBufferPosition().row === 0) {
        return (this.props.maximumCharacterLimit - this.editor.lineTextForBufferRow(0).length).toString();
      } else {
        return '∞';
      }
    } else {
      return this.props.maximumCharacterLimit || '';
    }
  }

  isCommitButtonEnabled() {
    return !this.props.isCommitting &&
      this.props.stagedChangesExist &&
      !this.props.mergeConflictsExist &&
      this.props.lastCommit.isPresent() &&
      (this.props.deactivateCommitBox || (this.editor && this.editor.getText().length !== 0));
  }

  commitButtonText() {
    if (this.props.isAmending) {
      return `Amend commit (${shortenSha(this.props.lastCommit.getSha())})`;
    } else if (this.props.isCommitting) {
      return 'Working...';
    } else {
      if (this.props.branchName) {
        return `Commit to ${this.props.branchName}`;
      } else {
        return 'Commit';
      }
    }
  }

  @autobind
  toggleExpandedCommitMessageEditor() {
    return this.props.toggleExpandedCommitMessageEditor(this.editor && this.editor.getText());
  }

  rememberFocus(event) {
    if (this.editorElement.contains(event.target)) {
      return CommitView.focus.EDITOR;
    }

    if (this.refs.abortMergeButton && this.refs.abortMergeButton.contains(event.target)) {
      return CommitView.focus.ABORT_MERGE_BUTTON;
    }

    if (this.refs.amend && this.refs.amend.contains(event.target)) {
      return CommitView.focus.AMEND_BOX;
    }

    if (this.refs.commitButton && this.refs.commitButton.contains(event.target)) {
      return CommitView.focus.COMMIT_BUTTON;
    }

    return null;
  }

  setFocus(focus) {
    let fallback = false;

    if (focus === CommitView.focus.EDITOR) {
      this.editorElement.focus();
      return true;
    }

    if (focus === CommitView.focus.ABORT_MERGE_BUTTON) {
      if (this.refs.abortMergeButton) {
        this.refs.abortMergeButton.focus();
        return true;
      } else {
        fallback = true;
      }
    }

    if (focus === CommitView.focus.AMEND_BOX) {
      if (this.refs.amend) {
        this.refs.amend.focus();
        return true;
      } else {
        fallback = true;
      }
    }

    if (focus === CommitView.focus.COMMIT_BUTTON) {
      if (this.refs.commitButton) {
        this.refs.commitButton.focus();
        return true;
      } else {
        fallback = true;
      }
    }

    if (fallback) {
      this.editorElement.focus();
      return true;
    }

    return false;
  }
}
<commit_msg>Adding delay to "Working..." message<commit_after>/** @jsx etch.dom */
/* eslint react/no-unknown-property: "off" */

import {TextEditor} from 'atom';
import {CompositeDisposable} from 'event-kit';

import etch from 'etch';
import {autobind} from 'core-decorators';
import cx from 'classnames';

import {shortenSha} from '../helpers';

export default class CommitView {
  static focus = {
    EDITOR: Symbol('commit-editor'),
    ABORT_MERGE_BUTTON: Symbol('commit-abort-merge-button'),
    AMEND_BOX: Symbol('commit-amend-box'),
    COMMIT_BUTTON: Symbol('commit-button'),
  };

  constructor(props) {
    this.props = props;

    // We don't want the user to see the UI flicker in the case
    // the commit takes a very small time to complete. Instead we
    // will only show the working message if we are working for longer
    // than 1 second as per https://www.nngroup.com/articles/response-times-3-important-limits/
    //
    // The closure is created to restrict variable access
    this.shouldShowWorking = (() => {
      let showWorking = false;
      let timeoutHandle = null;

      return () => {
        if (this.props.isCommitting) {
          if (!showWorking && timeoutHandle === null) {
            timeoutHandle = setTimeout(() => {
              showWorking = true;
              etch.update(this);
              timeoutHandle = null;
            }, 1000);
          }
        } else {
          clearTimeout(timeoutHandle);
          timeoutHandle = null;
          showWorking = false;
        }

        return showWorking;
      };
    })();

    etch.initialize(this);

    this.editor = this.refs.editor;
    // FIXME Use props-injected view registry instead of the Atom global
    this.editorElement = atom.views.getView(this.editor);
    this.editor.setText(this.props.message || '');
    this.subscriptions = new CompositeDisposable(
      this.editor.onDidChange(() => this.props.onChangeMessage && this.props.onChangeMessage(this.editor.getText())),
      this.editor.onDidChangeCursorPosition(() => { etch.update(this); }),
      props.commandRegistry.add('atom-workspace', {
        'github:commit': this.commit,
        'github:toggle-expanded-commit-message-editor': this.toggleExpandedCommitMessageEditor,
      }),
    );
  }

  destroy() {
    this.subscriptions.dispose();
    etch.destroy(this);
  }

  update(props) {
    const previousMessage = this.props.message;
    this.props = {...this.props, ...props};
    const newMessage = this.props.message;
    if (this.editor && previousMessage !== newMessage && this.editor.getText() !== newMessage) {
      this.editor.setText(newMessage);
    }
    return etch.update(this);
  }

  render() {
    let remainingCharsClassName = '';
    if (this.getRemainingCharacters() < 0) {
      remainingCharsClassName = 'is-error';
    } else if (this.getRemainingCharacters() < this.props.maximumCharacterLimit / 4) {
      remainingCharsClassName = 'is-warning';
    }

    const showAbortMergeButton = this.props.isMerging || null;
    const showAmendBox = (
      !this.props.isMerging &&
      this.props.lastCommit.isPresent() &&
      !this.props.lastCommit.isUnbornRef()
    ) || null;

    return (

          <TextEditor
            ref="editor"
            softWrapped={true}
            placeholderText="Commit message"
            lineNumberGutterVisible={false}
            showInvisibles={false}
            autoHeight={false}
            scrollPastEnd={false}
          />
          <button className="github-CommitView-expandButton icon icon-screen-full"
            onClick={this.toggleExpandedCommitMessageEditor}
          />

          {showAbortMergeButton &&
            <button ref="abortMergeButton" className="btn github-CommitView-button is-secondary"
              onclick={this.abortMerge}>Abort Merge</button>
          }
          {showAmendBox &&

              <input
                ref="amend"
                className="input-checkbox"
                type="checkbox"
                onclick={this.handleAmendBoxClick}
                checked={this.props.isAmending}
              /> Amend

          }
          <button ref="commitButton" className="btn github-CommitView-button"
            onclick={this.commit}
            disabled={!this.isCommitButtonEnabled()}>{this.commitButtonText()}</button>
          <div ref="remainingCharacters"
            className={`github-CommitView-remaining-characters ${remainingCharsClassName}`}>
            {this.getRemainingCharacters()}

    );
  }

  @autobind
  abortMerge() {
    this.props.abortMerge();
  }

  @autobind
  handleAmendBoxClick() {
    this.props.setAmending(this.refs.amend.checked);
  }

  @autobind
  async commit() {
    if (await this.props.prepareToCommit() && this.isCommitButtonEnabled()) {
      try {
        await this.props.commit(this.editor.getText());
      } catch (e) {
        // do nothing
      }
    } else {
      this.setFocus(CommitView.focus.EDITOR);
    }
  }

  getRemainingCharacters() {
    if (this.editor != null) {
      if (this.editor.getCursorBufferPosition().row === 0) {
        return (this.props.maximumCharacterLimit - this.editor.lineTextForBufferRow(0).length).toString();
      } else {
        return '∞';
      }
    } else {
      return this.props.maximumCharacterLimit || '';
    }
  }

  isCommitButtonEnabled() {
    return !this.props.isCommitting &&
      this.props.stagedChangesExist &&
      !this.props.mergeConflictsExist &&
      this.props.lastCommit.isPresent() &&
      (this.props.deactivateCommitBox || (this.editor && this.editor.getText().length !== 0));
  }

  @autobind
  commitButtonText() {
    if (this.props.isAmending) {
      return `Amend commit (${shortenSha(this.props.lastCommit.getSha())})`;
    } else if (this.shouldShowWorking()) {
      return 'Working...';
    } else {
      if (this.props.branchName) {
        return `Commit to ${this.props.branchName}`;
      } else {
        return 'Commit';
      }
    }
  }

  @autobind
  toggleExpandedCommitMessageEditor() {
    return this.props.toggleExpandedCommitMessageEditor(this.editor && this.editor.getText());
  }

  rememberFocus(event) {
    if (this.editorElement.contains(event.target)) {
      return CommitView.focus.EDITOR;
    }

    if (this.refs.abortMergeButton && this.refs.abortMergeButton.contains(event.target)) {
      return CommitView.focus.ABORT_MERGE_BUTTON;
    }

    if (this.refs.amend && this.refs.amend.contains(event.target)) {
      return CommitView.focus.AMEND_BOX;
    }

    if (this.refs.commitButton && this.refs.commitButton.contains(event.target)) {
      return CommitView.focus.COMMIT_BUTTON;
    }

    return null;
  }

  setFocus(focus) {
    let fallback = false;

    if (focus === CommitView.focus.EDITOR) {
      this.editorElement.focus();
      return true;
    }

    if (focus === CommitView.focus.ABORT_MERGE_BUTTON) {
      if (this.refs.abortMergeButton) {
        this.refs.abortMergeButton.focus();
        return true;
      } else {
        fallback = true;
      }
    }

    if (focus === CommitView.focus.AMEND_BOX) {
      if (this.refs.amend) {
        this.refs.amend.focus();
        return true;
      } else {
        fallback = true;
      }
    }

    if (focus === CommitView.focus.COMMIT_BUTTON) {
      if (this.refs.commitButton) {
        this.refs.commitButton.focus();
        return true;
      } else {
        fallback = true;
      }
    }

    if (fallback) {
      this.editorElement.focus();
      return true;
    }

    return false;
  }
}
<|endoftext|>


<commit_before>var WAITON_MESSAGE_FIELDS = ['msg', 'id', 'method', 'name', 'waitTime'];

// This is way how we can build waitTime and it's breakdown
WaitTimeBuilder = function() {
  this._waitListStore = {};
  this._currentProcessingMessages = {};
  this._messageCache = {};
};

WaitTimeBuilder.prototype.register = function(session, msgId) {
  var self = this;
  var mainKey = self._getMessageKey(session.id, msgId);

  var waitList = session.inQueue && session.inQueue.map(function(msg) {
    var key = self._getMessageKey(session.id, msg.id);
    return self._getCacheMessage(key, msg);
  });

  //add currently processing ddp message if exists
  var currentlyProcessingMessage = this._currentProcessingMessages[session.id];
  if(currentlyProcessingMessage) {
    var key = self._getMessageKey(session.id, currentlyProcessingMessage.id);
    waitList.unshift(this._getCacheMessage(key, currentlyProcessingMessage));
  }

  this._waitListStore[mainKey] = waitList;
};

WaitTimeBuilder.prototype.build = function(session, msgId) {
  var mainKey = this._getMessageKey(session.id, msgId);
  var waitList = this._waitListStore[mainKey] || [];
  delete this._waitListStore[mainKey];

  var filteredWaitList =  waitList.map(this._cleanCacheMessage.bind(this));
  return filteredWaitList;
};

WaitTimeBuilder.prototype._getMessageKey = function(sessionId, msgId) {
  return sessionId + "::" + msgId;
};

WaitTimeBuilder.prototype._getCacheMessage = function(key, msg) {
  var self = this;
  var cachedMessage = self._messageCache[key];
  if(!cachedMessage) {
    self._messageCache[key] = cachedMessage = _.pick(msg, WAITON_MESSAGE_FIELDS);
    cachedMessage._key = key;
    cachedMessage._registered = 1;
  } else {
    cachedMessage._registered++;
  }

  return cachedMessage;
};

WaitTimeBuilder.prototype._cleanCacheMessage = function(msg) {
  msg._registered--;
  if(msg._registered == 0) {
    delete this._messageCache[msg._key];
  }

  // need to send a clean set of objects
  // otherwise register can go with this
  return _.pick(msg, WAITON_MESSAGE_FIELDS);
};

WaitTimeBuilder.prototype.trackWaitTime = function(session, msg, unblock) {
  var self = this;
  var started = Date.now();
  self._currentProcessingMessages[session.id] = msg;

  var unblocked = false;
  var wrappedUnblock = function() {
    if(!unblocked) {
      var waitTime = Date.now() - started;
      var key = self._getMessageKey(session.id, msg.id);
      var cachedMessage = self._messageCache[key];
      if(cachedMessage) {
        cachedMessage.waitTime = waitTime;
      }
      delete self._currentProcessingMessages[session.id];
      unblocked = true;
      unblock();
    }
  };

  return wrappedUnblock;
};<commit_msg>Make sure inQueue.map is also exists<commit_after>var WAITON_MESSAGE_FIELDS = ['msg', 'id', 'method', 'name', 'waitTime'];

// This is way how we can build waitTime and it's breakdown
WaitTimeBuilder = function() {
  this._waitListStore = {};
  this._currentProcessingMessages = {};
  this._messageCache = {};
};

WaitTimeBuilder.prototype.register = function(session, msgId) {
  var self = this;
  var mainKey = self._getMessageKey(session.id, msgId);

  var waitList =
    session.inQueue &&
    session.inQueue.map &&
    session.inQueue.map(function(msg) {
    var key = self._getMessageKey(session.id, msg.id);
    return self._getCacheMessage(key, msg);
  });

  waitList = waitList || [];

  //add currently processing ddp message if exists
  var currentlyProcessingMessage = this._currentProcessingMessages[session.id];
  if(currentlyProcessingMessage) {
    var key = self._getMessageKey(session.id, currentlyProcessingMessage.id);
    waitList.unshift(this._getCacheMessage(key, currentlyProcessingMessage));
  }

  this._waitListStore[mainKey] = waitList;
};

WaitTimeBuilder.prototype.build = function(session, msgId) {
  var mainKey = this._getMessageKey(session.id, msgId);
  var waitList = this._waitListStore[mainKey] || [];
  delete this._waitListStore[mainKey];

  var filteredWaitList =  waitList.map(this._cleanCacheMessage.bind(this));
  return filteredWaitList;
};

WaitTimeBuilder.prototype._getMessageKey = function(sessionId, msgId) {
  return sessionId + "::" + msgId;
};

WaitTimeBuilder.prototype._getCacheMessage = function(key, msg) {
  var self = this;
  var cachedMessage = self._messageCache[key];
  if(!cachedMessage) {
    self._messageCache[key] = cachedMessage = _.pick(msg, WAITON_MESSAGE_FIELDS);
    cachedMessage._key = key;
    cachedMessage._registered = 1;
  } else {
    cachedMessage._registered++;
  }

  return cachedMessage;
};

WaitTimeBuilder.prototype._cleanCacheMessage = function(msg) {
  msg._registered--;
  if(msg._registered == 0) {
    delete this._messageCache[msg._key];
  }

  // need to send a clean set of objects
  // otherwise register can go with this
  return _.pick(msg, WAITON_MESSAGE_FIELDS);
};

WaitTimeBuilder.prototype.trackWaitTime = function(session, msg, unblock) {
  var self = this;
  var started = Date.now();
  self._currentProcessingMessages[session.id] = msg;

  var unblocked = false;
  var wrappedUnblock = function() {
    if(!unblocked) {
      var waitTime = Date.now() - started;
      var key = self._getMessageKey(session.id, msg.id);
      var cachedMessage = self._messageCache[key];
      if(cachedMessage) {
        cachedMessage.waitTime = waitTime;
      }
      delete self._currentProcessingMessages[session.id];
      unblocked = true;
      unblock();
    }
  };

  return wrappedUnblock;
};<|endoftext|>


<commit_before>/*

  a bootstrap like layout
  use it with a proper stylesheet (e.g. ../stylesheets/bootstrap)

*/
'use strict';

var React = require('../util/React');
var { View, Text, TextInput, SwitchIOS, PickerIOS, DatePickerIOS } = React;
var merge = require('../util/merge');

function textbox(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var textboxStyle = stylesheet.textbox.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    textboxStyle = stylesheet.textbox.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  if (locals.editable === false) {
    textboxStyle = stylesheet.textbox.notEditable;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  return (
    <View style={formGroupStyle}>
      {label}
      <TextInput
        autoCapitalize={locals.autoCapitalize}
        autoCorrect={locals.autoCorrect}
        autoFocus={locals.autoFocus}
        bufferDelay={locals.bufferDelay}
        clearButtonMode={locals.clearButtonMode}
        editable={locals.editable}
        enablesReturnKeyAutomatically={locals.enablesReturnKeyAutomatically}
        keyboardType={locals.keyboardType}
        multiline={locals.multiline}
        onBlur={locals.onBlur}
        onEndEditing={locals.onEndEditing}
        onFocus={locals.onFocus}
        onSubmitEditing={locals.onSubmitEditing}
        password={locals.password}
        placeholderTextColor={locals.placeholderTextColor}
        returnKeyType={locals.returnKeyType}
        secureTextEntry={locals.secureTextEntry}
        selectionState={locals.selectionState}
        onChangeText={(value) => locals.onChange(value)}
        placeholder={locals.placeholder}
        style={textboxStyle}
        value={locals.value}
      />
      {help}
      {error}
    </View>
  );
}

function checkbox(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var checkboxStyle = stylesheet.checkbox.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    checkboxStyle = stylesheet.checkbox.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  return (
    <View style={formGroupStyle}>
      {label}
      <SwitchIOS
        disabled={locals.disabled}
        onTintColor={locals.onTintColor}
        thumbTintColor={locals.thumbTintColor}
        tintColor={locals.tintColor}
        style={checkboxStyle}
        onValueChange={(value) => locals.onChange(value)}
        value={locals.value}
      />
      {help}
      {error}
    </View>
  );
}

function select(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var selectStyle = stylesheet.select.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    selectStyle = stylesheet.select.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  var options = locals.options.map(({value, text}) => <PickerIOS.Item key={value} value={value} label={text} />);

  return (
    <View style={formGroupStyle}>
      {label}
      <PickerIOS
        style={selectStyle}
        selectedValue={locals.value}
        onValueChange={locals.onChange}
      >
        {options}
      </PickerIOS>
      {help}
      {error}
    </View>
  );
}

function datepicker(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var datepickerStyle = stylesheet.datepicker.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    datepickerStyle = stylesheet.datepicker.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  return (
    <View style={formGroupStyle}>
      {label}
      <DatePickerIOS
        maximumDate={locals.maximumDate}
        minimumDate={locals.minimumDate}
        minuteInterval={locals.minuteInterval}
        mode={locals.mode}
        timeZoneOffsetInMinutes={locals.timeZoneOffsetInMinutes}
        style={datepickerStyle}
        onDateChange={(value) => locals.onChange(value)}
        date={locals.value}
      />
      {help}
      {error}
    </View>
  );
}

function struct(locals) {

  var stylesheet = locals.stylesheet;
  var fieldsetStyle = stylesheet.fieldset;

  var rows = locals.order.map(function (name) {
    return locals.inputs[name];
  });

  return (
    <View style={fieldsetStyle}>
      {rows}
    </View>
  );
}

module.exports = {
  textbox,
  checkbox,
  select,
  datepicker,
  struct
};<commit_msg>endPoint ref to use blur()/focus()<commit_after>/*

  a bootstrap like layout
  use it with a proper stylesheet (e.g. ../stylesheets/bootstrap)

*/
'use strict';

var React = require('../util/React');
var { View, Text, TextInput, SwitchIOS, PickerIOS, DatePickerIOS } = React;
var merge = require('../util/merge');

function textbox(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var textboxStyle = stylesheet.textbox.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    textboxStyle = stylesheet.textbox.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  if (locals.editable === false) {
    textboxStyle = stylesheet.textbox.notEditable;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  return (
    <View style={formGroupStyle}>
      {label}
      <TextInput
        ref="endPoint"
        autoCapitalize={locals.autoCapitalize}
        autoCorrect={locals.autoCorrect}
        autoFocus={locals.autoFocus}
        bufferDelay={locals.bufferDelay}
        clearButtonMode={locals.clearButtonMode}
        editable={locals.editable}
        enablesReturnKeyAutomatically={locals.enablesReturnKeyAutomatically}
        keyboardType={locals.keyboardType}
        multiline={locals.multiline}
        onBlur={locals.onBlur}
        onEndEditing={locals.onEndEditing}
        onFocus={locals.onFocus}
        onSubmitEditing={locals.onSubmitEditing}
        password={locals.password}
        placeholderTextColor={locals.placeholderTextColor}
        returnKeyType={locals.returnKeyType}
        secureTextEntry={locals.secureTextEntry}
        selectionState={locals.selectionState}
        onChangeText={(value) => locals.onChange(value)}
        placeholder={locals.placeholder}
        style={textboxStyle}
        value={locals.value}
      />
      {help}
      {error}
    </View>
  );
}

function checkbox(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var checkboxStyle = stylesheet.checkbox.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    checkboxStyle = stylesheet.checkbox.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  return (
    <View style={formGroupStyle}>
      {label}
      <SwitchIOS
        ref="endPoint"
        disabled={locals.disabled}
        onTintColor={locals.onTintColor}
        thumbTintColor={locals.thumbTintColor}
        tintColor={locals.tintColor}
        style={checkboxStyle}
        onValueChange={(value) => locals.onChange(value)}
        value={locals.value}
      />
      {help}
      {error}
    </View>
  );
}

function select(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var selectStyle = stylesheet.select.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    selectStyle = stylesheet.select.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  var options = locals.options.map(({value, text}) => <PickerIOS.Item key={value} value={value} label={text} />);

  return (
    <View style={formGroupStyle}>
      {label}
      <PickerIOS
        ref="endPoint"
        style={selectStyle}
        selectedValue={locals.value}
        onValueChange={locals.onChange}
      >
        {options}
      </PickerIOS>
      {help}
      {error}
    </View>
  );
}

function datepicker(locals) {

  var stylesheet = locals.stylesheet;
  var formGroupStyle = stylesheet.formGroup.normal;
  var controlLabelStyle = stylesheet.controlLabel.normal;
  var datepickerStyle = stylesheet.datepicker.normal;
  var helpBlockStyle = stylesheet.helpBlock.normal;
  var errorBlockStyle = stylesheet.errorBlock;

  if (locals.hasError) {
    formGroupStyle = stylesheet.formGroup.error;
    controlLabelStyle = stylesheet.controlLabel.error;
    datepickerStyle = stylesheet.datepicker.error;
    helpBlockStyle = stylesheet.helpBlock.error;
  }

  var label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null;
  var help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null;
  var error = locals.hasError && locals.error ? <Text style={errorBlockStyle}>{locals.error}</Text> : null;

  return (
    <View style={formGroupStyle}>
      {label}
      <DatePickerIOS
        ref="endPoint"
        maximumDate={locals.maximumDate}
        minimumDate={locals.minimumDate}
        minuteInterval={locals.minuteInterval}
        mode={locals.mode}
        timeZoneOffsetInMinutes={locals.timeZoneOffsetInMinutes}
        style={datepickerStyle}
        onDateChange={(value) => locals.onChange(value)}
        date={locals.value}
      />
      {help}
      {error}
    </View>
  );
}

function struct(locals) {

  var stylesheet = locals.stylesheet;
  var fieldsetStyle = stylesheet.fieldset;

  var rows = locals.order.map(function (name) {
    return locals.inputs[name];
  });

  return (
    <View style={fieldsetStyle}>
      {rows}
    </View>
  );
}

module.exports = {
  textbox,
  checkbox,
  select,
  datepicker,
  struct
};<|endoftext|>


<commit_before>var wd = require('wd')

function formatError (err) {
  return err.message + '\n' + (err.data ? '  ' + err.data : '')
}

function processConfig (helper, config, args) {
  config = config || {}
  args = args || {}

  var apiKey = args.apiKey || config.apiKey || process.env.TB_KEY
  var apiSecret = args.apiSecret || config.apiSecret || process.env.TB_SECRET
  var startConnect = config.startConnect !== false

  var browserName = args.browserName +
        (args.version ? ' ' + args.version : '') +
        (args.platform ? ' (' + args.platform + ')' : '')

  var connectOptions = helper.merge(config.connectOptions, {
    apiKey: apiKey,
    apiSecret: apiSecret,
    'se-port': 4445
  })

  var build = process.env.TRAVIS_BUILD_NUMBER ||
        process.env.BUILD_NUMBER ||
        process.env.BUILD_TAG ||
        process.env.CIRCLE_BUILD_NUM

  var defaults = {
    version: '',
    platform: 'ANY',
    tags: [],
    name: 'Karma Test',
    'screenrecorder': false,
    'screenshots': false,
    'device-orientation': null,
    'disable-popup-handler': true,
    build: build || null,
    public: null,
    customData: {}
  }

  var options = helper.merge(
    // Legacy
    config.options,
    defaults, {
      // Pull out all the properties from the config that
      // we are interested in
      name: config.testName,
      build: config.build,
      'screenrecorder': config.recordVideo,
      'screenshots': config.recordScreenshots,
      public: config.public,
      customData: config.customData
    }, {
      // Need to rename some properties from args
      name: args.testName,
      'screenrecorder': args.recordVideo,
      'screenshots': args.recordScreenshots
    }, args
  )

  return {
    options: options,
    connectOptions: connectOptions,
    browserName: browserName,
    apiKey: apiKey,
    apiSecret: apiSecret,
    startConnect: startConnect
  }
}

var TBLauncher = function (
  args, testingbotTunnel,
  /* config.testingbot */ config,
  logger, helper,
  baseLauncherDecorator, captureTimeoutLauncherDecorator, retryLauncherDecorator,
  /* testingbot:jobMapping */ jobMapping
) {
  var self = this

  baseLauncherDecorator(self)
  captureTimeoutLauncherDecorator(self)
  retryLauncherDecorator(self)

  var pConfig = processConfig(helper, config, args)
  var options = pConfig.options
  var connectOptions = pConfig.connectOptions
  var browserName = pConfig.browserName
  var apiKey = pConfig.apiKey
  var apiSecret = pConfig.apiSecret
  var startConnect = pConfig.startConnect

  var pendingCancellations = 0
  var sessionIsReady = false

  self.name = browserName + ' on TestingBot'

  var pendingHeartBeat

  var log = logger.create('launcher.testingbot')
  var driverLog = logger.create('wd')

  var driver = wd.promiseChainRemote('127.0.0.1', connectOptions['se-port'], apiKey, apiSecret)

  driver.on('status', function (info) {
    driverLog.debug(info.cyan)
  })

  driver.on('command', function (eventType, command, response) {
    driverLog.debug(' > ' + eventType.cyan, command, (response || '').grey)
  })

  driver.on('http', function (meth, path, data) {
    driverLog.debug(' > ' + meth.magenta, path, (data || '').grey)
  })

  var heartbeat = function () {
    pendingHeartBeat = setTimeout(function () {
      log.debug('Heartbeat to TestingBot (%s) - fetching title', browserName)

      driver.title()
        .then(null, function (err) {
          log.error('Heartbeat to %s failed\n  %s', browserName, formatError(err))

          clearTimeout(pendingHeartBeat)
          return self._done('failure')
        })

      heartbeat()
    }, 60000)
  }

  var start = function (url) {
    driver
      .init(options)
      .then(function () {
        if (pendingCancellations > 0) {
          pendingCancellations--
          return
        }
        // Record the job details, so we can access it later with the reporter
        jobMapping[self.id] = {
          jobId: driver.sessionID,
          credentials: {
            api_key: apiKey,
            api_secret: apiSecret
          }
        }

        sessionIsReady = true

        log.info('%s session at https://testingbot.com/tests/%s', browserName, driver.sessionID)
        log.debug('WebDriver channel for %s instantiated, opening %s', browserName, url)

        return driver.get(url)
          .then(heartbeat, function (err) {
            log.error('Can not start %s\n  %s', browserName, formatError(err))
            return self._done('failure')
          })
      }, function (err) {
        if (pendingCancellations > 0) {
          pendingCancellations--
          return
        }

        log.error('Can not start %s\n  %s', browserName, formatError(err))
        return self._done('failure')
      })
      .done()
  }

  self.on('start', function (url) {
    if (pendingCancellations > 0) {
      pendingCancellations--
      return
    }

    if (startConnect) {
      testingbotTunnel.start(connectOptions)
        .then(function () {
          if (pendingCancellations > 0) {
            pendingCancellations--
            return
          }

          start(url)
        }, function (err) {
          pendingCancellations--
          log.error('Can not start %s\n  Failed to start TestingBot Tunnel:\n  %s', browserName, err.message)

          self._retryLimit = -1 // don't retry
          self._done('failure')
        })
    } else {
      start(url)
    }
  })

  self.on('kill', function (done) {
    var allDone = function () {
      self._done()
      done()
    }

    if (sessionIsReady) {
      if (pendingHeartBeat) {
        clearTimeout(pendingHeartBeat)
      }

      log.debug('Shutting down the %s driver', browserName)
      driver.quit().nodeify(allDone)
      sessionIsReady = false
    } else {
      pendingCancellations++
      process.nextTick(allDone)
    }
  })
}

module.exports = TBLauncher<commit_msg>adding more env options for drone as well as general CI systems<commit_after>var wd = require('wd')

function formatError (err) {
  return err.message + '\n' + (err.data ? '  ' + err.data : '')
}

function processConfig (helper, config, args) {
  config = config || {}
  args = args || {}

  var apiKey = args.apiKey || config.apiKey || process.env.TB_KEY
  var apiSecret = args.apiSecret || config.apiSecret || process.env.TB_SECRET
  var startConnect = config.startConnect !== false

  var browserName = args.browserName +
        (args.version ? ' ' + args.version : '') +
        (args.platform ? ' (' + args.platform + ')' : '')

  var connectOptions = helper.merge(config.connectOptions, {
    apiKey: apiKey,
    apiSecret: apiSecret,
    'se-port': 4445
  })

  var build = process.env.BUILD_NUMBER ||
        process.env.BUILD_TAG ||
        process.env.CI_BUILD_NUMBER ||
        process.env.CI_BUILD_TAG ||
        process.env.TRAVIS_BUILD_NUMBER ||
        process.env.CIRCLE_BUILD_NUM ||
        process.env.DRONE_BUILD_NUMBER

  var defaults = {
    version: '',
    platform: 'ANY',
    tags: [],
    name: 'Karma Test',
    'screenrecorder': false,
    'screenshots': false,
    'device-orientation': null,
    'disable-popup-handler': true,
    build: build || null,
    public: null,
    customData: {}
  }

  var options = helper.merge(
    // Legacy
    config.options,
    defaults, {
      // Pull out all the properties from the config that
      // we are interested in
      name: config.testName,
      build: config.build,
      'screenrecorder': config.recordVideo,
      'screenshots': config.recordScreenshots,
      public: config.public,
      customData: config.customData
    }, {
      // Need to rename some properties from args
      name: args.testName,
      'screenrecorder': args.recordVideo,
      'screenshots': args.recordScreenshots
    }, args
  )

  return {
    options: options,
    connectOptions: connectOptions,
    browserName: browserName,
    apiKey: apiKey,
    apiSecret: apiSecret,
    startConnect: startConnect
  }
}

var TBLauncher = function (
  args, testingbotTunnel,
  /* config.testingbot */ config,
  logger, helper,
  baseLauncherDecorator, captureTimeoutLauncherDecorator, retryLauncherDecorator,
  /* testingbot:jobMapping */ jobMapping
) {
  var self = this

  baseLauncherDecorator(self)
  captureTimeoutLauncherDecorator(self)
  retryLauncherDecorator(self)

  var pConfig = processConfig(helper, config, args)
  var options = pConfig.options
  var connectOptions = pConfig.connectOptions
  var browserName = pConfig.browserName
  var apiKey = pConfig.apiKey
  var apiSecret = pConfig.apiSecret
  var startConnect = pConfig.startConnect

  var pendingCancellations = 0
  var sessionIsReady = false

  self.name = browserName + ' on TestingBot'

  var pendingHeartBeat

  var log = logger.create('launcher.testingbot')
  var driverLog = logger.create('wd')

  var driver = wd.promiseChainRemote('127.0.0.1', connectOptions['se-port'], apiKey, apiSecret)

  driver.on('status', function (info) {
    driverLog.debug(info.cyan)
  })

  driver.on('command', function (eventType, command, response) {
    driverLog.debug(' > ' + eventType.cyan, command, (response || '').grey)
  })

  driver.on('http', function (meth, path, data) {
    driverLog.debug(' > ' + meth.magenta, path, (data || '').grey)
  })

  var heartbeat = function () {
    pendingHeartBeat = setTimeout(function () {
      log.debug('Heartbeat to TestingBot (%s) - fetching title', browserName)

      driver.title()
        .then(null, function (err) {
          log.error('Heartbeat to %s failed\n  %s', browserName, formatError(err))

          clearTimeout(pendingHeartBeat)
          return self._done('failure')
        })

      heartbeat()
    }, 60000)
  }

  var start = function (url) {
    driver
      .init(options)
      .then(function () {
        if (pendingCancellations > 0) {
          pendingCancellations--
          return
        }
        // Record the job details, so we can access it later with the reporter
        jobMapping[self.id] = {
          jobId: driver.sessionID,
          credentials: {
            api_key: apiKey,
            api_secret: apiSecret
          }
        }

        sessionIsReady = true

        log.info('%s session at https://testingbot.com/tests/%s', browserName, driver.sessionID)
        log.debug('WebDriver channel for %s instantiated, opening %s', browserName, url)

        return driver.get(url)
          .then(heartbeat, function (err) {
            log.error('Can not start %s\n  %s', browserName, formatError(err))
            return self._done('failure')
          })
      }, function (err) {
        if (pendingCancellations > 0) {
          pendingCancellations--
          return
        }

        log.error('Can not start %s\n  %s', browserName, formatError(err))
        return self._done('failure')
      })
      .done()
  }

  self.on('start', function (url) {
    if (pendingCancellations > 0) {
      pendingCancellations--
      return
    }

    if (startConnect) {
      testingbotTunnel.start(connectOptions)
        .then(function () {
          if (pendingCancellations > 0) {
            pendingCancellations--
            return
          }

          start(url)
        }, function (err) {
          pendingCancellations--
          log.error('Can not start %s\n  Failed to start TestingBot Tunnel:\n  %s', browserName, err.message)

          self._retryLimit = -1 // don't retry
          self._done('failure')
        })
    } else {
      start(url)
    }
  })

  self.on('kill', function (done) {
    var allDone = function () {
      self._done()
      done()
    }

    if (sessionIsReady) {
      if (pendingHeartBeat) {
        clearTimeout(pendingHeartBeat)
      }

      log.debug('Shutting down the %s driver', browserName)
      driver.quit().nodeify(allDone)
      sessionIsReady = false
    } else {
      pendingCancellations++
      process.nextTick(allDone)
    }
  })
}

module.exports = TBLauncher
<|endoftext|>


<commit_before>'use strict';

const path = require("path");
const fs = require("fs");

const mkdirp = require("mkdirp");
const async = require("async");
const npm = require("npm");

const installerConfig = require(path.normalize(process.env.PWD + "/../etc/config.js"));
const serviceModule = require("./service");
const mongoModule = require("./mongo");

//set the logger
const logger = require("../utils/utils.js").getLogger();

const SOAJS_RMS = {
	'gateway': "soajs.controller",
	'urac': 'soajs.urac',
	'oauth': 'soajs.oauth',
	'dashboard': 'soajs.dashboard',
	'ui': 'soajs.dashboard.ui'
};

function updateConfigFile(workingDirectory, cb) {
	installerConfig.workingDirectory = workingDirectory;
	let newData = "'use strict';\n\n";
	newData += "module.exports = " + JSON.stringify(installerConfig, null, 2) + ";\n";
	fs.writeFile(path.normalize(process.env.PWD + "/../etc/config.js"), newData, cb);
}

function installConsoleComponents(cb) {
	let myPath = installerConfig.workingDirectory + "/node_modules/";
	fs.stat(myPath, (error, stats) => {
		if (error) {
			if (error.code === 'ENOENT' && !stats) {
				//if not found create the directories needed recursively
				mkdirp(myPath, runNPM);
			}
			else {
				return cb(error);
			}
		}
		else {
			runNPM();
		}
	});

	//install repos in component
	function runNPM() {
		logger.debug("\nInstalling SOAJS Console Components ...");
		process.argv = [installerConfig.workingDirectory];
		npm.load({prefix: installerConfig.workingDirectory}, (err) => {
			if (err) {
				return cb(err);
			}

			async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {

				logger.debug(`Installing ${oneService} from NPM ${oneRepo} ...`);
				npm.commands.install([oneRepo], (error) => {
					if (error) {
						return mCb(error);
					}

					logger.debug(`${oneService} installed!`);
					setTimeout(() => {
						return mCb(null, true);
					}, 500);
				});
			}, (error) => {
				if (error) {
					return cb(error);
				}

				return cb(null, true);
			});
		});
	}
}

const consoleModule = {

	/**
	 * This function configures and starts mongodb server stand alone
	 * then it patches the provisioned data in mongdb server
	 * then it installs all of SOAJS Console components
	 * then it starts all the SOAJS Console components
	 * @param args
	 * @param callback
	 */
	'install': (args, callback) => {
		if (args.length === 0) {
			return callback("Please provide where you want to install the SOAJS Console. Ex: soajs console install %folder_path%");
		}

		//clean up the path ...
		if (args[0].includes("node_modules")) {
			let myPath = args[0].split(path.sep);
			if (myPath[myPath.length - 1] === 'node_modules') {
				myPath.pop();
				myPath = myPath.join(path.sep);
				args[0] = myPath;
			}
		}

		logger.debug(`Checking provided path: ${args[0]} ...`);
		fs.stat(args[0], (error, stats) => {
			if (error) {
				if (error.code === 'ENOENT' && !stats) {
					//create the working directory
					mkdirp(path.normalize(args[0] + "/node_modules/"), (error) => {
						if (error) {
							return callback("Unable to work in provided folder path (might be permissions): " + args[0]);
						}
						updateConfiguration();
					});
				}
				else {
					return callback(error);
				}
			}
			else {
				updateConfiguration();
			}
		});

		function updateConfiguration() {
			logger.debug(`Configuring installer ...`);

			//update the configuration file
			installerConfig.workingDirectory = args[0];
			updateConfigFile(args[0], (error) => {
				if (error) {
					return callback("Unable to update Installer configuration file, please try again!");
				}

				//install and start mongo
				launchMongo();
			});
		}

		function launchMongo() {
			logger.debug(`Configuring MongoDB Server ...`);
			mongoModule.install([], (error, response) => {
				if (error) {
					return callback(error);
				}

				logger.debug(response);
				setTimeout(() => {
					logger.debug(`Starting MongoDB Server ...`);
					mongoModule.start([], (error, response) => {
						if (error) {
							return callback(error);
						}

						logger.debug(response);
						setTimeout(() => {

							logger.debug(`Importing Data in MongoDB Server ...`);
							mongoModule.patch([], (error, response) => {
								if (error) {
									return callback(error);
								}

								logger.debug(response);
								installSOAJSConsole();
							});
						}, 1000);
					});
				}, 100);
			});
		}

		function installSOAJSConsole() {
			logger.debug(`Installing SOAJS Console ...`);
			//install all repository content
			installConsoleComponents((error) => {
				if (error) {
					return callback("Error while isntalling the SOAJS Console files!")
				}

				//start microservices
				consoleModule.start(args, (error) => {
					if (error) {
						return callback("Unable to Start the SOAJS Console!");
					}

					return callback(null, "SOAJS Console Started!");
				});
			});
		}
	},

	/**
	 * This function will stop all the services of SOAJS Console
	 * it will then run npm install in the working directory to update all the microservices repos related
	 * then it will start the services of SOAJS Console again
	 * @param args
	 * @param callback
	 */
	'update': (args, callback) => {
		logger.info("Updating SOAJS Console ...\n\n");
		setTimeout(() => {
			//stop microservices
			consoleModule.stop(args, (error) => {
				if (error) {
					return callback("Unable to Stop the SOAJS Console!");
				}

				//update all repository content
				installConsoleComponents((error) => {
					if (error) {
						return callback("Error while updating the SOAJS Console files!")
					}

					//start microservices
					consoleModule.start(args, (error) => {
						if (error) {
							return callback("Unable to Restart the SOAJS Console!");
						}

						return callback(null, "SOAJS Console Updated!");
					});
				});
			});
		}, 2000);
	},

	/**
	 * This function will stop all services of SOAJS Console
	 * it will also stop mongodb and clean up all SOAJS data from the database
	 * Then it will remove all the installed files and folders of SOAJS Console (PURGE Everything)
	 * @param args
	 * @param callback
	 */
	'remove': (args, callback) => {
		logger.info("Removing SOAJS Console ...\n\n");
		setTimeout(() => {
			//stop microservices
			consoleModule.stop(args, (error) => {
				if (error) {
					return callback("Unable to Stop the SOAJS Console!");
				}

				const mongoModule = require("./mongo.js");
				logger.info("Cleaning up Mongo and stopping it ...");
				setTimeout(() => {
					//remove data from mongodb
					mongoModule.clean([], (error) => {
						if (error) {
							return callback("Error while Cleaning provisioned data from mongo!");
						}
						//stop mongodb
						mongoModule.stop([], (error) => {
							if (error) {
								return callback("Error while Stopping MongoDB Server!");
							}

							logger.info("Cleaning up downloaded SOAJS Console ...");
							setTimeout(() => {
								//remove folders of microservices
								async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {
									logger.debug(`Removing ${oneService} files ...`);
									logger.debug(path.normalize(installerConfig.workingDirectory + "/node_modules/" + SOAJS_RMS[oneService]) + "\n");
									fs.rmdir(path.normalize(installerConfig.workingDirectory + "/node_modules/" + SOAJS_RMS[oneService]), (error) => {
										if (error) {
											return mCb(error);
										}
										logger.debug(`${oneService} --> ${oneRepo}: Removed!`);
										return mCb();
									});
								}, (error) => {
									if (error) {
										return callback("Error Cleaning up SOAJS Console ...");
									}

									//remove working directory
									fs.rmdir(path.normalize(installerConfig.workingDirectory, () => {

										//clean up the configuration file
										updateConfigFile('', (error) => {
											logger.info("=========================\nSOAJS Console Removed!\n=========================\n\n");
											setTimeout(() => {
												return callback();
											}, 1000);
										});
									}));
								});

							}, 2000);
						});
					});
				}, 2000);
			});

		}, 2000);
	},

	/**
	 * This function restarts all the services of the SOAJS Console
	 * @param args
	 * @param callback
	 */
	'restart': (args, callback) => {
		logger.info("Restarting SOAJS Console ...\n\n");
		setTimeout(() => {
			consoleModule.stop(args, (error) => {
				if (error) {
					return callback("Unable to Stop the SOAJS Console!");
				}

				consoleModule.start(args, (error) => {
					if (error) {
						return callback("Unable to Restart the SOAJS Console!");
					}

					return callback(null, "SOAJS Console Restarted!");
				});
			});
		}, 2000);
	},

	/**
	 * This command will calculate the needed env variables and
	 * start all the microservices in dashboard environment that the soajs console requires
	 * @param args {Array}
	 * @param callback {Function}
	 */
	'start': (args, callback) => {
		let requestedEnvironment = 'dashboard';

		//check if service is installed and downloaded
		if (!installerConfig.workingDirectory || installerConfig.workingDirectory === '') {
			return callback(`SOAJS Console is not installed!`);
		}

		logger.debug("Checking MongoDB Server ....");
		mongoModule.start([], (error, response) => {
			if (error) {
				return callback(error);
			}

			logger.info("Starting Microservices for SOAJS Console in Dashboard Environment ... \n");
			setTimeout(() => {
				async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {
					launchMyService(oneService, (error, response) => {
						if (error) {
							return mCb(error);
						}

						if (response && response !== '') {
							logger.debug(response + "\n");
						}
						return mCb(null, true);
					});
				}, (error) => {
					if (error) {
						return callback("Error starting the SOAJS Console");
					}

					logger.info("=========================\nSOAJS Console started!\n=========================\n\n");
					setTimeout(() => {
						return callback();
					}, 1000);
				});
			}, 1000);
		});

		function launchMyService(oneService, mCb) {
			serviceModule.start([oneService, "--env=" + requestedEnvironment], mCb)
		}
	},

	/**
	 * This command will find the process id of all microservices that the soajs console is using and kill them
	 * @param args
	 * @param callback
	 * @returns {*}
	 */
	'stop': (args, callback) => {
		let requestedEnvironment = 'dashboard';

		//check if service is installed and downloaded
		if (!installerConfig.workingDirectory || installerConfig.workingDirectory === '') {
			return callback(`SOAJS Console is not installed!`);
		}

		logger.info("Stopping Microservices for SOAJS Console in Dashboard Environment ... \n");
		setTimeout(() => {
			async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {
				launchMyService(oneService, (error, response) => {
					if (error) {
						return mCb(error);
					}

					if (response && response !== '') {
						logger.debug(response + "\n");
					}

					return mCb(null, true);
				});
			}, (error) => {
				if (error) {
					return callback("Error stop the SOAJS Console");
				}

				logger.info("=========================\nSOAJS Console Stopped!\n=========================\n\n");
				setTimeout(() => {
					return callback();
				}, 1000);
			});

		}, 1000);

		function launchMyService(oneService, mCb) {
			serviceModule.stop([oneService, "--env=" + requestedEnvironment], mCb)
		}
	}
};

module.exports = consoleModule;<commit_msg>tested and completed soajs console remove.<commit_after>'use strict';

const path = require("path");
const fs = require("fs");

const mkdirp = require("mkdirp");
const async = require("async");
const npm = require("npm");
const rimraf = require("rimraf");

const installerConfig = require(path.normalize(process.env.PWD + "/../etc/config.js"));
const serviceModule = require("./service");
const mongoModule = require("./mongo");

//set the logger
const logger = require("../utils/utils.js").getLogger();

const SOAJS_RMS = {
	'gateway': "soajs.controller",
	'urac': 'soajs.urac',
	'oauth': 'soajs.oauth',
	'dashboard': 'soajs.dashboard',
	'ui': 'soajs.dashboard.ui'
};

function updateConfigFile(workingDirectory, cb) {
	installerConfig.workingDirectory = workingDirectory;
	let newData = "'use strict';\n\n";
	newData += "module.exports = " + JSON.stringify(installerConfig, null, 2) + ";\n";
	fs.writeFile(path.normalize(process.env.PWD + "/../etc/config.js"), newData, cb);
}

function installConsoleComponents(cb) {
	let myPath = installerConfig.workingDirectory + "/node_modules/";
	fs.stat(myPath, (error, stats) => {
		if (error) {
			if (error.code === 'ENOENT' && !stats) {
				//if not found create the directories needed recursively
				mkdirp(myPath, runNPM);
			}
			else {
				return cb(error);
			}
		}
		else {
			runNPM();
		}
	});

	//install repos in component
	function runNPM() {
		logger.debug("\nInstalling SOAJS Console Components ...");
		process.argv = [installerConfig.workingDirectory];
		npm.load({prefix: installerConfig.workingDirectory}, (err) => {
			if (err) {
				return cb(err);
			}

			async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {

				logger.debug(`Installing ${oneService} from NPM ${oneRepo} ...`);
				npm.commands.install([oneRepo], (error) => {
					if (error) {
						return mCb(error);
					}

					logger.debug(`${oneService} installed!`);
					setTimeout(() => {
						return mCb(null, true);
					}, 500);
				});
			}, (error) => {
				if (error) {
					return cb(error);
				}

				return cb(null, true);
			});
		});
	}
}

const consoleModule = {

	/**
	 * This function configures and starts mongodb server stand alone
	 * then it patches the provisioned data in mongdb server
	 * then it installs all of SOAJS Console components
	 * then it starts all the SOAJS Console components
	 * @param args
	 * @param callback
	 */
	'install': (args, callback) => {
		if (args.length === 0) {
			return callback("Please provide where you want to install the SOAJS Console. Ex: soajs console install %folder_path%");
		}

		//clean up the path ...
		if (args[0].includes("node_modules")) {
			let myPath = args[0].split(path.sep);
			if (myPath[myPath.length - 1] === 'node_modules') {
				myPath.pop();
				myPath = myPath.join(path.sep);
				args[0] = myPath;
			}
		}

		logger.debug(`Checking provided path: ${args[0]} ...`);
		fs.stat(args[0], (error, stats) => {
			if (error) {
				if (error.code === 'ENOENT' && !stats) {
					//create the working directory
					mkdirp(path.normalize(args[0] + "/node_modules/"), (error) => {
						if (error) {
							return callback("Unable to work in provided folder path (might be permissions): " + args[0]);
						}
						updateConfiguration();
					});
				}
				else {
					return callback(error);
				}
			}
			else {
				updateConfiguration();
			}
		});

		function updateConfiguration() {
			logger.debug(`Configuring installer ...`);

			//update the configuration file
			installerConfig.workingDirectory = args[0];
			updateConfigFile(args[0], (error) => {
				if (error) {
					return callback("Unable to update Installer configuration file, please try again!");
				}

				//install and start mongo
				launchMongo();
			});
		}

		function launchMongo() {
			logger.debug(`Configuring MongoDB Server ...`);
			mongoModule.install([], (error, response) => {
				if (error) {
					return callback(error);
				}

				logger.debug(response);
				setTimeout(() => {
					logger.debug(`Starting MongoDB Server ...`);
					mongoModule.start([], (error, response) => {
						if (error) {
							return callback(error);
						}

						logger.debug(response);
						setTimeout(() => {

							logger.debug(`Importing Data in MongoDB Server ...`);
							mongoModule.patch([], (error, response) => {
								if (error) {
									return callback(error);
								}

								logger.debug(response);
								installSOAJSConsole();
							});
						}, 1000);
					});
				}, 100);
			});
		}

		function installSOAJSConsole() {
			logger.debug(`Installing SOAJS Console ...`);
			//install all repository content
			installConsoleComponents((error) => {
				if (error) {
					return callback("Error while isntalling the SOAJS Console files!")
				}

				//start microservices
				consoleModule.start(args, (error) => {
					if (error) {
						return callback("Unable to Start the SOAJS Console!");
					}

					return callback(null, "SOAJS Console Started!");
				});
			});
		}
	},

	/**
	 * This function will stop all the services of SOAJS Console
	 * it will then run npm install in the working directory to update all the microservices repos related
	 * then it will start the services of SOAJS Console again
	 * @param args
	 * @param callback
	 */
	'update': (args, callback) => {
		logger.info("Updating SOAJS Console ...\n\n");
		setTimeout(() => {
			//stop microservices
			consoleModule.stop(args, (error) => {
				if (error) {
					return callback("Unable to Stop the SOAJS Console!");
				}

				//update all repository content
				installConsoleComponents((error) => {
					if (error) {
						return callback("Error while updating the SOAJS Console files!")
					}

					//start microservices
					consoleModule.start(args, (error) => {
						if (error) {
							return callback("Unable to Restart the SOAJS Console!");
						}

						return callback(null, "SOAJS Console Updated!");
					});
				});
			});
		}, 2000);
	},

	/**
	 * This function will stop all services of SOAJS Console
	 * it will also stop mongodb and clean up all SOAJS data from the database
	 * Then it will remove all the installed files and folders of SOAJS Console (PURGE Everything)
	 * @param args
	 * @param callback
	 */
	'remove': (args, callback) => {
		logger.info("Removing SOAJS Console ...\n\n");
		setTimeout(() => {
			//stop microservices
			consoleModule.stop(args, (error) => {
				if (error) {
					return callback("Unable to Stop the SOAJS Console!");
				}

				const mongoModule = require("./mongo.js");
				logger.info("Cleaning up Mongo and stopping it ...");
				setTimeout(() => {
					//remove data from mongodb
					mongoModule.clean([], (error) => {
						if (error && !error.message.includes("failed to connect to server")) {
							return callback("Error while Cleaning provisioned data from mongo!");
						}
						//stop mongodb
						mongoModule.stop([], (error) => {
							if (error) {
								return callback("Error while Stopping MongoDB Server!");
							}

							logger.info("Cleaning up downloaded SOAJS Console ...");
							setTimeout(() => {
								//remove folders of microservices
								async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {
									logger.debug(`Removing ${oneService} files ...`);
									logger.debug(path.normalize(installerConfig.workingDirectory + "/node_modules/" + SOAJS_RMS[oneService]) + "\n");
									rimraf(path.normalize(installerConfig.workingDirectory + "/node_modules/" + SOAJS_RMS[oneService]), (error) => {
										if (error) {
											return mCb(error);
										}
										logger.debug(`${oneService} --> ${oneRepo}: Removed!`);
										return mCb();
									});
								}, (error) => {
									if (error) {
										return callback("Error Cleaning up SOAJS Console ...");
									}

									//remove working directory
									rimraf(path.normalize(installerConfig.workingDirectory), () => {

										//clean up the configuration file
										updateConfigFile('', (error) => {
											logger.info("=========================\nSOAJS Console Removed!\n=========================\n\n");
											setTimeout(() => {
												return callback();
											}, 1000);
										});
									});
								});

							}, 2000);
						});
					});
				}, 2000);
			});

		}, 2000);
	},

	/**
	 * This function restarts all the services of the SOAJS Console
	 * @param args
	 * @param callback
	 */
	'restart': (args, callback) => {
		logger.info("Restarting SOAJS Console ...\n\n");
		setTimeout(() => {
			consoleModule.stop(args, (error) => {
				if (error) {
					return callback("Unable to Stop the SOAJS Console!");
				}

				consoleModule.start(args, (error) => {
					if (error) {
						return callback("Unable to Restart the SOAJS Console!");
					}

					return callback(null, "SOAJS Console Restarted!");
				});
			});
		}, 2000);
	},

	/**
	 * This command will calculate the needed env variables and
	 * start all the microservices in dashboard environment that the soajs console requires
	 * @param args {Array}
	 * @param callback {Function}
	 */
	'start': (args, callback) => {
		let requestedEnvironment = 'dashboard';

		//check if service is installed and downloaded
		if (!installerConfig.workingDirectory || installerConfig.workingDirectory === '') {
			return callback(`SOAJS Console is not installed!`);
		}

		logger.debug("Checking MongoDB Server ....");
		mongoModule.start([], (error, response) => {
			if (error) {
				return callback(error);
			}

			logger.info("Starting Microservices for SOAJS Console in Dashboard Environment ... \n");
			setTimeout(() => {
				async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {
					launchMyService(oneService, (error, response) => {
						if (error) {
							return mCb(error);
						}

						if (response && response !== '') {
							logger.debug(response + "\n");
						}
						return mCb(null, true);
					});
				}, (error) => {
					if (error) {
						return callback("Error starting the SOAJS Console");
					}

					logger.info("=========================\nSOAJS Console started!\n=========================\n\n");
					setTimeout(() => {
						return callback();
					}, 1000);
				});
			}, 1000);
		});

		function launchMyService(oneService, mCb) {
			serviceModule.start([oneService, "--env=" + requestedEnvironment], mCb)
		}
	},

	/**
	 * This command will find the process id of all microservices that the soajs console is using and kill them
	 * @param args
	 * @param callback
	 * @returns {*}
	 */
	'stop': (args, callback) => {
		let requestedEnvironment = 'dashboard';

		//check if service is installed and downloaded
		if (!installerConfig.workingDirectory || installerConfig.workingDirectory === '') {
			return callback(`SOAJS Console is not installed!`);
		}

		logger.info("Stopping Microservices for SOAJS Console in Dashboard Environment ... \n");
		setTimeout(() => {
			async.eachOfSeries(SOAJS_RMS, (oneRepo, oneService, mCb) => {
				launchMyService(oneService, (error, response) => {
					if (error) {
						return mCb(error);
					}

					if (response && response !== '') {
						logger.debug(response + "\n");
					}

					return mCb(null, true);
				});
			}, (error) => {
				if (error) {
					return callback("Error stop the SOAJS Console");
				}

				logger.info("=========================\nSOAJS Console Stopped!\n=========================\n\n");
				setTimeout(() => {
					return callback();
				}, 1000);
			});

		}, 1000);

		function launchMyService(oneService, mCb) {
			serviceModule.stop([oneService, "--env=" + requestedEnvironment], mCb)
		}
	}
};

module.exports = consoleModule;<|endoftext|>


<commit_before>/*
---

script: MooEditable.Table.js

description: Extends MooEditable to insert table with manipulation options.

license: MIT-style license

authors:
- Radovan Lozej

requires:
- /MooEditable
- /MooEditable.UI
- /MooEditable.Actions

usage:
	Add the following tags in your html
	<link rel="stylesheet" href="MooEditable.css">
	<link rel="stylesheet" href="MooEditable.Table.css">
	<script src="mootools.js"></script>
	<script src="MooEditable.js"></script>
	<script src="MooEditable.Table.js"></script>

	<script>
	window.addEvent('domready', function(){
		var mooeditable = $('textarea-1').mooEditable({
			actions: 'bold italic underline strikethrough | table | toggleview'
		});
	});
	</script>

...
*/

MooEditable.UI.TableDialog = function(editor, dialog){
	var html = {
		tableadd: 'columns <input type="text" class="table-c" value="" size="4" /> '
			+ 'rows <input type="text" class="table-r" value="" size="4" /> ',
		tableedit: 'width <input type="text" class="table-w" value="" size="4" /> '
			+ 'class <input type="text" class="table-c" value="" size="15" /> ',
		tablerowedit: 'class <input type="text" class="table-c" value="" size="15" /> ',
		tablecoledit: 'width <input type="text" class="table-w" value="" size="4" /> '
			+ 'class <input type="text" class="table-c" value="" size="15" /> '
			+ 'align <select class="table-a"><option>none</option><option>left</option><option>center</option><option>right</option></select> '
			+ 'valign <select class="table-va"><option>none</option><option>top</option><option>middle</option><option>bottom</option></select> '
	};
	html[dialog] += '<button class="dialog-button dialog-ok-button">OK</button>'
		+ '<button class="dialog-button dialog-cancel-button">Cancel</button>';

	var action = {
		tableadd: {
			click: function(e){
				var col = this.el.getElement('.table-c').value.toInt();
				var row = this.el.getElement('.table-r').value.toInt();
				if (!(row>0 && col>0)) return;
				var div, table, tbody, ro = [];
				div = new Element('tdiv');
				table = new Element('table').set('border', 0).set('width', '100%').inject(div);
				tbody = new Element('tbody').inject(table);
				for (var r = 0;r<row;r++){
					ro[r] = new Element('tr').inject(tbody, 'bottom');
					for (var c=0; c<col; c++) new Element('td').set('html', ' ').inject(ro[r], 'bottom');
				}
				editor.selection.insertContent(div.get('html'));
			}
		},
		tableedit: {
			load: function(e){
				var node = editor.selection.getNode().getParent('table');
				this.el.getElement('.table-w').set('value', node.get('width'));
				this.el.getElement('.table-c').set('value', node.className);
			},
			click: function(e){
				var node = editor.selection.getNode().getParent('table');
				node.set('width', this.el.getElement('.table-w').value);
				node.className = this.el.getElement('.table-c').value;
			}
		},
		tablerowedit: {
			load: function(e){
				var node = editor.selection.getNode().getParent('tr');
				this.el.getElement('.table-c').set('value', node.className);
			},
			click: function(e){
				var node = editor.selection.getNode().getParent('tr');
				node.className = this.el.getElement('.table-c').value;
			}
		},
		tablecoledit: {
			load : function(e){
				var node = editor.selection.getNode();
				if (node.get('tag') != 'td') node = node.getParent('td');
				this.el.getElement('.table-w').set('value', node.get('width'));
				this.el.getElement('.table-c').set('value', node.className);
				this.el.getElement('.table-a').set('value', node.get('align'));
				this.el.getElement('.table-va').set('value', node.get('valign'));
			},
			click: function(e){
				var node = editor.selection.getNode();
				if (node.get('tag') != 'td') node = node.getParent('td');
				node.set('width', this.el.getElement('.table-w').value);
				node.className = this.el.getElement('.table-c').value;
				node.set('align', this.el.getElement('.table-a').value);
				node.set('valign', this.el.getElement('.table-va').value);
			}
		}
	};

	return new MooEditable.UI.Dialog(html[dialog], {
		'class': 'mooeditable-prompt-dialog',
		onOpen: function(){
			if (action[dialog].load) action[dialog].load.apply(this);
			var input = this.el.getElement('input');
			(function(){ input.focus(); }).delay(10);
		},
		onClick: function(e){
			if (e.target.tagName.toLowerCase() == 'button') e.preventDefault();
			var button = document.id(e.target);
			if (button.hasClass('dialog-cancel-button')){
				this.close();
			} else if (button.hasClass('dialog-ok-button')){
				this.close();
				action[dialog].click.apply(this);
			}
		}
	});
};

MooEditable.Actions.extend({

	tableadd:{
		title: 'Add Table',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tableadd');
			}
		},
		command: function(){
			this.dialogs.tableadd.prompt.open();
		}
	},

	tableedit:{
		title: 'Edit Table',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tableedit');
			}
		},
		command: function(){
			if (this.selection.getNode().getParent('table')) this.dialogs.tableedit.prompt.open();
		}
	},

	tablerowadd:{
		title: 'Add Row',
		command: function(){
			var node = this.selection.getNode().getParent('tr');
			if (node) node.clone().inject(node, 'after');
		}
	},

	tablerowedit:{
		title: 'Edit Row',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tablerowedit');
			}
		},
		command: function(){
			if (this.selection.getNode().getParent('table')) this.dialogs.tablerowedit.prompt.open();
		}
	},

	tablerowspan:{
		title: 'Merge Row',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag') != 'td') node = node.getParent('td');
			if (node){
				var index = node.cellIndex;
				var row = node.getParent().rowIndex;
				if (node.getParent().getParent().childNodes[row+node.rowSpan]){
					node.getParent().getParent().childNodes[row+node.rowSpan].deleteCell(index);
					node.rowSpan++;
				}
			}
		}
	},

	tablerowdelete:{
		title: 'Delete Row',
		command: function(){
			var node = this.selection.getNode().getParent('tr');
			if (node) node.getParent().deleteRow(node.rowIndex);
		}
	},

	tablecoladd:{
		title: 'Add Column',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag') != 'td') node = node.getParent('td');
			if (node){
				var index = node.cellIndex;
				var len = node.getParent().getParent().childNodes.length;
				for (var i=0; i<len; i++){
					var ref = $(node.getParent().getParent().childNodes[i].childNodes[index]);
					ref.clone().inject(ref, 'after');
				}
			}
		}
	},

	tablecoledit:{
		title: 'Edit Column',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tablecoledit');
			}
		},
		command: function(){
			if (this.selection.getNode().getParent('table')) this.dialogs.tablecoledit.prompt.open();
		}
	},

	tablecolspan:{
		title: 'Merge Cell',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag')!='td') node = node.getParent('td');
			if (node){
				var index = node.cellIndex + 1;
				if (node.getParent().childNodes[index]){
					node.getParent().deleteCell(index);
					node.colSpan++;
				}
			}
		}
	},

	tablecoldelete:{
		title: 'Delete Column',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag') != 'td') node = node.getParent('td');
			if (node){
				var len = node.getParent().getParent().childNodes.length;
				var index = node.cellIndex;
				var tt = node.getParent().getParent();
				for (var i=0; i<len; i++) tt.childNodes[i].deleteCell(index);
			}
		}
	}

});
<commit_msg>Add th/td selection to row edit dialog<commit_after>/*
---

script: MooEditable.Table.js

description: Extends MooEditable to insert table with manipulation options.

license: MIT-style license

authors:
- Radovan Lozej

requires:
- /MooEditable
- /MooEditable.UI
- /MooEditable.Actions

usage:
	Add the following tags in your html
	<link rel="stylesheet" href="MooEditable.css">
	<link rel="stylesheet" href="MooEditable.Table.css">
	<script src="mootools.js"></script>
	<script src="MooEditable.js"></script>
	<script src="MooEditable.Table.js"></script>

	<script>
	window.addEvent('domready', function(){
		var mooeditable = $('textarea-1').mooEditable({
			actions: 'bold italic underline strikethrough | table | toggleview'
		});
	});
	</script>

...
*/

MooEditable.UI.TableDialog = function(editor, dialog){
	var html = {
		tableadd: 'columns <input type="text" class="table-c" value="" size="4" /> '
			+ 'rows <input type="text" class="table-r" value="" size="4" /> ',
		tableedit: 'width <input type="text" class="table-w" value="" size="4" /> '
			+ 'class <input type="text" class="table-c" value="" size="15" /> ',
		tablerowedit: 'class <input type="text" class="table-c" value="" size="15" /> type <select class="table-c-type"><option value="th">Header</option><option value="td">Cell</option></select> ',
		tablecoledit: 'width <input type="text" class="table-w" value="" size="4" /> '
			+ 'class <input type="text" class="table-c" value="" size="15" /> '
			+ 'align <select class="table-a"><option>none</option><option>left</option><option>center</option><option>right</option></select> '
			+ 'valign <select class="table-va"><option>none</option><option>top</option><option>middle</option><option>bottom</option></select> '
	};
	html[dialog] += '<button class="dialog-button dialog-ok-button">OK</button>'
		+ '<button class="dialog-button dialog-cancel-button">Cancel</button>';

	var action = {
		tableadd: {
			click: function(e){
				var col = this.el.getElement('.table-c').value.toInt();
				var row = this.el.getElement('.table-r').value.toInt();
				if (!(row>0 && col>0)) return;
				var div, table, tbody, ro = [];
				div = new Element('tdiv');
				table = new Element('table').set('border', 0).set('width', '100%').inject(div);
				tbody = new Element('tbody').inject(table);
				for (var r = 0;r<row;r++){
					ro[r] = new Element('tr').inject(tbody, 'bottom');
					for (var c=0; c<col; c++) new Element('td').set('html', ' ').inject(ro[r], 'bottom');
				}
				editor.selection.insertContent(div.get('html'));
			}
		},
		tableedit: {
			load: function(e){
				var node = editor.selection.getNode().getParent('table');
				this.el.getElement('.table-w').set('value', node.get('width'));
				this.el.getElement('.table-c').set('value', node.className);
			},
			click: function(e){
				var node = editor.selection.getNode().getParent('table');
				node.set('width', this.el.getElement('.table-w').value);
				node.className = this.el.getElement('.table-c').value;
			}
		},
		tablerowedit: {
			load: function(e){
				var node = editor.selection.getNode().getParent('tr');
				this.el.getElement('.table-c').set('value', node.className);
				this.el.getElement('.table-c-type').set('value', editor.selection.getNode().get('tag'));
			},
			click: function(e){
				var node = editor.selection.getNode().getParent('tr');
				node.className = this.el.getElement('.table-c').value;
				node.getElements('td,th').each(function(c){
					if (this.el.getElement('.table-c-type') != c.get('tag')){
						var n = editor.doc.createElement(this.el.getElement('.table-c-type').get('value'));
						$(n).set('html',c.get('html')).replaces(c);
					}
				},this);
			}
		},
		tablecoledit: {
			load : function(e){
				var node = editor.selection.getNode();
				if (node.get('tag') != 'td') node = node.getParent('td');
				this.el.getElement('.table-w').set('value', node.get('width'));
				this.el.getElement('.table-c').set('value', node.className);
				this.el.getElement('.table-a').set('value', node.get('align'));
				this.el.getElement('.table-va').set('value', node.get('valign'));
			},
			click: function(e){
				var node = editor.selection.getNode();
				if (node.get('tag') != 'td') node = node.getParent('td');
				node.set('width', this.el.getElement('.table-w').value);
				node.className = this.el.getElement('.table-c').value;
				node.set('align', this.el.getElement('.table-a').value);
				node.set('valign', this.el.getElement('.table-va').value);
			}
		}
	};

	return new MooEditable.UI.Dialog(html[dialog], {
		'class': 'mooeditable-prompt-dialog',
		onOpen: function(){
			if (action[dialog].load) action[dialog].load.apply(this);
			var input = this.el.getElement('input');
			(function(){ input.focus(); }).delay(10);
		},
		onClick: function(e){
			if (e.target.tagName.toLowerCase() == 'button') e.preventDefault();
			var button = document.id(e.target);
			if (button.hasClass('dialog-cancel-button')){
				this.close();
			} else if (button.hasClass('dialog-ok-button')){
				this.close();
				action[dialog].click.apply(this);
			}
		}
	});
};

MooEditable.Actions.extend({

	tableadd:{
		title: 'Add Table',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tableadd');
			}
		},
		command: function(){
			this.dialogs.tableadd.prompt.open();
		}
	},

	tableedit:{
		title: 'Edit Table',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tableedit');
			}
		},
		command: function(){
			if (this.selection.getNode().getParent('table')) this.dialogs.tableedit.prompt.open();
		}
	},

	tablerowadd:{
		title: 'Add Row',
		command: function(){
			var node = this.selection.getNode().getParent('tr');
			if (node) node.clone().inject(node, 'after');
		}
	},

	tablerowedit:{
		title: 'Edit Row',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tablerowedit');
			}
		},
		command: function(){
			if (this.selection.getNode().getParent('table')) this.dialogs.tablerowedit.prompt.open();
		}
	},

	tablerowspan:{
		title: 'Merge Row',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag') != 'td') node = node.getParent('td');
			if (node){
				var index = node.cellIndex;
				var row = node.getParent().rowIndex;
				if (node.getParent().getParent().childNodes[row+node.rowSpan]){
					node.getParent().getParent().childNodes[row+node.rowSpan].deleteCell(index);
					node.rowSpan++;
				}
			}
		}
	},

	tablerowdelete:{
		title: 'Delete Row',
		command: function(){
			var node = this.selection.getNode().getParent('tr');
			if (node) node.getParent().deleteRow(node.rowIndex);
		}
	},

	tablecoladd:{
		title: 'Add Column',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag') != 'td') node = node.getParent('td');
			if (node){
				var index = node.cellIndex;
				var len = node.getParent().getParent().childNodes.length;
				for (var i=0; i<len; i++){
					var ref = $(node.getParent().getParent().childNodes[i].childNodes[index]);
					ref.clone().inject(ref, 'after');
				}
			}
		}
	},

	tablecoledit:{
		title: 'Edit Column',
		dialogs: {
			prompt: function(editor){
				return MooEditable.UI.TableDialog(editor, 'tablecoledit');
			}
		},
		command: function(){
			if (this.selection.getNode().getParent('table')) this.dialogs.tablecoledit.prompt.open();
		}
	},

	tablecolspan:{
		title: 'Merge Cell',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag')!='td') node = node.getParent('td');
			if (node){
				var index = node.cellIndex + 1;
				if (node.getParent().childNodes[index]){
					node.getParent().deleteCell(index);
					node.colSpan++;
				}
			}
		}
	},

	tablecoldelete:{
		title: 'Delete Column',
		command: function(){
			var node = this.selection.getNode();
			if (node.get('tag') != 'td') node = node.getParent('td');
			if (node){
				var len = node.getParent().getParent().childNodes.length;
				var index = node.cellIndex;
				var tt = node.getParent().getParent();
				for (var i=0; i<len; i++) tt.childNodes[i].deleteCell(index);
			}
		}
	}

});
<|endoftext|>


<commit_before>exports.beforeTests = function(configuration, callback) {
  var Proxy = require('../../lib/proxy');

  // Create a new proxy and start it
  var proxy = new Proxy({
    p: 51000, u: 'mongodb://localhost:31000/test', b: '127.0.0.1', debug:true
  });

  // Start the proxy
  proxy.start(callback);
}

exports['Should correctly connect to proxy'] = {
  metadata: { requires: { } },

  // The actual test we wish to run
  test: function(configuration, test) {
    var MongoClient = require('mongodb').MongoClient;

    // Url for connection to proxy
    var url = 'mongodb://localhost:51000/test';

    // Connect to mongodb
    MongoClient.connect(url, function(err, db) {
      test.equal(null, err);

      // Perform an inserts
      db.collection('t').insert([{a:1}, {b:1}, {c:1}, {d:1}], function(err, r) {
        test.equal(null, err);

        db.collection('t').find({}).batchSize(2).toArray(function(err, docs) {
          test.equal(null, err);
          console.dir(docs)

          db.close();
          test.done();
        });
      });
    });
  }
}<commit_msg>Added concurrent cursor tests<commit_after>exports.beforeTests = function(configuration, callback) {
  var Proxy = require('../../lib/proxy')
    , MongoClient = require('mongodb').MongoClient;

  // URI
  var mongodburi = "mongodb://localhost:31000/test";
  // Create a new proxy and start it
  var proxy = new Proxy({
    p: 51000, u: mongodburi, b: '127.0.0.1', debug:true
  });

  MongoClient.connect(mongodburi, function(err, db) {
    db.dropDatabase(function() {
      // Start the proxy
      proxy.start(callback);
    });
  });
}

exports['Should correctly connect to proxy'] = {
  metadata: { requires: { } },

  // The actual test we wish to run
  test: function(configuration, test) {
    var MongoClient = require('mongodb').MongoClient;

    // Url for connection to proxy
    var url = 'mongodb://localhost:51000/test';

    // Connect to mongodb
    MongoClient.connect(url, function(err, db) {
      test.equal(null, err);

      // Perform an inserts
      db.collection('t').insert([{a:1}, {b:1}, {c:1}, {d:1}], function(err, r) {
        test.equal(null, err);

        db.collection('t').find({}).batchSize(2).toArray(function(err, docs) {
          test.equal(null, err);

          db.close();
          test.done();
        });
      });
    });
  }
}

exports['Concurrent cursors'] = {
  metadata: { requires: { } },

  // The actual test we wish to run
  test: function(configuration, test) {
    var MongoClient = require('mongodb').MongoClient;

    // Url for connection to proxy
    var url = 'mongodb://localhost:51000/test';

    // Connect to mongodb
    MongoClient.connect(url, function(err, db) {
      test.equal(null, err);

      // Perform an inserts
      db.collection('t2').insert([{a:1}, {b:1}, {c:1}, {d:1}], function(err, r) {
        test.equal(null, err);

        var total = 10;
        var numberLeft = total;

        for(var i = 0; i < total; i++) {
          db.collection('t2').find({}).batchSize(2).toArray(function(err, docs) {
            test.equal(null, err);
            numberLeft = numberLeft - 1;

            if(numberLeft == 0) {
              db.close();
              test.done();
            }
          });
        }
      });
    });
  }
}<|endoftext|>