<commit_before>// (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import CloseIcon from './icons/base/Close';
import KeyboardAccelerators from '../utils/KeyboardAccelerators';
import DOMUtils from '../utils/DOM';
import Button from './Button';
import Intl from '../utils/Intl';

const CLASS_ROOT = "layer";

class LayerContents extends Component {

  constructor() {
    super();

    this._processTab = this._processTab.bind(this);
  }

  getChildContext () {
    return {
      router: this.props.router,
      history: this.props.history,
      intl: this.props.intl,
      store: this.props.store
    };
  }

  componentDidMount () {

    var items = this.refs.container.getElementsByTagName('*');
    var firstFocusable = DOMUtils.getBestFirstFocusable(items);
    if (firstFocusable) {
      firstFocusable.focus();
    }

    if (this.props.onClose) {
      this._keyboardHandlers = {
        tab: this._processTab,
        esc: this.props.onClose
      };
      KeyboardAccelerators.startListeningToKeyboard(
        this, this._keyboardHandlers
      );
    }

    if (this.props.a11yCloserTitle) {
      console.log('a11yCloserTitle prop has been deprecated. Please use a11yTitle instead.');
    }
  }

  componentWillUnmount () {
    if (this.props.onClose) {
      KeyboardAccelerators.stopListeningToKeyboard(
        this, this._keyboardHandlers
      );
    }
  }

  _processTab (event) {
    var items = this.refs.container.getElementsByTagName('*');
    items = DOMUtils.filterByFocusable(items);

    if (!items || items.length === 0) {
      event.preventDefault();
    } else {
      if (event.shiftKey) {
        if (event.target === items[0]) {
          items[items.length - 1].focus();
          event.preventDefault();
        }
      } else if (event.target === items[items.length - 1]) {
        items[0].focus();
        event.preventDefault();
      }
    }
  }

  render () {
    var closer = null;
    if (this.props.closer) {
      //TODO: remove a11yCloserTitle after 0.6 release
      let closeLabel = Intl.getMessage(this.context.intl, 'Close');
      let layerLabel = Intl.getMessage(this.context.intl, 'Layer');
      let a11yTitle = this.props.a11yCloserTitle || (
        `${closeLabel} ${this.props.a11yTitle || ''} ${layerLabel}`
      );

      closer = (

          <Button plain={true} onClick={this.props.onClose}>
            <CloseIcon a11yTitle={a11yTitle} />
          </Button>

      );
    }

    return (

        {closer}
        {this.props.children}

    );
  }
}

LayerContents.propTypes = {
  //deprecated
  a11yCloserTitle: PropTypes.string,
  a11yTitle: PropTypes.string,
  closer: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.bool
  ]),
  history: PropTypes.object,
  intl: PropTypes.object,
  onClose: PropTypes.func,
  router: PropTypes.any
};

// Because Layer creates a new DOM render context, the context
// is not transfered. For now, we hard code these specific ones.
// TODO: Either figure out how to introspect the context and transfer
// whatever we find or have callers explicitly indicate which parts
// of the context to transfer somehow.
LayerContents.childContextTypes = {
  router: PropTypes.any,
  history: PropTypes.object,
  intl: PropTypes.object,
  store: PropTypes.object
};

export default class Layer extends Component {

  componentDidMount () {
    this._originalFocusedElement = document.activeElement;
    this._addLayer();
    this._renderLayer();
  }

  componentDidUpdate () {
    this._renderLayer();
  }

  componentWillUnmount () {

    if (this._originalFocusedElement) {
      this._originalFocusedElement.focus();
    }

    this._removeLayer();
  }

  _classesFromProps () {
    var classes = ['grommet', CLASS_ROOT];
    if (this.props.align) {
      classes.push(CLASS_ROOT + "--align-" + this.props.align);
    }
    if (this.props.flush) {
      classes.push(CLASS_ROOT + "--flush");
    }
    if (this.props.hidden) {
      classes.push(CLASS_ROOT + "--hidden");
    }
    if (this.props.peek) {
      classes.push(CLASS_ROOT + "--peek");
    }
    if (this.props.closer) {
      classes.push(CLASS_ROOT + "--closeable");
    }
    if (this.props.className) {
      classes.push(this.props.className);
    }
    return classes;
  }

  _addLayer () {
    var element = document.createElement('div');
    if (this.props.id) {
      element.id = this.props.id;
    }
    element.className = this._classesFromProps().join(' ');
    // insert before .app, if possible.
    var appElements = document.querySelectorAll('.app');
    var beforeElement;
    if (appElements.length > 0) {
      beforeElement = appElements[0];
    } else {
      beforeElement = document.body.firstChild;
    }
    this._element = beforeElement.parentNode.insertBefore(element, beforeElement);
  }

  _handleAriaHidden (hideOverlay) {
    this._element.setAttribute('aria-hidden', hideOverlay);
  }

  _renderLayer () {
    this._element.className = this._classesFromProps().join(' ');
    var contents = (
      <LayerContents {...this.props}
        router={this.context.router}
        history={this.context.history}
        intl={this.context.intl}
        store={this.context.store} />
    );
    ReactDOM.render(contents, this._element);
    this._handleAriaHidden(this.props.hidden);
  }

  _removeLayer () {
    this._element.removeEventListener('animationend', this._onAnimationEnd);
    this._handleAriaHidden(true);

    ReactDOM.unmountComponentAtNode(this._element);
    this._element.parentNode.removeChild(this._element);
    this._element = null;
  }

  render () {
    return ();
  }

}

Layer.propTypes = {
  align: PropTypes.oneOf(['center', 'top', 'bottom', 'left', 'right']),
  closer: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.bool
  ]),
  flush: PropTypes.bool,
  hidden: PropTypes.bool,
  peek: PropTypes.bool,
  onClose: PropTypes.func
};

Layer.contextTypes = {
  router: PropTypes.any,
  history: PropTypes.object,
  intl: PropTypes.object,
  store: PropTypes.object
};

Layer.defaultProps = {
  align: 'center'
};
<commit_msg>Fixes tabbing in Layer overlay content for when onClose prop is undefined.<commit_after>// (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import CloseIcon from './icons/base/Close';
import KeyboardAccelerators from '../utils/KeyboardAccelerators';
import DOMUtils from '../utils/DOM';
import Button from './Button';
import Intl from '../utils/Intl';

const CLASS_ROOT = "layer";

class LayerContents extends Component {

  constructor() {
    super();

    this._processTab = this._processTab.bind(this);
  }

  getChildContext () {
    return {
      router: this.props.router,
      history: this.props.history,
      intl: this.props.intl,
      store: this.props.store
    };
  }

  componentDidMount () {

    var items = this.refs.container.getElementsByTagName('*');
    var firstFocusable = DOMUtils.getBestFirstFocusable(items);
    if (firstFocusable) {
      firstFocusable.focus();
    }

    this._keyboardHandlers = {
      tab: this._processTab
    };

    if (this.props.onClose) {
      this._keyboardHandlers['esc'] = this.props.onClose;
    }

    KeyboardAccelerators.startListeningToKeyboard(
      this, this._keyboardHandlers
    );

    if (this.props.a11yCloserTitle) {
      console.log('a11yCloserTitle prop has been deprecated. Please use a11yTitle instead.');
    }
  }

  componentWillUnmount () {
    if (this.props.onClose) {
      KeyboardAccelerators.stopListeningToKeyboard(
        this, this._keyboardHandlers
      );
    }
  }

  _processTab (event) {
    var items = this.refs.container.getElementsByTagName('*');
    items = DOMUtils.filterByFocusable(items);

    if (!items || items.length === 0) {
      event.preventDefault();
    } else {
      if (event.shiftKey) {
        if (event.target === items[0]) {
          items[items.length - 1].focus();
          event.preventDefault();
        }
      } else if (event.target === items[items.length - 1]) {
        items[0].focus();
        event.preventDefault();
      }
    }
  }

  render () {
    var closer = null;
    if (this.props.onClose && this.props.closer) {
      //TODO: remove a11yCloserTitle after 0.6 release
      let closeLabel = Intl.getMessage(this.context.intl, 'Close');
      let layerLabel = Intl.getMessage(this.context.intl, 'Layer');
      let a11yTitle = this.props.a11yCloserTitle || (
        `${closeLabel} ${this.props.a11yTitle || ''} ${layerLabel}`
      );

      closer = (

          <Button plain={true} onClick={this.props.onClose}>
            <CloseIcon a11yTitle={a11yTitle} />
          </Button>

      );
    }

    return (

        {closer}
        {this.props.children}

    );
  }
}

LayerContents.propTypes = {
  //deprecated
  a11yCloserTitle: PropTypes.string,
  a11yTitle: PropTypes.string,
  closer: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.bool
  ]),
  history: PropTypes.object,
  intl: PropTypes.object,
  onClose: PropTypes.func,
  router: PropTypes.any
};

// Because Layer creates a new DOM render context, the context
// is not transfered. For now, we hard code these specific ones.
// TODO: Either figure out how to introspect the context and transfer
// whatever we find or have callers explicitly indicate which parts
// of the context to transfer somehow.
LayerContents.childContextTypes = {
  router: PropTypes.any,
  history: PropTypes.object,
  intl: PropTypes.object,
  store: PropTypes.object
};

export default class Layer extends Component {

  componentDidMount () {
    this._originalFocusedElement = document.activeElement;
    this._addLayer();
    this._renderLayer();
  }

  componentDidUpdate () {
    this._renderLayer();
  }

  componentWillUnmount () {

    if (this._originalFocusedElement) {
      this._originalFocusedElement.focus();
    }

    this._removeLayer();
  }

  _classesFromProps () {
    var classes = ['grommet', CLASS_ROOT];
    if (this.props.align) {
      classes.push(CLASS_ROOT + "--align-" + this.props.align);
    }
    if (this.props.flush) {
      classes.push(CLASS_ROOT + "--flush");
    }
    if (this.props.hidden) {
      classes.push(CLASS_ROOT + "--hidden");
    }
    if (this.props.peek) {
      classes.push(CLASS_ROOT + "--peek");
    }
    if (this.props.closer) {
      classes.push(CLASS_ROOT + "--closeable");
    }
    if (this.props.className) {
      classes.push(this.props.className);
    }
    return classes;
  }

