<commit_before>'use strict';

var formula = function($mdDialog, $location, $routeParams, npdcAppConfig, npolarDocumentUtil, NpolarTranslate) {
  'ngInject';

  return {
    template: require('./edit.html'),
    scope: false,
    controller: function($scope) {
      'ngInject';

      let initBottomSheet = function() {
        $scope.bottomSheetOptions = {
          items: [],
          alwaysShow: false
        };
        if ($scope.security.isAuthorized('delete', $scope.resource.path) && $scope.document._rev) {
          $scope.bottomSheetOptions.items.push({
            name: NpolarTranslate.translate('Delete'),
            icon: 'delete',
            classes: 'md-warn',
            action: function(ev) {
              // Appending dialog to document.body to cover sidenav in docs app
              var confirm = $mdDialog.confirm()
                .title(NpolarTranslate.translate('Delete'))
                .textContent(NpolarTranslate.translate('delete.confirm'))
                .targetEvent(ev)
                .ok(NpolarTranslate.translate('Delete'))
                .cancel(NpolarTranslate.translate('Cancel'));
              $mdDialog.show(confirm).then(function() {
                $scope.delete();
              }, function() {
                // noop
              });
            }
          });
        }
      };

      $scope.$on('npolar-lang', (e, lang) => {
        $scope.formula.i18n.set(lang.lang);
      });

      $scope.formula.setConfirmDirtyNavigate((navigate) => {
        let confirmNavigate = $mdDialog.confirm()
          .title(NpolarTranslate.translate('navigation.confirm.title'))
          .textContent(NpolarTranslate.translate('navigation.confirm.text'))
          .ok(NpolarTranslate.translate('Yes'))
          .cancel(NpolarTranslate.translate('No'));
        $mdDialog.show(confirmNavigate).then(function() {
          navigate();
        });
      });

      $scope.title = "";
      $scope.id = $routeParams.id;

      $scope.href = function (id) {
        return $scope.resource ? $scope.resource.href(id) : id;
      };

      $scope.$watch('document', (newVal, oldVal) => {
        if (newVal) {
          $scope.title = newVal._rev ? npolarDocumentUtil.title(newVal) :
            NpolarTranslate.translate('document.new');
          initBottomSheet();
        }
      });
    }
  };
};

module.exports = formula;
<commit_msg>Disable confirmNavigation<commit_after>'use strict';

var formula = function($mdDialog, $location, $routeParams, npdcAppConfig, npolarDocumentUtil, NpolarTranslate) {
  'ngInject';

  return {
    template: require('./edit.html'),
    scope: false,
    controller: function($scope) {
      'ngInject';

      let initBottomSheet = function() {
        $scope.bottomSheetOptions = {
          items: [],
          alwaysShow: false
        };
        if ($scope.security.isAuthorized('delete', $scope.resource.path) && $scope.document._rev) {
          $scope.bottomSheetOptions.items.push({
            name: NpolarTranslate.translate('Delete'),
            icon: 'delete',
            classes: 'md-warn',
            action: function(ev) {
              // Appending dialog to document.body to cover sidenav in docs app
              var confirm = $mdDialog.confirm()
                .title(NpolarTranslate.translate('Delete'))
                .textContent(NpolarTranslate.translate('delete.confirm'))
                .targetEvent(ev)
                .ok(NpolarTranslate.translate('Delete'))
                .cancel(NpolarTranslate.translate('Cancel'));
              $mdDialog.show(confirm).then(function() {
                $scope.delete();
              }, function() {
                // noop
              });
            }
          });
        }
      };

      $scope.$on('npolar-lang', (e, lang) => {
        $scope.formula.i18n.set(lang.lang);
      });

      // @FIXME Sometimes goes bananas and spams dialogs...
      // $scope.formula.setConfirmDirtyNavigate((navigate) => {
      //   let confirmNavigate = $mdDialog.confirm()
      //     .title(NpolarTranslate.translate('navigation.confirm.title'))
      //     .textContent(NpolarTranslate.translate('navigation.confirm.text'))
      //     .ok(NpolarTranslate.translate('Yes'))
      //     .cancel(NpolarTranslate.translate('No'));
      //   $mdDialog.show(confirmNavigate).then(function() {
      //     navigate();
      //   });
      // });

      $scope.title = "";
      $scope.id = $routeParams.id;

      $scope.href = function (id) {
        return $scope.resource ? $scope.resource.href(id) : id;
      };

      $scope.$watch('document', (newVal, oldVal) => {
        if (newVal) {
          $scope.title = newVal._rev ? npolarDocumentUtil.title(newVal) :
            NpolarTranslate.translate('document.new');
          initBottomSheet();
        }
      });
    }
  };
};

module.exports = formula;
<|endoftext|>


<commit_before>var cluster   = require('cluster')
  , has       = require('./util').has
  , commands  = require('./globals').commands
  , hubs      = require('./globals').hubs
  , workers   = require('./globals').workers
  , queue     = require('./globals').queue
  , queuemsg  = require('./globals').queuemsg
  , isReady   = require('./globals').isReady
  , broadcast = require('./globals').broadcast
  , emit      = require('./globals').emit
  , Hub       = require('./hub')
  ;

/**
 * When all workers are online, this tells all hubs in the current process
 */
function ready() {
  var key, hub, listener;

  for (key in hubs) {
    if (has(hubs, key)) {
      hub = hubs[key];
      if (hub.isready) continue;
      hub.isready = true;
      while (listener = hub._onready.shift()) listener();
    }
  }
}

/**
 * Listen for events from master
 */
process.on('message', function(msg) {
  if (msg.cmd === commands.READY) {
    return ready();
  }

  // check if hub exists
  if (msg.dir !== __dirname) return;
  if (msg.hub === undefined || !has(hubs, msg.hub)) return;
  var hub = hubs[msg.hub];

  if (msg.event) {
    emit(msg.hub, msg.event, msg.args);

  } else {
    // it can be a response to another command too
    hub._cb[msg.key].apply(null, msg.args);
    delete hub._cb[msg.key];
  }
});

/**
 * Forks a worker and keeps a reference to it. Listens for any emitted
 * events so it can distribute them amongst any worker listeners.
 *
 * @return (child)
 */
var origFork = cluster.fork;
cluster.fork = function() {
  var worker = origFork();
  var events = {};
  var obj = {
    worker: worker,
    events: events,
    ready: false,
    ononline: ononline,
    onmessage: onmessage,
  };
  workers.push(obj);

  function ononline() {
    obj.ready = true;

    // check if all workers are online and ready
    if (!isReady()) return;

    // process any messages that were buffered while the hub
    // was not ready
    var msg;
    while (msg = queue.shift()) msg.fn(msg.msg);

    // tell all workers hub is ready
    workers.forEach(function(child) {
      child.worker.send({ cmd: commands.READY });
    });

    ready();
  }

  function onmessage(msg) {
    if (msg.hub === undefined || msg.cmd === undefined) return;
    if (msg.dir !== __dirname) return;
    if (!has(hubs, msg.hub)) {
      new Hub(msg.hub);
    }

    switch (msg.cmd) {
      // if this is an emitted event, distribute it amongst all workers
      // who are listening for the event. Except the one who sent it
      case commands.EVENT:
        queuemsg(onevent, msg);
        break;

      // if it's on/off, add/remove counters to know if this worker should
      // get notified of any events or not
      case commands.ON:
        onon(msg);
        break;

      case commands.OFF:
        onoff(msg);
        break;

      case commands.OFFALL:
        onoffall(msg);
        break;

      // can be a EventVat command
      // in that case, execute it on the EventVat instance for this hub
      default:
        queuemsg(oncmd, msg);
    }
  }

  function onevent(msg) {
    broadcast(msg.hub, msg.event, msg.args, worker);
    emit(msg.hub, msg.event, msg.args);
  }

  function onon(msg) {
    if (has(events, msg.event)) {
      events[msg.event]++;
    } else {
      events[msg.event] = 1;
    }
  }

  function onoff(msg) {
    if (has(events, msg.event) && --events[msg.event] === 0) {
      delete events[msg.event];
    }
  }

  function onoffall(msg) {
    if (msg.event) {
      if (has(events, msg.event)) {
        delete events[msg.event];
      }
    } else {
      obj.events = events = {};
    }
  }

  function oncmd(msg) {
    var db = hubs[msg.hub]._db;
    var result = db[msg.cmd].apply(db, msg.args);

    // if key is given, then a callback is waiting for the result
    if (msg.key) {
      worker.send({
        dir  : __dirname
      , hub  : msg.hub
      , key  : msg.key
      , args : [result]
      });
    }
  }

  worker.on('online', ononline);
  worker.on('message', onmessage);

  return worker;
};

/**
 * Remove workers on death
 */
cluster.on('exit', function(worker) {
  workers.forEach(function(obj, i) {
    if (obj.worker === worker) {
      workers.splice(i, 1);
      worker.removeListener('online', obj.ononline);
      worker.removeListener('message', obj.onmessage);
      return false;
    }
  });
});
<commit_msg>listen to `exit` event from child process<commit_after>var cluster   = require('cluster')
  , has       = require('./util').has
  , commands  = require('./globals').commands
  , hubs      = require('./globals').hubs
  , workers   = require('./globals').workers
  , queue     = require('./globals').queue
  , queuemsg  = require('./globals').queuemsg
  , isReady   = require('./globals').isReady
  , broadcast = require('./globals').broadcast
  , emit      = require('./globals').emit
  , Hub       = require('./hub')
  ;

/**
 * When all workers are online, this tells all hubs in the current process
 */
function ready() {
  var key, hub, listener;

  for (key in hubs) {
    if (has(hubs, key)) {
      hub = hubs[key];
      if (hub.isready) continue;
      hub.isready = true;
      while (listener = hub._onready.shift()) listener();
    }
  }
}

/**
 * Listen for events from master
 */
process.on('message', function(msg) {
  if (msg.cmd === commands.READY) {
    return ready();
  }

  // check if hub exists
  if (msg.dir !== __dirname) return;
  if (msg.hub === undefined || !has(hubs, msg.hub)) return;
  var hub = hubs[msg.hub];

  if (msg.event) {
    emit(msg.hub, msg.event, msg.args);

  } else {
    // it can be a response to another command too
    hub._cb[msg.key].apply(null, msg.args);
    delete hub._cb[msg.key];
  }
});

/**
 * Forks a worker and keeps a reference to it. Listens for any emitted
 * events so it can distribute them amongst any worker listeners.
 *
 * @return (child)
 */
