<commit_before>/*!
 * Module dependencies.
 */

var util = require('util'),
	utils = require('../utils'),
	super_ = require('../field');

/**
 * Boolean FieldType Constructor
 * @extends Field
 * @api public
 */

function boolean(list, path, options) {
	this._nativeType = Boolean;
	this.indent = (options.indent) ? true : false;
	boolean.super_.call(this, list, path, options);
};

/*!
 * Inherit from Field
 */

util.inherits(boolean, super_);

/**
 * Validates that a value for this field has been provided in a data object.
 * Always returns true because a lack of data is considered a 'false' value.
 *
 * @api public
 */

boolean.prototype.validateInput = function(data) {
	return true;
}

/**
 * Updates the value for this field in the item from a data object.
 * Only updates the value if it has changed.
 * Treats a true boolean or string == 'true' as true, everything else as false.
 *
 * @api public
 */

boolean.prototype.updateItem = function(item, data) {

	if (data[this.path] == true || data[this.path] == 'true') {
		if (!item.get(this.path))
			item.set(this.path, true);
	} else if (item.get(this.path)) {
		item.set(this.path, false);
	}

}

/*!
 * Export class
 */

exports = module.exports = boolean;
<commit_msg>Implementing required option for boolean fields<commit_after>/*!
 * Module dependencies.
 */

var util = require('util'),
	utils = require('../utils'),
	super_ = require('../field');

/**
 * Boolean FieldType Constructor
 * @extends Field
 * @api public
 */

function boolean(list, path, options) {
	this._nativeType = Boolean;
	this.indent = (options.indent) ? true : false;
	boolean.super_.call(this, list, path, options);
};

/*!
 * Inherit from Field
 */

util.inherits(boolean, super_);

/**
 * Validates that a truthy value for this field has been provided in a data object.
 *
 * Useful for checkboxes that are required to be true (e.g. agreed to terms and cond's)
 *
 * @api public
 */

boolean.prototype.validateInput = function(data, required) {
	if (required) {
		return (data[this.path]) ? true : false;
	} else {
		return true;
	}
}

/**
 * Updates the value for this field in the item from a data object.
 * Only updates the value if it has changed.
 * Treats a true boolean or string == 'true' as true, everything else as false.
 *
 * @api public
 */

boolean.prototype.updateItem = function(item, data) {

	if (data[this.path] == true || data[this.path] == 'true') {
		if (!item.get(this.path))
			item.set(this.path, true);
	} else if (item.get(this.path)) {
		item.set(this.path, false);
	}

}

/*!
 * Export class
 */

exports = module.exports = boolean;
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

define(function(require, exports, module) {
var help = exports;

var canon = require('gcli/canon');
var util = require('gcli/util');
var l10n = require('gcli/l10n');
var domtemplate = require('gcli/ui/domtemplate');

var helpCss = require('text!gcli/commands/help.css');
var helpStyle = undefined;
var helpIntroHtml = require('text!gcli/commands/help_intro.html');
var helpIntroTemplate = undefined;
var helpListHtml = require('text!gcli/commands/help_list.html');
var helpListTemplate = undefined;
var helpManHtml = require('text!gcli/commands/help_man.html');
var helpManTemplate = undefined;

/**
 * 'help' command
 * We delay definition of helpCommandSpec until help.startup() to ensure that
 * the l10n strings have been loaded
 */
var helpCommandSpec;

/**
 * Registration and de-registration.
 */
help.startup = function() {

  helpCommandSpec = {
    name: 'help',
    description: l10n.lookup('helpDesc'),
    manual: l10n.lookup('helpManual'),
    params: [
      {
        name: 'search',
        type: 'string',
        description: l10n.lookup('helpSearchDesc'),
        manual: l10n.lookup('helpSearchManual'),
        defaultValue: null
      }
    ],
    returnType: 'html',

    exec: function(args, context) {
      help.onFirstUseStartup(context.document);

      var match = canon.getCommand(args.search);
      if (match) {
        var clone = helpManTemplate.cloneNode(true);
        domtemplate.template(clone, getManTemplateData(match, context),
                { stack: 'help_man.html' });
        return clone;
      }

      var parent = util.dom.createElement(context.document, 'div');
      if (!args.search) {
        parent.appendChild(helpIntroTemplate.cloneNode(true));
      }
      parent.appendChild(helpListTemplate.cloneNode(true));
      domtemplate.template(parent, getListTemplateData(args, context),
              { allowEval: true, stack: 'help_intro.html | help_list.html' });
      return parent;
    }
  };

  canon.addCommand(helpCommandSpec);
};

help.shutdown = function() {
  canon.removeCommand(helpCommandSpec);

  helpListTemplate = undefined;
  helpStyle.parentElement.removeChild(helpStyle);
  helpStyle = undefined;
};

/**
 * Called when the command is executed
 */
help.onFirstUseStartup = function(document) {
  if (!helpIntroTemplate) {
    helpIntroTemplate = util.dom.createElement(document, 'div');
    util.dom.setInnerHtml(helpIntroTemplate, helpIntroHtml);
  }
  if (!helpListTemplate) {
    helpListTemplate = util.dom.createElement(document, 'div');
    util.dom.setInnerHtml(helpListTemplate, helpListHtml);
  }
  if (!helpManTemplate) {
    helpManTemplate = util.dom.createElement(document, 'div');
    util.dom.setInnerHtml(helpManTemplate, helpManHtml);
  }
  if (!helpStyle && helpCss != null) {
    helpStyle = util.dom.importCss(helpCss, document);
  }
};

/**
 * Find an element within the passed element with the class gcli-help-command
 * and update the requisition to contain this text.
 */
function updateCommand(element, context) {
  context.requisition.update({
    typed: element.querySelector('.gcli-help-command').textContent
  });
}

/**
 * Find an element within the passed element with the class gcli-help-command
 * and execute this text.
 */
function executeCommand(element, context) {
  context.requisition.exec({
    visible: true,
    typed: element.querySelector('.gcli-help-command').textContent
  });
}

/**
 * Create a block of data suitable to be passed to the help_list.html template
 */
function getListTemplateData(args, context) {
  return {
    l10n: l10n.propertyLookup,
    lang: context.document.defaultView.navigator.language,

    onclick: function(ev) {
      updateCommand(ev.currentTarget, context);
    },

    ondblclick: function(ev) {
      executeCommand(ev.currentTarget, context);
    },

    getHeading: function() {
      return args.search == null ?
              'Available Commands:' :
              'Commands starting with \'' + args.search + '\':';
    },

    getMatchingCommands: function() {
      var matching = canon.getCommands().filter(function(command) {
        if (args.search && command.name.indexOf(args.search) !== 0) {
          // Filtered out because they don't match the search
          return false;
        }
        if (!args.search && command.name.indexOf(' ') != -1) {
          // We don't show sub commands with plain 'help'
          return false;
        }
        return true;
      });
      matching.sort();
      return matching;
    }
  };
}

/**
 * Create a block of data suitable to be passed to the help_man.html template
 */
function getManTemplateData(command, context) {
  return {
    l10n: l10n.propertyLookup,
    lang: context.document.defaultView.navigator.language,

    command: command,

    onclick: function(ev) {
      updateCommand(ev.currentTarget, context);
    },

    getTypeDescription: function(param) {
      var input = '';
      if (param.defaultValue === undefined) {
        input = 'required';
      }
      else if (param.defaultValue === null) {
        input = 'optional';
      }
      else {
        input = param.defaultValue;
      }
      return '(' + param.type.name + ', ' + input + ')';
    }
  };
}

});
<commit_msg>Bug 704838 (enhelp): Add allowEval:true missing from merge<commit_after>/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

define(function(require, exports, module) {
var help = exports;

var canon = require('gcli/canon');
var util = require('gcli/util');
var l10n = require('gcli/l10n');
var domtemplate = require('gcli/ui/domtemplate');

var helpCss = require('text!gcli/commands/help.css');
var helpStyle = undefined;
var helpIntroHtml = require('text!gcli/commands/help_intro.html');
var helpIntroTemplate = undefined;
var helpListHtml = require('text!gcli/commands/help_list.html');
var helpListTemplate = undefined;
var helpManHtml = require('text!gcli/commands/help_man.html');
var helpManTemplate = undefined;

/**
 * 'help' command
 * We delay definition of helpCommandSpec until help.startup() to ensure that
 * the l10n strings have been loaded
 */
var helpCommandSpec;

/**
 * Registration and de-registration.
 */
help.startup = function() {

  helpCommandSpec = {
    name: 'help',
    description: l10n.lookup('helpDesc'),
    manual: l10n.lookup('helpManual'),
    params: [
      {
        name: 'search',
        type: 'string',
        description: l10n.lookup('helpSearchDesc'),
        manual: l10n.lookup('helpSearchManual'),
        defaultValue: null
      }
    ],
    returnType: 'html',

    exec: function(args, context) {
      help.onFirstUseStartup(context.document);

      var match = canon.getCommand(args.search);
      if (match) {
        var clone = helpManTemplate.cloneNode(true);
        domtemplate.template(clone, getManTemplateData(match, context),
                { allowEval: true, stack: 'help_man.html' });
        return clone;
      }

      var parent = util.dom.createElement(context.document, 'div');
      if (!args.search) {
        parent.appendChild(helpIntroTemplate.cloneNode(true));
      }
      parent.appendChild(helpListTemplate.cloneNode(true));
      domtemplate.template(parent, getListTemplateData(args, context),
              { allowEval: true, stack: 'help_intro.html | help_list.html' });
      return parent;
    }
  };

  canon.addCommand(helpCommandSpec);
};

help.shutdown = function() {
  canon.removeCommand(helpCommandSpec);

  helpListTemplate = undefined;
  helpStyle.parentElement.removeChild(helpStyle);
  helpStyle = undefined;
};

/**
 * Called when the command is executed
 */
help.onFirstUseStartup = function(document) {
  if (!helpIntroTemplate) {
    helpIntroTemplate = util.dom.createElement(document, 'div');
    util.dom.setInnerHtml(helpIntroTemplate, helpIntroHtml);
  }
  if (!helpListTemplate) {
    helpListTemplate = util.dom.createElement(document, 'div');
    util.dom.setInnerHtml(helpListTemplate, helpListHtml);
  }
  if (!helpManTemplate) {
    helpManTemplate = util.dom.createElement(document, 'div');
    util.dom.setInnerHtml(helpManTemplate, helpManHtml);
  }
  if (!helpStyle && helpCss != null) {
    helpStyle = util.dom.importCss(helpCss, document);
  }
};

/**
 * Find an element within the passed element with the class gcli-help-command
 * and update the requisition to contain this text.
 */
function updateCommand(element, context) {
  context.requisition.update({
    typed: element.querySelector('.gcli-help-command').textContent
  });
}

/**
 * Find an element within the passed element with the class gcli-help-command
 * and execute this text.
 */
function executeCommand(element, context) {
  context.requisition.exec({
    visible: true,
    typed: element.querySelector('.gcli-help-command').textContent
  });
}

/**
 * Create a block of data suitable to be passed to the help_list.html template
 */
function getListTemplateData(args, context) {
  return {
    l10n: l10n.propertyLookup,
    lang: context.document.defaultView.navigator.language,

    onclick: function(ev) {
      updateCommand(ev.currentTarget, context);
    },

    ondblclick: function(ev) {
      executeCommand(ev.currentTarget, context);
    },

    getHeading: function() {
      return args.search == null ?
              'Available Commands:' :
              'Commands starting with \'' + args.search + '\':';
    },

    getMatchingCommands: function() {
      var matching = canon.getCommands().filter(function(command) {
        if (args.search && command.name.indexOf(args.search) !== 0) {
          // Filtered out because they don't match the search
          return false;
        }
        if (!args.search && command.name.indexOf(' ') != -1) {
          // We don't show sub commands with plain 'help'
          return false;
        }
        return true;
      });
      matching.sort();
      return matching;
    }
  };
}

/**
 * Create a block of data suitable to be passed to the help_man.html template
 */
function getManTemplateData(command, context) {
  return {
    l10n: l10n.propertyLookup,
    lang: context.document.defaultView.navigator.language,

    command: command,

    onclick: function(ev) {
      updateCommand(ev.currentTarget, context);
    },

    getTypeDescription: function(param) {
      var input = '';
      if (param.defaultValue === undefined) {
        input = 'required';
      }
      else if (param.defaultValue === null) {
        input = 'optional';
      }
      else {
        input = param.defaultValue;
      }
      return '(' + param.type.name + ', ' + input + ')';
    }
  };
}

});
<|endoftext|>