  _addLayer () {
    var element = document.createElement('div');
    if (this.props.id) {
      element.id = this.props.id;
    }
    element.className = this._classesFromProps().join(' ');
    // insert before .app, if possible.
    var appElements = document.querySelectorAll('.app');
    var beforeElement;
    if (appElements.length > 0) {
      beforeElement = appElements[0];
    } else {
      beforeElement = document.body.firstChild;
    }
    this._element = beforeElement.parentNode.insertBefore(element, beforeElement);
  }

  _handleAriaHidden (hideOverlay) {
    this._element.setAttribute('aria-hidden', hideOverlay);
  }

  _renderLayer () {
    this._element.className = this._classesFromProps().join(' ');
    var contents = (
      <LayerContents {...this.props}
        router={this.context.router}
        history={this.context.history}
        intl={this.context.intl}
        store={this.context.store} />
    );
    ReactDOM.render(contents, this._element);
    this._handleAriaHidden(this.props.hidden);
  }

  _removeLayer () {
    this._element.removeEventListener('animationend', this._onAnimationEnd);
    this._handleAriaHidden(true);

    ReactDOM.unmountComponentAtNode(this._element);
    this._element.parentNode.removeChild(this._element);
    this._element = null;
  }

  render () {
    return ();
  }

}

Layer.propTypes = {
  align: PropTypes.oneOf(['center', 'top', 'bottom', 'left', 'right']),
  closer: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.bool
  ]),
  flush: PropTypes.bool,
  hidden: PropTypes.bool,
  peek: PropTypes.bool,
  onClose: PropTypes.func
};

Layer.contextTypes = {
  router: PropTypes.any,
  history: PropTypes.object,
  intl: PropTypes.object,
  store: PropTypes.object
};

Layer.defaultProps = {
  align: 'center'
};
<|endoftext|>


<commit_before>/**

  compiler.js

  Powerful compiler for script transpilation, templating and CSS preprocessing.

  As a note: we differentiate between "extensions" and "types". The extension
  is the actual file extension, whereas the type is the extension a file will
  be after processing.

**/

var Bundler     = require("./bundler"),
    express     = require("express"),
    Metadata    = require("./metadata"),
    Pipelines   = global.pipelines,
    Promise     = require("bluebird"),
    Utils       = require("./utils"),
    makeQuery   = Promise.promisify(global.db.queries);

//
//  Lookup where key is file path and value is array of routes. Used for route removal.
//

var lookup = {};

/**

  Extracts metadata from a file if appropriate (HTML-like)

  @param {Stat} file fs.Stat object representing file
  @param {String} [type] Type of file
  @returns {Object} Metadata

**/

function extractMetadata(file, type) {

  var metadata = {};

  if (Utils.isHTML(type)) {
    metadata = Metadata.extract(Utils.readFileHead(file.path, 500));
    metadata.isTemplate = Utils.isTemplate(file, type);
  }

  return metadata;

}

/**

  Creates a compiler for a file. For bundles, this means webpacking. Otherwise,
  uses the Pipelines engine.

  @param {Stat} file fs.Stat object representing file
  @param {String} [type] Type of file
  @returns {Function} Function that compiles a file

**/

function createCompiler(file, type) {
  if (file.bundle)
    return Bundler.fromFile(file, type).get;
  else
    return Promise.promisify(Pipelines.compileFile.bind(Pipelines, file.path));
}

/**

  Creates a route handler for a file

  @param {String} type Type of file
  @param {Function} compiler Function that compiles and returns promise
  @param {Object} [metadata] Extracted metadata
  @return {Function} Route handler of form (req, res)

**/

function createHandler(type, compiler, metadata) {

  var tasks = [compiler],
      key;

  // Add data query if necessary
  metadata = metadata || {};
  if (metadata.data) tasks.unshift(createQueryFn(metadata.data));

  return function(req, res, next) {

    var data = {};

    if (Utils.isHTML(type)) {

      // Data object will include locals, cookies, session, params, query, slug
      // and if applicable, database query results
      data = Object.assign(data, global.locals);

      // Attach special variables
      data.$cookies = req.cookies;
      data.$session = req.session;
      data.$params  = req.params;
      data.$query   = req.query;

      // Special slug
      if (metadata.isTemplate)
        data.$slug = req.url.replace(req.route.path.split(":")[0], "");

      // Set cookies
      for (key in metadata.cookies || {}) {
        res.cookie(key, metadata.cookies[key]);
        data.$cookies[key] = metadata.cookies[key];
      }

      // Set session
      for (key in metadata.session || {}) {
        req.session[key] = metadata.session[key];
        data.$session[key] = metadata.session[key];
      }

    }

    Utils.sequence(tasks, data)
    .then(res.type(type).send.bind(res))
    .catch(function(err) {
      if (/not found/i.test(err.message)) res.status(404);
      next(err);
    });

  };

}

/**

  Creates a function that runs Universql-style data queries.

  @param {Array} queries The queries to be run
  @returns {Function} Function that performs query and returns promise

**/

function createQueryFn(queries) {
  return function(context) {
    return makeQuery(queries, context).then(function(data) {
      return Promise.resolve(Object.assign(data, context));
    });
  };
}

/**

  Creates compilation pipeline for a file, and adds route handlers. Currently
  occurs in a single file given need for me
  @returns <Array> Array of directory strings to ignore (if exists)

**/

function addFile(router, route, file, type) {

  // Add to list of extensions if not present
  if (!Pipelines.hasPipeline(file.ext)) Pipelines.addPipeline(file.ext);

  var metadata = extractMetadata(file, type),
      compiler = createCompiler(file, type),
      handler  = createHandler(type, compiler, metadata);

  // Add routes to router
  Utils.makeRoutes(route, file, { type : type, params : metadata.params }).forEach(function(r) {

    // Store path in lookup (for later removal if necessary)
    // Note that this section could be removed in production
    lookup[file.path] = lookup[file.path] || [];

    if (-1 === lookup[file.path].indexOf(r)) {
      lookup[file.path].push(r);
      router.get(r, handler);
    }

  });

}

/**

  Removes routes from the router matching the regex.

  @param {Router} router The router to search
  @param {RegExp} re The pattern to match

**/

function removeRoutes(router, routes) {

  if (!router._router || !router._router.stack || !routes || !routes.length) return;

  var stack = router._router.stack,
      re = new RegExp("^(" + routes.map(Utils.escapeRegex).join("|") + ")$");

  // Express keeps routes as a stack in _router.stack. Note that this section
  // is not part of the official API and thus subject to change
  for (var i = stack.length - 1; i >= 0; i--)
    if (stack[i].route && re.test(stack[i].route.path))
      stack.splice(i, 1);

}

/**

  Creates compilation pipelines for files and add route handlers.

  @param {String} options.exts The default file extension to apply
  @param {String} options.path Directory to process
  @param {String} options.url Base url to route from: url structure = base + directory structure
  @param {Boolean} [options.bundleFolders] If true, applies folder bundling
  @param {Boolean} [options.recursive] If true, processes the directory recursively (default: true)
  @returns {Router} An express-style router

**/

module.exports = function(options) {

  var router  = express(),
      ignored = [],
      type    = Array.isArray(options.exts) ? options.exts[0] : options.exts,
      exts    = {},
      files;

  // Since we can have multiple exts, we attach the type to the options object
  options.type = type;
  files = Utils.mapFiles(options.path, options),

  files.forEach(function(file) {

    // Handle the file
    addFile(router, options.url, file, type);

    // Add to extension watch list
    exts[file.ext] = 1;

    // Remove ignored directories from watch list
    if (file.ignored) ignored = ignored.concat(file.ignored);

  });

  for (var key in exts)
    Utils.watch(options.path, key, {
      chokidar: {
        ignoreInitial : true,
        ignored: ignored,
        type: type,
      },
      add: function(file, compiled) {
        addFile(router, options.url, Utils.parse(file, options.path), type);
      },
      change: function(file, compiled) {
        global.server.reload(compiled);
      },
      unlink: function(file, compiled) {
        removeRoutes(router, lookup[file]);
        delete lookup[file];
      }
    });

  return router;

};
<commit_msg>compiler: removes extension watch list (allows any file to be added on demand)<commit_after>/**

  compiler.js

  Powerful compiler for script transpilation, templating and CSS preprocessing.

  As a note: we differentiate between "extensions" and "types". The extension
  is the actual file extension, whereas the type is the extension a file will
  be after processing.

**/

var Bundler     = require("./bundler"),
    express     = require("express"),
    Metadata    = require("./metadata"),
    Pipelines   = global.pipelines,
    Promise     = require("bluebird"),
    Utils       = require("./utils"),
    makeQuery   = Promise.promisify(global.db.queries);

//
//  Lookup where key is file path and value is array of routes. Used for route removal.
//

var lookup = {};

/**

  Extracts metadata from a file if appropriate (HTML-like)

  @param {Stat} file fs.Stat object representing file
  @param {String} [type] Type of file
  @returns {Object} Metadata

**/

function extractMetadata(file, type) {

  var metadata = {};

  if (Utils.isHTML(type)) {
    metadata = Metadata.extract(Utils.readFileHead(file.path, 500));
    metadata.isTemplate = Utils.isTemplate(file, type);
  }

  return metadata;

}

/**

  Creates a compiler for a file. For bundles, this means webpacking. Otherwise,
  uses the Pipelines engine.

  @param {Stat} file fs.Stat object representing file
  @param {String} [type] Type of file
  @returns {Function} Function that compiles a file

**/

function createCompiler(file, type) {
  if (file.bundle)
    return Bundler.fromFile(file, type).get;
  else
    return Promise.promisify(Pipelines.compileFile.bind(Pipelines, file.path));
}

/**

  Creates a route handler for a file

  @param {String} type Type of file
  @param {Function} compiler Function that compiles and returns promise
  @param {Object} [metadata] Extracted metadata
  @return {Function} Route handler of form (req, res)

**/

