<commit_before>/*
 * Copyright [1999-2013] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 *
 * 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.
 */

// $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);
    Ensembl.EventManager.register('hashChange',    this, this.hashChange);
    Ensembl.EventManager.register('toggleContent', this, this.toggleContent);
    Ensembl.EventManager.register('changeWidth',   this, this.changeWidth);

    $('#page_nav .tool_buttons > p').show();

    $('#header a:not(#tabs a)').addClass('constant');

    if (window.location.hash.match(Ensembl.locationMatch)) {
      $('.ajax_load').val(function (i, val) {
        return Ensembl.urlFromHash(val);
      });

      this.hashChange(Ensembl.urlFromHash(window.location.href, true));
    }

    $(document).on('click', '.modal_link', function () {
      if (Ensembl.EventManager.trigger('modalOpen', this)) {
        return false;
      }
    }).on('click', '.popup', function () {
      if (window.name.match(/^popup_/)) {
        return true;
      }

      window.open(this.href, 'popup_' + window.name, 'width=950,height=500,resizable,scrollbars');
      return false;
    }).on('click', 'a[rel="external"]', function () {
      this.target = '_blank';
    }).on('click', 'a.update_panel', function () {
      var panelId = this.rel;
      var url     = Ensembl.updateURL({ update_panel: 1 }, this.href);

      if (Ensembl.PanelManager.panels[panelId] && this.href.split('?')[0].match(Ensembl.PanelManager.panels[panelId].params.updateURL.split('?')[0])) {
        var params = {};

        if (!$('.update_url', this).add($(this).siblings('.update_url')).each(function () { params[this.name] = this.value; }).length) {
          params = undefined;
        }

        Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, null, { updateURL: this.href }, params);
      } else {
        $.ajax({
          url: url,
          success: function () {
            Ensembl.EventManager.triggerSpecific('updatePanel', panelId);
          }
        });
      }

      return false;
    }).on('submit', 'form.update_panel', function (e) {
      var params    = $(this).serializeArray();
      var urlParams = {};
      var panelId, url, el;

      for (var i in params) {
        switch (params[i].name) {
          case 'panel_id': panelId = params[i].value; break;
          case 'url'     : url     = params[i].value; break;
          case 'element' : el      = params[i].value; break;
          default        : urlParams[params[i].name] = params[i].value; break;
        }
      }

      url = Ensembl.updateURL($.extend({ update_panel: 1 }, urlParams), url);

      Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, el, null, urlParams);

      return false;
    }).on({
      'keyup.ensembl': function (event) {
        if (event.keyCode === 27) {
          Ensembl.EventManager.trigger('modalClose', true); // Close modal window if the escape key is pressed
        }
      },
      'mouseup.ensembl': function (e) {
        // only fired on left click
        if (!e.which || e.which === 1) {
          Ensembl.EventManager.trigger('mouseUp', e);
        }
      }
    });

    $('.modal_link').show();

    this.validateForms(document);

    $(window).on({
      'resize.ensembl': function (e) {
        if (window.name.match(/^popup_/)) {
          return false;
        }

        // jquery ui resizable events cause window.resize to fire (all events bubble to window)
        // if target has no tagName it is window or document. Don't resize unless this is the case
        if (!e.target.tagName) {
          var width = Ensembl.width;

          if (Ensembl.dynamicWidth) {
            Ensembl.setWidth(undefined, true);
          }

          Ensembl.cookie.set('WINDOW_WIDTH', $(window).width());
          Ensembl.EventManager.trigger('windowResize');

          if (Ensembl.dynamicWidth && Ensembl.width !== width) {
            Ensembl.LayoutManager.changeWidth();
            Ensembl.EventManager.trigger('imageResize');
          }
        }
      },
      'hashchange.ensembl': $.proxy(this.popState, this),
      'popstate.ensembl'  : $.proxy(this.popState, this)
    });

    this.handleMirrorRedirect();
  },

  reloadPage: function (args, url) {
    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 {
      return Ensembl.redirect(url);
    }

    $('.session_messages').hide();
  },

  validateForms: function (context) {
    $('form._check', context).validate().on('submit', function () {
      var form = $(this);

      if (form.parents('#modal_panel').length) {
        var panels = form.parents('.js_panel').map(function () { return this.id; }).toArray();
        var rtn;

        while (panels.length && typeof rtn === 'undefined') {
          rtn = Ensembl.EventManager.triggerSpecific('modalFormSubmit', panels.shift(), form);
        }

        return rtn;
      }
    });
  },

  makeZMenu: function (id, params) {
    if (!$('#' + id).length) {
      Ensembl.Panel.ZMenu.template.clone().attr('id', id).appendTo('body');
    }

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

  popState: function () {
    if (
      Ensembl.historyReady && // stops popState executing on initial page load in Chrome. This value is set to true in Ensembl.updateLocation
      // there is an r param in the hash/search EXCEPT WHEN the browser supports history API, and there is a hash which doesn't have an r param (ajax added content)
      ((window.location[Ensembl.locationURL].match(Ensembl.locationMatch) && !(Ensembl.locationURL === 'search' && window.location.hash && !window.location.hash.match(Ensembl.locationMatch))) ||
      (!window.location.hash && Ensembl.hash.match(Ensembl.locationMatch))) // there is no location.hash, but Ensembl.hash (previous hash value) had an r param (going back from no hash url to hash url)
    ) {
      Ensembl.setCoreParams();
      Ensembl.EventManager.trigger('hashChange', Ensembl.urlFromHash(window.location.href, true));
    }
  },

  hashChange: function (r) {
    if (!r) {
      return;
    }

    r = decodeURIComponent(r);

    var text = r.split(/\W/);
        text = text[0] + ': ' + Ensembl.thousandify(text[1]) + '-' + Ensembl.thousandify(text[2]);

    $('a:not(.constant)').attr('href', function () {
      var r;

      if (this.title === 'UCSC') {
        this.href = this.href.replace(/(&?position=)[^&]+(.?)/, '$1chr' + Ensembl.urlFromHash(this.href, true) + '$2');
      } else if (this.title === 'NCBI') {
        r = Ensembl.urlFromHash(this.href, true).split(/[:\-]/);
        this.href = this.href.replace(/(&?CHR=).+&BEG=.+&END=[^&]+(.?)/, '$1' + r[0] + '&BEG=' + r[1] + '&END=' + r[2] + '$2');
      } else {
        return Ensembl.urlFromHash(this.href);
      }
    });

    $('input[name=r]', 'form:not(#core_params)').val(r);

    $('h1.summary-heading').html(function (i, html) {
      return html.replace(/^(Chromosome ).+/, '$1' + text);
    });

    document.title = document.title.replace(/(Chromosome ).+/, '$1' + text);
  },

  toggleContent: function (rel) {
    if (rel) {
      $('a.toggle[rel="' + rel + '"]').toggleClass('open closed');
    }
  },

  changeWidth: function () {
    var modal = $('#modal_panel');
    $('.navbar, div.info, div.hint, div.warning, div.error').not('.fixed_width').not(function () { return modal.find(this).length; }).width(Ensembl.width);
    modal = null;
  },

  handleMirrorRedirect: function() {

    var redirectCode = unescape(Ensembl.cookie.get('redirect_mirror'));

    if (redirectCode && redirectCode !== 'no') {
      redirectCode      = redirectCode.split(/\|/);
      if (redirectCode.length >= 3 && redirectCode[2]) {
        var mirrorName    = redirectCode.shift();
        var remainingTime = parseInt(redirectCode.shift());
        var mirrorURL     = redirectCode.join('|');
        var messageDiv    = $([
          '
',
          '
Redirecting to nearest mirror
',
          '

You are being redirected to ', mirrorName, ' in ', remainingTime, ' seconds. Click here if you don\'t wish to be redirected.

',
          '
'
        ].join('')).prependTo($('#widemain, #main').first()).find('a').on('click', function (e) {
          e.preventDefault();
          Ensembl.cookie.set('redirect_mirror', 'no');
          clearInterval(messageDiv.data('countdown'));
          window.location.replace(window.location.href.replace(/(\&|\;)?redirect=(force|no)/, '').replace(/(\&|\;)?debugip=[^\&|\;]+/, ''));
        }).end().data({
          remainingTime : remainingTime,
          mirrorURL     : mirrorURL,
          countdown     : setInterval(function() {
            var time  = messageDiv.data('remainingTime') - 1;
            messageDiv.data('remainingTime', time).find('._redirect_countdown').html(time > 0 ? time > 1 ? 'in ' + time + ' seconds' : 'in 1 second' : 'now');
            if (time <= 0) {
              clearInterval(messageDiv.data('countdown'));
              window.location.replace(messageDiv.data('mirrorURL'));
            }
          }, 1000)
        });
      }
    }
  }
});
<commit_msg>when redirecting, make sure the URN stays the same<commit_after>/*
 * Copyright [1999-2013] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 *
 * 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.
 */