<commit_before>"use strict";

var util = require('util'),

template = '<option value="%s"%s>%s</option>';

module.exports = function formoption(arr) {
  var html = '', related = false, select;

  if (this.post && this.post.related && this.post.related.length > 0) {
    related = this.post.related;
  }

  for (var i=0, length=arr.length; i<length; i++) {
    if (related && related.indexOf('' + arr[i].id) != -1) {
      select = ' selected';
    } else {
      select = '';
    }

    html += util.format(template, arr[i].id, select, arr[i].title);
  }

  return html;
};<commit_msg>Strict equals<commit_after>"use strict";

var util = require('util'),

template = '<option value="%s"%s>%s</option>';

module.exports = function formoption(arr) {
  var html = '', related = false, select;

  if (this.post && this.post.related && this.post.related.length > 0) {
    related = this.post.related;
  }

  for (var i=0, length=arr.length; i<length; i++) {
    if (related && related.indexOf('' + arr[i].id) !== -1) {
      select = ' selected';
    } else {
      select = '';
    }

    html += util.format(template, arr[i].id, select, arr[i].title);
  }

  return html;
};<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var utilities = require('./utilities');
var formatDOM = utilities.formatDOM;

/**
 * Parse HTML string to DOM nodes.
 * This uses the browser DOM API.
 *
 * @param  {String} html - The HTML.
 * @return {Object}      - The DOM nodes.
 */
function parseDOM(html) {
    // from `<p>` or `<p style="">` get `p`
    var match = typeof html === 'string' ? html.match(/<(.+?)[>\s]/) : null;
    var tagName;
    var parentNode;
    var nodes;

    if (match && typeof match[1] === 'string') {
        tagName = match[1].trim().toLowerCase();
    }

    // `DOMParser` can parse full HTML
    // https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
    if (tagName && window.DOMParser) {
        var parser = new window.DOMParser();
        var doc = parser.parseFromString(html, 'text/html');

        // <head> and <body> are siblings
        if (tagName === 'head' || tagName === 'body') {
            nodes = doc.getElementsByTagName(tagName);

        // document's child nodes
        } else if (tagName === 'html') {
            nodes = doc.childNodes;

        // get the element's parent's child nodes
        // do this in case of adjacent elements
        } else {
            parentNode = doc.getElementsByTagName(tagName)[0].parentNode;
            nodes = parentNode.childNodes;
        }

    // otherwise, use `innerHTML`
    // but this will strip out tags like <html> and <body>
    } else {
        parentNode = document.createElement('div');
        parentNode.innerHTML = html;
        nodes = parentNode.childNodes;
    }

    return formatDOM(nodes);
}

/**
 * Export HTML to DOM parser (client).
 */
module.exports = parseDOM;
<commit_msg>Refactor the client parser and try to detect the `directive`<commit_after>'use strict';

/**
 * Module dependencies.
 */
var utilities = require('./utilities');
var formatDOM = utilities.formatDOM;

/**
 * Parse HTML string to DOM nodes.
 * This uses the browser DOM API.
 *
 * @param  {String} html - The HTML.
 * @return {Object}      - The DOM nodes.
 */
function parseDOM(html) {
    // try to match the tags
    var match = html.match(/<[^\/](.+?)>/g);
    var container;
    var parentNode;
    var nodes;

    if (match && match.length) {
        var tagMatch = match[0];

        // directive matched
        if (/<![^-]/.test(tagMatch)) {
            var directive = (
                // remove angle brackets
                tagMatch
                    .substring(1, tagMatch.length - 1)
                    .trim()
            );

            // tag name can no longer be first match item
            tagMatch = match[1];

            // remove directive from html
            html = html.substring(html.indexOf('>') + 1);
        }

        // first tag name matched
        if (tagMatch) {
            var tagName = (
                // keep only tag name
                tagMatch
                    .substring(1, tagMatch.indexOf(' '))
                    .trim()
                    .toLowerCase()
            )
        }
    }

    // create html document to parse top-level nodes
    if (['html', 'head', 'body'].indexOf(tagName) > -1) {
        var doc;

        // `new DOMParser().parseFromString()`
        // https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Parsing_an_SVG_or_HTML_document
        if (window.DOMParser) {
            doc = new window.DOMParser().parseFromString(html, 'text/html');

        // `DOMImplementation.createHTMLDocument()`
        // https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createHTMLDocument
        } else if (document.implementation.createHTMLDocument) {
            doc = document.implementation.createHTMLDocument();
            doc.documentElement.innerHTML = html;
            doc.removeChild(doc.childNodes[0]); // remove doctype
        }

        // html
        if (tagName === 'html') {
            nodes = doc.childNodes;
        // head and body
        } else {
            nodes = (
                // do this so attributes are kept
                // but there may be an extra head/body node
                doc.getElementsByTagName(tagName)[0]
                    .parentNode
                    .childNodes
            );
        }

    // `innerHTML` approach
    } else {
        var container = document.createElement('body');
        container.innerHTML = html;
        nodes = container.childNodes;
    }

    return formatDOM(nodes, null, directive);
}

/**
 * Export HTML to DOM parser (client).
 */
module.exports = parseDOM;
<|endoftext|>


<commit_before>var Plugin = require('broccoli-plugin');
var fs = require('fs');
var PropertiesParser = require('properties-parser');
var mkrip = require('mkdirp');
var path = require('path');
var merge = require('lodash.merge');

I18NAssetBuilder.prototype = Object.create(Plugin.prototype);
I18NAssetBuilder.constructor = I18NAssetBuilder;

function I18NAssetBuilder(inputNodes, options) {
  options = options || {};
  Plugin.call(this, [inputNodes], {
    annotation: options.annotation
  });
  this.options = options;
}

I18NAssetBuilder.prototype.build = function() {
  var outputPath = path.join(this.outputPath,  this.options.outputPath);
  var inputPath = this.inputPaths[0];
  var outputFilePrefix = this.options.outputFilePrefix;
  var defaultLocaleFile = path.join(inputPath, this.options.defaultLocale + '.properties');

  var defaultLocaleTranslations = parsePropertiesFile(defaultLocaleFile);

  mkrip.sync(outputPath);

  fs.readdirSync(inputPath, { encoding: 'utf8' }).forEach(function(file) {
    var fileName = outputFilePrefix + path.basename(file, '.properties');
    var translations = parsePropertiesFile(path.join(inputPath, file));

    translations = merge(defaultLocaleTranslations, translations);

    var outputString = 'Ember.STRINGS = ' + JSON.stringify(translations);
    var outputFileName = path.join(outputPath, fileName + '.js');

    fs.writeFileSync(outputFileName, outputString, { encoding: 'utf8' });
  });
};

function parsePropertiesFile(fileName) {
  return PropertiesParser.parse(fs.readFileSync(fileName));
}

module.exports = I18NAssetBuilder;
<commit_msg>Merging translations when a specific language file is empty will result in the previous translated language’s content - issue fixed.<commit_after>var Plugin = require('broccoli-plugin');
var fs = require('fs');
var PropertiesParser = require('properties-parser');
var mkrip = require('mkdirp');
var path = require('path');
var merge = require('lodash.merge');

I18NAssetBuilder.prototype = Object.create(Plugin.prototype);
I18NAssetBuilder.constructor = I18NAssetBuilder;

function I18NAssetBuilder(inputNodes, options) {
  options = options || {};
  Plugin.call(this, [inputNodes], {
    annotation: options.annotation
  });
  this.options = options;
}

I18NAssetBuilder.prototype.build = function() {
  var outputPath = path.join(this.outputPath,  this.options.outputPath);
  var inputPath = this.inputPaths[0];
  var outputFilePrefix = this.options.outputFilePrefix;
  var defaultLocaleFile = path.join(inputPath, this.options.defaultLocale + '.properties');

  var defaultLocaleTranslations = parsePropertiesFile(defaultLocaleFile);

  mkrip.sync(outputPath);

  fs.readdirSync(inputPath, { encoding: 'utf8' }).forEach(function(file) {
    var fileName = outputFilePrefix + path.basename(file, '.properties');
    var translations = parsePropertiesFile(path.join(inputPath, file));

    translations = merge({}, defaultLocaleTranslations, translations);

    var outputString = 'Ember.STRINGS = ' + JSON.stringify(translations);
    var outputFileName = path.join(outputPath, fileName + '.js');

    fs.writeFileSync(outputFileName, outputString, { encoding: 'utf8' });
  });
};

function parsePropertiesFile(fileName) {
  return PropertiesParser.parse(fs.readFileSync(fileName));
}

module.exports = I18NAssetBuilder;
<|endoftext|>


<commit_before>'use strict';

describe('oide.editor.EditorService', function() {
  beforeEach(module('oide'));
  beforeEach(module('oide.editor'));

  describe('oide.editor.EditorService settings', function() {
    var aceMock,sessMock, httpBackend;

    beforeEach(function() {
      sessMock = jasmine.createSpyObj(
        'sessMock',
        [
          'getUndoManager',
          'setUndoManager',
          'getDocument',
          'setUseSoftTabs',
          'setTabSize',
          'setUseWrapMode'
        ]
      );
      aceMock = jasmine.createSpyObj(
        'aceMock',
        [
          'setSession',
          'setShowInvisibles',
          'setFontSize',
          'setDisplayIndentGuides'
        ]
      );
      aceMock.getSession = function() {
        return sessMock;
      };
    });

    beforeEach(inject(function($httpBackend){
      httpBackend = $httpBackend;
      httpBackend.whenGET(/\/filebrowser\/localfiles.*/).respond(function(){
        var file = {
          contents: 'this is a basic file'
        };
        return [200, file];
      });
    }));

    it('starts with the correct defaults.', inject(function(EditorService) {
      var defaults = {
        showInvisibles: true,
        useSoftTabs: true,
        fontSize: 12,
        tabSize: 4,
        showIndentGuides: true,
        wordWrap: false
      };
      expect(EditorService.getSettings()).toEqual(defaults);
    }));
    it('correctly modifies settings.', inject(function(EditorService) {
      EditorService.onAceLoad(aceMock);
      var newSettings = {
        showInvisibles: false,
        useSoftTabs: false,
        fontSize: 14,
        tabSize: 2,
        showIndentGuides: false
      };
      EditorService.setSettings(newSettings);
      expect(EditorService.getSettings()).toEqual(newSettings);
      expect(sessMock.setUseSoftTabs).toHaveBeenCalledWith(false);
      expect(sessMock.setTabSize).toHaveBeenCalledWith(2);
      expect(aceMock.setShowInvisibles).toHaveBeenCalledWith(false);
      expect(aceMock.setFontSize).toHaveBeenCalledWith(14);
    }));
    it('should open a document', inject(function(EditorService){
      EditorService.onAceLoad(aceMock);
      var filepath = "/home/saurabh/file1";
      EditorService.openDocument(filepath);
      httpBackend.flush();
      expect(Object.keys(EditorService.getOpenDocs()).length).toBe(2);
      expect(EditorService.getCurrentDoc()).toBe("/home/saurabh/file1");
    }));
  });
});
<commit_msg>close document specs<commit_after>'use strict';