function createHandler(type, compiler, metadata) {

  var tasks = [compiler],
      key;

  // Add data query if necessary
  metadata = metadata || {};
  if (metadata.data) tasks.unshift(createQueryFn(metadata.data));

  return function(req, res, next) {

    var data = {};

    if (Utils.isHTML(type)) {

      // Data object will include locals, cookies, session, params, query, slug
      // and if applicable, database query results
      data = Object.assign(data, global.locals);

      // Attach special variables
      data.$cookies = req.cookies;
      data.$session = req.session;
      data.$params  = req.params;
      data.$query   = req.query;

      // Special slug
      if (metadata.isTemplate)
        data.$slug = req.url.replace(req.route.path.split(":")[0], "");

      // Set cookies
      for (key in metadata.cookies || {}) {
        res.cookie(key, metadata.cookies[key]);
        data.$cookies[key] = metadata.cookies[key];
      }

      // Set session
      for (key in metadata.session || {}) {
        req.session[key] = metadata.session[key];
        data.$session[key] = metadata.session[key];
      }

    }

    Utils.sequence(tasks, data)
    .then(res.type(type).send.bind(res))
    .catch(function(err) {
      if (/not found/i.test(err.message)) res.status(404);
      next(err);
    });

  };

}

/**

  Creates a function that runs Universql-style data queries.

  @param {Array} queries The queries to be run
  @returns {Function} Function that performs query and returns promise

**/

function createQueryFn(queries) {
  return function(context) {
    return makeQuery(queries, context).then(function(data) {
      return Promise.resolve(Object.assign(data, context));
    });
  };
}

/**

  Creates compilation pipeline for a file, and adds route handlers. Currently
  occurs in a single file given need for me
  @returns <Array> Array of directory strings to ignore (if exists)

**/

function addFile(router, route, file, type) {

  // Add to list of extensions if not present
  if (!Pipelines.hasPipeline(file.ext)) Pipelines.addPipeline(file.ext);

  var metadata = extractMetadata(file, type),
      compiler = createCompiler(file, type),
      handler  = createHandler(type, compiler, metadata);

  // Add routes to router
  Utils.makeRoutes(route, file, { type : type, params : metadata.params }).forEach(function(r) {

    // Store path in lookup (for later removal if necessary)
    // Note that this section could be removed in production
    lookup[file.path] = lookup[file.path] || [];

    if (-1 === lookup[file.path].indexOf(r)) {
      lookup[file.path].push(r);
      router.get(r, handler);
    }

  });

}

/**

  Removes routes from the router matching the regex.

  @param {Router} router The router to search
  @param {RegExp} re The pattern to match

**/

function removeRoutes(router, routes) {

  if (!router._router || !router._router.stack || !routes || !routes.length) return;

  var stack = router._router.stack,
      re = new RegExp("^(" + routes.map(Utils.escapeRegex).join("|") + ")$");

  // Express keeps routes as a stack in _router.stack. Note that this section
  // is not part of the official API and thus subject to change
  for (var i = stack.length - 1; i >= 0; i--)
    if (stack[i].route && re.test(stack[i].route.path))
      stack.splice(i, 1);

}

/**

  Creates compilation pipelines for files and add route handlers.

  @param {String} options.exts The default file extension to apply
  @param {String} options.path Directory to process
  @param {String} options.url Base url to route from: url structure = base + directory structure
  @param {Boolean} [options.bundleFolders] If true, applies folder bundling
  @param {Boolean} [options.recursive] If true, processes the directory recursively (default: true)
  @returns {Router} An express-style router

**/

module.exports = function(options) {

  var router  = express(),
      ignored = [],
      type    = Array.isArray(options.exts) ? options.exts[0] : options.exts,
      files;

  // Since we can have multiple exts, we attach the type to the options object
  options.type = type;
  files = Utils.mapFiles(options.path, options),

  files.forEach(function(file) {

    // Handle the file
    addFile(router, options.url, file, type);

    // Remove ignored directories from watch list
    if (file.ignored) ignored = ignored.concat(file.ignored);

  });

  Utils.watch(options.path, "*", {
    chokidar: {
      ignoreInitial : true,
      ignored: ignored,
      type: type,
    },
    add: function(file, compiled) {
      console.log(file, compiled);
      addFile(router, options.url, Utils.parse(file, options.path), type);
    },
    change: function(file, compiled) {
      global.server.reload(compiled);
    },
    unlink: function(file, compiled) {
      removeRoutes(router, lookup[file]);
      delete lookup[file];
    }
  });

  return router;

};
<|endoftext|>


<commit_before>/**
 * Created by lz on 15/10/13.
 */
!function (factory) {
    if (typeof define === "function") {
        define("prefix", factory);
    } else {
        factory();
    }
}(function () {
    function getPrefixURL() {
        var links = document.getElementsByTagName("link"),
            prefixLinks = [],
            i,
            l;

        for (i = 0, l = links.length; i < l; i++) {
            if (links[i].getAttribute("rel") === "stylesheet/prefix") {
                prefixLinks.push(links[i].href);
            }
        }

        return prefixLinks;
    }

    function getPrefixFile() {
        var urls = getPrefixURL(),
            i,
            l;

        for (i = 0, l = urls.length; i < l; i++) {
            doXHR(urls[i], function (data) {
                if(data){
                    findAttrs(data);
                }
            });
        }
    }

    function getXMLHttpRequest() {
        if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject)) {
            return new XMLHttpRequest();
        } else {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                console.log("browser doesn't support AJAX.");
                return null;
            }
        }
    }

    function doXHR(url, callback, errback) {
        var xhr = getXMLHttpRequest();

        if (typeof(xhr.overrideMimeType) === 'function') {
            xhr.overrideMimeType('text/css');
        }

        xhr.open('GET', url, true);
        xhr.setRequestHeader('Accept', 'text/css; q=0.9, */*; q=0.5');
        xhr.send(null);

        function handleResponse(xhr, callback, errback) {
            if (xhr.status >= 200 && xhr.status < 300) {
                callback(xhr.responseText,
                    xhr.getResponseHeader("Last-Modified"));
            } else if (typeof(errback) === 'function') {
                errback(xhr.status, url);
            }
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                handleResponse(xhr, callback, errback);
            }
        };
    }

    function findAttrs(data){
        var pattern = new RegExp("[^{};\\s].*?(?=;)","igm"),
            result;

        data = data.replace(pattern,function(word){
            result = word.split(":");
            if(!CSS.supports(result[0],result[1])){
                return "current_attr: " + result[1];
            }else{
                return word;
            }
        });
        console.log(data);
    }

    getPrefixFile();
});<commit_msg>remove some limites in pattern<commit_after>/**
 * Created by lz on 15/10/13.
 */
!function (factory) {
    if (typeof define === "function") {
        define("prefix", factory);
    } else {
        factory();
    }
}(function () {
    function getPrefixURL() {
        var links = document.getElementsByTagName("link"),
            prefixLinks = [],
            i,
            l;

        for (i = 0, l = links.length; i < l; i++) {
            if (links[i].getAttribute("rel") === "stylesheet/prefix") {
                prefixLinks.push(links[i].href);
            }
        }

        return prefixLinks;
    }

    function getPrefixFile() {
        var urls = getPrefixURL(),
            i,
            l;

        for (i = 0, l = urls.length; i < l; i++) {
            doXHR(urls[i], function (data) {
                if(data){
                    findAttrs(data);
                }
            });
        }
    }

    function getXMLHttpRequest() {
        if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject)) {
            return new XMLHttpRequest();
        } else {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                console.log("browser doesn't support AJAX.");
                return null;
            }
        }
    }

    function doXHR(url, callback, errback) {
        var xhr = getXMLHttpRequest();

        if (typeof(xhr.overrideMimeType) === 'function') {
            xhr.overrideMimeType('text/css');
        }

        xhr.open('GET', url, true);
        xhr.setRequestHeader('Accept', 'text/css; q=0.9, */*; q=0.5');
        xhr.send(null);

        function handleResponse(xhr, callback, errback) {
            if (xhr.status >= 200 && xhr.status < 300) {
                callback(xhr.responseText,
                    xhr.getResponseHeader("Last-Modified"));
            } else if (typeof(errback) === 'function') {
                errback(xhr.status, url);
            }
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                handleResponse(xhr, callback, errback);
            }
        };
    }

    function findAttrs(data){
        var pattern = new RegExp("[^{};\\s].*?(?=;)","g"),
            result;

        data = data.replace(pattern,function(word){
            result = word.split(":");
            if(!CSS.supports(result[0],result[1])){
                return "current_attr: " + result[1];
            }else{
                return word;
            }
        });
        console.log(data);
    }

    getPrefixFile();
});<|endoftext|>


<commit_before>var Query   = require("./query")
  , Utils   = require("../../utils")