// $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);
    Ensembl.EventManager.register('hashChange',    this, this.hashChange);
    Ensembl.EventManager.register('toggleContent', this, this.toggleContent);
    Ensembl.EventManager.register('changeWidth',   this, this.changeWidth);

    $('#page_nav .tool_buttons > p').show();

    $('#header a:not(#tabs a)').addClass('constant');

    if (window.location.hash.match(Ensembl.locationMatch)) {
      $('.ajax_load').val(function (i, val) {
        return Ensembl.urlFromHash(val);
      });

      this.hashChange(Ensembl.urlFromHash(window.location.href, true));
    }

    $(document).on('click', '.modal_link', function () {
      if (Ensembl.EventManager.trigger('modalOpen', this)) {
        return false;
      }
    }).on('click', '.popup', function () {
      if (window.name.match(/^popup_/)) {
        return true;
      }

      window.open(this.href, 'popup_' + window.name, 'width=950,height=500,resizable,scrollbars');
      return false;
    }).on('click', 'a[rel="external"]', function () {
      this.target = '_blank';
    }).on('click', 'a.update_panel', function () {
      var panelId = this.rel;
      var url     = Ensembl.updateURL({ update_panel: 1 }, this.href);

      if (Ensembl.PanelManager.panels[panelId] && this.href.split('?')[0].match(Ensembl.PanelManager.panels[panelId].params.updateURL.split('?')[0])) {
        var params = {};

        if (!$('.update_url', this).add($(this).siblings('.update_url')).each(function () { params[this.name] = this.value; }).length) {
          params = undefined;
        }

        Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, null, { updateURL: this.href }, params);
      } else {
        $.ajax({
          url: url,
          success: function () {
            Ensembl.EventManager.triggerSpecific('updatePanel', panelId);
          }
        });
      }

      return false;
    }).on('submit', 'form.update_panel', function (e) {
      var params    = $(this).serializeArray();
      var urlParams = {};
      var panelId, url, el;

      for (var i in params) {
        switch (params[i].name) {
          case 'panel_id': panelId = params[i].value; break;
          case 'url'     : url     = params[i].value; break;
          case 'element' : el      = params[i].value; break;
          default        : urlParams[params[i].name] = params[i].value; break;
        }
      }

      url = Ensembl.updateURL($.extend({ update_panel: 1 }, urlParams), url);

      Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, el, null, urlParams);

      return false;
    }).on({
      'keyup.ensembl': function (event) {
        if (event.keyCode === 27) {
          Ensembl.EventManager.trigger('modalClose', true); // Close modal window if the escape key is pressed
        }
      },
      'mouseup.ensembl': function (e) {
        // only fired on left click
        if (!e.which || e.which === 1) {
          Ensembl.EventManager.trigger('mouseUp', e);
        }
      }
    });

    $('.modal_link').show();

    this.validateForms(document);

    $(window).on({
      'resize.ensembl': function (e) {
        if (window.name.match(/^popup_/)) {
          return false;
        }

        // jquery ui resizable events cause window.resize to fire (all events bubble to window)
        // if target has no tagName it is window or document. Don't resize unless this is the case
        if (!e.target.tagName) {
          var width = Ensembl.width;

          if (Ensembl.dynamicWidth) {
            Ensembl.setWidth(undefined, true);
          }

          Ensembl.cookie.set('WINDOW_WIDTH', $(window).width());
          Ensembl.EventManager.trigger('windowResize');

          if (Ensembl.dynamicWidth && Ensembl.width !== width) {
            Ensembl.LayoutManager.changeWidth();
            Ensembl.EventManager.trigger('imageResize');
          }
        }
      },
      'hashchange.ensembl': $.proxy(this.popState, this),
      'popstate.ensembl'  : $.proxy(this.popState, this)
    });

    this.handleMirrorRedirect();
  },

  reloadPage: function (args, url) {
    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 {
      return Ensembl.redirect(url);
    }

    $('.session_messages').hide();
  },

  validateForms: function (context) {
    $('form._check', context).validate().on('submit', function () {
      var form = $(this);

      if (form.parents('#modal_panel').length) {
        var panels = form.parents('.js_panel').map(function () { return this.id; }).toArray();
        var rtn;

        while (panels.length && typeof rtn === 'undefined') {
          rtn = Ensembl.EventManager.triggerSpecific('modalFormSubmit', panels.shift(), form);
        }

        return rtn;
      }
    });
  },

  makeZMenu: function (id, params) {
    if (!$('#' + id).length) {
      Ensembl.Panel.ZMenu.template.clone().attr('id', id).appendTo('body');
    }

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

  popState: function () {
    if (
      Ensembl.historyReady && // stops popState executing on initial page load in Chrome. This value is set to true in Ensembl.updateLocation
      // there is an r param in the hash/search EXCEPT WHEN the browser supports history API, and there is a hash which doesn't have an r param (ajax added content)
      ((window.location[Ensembl.locationURL].match(Ensembl.locationMatch) && !(Ensembl.locationURL === 'search' && window.location.hash && !window.location.hash.match(Ensembl.locationMatch))) ||
      (!window.location.hash && Ensembl.hash.match(Ensembl.locationMatch))) // there is no location.hash, but Ensembl.hash (previous hash value) had an r param (going back from no hash url to hash url)
    ) {
      Ensembl.setCoreParams();
      Ensembl.EventManager.trigger('hashChange', Ensembl.urlFromHash(window.location.href, true));
    }
  },

  hashChange: function (r) {
    if (!r) {
      return;
    }

    r = decodeURIComponent(r);

    var text = r.split(/\W/);
        text = text[0] + ': ' + Ensembl.thousandify(text[1]) + '-' + Ensembl.thousandify(text[2]);

    $('a:not(.constant)').attr('href', function () {
      var r;

      if (this.title === 'UCSC') {
        this.href = this.href.replace(/(&?position=)[^&]+(.?)/, '$1chr' + Ensembl.urlFromHash(this.href, true) + '$2');
      } else if (this.title === 'NCBI') {
        r = Ensembl.urlFromHash(this.href, true).split(/[:\-]/);
        this.href = this.href.replace(/(&?CHR=).+&BEG=.+&END=[^&]+(.?)/, '$1' + r[0] + '&BEG=' + r[1] + '&END=' + r[2] + '$2');
      } else {
        return Ensembl.urlFromHash(this.href);
      }
    });

    $('input[name=r]', 'form:not(#core_params)').val(r);

    $('h1.summary-heading').html(function (i, html) {
      return html.replace(/^(Chromosome ).+/, '$1' + text);
    });

    document.title = document.title.replace(/(Chromosome ).+/, '$1' + text);
  },

  toggleContent: function (rel) {
    if (rel) {
      $('a.toggle[rel="' + rel + '"]').toggleClass('open closed');
    }
  },

  changeWidth: function () {
    var modal = $('#modal_panel');
    $('.navbar, div.info, div.hint, div.warning, div.error').not('.fixed_width').not(function () { return modal.find(this).length; }).width(Ensembl.width);
    modal = null;
  },

  handleMirrorRedirect: function() {

    var redirectCode = unescape(Ensembl.cookie.get('redirect_mirror'));

    if (redirectCode && redirectCode !== 'no') {
      redirectCode      = redirectCode.split(/\|/);
      if (redirectCode.length >= 2) {
        var currentURI    = window.location.href.replace(/(\&|\;)?redirect=[^\&\;]+/, '').replace(/(\&|\;)?debugip=[^\&\;]+/, '').replace(/\?[\;\&]+/, '?').replace(/\?$/, '');
        var mirrorName    = redirectCode.shift();
        var remainingTime = parseInt(redirectCode.shift());
        var mirrorURI     = currentURI.replace(window.location.host, mirrorName);
            mirrorURI     = mirrorURI + (mirrorURI.match(/\?/) ? ';' : '?') + 'redirect=no';
        var messageDiv    = $([
          '
',
          '
Redirecting to nearest mirror
',
          '

You are being redirected to ', mirrorName, ' in ', remainingTime, ' seconds. Click here if you don\'t wish to be redirected.

',
          '
'
        ].join('')).prependTo($('#widemain, #main').first()).find('a').on('click', function (e) {
          e.preventDefault();
          Ensembl.cookie.set('redirect_mirror', 'no');
          clearInterval(messageDiv.data('countdown'));
          window.location.replace(window.location.href.replace(/(\&|\;)?redirect=(force|no)/, '').replace(/(\&|\;)?debugip=[^\&|\;]+/, ''));
        }).end().data({
          remainingTime : remainingTime,
          mirrorURI     : mirrorURI,
          countdown     : setInterval(function() {
            var time  = messageDiv.data('remainingTime') - 1;
            messageDiv.data('remainingTime', time).find('._redirect_countdown').html(time > 0 ? time > 1 ? 'in ' + time + ' seconds' : 'in 1 second' : 'now');
            if (time <= 0) {
              clearInterval(messageDiv.data('countdown'));
              window.location.replace(messageDiv.data('mirrorURI'));
            }
          }, 1000)
        });
      }
    }
  }
});
<|endoftext|>


<commit_before>/*global spyOn*/
var React = require('react');
var _ = require('lodash');
var {TestUtils} = require('react-dom/test-utils');
var CssSelectorParser = require('./CssSelectorParser');
var SelectorMatchers = require('./SelectorMatchers');
var TestLocation = require('./TestLocation');

var originalCreateElement = React.createElement;

var supportedPsuedoSelectors = [
    'empty',
    'checked',
];

/* eslint-disable */
/**
 * NOT CURRENTLY USED: I wrote this originally thinking it would be useful, but then found
 * another solution, but I didn't want to remove this code in case it becomes useful in the future
 *
 * Recursive method to take a root React node and build up an easy to traverse tree of children. Top level object will be an object
 * with an element and children array. Children will be composed of these same sub-objects.
 * @param  {ReactElement} root Root react node in tree
 * @return {Object}            React tree
 */
function buildReactTree(root){
    if (!root) {
        return [];
    }
    var ret = {element: root, children:[]};
    if (TestUtils.isDOMComponent(root)) {
        var renderedChildren = root._renderedChildren;
        var key;
        for (key in renderedChildren) {
            if (!renderedChildren.hasOwnProperty(key)) {
                continue;
            }
            ret.children = ret.children.concat([buildReactTree(renderedChildren[key])]);
        }
    }
    else if (TestUtils.isCompositeComponent(root)) {
        ret.children = ret.children.concat([buildReactTree(root._renderedComponent)]);
    }
    return ret;
}
/* eslint-enable */

/**
 * Convert a CSS selector into an AST.
 * @param  {String} selector Selector to parse
 * @return {Object}          Parsed selector rule
 * @throws Exception         If selector cannot be parsed
 */
function parseCssSelector(selector){
    var parser = new CssSelectorParser();
    parser.registerAttrEqualityMods('^', '$', '*', '~');
    var ruleSet = parser.parse(selector);
    if(ruleSet.type !== 'ruleSet'){
        throw new Error('Cannot currently parse multiple rules. You must only provide a single CSS selector.');
    }
    return ruleSet;
}

/**
 * Validate that rules are simple and don't include parsing we don't yet support
 * @param  {Object} rule Rule definition to parse
 * @throws {Error}       If rule contains unsupported syntax
 */
function validateParsedCssRule(rule){
    if(rule.pseudos){
        if(rule.pseudos.length > 1){
            throw new Error("Only a single pseudo selector at a time is supported.");
        }
        rule.pseudos = rule.pseudos[0];
        if(supportedPsuedoSelectors.indexOf(rule.pseudos.name) === -1 ){
            throw new Error("The '" + rule.pseudos.name + "' pseudo selector is currently not supported.");
        }
    }
    if(rule.nestingOperator){
        throw new Error("Nesting operators are currently not supported.");
    }
}

/**
 * Recursive function to find all nodes that match the provided rule.
 * @param  {ReactElement} root         The root node to search within
 * @param  {Object}       rule         Parsed CSS rule to match
 * @param  {Bool}         omitRootNode Whether we should ignore the root element from rule matching. If set to true only children will be matched
 * @return {Array}                     Array of matching results
 */
function findAllElementsWithSelector(root, rule, omitRootNode){
    var matches = TestUtils.findAllInRenderedTree(root, elementRuleMatcher(root, rule, omitRootNode)),
        subRule = rule.rule;
    if(subRule){
        var subMatches = [];
        validateParsedCssRule(subRule);
        for(var i = 0; i < matches.length; i++){
            subMatches = subMatches.concat(findAllElementsWithSelector(matches[i], subRule, true));
        }
        return subMatches;
    }
    return matches;
}

/**
 * Generates matcher function to pass into the React TestUtils findAllInRenderedTree given the
 * rule to match
 * @param  {ReactElement} root     The root node to search within
 * @param  {Object}       rule     Parsed CSS rule to match
 * @param  {Bool}         omitRoot Whether we should ignore the root element from rule matching. If set to true only children will be matched
 * @return {Function}              Matcher function which checks against tag names and class names
 */
function elementRuleMatcher(root, rule, omitRoot){
    return function(element){
        if(omitRoot && element === root){
            return false;
        }
        return SelectorMatchers.doesElementMatchSelector(element, rule);
    };
}