var origFork = cluster.fork;
cluster.fork = function() {
  var worker = origFork();
  var events = {};
  var obj = {
    worker: worker,
    events: events,
    ready: false,
    ononline: ononline,
    onmessage: onmessage,
  };
  workers.push(obj);

  function ononline() {
    obj.ready = true;

    // check if all workers are online and ready
    if (!isReady()) return;

    // process any messages that were buffered while the hub
    // was not ready
    var msg;
    while (msg = queue.shift()) msg.fn(msg.msg);

    // tell all workers hub is ready
    workers.forEach(function(child) {
      child.worker.send({ cmd: commands.READY });
    });

    ready();
  }

  function onmessage(msg) {
    if (msg.hub === undefined || msg.cmd === undefined) return;
    if (msg.dir !== __dirname) return;
    if (!has(hubs, msg.hub)) {
      new Hub(msg.hub);
    }

    switch (msg.cmd) {
      // if this is an emitted event, distribute it amongst all workers
      // who are listening for the event. Except the one who sent it
      case commands.EVENT:
        queuemsg(onevent, msg);
        break;

      // if it's on/off, add/remove counters to know if this worker should
      // get notified of any events or not
      case commands.ON:
        onon(msg);
        break;

      case commands.OFF:
        onoff(msg);
        break;

      case commands.OFFALL:
        onoffall(msg);
        break;

      // can be a EventVat command
      // in that case, execute it on the EventVat instance for this hub
      default:
        queuemsg(oncmd, msg);
    }
  }

  function onevent(msg) {
    broadcast(msg.hub, msg.event, msg.args, worker);
    emit(msg.hub, msg.event, msg.args);
  }

  function onon(msg) {
    if (has(events, msg.event)) {
      events[msg.event]++;
    } else {
      events[msg.event] = 1;
    }
  }

  function onoff(msg) {
    if (has(events, msg.event) && --events[msg.event] === 0) {
      delete events[msg.event];
    }
  }

  function onoffall(msg) {
    if (msg.event) {
      if (has(events, msg.event)) {
        delete events[msg.event];
      }
    } else {
      obj.events = events = {};
    }
  }

  function oncmd(msg) {
    var db = hubs[msg.hub]._db;
    var result = db[msg.cmd].apply(db, msg.args);

    // if key is given, then a callback is waiting for the result
    if (msg.key) {
      worker.send({
        dir  : __dirname
      , hub  : msg.hub
      , key  : msg.key
      , args : [result]
      });
    }
  }

  worker.on('online', ononline);
  worker.on('message', onmessage);
  worker.once('exit', function onexit() {
    workers.splice(workers.indexOf(obj), 1);
    worker.removeListener('online', obj.ononline);
    worker.removeListener('message', obj.onmessage);
    return false;
  });

  return worker;
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { COLORS } from '../../utils/constants';
import BaseView from '../../utils/rnw-compat/BaseView';

const propTypes = {
  children: PropTypes.node.isRequired,
  color: PropTypes.oneOf(COLORS),
  disabled: PropTypes.bool,
};

const ListGroupItem = React.forwardRef((props, ref) => {
  const { color = null, disabled = false, ...elementProps } = props;

  const classes = cx(
    // constant classes
    'list-group-item',
    // variable classes
    color && `list-group-item-${color}`,
    disabled && 'disabled',
  );

  return (
    <BaseView
      {...elementProps}
      ref={ref}
      accessibilityRole="listitem"
      essentials={{ className: classes }}
    />
  );
});

ListGroupItem.displayName = 'ListGroupItem';
ListGroupItem.propTypes = propTypes;

export default ListGroupItem;
<commit_msg>Add active prop to ListGroupItem<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { COLORS } from '../../utils/constants';
import BaseView from '../../utils/rnw-compat/BaseView';

const propTypes = {
  children: PropTypes.node.isRequired,
  color: PropTypes.oneOf(COLORS),
  active: PropTypes.bool,
  disabled: PropTypes.bool,
};

const ListGroupItem = React.forwardRef((props, ref) => {
  const {
    color = null,
    active = false,
    disabled = false,
    ...elementProps
  } = props;

  const classes = cx(
    // constant classes
    'list-group-item',
    // variable classes
    color && `list-group-item-${color}`,
    active && 'active',
    disabled && 'disabled',
  );

  return (
    <BaseView
      {...elementProps}
      ref={ref}
      accessibilityRole="listitem"
      essentials={{ className: classes }}
    />
  );
});

ListGroupItem.displayName = 'ListGroupItem';
ListGroupItem.propTypes = propTypes;

export default ListGroupItem;
<|endoftext|>


<commit_before>'use strict';
var childProcess = require('child_process');
var path = require('path');
var fs = require('fs');
var objectAssign = require('object-assign');
var Promise = require('bluebird');
var debug = require('debug')('ava');
var AvaError = require('./ava-error');
var doSend = require('./send');

if (fs.realpathSync(__filename) !== __filename) {
	console.warn(
		'WARNING: `npm link ava` and the `--preserve-symlink` flag are incompatible. ' +
		'We have detected that AVA is linked via `npm link`, and that your are using either using ether ' +
		'an early version of Node 6, or the `--preserve-symlink` flag. This breaks AVA. ' +
		'You should upgrade to Node 6.2.0+, avoid the `--preserve-symlink` flag, or avoid using `npm link ava`.'
	);
}

var env = process.env;

// ensure NODE_PATH paths are absolute
if (env.NODE_PATH) {
	env = objectAssign({}, env);

	env.NODE_PATH = env.NODE_PATH
		.split(path.delimiter)
		.map(function (x) {
			return path.resolve(x);
		})
		.join(path.delimiter);
}

module.exports = function (file, opts) {
	opts = objectAssign({
		file: file,
		baseDir: process.cwd(),
		tty: process.stdout.isTTY ? {
			columns: process.stdout.columns,
			rows: process.stdout.rows
		} : false
	}, opts);

	var ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), [JSON.stringify(opts)], {
		cwd: path.dirname(file),
		silent: true,
		env: env
	});

	var relFile = path.relative('.', file);

	var exiting = false;
	var send = function (ps, name, data) {
		if (!exiting) {
			// This seems to trigger a Node bug which kills the AVA master process, at
			// least while running AVA's tests. See
			// <https://github.com/novemberborn/_ava-tap-crash> for more details.
			doSend(ps, name, data);
		}
	};

	var testResults = [];
	var results;

	var promise = new Promise(function (resolve, reject) {
		ps.on('error', reject);

		// emit `test` and `stats` events
		ps.on('message', function (event) {
			if (!event.ava) {
				return;
			}

			event.name = event.name.replace(/^ava\-/, '');
			event.data.file = relFile;

			debug('ipc %s:\n%o', event.name, event.data);

			ps.emit(event.name, event.data);
		});

		ps.on('test', function (props) {
			testResults.push(props);
		});

		ps.on('results', function (data) {
			results = data;
			data.tests = testResults;
			send(ps, 'teardown');
		});

		ps.on('exit', function (code, signal) {
			if (code > 0) {
				return reject(new AvaError(relFile + ' exited with a non-zero exit code: ' + code));
			}

			if (code === null && signal) {
				return reject(new AvaError(relFile + ' exited due to ' + signal));
			}

			if (results) {
				resolve(results);
			} else {
				reject(new AvaError('Test results were not received from ' + relFile));
			}
		});

		ps.on('no-tests', function (data) {
			send(ps, 'teardown');

			var message = 'No tests found in ' + relFile;

			if (!data.avaRequired) {
				message += ', make sure to import "ava" at the top of your test file';
			}

			reject(new AvaError(message));
		});
	});

	// teardown finished, now exit
	ps.on('teardown', function () {
		send(ps, 'exit');
		exiting = true;
	});

	// uncaught exception in fork, need to exit
	ps.on('uncaughtException', function () {
		send(ps, 'teardown');
	});

	ps.stdout.on('data', function (data) {
		ps.emit('stdout', data);
	});

	ps.stderr.on('data', function (data) {
		ps.emit('stderr', data);
	});

	promise.on = function () {
		ps.on.apply(ps, arguments);

		return promise;
	};

	promise.send = function (name, data) {
		send(ps, name, data);

		return promise;
	};

	promise.exit = function () {
		send(ps, 'init-exit');

		return promise;
	};

	// send 'run' event only when fork is listening for it
	var isReady = false;

	ps.on('stats', function () {
		isReady = true;
	});

	promise.run = function (options) {
		if (isReady) {
			send(ps, 'run', options);
			return promise;
		}

		ps.on('stats', function () {
			send(ps, 'run', options);
		});

		return promise;
	};

	return promise;
};
<commit_msg>fix warning message<commit_after>'use strict';
var childProcess = require('child_process');
var path = require('path');
var fs = require('fs');
var objectAssign = require('object-assign');
var Promise = require('bluebird');
var debug = require('debug')('ava');
var AvaError = require('./ava-error');
var doSend = require('./send');

if (fs.realpathSync(__filename) !== __filename) {
	console.warn(
		'WARNING: `npm link ava` and the `--preserve-symlink` flag are incompatible. ' +
		'We have detected that AVA is linked via `npm link`, and that you are using either ' +
		'an early version of Node 6, or the `--preserve-symlink` flag. This breaks AVA. ' +
		'You should upgrade to Node 6.2.0+, avoid the `--preserve-symlink` flag, or avoid using `npm link ava`.'
	);
}

var env = process.env;

// ensure NODE_PATH paths are absolute
if (env.NODE_PATH) {
	env = objectAssign({}, env);

	env.NODE_PATH = env.NODE_PATH
		.split(path.delimiter)
		.map(function (x) {
			return path.resolve(x);
		})
		.join(path.delimiter);
}

module.exports = function (file, opts) {
	opts = objectAssign({
		file: file,
		baseDir: process.cwd(),
		tty: process.stdout.isTTY ? {
			columns: process.stdout.columns,
			rows: process.stdout.rows
		} : false
	}, opts);

	var ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), [JSON.stringify(opts)], {
		cwd: path.dirname(file),
		silent: true,
		env: env
	});

	var relFile = path.relative('.', file);

	var exiting = false;
	var send = function (ps, name, data) {
		if (!exiting) {
			// This seems to trigger a Node bug which kills the AVA master process, at
			// least while running AVA's tests. See
			// <https://github.com/novemberborn/_ava-tap-crash> for more details.
			doSend(ps, name, data);
		}
	};

	var testResults = [];
	var results;

	var promise = new Promise(function (resolve, reject) {
		ps.on('error', reject);

		// emit `test` and `stats` events
		ps.on('message', function (event) {
			if (!event.ava) {
				return;
			}

			event.name = event.name.replace(/^ava\-/, '');
			event.data.file = relFile;

			debug('ipc %s:\n%o', event.name, event.data);

			ps.emit(event.name, event.data);
		});

		ps.on('test', function (props) {
			testResults.push(props);
		});

		ps.on('results', function (data) {
			results = data;
			data.tests = testResults;
			send(ps, 'teardown');
		});

		ps.on('exit', function (code, signal) {
			if (code > 0) {
				return reject(new AvaError(relFile + ' exited with a non-zero exit code: ' + code));
			}

			if (code === null && signal) {
				return reject(new AvaError(relFile + ' exited due to ' + signal));
			}

			if (results) {
				resolve(results);
			} else {
				reject(new AvaError('Test results were not received from ' + relFile));
			}
		});

		ps.on('no-tests', function (data) {
			send(ps, 'teardown');

			var message = 'No tests found in ' + relFile;

			if (!data.avaRequired) {
				message += ', make sure to import "ava" at the top of your test file';
			}

			reject(new AvaError(message));
		});
	});

	// teardown finished, now exit
	ps.on('teardown', function () {
		send(ps, 'exit');
		exiting = true;
	});

	// uncaught exception in fork, need to exit
	ps.on('uncaughtException', function () {
		send(ps, 'teardown');
	});

	ps.stdout.on('data', function (data) {
		ps.emit('stdout', data);
	});

	ps.stderr.on('data', function (data) {
		ps.emit('stderr', data);
	});

	promise.on = function () {
		ps.on.apply(ps, arguments);

		return promise;
	};

	promise.send = function (name, data) {
		send(ps, name, data);

		return promise;
	};

	promise.exit = function () {
		send(ps, 'init-exit');

		return promise;
	};

	// send 'run' event only when fork is listening for it
	var isReady = false;

	ps.on('stats', function () {
		isReady = true;
	});

	promise.run = function (options) {
		if (isReady) {
			send(ps, 'run', options);
			return promise;
		}

		ps.on('stats', function () {
			send(ps, 'run', options);
		});

		return promise;
	};

	return promise;
};
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react'
import { connect } from 'react-redux'

import ReactDOM from 'react-dom'
import Icon from 'react-fa'