describe('oide.editor.EditorService', function() {
  beforeEach(module('oide'));
  beforeEach(module('oide.editor'));

  describe('oide.editor.EditorService settings', function() {
    var aceMock,sessMock, httpBackend;

    beforeEach(function() {
      sessMock = jasmine.createSpyObj(
        'sessMock',
        [
          'getUndoManager',
          'setUndoManager',
          'getDocument',
          'setUseSoftTabs',
          'setTabSize',
          'setUseWrapMode'
        ]
      );
      aceMock = jasmine.createSpyObj(
        'aceMock',
        [
          'setSession',
          'setShowInvisibles',
          'setFontSize',
          'setDisplayIndentGuides'
        ]
      );
      aceMock.getSession = function() {
        return sessMock;
      };
    });

    beforeEach(inject(function($httpBackend){
      httpBackend = $httpBackend;
      httpBackend.whenGET(/\/filebrowser\/localfiles.*/).respond(function(){
        var file = {
          contents: 'this is a basic file'
        };
        return [200, file];
      });
    }));

    it('starts with the correct defaults.', inject(function(EditorService) {
      var defaults = {
        showInvisibles: true,
        useSoftTabs: true,
        fontSize: 12,
        tabSize: 4,
        showIndentGuides: true,
        wordWrap: false
      };
      expect(EditorService.getSettings()).toEqual(defaults);
    }));
    it('correctly modifies settings.', inject(function(EditorService) {
      EditorService.onAceLoad(aceMock);
      var newSettings = {
        showInvisibles: false,
        useSoftTabs: false,
        fontSize: 14,
        tabSize: 2,
        showIndentGuides: false
      };
      EditorService.setSettings(newSettings);
      expect(EditorService.getSettings()).toEqual(newSettings);
      expect(sessMock.setUseSoftTabs).toHaveBeenCalledWith(false);
      expect(sessMock.setTabSize).toHaveBeenCalledWith(2);
      expect(aceMock.setShowInvisibles).toHaveBeenCalledWith(false);
      expect(aceMock.setFontSize).toHaveBeenCalledWith(14);
    }));
    it('should open a document', inject(function(EditorService){
      EditorService.onAceLoad(aceMock);
      var filepath = "/home/saurabh/file1";
      EditorService.openDocument(filepath);
      httpBackend.flush();
      expect(Object.keys(EditorService.getOpenDocs()).length).toBe(2);
      expect(EditorService.getCurrentDoc()).toBe("/home/saurabh/file1");
    }));
    it('should close a document when only 1 file', inject(function(EditorService){
      EditorService.onAceLoad(aceMock);
      var currentFile = EditorService.getCurrentDoc();
      EditorService.closeDocument(currentFile);
      expect(Object.keys(EditorService.getOpenDocs()).length).toBe(0);
    }));
    it('should close a document when multiple files are open', inject(function(EditorService){
      EditorService.onAceLoad(aceMock);
      var filename = "/home/saurabh/file1";
      EditorService.openDocument(filename);
      EditorService.closeDocument(filename);
      expect(Object.keys(EditorService.getOpenDocs()).length).toBe(1);
    }));
  });
});
<|endoftext|>


<commit_before>var schedule = require('node-schedule');
var moment = require("moment");

var bot = null;
var countdowns = {
	cccamp: '2015-08-13 00:00:00',
	'32c3': '2015-12-27 00:00:00',
};

var getDays = function(until) {
	var startDateTime = moment();
	var endDateTime = moment(until);
	var timeLeft = endDateTime.diff(startDateTime, 'milliseconds', true);
	var days = Math.floor(moment.duration(timeLeft).asDays());
	return days;
}

var getCountdown = function(nick, to, text, message) {
	for(var key in countdowns) {
		bot.respond(message, getDays(countdowns[key]) + " day(s) until " + key);
	}
}

var updateCountdown = function() {
	for(var key in countdowns) {
		bot.plugins['topic'].addData('countdown-'+key, getDays(countdowns[key]));
	}
	bot.plugins['topic'].updateTopic();
}

module.exports = {
	register: function(b) {
		bot = b;
		updateCountdown();
		bot.addMessageAction(function(nick, to, text, message){
			if(text.indexOf("!countdown") == -1)
				return false;
			return true;
		}, getCountdown);
		var job = schedule.scheduleJob('0 0 * * *', function(){
			updateCountdown();
		});
	},
	updateCountdown: updateCountdown
	help: [
		['!countdown', 'show countdown until $event in days'],
	],
};

<commit_msg>Small fix in coundown module<commit_after>var schedule = require('node-schedule');
var moment = require("moment");

var bot = null;
var countdowns = {
	cccamp: '2015-08-13 00:00:00',
	'32c3': '2015-12-27 00:00:00',
};

var getDays = function(until) {
	var startDateTime = moment();
	var endDateTime = moment(until);
	var timeLeft = endDateTime.diff(startDateTime, 'milliseconds', true);
	var days = Math.floor(moment.duration(timeLeft).asDays());
	return days;
}

var getCountdown = function(nick, to, text, message) {
	for(var key in countdowns) {
		bot.respond(message, getDays(countdowns[key]) + " day(s) until " + key);
	}
}

var updateCountdown = function() {
	for(var key in countdowns) {
		bot.plugins['topic'].addData('countdown-'+key, getDays(countdowns[key]));
	}
	bot.plugins['topic'].updateTopic();
}

module.exports = {
	register: function(b) {
		bot = b;
		updateCountdown();
		bot.addMessageAction(function(nick, to, text, message){
			if(text.indexOf("!countdown") == -1)
				return false;
			return true;
		}, getCountdown);
		var job = schedule.scheduleJob('0 0 * * *', function(){
			updateCountdown();
		});
	},
	updateCountdown: updateCountdown,
	help: [
		['!countdown', 'show countdown until $event in days'],
	],
};

<|endoftext|>


<commit_before>/**
 * dependencies
 */

var _       = require('lodash')
  , moment  = require('moment')
  , Promise = require('bluebird')
  , utils   = require('../libs/utils');

/**
 * global vars
 */

var cache = {};

/**
 * TODO write docs
 *
 * @param {String} [language]
 * @return {Promise}
 */

var loadMangaList = function(language) {

  // ensure language
  language = language || 'en';

  // if cached return
  if (cache[ language ]) return Promise.resolve(cache[ language ]);

  // set invalidate cache timeout
  setTimeout(function() {

    // invalidate cache
    delete cache[ language ];

  }, 60 * 60 * 1000); // 1h

  // get language ID
  var langID = language === 'it' ? 1 : 0;

  // api url (see mangaeden docs)
  var api = 'https://www.mangaeden.com/api/list/' + langID + '/';

  // launch web request
  return utils.ajax(api, { dataType: 'json' }).then(function(data) {

    // save result to cache and return
    return cache[ language ] = data;

  });

};

/**
 * TODO write docs
 *
 * @param {String} title
 * @param {String} [language]
 * @return {Promise}
 */

var searchTitle = function(title, language) {

  language = language || 'en';

  var template = _.template('http://www.mangaeden.com/<%= language %>/<%= language %>-manga/<%= title %>/');

  return loadMangaList(language).then(function(data) {

    var filtered = _.filter(data.manga, function(manga) {
      return utils.match(title, manga.a);
    });

    return _.map(filtered, function(manga) {
      return template({
        language: language,
        title: manga.a
      });
    });

  });

};

/**
 * start plugin-specific code to search comics
 *
 * @param {String} title      searched title
 * @param {Array} languages   requested languages
 * @param {Function} add      function to invoke with comic's attributes
 * @param {Function} end      function to invoke at the end of searching process
 */

var searchComics = function(title, languages, add, end) {

  var urls = [];

  Promise.each(languages, function(language) {

    return searchTitle(title, language).then(function(matching) {

      urls = urls.concat(matching);

    });

  }).then(function() {

    return urls;

  }).map(function(url) {

    return utils.ajax(url, { dataType: 'html' }).then(function($) {

      var author, artist;

      $('.rightBox a').each(function() {
        var $a = $(this);

        if ($a.attr('href').indexOf('?author=') >= 0) {
          author = $a.html();
        } else if ($a.attr('href').indexOf('?artist=') >= 0) {
          artist = $a.html();
        }
      });

      add({
        author      : author,
        artist      : artist,
        url         : url,
        language    : url.indexOf('/it-manga/') >= 0 ? 'it' : 'en',
        title       : $('.manga-title').html(),
        description : $('#mangaDescription').text(),
        thumbnail   : 'http:' + $('div.mangaImage2 img').attr('src')
      });

    });

  }).then(function() {

    end();

  }).catch(function(err) {

    end(err);

  });

};

/**
 * TODO write docs
 *
 * @param {ComicModel} comic    comic model instance
 * @param {Function} add        add chapter callback
 * @param {Function} end        process end callback
 */

var loadChapters = function(comic, add, end) {

  utils.ajax(comic.get('url'), { dataType: 'html' }).then(function($) {

    $('tr').each(function() {
      var $tr   = $(this)
        , link  = $tr.find('a.chapterLink');

      if (link.length <= 0) return;

      var url = link.attr('href');

      add({
        language  : comic.get('language'),
        title     : $tr.find('b').html(),
        number    : parseFloat(url.split('/')[4]),
        group     : $tr.find('td.hideM0').find('a').html(),
        url       : 'http://www.mangaeden.com' + url,
        added     : moment($tr.find('td.chapterDate').html(), 'MMM D, YYYY').toDate()
      });
    });

  }).then(function() {

    end();

  }).catch(function(err) {

    end(err);

  });

};

/**
 * TODO write docs
 *
 * @param {ChapterModel} chapter    chapter model instance
 * @param {Function} add            add page callback
 * @param {Function} end            process end callback
 */

var loadPages = function(chapter, add, end) {

  return utils.ajax(chapter.get('url'), { dataType: 'html' }).then(function($) {

    return $('select#pageSelect option').map(function() {
      return 'http://www.mangaeden.com' + $(this).attr('value');
    }).get();

  }).map(function(url) {

    return utils.ajax(url, { dataType: 'html' }).then(function($) {

      var data = url.split('/');

      add({
        number: parseInt(data[7], 10),
        url: 'http:' + $('img#mainImg').attr('src')
      });

    });

  }).then(function() {

    end();

  }).catch(function(err) {

    end(err);

  });

};

/**
 * exports
 */

module.exports = {

  // unique id for plugin identification
  id: 'mangaeden',

  // available languages for this plugin
  languages: [ 'en', 'it' ],

  // website url for credits
  url: 'http://www.mangaeden.com',

  // label used by GUI, default from ID
  name: 'Manga Eden',

  // thumbnail image used into gallery
  thumbnail: 'http://cdn.mangaeden.com/images/logo2.png',

  // short description
  description: 'Manga Eden plugin for GRABBIX',

  // plugin creator credits
  credits: 'greguz',

  // TODO write docs
  searchComics: searchComics,

  // TODO write docs
  loadChapters: loadChapters,

  // TODO write docs
  loadPages: loadPages

};
<commit_msg>removed comics with no chapters<commit_after>/**
 * dependencies
 */

var _       = require('lodash')
  , moment  = require('moment')
  , Promise = require('bluebird')
  , utils   = require('../libs/utils');

/**
 * global vars
 */

var cache = {};

/**
 * TODO write docs
 *
 * @param {String} [language]
 * @return {Promise}
 */

var loadMangaList = function(language) {

  // ensure language
  language = language || 'en';

  // if cached return
  if (cache[ language ]) return Promise.resolve(cache[ language ]);

  // set invalidate cache timeout
  setTimeout(function() {

    // invalidate cache
    delete cache[ language ];

  }, 60 * 60 * 1000); // 1h

  // get language ID
  var langID = language === 'it' ? 1 : 0;

  // api url (see mangaeden docs)
  var api = 'https://www.mangaeden.com/api/list/' + langID + '/';

  // launch web request
  return utils.ajax(api, { dataType: 'json' }).then(function(data) {

    // save result to cache and return
    return cache[ language ] = data;

  });

};

/**
 * TODO write docs
 *
 * @param {String} title
 * @param {String} [language]
 * @return {Promise}
 */

var searchTitle = function(title, language) {

  language = language || 'en';

  var template = _.template('http://www.mangaeden.com/<%= language %>/<%= language %>-manga/<%= title %>/');

  return loadMangaList(language).then(function(data) {

    var filtered = _.filter(data.manga, function(manga) {

      // check if this manga has at least one chapter
      if (!manga.ld) return false;

      // match searched title with manga title
      return utils.match(title, manga.a);

    });

    return _.map(filtered, function(manga) {
      return template({
        language: language,
        title: manga.a
      });
    });

  });

};