/**
 * Simple React component to render a JSX partial. Necessary with the React 0.14 upgrade which
 * requires a component to be passed to renderIntoDocument.
 */
var RenderWrapper = React.createClass({
    render: function(){
        return this.props.children;
    }
});

module.exports = {
    /**
     * Replaces a specific React component with an empty React div during the React render cycle.
     * It's useful to be able to test a component without having it's child components execute and render.
     *
     * @param {String|Object} componentName - Name of the component to replace or object of components to replace.
     *                                        If object, each key should be the name of the component to replace
     *                                        and the values are the optional options to augment.
     * @param {Object=} additionalOptions - Object of div tag attributes to pass to mocked replacement div (className, id, etc).
     * @return {Object} - The newly created Jasmine spy.
     */
    mockReactComponent: function(componentName, additionalOptions){
        if(typeof componentName === 'string'){
            var tempComponentName = {};
            tempComponentName[componentName] = additionalOptions || {};
            componentName = tempComponentName;
        }

        var componentList = _.keys(componentName);

        return spyOn(React, 'createElement').and.callFake(function(){
            var args = Array.prototype.slice.call(arguments),
                type = args[0];
            //If createElement is called with the component requested, replace it with
            //an empty div and overwrite it's options with what was provided or an empty object
            var displayName;
            if(type){
                displayName = type.displayName || type.name;
            }
            if(displayName && componentList.indexOf(displayName) > -1){
                var mock = React.createClass({
                    displayName: displayName,
                    render: () => null
                });
                args[0] = mock;
                //Merge options if present. Allow calls to add/overwrite values
                args[1] = args[1] ?
                    _.assign(args[1], componentName[displayName]) :
                    componentName[displayName];
            }
            return originalCreateElement.apply(React, args);
        });
    },

    /**
     * Returns a rendered React component that requires the react-router.
     * @param  {Object} Router         Instance of react-router Router class.
     * @param  {Object} reactComponent React component instance to render
     * @param  {Object} props          Properties to add to rendered component
     * @param  {String} path           Path necessary to render. If component uses a <Router.Link> component, it's 'to'
     *                                 attribute must exist as a path, so pass in the same name here.
     * @return {Object}                Rendered instance of the reactComponent
     */
    getRouterComponent: function(Router, reactComponent, props, path) {
        var component;
        var div = document.createElement('div');
        var routes = <Router.Route name={path} handler={reactComponent}/>;
        var loc = new TestLocation(['/' + path], Router);
        props = props || {};

        Router.run(routes, loc, function (Handler) {
            var mainComponent = React.render(<Handler {...props}/>, div);
            component = TestUtils.findRenderedComponentWithType(mainComponent, reactComponent);
        });

        return component;
    },

    /**
     * Render a test component using renderIntoDocument using a mock wrapper to get around renderIntoDocument restrictions. Used
     * to render a JSX partial.
     * @param  {ReactElement} partial JSX partial to render
     * @return {HTMLNode}             Resulting HTML markup
     */
    renderPartial(partial){
        return TestUtils.renderIntoDocument(<RenderWrapper>{partial}</RenderWrapper>);
    },

    /**
     * Finds a list of React elements that match the given CSS selector. CSS selector is expected to on contain a
     * single simple rule which uses only class names and element types. Examples:
     *
     *      div.main-content
     *      .section-title.home
     *      ul.item-list li.last span
     *
     * @param  {ReactElement} root     Root node to search within
     * @param  {String}       selector Simple CSS selector to query
     * @return {Array}                 List of results
     */
    scryRenderedDOMComponentsWithSelector: function(root, selector){
        if(typeof selector !== 'string'){
            throw new Error("You must provide a string selector to scryRenderedDOMComponentsWithSelector.");
        }
        var parsedRule = parseCssSelector(selector);
        var rule = parsedRule.rule;
        validateParsedCssRule(rule);

        //Some selectors end up causing multiple of the same elements to get selected so
        //run a unique on the results to make sure we don't get duplicates.
        return _.uniq(findAllElementsWithSelector(root, rule));
    },

    /**
     * Similar to scryRenderedDOMComponentsWithSelector but expects to only find a single
     * result. Will throw an exception if 0 or 2+ elements are found.
     * @param  {ReactElement} root     Root node to search within
     * @param  {String}       selector Simple CSS selector to query
     * @return {ReactElement}          Single found element
     * @throws Exception               If no items were found or more than 1 were found
     */
    findRenderedDOMComponentWithSelector: function(root, selector){
        if(typeof selector !== 'string'){
            throw new Error("You must provide a string selector to scryRenderedDOMComponentsWithSelector.");
        }

        var matches = this.scryRenderedDOMComponentsWithSelector(root, selector);
        if(matches.length !== 1){
            throw new Error("Did not find exactly one match (found: " + matches.length + ") for selector: " + selector);
        }
        return matches[0];
    },

    /**
     * Determines if the number of elements found with the provided class name in the tree is equal to the
     * expected size provided.
     * @param  {ReactElement} root      Rendered React element to check
     * @param  {String}       className Classname to look for
     * @param  {number}       [count=1] Number of times it should appear, defaults to 1 if not provided
     * @return {Bool}                   True if component with class name was found the correct number of times
     * @throws Exception                If element was not found the expected number of times
     */
    findComponentCountWithClassname: function(root, className, count){
        if(!count && count !== 0){
            count = 1;
        }
        var matches = TestUtils.scryRenderedDOMComponentsWithClass(root, className);
        if(matches.length === count){
            return true;
        }
        throw new Error('Expected to find ' + count + ' elements with class "' + className + '", but instead found ' + matches.length);
    },

    /**
     * Determines if the number of elements found with the provided tag name in the tree is equal to the
     * expected size provided.
     * @param  {ReactElement} root      Rendered React element to check
     * @param  {String}       tagName   DOM tag name to look for
     * @param  {number}       [count=1] Number of times it should appear, defaults to 1 if not provided
     * @return {Bool}                   True if component with class name was found the correct number of times
     * @throws Exception                If element was not found the expected number of times
     */
    findComponentCountWithTag: function(root, tagName, count){
        if(!count && count !== 0){
            count = 1;
        }
        var matches = TestUtils.scryRenderedDOMComponentsWithTag(root, tagName);
        if(matches.length === count){
            return true;
        }
        throw new Error('Expected to find ' + count + ' elements with tag "' + tagName + '", but instead found ' + matches.length);
    },

    /**
     * Determines if the number of elements found with the provided selector is equal to the
     * expected size provided.
     * @param  {ReactElement} root      Rendered React element to check
     * @param  {String}       selector  Simple CSS selector to find
     * @param  {number}       [count=1] Number of times it should appear, defaults to 1 if not provided
     * @return {Bool}                   True if components matching selector were found the expected number of times
     * @throws Exception                If element was not found the expected number of times
     */
    findComponentCountWithSelector: function(root, selector, count){
        if(!count && count !== 0){
            count = 1;
        }
        var matches = this.scryRenderedDOMComponentsWithSelector(root, selector);
        if(matches.length === count){
            return true;
        }
        throw new Error('Expected to find ' + count + ' elements with selector "' + selector + '", but instead found ' + matches.length);
    }
};
<commit_msg>Require fix<commit_after>/*global spyOn*/
var React = require('react');
var _ = require('lodash');
var TestUtils = require('react-dom/test-utils');
var CssSelectorParser = require('./CssSelectorParser');
var SelectorMatchers = require('./SelectorMatchers');
var TestLocation = require('./TestLocation');

var originalCreateElement = React.createElement;

var supportedPsuedoSelectors = [
    'empty',
    'checked',
];

/* eslint-disable */
/**
 * NOT CURRENTLY USED: I wrote this originally thinking it would be useful, but then found
 * another solution, but I didn't want to remove this code in case it becomes useful in the future
 *
 * Recursive method to take a root React node and build up an easy to traverse tree of children. Top level object will be an object
 * with an element and children array. Children will be composed of these same sub-objects.
 * @param  {ReactElement} root Root react node in tree
 * @return {Object}            React tree
 */
function buildReactTree(root){
    if (!root) {
        return [];
    }
    var ret = {element: root, children:[]};
    if (TestUtils.isDOMComponent(root)) {
        var renderedChildren = root._renderedChildren;
        var key;
        for (key in renderedChildren) {
            if (!renderedChildren.hasOwnProperty(key)) {
                continue;
            }
            ret.children = ret.children.concat([buildReactTree(renderedChildren[key])]);
        }
    }
    else if (TestUtils.isCompositeComponent(root)) {
        ret.children = ret.children.concat([buildReactTree(root._renderedComponent)]);
    }
    return ret;
}
/* eslint-enable */

/**
 * Convert a CSS selector into an AST.
 * @param  {String} selector Selector to parse
 * @return {Object}          Parsed selector rule
 * @throws Exception         If selector cannot be parsed
 */
function parseCssSelector(selector){
    var parser = new CssSelectorParser();
    parser.registerAttrEqualityMods('^', '$', '*', '~');
    var ruleSet = parser.parse(selector);
    if(ruleSet.type !== 'ruleSet'){
        throw new Error('Cannot currently parse multiple rules. You must only provide a single CSS selector.');
    }
    return ruleSet;
}

/**
 * Validate that rules are simple and don't include parsing we don't yet support
 * @param  {Object} rule Rule definition to parse
 * @throws {Error}       If rule contains unsupported syntax
 */
function validateParsedCssRule(rule){
    if(rule.pseudos){
        if(rule.pseudos.length > 1){
            throw new Error("Only a single pseudo selector at a time is supported.");
        }
        rule.pseudos = rule.pseudos[0];
        if(supportedPsuedoSelectors.indexOf(rule.pseudos.name) === -1 ){
            throw new Error("The '" + rule.pseudos.name + "' pseudo selector is currently not supported.");
        }
    }
    if(rule.nestingOperator){
        throw new Error("Nesting operators are currently not supported.");
    }
}

/**
 * Recursive function to find all nodes that match the provided rule.
 * @param  {ReactElement} root         The root node to search within
 * @param  {Object}       rule         Parsed CSS rule to match
 * @param  {Bool}         omitRootNode Whether we should ignore the root element from rule matching. If set to true only children will be matched
 * @return {Array}                     Array of matching results
 */
function findAllElementsWithSelector(root, rule, omitRootNode){
    var matches = TestUtils.findAllInRenderedTree(root, elementRuleMatcher(root, rule, omitRootNode)),
        subRule = rule.rule;
    if(subRule){
        var subMatches = [];
        validateParsedCssRule(subRule);
        for(var i = 0; i < matches.length; i++){
            subMatches = subMatches.concat(findAllElementsWithSelector(matches[i], subRule, true));
        }
        return subMatches;
    }
    return matches;
}