import SpaceList from 'gComponents/spaces/list'
import * as spaceActions from 'gModules/spaces/actions'
import * as organizationActions from 'gModules/organizations/actions'
import * as userOrganizationMembershipActions from 'gModules/userOrganizationMemberships/actions'
import { organizationSpaceSelector } from './organizationSpaceSelector'
import { organizationMemberSelector } from './organizationMemberSelector'
import { httpRequestSelector } from './httpRequestSelector'
import SpaceCards from 'gComponents/spaces/cards'
import Container from 'gComponents/utility/container/Container'
import e from 'gEngine/engine'

import * as modalActions from 'gModules/modal/actions'

import './style.css'

function mapStateToProps(state) {
  return {
    me: state.me,
    organizations: state.organizations,
  }
}

@connect(mapStateToProps)
@connect(organizationSpaceSelector)
@connect(organizationMemberSelector)
@connect(httpRequestSelector)
export default class OrganizationShow extends Component{
  displayName: 'OrganizationShow'

  state = {
    attemptedFetch: false,
    openTab: 'MODELS',
    subMembersTab: 'INDEX'
  }

  componentWillMount() {
    this.fetchData()
  }

  componentDidUpdate() {
    this.fetchData()
  }

  fetchData() {
    if (!this.state.attemptedFetch) {
      this.props.dispatch(organizationActions.fetchById(this.props.organizationId))
      this.props.dispatch(spaceActions.fetch({organizationId: this.props.organizationId}))
      this.setState({attemptedFetch: true})
    }
  }

  changeTab(tab) {
    this.setState({
      openTab: tab,
      subMembersTab: 'INDEX'
    })
  }

  destroyMembership(membershipId) {
    this.props.dispatch(userOrganizationMembershipActions.destroy(membershipId))
  }

  addUser(email) {
    this.props.dispatch(userOrganizationMembershipActions.createWithEmail(this.props.organizationId, email))
  }

  onRemove(member) {
    this.confirmRemove(member)
  }

  confirmRemove({email, name, membershipId}) {
    const removeCallback = () => {
      this.destroyMembership(membershipId)
      this.props.dispatch(modalActions.close())
    }

    const message = `Are you sure you want to remove ${name} from this organization?`

    this.props.dispatch(modalActions.openConfirmation({onConfirm: removeCallback, message}))
  }

  render () {
    const {organizationId, organizations, members, memberships, invitations} = this.props
    const unjoinedInvitees = invitations.filter(i => !_.some(memberships, m => m.invitation_id === i.id))
    const {openTab} = this.state
    const spaces =  _.orderBy(this.props.organizationSpaces.asMutable(), ['updated_at'], ['desc'])
    const organization = organizations.find(u => u.id.toString() === organizationId.toString())
    const meIsAdmin = !!organization && (organization.admin_id === this.props.me.id)
    const meIsMember = meIsAdmin || !!(members.find(m => m.id === this.props.me.id))

    return (
      <Container>

          <OrganizationHeader organization={organization}/>

          {meIsMember &&
            <OrganizationTabButtons
              tabs={[{name: 'Models', key: 'MODELS'}, {name: 'Members', key: 'MEMBERS'}]}
              openTab={openTab}
              changeTab={this.changeTab.bind(this)}
            />
          }

            {(openTab === 'MODELS' || !meIsMember) && spaces &&
              <SpaceCards
                spaces={spaces}
                showPrivacy={true}
              />
            }

            {(openTab === 'MEMBERS') && meIsMember && members && organization &&
              <MembersTab
                subTab={this.state.subMembersTab}
                members={members}
                invitations={unjoinedInvitees}
                admin_id={organization.admin_id}
                onRemove={this.onRemove.bind(this)}
                addUser={this.addUser.bind(this)}
                onChangeSubTab={(name) => {this.setState({subMembersTab: name})}}
                httpRequests={this.props.httpRequests}
                meIsAdmin={meIsAdmin}
              />
            }

      </Container>
    )
  }
}

const OrganizationHeader = ({organization}) => (

      {organization &&

              {organization.name}

      }

)

const OrganizationTabButtons = ({tabs, openTab, changeTab}) => (

        { tabs.map( e => {
          const className = `item ${(openTab === e.key) ? 'active' : ''}`
          return (
             {changeTab(e.key)}}> {e.name}
          )
         })}

)

const MembersTab = ({subTab, members, invitations, admin_id, onRemove, addUser, onChangeSubTab, httpRequests, meIsAdmin}) => (

    {subTab === 'ADD' &&
      <MembersAddSubTab {...{addUser, httpRequests, onChangeSubTab}}/>
    }
    {subTab === 'INDEX' &&
      <MembersIndexSubTab {...{subTab, members, invitations, admin_id, onRemove, onChangeSubTab, meIsAdmin}}/>
    }

)

const MembersIndexSubTab = ({subTab, members, invitations, admin_id, onChangeSubTab, onRemove, meIsAdmin}) => (

      {subTab === 'INDEX' && meIsAdmin &&

 {onChangeSubTab('ADD')}}>
          Add Members

      }

      {subTab === 'INDEX' &&

            {members.map(m => {
              return (
                <Member
                  key={m.id}
                  user={m}
                  isAdmin={admin_id === m.id}
                  onRemove={() => {onRemove(m)}}
                  meIsAdmin={meIsAdmin}
                />
              )
            })}
            {meIsAdmin && invitations.map(i => {
              return (
                <Invitee
                  key={i.id}
                  email={i.email}
                />
              )
            })}

      }

)

// TODO(matthew): Invitee only renders if I'm an admin. So strip out the unnecessary stuff.
const Invitee = ({email, meIsAdmin}) => (

<Icon name='envelope'/>

{email}

invited

)

const Member = ({user, isAdmin, onRemove, meIsAdmin}) => (

    {meIsAdmin &&

          {user.name}

          {isAdmin ? 'Admin' : 'Editor'}

joined

          {user.membershipId && !isAdmin &&
            <button className='ui circular button small remove' onClick={onRemove}>

            </button>
          }

    }
    {!meIsAdmin &&

          {user.name}

    }

)

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

class MembersAddSubTab extends Component{
  state = { value: '' }

  componentDidMount() {
    this.refs.input.focus()
  }

  _submit() {
    this.props.addUser(this.state.value)
    this.setState({value: ''})
  }

  _onChange(e) {
    this.setState({value: e.target.value})
  }

  _onKeyDown(e) {
    if (e.keyCode === 13 && validateEmail(this.state.value)) {
      this._submit();
    }
  }

  render() {
    const {value} = this.state
    const isValid = validateEmail(value)
    const isEmpty = _.isEmpty(value)
    const buttonColor = (isValid || isEmpty) ? 'green' : 'grey'

    const requests = _.orderBy(_.cloneDeep(this.props.httpRequests), ['created_at'], ['desc'])
    return(

 {this.props.onChangeSubTab('INDEX')}}>
            <Icon name='chevron-left'/> Member List

 Invite New Members

 Members have viewing & editing access to all organization models.
 If you are on a plan, your pricing will be adjusted within 24 hours.

              Email Address
              <input
                value={this.state.value}
                onKeyDown={this._onKeyDown.bind(this)}
                type='text'
                placeholder='name@domain.com'
                ref='input'
                onChange={this._onChange.bind(this)}
              />

            <div className={`ui button submit ${buttonColor} ${isValid ? '' : 'disabled'}`} onClick={this._submit.bind(this)}>
              Invite User

            {_.map(requests, (request) =>  {
              return(
                <InvitationHttpRequest
                  key={request.id}
                  busy={request.busy}
                  success={request.success}
                  email={request.email}
                  isExistingMember={request.isExistingMember}
                />
              )
            })}

    )
  }
}

const InvitationHttpRequest = ({busy, success, email, isExistingMember}) => {
  let status = httpStatus(busy, success)

  if (status === 'sending'){ return (

      Sending...

  )} else if (status === 'failure'){ return (

      Invitation to {email} failed.  This could be because they are already part of the organization or because of a server problem.  If it continues, please let us know.

  )} else if (isExistingMember){ return (

      {email} was added to your organization.

  )} else { return(

      {email} was sent an email invitation to join your organization.

  )}
}

function httpStatus(busy, success) {
  if (busy) { return 'sending' }
  else if (success) { return 'success' }
  else { return 'failure' }
}
<commit_msg>Removing unnecessary cruft.<commit_after>import React, {Component, PropTypes} from 'react'
import { connect } from 'react-redux'

import ReactDOM from 'react-dom'
import Icon from 'react-fa'

import SpaceList from 'gComponents/spaces/list'
import * as spaceActions from 'gModules/spaces/actions'
import * as organizationActions from 'gModules/organizations/actions'
import * as userOrganizationMembershipActions from 'gModules/userOrganizationMemberships/actions'
import { organizationSpaceSelector } from './organizationSpaceSelector'
import { organizationMemberSelector } from './organizationMemberSelector'
import { httpRequestSelector } from './httpRequestSelector'
import SpaceCards from 'gComponents/spaces/cards'
import Container from 'gComponents/utility/container/Container'
import e from 'gEngine/engine'

import * as modalActions from 'gModules/modal/actions'

import './style.css'

function mapStateToProps(state) {
  return {
    me: state.me,
    organizations: state.organizations,
  }
}

@connect(mapStateToProps)
@connect(organizationSpaceSelector)
@connect(organizationMemberSelector)
@connect(httpRequestSelector)
export default class OrganizationShow extends Component{
  displayName: 'OrganizationShow'

  state = {
    attemptedFetch: false,
    openTab: 'MODELS',
    subMembersTab: 'INDEX'
  }

  componentWillMount() {
    this.fetchData()
  }

  componentDidUpdate() {
    this.fetchData()
  }

  fetchData() {
    if (!this.state.attemptedFetch) {
      this.props.dispatch(organizationActions.fetchById(this.props.organizationId))
      this.props.dispatch(spaceActions.fetch({organizationId: this.props.organizationId}))
      this.setState({attemptedFetch: true})
    }
  }

  changeTab(tab) {
    this.setState({
      openTab: tab,
      subMembersTab: 'INDEX'
    })
  }

  destroyMembership(membershipId) {
    this.props.dispatch(userOrganizationMembershipActions.destroy(membershipId))
  }

  addUser(email) {
    this.props.dispatch(userOrganizationMembershipActions.createWithEmail(this.props.organizationId, email))
  }

  onRemove(member) {
    this.confirmRemove(member)
  }

  confirmRemove({email, name, membershipId}) {
    const removeCallback = () => {
      this.destroyMembership(membershipId)
      this.props.dispatch(modalActions.close())
    }

    const message = `Are you sure you want to remove ${name} from this organization?`

    this.props.dispatch(modalActions.openConfirmation({onConfirm: removeCallback, message}))
  }

  render () {
    const {organizationId, organizations, members, memberships, invitations} = this.props
    const unjoinedInvitees = invitations.filter(i => !_.some(memberships, m => m.invitation_id === i.id))
    const {openTab} = this.state
    const spaces =  _.orderBy(this.props.organizationSpaces.asMutable(), ['updated_at'], ['desc'])
    const organization = organizations.find(u => u.id.toString() === organizationId.toString())
    const meIsAdmin = !!organization && (organization.admin_id === this.props.me.id)
    const meIsMember = meIsAdmin || !!(members.find(m => m.id === this.props.me.id))

    return (
      <Container>

          <OrganizationHeader organization={organization}/>

          {meIsMember &&
            <OrganizationTabButtons
              tabs={[{name: 'Models', key: 'MODELS'}, {name: 'Members', key: 'MEMBERS'}]}
              openTab={openTab}
              changeTab={this.changeTab.bind(this)}
            />
          }

            {(openTab === 'MODELS' || !meIsMember) && spaces &&
              <SpaceCards
                spaces={spaces}
                showPrivacy={true}
              />
            }

            {(openTab === 'MEMBERS') && meIsMember && members && organization &&
              <MembersTab
                subTab={this.state.subMembersTab}
                members={members}
                invitations={unjoinedInvitees}
                admin_id={organization.admin_id}
                onRemove={this.onRemove.bind(this)}
                addUser={this.addUser.bind(this)}
                onChangeSubTab={(name) => {this.setState({subMembersTab: name})}}
                httpRequests={this.props.httpRequests}
                meIsAdmin={meIsAdmin}
              />
            }

      </Container>
    )
  }
}