/**
 * start plugin-specific code to search comics
 *
 * @param {String} title      searched title
 * @param {Array} languages   requested languages
 * @param {Function} add      function to invoke with comic's attributes
 * @param {Function} end      function to invoke at the end of searching process
 */

var searchComics = function(title, languages, add, end) {

  var urls = [];

  Promise.each(languages, function(language) {

    return searchTitle(title, language).then(function(matching) {

      urls = urls.concat(matching);

    });

  }).then(function() {

    return urls;

  }).map(function(url) {

    return utils.ajax(url, { dataType: 'html' }).then(function($) {

      var author, artist;

      $('.rightBox a').each(function() {
        var $a = $(this);

        if ($a.attr('href').indexOf('?author=') >= 0) {
          author = $a.html();
        } else if ($a.attr('href').indexOf('?artist=') >= 0) {
          artist = $a.html();
        }
      });

      add({
        author      : author,
        artist      : artist,
        url         : url,
        language    : url.indexOf('/it-manga/') >= 0 ? 'it' : 'en',
        title       : $('.manga-title').html(),
        description : $('#mangaDescription').text(),
        thumbnail   : 'http:' + $('div.mangaImage2 img').attr('src')
      });

    });

  }).then(function() {

    end();

  }).catch(function(err) {

    end(err);

  });

};

/**
 * TODO write docs
 *
 * @param {ComicModel} comic    comic model instance
 * @param {Function} add        add chapter callback
 * @param {Function} end        process end callback
 */

var loadChapters = function(comic, add, end) {

  utils.ajax(comic.get('url'), { dataType: 'html' }).then(function($) {

    $('tr').each(function() {
      var $tr   = $(this)
        , link  = $tr.find('a.chapterLink');

      if (link.length <= 0) return;

      var url = link.attr('href');

      add({
        language  : comic.get('language'),
        title     : $tr.find('b').html(),
        number    : parseFloat(url.split('/')[4]),
        group     : $tr.find('td.hideM0').find('a').html(),
        url       : 'http://www.mangaeden.com' + url,
        added     : moment($tr.find('td.chapterDate').html(), 'MMM D, YYYY').toDate()
      });
    });

  }).then(function() {

    end();

  }).catch(function(err) {

    end(err);

  });

};

/**
 * TODO write docs
 *
 * @param {ChapterModel} chapter    chapter model instance
 * @param {Function} add            add page callback
 * @param {Function} end            process end callback
 */

var loadPages = function(chapter, add, end) {

  return utils.ajax(chapter.get('url'), { dataType: 'html' }).then(function($) {

    return $('select#pageSelect option').map(function() {
      return 'http://www.mangaeden.com' + $(this).attr('value');
    }).get();

  }).map(function(url) {

    return utils.ajax(url, { dataType: 'html' }).then(function($) {

      var data = url.split('/');

      add({
        number: parseInt(data[7], 10),
        url: 'http:' + $('img#mainImg').attr('src')
      });

    });

  }).then(function() {

    end();

  }).catch(function(err) {

    end(err);

  });

};

/**
 * exports
 */

module.exports = {

  // unique id for plugin identification
  id: 'mangaeden',

  // available languages for this plugin
  languages: [ 'en', 'it' ],

  // website url for credits
  url: 'http://www.mangaeden.com',

  // label used by GUI, default from ID
  name: 'Manga Eden',

  // thumbnail image used into gallery
  thumbnail: 'http://cdn.mangaeden.com/images/logo2.png',

  // short description
  description: 'Manga Eden plugin for GRABBIX',

  // plugin creator credits
  credits: 'greguz',

  // TODO write docs
  searchComics: searchComics,

  // TODO write docs
  loadChapters: loadChapters,

  // TODO write docs
  loadPages: loadPages

};
<|endoftext|>


<commit_before>/*
 * Copyright (c), Buddy Brewer.
 */

/**
\file navtiming.js
Plugin to collect metrics from the W3C Navigation Timing API. For more information about Navigation Timing,
see: http://www.w3.org/TR/navigation-timing/
*/

(function() {

// First make sure BOOMR is actually defined.  It's possible that your plugin is loaded before boomerang, in which case
// you'll need this.
BOOMR = BOOMR || {};
BOOMR.plugins = BOOMR.plugins || {};
if (BOOMR.plugins.NavigationTiming) {
	return;
}

// A private object to encapsulate all your implementation details
var impl = {
	complete: false,
	xhr_done: function(edata) {
		var w = BOOMR.window, res, data = {}, k;

		if (!edata) {
			return;
		}

		if (edata.data) {
			edata = edata.data;
		}

		if (edata.url && w.performance && w.performance.getEntriesByName) {
			res = w.performance.getEntriesByName(edata.url);
			if(res && res.length > 0) {
				res = res[0];

				data = {
					nt_red_st: res.redirectStart,
					nt_red_end: res.redirectEnd,
					nt_fet_st: res.fetchStart,
					nt_dns_st: res.domainLookupStart,
					nt_dns_end: res.domainLookupEnd,
					nt_con_st: res.connectStart,
					nt_con_end: res.connectEnd,
					nt_req_st: res.requestStart,
					nt_res_st: res.responseStart,
					nt_res_end: res.responseEnd
				};
				if (res.secureConnectionStart) {
					// secureConnectionStart is OPTIONAL in the spec
					data.nt_ssl_st = res.secureConnectionStart;
				}

				for(k in data) {
					if (data.hasOwnProperty(k) && data[k]) {
						data[k] += w.performance.timing.navigationStart;
					}
				}

			}
		}

		if (edata.timing) {
			res = edata.timing;
			if (!data.nt_req_st) {
				data.nt_req_st = res.requestStart;
			}
			if (!data.nt_res_st) {
				data.nt_res_st = res.responseStart;
			}
			if (!data.nt_res_end) {
				data.nt_res_end = res.responseEnd;
			}
			data.nt_domint = res.domInteractive;
			data.nt_load_st = res.loadEventEnd;
			data.nt_load_end = res.loadEventEnd;
		}

		for(k in data) {
			if (data.hasOwnProperty(k) && !data[k]) {
				delete data[k];
			}
		}

		BOOMR.addVar(data);

		try { impl.addedVars.push.apply(impl.addedVars, Object.keys(data)); } catch(ignore) {}

		this.complete = true;
		BOOMR.sendBeacon();
	},

	done: function() {
		var w = BOOMR.window, p, pn, pt, data;
		if(this.complete) {
			return this;
		}

		impl.addedVars = [];

		p = w.performance || w.msPerformance || w.webkitPerformance || w.mozPerformance;
		if(p && p.timing && p.navigation) {
			BOOMR.info("This user agent supports NavigationTiming.", "nt");
			pn = p.navigation;
			pt = p.timing;
			data = {
				nt_red_cnt: pn.redirectCount,
				nt_nav_type: pn.type,
				nt_nav_st: pt.navigationStart,
				nt_red_st: pt.redirectStart,
				nt_red_end: pt.redirectEnd,
				nt_fet_st: pt.fetchStart,
				nt_dns_st: pt.domainLookupStart,
				nt_dns_end: pt.domainLookupEnd,
				nt_con_st: pt.connectStart,
				nt_con_end: pt.connectEnd,
				nt_req_st: pt.requestStart,
				nt_res_st: pt.responseStart,
				nt_res_end: pt.responseEnd,
				nt_domloading: pt.domLoading,
				nt_domint: pt.domInteractive,
				nt_domcontloaded_st: pt.domContentLoadedEventStart,
				nt_domcontloaded_end: pt.domContentLoadedEventEnd,
				nt_domcomp: pt.domComplete,
				nt_load_st: pt.loadEventStart,
				nt_load_end: pt.loadEventEnd,
				nt_unload_st: pt.unloadEventStart,
				nt_unload_end: pt.unloadEventEnd
			};
			if (pt.secureConnectionStart) {
				// secureConnectionStart is OPTIONAL in the spec
				data.nt_ssl_st = pt.secureConnectionStart;
			}
			if (pt.msFirstPaint) {
				// msFirstPaint is IE9+ http://msdn.microsoft.com/en-us/library/ff974719
				data.nt_first_paint = pt.msFirstPaint;
			}

			BOOMR.addVar(data);

			try { impl.addedVars.push.apply(impl.addedVars, Object.keys(data)); } catch(ignore) {}
		}

		// XXX Inconsistency warning.  msFirstPaint above is in milliseconds while
		//     firstPaintTime below is in seconds.microseconds.  The server needs to deal with this.

		// This is Chrome only, so will not overwrite nt_first_paint above
		if(w.chrome && w.chrome.loadTimes) {
			pt = w.chrome.loadTimes();
			if(pt) {
				data = {
					nt_spdy: (pt.wasFetchedViaSpdy?1:0),
					nt_first_paint: pt.firstPaintTime
				};

				BOOMR.addVar(data);

				try { impl.addedVars.push.apply(impl.addedVars, Object.keys(data)); } catch(ignore) {}
			}
		}

		this.complete = true;
		BOOMR.sendBeacon();
	},

	clear: function(vars) {
		if (impl.addedVars && impl.addedVars.length > 0) {
			BOOMR.removeVar(impl.addedVars);
			impl.addedVars = [];
		}
		this.complete = false;
	}
};

BOOMR.plugins.NavigationTiming = {
	init: function() {
		if (!impl.initialized) {
			// we'll fire on whichever happens first
			BOOMR.subscribe("page_ready", impl.done, null, impl);
			BOOMR.subscribe("xhr_load", impl.xhr_done, null, impl);
			BOOMR.subscribe("page_unload", impl.done, null, impl);
			BOOMR.subscribe("onbeacon", impl.clear, null, impl);

			impl.initialized = true;
		}
		return this;
	},

	is_complete: function() {
		return impl.complete;
	}
};

}());

<commit_msg>add domcomplete from xhr to beacon<commit_after>/*
 * Copyright (c), Buddy Brewer.
 */

/**
\file navtiming.js
Plugin to collect metrics from the W3C Navigation Timing API. For more information about Navigation Timing,
see: http://www.w3.org/TR/navigation-timing/
*/