/**
 * Generates matcher function to pass into the React TestUtils findAllInRenderedTree given the
 * rule to match
 * @param  {ReactElement} root     The root node to search within
 * @param  {Object}       rule     Parsed CSS rule to match
 * @param  {Bool}         omitRoot Whether we should ignore the root element from rule matching. If set to true only children will be matched
 * @return {Function}              Matcher function which checks against tag names and class names
 */
function elementRuleMatcher(root, rule, omitRoot){
    return function(element){
        if(omitRoot && element === root){
            return false;
        }
        return SelectorMatchers.doesElementMatchSelector(element, rule);
    };
}

/**
 * Simple React component to render a JSX partial. Necessary with the React 0.14 upgrade which
 * requires a component to be passed to renderIntoDocument.
 */
var RenderWrapper = React.createClass({
    render: function(){
        return this.props.children;
    }
});

module.exports = {
    /**
     * Replaces a specific React component with an empty React div during the React render cycle.
     * It's useful to be able to test a component without having it's child components execute and render.
     *
     * @param {String|Object} componentName - Name of the component to replace or object of components to replace.
     *                                        If object, each key should be the name of the component to replace
     *                                        and the values are the optional options to augment.
     * @param {Object=} additionalOptions - Object of div tag attributes to pass to mocked replacement div (className, id, etc).
     * @return {Object} - The newly created Jasmine spy.
     */
    mockReactComponent: function(componentName, additionalOptions){
        if(typeof componentName === 'string'){
            var tempComponentName = {};
            tempComponentName[componentName] = additionalOptions || {};
            componentName = tempComponentName;
        }

        var componentList = _.keys(componentName);

        return spyOn(React, 'createElement').and.callFake(function(){
            var args = Array.prototype.slice.call(arguments),
                type = args[0];
            //If createElement is called with the component requested, replace it with
            //an empty div and overwrite it's options with what was provided or an empty object
            var displayName;
            if(type){
                displayName = type.displayName || type.name;
            }
            if(displayName && componentList.indexOf(displayName) > -1){
                var mock = React.createClass({
                    displayName: displayName,
                    render: () => null
                });
                args[0] = mock;
                //Merge options if present. Allow calls to add/overwrite values
                args[1] = args[1] ?
                    _.assign(args[1], componentName[displayName]) :
                    componentName[displayName];
            }
            return originalCreateElement.apply(React, args);
        });
    },

    /**
     * Returns a rendered React component that requires the react-router.
     * @param  {Object} Router         Instance of react-router Router class.
     * @param  {Object} reactComponent React component instance to render
     * @param  {Object} props          Properties to add to rendered component
     * @param  {String} path           Path necessary to render. If component uses a <Router.Link> component, it's 'to'
     *                                 attribute must exist as a path, so pass in the same name here.
     * @return {Object}                Rendered instance of the reactComponent
     */
    getRouterComponent: function(Router, reactComponent, props, path) {
        var component;
        var div = document.createElement('div');
        var routes = <Router.Route name={path} handler={reactComponent}/>;
        var loc = new TestLocation(['/' + path], Router);
        props = props || {};

        Router.run(routes, loc, function (Handler) {
            var mainComponent = React.render(<Handler {...props}/>, div);
            component = TestUtils.findRenderedComponentWithType(mainComponent, reactComponent);
        });

        return component;
    },

    /**
     * Render a test component using renderIntoDocument using a mock wrapper to get around renderIntoDocument restrictions. Used
     * to render a JSX partial.
     * @param  {ReactElement} partial JSX partial to render
     * @return {HTMLNode}             Resulting HTML markup
     */
    renderPartial(partial){
        return TestUtils.renderIntoDocument(<RenderWrapper>{partial}</RenderWrapper>);
    },

    /**
     * Finds a list of React elements that match the given CSS selector. CSS selector is expected to on contain a
     * single simple rule which uses only class names and element types. Examples:
     *
     *      div.main-content
     *      .section-title.home
     *      ul.item-list li.last span
     *
     * @param  {ReactElement} root     Root node to search within
     * @param  {String}       selector Simple CSS selector to query
     * @return {Array}                 List of results
     */
    scryRenderedDOMComponentsWithSelector: function(root, selector){
        if(typeof selector !== 'string'){
            throw new Error("You must provide a string selector to scryRenderedDOMComponentsWithSelector.");
        }
        var parsedRule = parseCssSelector(selector);
        var rule = parsedRule.rule;
        validateParsedCssRule(rule);

        //Some selectors end up causing multiple of the same elements to get selected so
        //run a unique on the results to make sure we don't get duplicates.
        return _.uniq(findAllElementsWithSelector(root, rule));
    },

    /**
     * Similar to scryRenderedDOMComponentsWithSelector but expects to only find a single
     * result. Will throw an exception if 0 or 2+ elements are found.
     * @param  {ReactElement} root     Root node to search within
     * @param  {String}       selector Simple CSS selector to query
     * @return {ReactElement}          Single found element
     * @throws Exception               If no items were found or more than 1 were found
     */
    findRenderedDOMComponentWithSelector: function(root, selector){
        if(typeof selector !== 'string'){
            throw new Error("You must provide a string selector to scryRenderedDOMComponentsWithSelector.");
        }

        var matches = this.scryRenderedDOMComponentsWithSelector(root, selector);
        if(matches.length !== 1){
            throw new Error("Did not find exactly one match (found: " + matches.length + ") for selector: " + selector);
        }
        return matches[0];
    },

    /**
     * Determines if the number of elements found with the provided class name in the tree is equal to the
     * expected size provided.
     * @param  {ReactElement} root      Rendered React element to check
     * @param  {String}       className Classname to look for
     * @param  {number}       [count=1] Number of times it should appear, defaults to 1 if not provided
     * @return {Bool}                   True if component with class name was found the correct number of times
     * @throws Exception                If element was not found the expected number of times
     */
    findComponentCountWithClassname: function(root, className, count){
        if(!count && count !== 0){
            count = 1;
        }
        var matches = TestUtils.scryRenderedDOMComponentsWithClass(root, className);
        if(matches.length === count){
            return true;
        }
        throw new Error('Expected to find ' + count + ' elements with class "' + className + '", but instead found ' + matches.length);
    },

    /**
     * Determines if the number of elements found with the provided tag name in the tree is equal to the
     * expected size provided.
     * @param  {ReactElement} root      Rendered React element to check
     * @param  {String}       tagName   DOM tag name to look for
     * @param  {number}       [count=1] Number of times it should appear, defaults to 1 if not provided
     * @return {Bool}                   True if component with class name was found the correct number of times
     * @throws Exception                If element was not found the expected number of times
     */
    findComponentCountWithTag: function(root, tagName, count){
        if(!count && count !== 0){
            count = 1;
        }
        var matches = TestUtils.scryRenderedDOMComponentsWithTag(root, tagName);
        if(matches.length === count){
            return true;
        }
        throw new Error('Expected to find ' + count + ' elements with tag "' + tagName + '", but instead found ' + matches.length);
    },

    /**
     * Determines if the number of elements found with the provided selector is equal to the
     * expected size provided.
     * @param  {ReactElement} root      Rendered React element to check
     * @param  {String}       selector  Simple CSS selector to find
     * @param  {number}       [count=1] Number of times it should appear, defaults to 1 if not provided
     * @return {Bool}                   True if components matching selector were found the expected number of times
     * @throws Exception                If element was not found the expected number of times
     */
    findComponentCountWithSelector: function(root, selector, count){
        if(!count && count !== 0){
            count = 1;
        }
        var matches = this.scryRenderedDOMComponentsWithSelector(root, selector);
        if(matches.length === count){
            return true;
        }
        throw new Error('Expected to find ' + count + ' elements with selector "' + selector + '", but instead found ' + matches.length);
    }
};
<|endoftext|>