const OrganizationHeader = ({organization}) => (

      {organization &&

              {organization.name}

      }

)

const OrganizationTabButtons = ({tabs, openTab, changeTab}) => (

        { tabs.map( e => {
          const className = `item ${(openTab === e.key) ? 'active' : ''}`
          return (
             {changeTab(e.key)}}> {e.name}
          )
         })}

)

const MembersTab = ({subTab, members, invitations, admin_id, onRemove, addUser, onChangeSubTab, httpRequests, meIsAdmin}) => (

    {subTab === 'ADD' &&
      <MembersAddSubTab {...{addUser, httpRequests, onChangeSubTab}}/>
    }
    {subTab === 'INDEX' &&
      <MembersIndexSubTab {...{subTab, members, invitations, admin_id, onRemove, onChangeSubTab, meIsAdmin}}/>
    }

)

const MembersIndexSubTab = ({subTab, members, invitations, admin_id, onChangeSubTab, onRemove, meIsAdmin}) => (

      {subTab === 'INDEX' && meIsAdmin &&

 {onChangeSubTab('ADD')}}>
          Add Members

      }

      {subTab === 'INDEX' &&

            {members.map(m => {
              return (
                <Member
                  key={m.id}
                  user={m}
                  isAdmin={admin_id === m.id}
                  onRemove={() => {onRemove(m)}}
                  meIsAdmin={meIsAdmin}
                />
              )
            })}
            {meIsAdmin && invitations.map(i => {
              return (
                <Invitee
                  key={i.id}
                  email={i.email}
                />
              )
            })}

      }

)

const Invitee = ({email}) => (

<Icon name='envelope'/>

{email}

invited

)

const Member = ({user, isAdmin, onRemove, meIsAdmin}) => (

    {meIsAdmin &&

          {user.name}

          {isAdmin ? 'Admin' : 'Editor'}

joined

          {user.membershipId && !isAdmin &&
            <button className='ui circular button small remove' onClick={onRemove}>

            </button>
          }

    }
    {!meIsAdmin &&

          {user.name}

    }

)

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

class MembersAddSubTab extends Component{
  state = { value: '' }

  componentDidMount() {
    this.refs.input.focus()
  }

  _submit() {
    this.props.addUser(this.state.value)
    this.setState({value: ''})
  }

  _onChange(e) {
    this.setState({value: e.target.value})
  }

  _onKeyDown(e) {
    if (e.keyCode === 13 && validateEmail(this.state.value)) {
      this._submit();
    }
  }

  render() {
    const {value} = this.state
    const isValid = validateEmail(value)
    const isEmpty = _.isEmpty(value)
    const buttonColor = (isValid || isEmpty) ? 'green' : 'grey'

    const requests = _.orderBy(_.cloneDeep(this.props.httpRequests), ['created_at'], ['desc'])
    return(

 {this.props.onChangeSubTab('INDEX')}}>
            <Icon name='chevron-left'/> Member List

 Invite New Members

 Members have viewing & editing access to all organization models.
 If you are on a plan, your pricing will be adjusted within 24 hours.

              Email Address
              <input
                value={this.state.value}
                onKeyDown={this._onKeyDown.bind(this)}
                type='text'
                placeholder='name@domain.com'
                ref='input'
                onChange={this._onChange.bind(this)}
              />

            <div className={`ui button submit ${buttonColor} ${isValid ? '' : 'disabled'}`} onClick={this._submit.bind(this)}>
              Invite User

            {_.map(requests, (request) =>  {
              return(
                <InvitationHttpRequest
                  key={request.id}
                  busy={request.busy}
                  success={request.success}
                  email={request.email}
                  isExistingMember={request.isExistingMember}
                />
              )
            })}

    )
  }
}

const InvitationHttpRequest = ({busy, success, email, isExistingMember}) => {
  let status = httpStatus(busy, success)

  if (status === 'sending'){ return (

      Sending...

  )} else if (status === 'failure'){ return (

      Invitation to {email} failed.  This could be because they are already part of the organization or because of a server problem.  If it continues, please let us know.

  )} else if (isExistingMember){ return (

      {email} was added to your organization.

  )} else { return(

      {email} was sent an email invitation to join your organization.

  )}
}

function httpStatus(busy, success) {
  if (busy) { return 'sending' }
  else if (success) { return 'success' }
  else { return 'failure' }
}
<|endoftext|>


<commit_before>/* 28dec12abu
 * (c) Software Lab. Alexander Burger
 */

var FormReq = false;
var HintReq = false;
var LispReq = false;
var Hint, Hints, Item, Beg, End;

try {
   FormReq = new XMLHttpRequest();
   HintReq = new XMLHttpRequest();
   LispReq = new XMLHttpRequest();
   FormReq.upload.addEventListener("progress", dropProgress, false);
   FormReq.upload.addEventListener("load", dropLoad, false);
}
catch (e) {}

var Queue = new Array();
var Btn = new Array();
var Key, InBtn, Auto, Drop;

function inBtn(flg) {InBtn = flg;}

function formKey(event) {
   Key = event.keyCode;
   if (Hint  &&  Hint.style.visibility == "visible") {
      if ((Item >= 0 && Key == 13) || Key == 38 || Key == 40)
         return false;
      if (event.keyCode == 27) {
         Hint.style.visibility = "hidden";
         return false;
      }
   }
   return true;
}

function fldChg(field) {
   if (!InBtn && Key != 13)
      post(field.form, null);
   return true;
}

function doBtn(btn) {
   Btn.push(btn);
   return true;
}

function doDrag(event) {
   event.stopPropagation();
   event.preventDefault();
}

function doDrop(btn, event) {
   doDrag(event);
   if (event.dataTransfer.files.length != 0) {
      Btn.push(Drop = btn);
      btn.value = "0 %";
      post(btn.form, event.dataTransfer.files[0]);
   }
}

function dropProgress(event) {
   if (Drop)
      Drop.value = event.lengthComputable?
         Math.round((event.loaded * 100) / event.total) + " %" : "(?) %";
}

function dropLoad(event) {
   Drop = null;
}

function hasElement(form, name) {
   for (var i = 0; i < form.elements.length; ++i)
      if (form.elements[i].name == name)
         return true;
   return false;
}

/*** Form submit ***/
function doPost(form) {
   for (var i = 0; ; ++i) {
      if (i == Btn.length)
         return true;
      if (Btn[i].form == form)
         break;
   }
   return post(form, null);
}

function post(form, file) {
   var i;

   if (!FormReq || !hasElement(form,"*Get") || (i = form.action.indexOf("~")) <= 0)
      return true;
   if (FormReq.readyState > 0 && FormReq.readyState < 4) {
      Queue.push(form);
      return false;
   }
   form.style.cursor = "wait";
   try {FormReq.open("POST", form.action.substr(0,i) + "~!jsForm?" + form.action.substr(i+1));}
   catch (e) {return true;}
   FormReq.onload = function() {
      var i, j;

      if (FormReq.responseText == "T") {
         Queue.length = 0;
         form.submit();
      }
      else {
         var txt = FormReq.responseText.split("&");

         if (txt[0]) {
            var r = txt[0].split(":");

            if (Auto)
               window.clearTimeout(Auto);
            if (r[1])
               Auto = window.setTimeout("document.getElementById(\"" + r[0] + "\").click()", r[1]);
         }
         for (i = 1; i < txt.length;) {
            var fld = txt[i++];
            var val = decodeURIComponent(txt[i++]);

            if (!fld) {
               window[txt[i++]](val);
               continue;
            }
            if (!(fld = document.getElementById(fld)))
               continue;
            if (fld.tagName == "SPAN") {
               if (i != txt.length && txt[i].charAt(0) == "=")
                  ++i;
               if (i == txt.length || txt[i].charAt(0) != "+") {
                  if (fld.firstChild.tagName != "A")
                     fld.firstChild.data = val? val : "\u00A0";
                  else
                     fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
               }
               else {
                  var a = document.createElement("A");

                  a.href = decodeURIComponent(txt[i++].substr(1));
                  a.appendChild(document.createTextNode(val));
                  fld.replaceChild(a, fld.firstChild);
               }
            }
            else if (fld.tagName == "A") {
               if (i != txt.length && txt[i].charAt(0) == "=")
                  ++i;
               if (i == txt.length || txt[i].charAt(0) != "+") {
                  fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
                  fld.removeAttribute("href");
               }
               else {
                  fld.firstChild.data = val;
                  fld.href = decodeURIComponent(txt[i++].substr(1));
               }
            }
            else if (fld.tagName == "IMG")
               fld.src = val;
            else {
               if (fld.custom != null)
                  putCustom(fld.custom, val);
               else if (fld.type == "checkbox") {
                  fld.checked = val != "";
                  document.getElementsByName(fld.name)[0].value = "";
               }
               else if (fld.type == "select-one") {
                  for (j = 0; j < fld.options.length; ++j) {
                     if (fld.options[j].text == val)
                        fld.selectedIndex = j;
                     fld.options[j].disabled = false;
                  }
               }
               else if (fld.type == "radio") {
                  fld.value = val;
                  fld.checked = txt[i++].charAt(0) != "";
               }
               else if (fld.type == "image")
                  fld.src = val;
               else if (fld.value != val) {
                  fld.value = val;
                  fld.scrollTop = fld.scrollHeight;
               }
               fld.disabled = false;
               if (i < txt.length && txt[i].charAt(0) == "=") {
                  if (fld.type == "select-one") {
                     for (j = 0; j < fld.options.length; ++j)
                        if (fld.options[j].text != val)
                           fld.options[j].disabled = true;
                  }
                  fld.disabled = true;
                  InBtn = 0;  // 'onblur' on won't come when disabled
                  if (fld.type == "checkbox"  &&  fld.checked)
                     document.getElementsByName(fld.name)[0].value = "T";
                  ++i;
               }
               if (fld.custom != null)
                  ableCustom(fld.custom);
            }
            while (i < txt.length && (j = "#*?".indexOf(txt[i].charAt(0))) >= 0) {
               switch (j) {

               case 0:  // '#'
                  var cls;

                  val = txt[i++].substr(1);
                  if ((cls = fld.getAttribute("class")) != null  &&  (j = cls.indexOf(" ")) >= 0)
                     val += cls.substr(j);
                  fld.setAttribute("class", val);
                  break;

               case 1:  // '*'
                  var node = fld.parentNode.parentNode.lastChild;
                  var img = document.createElement("IMG");

                  if (!node.firstChild)
                     node = fld.parentNode.parentNode.parentNode.lastChild;
                  node.removeChild(node.firstChild);
                  img.src = txt[i++].substr(1);
                  if (!txt[i])
                     node.appendChild(img);
                  else {
                     var a = document.createElement("A");

                     a.href = decodeURIComponent(txt[i]);
                     a.appendChild(img);
                     node.appendChild(a);
                  }
                  ++i;
                  break;

               case 2:  // '?'
                  fld.title = decodeURIComponent(txt[i++].substr(1));
                  break;
               }
            }
         }
      }
      form.style.cursor = "";
      if (Queue.length > 0)
         post(Queue.shift(), null);
   }
   var data = "";
   for (var i = 0; i < Btn.length;)
      if (Btn[i].form != form)
         ++i;
      else {
         data += (data? "&":"") + Btn[i].name + "=" + encodeURIComponent(Btn[i].type == "submit"? Btn[i].value : Btn[i].src);
         Btn.splice(i,1);
      }
   for (i = 0; i < form.elements.length; ++i) {
      var fld = form.elements[i];

      if (fld.name  &&  fld.type != "submit") {   // "image" won't come :-(
         var val;

         if (fld.custom != null)
            val = getCustom(fld.custom);
         else if (fld.type == "checkbox")
            val = fld.checked? "T" : "";
         else if (fld.type == "select-one")
            val = fld.options[fld.selectedIndex].text;
         else if (fld.type == "radio" && !fld.checked)
            continue;
         else
            val = fld.value;
         data += "&" + fld.name + "=" + encodeURIComponent(val);
      }
   }
   try {
      if (!file)
         FormReq.send(data);
      else {
         var rd = new FileReader();
         rd.readAsBinaryString(file);
         rd.onload = function() {
            FormReq.setRequestHeader("X-Pil", "*ContLen=");
            FormReq.sendAsBinary(data + "&*Drop=" +
               encodeURIComponent(file.name) + "=" +
               file.size + "\n" + rd.result );
         }
      }
   }
   catch (e) {
      FormReq.abort();
      return true;
   }
   return false;
}