(function() {

// First make sure BOOMR is actually defined.  It's possible that your plugin is loaded before boomerang, in which case
// you'll need this.
BOOMR = BOOMR || {};
BOOMR.plugins = BOOMR.plugins || {};
if (BOOMR.plugins.NavigationTiming) {
	return;
}

// A private object to encapsulate all your implementation details
var impl = {
	complete: false,
	xhr_done: function(edata) {
		var w = BOOMR.window, res, data = {}, k;

		if (!edata) {
			return;
		}

		if (edata.data) {
			edata = edata.data;
		}

		if (edata.url && w.performance && w.performance.getEntriesByName) {
			res = w.performance.getEntriesByName(edata.url);
			if(res && res.length > 0) {
				res = res[0];

				data = {
					nt_red_st: res.redirectStart,
					nt_red_end: res.redirectEnd,
					nt_fet_st: res.fetchStart,
					nt_dns_st: res.domainLookupStart,
					nt_dns_end: res.domainLookupEnd,
					nt_con_st: res.connectStart,
					nt_con_end: res.connectEnd,
					nt_req_st: res.requestStart,
					nt_res_st: res.responseStart,
					nt_res_end: res.responseEnd
				};
				if (res.secureConnectionStart) {
					// secureConnectionStart is OPTIONAL in the spec
					data.nt_ssl_st = res.secureConnectionStart;
				}

				for(k in data) {
					if (data.hasOwnProperty(k) && data[k]) {
						data[k] += w.performance.timing.navigationStart;
					}
				}

			}
		}

		if (edata.timing) {
			res = edata.timing;
			if (!data.nt_req_st) {
				data.nt_req_st = res.requestStart;
			}
			if (!data.nt_res_st) {
				data.nt_res_st = res.responseStart;
			}
			if (!data.nt_res_end) {
				data.nt_res_end = res.responseEnd;
			}
			data.nt_domint = res.domInteractive;
			data.nt_domcomp = res.domComplete;
			data.nt_load_st = res.loadEventEnd;
			data.nt_load_end = res.loadEventEnd;
		}

		for(k in data) {
			if (data.hasOwnProperty(k) && !data[k]) {
				delete data[k];
			}
		}

		BOOMR.addVar(data);

		try { impl.addedVars.push.apply(impl.addedVars, Object.keys(data)); } catch(ignore) {}

		this.complete = true;
		BOOMR.sendBeacon();
	},

	done: function() {
		var w = BOOMR.window, p, pn, pt, data;
		if(this.complete) {
			return this;
		}

		impl.addedVars = [];

		p = w.performance || w.msPerformance || w.webkitPerformance || w.mozPerformance;
		if(p && p.timing && p.navigation) {
			BOOMR.info("This user agent supports NavigationTiming.", "nt");
			pn = p.navigation;
			pt = p.timing;
			data = {
				nt_red_cnt: pn.redirectCount,
				nt_nav_type: pn.type,
				nt_nav_st: pt.navigationStart,
				nt_red_st: pt.redirectStart,
				nt_red_end: pt.redirectEnd,
				nt_fet_st: pt.fetchStart,
				nt_dns_st: pt.domainLookupStart,
				nt_dns_end: pt.domainLookupEnd,
				nt_con_st: pt.connectStart,
				nt_con_end: pt.connectEnd,
				nt_req_st: pt.requestStart,
				nt_res_st: pt.responseStart,
				nt_res_end: pt.responseEnd,
				nt_domloading: pt.domLoading,
				nt_domint: pt.domInteractive,
				nt_domcontloaded_st: pt.domContentLoadedEventStart,
				nt_domcontloaded_end: pt.domContentLoadedEventEnd,
				nt_domcomp: pt.domComplete,
				nt_load_st: pt.loadEventStart,
				nt_load_end: pt.loadEventEnd,
				nt_unload_st: pt.unloadEventStart,
				nt_unload_end: pt.unloadEventEnd
			};
			if (pt.secureConnectionStart) {
				// secureConnectionStart is OPTIONAL in the spec
				data.nt_ssl_st = pt.secureConnectionStart;
			}
			if (pt.msFirstPaint) {
				// msFirstPaint is IE9+ http://msdn.microsoft.com/en-us/library/ff974719
				data.nt_first_paint = pt.msFirstPaint;
			}

			BOOMR.addVar(data);

			try { impl.addedVars.push.apply(impl.addedVars, Object.keys(data)); } catch(ignore) {}
		}

		// XXX Inconsistency warning.  msFirstPaint above is in milliseconds while
		//     firstPaintTime below is in seconds.microseconds.  The server needs to deal with this.

		// This is Chrome only, so will not overwrite nt_first_paint above
		if(w.chrome && w.chrome.loadTimes) {
			pt = w.chrome.loadTimes();
			if(pt) {
				data = {
					nt_spdy: (pt.wasFetchedViaSpdy?1:0),
					nt_first_paint: pt.firstPaintTime
				};

				BOOMR.addVar(data);

				try { impl.addedVars.push.apply(impl.addedVars, Object.keys(data)); } catch(ignore) {}
			}
		}

		this.complete = true;
		BOOMR.sendBeacon();
	},

	clear: function(vars) {
		if (impl.addedVars && impl.addedVars.length > 0) {
			BOOMR.removeVar(impl.addedVars);
			impl.addedVars = [];
		}
		this.complete = false;
	}
};

BOOMR.plugins.NavigationTiming = {
	init: function() {
		if (!impl.initialized) {
			// we'll fire on whichever happens first
			BOOMR.subscribe("page_ready", impl.done, null, impl);
			BOOMR.subscribe("xhr_load", impl.xhr_done, null, impl);
			BOOMR.subscribe("page_unload", impl.done, null, impl);
			BOOMR.subscribe("onbeacon", impl.clear, null, impl);

			impl.initialized = true;
		}
		return this;
	},

	is_complete: function() {
		return impl.complete;
	}
};

}());

<|endoftext|>


<commit_before>// $Revision$

Ensembl.LayoutManager = new Base();