<commit_before>import app from 'app';
import _ from 'lodash';
import template from 'text!./edit-authority.directive.html';
import 'services/main';
import 'views/forms/edit/edit';
import 'views/forms/edit/document-selector';
import '~/views/forms/edit/warning-message-cna';
import '~/views/forms/view/view-authority.directive';

    const authorityController = ["$http", "Thesaurus", "$q", "$controller", "$location", "realm", "solr",'thesaurusService',
        function($http, Thesaurus, $q, $controller, $location, realm, solr,thesaurusService) {
		return {
			restrict   : "EA",
			template: template,
			replace    : true,
			require    : '?ngModel',
			scope:{
				onPostSubmitFn   : "&onPostSubmit"
			},
			link: function($scope, $element, $attr){

				$scope.scientificNameSynonyms = [{}];
				$scope.commonNames = [{}];
				$scope.container        = $attr.container;
    			$scope.isDialog         = $attr.isDialog;
				$scope.type 			= $attr.documentType;
				$controller('editController', { $scope: $scope });

                $scope.getMeasures=[];
                $scope.path = $location.path();
                $scope.isBch = realm.is('BCH');
                $scope.isAbs = realm.is('ABS');

                _.extend($scope.options, {
                    organizationTypes: function() { return thesaurusService.getDomainTerms('organizationTypes')
                        .then(function(types){ return _.filter(types, function(type){return type.identifier!='B3699A74-EF2E-467A-A82F-EF2149A2EFC5'}); }) },
                    cbdSubjects: function() {return thesaurusService.getDomainTerms('cbdSubjects')},
                    jurisdictions: function() {return thesaurusService.getDomainTerms('cnaJurisdictions', {other:true})},
                    absGeneticResourceTypes: function() {return thesaurusService.getDomainTerms('absGeneticResourceTypes')},
                    absGeneticResourceAreas: function() {return thesaurusService.getDomainTerms('absGeneticResourceAreas')},
                    functions: function() {
                        var functionDomain = 'subjectAreas';
                        if($scope.type=='SPCA')//supplementaryAuthority
                            functionDomain = 'supplementaryProtocolFunctions';

                        return thesaurusService.getDomainTerms(functionDomain, {other:true, otherType:'lstring'});
                    },
                    bchOrganismTypes: function() { return thesaurusService.getDomainTerms('typeOfOrganisms', {other:true, otherType:'lstring'})},
                    absFunctions: function() {return thesaurusService.getDomainTerms('absFunctions');},
                    keywords: function() { return thesaurusService.getDomainTerms('keywords');},

                });

                //==================================
                $scope.showResponsibleforAllMsg = function() {

                    //TODO: you need to gain access to the promise in order to do this correctly.a Otherwise the document won't be loaded when angular evaluated the ng-show.
                    if (!$scope.document || (!$scope.document.responsibleForAll || !$scope.validationReport))
                        return false;

                    return _.some($scope.validationReport.errors, function(error) {
                        return error.property == 'responsibleForAllNot';
                    });
                };

                //==================================
                //
                //==================================
                $scope.getCleanDocument = function(document) {

                    document = document || $scope.document;
                    ///////for legacy records////////////////
                    document.bchFunctions = undefined;
                    document.bchOrganismTypes = undefined;
                    ////////////////////////
                    if (!document)
                        return undefined;

                    ///////for legacy records////////////////
                    resolveLegacyFields(document)

                    if(!document.hasOwnProperty('responsibleForAll'))
                        document.responsibleForAll       = document.absResponsibleForAll;

                    if($scope.isBCH){//no longer required for BCH
                        document.policyBasisForCompetencyRef = undefined;
                    }
                    //delete obsolete fields
                    document.absPolicyBasisForCompetencyRef = undefined;
                    document.absPolicyBasisForCompetency = undefined;

                    if ($scope.type == 'SPCA' || document.responsibleForAll) {
                        document.absJurisdiction = undefined;
                        document.absJurisdictionName = undefined;
                        document.absGeneticResourceTypes = undefined;
                    }
                    else{
                        if(!$scope.showJurisdictionName())
                            document.absJurisdictionName = undefined;
                    }

                    if($scope.isBch){

                        if($scope.type != 'SPCA'){ //Not Suuplementary protocol
                            document.responsibleForAll = undefined;
                        }

                        document.absJurisdiction = undefined;
                        document.absJurisdictionName = undefined;
                        document.absGeneticResourceTypes = undefined;
                        if($scope.type == 'SPCA'){ //Suuplementary protocol
                            document.cpbOrganismTypes = undefined;
                            document.functions = undefined;
                        }
                    }
                    else{
                        document.functions = undefined;
                        document.cpbOrganismTypes = undefined;
                    }

                    if (/^\s*$/g.test(document.notes))
                        document.notes = undefined;

                    return $scope.sanitizeDocument(document);
                };
                //==================================
                $scope.setDocument({}).then(function(document){
                    resolveLegacyFields(document)
                });

                //==================================
                $scope.showJurisdictionName = function() {

                    if (!$scope.document || !$scope.document.absJurisdiction)
                        return false;

                    //var jurisdictions = $scope.document.absJurisdiction
                    return _.intersection(_.map($scope.document.absJurisdiction, 'identifier'),
                                        ['DEBB019D-8647-40EC-8AE5-10CA88572F6E', 'DEEEDB35-A34B-4755-BF77-D713017195E3', '5B6177DD-5E5E-434E-8CB7-D63D67D5EBED']).length > 0;
                }

                $scope.onContactQuery = function(searchText){
                    var queryOptions = {
                        realm     : realm.value,
                        searchText: searchText
                    }
                    if($scope.isAbs){
                        if($scope.document?.header?.identifier)
                            queryOptions.fieldQueries = [`NOT identifier_s:${solr.escape($scope.document.header.identifier)}`];
                        }
                        queryOptions.schemas = ['contact', 'authority'];
                        queryOptions.query = `(schema_s:authority AND government_s:${$scope.document.government.identifier}) OR (schema_s:contact AND type_s: person)`;
                    }
                    else{
                        queryOptions.schemas = ['contact'];
                        queryOptions.fieldQueries = ['type_s: person'];
                    }

                    return $scope.onBuildDocumentSelectorQuery(queryOptions);

                }

                $scope.onMeasureQuery = function(searchText){

                    var queryOptions = {
                        realm     : realm.value,
                        schemas     : ['measure'],
                        searchText  : searchText
                    }
                    if ($scope.document && $scope.document.government)
                        queryOptions.government = $scope.document.government.identifier;

                    return $scope.onBuildDocumentSelectorQuery(queryOptions);

                }

                function resolveLegacyFields(document){

                    document.policyBasisForCompetencyRef    = document.policyBasisForCompetencyRef || document.absPolicyBasisForCompetencyRef;
                    document.policyBasisForCompetency       = document.policyBasisForCompetency || document.absPolicyBasisForCompetency;
                    document.functions                      = document.functions || document.cpbFunctions || document.bchFunctions;
                    document.bchFunctions                   = document.cpbFunctions = undefined;
                    document.absPolicyBasisForCompetencyRef = undefined;
                    document.absPolicyBasisForCompetency    = undefined;
                    document.bchOrganismTypes               = undefined;
                }

			}
		}
    }]

	app.directive("editAuthority", authorityController);
	app.directive("editSupplementaryAuthority", authorityController);

<commit_msg>fix broken code<commit_after>import app from 'app';
import _ from 'lodash';
import template from 'text!./edit-authority.directive.html';
import 'services/main';
import 'views/forms/edit/edit';
import 'views/forms/edit/document-selector';
import '~/views/forms/edit/warning-message-cna';
import '~/views/forms/view/view-authority.directive';

    const authorityController = ["$http", "Thesaurus", "$q", "$controller", "$location", "realm", "solr",'thesaurusService',
        function($http, Thesaurus, $q, $controller, $location, realm, solr,thesaurusService) {
		return {
			restrict   : "EA",
			template: template,
			replace    : true,
			require    : '?ngModel',
			scope:{
				onPostSubmitFn   : "&onPostSubmit"
			},
			link: function($scope, $element, $attr){

				$scope.scientificNameSynonyms = [{}];
				$scope.commonNames = [{}];
				$scope.container        = $attr.container;
    			$scope.isDialog         = $attr.isDialog;
				$scope.type 			= $attr.documentType;
				$controller('editController', { $scope: $scope });

                $scope.getMeasures=[];
                $scope.path = $location.path();
                $scope.isBch = realm.is('BCH');
                $scope.isAbs = realm.is('ABS');

                _.extend($scope.options, {
                    organizationTypes: function() { return thesaurusService.getDomainTerms('organizationTypes')
                        .then(function(types){ return _.filter(types, function(type){return type.identifier!='B3699A74-EF2E-467A-A82F-EF2149A2EFC5'}); }) },
                    cbdSubjects: function() {return thesaurusService.getDomainTerms('cbdSubjects')},
                    jurisdictions: function() {return thesaurusService.getDomainTerms('cnaJurisdictions', {other:true})},
                    absGeneticResourceTypes: function() {return thesaurusService.getDomainTerms('absGeneticResourceTypes')},
                    absGeneticResourceAreas: function() {return thesaurusService.getDomainTerms('absGeneticResourceAreas')},
                    functions: function() {
                        var functionDomain = 'subjectAreas';
                        if($scope.type=='SPCA')//supplementaryAuthority
                            functionDomain = 'supplementaryProtocolFunctions';

                        return thesaurusService.getDomainTerms(functionDomain, {other:true, otherType:'lstring'});
                    },
                    bchOrganismTypes: function() { return thesaurusService.getDomainTerms('typeOfOrganisms', {other:true, otherType:'lstring'})},
                    absFunctions: function() {return thesaurusService.getDomainTerms('absFunctions');},
                    keywords: function() { return thesaurusService.getDomainTerms('keywords');},

                });

                //==================================
                $scope.showResponsibleforAllMsg = function() {

                    //TODO: you need to gain access to the promise in order to do this correctly.a Otherwise the document won't be loaded when angular evaluated the ng-show.
                    if (!$scope.document || (!$scope.document.responsibleForAll || !$scope.validationReport))
                        return false;

                    return _.some($scope.validationReport.errors, function(error) {
                        return error.property == 'responsibleForAllNot';
                    });
                };

                //==================================
                //
                //==================================
                $scope.getCleanDocument = function(document) {

                    document = document || $scope.document;
                    ///////for legacy records////////////////
                    document.bchFunctions = undefined;
                    document.bchOrganismTypes = undefined;
                    ////////////////////////
                    if (!document)
                        return undefined;

                    ///////for legacy records////////////////
                    resolveLegacyFields(document)

                    if(!document.hasOwnProperty('responsibleForAll'))
                        document.responsibleForAll       = document.absResponsibleForAll;

                    if($scope.isBCH){//no longer required for BCH
                        document.policyBasisForCompetencyRef = undefined;
                    }
                    //delete obsolete fields
                    document.absPolicyBasisForCompetencyRef = undefined;
                    document.absPolicyBasisForCompetency = undefined;

                    if ($scope.type == 'SPCA' || document.responsibleForAll) {
                        document.absJurisdiction = undefined;
                        document.absJurisdictionName = undefined;
                        document.absGeneticResourceTypes = undefined;
                    }
                    else{
                        if(!$scope.showJurisdictionName())
                            document.absJurisdictionName = undefined;
                    }

                    if($scope.isBch){

                        if($scope.type != 'SPCA'){ //Not Suuplementary protocol
                            document.responsibleForAll = undefined;
                        }

                        document.absJurisdiction = undefined;
                        document.absJurisdictionName = undefined;
                        document.absGeneticResourceTypes = undefined;
                        if($scope.type == 'SPCA'){ //Suuplementary protocol
                            document.cpbOrganismTypes = undefined;
                            document.functions = undefined;
                        }
                    }
                    else{
                        document.functions = undefined;
                        document.cpbOrganismTypes = undefined;
                    }

                    if (/^\s*$/g.test(document.notes))
                        document.notes = undefined;

                    return $scope.sanitizeDocument(document);
                };
                //==================================
                $scope.setDocument({}).then(function(document){
                    resolveLegacyFields(document)
                });

                //==================================
                $scope.showJurisdictionName = function() {

                    if (!$scope.document || !$scope.document.absJurisdiction)
                        return false;

                    //var jurisdictions = $scope.document.absJurisdiction
                    return _.intersection(_.map($scope.document.absJurisdiction, 'identifier'),
                                        ['DEBB019D-8647-40EC-8AE5-10CA88572F6E', 'DEEEDB35-A34B-4755-BF77-D713017195E3', '5B6177DD-5E5E-434E-8CB7-D63D67D5EBED']).length > 0;
                }

                $scope.onContactQuery = function(searchText){
                    var queryOptions = {
                        realm     : realm.value,
                        searchText: searchText,
                        fieldQueries:[]
                    }
                    if($scope.isAbs){

                        queryOptions.schemas = ['contact', 'authority'];
                        queryOptions.query = `(schema_s:authority AND government_s:${$scope.document.government.identifier}) OR (schema_s:contact AND type_s: person)`;
                    }
                    else{
                        queryOptions.schemas = ['contact'];
                        queryOptions.fieldQueries = ['type_s: person'];
                    }

                    if($scope.document?.header?.identifier)
                        queryOptions.fieldQueries.push(`NOT identifier_s:${solr.escape($scope.document.header.identifier)}`);

                    return $scope.onBuildDocumentSelectorQuery(queryOptions);

                }

                $scope.onMeasureQuery = function(searchText){

                    var queryOptions = {
                        realm     : realm.value,
                        schemas     : ['measure'],
                        searchText  : searchText
                    }
                    if ($scope.document && $scope.document.government)
                        queryOptions.government = $scope.document.government.identifier;

                    return $scope.onBuildDocumentSelectorQuery(queryOptions);

                }

                function resolveLegacyFields(document){

                    document.policyBasisForCompetencyRef    = document.policyBasisForCompetencyRef || document.absPolicyBasisForCompetencyRef;
                    document.policyBasisForCompetency       = document.policyBasisForCompetency || document.absPolicyBasisForCompetency;
                    document.functions                      = document.functions || document.cpbFunctions || document.bchFunctions;
                    document.bchFunctions                   = document.cpbFunctions = undefined;
                    document.absPolicyBasisForCompetencyRef = undefined;
                    document.absPolicyBasisForCompetency    = undefined;
                    document.bchOrganismTypes               = undefined;
                }

			}
		}
    }]

	app.directive("editAuthority", authorityController);
	app.directive("editSupplementaryAuthority", authorityController);