/*** Hints ***/
function doHint(field) {
   if (HintReq) {
      if (!Hint) {
         Hint = document.createElement("div");
         Hint.setAttribute("class", "hint");
         Hint.style.visibility = "hidden";
         Hint.style.position = "absolute";
         Hints = document.createElement("div");
         Hints.setAttribute("class", "hints");
         Hints.style.position = "relative";
         Hints.style.top = "-2px";
         Hints.style.left = "-3px";
         Hint.appendChild(Hints);
      }
      field.parentNode.appendChild(Hint);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      var top = field.offsetHeight + 2;
      var left = 3;
      for (var obj = field;  obj.id != "main" && obj.id != "menu";  obj = obj.offsetParent) {
         top += obj.offsetTop;
         left += obj.offsetLeft;
      }
      Hint.style.top = top + "px";
      Hint.style.left = left + "px";
   }
}

function hintKey(field, event, tok, coy) {
   var i, data;

   if (!HintReq)
      return true;
   if (event.keyCode == 9 || event.keyCode == 27)
      return false;
   if (Hint.style.visibility == "visible") {
      if (Item >= 0 && event.keyCode == 13) {
         setHint(field, Hints.childNodes[Item]);
         return false;
      }
      if (event.keyCode == 38) {  // Up
         if (Item > 0) {
            hintOff(Item);
            hintOn(--Item);
         }
         return false;
      }
      if (event.keyCode == 40) {  // Down
         if (Item < (lst = Hints.childNodes).length-1) {
            if (Item >= 0)
               hintOff(Item);
            hintOn(++Item);
         }
         return false;
      }
   }
   if (event.keyCode == 13)
      return true;
   if (HintReq.readyState > 0 && HintReq.readyState < 4)
      return false;
   if (tok) {
      for (Beg = field.selectionStart;  Beg > 0 && !field.value.charAt(Beg-1).match(/\s/);  --Beg);
      End = field.selectionEnd;
   }
   else {
      Beg = 0;
      End = field.value.length;
   }
   if (event.keyCode != 45) {  // INS
      if (Beg == End) {
         Hint.style.visibility = "hidden";
         return false;
      }
      if (coy && Hint.style.visibility == "hidden")
         return false;
   }
   try {
      HintReq.open("POST",
         ((i = field.form.action.indexOf("~")) <= 0?
            "" : field.form.action.substr(0, i+1) ) +
         ((i = field.id.lastIndexOf("-")) < 0?
            "!jsHint?$" + field.id : "!jsHint?+" + field.id.substr(i+1) ) );
   }
   catch (e) {return true;}
   HintReq.onload = function() {
      var i, n, lst, str;

      if ((str = HintReq.responseText).length == 0)
         Hint.style.visibility = "hidden";
      else {
         lst = str.split("&");
         while (Hints.hasChildNodes())
            Hints.removeChild(Hints.firstChild);
         for (i = 0, n = 7; i < lst.length; ++i) {
            addHint(i, field, str = decodeURIComponent(lst[i]));
            if (str.length > n)
               n = str.length;
         }
         Hints.style.width = n + 3 + "ex";
         Hint.style.width = n + 4 + "ex";
         Hint.style.visibility = "visible";
         Item = -1;
      }
   }
   var data = "*JsHint=" + encodeURIComponent(field.value.substring(Beg,End));
   for (i = 0; i < field.form.elements.length; ++i) {
      var fld = field.form.elements[i];

      if (fld.name == "*Get")
         data += "&*Get=" + fld.value;
      else if (fld.name == "*Form")
         data += "&*Form=" + fld.value;
   }
   try {HintReq.send(data);}
   catch (e) {
      HintReq.abort();
      return true;
   }
   return (event.keyCode != 45);  // INS
}

function addHint(i, field, str) {
   var item = document.createElement("div");
   item.appendChild(document.createTextNode(str));
   item.onmouseover = function() {
      if (Item >= 0)
         hintOff(Item);
      hintOn(i);
      field.onblur = false;
      field.onchange = false;
      Item = i;
   }
   item.onmouseout = function() {
      hintOff(Item);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      field.onchange = function() {
         return fldChg(field, item);
      };
      Item = -1;
   }
   item.onclick = function() {
      setHint(field, item);
   }
   Hints.appendChild(item);
}

function setHint(field, item) {
   Hint.style.visibility = "hidden";
   field.value = field.value.substr(0,Beg) + item.firstChild.nodeValue + field.value.substr(End);
   post(field.form, null);
   field.setSelectionRange(Beg + item.firstChild.nodeValue.length, field.value.length);
   field.focus();
   field.onchange = function() {
      return fldChg(field)
   };
}

function hintOn(i) {
   var s = Hints.childNodes[i].style;
   s.background = "black";
   s.color= "white";
}

function hintOff(i) {
   var s = Hints.childNodes[i].style;
   s.background = "white";
   s.color= "black";
}

/*** Lisp calls ***/
function lisp(url) {
   if (!LispReq)
      return true;
   if (arguments.length > 1) {
      url += "?" + arguments[1];  // arguments should be properly encoded
      for (var i = 2; i < arguments.length; ++i)
         url += "&" + arguments[i];
   }
   try {LispReq.open("GET", url);}
   catch (e) {return true;}
   try {LispReq.send(null);}
   catch (e) {
      LispReq.abort();
      return true;
   }
   return false;
}
<commit_msg>Clean up<commit_after>/* 17jan13abu
 * (c) Software Lab. Alexander Burger
 */

var FormReq = new XMLHttpRequest();
var HintReq = new XMLHttpRequest();
var LispReq = new XMLHttpRequest();

FormReq.upload.addEventListener("progress", dropProgress, false);
FormReq.upload.addEventListener("load", dropLoad, false);

var Queue = new Array();
var Btn = new Array();
var Key, InBtn, Auto, Drop;
var Hint, Hints, Item, Beg, End;

function inBtn(flg) {InBtn = flg;}

function formKey(event) {
   Key = event.keyCode;
   if (Hint  &&  Hint.style.visibility == "visible") {
      if ((Item >= 0 && Key == 13) || Key == 38 || Key == 40)
         return false;
      if (event.keyCode == 27) {
         Hint.style.visibility = "hidden";
         return false;
      }
   }
   return true;
}

function fldChg(field) {
   if (!InBtn && Key != 13)
      post(field.form, null);
   return true;
}

function doBtn(btn) {
   Btn.push(btn);
   return true;
}

function doDrag(event) {
   event.stopPropagation();
   event.preventDefault();
}

function doDrop(btn, event) {
   doDrag(event);
   if (event.dataTransfer.files.length != 0) {
      Btn.push(Drop = btn);
      btn.value = "0 %";
      post(btn.form, event.dataTransfer.files[0]);
   }
}

function dropProgress(event) {
   if (Drop)
      Drop.value = event.lengthComputable?
         Math.round((event.loaded * 100) / event.total) + " %" : "(?) %";
}

function dropLoad(event) {
   Drop = null;
}

function hasElement(form, name) {
   for (var i = 0; i < form.elements.length; ++i)
      if (form.elements[i].name == name)
         return true;
   return false;
}

/*** Form submit ***/
function doPost(form) {
   for (var i = 0; ; ++i) {
      if (i == Btn.length)
         return true;
      if (Btn[i].form == form)
         break;
   }
   return post(form, null);
}