module.exports = (function() {
  var ConnectorManager = function(sequelize, config) {
    var pgModule = config.dialectModulePath || 'pg'

    this.sequelize = sequelize
    this.client         = null
    this.config         = config || {}
    this.config.port    = this.config.port || 5432
    this.pooling        = (!!this.config.pool && (this.config.pool.maxConnections > 0))
    this.pg             = this.config.native ? require(pgModule).native : require(pgModule)
    this.poolIdentifier = null

    // Better support for BigInts
    // https://github.com/brianc/node-postgres/issues/166#issuecomment-9514935
    this.pg.types.setTypeParser(20, String);

    // set pooling parameters if specified
    if (this.pooling) {
      this.pg.defaults.poolSize        = this.config.pool.maxConnections
      this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime
    }

    this.disconnectTimeoutId = null
    this.pendingQueries = 0
    this.maxConcurrentQueries = (this.config.maxConcurrentQueries || 50)

    process.on('exit', function() {
      this.disconnect()
    }.bind(this))
  }
  Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype)

  ConnectorManager.prototype.endQuery = function() {
    var self = this

    self.pendingQueries--

    if (!self.pooling && self.pendingQueries === 0) {
      setTimeout(function() {
        self.pendingQueries === 0 && self.disconnect.call(self)
      }, 100)
    }
  }

  ConnectorManager.prototype.query = function(sql, callee, options) {
    var self = this

    self.pendingQueries++

    return new Utils.CustomEventEmitter(function(emitter) {
      self.connect()
      .on('error', function(err) {
        emitter.emit('error', err)
      })
      .on('success', function(done) {
        var query = new Query(self.client, self.sequelize, callee, options || {})
        done = done || null

        return query.run(sql, done)
          .success(function(results) { self.endQuery.call(self) })
          .error(function(err) { self.endQuery.call(self) })
          .proxy(emitter)
      })
    }).run()
  }

  ConnectorManager.prototype.connect = function(callback) {
    var self = this
    var emitter = new (require('events').EventEmitter)()

    // in case database is slow to connect, prevent orphaning the client
    if (this.isConnecting && !this.pooling) {
      emitter.emit('success')
      return emitter
    }

    this.isConnecting = true
    this.isConnected  = false

    var uri = this.sequelize.getQueryInterface().QueryGenerator.databaseConnectionUri(this.config)

    var connectCallback = function(err, client, done) {
      self.isConnecting = false

      if (!!err) {
        // release the pool immediately, very important.
        done && done(err)

        if (err.code) {
          switch(err.code) {
          case 'ECONNREFUSED':
            emitter.emit('error', new Error("Failed to authenticate for PostgresSQL. Please double check your settings."))
            break
          case 'ENOTFOUND':
          case 'EHOSTUNREACH':
          case 'EINVAL':
            emitter.emit('error', new Error("Failed to find PostgresSQL server. Please double check your settings."))
            break
          default:
            emitter.emit('error', err)
            break
          }
        }
      } else if (client) {
        client.query("SET TIME ZONE 'UTC'").on('end', function() {
          self.isConnected = true
          self.client = client
          emitter.emit('success', done)
        })
      } else {
        self.client = null
        emitter.emit('success', done)
      }
    }

    if (this.pooling) {
      // acquire client from pool
      this.poolIdentifier = this.pg.pools.getOrCreate(this.sequelize.config)
      this.poolIdentifier.connect(connectCallback)
    } else {
      if (!!this.client) {
        connectCallback(null, this.client);
      } else {
        //create one-off client
        this.client = new this.pg.Client(uri)
        this.client.connect(connectCallback)
      }
    }

    return emitter
  }

  ConnectorManager.prototype.disconnect = function() {
    if (this.poolIdentifier) {
      this.poolIdentifier.destroyAllNow()
    }

    if (this.client) {
      this.client.end()
    }

    this.client = null
    this.isConnecting = false
    this.isConnected  = false
  }

  return ConnectorManager
})()<commit_msg>Postgres connector manager should now be able agnostic as to whether or not you have an environment variable called USER. Closes #819<commit_after>var Query   = require("./query")
  , Utils   = require("../../utils")

module.exports = (function() {
  var ConnectorManager = function(sequelize, config) {
    var pgModule = config.dialectModulePath || 'pg'

    this.sequelize = sequelize
    this.client         = null
    this.config         = config || {}
    this.config.port    = this.config.port || 5432
    this.pooling        = (!!this.config.pool && (this.config.pool.maxConnections > 0))
    this.pg             = this.config.native ? require(pgModule).native : require(pgModule)
    this.poolIdentifier = null

    // Better support for BigInts
    // https://github.com/brianc/node-postgres/issues/166#issuecomment-9514935
    this.pg.types.setTypeParser(20, String);

    // set pooling parameters if specified
    if (this.pooling) {
      this.pg.defaults.poolSize        = this.config.pool.maxConnections
      this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime
    }

    this.disconnectTimeoutId = null
    this.pendingQueries = 0
    this.maxConcurrentQueries = (this.config.maxConcurrentQueries || 50)

    process.on('exit', function() {
      this.disconnect()
    }.bind(this))
  }
  Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype)

  ConnectorManager.prototype.endQuery = function() {
    var self = this

    self.pendingQueries--

    if (!self.pooling && self.pendingQueries === 0) {
      setTimeout(function() {
        self.pendingQueries === 0 && self.disconnect.call(self)
      }, 100)
    }
  }

  ConnectorManager.prototype.query = function(sql, callee, options) {
    var self = this

    self.pendingQueries++

    return new Utils.CustomEventEmitter(function(emitter) {
      self.connect()
      .on('error', function(err) {
        emitter.emit('error', err)
      })
      .on('success', function(done) {
        var query = new Query(self.client, self.sequelize, callee, options || {})
        done = done || null

        return query.run(sql, done)
          .success(function(results) { self.endQuery.call(self) })
          .error(function(err) { self.endQuery.call(self) })
          .proxy(emitter)
      })
    }).run()
  }

  ConnectorManager.prototype.connect = function(callback) {
    var self = this
    var emitter = new (require('events').EventEmitter)()

    // in case database is slow to connect, prevent orphaning the client
    if (this.isConnecting && !this.pooling) {
      emitter.emit('success')
      return emitter
    }

    this.isConnecting = true
    this.isConnected  = false

    var uri = this.sequelize.getQueryInterface().QueryGenerator.databaseConnectionUri(this.config)

    var connectCallback = function(err, client, done) {
      self.isConnecting = false

      if (!!err) {
        // release the pool immediately, very important.
        done && done(err)

        if (err.code) {
          switch(err.code) {
          case 'ECONNREFUSED':
            emitter.emit('error', new Error("Failed to authenticate for PostgresSQL. Please double check your settings."))
            break
          case 'ENOTFOUND':
          case 'EHOSTUNREACH':
          case 'EINVAL':
            emitter.emit('error', new Error("Failed to find PostgresSQL server. Please double check your settings."))
            break
          default:
            emitter.emit('error', err)
            break
          }
        }
      } else if (client) {
        client.query("SET TIME ZONE 'UTC'").on('end', function() {
          self.isConnected = true
          self.client = client
          emitter.emit('success', done)
        })
      } else {
        self.client = null
        emitter.emit('success', done)
      }
    }

    if (this.pooling) {
      // acquire client from pool
      this.poolIdentifier = this.pg.pools.getOrCreate(uri)
      this.poolIdentifier.connect(connectCallback)
    } else {
      if (!!this.client) {
        connectCallback(null, this.client);
      } else {
        //create one-off client
        this.client = new this.pg.Client(uri)
        this.client.connect(connectCallback)
      }
    }

    return emitter
  }

  ConnectorManager.prototype.disconnect = function() {
    if (this.poolIdentifier) {
      this.poolIdentifier.destroyAllNow()
    }

    if (this.client) {
      this.client.end()
    }

    this.client = null
    this.isConnecting = false
    this.isConnected  = false
  }

  return ConnectorManager
})()<|endoftext|>


<commit_before>"use strict";

function test() {
    test.prototype.doit = function () {
        alert('here')
    }
}

var t = new test();
t.doit();
<commit_msg>implement logicalValue<commit_after>"use strict";

function logicalValue()
{
    this.value = null;
    // valueの値がHかLならそのまま返します。それ以外ならハイインピーダンス(Z)を返します。
    logicalValue.prototype.toString = function () {
        if (this.value == "H" || this.value == "L") return this.value;
        return "Z";
    }
}

var t = new logicalValue();
t.value = "L";
alert(t.toString());
<|endoftext|>


<commit_before>/* @flow */

import Rule from '../Rule'

import type { Command, Message } from '../types'

const WRAPPED_LINE_PATTERN = /^.{76}[^.]{3}$/

export default class ParseLaTeXLog extends Rule {
  static parameterTypes: Array<Set<string>> = [new Set(['LaTeXLog'])]
  static commands: Set<Command> = new Set(['build', 'log'])
  static description: string = 'Parses the logs produced by all latex variants.'