<|endoftext|>


<commit_before>define('audio', ['jsfxr', 'vent'], function( jsfxr, vent ){

    'use strict';

    function play( sound ){
        var player = new Audio(),
            soundURL = jsfxr(sound);
        player.src = soundURL;
        player.play();
    }

    vent.on('shoot', function(){
        play([0,,0.0243,,0.2334,0.7546,,-0.3971,,,,,,,,,,,1,,,,,0.33]);
    });

    vent.on('kaboom!', function(){
        play([3,0.03,0.53,0.79,0.54,0.1062,,,,,,,,,,0.7691,-0.2803,-0.1151,1,,,,,0.16]);
    });

});
<commit_msg>new explosion<commit_after>define('audio', ['jsfxr', 'vent'], function( jsfxr, vent ){

    'use strict';

    function play( sound ){
        var player = new Audio(),
            soundURL = jsfxr(sound);
        player.src = soundURL;
        player.play();
    }

    vent.on('shoot', function(){
        play([0,,0.0243,,0.2334,0.7546,,-0.3971,,,,,,,,,,,1,,,,,0.33]);
    });

    vent.on('kaboom!', function(){
        play([3,,0.233,0.3771,0.67,0.0656,,-0.29,,,,,,,,0.75,-0.24,0.34,0.15,-0.18,0.76,,,0.31]);
    });

});
<|endoftext|>


<commit_before><commit_msg>Upgraded sinonJS from v2.3.2 to v2.3.4<commit_after><|endoftext|>


<commit_before>/* global define */

(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], factory)
  } else if (typeof exports === 'object') {
    // Node/CommonJS
    factory(require('jquery'))
  } else {
    // Browser globals
    factory(jQuery)
  }
}(function ($, undefined) {
  'use strict'

  const pluginName = 'numberedList'
  const defaults = {
    wrapper: '.fx-numberedList-wrapper',
    item: '.fx-numberedList-item',
    number: '.fx-numberedList-number',
    action: '.fx-numberedList-action'
  }
  let activated = false

  // Plugin constructor
  function Plugin (options) {
    this.settings = $.extend({}, defaults, options)
    this.init()
  }

  // Avoid Plugin.prototype conflicts
  $.extend(Plugin.prototype, {
    init: function () {
      if ($(this.settings.wrapper).length >= 1) {
        this.bindListeners()
        this.updateNumbers()
      }
    },
    bindListeners: function () {
      const self = this
      const el = '#' + $(this.settings.wrapper).attr('id')
      if (el === '#undefined') {
        throw Error('This is an error message')
      }

      $(el).on('cocoon:after-insert', function (e, insertedItem) {
        self.updateNumbers()
        insertedItem.find('.remove_fields:first').focus()
      })

      $(el).on('cocoon:after-remove', function (e) {
        self.updateNumbers()
      })
    },
    updateNumbers: function () {
      const self = this
      const number = self.settings.number
      const action = self.settings.action
      const items = $(this.settings.wrapper).find(this.settings.item + ':visible')

      items.each(function (idx, el) {
        $(el).find(action).removeClass('govuk-!-display-none')
        $(el).find(number).text('')
        if (items.length > 1) {
          $(el).find(number).text(idx + 1)
        }
      })
    }
  })

  // Plugin wrapper to prevent multiple copies of the
  // plugin being included and to prevent it running
  // multiple times
  if (typeof $[pluginName] === 'undefined') {
    $[pluginName] = function (options) {
      if (!activated) {
        new Plugin(options)
        activated = true
      }

      // chain jQuery functions
      return this
    }
  }
}))
<commit_msg>CBO-1612 Linting, resolve no-new rule<commit_after>/* global define */

(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], factory)
  } else if (typeof exports === 'object') {
    // Node/CommonJS
    factory(require('jquery'))
  } else {
    // Browser globals
    factory(jQuery)
  }
}(function ($, undefined) {
  'use strict'

  const pluginName = 'numberedList'
  const defaults = {
    wrapper: '.fx-numberedList-wrapper',
    item: '.fx-numberedList-item',
    number: '.fx-numberedList-number',
    action: '.fx-numberedList-action'
  }
  let activated = false

  // Plugin constructor
  function Plugin (options) {
    this.settings = $.extend({}, defaults, options)
    this.init()
  }

  // Avoid Plugin.prototype conflicts
  $.extend(Plugin.prototype, {
    init: function () {
      if ($(this.settings.wrapper).length >= 1) {
        this.bindListeners()
        this.updateNumbers()
      }
    },
    bindListeners: function () {
      const self = this
      const el = '#' + $(this.settings.wrapper).attr('id')
      if (el === '#undefined') {
        throw Error('This is an error message')
      }

      $(el).on('cocoon:after-insert', function (e, insertedItem) {
        self.updateNumbers()
        insertedItem.find('.remove_fields:first').focus()
      })

      $(el).on('cocoon:after-remove', function (e) {
        self.updateNumbers()
      })
    },
    updateNumbers: function () {
      const self = this
      const number = self.settings.number
      const action = self.settings.action
      const items = $(this.settings.wrapper).find(this.settings.item + ':visible')

      items.each(function (idx, el) {
        $(el).find(action).removeClass('govuk-!-display-none')
        $(el).find(number).text('')
        if (items.length > 1) {
          $(el).find(number).text(idx + 1)
        }
      })
    }
  })

  // Plugin wrapper to prevent multiple copies of the
  // plugin being included and to prevent it running
  // multiple times
  if (typeof $[pluginName] === 'undefined') {
    $[pluginName] = function (options) {
      if (!activated) {
        new Plugin(options).init()
        activated = true
      }

      // chain jQuery functions
      return this
    }
  }
}))
<|endoftext|>


<commit_before>var path = require('path');

module.exports = {
  entry: './test/build/index.js',
  output: {
    filename: './test/build/bundle.js'
  },
  debug: true,
  devtool: 'source-map',
  bail: true,
  module: {
    loaders: [
      { test: /\.css$/, loader: 'style-loader!css-loader' },
    ],
  }
}
<commit_msg>Remove extra trailing comma<commit_after>var path = require('path');

module.exports = {
  entry: './test/build/index.js',
  output: {
    filename: './test/build/bundle.js'
  },
  debug: true,
  devtool: 'source-map',
  bail: true,
  module: {
    loaders: [
      { test: /\.css$/, loader: 'style-loader!css-loader' },
    ]
  }
}
<|endoftext|>


<commit_before>/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true,
   undef:true, curly:true, browser:true, jquery:true, indent:4, maxerr:50, newcap:true */

( function( $ )
{
	"use strict";

	var error = new Error( "A template URL must be provided." ),
	    obj   = Object.prototype,
	    cache = {},
	    options,
	    callback;

	/*
	 * Preprocesses each template contained within the templates
	 * file (specified by opts or opts.url). Each template id is
	 * used as a key and the compiled template is the value of
	 * the key. An object containing each template id key and
	 * compiled template is returned.
	 *
	 * @return {Object} An Object containing each template where
	 * the id of each template is used as a key and the compiled
	 * template is the value of the key, and the resulting object
	 * is returned.
	 */
	var _preprocess = function( file )
	{
		var templates = $( file ).filter( options.element || 'script' ),
			template,
			i,
			n;

		if ( templates )
		{
			cache = options.reset ? {} : cache;

			for ( i = 0, n = templates.length; i < n; i++ )
			{
				template = templates[i];
				cache[ template.id ] = $.jqotec( template );
			}
		}
		callback( cache );

		options  = null;
		callback = null;
	};

	/*
	 * Clients can invoke jqoteret with a single template element
	 * id, or an Array of template element ids. When an Array of
	 * template ids is passed, _jqoteretMulti retrieves each and
	 * returns all matches.
	 */
	var _jqoteretMulti = function( ids )
	{
		var ret = [];

		for ( var i = 0, n = ids.length; i < n; i++ )
		{
			ret.push( cache[ ids[i] ] );
		}
		return ret;
	};

	/*
	 * Loads an external templates file via jQuery.get();. Accordingly,
	 * the loading of a template file is subject to the jQuery.get();
	 * API. See: http://api.jquery.com/jQuery.get/ for implementation
	 * details.
	 *
	 * Once loaded, the individual templates defined in the templates
	 * file are precompiled (via $.jqotec) and stored in an object
	 * where each key is the id of a template and the value is the
	 * precompiled template (lambda). If a success callback function
	 * is specified, it will be invoked with the resulting templates
	 * object once loaded (unless preprocessing is configured to be
	 * omitted via the opts.preprocess = false property).
	 *
	 * @param opts: {Object} A configuration object which defines any
	 * of the following properties:
	 *
	 *    url: {String} The URL of the external template which is to
	 *    be loaded  and precompiled. This value is required.
	 *
	 *    preprocess: {Boolean} specifies if the loaded templates file
	 *    is to be preprocessed internally by $.jqoteload(), and have
	 *    the resulting precompiled templates returned via an invocation
	 *    of the success callback argument.
	 *
	 *    element: {String} The name of the HTML elements which define
	 *    templates in the loaded templates file. This is an optional
	 *    property. The default value is 'script'.
	 *
	 *    reset: {Boolean} Specifies if the loaded templates should
	 *    overwrite any existing templates previously loaded.
	 *
	 * @param success {Function}
	 *    A callback function which accepts either an object (when the
	 *    opts.precompiled properrty == true) or, a result from jQuery
	 *    get();. The success callback is invoked either after the given
	 *    template has been loaded and preprocessed, or once the template
	 *    has been loaded (if opts.preprocess == false).
	 *
	 */
	var jqoteload = function( opts, success )
	{
		var request,
			defaults;

		if ( opts || opts.url )
		{
			options  = null;
			defaults = {
				preprocess : true,
				reset      : false,
				element    : 'script'
			};
			if ( typeof opts === 'object' )
			{
				options = $.extend( defaults, opts );
			}
			else if ( typeof opts === 'string' )
			{
				options = $.extend( defaults, {url: opts} );
			}
			callback = success;
			request  = $.get( options.url ).success( options.preprocess ? _preprocess : success );

			return request;
		}
		else
		{
			throw error;
		}
	};

	/*
	 * Provides a convenience method for accessing each compiled template
	 * via its id. By default, an Object containing each compiled template
	 * is passed to the callback specified to $.jqoteload. This method is
	 * useful for storing the compiled templates outside of the scope of
	 * the callback, allowing clients to access the templates via jQuery
	 * i.e. $.jqoteret.
	 *
	 * This method is similar to the jqotecache object, and the compiled
	 * templates returned are references to the same templates; the only
	 * difference is that jqoteret (short for "retrieve") allows for the
	 * retrieval of templates via thier defined id in the loaded templates
	 * file.
	 *
	 * @param id
	 *    {String} The string id of a previously loaded template file, via
	 *    $.jqoteload
	 *
	 *    {Array} An Array of String ids of templates previously loaded via
	 *    $.jqoteload
	 *
	 */
	var jqoteret = function( id )
	{
		if ( obj.toString.call( id ) === "[object Array]" )
		{
			return _jqoteretMulti( id );
		}
		return cache[ id ];
	};

	// We extend the jQuery object itself with two additional methods,
	// the define the jqote2 loader API
	$.extend( {
		jqoteload : jqoteload,
		jqoteret  : jqoteret
	});
}( jQuery ));
<commit_msg>Updating comments.<commit_after>/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true,
   undef:true, curly:true, browser:true, jquery:true, indent:4, maxerr:50, newcap:true */