function post(form, file) {
   var i;

   if (!FormReq || !hasElement(form,"*Get") || (i = form.action.indexOf("~")) <= 0)
      return true;
   if (FormReq.readyState > 0 && FormReq.readyState < 4) {
      Queue.push(form);
      return false;
   }
   form.style.cursor = "wait";
   try {FormReq.open("POST", form.action.substr(0,i) + "~!jsForm?" + form.action.substr(i+1));}
   catch (e) {return true;}
   FormReq.onload = function() {
      var i, j;

      if (FormReq.responseText == "T") {
         Queue.length = 0;
         form.submit();
      }
      else {
         var txt = FormReq.responseText.split("&");

         if (txt[0]) {
            var r = txt[0].split(":");

            if (Auto)
               window.clearTimeout(Auto);
            if (r[1])
               Auto = window.setTimeout("document.getElementById(\"" + r[0] + "\").click()", r[1]);
         }
         for (i = 1; i < txt.length;) {
            var fld = txt[i++];
            var val = decodeURIComponent(txt[i++]);

            if (!fld) {
               window[txt[i++]](val);
               continue;
            }
            if (!(fld = document.getElementById(fld)))
               continue;
            if (fld.tagName == "SPAN") {
               if (i != txt.length && txt[i].charAt(0) == "=")
                  ++i;
               if (i == txt.length || txt[i].charAt(0) != "+") {
                  if (fld.firstChild.tagName != "A")
                     fld.firstChild.data = val? val : "\u00A0";
                  else
                     fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
               }
               else {
                  var a = document.createElement("A");

                  a.href = decodeURIComponent(txt[i++].substr(1));
                  a.appendChild(document.createTextNode(val));
                  fld.replaceChild(a, fld.firstChild);
               }
            }
            else if (fld.tagName == "A") {
               if (i != txt.length && txt[i].charAt(0) == "=")
                  ++i;
               if (i == txt.length || txt[i].charAt(0) != "+") {
                  fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
                  fld.removeAttribute("href");
               }
               else {
                  fld.firstChild.data = val;
                  fld.href = decodeURIComponent(txt[i++].substr(1));
               }
            }
            else if (fld.tagName == "IMG")
               fld.src = val;
            else {
               if (fld.custom != null)
                  putCustom(fld.custom, val);
               else if (fld.type == "checkbox") {
                  fld.checked = val != "";
                  document.getElementsByName(fld.name)[0].value = "";
               }
               else if (fld.type == "select-one") {
                  for (j = 0; j < fld.options.length; ++j) {
                     if (fld.options[j].text == val)
                        fld.selectedIndex = j;
                     fld.options[j].disabled = false;
                  }
               }
               else if (fld.type == "radio") {
                  fld.value = val;
                  fld.checked = txt[i++].charAt(0) != "";
               }
               else if (fld.type == "image")
                  fld.src = val;
               else if (fld.value != val) {
                  fld.value = val;
                  fld.scrollTop = fld.scrollHeight;
               }
               fld.disabled = false;
               if (i < txt.length && txt[i].charAt(0) == "=") {
                  if (fld.type == "select-one") {
                     for (j = 0; j < fld.options.length; ++j)
                        if (fld.options[j].text != val)
                           fld.options[j].disabled = true;
                  }
                  fld.disabled = true;
                  InBtn = 0;  // 'onblur' on won't come when disabled
                  if (fld.type == "checkbox"  &&  fld.checked)
                     document.getElementsByName(fld.name)[0].value = "T";
                  ++i;
               }
               if (fld.custom != null)
                  ableCustom(fld.custom);
            }
            while (i < txt.length && (j = "#*?".indexOf(txt[i].charAt(0))) >= 0) {
               switch (j) {

               case 0:  // '#'
                  var cls;

                  val = txt[i++].substr(1);
                  if ((cls = fld.getAttribute("class")) != null  &&  (j = cls.indexOf(" ")) >= 0)
                     val += cls.substr(j);
                  fld.setAttribute("class", val);
                  break;

               case 1:  // '*'
                  var node = fld.parentNode.parentNode.lastChild;
                  var img = document.createElement("IMG");

                  if (!node.firstChild)
                     node = fld.parentNode.parentNode.parentNode.lastChild;
                  node.removeChild(node.firstChild);
                  img.src = txt[i++].substr(1);
                  if (!txt[i])
                     node.appendChild(img);
                  else {
                     var a = document.createElement("A");

                     a.href = decodeURIComponent(txt[i]);
                     a.appendChild(img);
                     node.appendChild(a);
                  }
                  ++i;
                  break;

               case 2:  // '?'
                  fld.title = decodeURIComponent(txt[i++].substr(1));
                  break;
               }
            }
         }
      }
      form.style.cursor = "";
      if (Queue.length > 0)
         post(Queue.shift(), null);
   }
   var data = "";
   for (var i = 0; i < Btn.length;)
      if (Btn[i].form != form)
         ++i;
      else {
         data += "&" + Btn[i].name + "=" + encodeURIComponent(Btn[i].type == "submit"? Btn[i].value : Btn[i].src);
         Btn.splice(i,1);
      }
   for (i = 0; i < form.elements.length; ++i) {
      var fld = form.elements[i];

      if (fld.name  &&  fld.type != "submit") {   // "image" won't come :-(
         var val;

         if (fld.custom != null)
            val = getCustom(fld.custom);
         else if (fld.type == "checkbox")
            val = fld.checked? "T" : "";
         else if (fld.type == "select-one")
            val = fld.options[fld.selectedIndex].text;
         else if (fld.type == "radio" && !fld.checked)
            continue;
         else
            val = fld.value;
         data += "&" + fld.name + "=" + encodeURIComponent(val);
      }
   }
   try {
      if (!file)
         FormReq.send(data);
      else {
         var rd = new FileReader();
         rd.readAsBinaryString(file);
         rd.onload = function() {
            FormReq.setRequestHeader("X-Pil", "*ContLen=");
            FormReq.sendAsBinary(data + "&*Drop=" +
               encodeURIComponent(file.name) + "=" +
               file.size + "\n" + rd.result );
         }
      }
   }
   catch (e) {
      FormReq.abort();
      return true;
   }
   return false;
}

/*** Hints ***/
function doHint(field) {
   if (HintReq) {
      if (!Hint) {
         Hint = document.createElement("div");
         Hint.setAttribute("class", "hint");
         Hint.style.visibility = "hidden";
         Hint.style.position = "absolute";
         Hints = document.createElement("div");
         Hints.setAttribute("class", "hints");
         Hints.style.position = "relative";
         Hints.style.top = "-2px";
         Hints.style.left = "-3px";
         Hint.appendChild(Hints);
      }
      field.parentNode.appendChild(Hint);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      var top = field.offsetHeight + 2;
      var left = 3;
      for (var obj = field;  obj.id != "main" && obj.id != "menu";  obj = obj.offsetParent) {
         top += obj.offsetTop;
         left += obj.offsetLeft;
      }
      Hint.style.top = top + "px";
      Hint.style.left = left + "px";
   }
}

function hintKey(field, event, tok, coy) {
   var i, data;

   if (!HintReq)
      return true;
   if (event.keyCode == 9 || event.keyCode == 27)
      return false;
   if (Hint.style.visibility == "visible") {
      if (Item >= 0 && event.keyCode == 13) {
         setHint(field, Hints.childNodes[Item]);
         return false;
      }
      if (event.keyCode == 38) {  // Up
         if (Item > 0) {
            hintOff(Item);
            hintOn(--Item);
         }
         return false;
      }
      if (event.keyCode == 40) {  // Down
         if (Item < (lst = Hints.childNodes).length-1) {
            if (Item >= 0)
               hintOff(Item);
            hintOn(++Item);
         }
         return false;
      }
   }
   if (event.keyCode == 13)
      return true;
   if (HintReq.readyState > 0 && HintReq.readyState < 4)
      return false;
   if (tok) {
      for (Beg = field.selectionStart;  Beg > 0 && !field.value.charAt(Beg-1).match(/\s/);  --Beg);
      End = field.selectionEnd;
   }
   else {
      Beg = 0;
      End = field.value.length;
   }
   if (event.keyCode != 45) {  // INS
      if (Beg == End) {
         Hint.style.visibility = "hidden";
         return false;
      }
      if (coy && Hint.style.visibility == "hidden")
         return false;
   }
   try {
      HintReq.open("POST",
         ((i = field.form.action.indexOf("~")) <= 0?
            "" : field.form.action.substr(0, i+1) ) +
         ((i = field.id.lastIndexOf("-")) < 0?
            "!jsHint?$" + field.id : "!jsHint?+" + field.id.substr(i+1) ) );
   }
   catch (e) {return true;}
   HintReq.onload = function() {
      var i, n, lst, str;

      if ((str = HintReq.responseText).length == 0)
         Hint.style.visibility = "hidden";
      else {
         lst = str.split("&");
         while (Hints.hasChildNodes())
            Hints.removeChild(Hints.firstChild);
         for (i = 0, n = 7; i < lst.length; ++i) {
            addHint(i, field, str = decodeURIComponent(lst[i]));
            if (str.length > n)
               n = str.length;
         }
         Hints.style.width = n + 3 + "ex";
         Hint.style.width = n + 4 + "ex";
         Hint.style.visibility = "visible";
         Item = -1;
      }
   }
   var data = "*JsHint=" + encodeURIComponent(field.value.substring(Beg,End));
   for (i = 0; i < field.form.elements.length; ++i) {
      var fld = field.form.elements[i];

      if (fld.name == "*Get")
         data += "&*Get=" + fld.value;
      else if (fld.name == "*Form")
         data += "&*Form=" + fld.value;
   }
   try {HintReq.send(data);}
   catch (e) {
      HintReq.abort();
      return true;
   }
   return (event.keyCode != 45);  // INS
}

function addHint(i, field, str) {
   var item = document.createElement("div");
   item.appendChild(document.createTextNode(str));
   item.onmouseover = function() {
      if (Item >= 0)
         hintOff(Item);
      hintOn(i);
      field.onblur = false;
      field.onchange = false;
      Item = i;
   }
   item.onmouseout = function() {
      hintOff(Item);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      field.onchange = function() {
         return fldChg(field, item);
      };
      Item = -1;
   }
   item.onclick = function() {
      setHint(field, item);
   }
   Hints.appendChild(item);
}

function setHint(field, item) {
   Hint.style.visibility = "hidden";
   field.value = field.value.substr(0,Beg) + item.firstChild.nodeValue + field.value.substr(End);
   post(field.form, null);
   field.setSelectionRange(Beg + item.firstChild.nodeValue.length, field.value.length);
   field.focus();
   field.onchange = function() {
      return fldChg(field)
   };
}

function hintOn(i) {
   var s = Hints.childNodes[i].style;
   s.background = "black";
   s.color= "white";
}

function hintOff(i) {
   var s = Hints.childNodes[i].style;
   s.background = "white";
   s.color= "black";
}

/*** Lisp calls ***/
function lisp(url) {
   if (!LispReq)
      return true;
   if (arguments.length > 1) {
      url += "?" + arguments[1];  // arguments should be properly encoded
      for (var i = 2; i < arguments.length; ++i)
         url += "&" + arguments[i];
   }
   try {LispReq.open("GET", url);}
   catch (e) {return true;}
   try {LispReq.send(null);}
   catch (e) {
      LispReq.abort();
      return true;
   }
   return false;
}
<|endoftext|>


<commit_before>/* 01dec11abu
 * (c) Software Lab. Alexander Burger
 */

var FormReq = false;
var HintReq = false;
var Hint, Hints, Item, Beg, End;

try {
   FormReq = new XMLHttpRequest();
   HintReq = new XMLHttpRequest();
   FormReq.upload.addEventListener("progress", dropProgress, false);
   FormReq.upload.addEventListener("load", dropLoad, false);
}
catch (e) {}

var Queue = new Array();
var Btn = new Array();
var Key, InBtn, Auto, Drop;

function inBtn(flg) {InBtn = flg;}

function formKey(event) {
   Key = event.keyCode;
   if (Hint  &&  Hint.style.visibility == "visible") {
      if ((Item >= 0 && Key == 13) || Key == 38 || Key == 40)
         return false;
      if (event.keyCode == 27) {
         Hint.style.visibility = "hidden";
         return false;
      }
   }
   return true;
}

function fldChg(field) {
   if (!InBtn && Key != 13)
      post(field.form, null);
   return true;
}

function doBtn(btn) {
   Btn.push(btn);
   return true;
}

function doDrag(event) {
   event.stopPropagation();
   event.preventDefault();
}

function doDrop(btn, event) {
   doDrag(event);
   if (event.dataTransfer.files.length != 0) {
      Btn.push(Drop = btn);
      btn.value = "0 %";
      post(btn.form, event.dataTransfer.files[0]);
   }
}

function dropProgress(event) {
   if (Drop)
      Drop.value = event.lengthComputable?
         Math.round((event.loaded * 100) / event.total) + " %" : "(?) %";
}

function dropLoad(event) {
   Drop = null;
}

function hasElement(form, name) {
   for (var i = 0; i < form.elements.length; ++i)
      if (form.elements[i].name == name)
         return true;
   return false;
}

/*** Form submit ***/
function doPost(form) {
   for (var i = 0; ; ++i) {
      if (i == Btn.length)
         return true;
      if (Btn[i].form == form)
         break;
   }
   return post(form, null);
}