  async run () {
    const output = await this.getResolvedOutput('$DIR/$BASE-ParsedLaTeXLog', this.firstParameter)
    if (!output) return false

    const messages: Array<Message> = []
    const outputs: Array<string> = []
    let name: string
    let filePath: string

    await this.firstParameter.parse([{
      names: ['filePath'],
      patterns: [/^\*\*([^*]+)$/],
      evaluate: (reference, groups) => {
        // Don't let subsequent lines overwrite the first.
        if (!filePath) {
          filePath = this.normalizePath(groups.filePath)
        }
      }
    }, {
      names: ['name'],
      patterns: [/^This is (.*),/],
      evaluate: (reference, groups) => {
        name = groups.name
      }
    }, {
      names: ['text'],
      patterns: [/^Package: (.*)$/i],
      evaluate: (reference, groups) => {
        messages.push({
          name,
          severity: 'info',
          text: groups.text,
          source: { file: filePath },
          log: reference
        })
      }
    }, {
      names: ['category', 'text'],
      patterns: [/^! (.+) Error: (.+?)\.?$/i],
      evaluate: (reference, groups) => {
        messages.push({
          severity: 'error',
          name,
          category: groups.category,
          text: groups.text,
          source: { file: filePath },
          log: reference
        })
      }
    }, {
      names: ['file', 'line', 'category', 'text'],
      patterns: [/^(\S.*):(\d+): (?:(.+) Error: )?(.+?)\.?$/i],
      evaluate: (reference, groups) => {
        const line: number = parseInt(groups.line, 10)
        const message: Message = {
          severity: 'error',
          name,
          text: groups.text,
          log: reference,
          source: {
            file: this.normalizePath(groups.file),
            range: { start: line, end: line }
          }
        }

        if (groups.category) message.category = groups.category

        messages.push(message)
      }
    }, {
      names: ['category', 'severity', 'text', 'line'],
      patterns: [/^(.+) (Warning|Info): +(.*?)(?: on input line (\d+)\.)?$/i],
      evaluate: (reference, groups) => {
        const message: Message = {
          severity: groups.severity.toLowerCase() === 'info' ? 'info' : 'warning',
          name,
          category: groups.category,
          text: groups.text,
          source: { file: filePath },
          log: reference
        }

        if (groups.line) {
          const line: number = parseInt(groups.line, 10)

          message.source = {
            file: filePath,
            range: { start: line, end: line }
          }
        }

        messages.push(message)
      }
    }, {
      names: ['package', 'text', 'line'],
      patterns: [/^\(([^()]+)\) +(.*?)(?: on input line (\d+)\.?)?$/],
      evaluate: (reference, groups) => {
        const message: Message = messages[messages.length - 1]
        if (message && message.category && message.category.endsWith(groups.package)) {
          message.text = `${message.text} ${groups.text}`
          if (message.log && message.log.range && reference.range) message.log.range.end = reference.range.end
          if (groups.line) {
            const line: number = parseInt(groups.line, 10)

            message.text = `${message.text}.`
            message.source = {
              file: filePath,
              range: { start: line, end: line }
            }
          }
        }
      }
    }, {
      // LaTeX3 error messages when -file-line-error is on
      names: ['file', 'line', 'category', 'text'],
      patterns: [
        /^!{48,50}$/,
        /^!$/,
        /^(.*):(\d+): (?:(.+) error: )?(.+?)\.?$/
      ],
      evaluate: (reference, groups) => {
        const line: number = parseInt(groups.line, 10)
        const message: Message = {
          severity: 'error',
          name,
          category: groups.category,
          source: {
            file: this.normalizePath(groups.file),
            range: { start: line, end: line }
          },
          text: groups.text,
          log: reference
        }

        messages.push(message)
      }
    }, {
      // LaTeX3 messages
      names: ['category', 'severity', 'text'],
      patterns: [
        /^[.*!]{48,50}$/,
        /^[.*!] (.*?) (info|warning|error): ("[^"]*")$/
      ],
      evaluate: (reference, groups) => {
        const message: Message = {
          severity: groups.severity.toLowerCase() === 'info' ? 'info' : 'warning',
          name,
          category: groups.category,
          source: { file: filePath },
          text: groups.text,
          log: reference
        }

        messages.push(message)
      }
    }, {
      // LaTeX3 continued message
      names: ['text', 'line'],
      patterns: [/^[.*!] (.*?)(?: on line (\d+)\.?)?$/],
      evaluate: (reference, groups) => {
        const message: Message = messages[messages.length - 1]
        if (message) {
          if (groups.text !== 'Type <return> to continue.') {
            message.text = `${message.text} ${groups.text.trim() || '\n'}`
          }
          if (message.log && message.log.range && reference.range) message.log.range.end = reference.range.end
          if (groups.line) {
            const line: number = parseInt(groups.line, 10)

            message.text = `${message.text}.`
            message.source = {
              file: filePath,
              range: { start: line, end: line }
            }
          }
        }
      }
    }, {
      // End of LaTeX3 message
      names: [],
      patterns: [/^[.*!]{48,50} *$/],
      evaluate: (reference, groups) => {
        const message: Message = messages[messages.length - 1]
        if (message && message.log && message.log.range && reference.range) {
          message.log.range.end = reference.range.end
        }
      }
    }, {
      names: ['text'],
      patterns: [/^(No file .*\.)$/],
      evaluate: (reference, groups) => {
        messages.push({
          severity: 'warning',
          name,
          text: groups.text,
          log: reference
        })
      }
    }, {
      names: ['filePath'],
      patterns: [/^Output written on "?([^"]+)"? \([^)]*\)\.$/],
      evaluate: (reference, groups) => {
        outputs.push(this.normalizePath(groups.filePath))
      }
    }], line => WRAPPED_LINE_PATTERN.test(line))

    for (const message of messages) {
      message.text = message.text.trim().replace(/ *\n+ */g, '\n').replace(/ +/g, ' ')
    }

    output.value = { outputs, messages }

    return true
  }
}
<commit_msg>Add more comments<commit_after>/* @flow */

import Rule from '../Rule'

import type { Command, Message } from '../types'

const WRAPPED_LINE_PATTERN = /^.{76}[^.]{3}$/

export default class ParseLaTeXLog extends Rule {
  static parameterTypes: Array<Set<string>> = [new Set(['LaTeXLog'])]
  static commands: Set<Command> = new Set(['build', 'log'])
  static description: string = 'Parses the logs produced by all latex variants.'

  /**
   * Parse the latex log.
   * @return {Promise<boolean>}  Status of rule evaluation
   */
  async run (): Promise<boolean> {
    // Get the output file
    const output = await this.getResolvedOutput('$DIR/$BASE-ParsedLaTeXLog', this.firstParameter)
    if (!output) return false

    const messages: Array<Message> = []
    const outputs: Array<string> = []
    let name: string
    let filePath: string

    await this.firstParameter.parse([{
      // Input file name
      names: ['filePath'],
      patterns: [/^\*\*([^*]+)$/],
      evaluate: (reference, groups) => {
        // Don't let subsequent lines overwrite the first.
        if (!filePath) {
          filePath = this.normalizePath(groups.filePath)
        }
      }
    }, {
      // Program identifier
      names: ['name'],
      patterns: [/^This is (.*),/],
      evaluate: (reference, groups) => {
        name = groups.name
      }
    }, {
      // Package info message
      names: ['text'],
      patterns: [/^Package: (.*)$/i],
      evaluate: (reference, groups) => {
        messages.push({
          name,
          severity: 'info',
          text: groups.text,
          source: { file: filePath },
          log: reference
        })
      }
    }, {
      // Error messages when -file-line-error is off or no file reference is
      // included.
      names: ['category', 'text'],
      patterns: [/^! (.+) Error: (.+?)\.?$/i],
      evaluate: (reference, groups) => {
        messages.push({
          severity: 'error',
          name,
          category: groups.category,
          text: groups.text,
          source: { file: filePath },
          log: reference
        })
      }
    }, {
      // Error messages when -file-line-error is on and file reference is
      // available.
      names: ['file', 'line', 'category', 'text'],
      patterns: [/^(\S.*):(\d+): (?:(.+) Error: )?(.+?)\.?$/i],
      evaluate: (reference, groups) => {
        const line: number = parseInt(groups.line, 10)
        const message: Message = {
          severity: 'error',
          name,
          text: groups.text,
          log: reference,
          source: {
            file: this.normalizePath(groups.file),
            range: { start: line, end: line }
          }
        }

        if (groups.category) message.category = groups.category

        messages.push(message)
      }
    }, {
      // Warning/Info messages, possibly with a line reference.
      names: ['category', 'severity', 'text', 'line'],
      patterns: [/^(.+) (Warning|Info): +(.*?)(?: on input line (\d+)\.)?$/i],
      evaluate: (reference, groups) => {
        const message: Message = {
          severity: groups.severity.toLowerCase(),
          name,
          category: groups.category,
          text: groups.text,
          source: { file: filePath },
          log: reference
        }

        // There is a line reference so add it to the message.
        if (groups.line) {
          const line: number = parseInt(groups.line, 10)

          message.source = {
            file: filePath,
            range: { start: line, end: line }
          }
        }

        messages.push(message)
      }
    }, {
      // Continuation of message with possible file reference.
      names: ['package', 'text', 'line'],
      patterns: [/^\(([^()]+)\) +(.*?)(?: on input line (\d+)\.?)?$/],
      evaluate: (reference, groups) => {
        const message: Message = messages[messages.length - 1]
        // Verify that the previous message matches the category.
        if (message && message.category && message.category.endsWith(groups.package)) {
          message.text = `${message.text} ${groups.text}`
          // If the previous message has a log reference then extend it.
          if (message.log && message.log.range && reference.range) {
            message.log.range.end = reference.range.end
          }
          // If there is a line reference then add it the the message.
          if (groups.line) {
            const line: number = parseInt(groups.line, 10)

            message.text = `${message.text}.`
            message.source = {
              file: filePath,
              range: { start: line, end: line }
            }
          }
        }
      }
    }, {
      // LaTeX3 error messages when -file-line-error is on
      names: ['file', 'line', 'category', 'text'],
      patterns: [
        /^!{48,50}$/,
        /^!$/,
        /^(.*):(\d+): (?:(.+) error: )?(.+?)\.?$/
      ],
      evaluate: (reference, groups) => {
        const line: number = parseInt(groups.line, 10)
        const message: Message = {
          severity: 'error',
          name,
          source: {
            file: this.normalizePath(groups.file),
            range: { start: line, end: line }
          },
          text: groups.text,
          log: reference
        }

        if (groups.category) message.category = groups.category

        messages.push(message)
      }
    }, {
      // LaTeX3 messages
      names: ['category', 'severity', 'text'],
      patterns: [
        /^[.*!]{48,50}$/,
        /^[.*!] (.*?) (info|warning|error): ("[^"]*")$/
      ],
      evaluate: (reference, groups) => {
        const message: Message = {
          severity: groups.severity,
          name,
          category: groups.category,
          source: { file: filePath },
          text: groups.text,
          log: reference
        }

        messages.push(message)
      }
    }, {
      // LaTeX3 continued message
      names: ['text', 'line'],
      patterns: [/^[.*!] (.*?)(?: on line (\d+)\.?)?$/],
      evaluate: (reference, groups) => {
        const message: Message = messages[messages.length - 1]
        if (message) {
          // Don't add input requests to the message.
          if (groups.text !== 'Type <return> to continue.') {
            message.text = `${message.text} ${groups.text.trim() || '\n'}`
          }
          // If the the previous message has a log reference then extend it.
          if (message.log && message.log.range && reference.range) {
            message.log.range.end = reference.range.end
          }
          // If there is a line reference then add it to the message.
          if (groups.line) {
            const line: number = parseInt(groups.line, 10)

            message.text = `${message.text}.`
            message.source = {
              file: filePath,
              range: { start: line, end: line }
            }
          }
        }
      }
    }, {
      // End of LaTeX3 message
      names: [],
      patterns: [/^[.*!]{48,50} *$/],
      evaluate: (reference, groups) => {
        const message: Message = messages[messages.length - 1]
        // If the the previous message has a log reference then extend it.
        if (message && message.log && message.log.range && reference.range) {
          message.log.range.end = reference.range.end
        }
      }
    }, {
      // Missing file warning.
      names: ['text'],
      patterns: [/^(No file .*\.)$/],
      evaluate: (reference, groups) => {
        messages.push({
          severity: 'warning',
          name,
          text: groups.text,
          log: reference
        })
      }
    }, {
      // Output file message.
      names: ['filePath'],
      patterns: [/^Output written on "?([^"]+)"? \([^)]*\)\.$/],
      evaluate: (reference, groups) => {
        outputs.push(this.normalizePath(groups.filePath))
      }
    }], line => WRAPPED_LINE_PATTERN.test(line))