( function( $ )
{
	"use strict";

	var error = new Error( "A template URL must be provided." ),
	    obj   = Object.prototype,
	    cache = {},
	    options,
	    callback;

	/*
	 * Preprocesses each template contained within the templates
	 * file (specified by opts or opts.url). Each template id is
	 * used as a key and the compiled template is the value of
	 * the key. An object containing each template id key and
	 * compiled template is returned.
	 *
	 * @return {Object} An Object containing each template where
	 * the id of each template is used as a key and the compiled
	 * template is the value of the key, and the resulting object
	 * is returned.
	 */
	var _preprocess = function( file )
	{
		var templates = $( file ).filter( options.element || 'script' ),
			template,
			i,
			n;

		if ( templates )
		{
			cache = options.reset ? {} : cache;

			for ( i = 0, n = templates.length; i < n; i++ )
			{
				template = templates[i];
				cache[ template.id ] = $.jqotec( template );
			}
		}
		callback( cache );

		options  = null;
		callback = null;
	};

	/*
	 * Clients can invoke jqoteret with a single template element
	 * id, or an Array of template element ids. When an Array of
	 * template ids is passed, _jqoteretMulti retrieves each and
	 * returns all matches.
	 */
	var _jqoteretMulti = function( ids )
	{
		var ret = [];

		for ( var i = 0, n = ids.length; i < n; i++ )
		{
			ret.push( cache[ ids[i] ] );
		}
		return ret;
	};

	/*
	 * Loads an external templates file via jQuery.get();. Accordingly,
	 * the loading of a template file is subject to the jQuery.get();
	 * API. See: http://api.jquery.com/jQuery.get/ for implementation
	 * details.
	 *
	 * Once loaded, the individual templates defined in the templates
	 * file are precompiled (via $.jqotec) and stored in an object
	 * where each key is the id of a template and the value is the
	 * precompiled template (lambda). If a success callback function
	 * is specified, it will be invoked with the resulting templates
	 * object once loaded (unless preprocessing is configured to be
	 * omitted via the opts.preprocess = false property).
	 *
	 * @param opts: {Object} A configuration object which defines any
	 * of the following properties:
	 *
	 *    url: {String} The URL of the external template which is to
	 *    be loaded  and precompiled. This value is required.
	 *
	 *    preprocess: {Boolean} specifies if the loaded templates file
	 *    is to be preprocessed internally by $.jqoteload(), and have
	 *    the resulting precompiled templates returned via an invocation
	 *    of the success callback argument. When false, the template file
	 *    contents will be returned unmodified.
	 *
	 *    element: {String} The name of the HTML elements which define
	 *    templates in the loaded templates file. This is an optional
	 *    property. The default value is 'script'.
	 *
	 *    reset: {Boolean} Specifies if the loaded templates should
	 *    overwrite any existing templates previously loaded.
	 *
	 * @param success {Function}
	 *    A callback function which accepts either an object (when the
	 *    opts.precompiled properrty == true) or, a result from jQuery
	 *    get();. The success callback is invoked either after the given
	 *    template has been loaded and preprocessed, or once the template
	 *    has been loaded (if opts.preprocess == false).
	 *
	 */
	var jqoteload = function( opts, success )
	{
		var request,
			defaults;

		if ( opts || opts.url )
		{
			options  = null;
			defaults = {
				preprocess : true,
				reset      : false,
				element    : 'script'
			};
			if ( typeof opts === 'object' )
			{
				options = $.extend( defaults, opts );
			}
			else if ( typeof opts === 'string' )
			{
				options = $.extend( defaults, {url: opts} );
			}
			callback = success;
			request  = $.get( options.url ).success( options.preprocess ? _preprocess : success );

			return request;
		}
		else
		{
			throw error;
		}
	};

	/*
	 * Provides a convenience method for accessing each compiled template
	 * via its id. By default, an Object containing each compiled template
	 * is passed to the callback specified to $.jqoteload. This method is
	 * useful for storing the compiled templates outside of the scope of
	 * the callback, allowing clients to access the templates via jQuery
	 * i.e. $.jqoteret.
	 *
	 * This method is similar to the jqotecache object, and the compiled
	 * templates returned are references to the same templates; the only
	 * difference is that jqoteret (short for "retrieve") allows for the
	 * retrieval of templates via thier defined id in the loaded templates
	 * file.
	 *
	 * @param id
	 *    {String} The string id of a previously loaded template file, via
	 *    $.jqoteload
	 *
	 *    {Array} An Array of String ids of templates previously loaded via
	 *    $.jqoteload
	 *
	 */
	var jqoteret = function( id )
	{
		if ( obj.toString.call( id ) === "[object Array]" )
		{
			return _jqoteretMulti( id );
		}
		return cache[ id ];
	};

	// We extend the jQuery object itself with two additional methods,
	// these define the jqote2 loader API
	$.extend( {
		jqoteload : jqoteload,
		jqoteret  : jqoteret
	});
}( jQuery ));
<|endoftext|>


<commit_before>/*
 * MagicBootTabs
 * A nice way of styling and using Bootstrap tabs for content
 *
 * Author: Unreal Designs <contact@unreal-designs.co.uk>
 * Copyright: Unreal Designs 2015
 */

//Declare Version
var magicBootTabsVersion = "1.21";

// Colored Console Logging Function
var old = console.log;
console.log = function(){
    old.apply(console, consolelog(arguments));
}

function consolelog(message) {
	if (message != "") {
		var messages = Array();
		var styles = Array();

		messages.push("%cMagicBootTabs");
		styles.push("background: #222; color: #bada55;");

		for (index = 0; index < message.length; ++index) {
			args = message[index].split(" -- ");
			msg = args[0].trim();
			color = args[1].trim();
			if (args.length == 3) {
				bg = args[2].trim();
			} else {
				bg = "#222";
			}
			messages.push(" %c" + msg);
			styles.push("background: " + bg + "; color: " + color);
		}

		var arguments = Array();
		arguments.push(messages.join(""));
		for (index = 0; index < styles.length; ++index) {
			arguments.push(styles[index]);
		}

		return arguments;
	} else {
		return "";
	}
}