function post(form, file) {
   var i;

   if (!FormReq || !hasElement(form,"*Get") || (i = form.action.indexOf("~")) <= 0)
      return true;
   if (FormReq.readyState > 0 && FormReq.readyState < 4) {
      Queue.push(form);
      return false;
   }
   form.style.cursor = "wait";
   try {FormReq.open("POST", form.action.substr(0,i) + "~!jsForm?" + form.action.substr(i+1));}
   catch (e) {return true;}
   FormReq.onreadystatechange = function() {
      if (FormReq.readyState == 4 && FormReq.status == 200) {
         var i, j;

         if (FormReq.responseText == "T") {
            Queue.length = 0;
            form.submit();
         }
         else {
            var txt = FormReq.responseText.split("&");

            if (txt[0]) {
               var r = txt[0].split(":");

               if (Auto)
                  window.clearTimeout(Auto);
               if (r[1])
                  Auto = window.setTimeout("document.getElementById(\"" + r[0] + "\").click()", r[1]);
            }
            for (i = 1; i < txt.length;) {
               var fld = txt[i++];
               var val = decodeURIComponent(txt[i++]);

               if (!fld) {
                  window[txt[i++]](val);
                  continue;
               }
               if (!(fld = document.getElementById(fld)))
                  continue;
               if (fld.tagName == "SPAN") {
                  if (i != txt.length && txt[i].charAt(0) == "=")
                     ++i;
                  if (i == txt.length || txt[i].charAt(0) != "+") {
                     if (fld.firstChild.tagName != "A")
                        fld.firstChild.data = val? val : "\u00A0";
                     else
                        fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
                  }
                  else {
                     var a = document.createElement("A");

                     a.href = decodeURIComponent(txt[i++].substr(1));
                     a.appendChild(document.createTextNode(val));
                     fld.replaceChild(a, fld.firstChild);
                  }
               }
               else if (fld.tagName == "A") {
                  if (i != txt.length && txt[i].charAt(0) == "=")
                     ++i;
                  if (i == txt.length || txt[i].charAt(0) != "+") {
                     fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
                     fld.removeAttribute("href");
                  }
                  else {
                     fld.firstChild.data = val;
                     fld.href = decodeURIComponent(txt[i++].substr(1));
                  }
               }
               else if (fld.tagName == "IMG")
                  fld.src = val;
               else {
                  if (fld.custom != null)
                     putCustom(fld.custom, val);
                  else if (fld.type == "checkbox") {
                     fld.checked = val != "";
                     document.getElementsByName(fld.name)[0].value = "";
                  }
                  else if (fld.type == "select-one") {
                     for (j = 0; j < fld.options.length; ++j) {
                        if (fld.options[j].text == val)
                           fld.selectedIndex = j;
                        fld.options[j].disabled = false;
                     }
                  }
                  else if (fld.type == "radio") {
                     fld.value = val;
                     fld.checked = txt[i++].charAt(0) != "";
                  }
                  else if (fld.type == "image")
                     fld.src = val;
                  else if (fld.value != val) {
                     fld.value = val;
                     fld.scrollTop = fld.scrollHeight;
                  }
                  fld.disabled = false;
                  if (i < txt.length && txt[i].charAt(0) == "=") {
                     if (fld.type == "select-one") {
                        for (j = 0; j < fld.options.length; ++j)
                           if (fld.options[j].text != val)
                              fld.options[j].disabled = true;
                     }
                     fld.disabled = true;
                     if (fld.type == "checkbox"  &&  fld.checked)
                        document.getElementsByName(fld.name)[0].value = "T";
                     ++i;
                  }
                  if (fld.custom != null)
                     ableCustom(fld.custom);
               }
               while (i < txt.length && (j = "#*?".indexOf(txt[i].charAt(0))) >= 0) {
                  switch (j) {

                  case 0:  // '#'
                     var cls;

                     val = txt[i++].substr(1);
                     if ((cls = fld.getAttribute("class")) != null  &&  (j = cls.indexOf(" ")) >= 0)
                        val += cls.substr(j);
                     fld.setAttribute("class", val);
                     break;

                  case 1:  // '*'
                     var node = fld.parentNode.parentNode.lastChild;
                     var img = document.createElement("IMG");

                     if (!node.firstChild)
                        node = fld.parentNode.parentNode.parentNode.lastChild;
                     node.removeChild(node.firstChild);
                     img.src = txt[i++].substr(1);
                     if (!txt[i])
                        node.appendChild(img);
                     else {
                        var a = document.createElement("A");

                        a.href = decodeURIComponent(txt[i]);
                        a.appendChild(img);
                        node.appendChild(a);
                     }
                     ++i;
                     break;

                  case 2:  // '?'
                     fld.title = decodeURIComponent(txt[i++].substr(1));
                     break;
                  }
               }
            }
         }
         form.style.cursor = "";
         if (Queue.length > 0)
            post(Queue.shift(), null);
      }
   }
   var data = "";
   for (var i = 0; i < Btn.length;)
      if (Btn[i].form != form)
         ++i;
      else {
         data += (data? "&":"") + Btn[i].name + "=" + encodeURIComponent(Btn[i].type == "submit"? Btn[i].value : Btn[i].src);
         Btn.splice(i,1);
      }
   for (i = 0; i < form.elements.length; ++i) {
      var fld = form.elements[i];

      if (fld.name  &&  fld.type != "submit") {   // "image" won't come :-(
         var val;

         if (fld.custom != null)
            val = getCustom(fld.custom);
         else if (fld.type == "checkbox")
            val = fld.checked? "T" : "";
         else if (fld.type == "select-one")
            val = fld.options[fld.selectedIndex].text;
         else if (fld.type == "radio" && !fld.checked)
            continue;
         else
            val = fld.value;
         data += "&" + fld.name + "=" + encodeURIComponent(val);
      }
   }
   try {
      if (!file)
         FormReq.send(data);
      else {
         var rd = new FileReader();
         rd.readAsBinaryString(file);
         rd.onload = function() {
            FormReq.setRequestHeader("X-Pil", "*ContLen=");
            FormReq.sendAsBinary(data + "&*Drop=" +
               encodeURIComponent(file.name) + "=" +
               file.size + "\n" + rd.result );
         }
      }
   }
   catch (e) {
      FormReq.abort();
      return true;
   }
   return false;
}

/*** Hints ***/
function doHint(field) {
   if (HintReq) {
      if (!Hint) {
         Hint = document.createElement("div");
         Hint.setAttribute("class", "hint");
         Hint.style.visibility = "hidden";
         Hint.style.position = "absolute";
         Hints = document.createElement("div");
         Hints.setAttribute("class", "hints");
         Hints.style.position = "relative";
         Hints.style.top = "-2px";
         Hints.style.left = "-3px";
         Hint.appendChild(Hints);
      }
      field.parentNode.appendChild(Hint);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      var top = field.offsetHeight + 2;
      var left = 3;
      for (var obj = field;  obj.id != "main" && obj.id != "menu";  obj = obj.offsetParent) {
         top += obj.offsetTop;
         left += obj.offsetLeft;
      }
      Hint.style.top = top + "px";
      Hint.style.left = left + "px";
   }
}

function hintKey(field, event, tok, coy) {
   var i, data;

   if (!HintReq)
      return true;
   if (event.keyCode == 9 || event.keyCode == 27)
      return false;
   if (Hint.style.visibility == "visible") {
      if (Item >= 0 && event.keyCode == 13) {
         setHint(field, Hints.childNodes[Item]);
         return false;
      }
      if (event.keyCode == 38) {  // Up
         if (Item > 0) {
            hintOff(Item);
            hintOn(--Item);
         }
         return false;
      }
      if (event.keyCode == 40) {  // Down
         if (Item < (lst = Hints.childNodes).length-1) {
            if (Item >= 0)
               hintOff(Item);
            hintOn(++Item);
         }
         return false;
      }
   }
   if (event.keyCode == 13)
      return true;
   if (HintReq.readyState > 0 && HintReq.readyState < 4)
      return false;
   if (tok) {
      for (Beg = field.selectionStart;  Beg > 0 && !field.value.charAt(Beg-1).match(/\s/);  --Beg);
      End = field.selectionEnd;
   }
   else {
      Beg = 0;
      End = field.value.length;
   }
   if (event.keyCode != 45) {  // INS
      if (Beg == End) {
         Hint.style.visibility = "hidden";
         return false;
      }
      if (coy && Hint.style.visibility == "hidden")
         return false;
   }
   try {
      HintReq.open("POST",
         ((i = field.form.action.indexOf("~")) <= 0?  "" :
            field.form.action.substr(0, i+1) ) +
         ((i = field.id.lastIndexOf("-")) < 0?  "!jsHint?$" + field.id :
            "!jsHint?+" + field.id.substr(i+1) ) );
   }
   catch (e) {return true;}
   HintReq.onreadystatechange = function() {
      if (HintReq.readyState == 4 && HintReq.status == 200) {
         var i, n, lst, str;

         if ((str = HintReq.responseText).length == 0)
            Hint.style.visibility = "hidden";
         else {
            lst = str.split("&");
            while (Hints.hasChildNodes())
               Hints.removeChild(Hints.firstChild);
            for (i = 0, n = 7; i < lst.length; ++i) {
               addHint(i, field, str = decodeURIComponent(lst[i]));
               if (str.length > n)
                  n = str.length;
            }
            Hints.style.width = n + 3 + "ex";
            Hint.style.width = n + 4 + "ex";
            Hint.style.visibility = "visible";
            Item = -1;
         }
      }
   }
   var data = "*JsHint=" + encodeURIComponent(field.value.substring(Beg,End));
   for (i = 0; i < field.form.elements.length; ++i) {
      var fld = field.form.elements[i];

      if (fld.name == "*Get")
         data += "&*Get=" + fld.value;
      else if (fld.name == "*Form")
         data += "&*Form=" + fld.value;
   }
   try {HintReq.send(data);}
   catch (e) {HintReq.abort();}
   return (event.keyCode != 45);  // INS
}

function addHint(i, field, str) {
   var item = document.createElement("div");
   item.appendChild(document.createTextNode(str));
   item.onmouseover = function() {
      if (Item >= 0)
         hintOff(Item);
      hintOn(i);
      field.onblur = false;
      field.onchange = false;
      Item = i;
   }
   item.onmouseout = function() {
      hintOff(Item);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      field.onchange = function() {
         return fldChg(field, item);
      };
      Item = -1;
   }
   item.onclick = function() {
      setHint(field, item);
   }
   Hints.appendChild(item);
}

function setHint(field, item) {
   Hint.style.visibility = "hidden";
   field.value = field.value.substr(0,Beg) + item.firstChild.nodeValue + field.value.substr(End);
   post(field.form, null);
   field.setSelectionRange(Beg + item.firstChild.nodeValue.length, field.value.length);
   field.focus();
   field.onchange = function() {
      return fldChg(field)
   };
}

function hintOn(i) {
   var s = Hints.childNodes[i].style;
   s.background = "black";
   s.color= "white";
}

function hintOff(i) {
   var s = Hints.childNodes[i].style;
   s.background = "white";
   s.color= "black";
}
<commit_msg>Minor formatting<commit_after>/* 02dec11abu
 * (c) Software Lab. Alexander Burger
 */

var FormReq = false;
var HintReq = false;
var Hint, Hints, Item, Beg, End;

try {
   FormReq = new XMLHttpRequest();
   HintReq = new XMLHttpRequest();
   FormReq.upload.addEventListener("progress", dropProgress, false);
   FormReq.upload.addEventListener("load", dropLoad, false);
}
catch (e) {}

var Queue = new Array();
var Btn = new Array();
var Key, InBtn, Auto, Drop;

function inBtn(flg) {InBtn = flg;}

function formKey(event) {
   Key = event.keyCode;
   if (Hint  &&  Hint.style.visibility == "visible") {
      if ((Item >= 0 && Key == 13) || Key == 38 || Key == 40)
         return false;
      if (event.keyCode == 27) {
         Hint.style.visibility = "hidden";
         return false;
      }
   }
   return true;
}

function fldChg(field) {
   if (!InBtn && Key != 13)
      post(field.form, null);
   return true;
}

function doBtn(btn) {
   Btn.push(btn);
   return true;
}

function doDrag(event) {
   event.stopPropagation();
   event.preventDefault();
}

function doDrop(btn, event) {
   doDrag(event);
   if (event.dataTransfer.files.length != 0) {
      Btn.push(Drop = btn);
      btn.value = "0 %";
      post(btn.form, event.dataTransfer.files[0]);
   }
}

function dropProgress(event) {
   if (Drop)
      Drop.value = event.lengthComputable?
         Math.round((event.loaded * 100) / event.total) + " %" : "(?) %";
}