    // Clean the message text up.
    for (const message of messages) {
      message.text = message.text.trim().replace(/ *\n+ */g, '\n').replace(/ +/g, ' ')
    }

    output.value = { outputs, messages }

    return true
  }
}
<|endoftext|>


<commit_before>var curPic = 0;
var dia = 0;
var timer;
var time = 2500;

$(window).resize(function(){
    resizeImg();
});

function init() {
  document.onkeydown = checkKey;
  initDiashow();
  initPicker();
}

function resizeImg() {
  var height = parseInt($(window).height()) - 150;

  $('.fullPic').css({
    'max-width': $(window).width(),
    'max-height': height,
  });

  $('.container').css({
    'width': $('.fullPic').width(),
  })
}

function getGet(index) {
  var $_GET = {};
  if(document.location.toString().indexOf('?') !== -1) {
      var query = document.location
                     .toString()
                     // get the query string
                     .replace(/^.*?\?/, '')
                     // and remove any existing hash string (thanks, @vrijdenker)
                     .replace(/#.*$/, '')
                     .split('&');

      for(var i=0, l=query.length; i<l; i++) {
         var aux = decodeURIComponent(query[i]).split('=');
         $_GET[aux[0]] = aux[1];
      }
  }
  //get the 'index' query parameter
  return $_GET[index];
}

function prev() {
  ChangeImage(false);

  var img = document.getElementsByClassName("fullPic")[0];
  setPickerPosition(img.id);
  activePicker(false, parseInt(img.id) + 1);

  refreshPicker();
}

function next() {
  ChangeImage(true);

  var img = document.getElementsByClassName("fullPic")[0];
  setPickerPosition(img.id);
  activePicker(false, parseInt(img.id) - 1);

  refreshPicker();
}

function imgLoaded() {
  img = document.getElementsByClassName("fullPic")[0];
  if (img.height > 0)
  {
    resizeImg();
    loader = document.getElementById("loader");

    loader.style.display = "none";
    $(".fullPic").fadeIn();
  }
}

function checkKey(e) {
    e = e || window.event;

    if (e.keyCode == '37' || e.keyCode == '8') {
       // left arrow
       prev();
    }
    else if (e.keyCode == '39' || e.keyCode == '32' || e.keyCode == '13') {
       // right arrow
       next();
    }
}

function hide(elem) {
  sender = document.getElementById(elem);
  sender.style.visibility = "hidden";
}

function show(elem) {
  sender = document.getElementById(elem);
  sender.style.visibility = "visible";
}

function initDiashow() {
  getDia = getGet('dia');
  if (getDia == '1') {
    button = document.getElementById("play");
    button.className = "fa fa-fw fa-pause fa-lg";
    dia = 1;
    timer = setInterval(function() {next()}, time);
  }
  else {
    dia = 0;
  }
}

function diashow() {
  if (dia == 0) {
    dia = 1;
    button = document.getElementById("play");
    button.className = "fa fa-fw fa-pause fa-lg";

    timer = setInterval(function() {next()}, time);
  }
  else {
    dia = 0;
    button = document.getElementById("play");
    button.className = "fa fa-fw fa-play fa-lg";

    window.clearInterval(timer);
  }
}

function initPicker() {
  $('.picker').jScrollPane({
    showArrows: true,
    animateScroll: false,
    arrowScrollOnHover: true
  });

  $('.picker').each(
    function() {
      var api = $(this).data('jsp');
      var throttleTimeout;
      $(window).bind('resize',
        function() {
          if (!throttleTimeout) {
            throttleTimeout = setTimeout(
              function() {
                api.reinitialise();
                throttleTimeout = null;
              },
              50
            );
          }
        }
      );
  });

  var img = document.getElementsByClassName("fullPic")[0];
  setPickerPosition(img.id);

  refreshPicker();
}

function refreshPicker() {
  $('.picker').each(
    function() {
      var api = $(this).data('jsp');
      var throttleTimeout;
      if (!throttleTimeout) {
        throttleTimeout = setTimeout(
          function() {
            api.reinitialise();
            throttleTimeout = null;
          },
          50
        );
      }
  });
}

function setPickerPosition(pic_name) {
  // var thumbs = document.getElementById("picker").childNodes;
  // var position = 0;
  // for (i=0; i<thumbs.length; i++) {
  //   position++;
  //   var img = thumbs[i].id;

  //   if (img == pic_name) {
  //     break;
  //   }
  // }

  var pane = $('.picker');
  var api = pane.data('jsp');
  api.scrollToY((parseInt(pic_name) - 1) * 50);

  activePicker(true, pic_name);
}

function activePicker(active, pic_id) {
  var picker_prev = document.getElementById("thumb" + pic_id);
  if active {
    picker_prev.className = "";
  }
  else {
    picker_prev.className = "inactive";
  }
}<commit_msg>Completed Issue #18 and #19<commit_after>var curPic = 0;
var dia = 0;
var timer;
var time = 2500;

$(window).resize(function(){
    resizeImg();
});

function init() {
  document.onkeydown = checkKey;
  initDiashow();
  initPicker();
}

function resizeImg() {
  var height = parseInt($(window).height()) - 150;

  $('.fullPic').css({
    'max-width': $(window).width(),
    'max-height': height,
  });

  $('.container').css({
    'width': $('.fullPic').width(),
  })
}

function getGet(index) {
  var $_GET = {};
  if(document.location.toString().indexOf('?') !== -1) {
      var query = document.location
                     .toString()
                     // get the query string
                     .replace(/^.*?\?/, '')
                     // and remove any existing hash string (thanks, @vrijdenker)
                     .replace(/#.*$/, '')
                     .split('&');

      for(var i=0, l=query.length; i<l; i++) {
         var aux = decodeURIComponent(query[i]).split('=');
         $_GET[aux[0]] = aux[1];
      }
  }
  //get the 'index' query parameter
  return $_GET[index];
}

function prev() {
  ChangeImage(false);

  setPickerPosition(currentId);
  activePicker(false, currentId + 1);

  refreshPicker();
}

function next() {
  ChangeImage(true);

  setPickerPosition(currentId);
  activePicker(false, currentId - 1);

  refreshPicker();
}

function imgLoaded() {
  img = document.getElementById("fullPic");
  if (img.height > 0)
  {
    resizeImg();
    loader = document.getElementById("loader");

    loader.style.display = "none";
    $(".fullPic").fadeIn();
  }
}

function checkKey(e) {
    e = e || window.event;

    if (e.keyCode == '37' || e.keyCode == '8') {
       // left arrow
       prev();
    }
    else if (e.keyCode == '39' || e.keyCode == '32' || e.keyCode == '13') {
       // right arrow
       next();
    }
}

function hide(elem) {
  sender = document.getElementById(elem);
  sender.style.visibility = "hidden";
}

function show(elem) {
  sender = document.getElementById(elem);
  sender.style.visibility = "visible";
}

function initDiashow() {
  getDia = getGet('dia');
  if (getDia == '1') {
    button = document.getElementById("play");
    button.className = "fa fa-fw fa-pause fa-lg";
    dia = 1;
    timer = setInterval(function() {next()}, time);
  }
  else {
    dia = 0;
  }
}

function diashow() {
  if (dia == 0) {
    dia = 1;
    button = document.getElementById("play");
    button.className = "fa fa-fw fa-pause fa-lg";

    timer = setInterval(function() {next()}, time);
  }
  else {
    dia = 0;
    button = document.getElementById("play");
    button.className = "fa fa-fw fa-play fa-lg";

    window.clearInterval(timer);
  }
}

function initPicker() {
  $('.picker').jScrollPane({
    showArrows: true,
    animateScroll: false,
    arrowScrollOnHover: true
  });

  $('.picker').each(
    function() {
      var api = $(this).data('jsp');
      var throttleTimeout;
      $(window).bind('resize',
        function() {
          if (!throttleTimeout) {
            throttleTimeout = setTimeout(
              function() {
                api.reinitialise();
                throttleTimeout = null;
              },
              50
            );
          }
        }
      );
  });

  setPickerPosition(currentId);

  refreshPicker();
}

function refreshPicker() {
  $('.picker').each(
    function() {
      var api = $(this).data('jsp');
      var throttleTimeout;
      if (!throttleTimeout) {
        throttleTimeout = setTimeout(
          function() {
            api.reinitialise();
            throttleTimeout = null;
          },
          50
        );
      }
  });
}

function setPickerPosition(pic_name) {
  // var thumbs = document.getElementById("picker").childNodes;
  // var position = 0;
  // for (i=0; i<thumbs.length; i++) {
  //   position++;
  //   var img = thumbs[i].id;

  //   if (img == pic_name) {
  //     break;
  //   }
  // }

  var pane = $('.picker');
  var api = pane.data('jsp');
  api.scrollToY((parseInt(pic_name) - 2) * 50);

  activePicker(true, pic_name);
}

function activePicker(active, pic_id) {
  var picker_prev = document.getElementById("thumb" + pic_id);
  if (active) {
    picker_prev.className = "";
  }
  else {
    picker_prev.className = "inactive";
  }
}<|endoftext|>


<commit_before><commit_msg>ClientRouter: Fixed argument passing between methods<commit_after><|endoftext|>


<commit_before>'use strict';

const Mongoose = require('mongoose');

Mongoose.Promise = global.Promise;

console.log(process.env.MONGO_LOG);
Mongoose.set('debug', process.env.MONGO_LOG);
Mongoose.set('useNewUrlParser', true);
Mongoose.set('useCreateIndex', true);

Mongoose.connection.on('connected', () => {
    const {host, port, name} = Mongoose.connection;
    const {NODE_ENV} = process.env;
    console.info(`[${NODE_ENV}] Mongoose connection open @ ${host}:${port}/${name}`);
});

Mongoose.connection.on('error', err => {
    console.error('Mongoose connection error: ' + err);
});

Mongoose.connection.on('disconnected', () => {
    console.info('Mongoose connection disconnected');
});

process.on('SIGINT', () => {
    Mongoose.connection.close(() => {
        console.info('Mongoose connection disconnected through app termination');
        process.exit(0);
    });
});

module.exports.connect = uri => Mongoose.connect(uri);<commit_msg>Remove log<commit_after>'use strict';

const Mongoose = require('mongoose');

Mongoose.Promise = global.Promise;

Mongoose.set('debug', process.env.MONGO_LOG);
Mongoose.set('useNewUrlParser', true);
Mongoose.set('useCreateIndex', true);

Mongoose.connection.on('connected', () => {
    const {host, port, name} = Mongoose.connection;
    const {NODE_ENV} = process.env;
    console.info(`[${NODE_ENV}] Mongoose connection open @ ${host}:${port}/${name}`);
});

Mongoose.connection.on('error', err => {
    console.error('Mongoose connection error: ' + err);
});

Mongoose.connection.on('disconnected', () => {
    console.info('Mongoose connection disconnected');
});

process.on('SIGINT', () => {
    Mongoose.connection.close(() => {
        console.info('Mongoose connection disconnected through app termination');
        process.exit(0);
    });
});

module.exports.connect = uri => Mongoose.connect(uri);<|endoftext|>


<commit_before>/*
Copyright 2015 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

var React = require('react');
var DragSource = require('react-dnd').DragSource;
var DropTarget = require('react-dnd').DropTarget;
var classNames = require('classnames');

var RoomTileController = require('matrix-react-sdk/lib/controllers/molecules/RoomTile')

var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');

var sdk = require('matrix-react-sdk')

/**
 * Specifies the drag source contract.
 * Only `beginDrag` function is required.
 */
var roomTileSource = {
    canDrag: function(props, monitor) {
        return props.roomSubList.props.editable;
    },

    beginDrag: function (props) {
        // Return the data describing the dragged item
        var item = {
            room: props.room,
            originalList: props.roomSubList,
            originalIndex: props.roomSubList.findRoomTile(props.room).index,
            targetList: props.roomSubList, // at first target is same as original
            lastTargetRoom: null,
            lastYOffset: null,
            lastYDelta: null,
        };

        if (props.roomSubList.debug) console.log("roomTile beginDrag for " + item.room.roomId);

        // doing this 'correctly' with state causes react-dnd to break seemingly due to the state transitions
        props.room._dragging = true;

        return item;
    },

    endDrag: function (props, monitor, component) {
        var item = monitor.getItem();

        if (props.roomSubList.debug) console.log("roomTile endDrag for " + item.room.roomId + " with didDrop=" + monitor.didDrop());

        props.room._dragging = false;
        if (monitor.didDrop()) {
            if (props.roomSubList.debug) console.log("force updating component " + item.targetList.props.label);
            item.targetList.forceUpdate(); // as we're not using state
        }

        if (monitor.didDrop() && item.targetList.props.editable) {
            // if we moved lists, remove the old tag
            if (item.targetList !== item.originalList) {
                // commented out attempts to set a spinner on our target component as component is actually
                // the original source component being dragged, not our target.  To fix we just need to
                // move all of this to endDrop in the target instead.  FIXME later.

                //component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
                MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() {
                    //component.state.set({ spinner: component.state.spinner-- });
                }).fail(function(err) {
                    var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
                    Modal.createDialog(ErrorDialog, {
                        title: "Failed to remove tag " + item.originalList.props.tagName + " from room",
                        description: err.toString()
                    });
                });
            }

            var newOrder= {};
            if (item.targetList.props.order === 'manual') {
                newOrder['order'] = item.targetList.calcManualOrderTagData(item.room);
            }

            // if we moved lists or the ordering changed, add the new tag
            if (item.targetList.props.tagName && (item.targetList !== item.originalList || newOrder)) {
                //component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
                MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() {
                    //component.state.set({ spinner: component.state.spinner-- });
                }).fail(function(err) {
                    var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
                    Modal.createDialog(ErrorDialog, {
                        title: "Failed to add tag " + item.targetList.props.tagName + " to room",
                        description: err.toString()
                    });
                });
            }
        }
        else {
            // cancel the drop and reset our original position
            if (props.roomSubList.debug) console.log("cancelling drop & drag");
            props.roomSubList.moveRoomTile(item.room, item.originalIndex);
            if (item.targetList && item.targetList !== item.originalList) {
                item.targetList.removeRoomTile(item.room);
            }
        }
    }
};