// JQuery Check
if (typeof jQuery != 'undefined') {

	// Bootstrap JS Tabs Check
	if (typeof($.fn.tab) != 'undefined') {

		// Log - Plugin Loaded And Version In Console
		consolelog(Array(
			"A magical way of styling and using Bootstrap tabs for content. -- #6BB9F0"
		));
		consolelog(Array(
			"Version -- #6BB9F0",
			magicBootTabsVersion + " -- #F27935",
			"Loaded! -- #6BB9F0"
		));

		// Load in CSS File
		$("head").append("<link>");
		var css = $("head").children(":last");
		css.attr({
			rel: "stylesheet",
			type: "text/css",
			href: "//rawgithub.com/MattCowley/MagicBootTabs/master/src/jquery.magicBootTabs.css"
		});

		// Create Style Tag For MagicBootTab Colors
		$("head").append("");
		var styles = $("head").children(":last");
		styles.attr({
			id: "magicBootTabsStyles",
			type: "text/css"
		});

		// Log Styles Loaded In Console
		consolelog(Array(
			"CSS File Linked In Head, Style Holder Created! -- #6BB9F0"
		));

		// Begin magicBootTab JQuery Function
		$.fn.magicBootTab = function(options) {

			//Check Options Is Passed
			options = options || {};

			// Set Option Defaults If Not Set
			options.lnColor 	= options.hasOwnProperty('lnColor') 	? options.lnColor 	: "#4144FF";
			options.acColor 	= options.hasOwnProperty('acColor') 	? options.acColor 	: "#4183D7";
			options.speed 		= options.hasOwnProperty('speed') 	? options.speed 	: 400;
			options.advAnimation 	= options.hasOwnProperty('advAnimation') 	? options.advAnimation 	: false;

			// Create Usable Plugin Variables
			$tabId = this;
			tabIdAttr = this.attr("id");
			$tabId.append("

");
			var $magicLine = $("#magic-line[magic-tab='" + tabIdAttr + "']");

			//Create Line Break Before Tab Info
			consolelog("");

			// Log Basic MagicBootTab Info
			consolelog(Array(
				"Tab -- #F27935",
				"#" + tabIdAttr + " -- #F27935",
				"Using Line Color -- #6BB9F0",
				options.lnColor + " -- " + options.lnColor + " -- #fff",
				", Using Active Color -- #6BB9F0",
				options.acColor + " -- " + options.acColor + " -- #fff"
			));

			consolelog(Array(
				"Tab -- #F27935",
				"#" + tabIdAttr + " -- #F27935",
				"Using Animation Speed -- #6BB9F0",
				options.speed + " -- #4183D7" + " -- #fff"
			));

			if (options.advAnimation) {
				consolelog(Array(
					"Tab -- #F27935",
					"#" + tabIdAttr + " -- #F27935",
					"Advanced Animation Mode Enabled -- #6BB9F0"
				));
			} else {
				consolelog(Array(
					"Tab -- #F27935",
					"#" + tabIdAttr + " -- #F27935",
					"Advanced Animation Mode Disabled -- #6BB9F0"
				));
			}

			// Set Custom Colors For MagicBootTab
			$("head style#magicBootTabsStyles").append(".nav-tabs#" + tabIdAttr + " > li.active > a { color: " + options.acColor + "; }\n");
			$("head style#magicBootTabsStyles").append(".nav-tabs#" + tabIdAttr + " > li#magic-line { background: " + options.lnColor + " }\n");

			// Log Tab Info In Console
			consolelog(Array(
				"Tab -- #F27935",
				"#" + tabIdAttr + " -- #F27935",
				"MagicBootTab Created! -- #6BB9F0"
			));

			//Begin - Set Original Values
			$magicLine
				.width($(".active").width())
				.height(3)
				.css("left", $(".active a").position().left)
				.css("zIndex", 0)
				.data("origLeft", $magicLine.position().left)
				.data("origWidth", $magicLine.width());

			if (!options.advAnimation) {
				//Hover Event
				$tabId.find("li a").hover(function() {
					$el = $(this);
					leftPos = $el.position().left;
					newWidth = $el.parent().width();
					$magicLine.stop().animate({
						left: leftPos,
						width: newWidth
					}, options.speed);
				}, function() {
					$magicLine.stop().animate({
						left: $magicLine.data("origLeft"),
						width: $magicLine.data("origWidth")
					}, options.speed);
				});

				//Click Event
				$tabId.find("li a").click(function() {
					$el = $(this);
					leftPos = $el.position().left
					newWidth = $el.parent().width();
					$magicLine.stop().animate({
						left: leftPos,
						width: newWidth
					}, options.speed, function() {
						$magicLine
							.width($el.parent().width())
							.css("left", $el.position().left)
							.data("origLeft", $magicLine.position().left)
							.data("origWidth", $magicLine.width());
					});
				});
			} else {
				//Set Org Height
				$magicLine.stop().animate({
					height: $tabId.find("li.active").height()
				}, options.speed/1.5, function() {
					$magicLine.data("origHeight", $magicLine.height());
				});

				//Hover Event
				$tabId.find("li a").hover(function() {
					$el = $(this);
					leftPos = $el.position().left;
					newWidth = $el.parent().width();
					newHeight = $el.parent().height();
					$magicLine.stop().animate({
						height: 3
					}, options.speed/1.5, function() {
						$magicLine.animate({
							left: leftPos,
							width: newWidth
						}, options.speed/1.5, function() {
							$magicLine.animate({
								height: newHeight
							}, options.speed/1.5);
						});
					});
				}, function() {
					$magicLine.stop().animate({
						height: 3
					}, options.speed/1.5, function() {
						$magicLine.animate({
							left: $magicLine.data("origLeft"),
							width: $magicLine.data("origWidth")
						}, options.speed/1.5, function() {
							$magicLine.animate({
								height: $magicLine.data("origHeight")
							}, options.speed/1.5);
						});
					});
				});

				//Click Event
				$tabId.find("li a").click(function() {
					$el = $(this);
					leftPos = $el.position().left
					newWidth = $el.parent().width();
					newHeight = $el.parent().height();
					$magicLine.stop().animate({
						height: 3
					}, options.speed/1.5, function() {
						$magicLine.animate({
							left: leftPos,
							width: newWidth
						}, options.speed/1.5, function() {
							$magicLine.animate({
								height: newHeight
							}, options.speed/1.5, function() {
								$magicLine
									.width($el.parent().width())
									.css("left", $el.position().left)
									.data("origLeft", $magicLine.position().left)
									.data("origHeight", $magicLine.height())
									.data("origWidth", $magicLine.width());
							});
						});
					});
				});
			}

			// Return JQuery Selector For Function Chaining
			return this;
		}

	} else {

		// Log Bootstrap JS Error In Console
		consolelog(Array(
			"Plugin Requires Bootstrap 3 (JS - Tabs)! -- #F53C2B"
		));
	}

} else {

	// Log JQuery Error In Console
	consolelog(Array(
		"Plugin Requires JQuery! -- #F53C2B"
	));
}
<commit_msg>Console.log<commit_after>/*
 * MagicBootTabs
 * A nice way of styling and using Bootstrap tabs for content
 *
 * Author: Unreal Designs <contact@unreal-designs.co.uk>
 * Copyright: Unreal Designs 2015
 */

//Declare Version
var magicBootTabsVersion = "1.22";

// Colored Console Logging Function
var old = console.log;
console.log = function(){
	arguments = consolelog(arguments)
	old(arguments);
    old.apply(this, arguments);
}

function consolelog(message) {
	if (message != "") {
		var messages = Array();
		var styles = Array();

		messages.push("%cMagicBootTabs");
		styles.push("background: #222; color: #bada55;");

		for (index = 0; index < message.length; ++index) {
			args = message[index].split(" -- ");
			msg = args[0].trim();
			color = args[1].trim();
			if (args.length == 3) {
				bg = args[2].trim();
			} else {
				bg = "#222";
			}
			messages.push(" %c" + msg);
			styles.push("background: " + bg + "; color: " + color);
		}

		var arguments = Array();
		arguments.push(messages.join(""));
		for (index = 0; index < styles.length; ++index) {
			arguments.push(styles[index]);
		}

		return arguments;
	} else {
		return "";
	}
}

// JQuery Check
if (typeof jQuery != 'undefined') {

	// Bootstrap JS Tabs Check
	if (typeof($.fn.tab) != 'undefined') {

		// Log - Plugin Loaded And Version In Console
		consolelog(Array(
			"A magical way of styling and using Bootstrap tabs for content. -- #6BB9F0"
		));
		consolelog(Array(
			"Version -- #6BB9F0",
			magicBootTabsVersion + " -- #F27935",
			"Loaded! -- #6BB9F0"
		));

		// Load in CSS File
		$("head").append("<link>");
		var css = $("head").children(":last");
		css.attr({
			rel: "stylesheet",
			type: "text/css",
			href: "//rawgithub.com/MattCowley/MagicBootTabs/master/src/jquery.magicBootTabs.css"
		});

		// Create Style Tag For MagicBootTab Colors
		$("head").append("");
		var styles = $("head").children(":last");
		styles.attr({
			id: "magicBootTabsStyles",
			type: "text/css"
		});

		// Log Styles Loaded In Console
		consolelog(Array(
			"CSS File Linked In Head, Style Holder Created! -- #6BB9F0"
		));

		// Begin magicBootTab JQuery Function
		$.fn.magicBootTab = function(options) {

			//Check Options Is Passed
			options = options || {};

			// Set Option Defaults If Not Set
			options.lnColor 	= options.hasOwnProperty('lnColor') 	? options.lnColor 	: "#4144FF";
			options.acColor 	= options.hasOwnProperty('acColor') 	? options.acColor 	: "#4183D7";
			options.speed 		= options.hasOwnProperty('speed') 	? options.speed 	: 400;
			options.advAnimation 	= options.hasOwnProperty('advAnimation') 	? options.advAnimation 	: false;

			// Create Usable Plugin Variables
			$tabId = this;
			tabIdAttr = this.attr("id");
			$tabId.append("

");
			var $magicLine = $("#magic-line[magic-tab='" + tabIdAttr + "']");

			//Create Line Break Before Tab Info
			consolelog("");

			// Log Basic MagicBootTab Info
			consolelog(Array(
				"Tab -- #F27935",
				"#" + tabIdAttr + " -- #F27935",
				"Using Line Color -- #6BB9F0",
				options.lnColor + " -- " + options.lnColor + " -- #fff",
				", Using Active Color -- #6BB9F0",
				options.acColor + " -- " + options.acColor + " -- #fff"
			));

			consolelog(Array(
				"Tab -- #F27935",
				"#" + tabIdAttr + " -- #F27935",
				"Using Animation Speed -- #6BB9F0",
				options.speed + " -- #4183D7" + " -- #fff"
			));

			if (options.advAnimation) {
				consolelog(Array(
					"Tab -- #F27935",
					"#" + tabIdAttr + " -- #F27935",
					"Advanced Animation Mode Enabled -- #6BB9F0"
				));
			} else {
				consolelog(Array(
					"Tab -- #F27935",
					"#" + tabIdAttr + " -- #F27935",
					"Advanced Animation Mode Disabled -- #6BB9F0"
				));
			}

			// Set Custom Colors For MagicBootTab
			$("head style#magicBootTabsStyles").append(".nav-tabs#" + tabIdAttr + " > li.active > a { color: " + options.acColor + "; }\n");
			$("head style#magicBootTabsStyles").append(".nav-tabs#" + tabIdAttr + " > li#magic-line { background: " + options.lnColor + " }\n");

			// Log Tab Info In Console
			consolelog(Array(
				"Tab -- #F27935",
				"#" + tabIdAttr + " -- #F27935",
				"MagicBootTab Created! -- #6BB9F0"
			));

			//Begin - Set Original Values
			$magicLine
				.width($(".active").width())
				.height(3)
				.css("left", $(".active a").position().left)
				.css("zIndex", 0)
				.data("origLeft", $magicLine.position().left)
				.data("origWidth", $magicLine.width());

			if (!options.advAnimation) {
				//Hover Event
				$tabId.find("li a").hover(function() {
					$el = $(this);
					leftPos = $el.position().left;
					newWidth = $el.parent().width();
					$magicLine.stop().animate({
						left: leftPos,
						width: newWidth
					}, options.speed);
				}, function() {
					$magicLine.stop().animate({
						left: $magicLine.data("origLeft"),
						width: $magicLine.data("origWidth")
					}, options.speed);
				});

				//Click Event
				$tabId.find("li a").click(function() {
					$el = $(this);
					leftPos = $el.position().left
					newWidth = $el.parent().width();
					$magicLine.stop().animate({
						left: leftPos,
						width: newWidth
					}, options.speed, function() {
						$magicLine
							.width($el.parent().width())
							.css("left", $el.position().left)
							.data("origLeft", $magicLine.position().left)
							.data("origWidth", $magicLine.width());
					});
				});
			} else {
				//Set Org Height
				$magicLine.stop().animate({
					height: $tabId.find("li.active").height()
				}, options.speed/1.5, function() {
					$magicLine.data("origHeight", $magicLine.height());
				});

				//Hover Event
				$tabId.find("li a").hover(function() {
					$el = $(this);
					leftPos = $el.position().left;
					newWidth = $el.parent().width();
					newHeight = $el.parent().height();
					$magicLine.stop().animate({
						height: 3
					}, options.speed/1.5, function() {
						$magicLine.animate({
							left: leftPos,
							width: newWidth
						}, options.speed/1.5, function() {
							$magicLine.animate({
								height: newHeight
							}, options.speed/1.5);
						});
					});
				}, function() {
					$magicLine.stop().animate({
						height: 3
					}, options.speed/1.5, function() {
						$magicLine.animate({
							left: $magicLine.data("origLeft"),
							width: $magicLine.data("origWidth")
						}, options.speed/1.5, function() {
							$magicLine.animate({
								height: $magicLine.data("origHeight")
							}, options.speed/1.5);
						});
					});
				});

				//Click Event
				$tabId.find("li a").click(function() {
					$el = $(this);
					leftPos = $el.position().left
					newWidth = $el.parent().width();
					newHeight = $el.parent().height();
					$magicLine.stop().animate({
						height: 3
					}, options.speed/1.5, function() {
						$magicLine.animate({
							left: leftPos,
							width: newWidth
						}, options.speed/1.5, function() {
							$magicLine.animate({
								height: newHeight
							}, options.speed/1.5, function() {
								$magicLine
									.width($el.parent().width())
									.css("left", $el.position().left)
									.data("origLeft", $magicLine.position().left)
									.data("origHeight", $magicLine.height())
									.data("origWidth", $magicLine.width());
							});
						});
					});
				});
			}

			// Return JQuery Selector For Function Chaining
			return this;
		}

	} else {

		// Log Bootstrap JS Error In Console
		consolelog(Array(
			"Plugin Requires Bootstrap 3 (JS - Tabs)! -- #F53C2B"
		));
	}

} else {

	// Log JQuery Error In Console
	consolelog(Array(
		"Plugin Requires JQuery! -- #F53C2B"
	));
}
<|endoftext|>