function dropLoad(event) {
   Drop = null;
}

function hasElement(form, name) {
   for (var i = 0; i < form.elements.length; ++i)
      if (form.elements[i].name == name)
         return true;
   return false;
}

/*** Form submit ***/
function doPost(form) {
   for (var i = 0; ; ++i) {
      if (i == Btn.length)
         return true;
      if (Btn[i].form == form)
         break;
   }
   return post(form, null);
}

function post(form, file) {
   var i;

   if (!FormReq || !hasElement(form,"*Get") || (i = form.action.indexOf("~")) <= 0)
      return true;
   if (FormReq.readyState > 0 && FormReq.readyState < 4) {
      Queue.push(form);
      return false;
   }
   form.style.cursor = "wait";
   try {FormReq.open("POST", form.action.substr(0,i) + "~!jsForm?" + form.action.substr(i+1));}
   catch (e) {return true;}
   FormReq.onreadystatechange = function() {
      if (FormReq.readyState == 4 && FormReq.status == 200) {
         var i, j;

         if (FormReq.responseText == "T") {
            Queue.length = 0;
            form.submit();
         }
         else {
            var txt = FormReq.responseText.split("&");

            if (txt[0]) {
               var r = txt[0].split(":");

               if (Auto)
                  window.clearTimeout(Auto);
               if (r[1])
                  Auto = window.setTimeout("document.getElementById(\"" + r[0] + "\").click()", r[1]);
            }
            for (i = 1; i < txt.length;) {
               var fld = txt[i++];
               var val = decodeURIComponent(txt[i++]);

               if (!fld) {
                  window[txt[i++]](val);
                  continue;
               }
               if (!(fld = document.getElementById(fld)))
                  continue;
               if (fld.tagName == "SPAN") {
                  if (i != txt.length && txt[i].charAt(0) == "=")
                     ++i;
                  if (i == txt.length || txt[i].charAt(0) != "+") {
                     if (fld.firstChild.tagName != "A")
                        fld.firstChild.data = val? val : "\u00A0";
                     else
                        fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
                  }
                  else {
                     var a = document.createElement("A");

                     a.href = decodeURIComponent(txt[i++].substr(1));
                     a.appendChild(document.createTextNode(val));
                     fld.replaceChild(a, fld.firstChild);
                  }
               }
               else if (fld.tagName == "A") {
                  if (i != txt.length && txt[i].charAt(0) == "=")
                     ++i;
                  if (i == txt.length || txt[i].charAt(0) != "+") {
                     fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
                     fld.removeAttribute("href");
                  }
                  else {
                     fld.firstChild.data = val;
                     fld.href = decodeURIComponent(txt[i++].substr(1));
                  }
               }
               else if (fld.tagName == "IMG")
                  fld.src = val;
               else {
                  if (fld.custom != null)
                     putCustom(fld.custom, val);
                  else if (fld.type == "checkbox") {
                     fld.checked = val != "";
                     document.getElementsByName(fld.name)[0].value = "";
                  }
                  else if (fld.type == "select-one") {
                     for (j = 0; j < fld.options.length; ++j) {
                        if (fld.options[j].text == val)
                           fld.selectedIndex = j;
                        fld.options[j].disabled = false;
                     }
                  }
                  else if (fld.type == "radio") {
                     fld.value = val;
                     fld.checked = txt[i++].charAt(0) != "";
                  }
                  else if (fld.type == "image")
                     fld.src = val;
                  else if (fld.value != val) {
                     fld.value = val;
                     fld.scrollTop = fld.scrollHeight;
                  }
                  fld.disabled = false;
                  if (i < txt.length && txt[i].charAt(0) == "=") {
                     if (fld.type == "select-one") {
                        for (j = 0; j < fld.options.length; ++j)
                           if (fld.options[j].text != val)
                              fld.options[j].disabled = true;
                     }
                     fld.disabled = true;
                     if (fld.type == "checkbox"  &&  fld.checked)
                        document.getElementsByName(fld.name)[0].value = "T";
                     ++i;
                  }
                  if (fld.custom != null)
                     ableCustom(fld.custom);
               }
               while (i < txt.length && (j = "#*?".indexOf(txt[i].charAt(0))) >= 0) {
                  switch (j) {

                  case 0:  // '#'
                     var cls;

                     val = txt[i++].substr(1);
                     if ((cls = fld.getAttribute("class")) != null  &&  (j = cls.indexOf(" ")) >= 0)
                        val += cls.substr(j);
                     fld.setAttribute("class", val);
                     break;

                  case 1:  // '*'
                     var node = fld.parentNode.parentNode.lastChild;
                     var img = document.createElement("IMG");

                     if (!node.firstChild)
                        node = fld.parentNode.parentNode.parentNode.lastChild;
                     node.removeChild(node.firstChild);
                     img.src = txt[i++].substr(1);
                     if (!txt[i])
                        node.appendChild(img);
                     else {
                        var a = document.createElement("A");

                        a.href = decodeURIComponent(txt[i]);
                        a.appendChild(img);
                        node.appendChild(a);
                     }
                     ++i;
                     break;

                  case 2:  // '?'
                     fld.title = decodeURIComponent(txt[i++].substr(1));
                     break;
                  }
               }
            }
         }
         form.style.cursor = "";
         if (Queue.length > 0)
            post(Queue.shift(), null);
      }
   }
   var data = "";
   for (var i = 0; i < Btn.length;)
      if (Btn[i].form != form)
         ++i;
      else {
         data += (data? "&":"") + Btn[i].name + "=" + encodeURIComponent(Btn[i].type == "submit"? Btn[i].value : Btn[i].src);
         Btn.splice(i,1);
      }
   for (i = 0; i < form.elements.length; ++i) {
      var fld = form.elements[i];

      if (fld.name  &&  fld.type != "submit") {   // "image" won't come :-(
         var val;

         if (fld.custom != null)
            val = getCustom(fld.custom);
         else if (fld.type == "checkbox")
            val = fld.checked? "T" : "";
         else if (fld.type == "select-one")
            val = fld.options[fld.selectedIndex].text;
         else if (fld.type == "radio" && !fld.checked)
            continue;
         else
            val = fld.value;
         data += "&" + fld.name + "=" + encodeURIComponent(val);
      }
   }
   try {
      if (!file)
         FormReq.send(data);
      else {
         var rd = new FileReader();
         rd.readAsBinaryString(file);
         rd.onload = function() {
            FormReq.setRequestHeader("X-Pil", "*ContLen=");
            FormReq.sendAsBinary(data + "&*Drop=" +
               encodeURIComponent(file.name) + "=" +
               file.size + "\n" + rd.result );
         }
      }
   }
   catch (e) {
      FormReq.abort();
      return true;
   }
   return false;
}

/*** Hints ***/
function doHint(field) {
   if (HintReq) {
      if (!Hint) {
         Hint = document.createElement("div");
         Hint.setAttribute("class", "hint");
         Hint.style.visibility = "hidden";
         Hint.style.position = "absolute";
         Hints = document.createElement("div");
         Hints.setAttribute("class", "hints");
         Hints.style.position = "relative";
         Hints.style.top = "-2px";
         Hints.style.left = "-3px";
         Hint.appendChild(Hints);
      }
      field.parentNode.appendChild(Hint);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      var top = field.offsetHeight + 2;
      var left = 3;
      for (var obj = field;  obj.id != "main" && obj.id != "menu";  obj = obj.offsetParent) {
         top += obj.offsetTop;
         left += obj.offsetLeft;
      }
      Hint.style.top = top + "px";
      Hint.style.left = left + "px";
   }
}

function hintKey(field, event, tok, coy) {
   var i, data;

   if (!HintReq)
      return true;
   if (event.keyCode == 9 || event.keyCode == 27)
      return false;
   if (Hint.style.visibility == "visible") {
      if (Item >= 0 && event.keyCode == 13) {
         setHint(field, Hints.childNodes[Item]);
         return false;
      }
      if (event.keyCode == 38) {  // Up
         if (Item > 0) {
            hintOff(Item);
            hintOn(--Item);
         }
         return false;
      }
      if (event.keyCode == 40) {  // Down
         if (Item < (lst = Hints.childNodes).length-1) {
            if (Item >= 0)
               hintOff(Item);
            hintOn(++Item);
         }
         return false;
      }
   }
   if (event.keyCode == 13)
      return true;
   if (HintReq.readyState > 0 && HintReq.readyState < 4)
      return false;
   if (tok) {
      for (Beg = field.selectionStart;  Beg > 0 && !field.value.charAt(Beg-1).match(/\s/);  --Beg);
      End = field.selectionEnd;
   }
   else {
      Beg = 0;
      End = field.value.length;
   }
   if (event.keyCode != 45) {  // INS
      if (Beg == End) {
         Hint.style.visibility = "hidden";
         return false;
      }
      if (coy && Hint.style.visibility == "hidden")
         return false;
   }
   try {
      HintReq.open("POST",
         ((i = field.form.action.indexOf("~")) <= 0?
            "" : field.form.action.substr(0, i+1) ) +
         ((i = field.id.lastIndexOf("-")) < 0?
            "!jsHint?$" + field.id : "!jsHint?+" + field.id.substr(i+1) ) );
   }
   catch (e) {return true;}
   HintReq.onreadystatechange = function() {
      if (HintReq.readyState == 4 && HintReq.status == 200) {
         var i, n, lst, str;

         if ((str = HintReq.responseText).length == 0)
            Hint.style.visibility = "hidden";
         else {
            lst = str.split("&");
            while (Hints.hasChildNodes())
               Hints.removeChild(Hints.firstChild);
            for (i = 0, n = 7; i < lst.length; ++i) {
               addHint(i, field, str = decodeURIComponent(lst[i]));
               if (str.length > n)
                  n = str.length;
            }
            Hints.style.width = n + 3 + "ex";
            Hint.style.width = n + 4 + "ex";
            Hint.style.visibility = "visible";
            Item = -1;
         }
      }
   }
   var data = "*JsHint=" + encodeURIComponent(field.value.substring(Beg,End));
   for (i = 0; i < field.form.elements.length; ++i) {
      var fld = field.form.elements[i];

      if (fld.name == "*Get")
         data += "&*Get=" + fld.value;
      else if (fld.name == "*Form")
         data += "&*Form=" + fld.value;
   }
   try {HintReq.send(data);}
   catch (e) {HintReq.abort();}
   return (event.keyCode != 45);  // INS
}

function addHint(i, field, str) {
   var item = document.createElement("div");
   item.appendChild(document.createTextNode(str));
   item.onmouseover = function() {
      if (Item >= 0)
         hintOff(Item);
      hintOn(i);
      field.onblur = false;
      field.onchange = false;
      Item = i;
   }
   item.onmouseout = function() {
      hintOff(Item);
      field.onblur = function() {
         Hint.style.visibility = "hidden";
      }
      field.onchange = function() {
         return fldChg(field, item);
      };
      Item = -1;
   }
   item.onclick = function() {
      setHint(field, item);
   }
   Hints.appendChild(item);
}

function setHint(field, item) {
   Hint.style.visibility = "hidden";
   field.value = field.value.substr(0,Beg) + item.firstChild.nodeValue + field.value.substr(End);
   post(field.form, null);
   field.setSelectionRange(Beg + item.firstChild.nodeValue.length, field.value.length);
   field.focus();
   field.onchange = function() {
      return fldChg(field)
   };
}

function hintOn(i) {
   var s = Hints.childNodes[i].style;
   s.background = "black";
   s.color= "white";
}

function hintOff(i) {
   var s = Hints.childNodes[i].style;
   s.background = "white";
   s.color= "black";
}
<|endoftext|>