var roomTileTarget = {
    canDrop: function() {
        return false;
    },

    hover: function(props, monitor) {
        var item = monitor.getItem();
        var off = monitor.getClientOffset();
        // console.log("hovering on room " + props.room.roomId + ", isOver=" + monitor.isOver());

        //console.log("item.targetList=" + item.targetList + ", roomSubList=" + props.roomSubList);

        var switchedTarget = false;
        if (item.targetList !== props.roomSubList) {
            // we've switched target, so remove the tile from the previous target.
            // n.b. the previous target might actually be the source list.
            if (props.roomSubList.debug) console.log("switched target sublist");
            switchedTarget = true;
            item.targetList.removeRoomTile(item.room);
            item.targetList = props.roomSubList;
        }

        if (!item.targetList.props.editable) return;

        if (item.targetList.props.order === 'manual') {
            if (item.room.roomId !== props.room.roomId && props.room !== item.lastTargetRoom) {
                // find the offset of the target tile in the list.
                var roomTile = props.roomSubList.findRoomTile(props.room);
                // shuffle the list to add our tile to that position.
                props.roomSubList.moveRoomTile(item.room, roomTile.index);
            }

            // stop us from flickering between our droptarget and the previous room.
            // whenever the cursor changes direction we have to reset the flicker-damping.

            var yDelta = off.y - item.lastYOffset;

            if ((yDelta > 0 && item.lastYDelta < 0) ||
                (yDelta < 0 && item.lastYDelta > 0))
            {
                // the cursor changed direction - forget our previous room
                item.lastTargetRoom = null;
            }
            else {
                // track the last room we were hovering over so we can stop
                // bouncing back and forth if the droptarget is narrower than
                // the other list items.  The other way to do this would be
                // to reduce the size of the hittarget on the list items, but
                // can't see an easy way to do that.
                item.lastTargetRoom = props.room;
            }

            if (yDelta) item.lastYDelta = yDelta;
            item.lastYOffset = off.y;
        }
        else if (switchedTarget) {
            if (!props.roomSubList.findRoomTile(item.room).room) {
                // add to the list in the right place
                props.roomSubList.moveRoomTile(item.room, 0);
            }
            // we have to sort the list whatever to recalculate it
            props.roomSubList.sortList();
        }
    },
};

var RoomTile = React.createClass({
    displayName: 'RoomTile',
    mixins: [RoomTileController],

    propTypes: {
        connectDragSource: React.PropTypes.func.isRequired,
        connectDropTarget: React.PropTypes.func.isRequired,
        isDragging: React.PropTypes.bool.isRequired,
        room: React.PropTypes.object.isRequired,
        collapsed: React.PropTypes.bool.isRequired,
        selected: React.PropTypes.bool.isRequired,
        unread: React.PropTypes.bool.isRequired,
        highlight: React.PropTypes.bool.isRequired,
        isInvite: React.PropTypes.bool.isRequired,
        roomSubList: React.PropTypes.object.isRequired,
    },

    getInitialState: function() {
        return( { hover : false });
    },

    onMouseEnter: function() {
        this.setState( { hover : true });
    },

    onMouseLeave: function() {
        this.setState( { hover : false });
    },

    render: function() {
        // if (this.props.clientOffset) {
        //     //console.log("room " + this.props.room.roomId + " has dropTarget clientOffset " + this.props.clientOffset.x + "," + this.props.clientOffset.y);
        // }

        if (this.props.room._dragging) {
            var RoomDropTarget = sdk.getComponent("molecules.RoomDropTarget");
            return <RoomDropTarget placeholder={true}/>;
        }

        var myUserId = MatrixClientPeg.get().credentials.userId;
        var me = this.props.room.currentState.members[myUserId];
        var classes = classNames({
            'mx_RoomTile': true,
            'mx_RoomTile_selected': this.props.selected,
            'mx_RoomTile_unread': this.props.unread,
            'mx_RoomTile_highlight': this.props.highlight,
            'mx_RoomTile_invited': (me && me.membership == 'invite'),
        });

        var name;
        if (this.props.isInvite) {
            name = this.props.room.getMember(myUserId).events.member.getSender();
        }
        else {
            // XXX: We should never display raw room IDs, but sometimes the room name js sdk gives is undefined
            name = this.props.room.name || this.props.room.roomId;
        }

        name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
        var badge;
        if (this.props.highlight) {
            badge =
;
        }
        /*
        if (this.props.highlight) {
            badge =
!
;
        }
        else if (this.props.unread) {
            badge =
1
;
        }
        var nameCell;
        if (badge) {
            nameCell =

{name}

{badge}

;
        }
        else {
            nameCell =
{name}
;
        }
        */

        var label;
        if (!this.props.collapsed) {
            var className = 'mx_RoomTile_name' + (this.props.isInvite ? ' mx_RoomTile_invite' : '');
            label =
{name}
;
        }
        else if (this.state.hover) {
            var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
            label = <RoomTooltip room={this.props.room}/>;
        }

        var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');

        // These props are injected by React DnD,
        // as defined by your `collect` function above:
        var isDragging = this.props.isDragging;
        var connectDragSource = this.props.connectDragSource;
        var connectDropTarget = this.props.connectDropTarget;

        return connectDragSource(connectDropTarget(

                    <RoomAvatar room={this.props.room} width="24" height="24" />
                    { badge }

                { label }

        ));
    }
});