Ensembl.LayoutManager.extend({
  constructor: null,

  /**
   * Creates events on elements outside of the domain of panels
   */
  initialize: function () {
    this.id = 'LayoutManager';

    Ensembl.EventManager.register('reloadPage', this, this.reloadPage);
    Ensembl.EventManager.register('validateForms', this, this.validateForms);
    Ensembl.EventManager.register('makeZMenu', this, this.makeZMenu);

    $('#local-tools').show();

    $('.modal_link').show().live('click', function () {
      // If ajax is not enabled, make popup config window
      // If ajax is enabled, modalOpen is triggered. If it doesn't returns true then there's no ModalContainer panel, so make popup config window
      if (Ensembl.ajax != 'enabled' || !Ensembl.EventManager.trigger('modalOpen', this)) {
        var name = 'cp_' + window.name;
        var w = window.open(this.href, name.replace(/cp_cp_/, 'cp_'), 'width=950,height=500,resizable,scrollbars');
        w.focus();
      }

      return false;
    });

    $('.popup').live('click', function () {
      var w = window.open(this.href, 'popup_' + window.name, 'width=950,height=500,resizable,scrollbars');
      w.focus();

      return false;
    });

    $('a[rel="external"]').live('click', function () {
      this.target = '_blank';
    });

    // using livequery plugin because .live doesn't support blur, focus, mouseenter, mouseleave, change or submit in IE
    $('form.check').livequery('submit', function () {
      var form = $(this);
      var rtn = form.parents('#modal_panel').length ?
                Ensembl.EventManager.trigger('modalFormSubmit', form) :
                Ensembl.FormValidator.submit(form);

      form = null;
      return rtn;
    });

    $(':input', 'form.check').live('keyup', function () {
      Ensembl.FormValidator.check($(this));
    }).livequery('change', function () {
      Ensembl.FormValidator.check($(this));
    }).livequery('blur', function () { // IE is stupid, so we need blur as well as change if you select from browser-stored values
      Ensembl.FormValidator.check($(this));
    }).each(function () {
      Ensembl.FormValidator.check($(this));
    });

    // For non ajax support - popup window close button
    var close = $('.popup_close');

    if (close.length) {
      if ($('input.panel_type[value=Configurator]').length) {
        close.html('Save and close').click(function () {
          if (Ensembl.EventManager.trigger('updateConfiguration') || window.location.search.match('reset=1')) {
            window.open(Ensembl.replaceTimestamp(this.href), window.name.replace(/^cp_/, '')); // Reload the main page
          }

          window.close();

          return false;
        });
      } else {
        close.hide();
      }
    }

    close = null;

    // Close modal window if the escape key is pressed
    $(document).keyup(function (event) {
      if (event.keyCode == 27) {
        Ensembl.EventManager.trigger('modalClose');
      }
    }).mouseup(function (e) {
      Ensembl.EventManager.trigger('dragStop', e);
    });
  },

  reloadPage: function () {
    var date = new Date();
    var time = date.getTime() + date.getMilliseconds() / 1000;
    var url = window.location.href.replace(/&/g, ';').replace(/#.*$/g, '').replace(/\?time=[^;]+;?/g, '?').replace(/;time=[^;]+;?/g, ';').replace(/[\?;]$/g, '');

    window.location = url + (url.match(/\?/) ? ';' : '?') + 'time=' + time;
  },

  validateForms: function (context) {
    $('form.check', context).find(':input').each(function () {
      Ensembl.FormValidator.check($(this));
    });
  },

  makeZMenu: function (id, params) {
    $('
' +
      '
' +
      '
X
' +
      '
' +
      '

' +
      '
').draggable({ handle: 'thead' }).appendTo('body');

    Ensembl.EventManager.trigger('addPanel', id, 'ZMenu', undefined, undefined, params, 'showExistingZMenu');
  }
});<commit_msg>tweak reloadPage, add user message stuff<commit_after>// $Revision$

Ensembl.LayoutManager = new Base();

Ensembl.LayoutManager.extend({
  constructor: null,

  /**
   * Creates events on elements outside of the domain of panels
   */
  initialize: function () {
    this.id = 'LayoutManager';

    Ensembl.EventManager.register('reloadPage', this, this.reloadPage);
    Ensembl.EventManager.register('validateForms', this, this.validateForms);
    Ensembl.EventManager.register('makeZMenu', this, this.makeZMenu);

    $('#local-tools').show();

    $('.modal_link').show().live('click', function () {
      // If ajax is not enabled, make popup config window
      // If ajax is enabled, modalOpen is triggered. If it doesn't returns true then there's no ModalContainer panel, so make popup config window
      if (Ensembl.ajax != 'enabled' || !Ensembl.EventManager.trigger('modalOpen', this)) {
        var name = 'cp_' + window.name;
        var w = window.open(this.href, name.replace(/cp_cp_/, 'cp_'), 'width=950,height=500,resizable,scrollbars');
        w.focus();
      }

      return false;
    });

    $('.popup').live('click', function () {
      var w = window.open(this.href, 'popup_' + window.name, 'width=950,height=500,resizable,scrollbars');
      w.focus();

      return false;
    });

    $('a[rel="external"]').live('click', function () {
      this.target = '_blank';
    });

    // using livequery plugin because .live doesn't support blur, focus, mouseenter, mouseleave, change or submit in IE
    $('form.check').livequery('submit', function () {
      var form = $(this);
      var rtn = form.parents('#modal_panel').length ?
                Ensembl.EventManager.trigger('modalFormSubmit', form) :
                Ensembl.FormValidator.submit(form);

      form = null;
      return rtn;
    });

    $(':input', 'form.check').live('keyup', function () {
      Ensembl.FormValidator.check($(this));
    }).livequery('change', function () {
      Ensembl.FormValidator.check($(this));
    }).livequery('blur', function () { // IE is stupid, so we need blur as well as change if you select from browser-stored values
      Ensembl.FormValidator.check($(this));
    }).each(function () {
      Ensembl.FormValidator.check($(this));
    });

    // For non ajax support - popup window close button
    var close = $('.popup_close');

    if (close.length) {
      if ($('input.panel_type[value=Configurator]').length) {
        close.html('Save and close').click(function () {
          if (Ensembl.EventManager.trigger('updateConfiguration') || window.location.search.match('reset=1')) {
            window.open(Ensembl.replaceTimestamp(this.href), window.name.replace(/^cp_/, '')); // Reload the main page
          }

          window.close();

          return false;
        });
      } else {
        close.hide();
      }
    }

    close = null;

    // Close modal window if the escape key is pressed
    $(document).keyup(function (event) {
      if (event.keyCode == 27) {
        Ensembl.EventManager.trigger('modalClose');
      }
    }).mouseup(function (e) {
      Ensembl.EventManager.trigger('dragStop', e);
    });

    var userMessage = unescape(Ensembl.cookie.get('user_message'));

    if (userMessage) {
      userMessage = userMessage.split('\n');

      $('
' +
        '
' + userMessage[0] + '
' +
        '
' + userMessage[1] + '
' +
        '
').prependTo('#main').find('h3 img, a').click(function () {
        $(this).parents('div.hint').remove();
        Ensembl.cookie.set('user_message', '', -1);
      });
    }
  },

  reloadPage: function (args) {
    if (typeof args == 'string') {
      Ensembl.EventManager.triggerSpecific('updatePanel', args);
    } else if (typeof args == 'object') {
      for (var i in args) {
        Ensembl.EventManager.triggerSpecific('updatePanel', i);
      }
    } else {
      window.location = Ensembl.replaceTimestamp(window.location.href);
    }
  },

  validateForms: function (context) {
    $('form.check', context).find(':input').each(function () {
      Ensembl.FormValidator.check($(this));
    });
  },

  makeZMenu: function (id, params) {
    $('
' +
      '
' +
      '
X
' +
      '
' +
      '

' +
      '
').draggable({ handle: 'thead' }).appendTo('body');

    Ensembl.EventManager.trigger('addPanel', id, 'ZMenu', undefined, undefined, params, 'showExistingZMenu');
  }
});<|endoftext|>


<commit_before>var templates = [
    "root/externallib/text!root/plugins/page/view.html",
    "root/externallib/text!root/plugins/page/dialog.html",
	"root/externallib/text!root/plugins/page/test_page.html"
];

define(templates, function (viewTpl, dialogTpl, testpageTpl) {
    var plugin = {
        settings: {
            name: "page",
            type: "mod",
            component: "mod_page",
            lang: {
                component: "core"
            }
        },

        render: function(courseId, sectionId, section, module) {
            var data = {
                "courseId": courseId,
                "sectionId": sectionId,
                "section": section,
                "module": module
            };

            return MM.tpl.render(MM.plugins.page.templates.view.html, data);
        },

        /**
         * Callback executed when the contents page is rendered.
         */
        contentsPageRendered: function() {

            $(".page-downloaded").on(MM.clickType, function(e) {
                e.preventDefault();
                var path = $(this).data("path");
                path = path.substring(0, path.lastIndexOf("/") + 1) + "index.html";
                path = MM.fs.getRoot() + "/" + path;

                MM.plugins.page._showPage(path);
            });

            $(".page-download-all").on(MM.clickType, function(e) {
                e.preventDefault();

                var contentId = $(this).data("content");
                var courseId = $(this).data("course");
                var sectionId = $(this).data("section");

                var downloadIcon = $("#download-all-" + contentId);
                if (downloadIcon) {
                    downloadIcon.attr("src", "img/loadingblack.gif");
                }

                var that = $(this);

                var errorFn = function() {
                    downloadIcon.attr("src", "img/download.png");
                    MM.popErrorMessage(MM.lang.s("errordownloading"));
                };

                // Download all the page images, css, etc...
                MM.plugins.contents.downloadAll(courseId, sectionId, contentId,
                    // Success.
                    function(paths) {
                        downloadIcon.remove();
                        var path = paths[0].filePath;
                        path = path.substring(0, path.lastIndexOf("/") + 1);
                        var link = $("#page-" + contentId);
                        link.attr("data-path", path);
                        link.removeClass("page-download-all").addClass("page-downloaded");

                        var indexFileURL = MM.fs.getRoot() + "/" + path + "index.html";

                        MM.plugins.page._showPage(indexFileURL);
                    },
                    // Error.
                    errorFn
                );
            });
        },

        _showPage: function(path) {
            var data = {
                path: path
            };
            var title = MM.tpl.render(MM.plugins.page.templates.dialog.html, data);

            MM.widgets.renderIframeModal(title, path);
        },

        templates: {
            "view": {
                html: viewTpl
            },
            "dialog": {
                html: dialogTpl
            },
			"": {
				html: test_pageTpl
			}
        }

    };

    MM.registerPlugin(plugin);

});<commit_msg>commented all page tpl entries<commit_after>var templates = [
    "root/externallib/text!root/plugins/page/view.html",
    "root/externallib/text!root/plugins/page/dialog.html"
	//"root/externallib/text!root/plugins/page/test_page.html"
];

define(templates, function (viewTpl, dialogTpl /*testpageTpl*/) {
    var plugin = {
        settings: {
            name: "page",
            type: "mod",
            component: "mod_page",
            lang: {
                component: "core"
            }
        },

        render: function(courseId, sectionId, section, module) {
            var data = {
                "courseId": courseId,
                "sectionId": sectionId,
                "section": section,
                "module": module
            };

            return MM.tpl.render(MM.plugins.page.templates.view.html, data);
        },

        /**
         * Callback executed when the contents page is rendered.
         */
        contentsPageRendered: function() {

            $(".page-downloaded").on(MM.clickType, function(e) {
                e.preventDefault();
                var path = $(this).data("path");
                path = path.substring(0, path.lastIndexOf("/") + 1) + "index.html";
                path = MM.fs.getRoot() + "/" + path;

                MM.plugins.page._showPage(path);
            });

            $(".page-download-all").on(MM.clickType, function(e) {
                e.preventDefault();

                var contentId = $(this).data("content");
                var courseId = $(this).data("course");
                var sectionId = $(this).data("section");

                var downloadIcon = $("#download-all-" + contentId);
                if (downloadIcon) {
                    downloadIcon.attr("src", "img/loadingblack.gif");
                }

                var that = $(this);

                var errorFn = function() {
                    downloadIcon.attr("src", "img/download.png");
                    MM.popErrorMessage(MM.lang.s("errordownloading"));
                };

                // Download all the page images, css, etc...
                MM.plugins.contents.downloadAll(courseId, sectionId, contentId,
                    // Success.
                    function(paths) {
                        downloadIcon.remove();
                        var path = paths[0].filePath;
                        path = path.substring(0, path.lastIndexOf("/") + 1);
                        var link = $("#page-" + contentId);
                        link.attr("data-path", path);
                        link.removeClass("page-download-all").addClass("page-downloaded");

                        var indexFileURL = MM.fs.getRoot() + "/" + path + "index.html";

                        MM.plugins.page._showPage(indexFileURL);
                    },
                    // Error.
                    errorFn
                );
            });
        },

        _showPage: function(path) {
            var data = {
                path: path
            };
            var title = MM.tpl.render(MM.plugins.page.templates.dialog.html, data);

            MM.widgets.renderIframeModal(title, path);
        },

        templates: {
            "view": {
                html: viewTpl
            },
            "dialog": {
                html: dialogTpl
            }
			/*"test_page": {
				html: test_pageTpl
			}*/
        }

    };

    MM.registerPlugin(plugin);

});
<|endoftext|>


<commit_before><?php
/*
Copyright 2010 Google Inc.

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.
*/

require_once("utils.php");

$gPageid = ( array_key_exists('pageid', $_GET) ? $_GET['pageid'] : "" );

$query = "select harfile, url, wptid, wptrun, onLoad, renderStart from $gPagesTable where pageid=$gPageid;";

$result = doQuery($query);
$row = mysql_fetch_assoc($result);
$harfile = $row['harfile'];
$url = $row['url'];
$wptid = $row['wptid'];
$wptrun = $row['wptrun'];
$onLoad = $row['onLoad'];
$interval = ( $onLoad > 15000 ? 5000 : ( $onLoad > 4000 ? 1000 : ( $onLoad > 1000 ? 500 : 100 ) ) );
$renderStart = $row['renderStart'];

$xmlurl = "http://httparchive.webpagetest.org/xmlResult.php?test=$wptid";
$xmlstr = file_get_contents($xmlurl);
$xml = new SimpleXMLElement($xmlstr);
$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;

$aTimes = array();
foreach($frames->frame as $frame) {
	$time = floatval($frame->time) * 1000;
	$aTimes[$time] = true;
}

$sTh = "";
$sTd = "";
$aMatches = array();
$url = "";
$pattern = '/([0-9][0-9])([0-9][0-9])([0-9][0-9])_(.*)/';
if ( preg_match($pattern, $wptid, $aMatches) ) {
	$url = "http://httparchive.webpagetest.org/results/" . $aMatches[1] . "/" . $aMatches[2] . "/" . $aMatches[3] . "/" . $aMatches[4] . "/video_$wptrun/frame_";
}
$lastFrameTime = 0;
for ( $i = 0; $i < ($onLoad+100); $i += 100 ) {
	$sTh .= "" . ($i/1000) . "s	 ";
	//$border = "";
	$class = "thumb";
	if ( array_key_exists($i, $aTimes) ) {
		$lastFrameTime = $i;
		//$border = "style='border: 3px solid #FEB301;'";
		$class = "thumb changed";
	}
	$f = "0000" . ($lastFrameTime/100);
	$f = substr($f, strlen($f)-4);
	$sTd .= "	";
}
?>

var sTh = "<?php echo $sTh ?>";
var sTd = "<?php echo $sTd ?>";
document.getElementById('videoDiv').innerHTML = "

" + sTh + "

" + sTd + "

";
showInterval(<?php echo $interval ?>);
<commit_msg>remove unused $harfile variable<commit_after><?php
/*
Copyright 2010 Google Inc.

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.
*/

require_once("utils.php");

$gPageid = ( array_key_exists('pageid', $_GET) ? $_GET['pageid'] : "" );

$query = "select url, wptid, wptrun, onLoad, renderStart from $gPagesTable where pageid=$gPageid;";

$result = doQuery($query);
$row = mysql_fetch_assoc($result);
$url = $row['url'];
$wptid = $row['wptid'];
$wptrun = $row['wptrun'];
$onLoad = $row['onLoad'];
$interval = ( $onLoad > 15000 ? 5000 : ( $onLoad > 4000 ? 1000 : ( $onLoad > 1000 ? 500 : 100 ) ) );
$renderStart = $row['renderStart'];

$xmlurl = "http://httparchive.webpagetest.org/xmlResult.php?test=$wptid";
$xmlstr = file_get_contents($xmlurl);
$xml = new SimpleXMLElement($xmlstr);
$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;

$aTimes = array();
foreach($frames->frame as $frame) {
	$time = floatval($frame->time) * 1000;
	$aTimes[$time] = true;
}

$sTh = "";
$sTd = "";
$aMatches = array();
$url = "";
$pattern = '/([0-9][0-9])([0-9][0-9])([0-9][0-9])_(.*)/';
if ( preg_match($pattern, $wptid, $aMatches) ) {
	$url = "http://httparchive.webpagetest.org/results/" . $aMatches[1] . "/" . $aMatches[2] . "/" . $aMatches[3] . "/" . $aMatches[4] . "/video_$wptrun/frame_";
}
$lastFrameTime = 0;
for ( $i = 0; $i < ($onLoad+100); $i += 100 ) {
	$sTh .= "" . ($i/1000) . "s	 ";
	//$border = "";
	$class = "thumb";
	if ( array_key_exists($i, $aTimes) ) {
		$lastFrameTime = $i;
		//$border = "style='border: 3px solid #FEB301;'";
		$class = "thumb changed";
	}
	$f = "0000" . ($lastFrameTime/100);
	$f = substr($f, strlen($f)-4);
	$sTd .= "	";
}
?>

var sTh = "<?php echo $sTh ?>";
var sTd = "<?php echo $sTd ?>";
document.getElementById('videoDiv').innerHTML = "

" + sTh + "

" + sTd + "

";
showInterval(<?php echo $interval ?>);
<|endoftext|>


<commit_before>export default class Toast {
    static instance;
    constructor(board) {
        const $boardView = $(board.view);

        if (!$boardView.find('.entryMobileToast') && Toast.instance) {
            return Toast.instance;
        }
        this.board = board;
        this.$boardView = $boardView;
        this.generateView();
        Toast.instance = this;
    }

    generateView() {
        const template = `

        `;
        this.$view = $('
').append(template);
        this.$toast = this.$view.find('.entryMobileToast');
        this.$content = this.$view.find('.content');
        if (!this.$boardView.has(this.$view).length) {
            this.$boardView.append(this.$view);
        }
    }

    show(message) {
        this.$content.text(message);
        this.$toast.removeClass('fadeToast');
        $(this.$toast).width();
        this.$toast.addClass('fadeToast');
        this.removeToast(this);
    }

    // 애니메이션 Debounce 처리
    removeToast = _.debounce((toast) => {
        toast.$toast.removeClass('fadeToast');
    }, 3000);

    destroy() {
        delete this.$boardView;
        delete this.board;
        delete this.$view;
        delete this.$toast;
        delete this.$content;
        delete Toast.instance;
    }
}
<commit_msg>board view 에 토스트 엘리먼트가 없는 경우 주입하는 로직으로 수정<commit_after>export default class Toast {
    static instance;
    constructor(board) {
        const $boardView = $(board.view);

        if (Toast.instance) {
            const instance = Toast.instance;
            if ($boardView.find('.entryMobileToast')) {
                instance.board = board;
                instance.$boardView = $boardView;
                instance.$boardView.append(instance.$view);
            }
            return instance;
        }
        this.board = board;
        this.$boardView = $boardView;
        this.generateView();
        Toast.instance = this;
    }

    generateView() {
        const template = `

        `;
        this.$view = $('
').append(template);
        this.$toast = this.$view.find('.entryMobileToast');
        this.$content = this.$view.find('.content');
        if (!this.$boardView.has(this.$view).length) {
            this.$boardView.append(this.$view);
        }
    }

    show(message) {
        this.$content.text(message);
        this.$toast.removeClass('fadeToast');
        $(this.$toast).width();
        this.$toast.addClass('fadeToast');
        this.removeToast(this);
    }

    // 애니메이션 Debounce 처리
    removeToast = _.debounce((toast) => {
        toast.$toast.removeClass('fadeToast');
    }, 3000);

    destroy() {
        delete this.$boardView;
        delete this.board;
        delete this.$view;
        delete this.$toast;
        delete this.$content;
        delete Toast.instance;
    }
}
<|endoftext|>


<commit_before>/**
 * This plugin provides "drag-down" and "copy-down" functionalities, both operated
 * using the small square in the right bottom of the cell selection.
 *
 * "Drag-down" expands the value of the selected cells to the neighbouring
 * cells when you drag the small square in the corner.
 *
 * "Copy-down" copies the value of the selection to all empty cells
 * below when you double click the small square.
 */
(function (Handsontable) {
  'use strict';

  function Autofill(instance) {
    this.instance = instance;
    this.addingStarted = false;

    var $document = $(document),
      wtOnCellCornerMouseDown,
      wtOnCellMouseOver;

    $(this.instance.$table).off('mouseup.' + instance.guid).on('mouseup.' + instance.guid, function (event) {
      if (instance.autofill.handle && instance.autofill.handle.isDragged) {
        if (instance.autofill.handle.isDragged > 1) {
          instance.autofill.apply();
        }
        instance.autofill.handle.isDragged = 0;
      }
    });

    /*
     * Appeding autofill-specific methods to walkontable event settings
     */
    wtOnCellCornerMouseDown = this.instance.view.wt.wtSettings.settings.onCellCornerMouseDown;
    this.instance.view.wt.wtSettings.settings.onCellCornerMouseDown = function(event) {
      instance.autofill.handle.isDragged = 1;
      wtOnCellCornerMouseDown(event);
    }

    wtOnCellMouseOver = this.instance.view.wt.wtSettings.settings.onCellMouseOver;
    this.instance.view.wt.wtSettings.settings.onCellMouseOver = function(event, coords, TD, wt) {

      if (instance.autofill && (!instance.view.isMouseDown() && instance.autofill.handle && instance.autofill.handle.isDragged)) {
        instance.autofill.handle.isDragged++;
        instance.autofill.showBorder(coords);
        instance.autofill.checkIfNewRowNeeded();
      }

      wtOnCellMouseOver(event, coords, TD, wt);
    }

    this.instance.view.wt.wtSettings.settings.onCellCornerDblClick = function () {
      instance.autofill.selectAdjacent();
    };

  };

  /**
   * Create fill handle and fill border objects
   */
  Autofill.prototype.init = function () {
    this.handle = {};
  },

  /**
   * Hide fill handle and fill border permanently
   */
    Autofill.prototype.disable = function () {
      this.handle.disabled = true;
    },

  /**
   * Selects cells down to the last row in the left column, then fills down to that cell
   */
    Autofill.prototype.selectAdjacent = function () {
      var select, data, r, maxR, c;

      if (this.instance.selection.isMultiple()) {
        select = this.instance.view.wt.selections.area.getCorners();
      }
      else {
        select = this.instance.view.wt.selections.current.getCorners();
      }

      data = this.instance.getData();
      rows : for (r = select[2] + 1; r < this.instance.countRows(); r++) {
        for (c = select[1]; c <= select[3]; c++) {
          if (data[r][c]) {
            break rows;
          }
        }
        if (!!data[r][select[1] - 1] || !!data[r][select[3] + 1]) {
          maxR = r;
        }
      }
      if (maxR) {
        this.instance.view.wt.selections.fill.clear();
        this.instance.view.wt.selections.fill.add(new WalkontableCellCoords(select[0], select[1]));
        this.instance.view.wt.selections.fill.add(new WalkontableCellCoords(maxR, select[3]));
        this.apply();
      }
    },

  /**
   * Apply fill values to the area in fill border, omitting the selection border
   */
    Autofill.prototype.apply = function () {
      var drag, select, start, end, _data;

      this.handle.isDragged = 0;

      drag = this.instance.view.wt.selections.fill.getCorners();
      if (!drag) {
        return;
      }

      this.instance.view.wt.selections.fill.clear();

      if (this.instance.selection.isMultiple()) {
        select = this.instance.view.wt.selections.area.getCorners();
      }
      else {
        select = this.instance.view.wt.selections.current.getCorners();
      }

      if (drag[0] === select[0] && drag[1] < select[1]) {
        start = new WalkontableCellCoords(
          drag[0],
          drag[1]
        );
        end = new WalkontableCellCoords(
          drag[2],
          select[1] - 1
        );
      }
      else if (drag[0] === select[0] && drag[3] > select[3]) {
        start = new WalkontableCellCoords(
          drag[0],
          select[3] + 1
        );
        end = new WalkontableCellCoords(
          drag[2],
          drag[3]
        );
      }
      else if (drag[0] < select[0] && drag[1] === select[1]) {
        start = new WalkontableCellCoords(
          drag[0],
          drag[1]
        );
        end = new WalkontableCellCoords(
          select[0] - 1,
          drag[3]
        );
      }
      else if (drag[2] > select[2] && drag[1] === select[1]) {
        start = new WalkontableCellCoords(
          select[2] + 1,
          drag[1]
        );
        end = new WalkontableCellCoords(
          drag[2],
          drag[3]
        );
      }

      if (start) {
        var selRange = {from: this.instance.getSelectedRange().from, to: this.instance.getSelectedRange().to};

        _data = this.instance.getData(selRange.from.row,selRange.from.col,selRange.to.row,selRange.to.col);

        Handsontable.hooks.run(this.instance, 'beforeAutofill', start, end, _data);

        this.instance.populateFromArray(start.row, start.col, _data, end.row, end.col, 'autofill');

        this.instance.selection.setRangeStart(new WalkontableCellCoords(drag[0], drag[1]));
        this.instance.selection.setRangeEnd(new WalkontableCellCoords(drag[2], drag[3]));
      }
      /*else {
       //reset to avoid some range bug
       selection.refreshBorders();
       }*/
    },

  /**
   * Show fill border
   * @param {WalkontableCellCoords} coords
   */
    Autofill.prototype.showBorder = function (coords) {
      var topLeft = this.instance.getSelectedRange().getTopLeftCorner();
      var bottomRight = this.instance.getSelectedRange().getBottomRightCorner();
      if (this.instance.getSettings().fillHandle !== 'horizontal' && (bottomRight.row < coords.row || topLeft.row > coords.row)) {
        coords = new WalkontableCellCoords(coords.row, bottomRight.col);
      }
      else if (this.instance.getSettings().fillHandle !== 'vertical') {
        coords = new WalkontableCellCoords(bottomRight.row, coords.col);
      }
      else {
        return; //wrong direction
      }

      this.instance.view.wt.selections.fill.clear();
      this.instance.view.wt.selections.fill.add(this.instance.getSelectedRange().from);
      this.instance.view.wt.selections.fill.add(this.instance.getSelectedRange().to);
      this.instance.view.wt.selections.fill.add(coords);
      this.instance.view.render();
    }

  Autofill.prototype.checkIfNewRowNeeded = function() {
    var fillCorners,
      tableRows = this.instance.countRows(),
      that = this;

    if(this.instance.view.wt.selections.fill.cellRange && this.addingStarted === false) {
      fillCorners = this.instance.view.wt.selections.fill.getCorners();

      if(fillCorners[2] === tableRows - 1) {
        this.addingStarted = true;

        setTimeout(function() {
          that.instance.alter('insert_row');
          that.addingStarted = false;
        }, 200);
      }
    }

  }

  Handsontable.hooks.add('afterInit', function(){
    var autofill = new Autofill(this);

    if (typeof this.getSettings().fillHandle !== "undefined") {
      if (autofill.handle && this.getSettings().fillHandle === false) {
        autofill.disable();
      }
      else if (!autofill.handle && this.getSettings().fillHandle !== false) {
        this.autofill = autofill;
        this.autofill.init();
      }
    }

  });

  Handsontable.Autofill = Autofill;

})(Handsontable);<commit_msg>#10019 - Fix for fillHandle causing an error with autofill<commit_after>/**
 * This plugin provides "drag-down" and "copy-down" functionalities, both operated
 * using the small square in the right bottom of the cell selection.
 *
 * "Drag-down" expands the value of the selected cells to the neighbouring
 * cells when you drag the small square in the corner.
 *
 * "Copy-down" copies the value of the selection to all empty cells
 * below when you double click the small square.
 */
(function (Handsontable) {
  'use strict';

  function Autofill(instance) {
    this.instance = instance;
    this.addingStarted = false;

    var $document = $(document),
      wtOnCellCornerMouseDown,
      wtOnCellMouseOver;

    $(this.instance.$table).off('mouseup.' + instance.guid).on('mouseup.' + instance.guid, function (event) {
      if(!instance.autofill) {
        return true;
      }

      if (instance.autofill.handle && instance.autofill.handle.isDragged) {
        if (instance.autofill.handle.isDragged > 1) {
          instance.autofill.apply();
        }
        instance.autofill.handle.isDragged = 0;
      }
    });

    /*
     * Appeding autofill-specific methods to walkontable event settings
     */
    wtOnCellCornerMouseDown = this.instance.view.wt.wtSettings.settings.onCellCornerMouseDown;
    this.instance.view.wt.wtSettings.settings.onCellCornerMouseDown = function(event) {
      instance.autofill.handle.isDragged = 1;
      wtOnCellCornerMouseDown(event);
    }

    wtOnCellMouseOver = this.instance.view.wt.wtSettings.settings.onCellMouseOver;
    this.instance.view.wt.wtSettings.settings.onCellMouseOver = function(event, coords, TD, wt) {

      if (instance.autofill && (!instance.view.isMouseDown() && instance.autofill.handle && instance.autofill.handle.isDragged)) {
        instance.autofill.handle.isDragged++;
        instance.autofill.showBorder(coords);
        instance.autofill.checkIfNewRowNeeded();
      }

      wtOnCellMouseOver(event, coords, TD, wt);
    }

    this.instance.view.wt.wtSettings.settings.onCellCornerDblClick = function () {
      instance.autofill.selectAdjacent();
    };

  };

  /**
   * Create fill handle and fill border objects
   */
  Autofill.prototype.init = function () {
    this.handle = {};
  },

  /**
   * Hide fill handle and fill border permanently
   */
    Autofill.prototype.disable = function () {
      this.handle.disabled = true;
    },

  /**
   * Selects cells down to the last row in the left column, then fills down to that cell
   */
    Autofill.prototype.selectAdjacent = function () {
      var select, data, r, maxR, c;

      if (this.instance.selection.isMultiple()) {
        select = this.instance.view.wt.selections.area.getCorners();
      }
      else {
        select = this.instance.view.wt.selections.current.getCorners();
      }

      data = this.instance.getData();
      rows : for (r = select[2] + 1; r < this.instance.countRows(); r++) {
        for (c = select[1]; c <= select[3]; c++) {
          if (data[r][c]) {
            break rows;
          }
        }
        if (!!data[r][select[1] - 1] || !!data[r][select[3] + 1]) {
          maxR = r;
        }
      }
      if (maxR) {
        this.instance.view.wt.selections.fill.clear();
        this.instance.view.wt.selections.fill.add(new WalkontableCellCoords(select[0], select[1]));
        this.instance.view.wt.selections.fill.add(new WalkontableCellCoords(maxR, select[3]));
        this.apply();
      }
    },

  /**
   * Apply fill values to the area in fill border, omitting the selection border
   */
    Autofill.prototype.apply = function () {
      var drag, select, start, end, _data;

      this.handle.isDragged = 0;

      drag = this.instance.view.wt.selections.fill.getCorners();
      if (!drag) {
        return;
      }

      this.instance.view.wt.selections.fill.clear();

      if (this.instance.selection.isMultiple()) {
        select = this.instance.view.wt.selections.area.getCorners();
      }
      else {
        select = this.instance.view.wt.selections.current.getCorners();
      }

      if (drag[0] === select[0] && drag[1] < select[1]) {
        start = new WalkontableCellCoords(
          drag[0],
          drag[1]
        );
        end = new WalkontableCellCoords(
          drag[2],
          select[1] - 1
        );
      }
      else if (drag[0] === select[0] && drag[3] > select[3]) {
        start = new WalkontableCellCoords(
          drag[0],
          select[3] + 1
        );
        end = new WalkontableCellCoords(
          drag[2],
          drag[3]
        );
      }
      else if (drag[0] < select[0] && drag[1] === select[1]) {
        start = new WalkontableCellCoords(
          drag[0],
          drag[1]
        );
        end = new WalkontableCellCoords(
          select[0] - 1,
          drag[3]
        );
      }
      else if (drag[2] > select[2] && drag[1] === select[1]) {
        start = new WalkontableCellCoords(
          select[2] + 1,
          drag[1]
        );
        end = new WalkontableCellCoords(
          drag[2],
          drag[3]
        );
      }

      if (start) {
        var selRange = {from: this.instance.getSelectedRange().from, to: this.instance.getSelectedRange().to};

        _data = this.instance.getData(selRange.from.row,selRange.from.col,selRange.to.row,selRange.to.col);

        Handsontable.hooks.run(this.instance, 'beforeAutofill', start, end, _data);

        this.instance.populateFromArray(start.row, start.col, _data, end.row, end.col, 'autofill');

        this.instance.selection.setRangeStart(new WalkontableCellCoords(drag[0], drag[1]));
        this.instance.selection.setRangeEnd(new WalkontableCellCoords(drag[2], drag[3]));
      }
      /*else {
       //reset to avoid some range bug
       selection.refreshBorders();
       }*/
    },

  /**
   * Show fill border
   * @param {WalkontableCellCoords} coords
   */
    Autofill.prototype.showBorder = function (coords) {
      var topLeft = this.instance.getSelectedRange().getTopLeftCorner();
      var bottomRight = this.instance.getSelectedRange().getBottomRightCorner();
      if (this.instance.getSettings().fillHandle !== 'horizontal' && (bottomRight.row < coords.row || topLeft.row > coords.row)) {
        coords = new WalkontableCellCoords(coords.row, bottomRight.col);
      }
      else if (this.instance.getSettings().fillHandle !== 'vertical') {
        coords = new WalkontableCellCoords(bottomRight.row, coords.col);
      }
      else {
        return; //wrong direction
      }

      this.instance.view.wt.selections.fill.clear();
      this.instance.view.wt.selections.fill.add(this.instance.getSelectedRange().from);
      this.instance.view.wt.selections.fill.add(this.instance.getSelectedRange().to);
      this.instance.view.wt.selections.fill.add(coords);
      this.instance.view.render();
    }

  Autofill.prototype.checkIfNewRowNeeded = function() {
    var fillCorners,
      tableRows = this.instance.countRows(),
      that = this;

    if(this.instance.view.wt.selections.fill.cellRange && this.addingStarted === false) {
      fillCorners = this.instance.view.wt.selections.fill.getCorners();

      if(fillCorners[2] === tableRows - 1) {
        this.addingStarted = true;

        setTimeout(function() {
          that.instance.alter('insert_row');
          that.addingStarted = false;
        }, 200);
      }
    }

  }

  Handsontable.hooks.add('afterInit', function(){
    var autofill = new Autofill(this);

    if (typeof this.getSettings().fillHandle !== "undefined") {
      if (autofill.handle && this.getSettings().fillHandle === false) {
        autofill.disable();
      }
      else if (!autofill.handle && this.getSettings().fillHandle !== false) {
        this.autofill = autofill;
        this.autofill.init();
      }
    }

  });

  Handsontable.Autofill = Autofill;

})(Handsontable);
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from "react";
import {
  View,
  Text,
  TextInput,
  StyleSheet,
  Image,
  LayoutAnimation,
  TouchableOpacity,
} from "react-native";

import Icons from "./Icons";
import CCInput from "./CCInput";
import { InjectedProps } from "./connectToState";

const INFINITE_WIDTH = 1000;

const s = StyleSheet.create({
  container: {
    paddingLeft: 10,
    paddingRight: 10,
    flexDirection: "row",
    alignItems: "center",
    overflow: "hidden",
  },
  icon: {
    width: 48,
    height: 40,
    resizeMode: "contain",
  },
  expanded: {
    flex: 1,
  },
  hidden: {
    width: 0,
  },
  leftPart: {
    overflow: "hidden",
  },
  rightPart: {
    overflow: "hidden",
    flexDirection: "row",
    marginLeft: 10,
  },
  last4: {
    flex: 1,
    justifyContent: "center",
  },
  numberInput: {
    width: INFINITE_WIDTH,
  },
  expiryInput: {
    width: 80,
  },
  cvcInput: {
    width: 80,
  },
});

/* eslint react/prop-types: 0 */ // https://github.com/yannickcr/eslint-plugin-react/issues/106
export default class LiteCreditCardInput extends Component {
  static propTypes = {
    ...InjectedProps,

    placeholders: PropTypes.object,

    inputStyle: Text.propTypes.style,

    validColor: PropTypes.string,
    invalidColor: PropTypes.string,
    placeholderColor: PropTypes.string,
  };

  componentDidMount = () => this._focus(this.props.focused);

  componentWillReceiveProps = newProps => {
    if (this.props.focused !== newProps.focused) this._focus(newProps.focused);
  };

  _focusNumber = () => this._focus("number");

  _focus = field => {
    if (!field) return;
    this.refs[field].focus();
    LayoutAnimation.easeInEaseOut();
  }

  _inputProps = field => {
    const {
      inputStyle, validColor, invalidColor, placeholderColor,
      placeholders, values, status,
      onFocus, onChange, onBecomeEmpty, onBecomeValid,
    } = this.props;

    return {
      inputStyle, validColor, invalidColor, placeholderColor,
      ref: field, field,

      placeholder: placeholders[field],
      value: values[field],
      status: status[field],

      onFocus, onChange, onBecomeEmpty, onBecomeValid,
    };
  };

  _iconToShow = () => {
    const { focused, values: { type } } = this.props;
    if (focused === "cvc" && type === "american-express") return "cvc_amex";
    if (focused === "cvc") return "cvc";
    if (type) return type;
    return "placeholder";
  }

  render() {
    const { focused, values: { number }, inputStyle } = this.props;
    const showRightPart = focused && focused !== "number";

    return (
      <View style={s.container}>
        <View style={[
          s.leftPart,
          showRightPart ? s.hidden : s.expanded,
        ]}>
          <CCInput {...this._inputProps("number")}
              containerStyle={s.numberInput} />
        </View>
        <Image style={s.icon}
            source={{ uri: Icons[this._iconToShow()] }} />
        <View style={[
          s.rightPart,
          showRightPart ? s.expanded : s.hidden,
        ]}>
          <TouchableOpacity onPress={this._focusNumber}
              style={s.last4}>
            <View pointerEvents={"none"}>
              <TextInput editable={false}
                  underlineColorAndroid={"transparent"}
                  style={[inputStyle]}
                  value={ number ? number.substr(number.length - 4, 4) : "" } />
            </View>
          </TouchableOpacity>
          <CCInput {...this._inputProps("expiry")}
              containerStyle={s.expiryInput} />
          <CCInput {...this._inputProps("cvc")}
              containerStyle={s.cvcInput} />
        </View>
      </View>
    );
  }
}

LiteCreditCardInput.defaultProps = {
  placeholders: {
    number: "1234 5678 1234 5678",
    expiry: "MM/YY",
    cvc: "CVC",
  },
  validColor: "",
  invalidColor: "red",
  placeholderColor: "gray",
};
<commit_msg>Improve LiteCreditCardInput field navigations<commit_after>import React, { Component, PropTypes } from "react";
import {
  View,
  Text,
  TextInput,
  StyleSheet,
  Image,
  LayoutAnimation,
  TouchableOpacity,
} from "react-native";

import Icons from "./Icons";
import CCInput from "./CCInput";
import { InjectedProps } from "./connectToState";

const INFINITE_WIDTH = 1000;

const s = StyleSheet.create({
  container: {
    paddingLeft: 10,
    paddingRight: 10,
    flexDirection: "row",
    alignItems: "center",
    overflow: "hidden",
  },
  icon: {
    width: 48,
    height: 40,
    resizeMode: "contain",
  },
  expanded: {
    flex: 1,
  },
  hidden: {
    width: 0,
  },
  leftPart: {
    overflow: "hidden",
  },
  rightPart: {
    overflow: "hidden",
    flexDirection: "row",
    marginLeft: 10,
  },
  last4: {
    flex: 1,
    justifyContent: "center",
  },
  numberInput: {
    width: INFINITE_WIDTH,
  },
  expiryInput: {
    width: 80,
  },
  cvcInput: {
    width: 80,
  },
});

/* eslint react/prop-types: 0 */ // https://github.com/yannickcr/eslint-plugin-react/issues/106
export default class LiteCreditCardInput extends Component {
  static propTypes = {
    ...InjectedProps,

    placeholders: PropTypes.object,

    inputStyle: Text.propTypes.style,

    validColor: PropTypes.string,
    invalidColor: PropTypes.string,
    placeholderColor: PropTypes.string,
  };

  componentDidMount = () => this._focus(this.props.focused);

  componentWillReceiveProps = newProps => {
    if (this.props.focused !== newProps.focused) this._focus(newProps.focused);
  };

  _focusNumber = () => this._focus("number");
  _focusExpiry = () => this._focus("expiry");

  _focus = field => {
    if (!field) return;
    this.refs[field].focus();
    LayoutAnimation.easeInEaseOut();
  }

  _inputProps = field => {
    const {
      inputStyle, validColor, invalidColor, placeholderColor,
      placeholders, values, status,
      onFocus, onChange, onBecomeEmpty, onBecomeValid,
    } = this.props;

    return {
      inputStyle, validColor, invalidColor, placeholderColor,
      ref: field, field,

      placeholder: placeholders[field],
      value: values[field],
      status: status[field],

      onFocus, onChange, onBecomeEmpty, onBecomeValid,
    };
  };

  _iconToShow = () => {
    const { focused, values: { type } } = this.props;
    if (focused === "cvc" && type === "american-express") return "cvc_amex";
    if (focused === "cvc") return "cvc";
    if (type) return type;
    return "placeholder";
  }

  render() {
    const { focused, values: { number }, inputStyle } = this.props;
    const showRightPart = focused && focused !== "number";

    return (
      <View style={s.container}>
        <View style={[
          s.leftPart,
          showRightPart ? s.hidden : s.expanded,
        ]}>
          <CCInput {...this._inputProps("number")}
              containerStyle={s.numberInput} />
        </View>
        <TouchableOpacity onPress={showRightPart ? this._focusNumber : this._focusExpiry }>
          <Image style={s.icon}
              source={{ uri: Icons[this._iconToShow()] }} />
        </TouchableOpacity>
        <View style={[
          s.rightPart,
          showRightPart ? s.expanded : s.hidden,
        ]}>
          <TouchableOpacity onPress={this._focusNumber}
              style={s.last4}>
            <View pointerEvents={"none"}>
              <TextInput editable={false}
                  underlineColorAndroid={"transparent"}
                  style={[inputStyle]}
                  value={ number ? number.substr(number.length - 4, 4) : "" } />
            </View>
          </TouchableOpacity>
          <CCInput {...this._inputProps("expiry")}
              containerStyle={s.expiryInput} />
          <CCInput {...this._inputProps("cvc")}
              containerStyle={s.cvcInput} />
        </View>
      </View>
    );
  }
}

LiteCreditCardInput.defaultProps = {
  placeholders: {
    number: "1234 5678 1234 5678",
    expiry: "MM/YY",
    cvc: "CVC",
  },
  validColor: "",
  invalidColor: "red",
  placeholderColor: "gray",
};
<|endoftext|>