// Export the wrapped version, inlining the 'collect' functions
// to more closely resemble the ES7
module.exports =
DropTarget('RoomTile', roomTileTarget, function(connect, monitor) {
    return {
        // Call this function inside render()
        // to let React DnD handle the drag events:
        connectDropTarget: connect.dropTarget(),
        isOver: monitor.isOver(),
    }
})(
DragSource('RoomTile', roomTileSource, function(connect, monitor) {
    return {
        // Call this function inside render()
        // to let React DnD handle the drag events:
        connectDragSource: connect.dragSource(),
        // You can ask the monitor about the current drag state:
        isDragging: monitor.isDragging()
    };
})(RoomTile));<commit_msg>turn off the placeholder drag & drop function to get an opinion from folks<commit_after>/*
Copyright 2015 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

var React = require('react');
var DragSource = require('react-dnd').DragSource;
var DropTarget = require('react-dnd').DropTarget;
var classNames = require('classnames');

var RoomTileController = require('matrix-react-sdk/lib/controllers/molecules/RoomTile')

var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');

var sdk = require('matrix-react-sdk')

/**
 * Specifies the drag source contract.
 * Only `beginDrag` function is required.
 */
var roomTileSource = {
    canDrag: function(props, monitor) {
        return props.roomSubList.props.editable;
    },

    beginDrag: function (props) {
        // Return the data describing the dragged item
        var item = {
            room: props.room,
            originalList: props.roomSubList,
            originalIndex: props.roomSubList.findRoomTile(props.room).index,
            targetList: props.roomSubList, // at first target is same as original
            // lastTargetRoom: null,
            // lastYOffset: null,
            // lastYDelta: null,
        };

        if (props.roomSubList.debug) console.log("roomTile beginDrag for " + item.room.roomId);

        // doing this 'correctly' with state causes react-dnd to break seemingly due to the state transitions
        props.room._dragging = true;

        return item;
    },

    endDrag: function (props, monitor, component) {
        var item = monitor.getItem();

        if (props.roomSubList.debug) console.log("roomTile endDrag for " + item.room.roomId + " with didDrop=" + monitor.didDrop());

        props.room._dragging = false;
        if (monitor.didDrop()) {
            if (props.roomSubList.debug) console.log("force updating component " + item.targetList.props.label);
            item.targetList.forceUpdate(); // as we're not using state
        }

        if (monitor.didDrop() && item.targetList.props.editable) {
            // if we moved lists, remove the old tag
            if (item.targetList !== item.originalList) {
                // commented out attempts to set a spinner on our target component as component is actually
                // the original source component being dragged, not our target.  To fix we just need to
                // move all of this to endDrop in the target instead.  FIXME later.

                //component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
                MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() {
                    //component.state.set({ spinner: component.state.spinner-- });
                }).fail(function(err) {
                    var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
                    Modal.createDialog(ErrorDialog, {
                        title: "Failed to remove tag " + item.originalList.props.tagName + " from room",
                        description: err.toString()
                    });
                });
            }

            var newOrder= {};
            if (item.targetList.props.order === 'manual') {
                newOrder['order'] = item.targetList.calcManualOrderTagData(item.room);
            }

            // if we moved lists or the ordering changed, add the new tag
            if (item.targetList.props.tagName && (item.targetList !== item.originalList || newOrder)) {
                //component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
                MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() {
                    //component.state.set({ spinner: component.state.spinner-- });
                }).fail(function(err) {
                    var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
                    Modal.createDialog(ErrorDialog, {
                        title: "Failed to add tag " + item.targetList.props.tagName + " to room",
                        description: err.toString()
                    });
                });
            }
        }
        else {
            // cancel the drop and reset our original position
            if (props.roomSubList.debug) console.log("cancelling drop & drag");
            props.roomSubList.moveRoomTile(item.room, item.originalIndex);
            if (item.targetList && item.targetList !== item.originalList) {
                item.targetList.removeRoomTile(item.room);
            }
        }
    }
};

var roomTileTarget = {
    canDrop: function() {
        return false;
    },

    hover: function(props, monitor) {
        var item = monitor.getItem();
        //var off = monitor.getClientOffset();
        // console.log("hovering on room " + props.room.roomId + ", isOver=" + monitor.isOver());

        //console.log("item.targetList=" + item.targetList + ", roomSubList=" + props.roomSubList);

        var switchedTarget = false;
        if (item.targetList !== props.roomSubList) {
            // we've switched target, so remove the tile from the previous target.
            // n.b. the previous target might actually be the source list.
            if (props.roomSubList.debug) console.log("switched target sublist");
            switchedTarget = true;
            item.targetList.removeRoomTile(item.room);
            item.targetList = props.roomSubList;
        }

        if (!item.targetList.props.editable) return;

        if (item.targetList.props.order === 'manual') {
            if (item.room.roomId !== props.room.roomId && props.room !== item.lastTargetRoom) {
                // find the offset of the target tile in the list.
                var roomTile = props.roomSubList.findRoomTile(props.room);
                // shuffle the list to add our tile to that position.
                props.roomSubList.moveRoomTile(item.room, roomTile.index);
            }

            // stop us from flickering between our droptarget and the previous room.
            // whenever the cursor changes direction we have to reset the flicker-damping.
/*
            var yDelta = off.y - item.lastYOffset;

            if ((yDelta > 0 && item.lastYDelta < 0) ||
                (yDelta < 0 && item.lastYDelta > 0))
            {
                // the cursor changed direction - forget our previous room
                item.lastTargetRoom = null;
            }
            else {
                // track the last room we were hovering over so we can stop
                // bouncing back and forth if the droptarget is narrower than
                // the other list items.  The other way to do this would be
                // to reduce the size of the hittarget on the list items, but
                // can't see an easy way to do that.
                item.lastTargetRoom = props.room;
            }

            if (yDelta) item.lastYDelta = yDelta;
            item.lastYOffset = off.y;
*/
        }
        else if (switchedTarget) {
            if (!props.roomSubList.findRoomTile(item.room).room) {
                // add to the list in the right place
                props.roomSubList.moveRoomTile(item.room, 0);
            }
            // we have to sort the list whatever to recalculate it
            props.roomSubList.sortList();
        }
    },
};

var RoomTile = React.createClass({
    displayName: 'RoomTile',
    mixins: [RoomTileController],

    propTypes: {
        connectDragSource: React.PropTypes.func.isRequired,
        connectDropTarget: React.PropTypes.func.isRequired,
        isDragging: React.PropTypes.bool.isRequired,
        room: React.PropTypes.object.isRequired,
        collapsed: React.PropTypes.bool.isRequired,
        selected: React.PropTypes.bool.isRequired,
        unread: React.PropTypes.bool.isRequired,
        highlight: React.PropTypes.bool.isRequired,
        isInvite: React.PropTypes.bool.isRequired,
        roomSubList: React.PropTypes.object.isRequired,
    },

    getInitialState: function() {
        return( { hover : false });
    },

    onMouseEnter: function() {
        this.setState( { hover : true });
    },

    onMouseLeave: function() {
        this.setState( { hover : false });
    },

    render: function() {
        // if (this.props.clientOffset) {
        //     //console.log("room " + this.props.room.roomId + " has dropTarget clientOffset " + this.props.clientOffset.x + "," + this.props.clientOffset.y);
        // }

/*
        if (this.props.room._dragging) {
            var RoomDropTarget = sdk.getComponent("molecules.RoomDropTarget");
            return <RoomDropTarget placeholder={true}/>;
        }
*/

        var myUserId = MatrixClientPeg.get().credentials.userId;
        var me = this.props.room.currentState.members[myUserId];
        var classes = classNames({
            'mx_RoomTile': true,
            'mx_RoomTile_selected': this.props.selected,
            'mx_RoomTile_unread': this.props.unread,
            'mx_RoomTile_highlight': this.props.highlight,
            'mx_RoomTile_invited': (me && me.membership == 'invite'),
        });

        var name;
        if (this.props.isInvite) {
            name = this.props.room.getMember(myUserId).events.member.getSender();
        }
        else {
            // XXX: We should never display raw room IDs, but sometimes the room name js sdk gives is undefined
            name = this.props.room.name || this.props.room.roomId;
        }

        name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
        var badge;
        if (this.props.highlight) {
            badge =
;
        }
        /*
        if (this.props.highlight) {
            badge =
!
;
        }
        else if (this.props.unread) {
            badge =
1
;
        }
        var nameCell;
        if (badge) {
            nameCell =

{name}

{badge}

;
        }
        else {
            nameCell =
{name}
;
        }
        */

        var label;
        if (!this.props.collapsed) {
            var className = 'mx_RoomTile_name' + (this.props.isInvite ? ' mx_RoomTile_invite' : '');
            label =
{name}
;
        }
        else if (this.state.hover) {
            var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
            label = <RoomTooltip room={this.props.room}/>;
        }

        var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');

        // These props are injected by React DnD,
        // as defined by your `collect` function above:
        var isDragging = this.props.isDragging;
        var connectDragSource = this.props.connectDragSource;
        var connectDropTarget = this.props.connectDropTarget;

        return connectDragSource(connectDropTarget(

                    <RoomAvatar room={this.props.room} width="24" height="24" />
                    { badge }

                { label }

        ));
    }
});

// Export the wrapped version, inlining the 'collect' functions
// to more closely resemble the ES7
module.exports =
DropTarget('RoomTile', roomTileTarget, function(connect, monitor) {
    return {
        // Call this function inside render()
        // to let React DnD handle the drag events:
        connectDropTarget: connect.dropTarget(),
        isOver: monitor.isOver(),
    }
})(
DragSource('RoomTile', roomTileSource, function(connect, monitor) {
    return {
        // Call this function inside render()
        // to let React DnD handle the drag events:
        connectDragSource: connect.dragSource(),
        // You can ask the monitor about the current drag state:
        isDragging: monitor.isDragging()
    };
})(RoomTile));<|endoftext|>