<commit_before>/*
 *
 * preload
 *
 * ---
 * @Copyright(c) 2014, falsandtru
 * @license MIT http://opensource.org/licenses/mit-license.php
 * @version 0.1.2
 * @updated 2014/02/23
 * @author falsandtru https://github.com/falsandtru/
 * @Compressor Closure Compiler
 */
(function(f,n,m,p){function q(a,b,h,f,c,d){var k=this;switch(!0){case "string"===typeof d:d={link:d};default:k=k instanceof a?k:a(h),k=c.setProperties.call(k,null,null)}var e;e=a.extend(!0,{gns:c.name,ns:f,link:"a:not([target])",filter:function(){return/(\/|\.html?|\.php)([#?].*)?$/.test(this.href)},lock:1E3,forward:null,interval:1E3,limit:2,cooldown:1E4,query:null,fix:!1,ajax:{dataType:"text",async:!0,timeout:1500}},d);e.nss={array:[c.name].concat(e.ns&&String(e.ns).split(".")||[])};a.extend(!0,
e=e.scope&&c.scope(e)||e,{id:0,nss:{name:e.ns||"",alias:c.alias?[c.alias].concat(e.nss.array.slice(1)).join("."):!1,event:e.nss.array.join("."),data:e.nss.array.join("-"),class4html:e.nss.array.join("-"),click:["click"].concat(e.nss.array.join(":")).join("."),mousemove:["mousemove"].concat(e.nss.array.join(":")).join("."),mouseover:["mouseover"].concat(e.nss.array.join(":")).join("."),mouseout:["mouseout"].concat(e.nss.array.join(":")).join(".")},target:null,volume:0,points:[],queue:[],xhr:null,timestamp:0,
option:d});a(function(){c.registrate.call(k,a,b,h,f,c,e)});return k}var g;g={name:"preload",alias:"",ids:[],settings:[0],count:0,parseHTML:null,setAlias:function(a){g.alias="string"===typeof a?a:g.alias;g.name===g.alias||f[g.alias]||(f[g.name][g.alias]=f.fn[g.name],f.fn[g.alias]=f[g.alias]=f.fn[g.name])},setProperties:function(a,b){var h=this;if(h instanceof f||h===f[g.name])h=h instanceof f&&b!==p?h.add(b):h,h[g.name]=f[g.name];return h},loaded:{},registrate:function(a,b,f,g,c,d){d.id=c.settings.length;
c.ids.push(d.id);c.settings[d.id]=d;b=d.fix?c.canonicalizeURL(b.location.href):b.location.href;c.loaded[b.replace(/#.*/,"")]=!0;this.find(d.link).filter(d.filter).unbind(d.nss.click).one(d.nss.click,d.id,function(b){var e=c.settings[b.data];b.timeStamp=(new Date).getTime();e.fix&&(this.href=c.canonicalizeURL(this.href));switch(!b.isDefaultPrevented()&&a.data(b.currentTarget,e.nss.data)){case "preload":case "lock":e.forward?(e.fix&&c.canonicalizeURL(b.currentTarget.href),!1===c.fire(e.forward,null,
[b,e.xhr,e.timeStamp])?"lock"===a.data(b.currentTarget,e.nss.data)?b.preventDefault():(c.click(e,b),a.removeData(b.currentTarget,e.nss.data)):(b.preventDefault(),a.removeData(b.currentTarget,e.nss.data))):"lock"===a.data(b.currentTarget,e.nss.data)?b.preventDefault():(c.click(e,b),a.removeData(b.currentTarget,e.nss.data));break;default:e.xhr&&4>e.xhr.readyState&&e.xhr.abort()}}).unbind(d.nss.mouseover).bind(d.nss.mouseover,d.id,function(a){c.settings[a.data].target=this}).unbind(d.nss.mouseout).bind(d.nss.mouseout,
d.id,function(a){c.settings[a.data].target=null}).unbind(d.nss.mousemove).bind(d.nss.mousemove,d.id,function(a){var b=c.settings[a.data];a.timeStamp=(new Date).getTime();b.points.unshift(a);b.points.splice(10,1);c.check(b,a,b.target)});setTimeout(function(){d.volume-=Number(!!d.volume);setTimeout(arguments.callee,d.cooldown)},d.cooldown)},check:function(a,b,h,r){var c,d,k;if(h)switch(c=a.fix?g.canonicalizeURL(b.currentTarget.href):b.currentTarget.href,d=a.queue,!0){case !g.settings[a.id]:case g.loaded[c.replace(/#.*/,
"")]:case 100<d.length:case a.interval?(new Date).getTime()-a.timestamp<a.interval:0:case a.volume>=a.limit:case a.target!==h:case a.target.protocol!==h.protocol:case a.target.host!==h.host:case f(h).is('[target="_blank"]'):case !function(a){if(3>a.length)return!1;var b,c,d;c=a[0].timeStamp-a[1].timeStamp;b=Math.pow(a[0].pageX-a[1].pageX,2)+Math.pow(a[0].pageY-a[1].pageY,2)/(c||1);d=a[1].timeStamp-a[2].timeStamp;a=Math.pow(a[1].pageX-a[2].pageX,2)+Math.pow(a[1].pageY-a[2].pageY,2)/(d||1);switch(!0){case 100<
c||100<d:return!1;case b<a+Math.pow(5,2)&&b<=Math.pow(25,2):return!0;default:return!1}}(a.points):break;default:for(;k=d.shift();)clearTimeout(k);k=setTimeout(function(){for(;k=d.shift();)clearTimeout(k);switch(!0){case !a.target:case b!==a.points[0]:case b.pageX!==a.points[0].pageX||b.pageY!==a.points[0].pageY:break;default:a.xhr&&4>a.xhr.readyState&&a.xhr.abort();g.loaded[c.replace(/#.*/,"")]=!0;++a.volume;a.timeStamp=b.timeStamp;f.data(a.target,a.nss.data,"preload");a.lock&&(f.data(a.target,a.nss.data,
"lock"),f(a.target).one(a.nss.click,b.timeStamp,function(b){if(f.data(b.currentTarget,a.nss.data)){f(this);var c=Math.max(a.lock-(new Date).getTime()+b.data,0);f.data(b.currentTarget,a.nss.data,"click");c&&(setTimeout(function(){"click"===f.data(b.currentTarget,a.nss.data)&&g.click(a,b);f.removeData(b.currentTarget,a.nss.data)},c),b.preventDefault())}}));var e=f.extend(!0,{},a.ajax,{success:function(){g.fire(a.ajax.success,this,arguments);g.loaded[this.url.replace(/#.*/,"")]=!0;a.volume-=Number(304===
arguments[2].status&&!!a.volume);"click"===f.data(b.currentTarget,a.nss.data)&&g.click(a,b);f.removeData(b.currentTarget,a.nss.data)},error:function(){g.fire(a.ajax.error,this,arguments);a.volume-=Number(!!a.volume);f.removeData(h,a.nss.data)}}),l=a.query;l&&(l=l.split("="),l=encodeURIComponent(l[0])+(0<l.length?"="+encodeURIComponent(l[1]):""));e.url=c.replace(/([^#]+)(#[^\s]*)?$/,"$1"+(l?(c.match(/\?/)?"&":"?")+l:"")+"$2");a.xhr=f.ajax(e)}},30);d.push(k)}},click:function(a,b){var h=b.currentTarget;
a.xhr&&4>a.xhr.readyState&&a.xhr.abort();f(b.currentTarget).removeData(a.nss.data);f(m).find(b.currentTarget)[0]&&(f(m).unbind(a.nss.click).one(a.nss.click,function(b){b.isDefaultPrevented()||(n.location.href=a.fix?g.canonicalizeURL(h.href):h.href)}),f(b.currentTarget).click());b.preventDefault()},canonicalizeURL:function(a){var b;b=g.trim(a);b=b.replace(/[<>"{}|\\^\[\]`\s].*/,"");b=/^https?:/i.test(b)?b:f("<a/>",{href:b})[0].href;b=encodeURI(decodeURI(b));return b=b.replace(/(?:%\w{2})+/g,function(b){return a.match(b.toLowerCase())||
b})},trim:function(a){if(String.prototype.trim)a=String(a).trim();else if(a=String(a).replace(/^\s+/,""))for(var b=a.length;--b;)if(/\S/.test(a.charAt(b))){a=a.substring(0,b+1);break}return a},fire:function(a,b,f,g){return"function"===typeof a?g?setTimeout(function(){a.apply(b,f)},0):a.apply(b,f):a}};(function(a,b,f,g,c){a.fn[c.name]=a[c.name]=function(){return q.apply(this,[a,b,f,g,c].concat([].slice.call(arguments)))};c.setProperties.call(a[c.name])}).apply(this,[].slice.call(arguments).concat([g]))})(jQuery,
window,document,void 0);
<commit_msg>Compress: jquery.preload.js<commit_after>/*
 *
 * preload
 *
 * ---
 * @Copyright(c) 2014, falsandtru
 * @license MIT http://opensource.org/licenses/mit-license.php
 * @version 0.1.2
 * @updated 2014/02/23
 * @author falsandtru https://github.com/falsandtru/
 * @Compressor Closure Compiler
 */
(function(g,n,m,p){function q(a,b,c,g,d,f){var k=this;switch(!0){case "string"===typeof f:f={link:f};default:k=k instanceof a?k:a(c),k=d.setProperties.call(k,null,null)}var e;e=a.extend(!0,{gns:d.name,ns:g,link:"a:not([target])",filter:function(){return/(\/|\.html?|\.php)([#?].*)?$/.test(this.href)},lock:1E3,forward:null,interval:1E3,limit:2,cooldown:1E4,query:null,encode:!1,prefetch:null,ajax:{dataType:"text",async:!0,timeout:1500}},f);e.nss={array:[d.name].concat(e.ns&&String(e.ns).split(".")||
[])};a.extend(!0,e=e.scope&&d.scope(e)||e,{id:0,nss:{name:e.ns||"",alias:d.alias?[d.alias].concat(e.nss.array.slice(1)).join("."):!1,event:e.nss.array.join("."),data:e.nss.array.join("-"),class4html:e.nss.array.join("-"),click:["click"].concat(e.nss.array.join(":")).join("."),mousemove:["mousemove"].concat(e.nss.array.join(":")).join("."),mouseover:["mouseover"].concat(e.nss.array.join(":")).join("."),mouseout:["mouseout"].concat(e.nss.array.join(":")).join(".")},target:null,volume:0,points:[],queue:[],
xhr:null,timestamp:0,option:f});a(function(){d.registrate.call(k,a,b,c,g,d,e)});return k}var c;c={name:"preload",alias:"",ids:[],settings:[0],count:0,parseHTML:null,setAlias:function(a){c.alias="string"===typeof a?a:c.alias;c.name===c.alias||g[c.alias]||(g[c.name][c.alias]=g.fn[c.name],g.fn[c.alias]=g[c.alias]=g.fn[c.name])},setProperties:function(a,b){var h=this;if(h instanceof g||h===g[c.name])h=h instanceof g&&b!==p?h.add(b):h,h[c.name]=g[c.name];return h},req:{},loaded:{},registrate:function(a,
b,c,g,d,f){f.id=d.settings.length;d.ids.push(f.id);d.settings[f.id]=f;b=f.encode?d.canonicalizeURL(b.location.href):b.location.href;d.loaded[b.replace(/#.*/,"")]=!0;this.find(f.link).filter(f.filter).unbind(f.nss.click).one(f.nss.click,f.id,function(b){var e=d.settings[b.data];b.timeStamp=(new Date).getTime();e.encode&&(this.href=d.canonicalizeURL(this.href));switch(!b.isDefaultPrevented()&&a.data(b.currentTarget,e.nss.data)){case "preload":case "lock":e.forward?(e.encode&&d.canonicalizeURL(b.currentTarget.href),
!1===d.fire(e.forward,null,[b,e.xhr,e.timeStamp])?"lock"===a.data(b.currentTarget,e.nss.data)?b.preventDefault():(d.click(e,b),a.removeData(b.currentTarget,e.nss.data)):(b.preventDefault(),a.removeData(b.currentTarget,e.nss.data))):"lock"===a.data(b.currentTarget,e.nss.data)?b.preventDefault():(d.click(e,b),a.removeData(b.currentTarget,e.nss.data));break;default:e.xhr&&4>e.xhr.readyState&&e.xhr.abort()}}).unbind(f.nss.mouseover).bind(f.nss.mouseover,f.id,function(a){d.settings[a.data].target=this}).unbind(f.nss.mouseout).bind(f.nss.mouseout,
f.id,function(a){d.settings[a.data].target=null}).unbind(f.nss.mousemove).bind(f.nss.mousemove,f.id,function(a){var b=d.settings[a.data];a.timeStamp=(new Date).getTime();b.points.unshift(a);b.points.splice(10,1);d.check(b,a,b.target)});setTimeout(function(){f.volume-=Number(!!f.volume);setTimeout(arguments.callee,f.cooldown)},f.cooldown);f.prefetch&&a(f.prefetch).each(function(){d.prefetch.call(this)})},check:function(a,b,h,r){var d,f,k;if(h)switch(d=a.encode?c.canonicalizeURL(b.currentTarget.href):
b.currentTarget.href,f=a.queue,!0){case !c.settings[a.id]:case c.loaded[d.replace(/#.*/,"")]:case 100<f.length:case a.interval?(new Date).getTime()-a.timestamp<a.interval:0:case a.volume>=a.limit:case a.target!==h:case a.target.protocol!==h.protocol:case a.target.host!==h.host:case g(h).is('[target="_blank"]'):case !function(a){if(3>a.length)return!1;var b,c,d;c=a[0].timeStamp-a[1].timeStamp;b=Math.pow(a[0].pageX-a[1].pageX,2)+Math.pow(a[0].pageY-a[1].pageY,2)/(c||1);d=a[1].timeStamp-a[2].timeStamp;
a=Math.pow(a[1].pageX-a[2].pageX,2)+Math.pow(a[1].pageY-a[2].pageY,2)/(d||1);switch(!0){case 100<c||100<d:return!1;case b<a+Math.pow(5,2)&&b<=Math.pow(25,2):return!0;default:return!1}}(a.points):break;default:for(;k=f.shift();)clearTimeout(k);k=setTimeout(function(){for(;k=f.shift();)clearTimeout(k);switch(!0){case !a.target:case b!==a.points[0]:case b.pageX!==a.points[0].pageX||b.pageY!==a.points[0].pageY:break;default:a.xhr&&4>a.xhr.readyState&&a.xhr.abort();c.loaded[d.replace(/#.*/,"")]=!0;++a.volume;
a.timeStamp=b.timeStamp;g.data(a.target,a.nss.data,"preload");a.lock&&(g.data(a.target,a.nss.data,"lock"),g(a.target).one(a.nss.click,b.timeStamp,function(b){if(g.data(b.currentTarget,a.nss.data)){g(this);var d=Math.max(a.lock-(new Date).getTime()+b.data,0);g.data(b.currentTarget,a.nss.data,"click");d&&(setTimeout(function(){"click"===g.data(b.currentTarget,a.nss.data)&&c.click(a,b);g.removeData(b.currentTarget,a.nss.data)},d),b.preventDefault())}}));var e=g.extend(!0,{},a.ajax,{success:function(){c.fire(a.ajax.success,
this,arguments);c.loaded[this.url.replace(/#.*/,"")]=!0;for(var e in c.req){var f=c.req[e];f&&4>f.readyState&&(f.abort(),c.req[e]=null)}a.volume-=Number(304===arguments[2].status&&!!a.volume);if("click"===g.data(b.currentTarget,a.nss.data))c.click(a,b);else{var h;a.prefetch&&(h={async:!0,dataType:"text",success:function(){c.loaded[this.url]=!0;c.req[d]=null}},e=g(arguments[0]),e.filter(a.prefetch).add(e.find(a.prefetch)).each(function(){c.prefetch.call(this,h)}))}g.removeData(b.currentTarget,a.nss.data)},
error:function(){c.fire(a.ajax.error,this,arguments);a.volume-=Number(!!a.volume);g.removeData(h,a.nss.data)}}),l=a.query;l&&(l=l.split("="),l=encodeURIComponent(l[0])+(0<l.length?"="+encodeURIComponent(l[1]):""));e.url=d.replace(/([^#]+)(#[^\s]*)?$/,"$1"+(l?(d.match(/\?/)?"&":"?")+l:"")+"$2");a.xhr=g.ajax(e)}},30);f.push(k)}},click:function(a,b){var h=b.currentTarget;a.xhr&&4>a.xhr.readyState&&a.xhr.abort();g(b.currentTarget).removeData(a.nss.data);g(m).find(b.currentTarget)[0]&&(g(m).unbind(a.nss.click).one(a.nss.click,
function(b){b.isDefaultPrevented()||(n.location.href=a.encode?c.canonicalizeURL(h.href):h.href)}),g(b.currentTarget).click());b.preventDefault()},prefetch:function(a){var b;switch(this.tagName.toLowerCase()){case "link":b=this.href;break;case "script":case "img":case "iframe":b=this.src}a?b&&!c.loaded[b]&&(a.url=b,c.req[b]=g.ajax(a)):c.loaded[b]=!0},canonicalizeURL:function(a){var b;b=c.trim(a);b=b.replace(/[<>"{}|\\^\[\]`\s].*/,"");b=/^https?:/i.test(b)?b:g("<a/>",{href:b})[0].href;b=encodeURI(decodeURI(b));
return b=b.replace(/(?:%\w{2})+/g,function(b){return a.match(b.toLowerCase())||b})},trim:function(a){if(String.prototype.trim)a=String(a).trim();else if(a=String(a).replace(/^\s+/,""))for(var b=a.length;--b;)if(/\S/.test(a.charAt(b))){a=a.substring(0,b+1);break}return a},fire:function(a,b,c,g){return"function"===typeof a?g?setTimeout(function(){a.apply(b,c)},0):a.apply(b,c):a}};(function(a,b,c,g,d){a.fn[d.name]=a[d.name]=function(){return q.apply(this,[a,b,c,g,d].concat([].slice.call(arguments)))};
d.setProperties.call(a[d.name])}).apply(this,[].slice.call(arguments).concat([c]))})(jQuery,window,document,void 0);
<|endoftext|>


<commit_before>// Copyright 2018-2020, University of Colorado Boulder

/**
 * Creates an HBox that can have the sound toggle button, a11y button, or be empty
 *
 * @author Chris Klusendorf (PhET Interactive Simulations)
 */

import inherit from '../../phet-core/js/inherit.js';
import merge from '../../phet-core/js/merge.js';
import platform from '../../phet-core/js/platform.js';
import HBox from '../../scenery/js/nodes/HBox.js';
import soundManager from '../../tambo/js/soundManager.js';
import joist from './joist.js';
import KeyboardHelpButton from './KeyboardHelpButton.js';
import NavigationBarSoundToggleButton from './NavigationBarSoundToggleButton.js';

/**
 * @param {Sim} sim
 * @param {Property.<Color|string>} backgroundColorProperty
 * @param {Tandem} tandem
 * @param {Object} [options]
 * @constructor
 */
function A11yButtonsHBox( sim, backgroundColorProperty, tandem, options ) {
  options = merge( {
    align: 'center',
    spacing: 6
  }, options );

  // list of optional buttons added for a11y
  const a11yButtons = [];

  // If the sim has sound support in its API, then create the button. This is support consistent API for PhET-iO
  if ( sim.soundPartOfTheAPI ) {
    const soundOnOffButton = new NavigationBarSoundToggleButton(
      soundManager.enabledProperty,
      backgroundColorProperty,
      tandem.createTandem( 'soundOnOffButton' )
    );

    // only put the sound on/off button on the nav bar if the sound library is enabled
    if ( sim.supportsSound ) {
      a11yButtons.push( soundOnOffButton );
    }
  }

  // If the sim has accessibility support in its API, then create the button. This is support consistent API for PhET-iO
  if ( sim.accessibilityPartOfTheAPI && sim.keyboardHelpNode ) {

    // Pops open a dialog with information about keyboard navigation
    const keyboardHelpButton = new KeyboardHelpButton(
      sim.keyboardHelpNode,
      backgroundColorProperty,
      tandem.createTandem( 'keyboardHelpButton' )
    );

    // only show the keyboard help button if the sim supports interactive descriptions, there is keyboard help content, and we are
    // not in mobile safari
    if ( sim.supportsInteractiveDescriptions && !platform.mobileSafari ) {
      a11yButtons.push( keyboardHelpButton );
    }
  }

  options.children = a11yButtons;
  HBox.call( this, options );
}

joist.register( 'A11yButtonsHBox', A11yButtonsHBox );

inherit( HBox, A11yButtonsHBox );
export default A11yButtonsHBox;<commit_msg>break long line<commit_after>// Copyright 2018-2020, University of Colorado Boulder

/**
 * Creates an HBox that can have the sound toggle button, a11y button, or be empty
 *
 * @author Chris Klusendorf (PhET Interactive Simulations)
 */

import inherit from '../../phet-core/js/inherit.js';
import merge from '../../phet-core/js/merge.js';
import platform from '../../phet-core/js/platform.js';
import HBox from '../../scenery/js/nodes/HBox.js';
import soundManager from '../../tambo/js/soundManager.js';
import joist from './joist.js';
import KeyboardHelpButton from './KeyboardHelpButton.js';
import NavigationBarSoundToggleButton from './NavigationBarSoundToggleButton.js';

/**
 * @param {Sim} sim
 * @param {Property.<Color|string>} backgroundColorProperty
 * @param {Tandem} tandem
 * @param {Object} [options]
 * @constructor
 */
function A11yButtonsHBox( sim, backgroundColorProperty, tandem, options ) {
  options = merge( {
    align: 'center',
    spacing: 6
  }, options );

  // list of optional buttons added for a11y
  const a11yButtons = [];

  // If the sim has sound support in its API, then create the button. This is support consistent API for PhET-iO
  if ( sim.soundPartOfTheAPI ) {
    const soundOnOffButton = new NavigationBarSoundToggleButton(
      soundManager.enabledProperty,
      backgroundColorProperty,
      tandem.createTandem( 'soundOnOffButton' )
    );

    // only put the sound on/off button on the nav bar if the sound library is enabled
    if ( sim.supportsSound ) {
      a11yButtons.push( soundOnOffButton );
    }
  }

  // If the sim has accessibility support in its API, then create the button. This is support consistent API for PhET-iO
  if ( sim.accessibilityPartOfTheAPI && sim.keyboardHelpNode ) {

    // Pops open a dialog with information about keyboard navigation
    const keyboardHelpButton = new KeyboardHelpButton(
      sim.keyboardHelpNode,
      backgroundColorProperty,
      tandem.createTandem( 'keyboardHelpButton' )
    );

    // only show the keyboard help button if the sim supports interactive descriptions, there is keyboard help content,
    // and we are not in mobile safari
    if ( sim.supportsInteractiveDescriptions && !platform.mobileSafari ) {
      a11yButtons.push( keyboardHelpButton );
    }
  }

  options.children = a11yButtons;
  HBox.call( this, options );
}

joist.register( 'A11yButtonsHBox', A11yButtonsHBox );

inherit( HBox, A11yButtonsHBox );
export default A11yButtonsHBox;<|endoftext|>


<commit_before>(function() {
    let objBrowser = chrome ? chrome : browser;

    //Get the blacklist domains option for the user
    objBrowser.runtime.sendMessage({func: "blacklist_domains"}, function(objResponse) {
        if(objResponse && objResponse.hasOwnProperty("resp")) {
            if(objResponse.resp == 1) {
                blacklistedDomainCheck();
            }
        }
    });

    //Detects if the current tab is in the blacklisted domains file
    function blacklistedDomainCheck() {
        let objBrowser = chrome ? chrome : browser;
        var arrBlacklistedDomains = [];
        var arrWhitelistedDomains = ["www.myetherwallet.com", "myetherwallet.com"];
        objBrowser.runtime.sendMessage({func: "blacklist_whitelist_domain_list"}, function (objResponse) {
            if (objResponse && objResponse.hasOwnProperty("resp")) {
                var objDomainLists = JSON.parse(objResponse.resp);
                var arrWhitelistedDomains = objDomainLists.whitelist;
                var arrBlacklistedDomains = objDomainLists.blacklist;
                return doBlacklistCheck(arrWhitelistedDomains, arrBlacklistedDomains);
            }
        });
    }

    function doBlacklistCheck(arrWhitelistedDomains, arrBlacklistedDomains)
    {
        //See if we are blocking all punycode domains.
        objBrowser.runtime.sendMessage({func: "block_punycode_domains"}, function(objResponse) {
            if(objResponse && objResponse.hasOwnProperty("resp")) {
                var strCurrentTab = window.location.hostname;
                var strCurrentTab = strCurrentTab.replace(/www\./g,'');

                if(objResponse.resp == 1) {
                    var arrDomainParts = strCurrentTab.split(".");
                    arrDomainParts.forEach(strDomainPart => {
                        if (strDomainPart.startsWith("xn--")) {
                            window.location.href = "https://harrydenley.com/EtherAddressLookup/phishing.html#" + (window.location.href) + "#punycode";
                            return false;
                        }
                    });
                }
            }
        });

        //Domain is whitelisted, don't check the blacklist.
        var strCurrentTab = window.location.hostname;
        strCurrentTab = strCurrentTab.replace(/www\./g,'');
        if(arrWhitelistedDomains.indexOf(strCurrentTab) >= 0) {
            console.log("Domain "+ strCurrentTab +" is whitelisted on EAL!");
            return false;
        }

        if(arrBlacklistedDomains.length > 0) {
            var isBlacklisted = arrBlacklistedDomains.indexOf(strCurrentTab) >= 0 ? true : false;

            //Only do Levenshtein if it's not blacklisted
            //Levenshtein - @sogoiii
            var blHolisticStatus = false;
            if(isBlacklisted === false && arrWhitelistedDomains.indexOf(strCurrentTab) < 0) {
                var strCurrentTab = punycode.toUnicode(strCurrentTab);
                var source = strCurrentTab.replace(/\./g, '');
                var intHolisticMetric = levenshtein(source, 'myetherwallet');
                var intHolisticLimit = 7 // How different can the word be?
                blHolisticStatus = (intHolisticMetric > 0 && intHolisticMetric < intHolisticLimit) ? true : false;
                if(blHolisticStatus === false) {
                    //Do edit distance against mycrypto
                    var intHolisticMetric = levenshtein(source, 'mycrypto');
                    blHolisticStatus = (intHolisticMetric > 0 && intHolisticMetric < 3) ? true : false;
                }
            }

            //If it's not in the whitelist and it is blacklisted or levenshtien wants to blacklist it.
            if ( arrWhitelistedDomains.indexOf(strCurrentTab) < 0 && (isBlacklisted === true || blHolisticStatus === true)) {
                console.warn(window.location.href + " is blacklisted by EAL - "+ (isBlacklisted ? "Blacklisted" : "Levenshtein Logic"));
                window.location.href = "https://harrydenley.com/EtherAddressLookup/phishing.html#"+ (window.location.href) +"#"+ (isBlacklisted ? "blacklisted" : "levenshtein");
                return false;
            }
        }

        //Now do the 3rd party domain list check if they have that option enabled.
        objBrowser.runtime.sendMessage({func: "3rd_party_blacklist_domains"}, function(objResponse) {
            if(objResponse && objResponse.hasOwnProperty("resp")) {
                if(objResponse.resp == 1) {
                    objBrowser.runtime.sendMessage({func: "3p_blacklist_domain_list"}, function(objResponse) {
                        if(objResponse && objResponse.hasOwnProperty("resp")) {
                            var obj3rdPartyLists = JSON.parse(objResponse.resp);
                            var strCurrentTab = window.location.hostname;
                            var strCurrentTab = strCurrentTab.replace(/www\./g,'');

                            for(var str3rdPartyIdentifier in obj3rdPartyLists) {

                                if(obj3rdPartyLists[str3rdPartyIdentifier].format == "sha256") {
                                    strCurrentTab = sha256(strCurrentTab);
                                }

                                if(obj3rdPartyLists[str3rdPartyIdentifier].domains.indexOf(strCurrentTab) >= 0) {
                                    console.warn(window.location.href + " is blacklisted by "+ str3rdPartyIdentifier);
                                    window.location.href = "https://harrydenley.com/EtherAddressLookup/phishing-"+ str3rdPartyIdentifier +".html#"+ (window.location.href);
                                    return false;
                                }
                            }
                        }
                    });
                }
            }
        });
    }

    function levenshtein(a, b) {
        if(a.length == 0) return b.length;
        if(b.length == 0) return a.length;

        // swap to save some memory O(min(a,b)) instead of O(a)
        if(a.length > b.length) {
            var tmp = a;
            a = b;
            b = tmp;
        }

        var row = [];
        // init the row
        for(var i = 0; i <= a.length; i++){
            row[i] = i;
        }

        // fill in the rest
        for(var i = 1; i <= b.length; i++){
            var prev = i;
            for(var j = 1; j <= a.length; j++){
                var val;
                if(b.charAt(i-1) == a.charAt(j-1)){
                    val = row[j-1]; // match
                } else {
                    val = Math.min(row[j-1] + 1, // substitution
                        prev + 1,     // insertion
                        row[j] + 1);  // deletion
                }
                row[j - 1] = prev;
                prev = val;
            }
            row[a.length] = prev;
        }

        return row[a.length];
    }
})();
<commit_msg>Adjusted edit distance for myetherwallet from 7 to 5<commit_after>(function() {
    let objBrowser = chrome ? chrome : browser;

    //Get the blacklist domains option for the user
    objBrowser.runtime.sendMessage({func: "blacklist_domains"}, function(objResponse) {
        if(objResponse && objResponse.hasOwnProperty("resp")) {
            if(objResponse.resp == 1) {
                blacklistedDomainCheck();
            }
        }
    });

    //Detects if the current tab is in the blacklisted domains file
    function blacklistedDomainCheck() {
        let objBrowser = chrome ? chrome : browser;
        var arrBlacklistedDomains = [];
        var arrWhitelistedDomains = ["www.myetherwallet.com", "myetherwallet.com"];
        objBrowser.runtime.sendMessage({func: "blacklist_whitelist_domain_list"}, function (objResponse) {
            if (objResponse && objResponse.hasOwnProperty("resp")) {
                var objDomainLists = JSON.parse(objResponse.resp);
                var arrWhitelistedDomains = objDomainLists.whitelist;
                var arrBlacklistedDomains = objDomainLists.blacklist;
                return doBlacklistCheck(arrWhitelistedDomains, arrBlacklistedDomains);
            }
        });
    }

    function doBlacklistCheck(arrWhitelistedDomains, arrBlacklistedDomains)
    {
        //See if we are blocking all punycode domains.
        objBrowser.runtime.sendMessage({func: "block_punycode_domains"}, function(objResponse) {
            if(objResponse && objResponse.hasOwnProperty("resp")) {
                var strCurrentTab = window.location.hostname;
                var strCurrentTab = strCurrentTab.replace(/www\./g,'');

                if(objResponse.resp == 1) {
                    var arrDomainParts = strCurrentTab.split(".");
                    arrDomainParts.forEach(strDomainPart => {
                        if (strDomainPart.startsWith("xn--")) {
                            window.location.href = "https://harrydenley.com/EtherAddressLookup/phishing.html#" + (window.location.href) + "#punycode";
                            return false;
                        }
                    });
                }
            }
        });

        //Domain is whitelisted, don't check the blacklist.
        var strCurrentTab = window.location.hostname;
        strCurrentTab = strCurrentTab.replace(/www\./g,'');
        if(arrWhitelistedDomains.indexOf(strCurrentTab) >= 0) {
            console.log("Domain "+ strCurrentTab +" is whitelisted on EAL!");
            return false;
        }

        if(arrBlacklistedDomains.length > 0) {
            var isBlacklisted = arrBlacklistedDomains.indexOf(strCurrentTab) >= 0 ? true : false;

            //Only do Levenshtein if it's not blacklisted
            //Levenshtein - @sogoiii
            var blHolisticStatus = false;
            if(isBlacklisted === false && arrWhitelistedDomains.indexOf(strCurrentTab) < 0) {
                var strCurrentTab = punycode.toUnicode(strCurrentTab);
                var source = strCurrentTab.replace(/\./g, '');
                var intHolisticMetric = levenshtein(source, 'myetherwallet');
                var intHolisticLimit = 5; // How different can the word be?
                blHolisticStatus = (intHolisticMetric > 0 && intHolisticMetric < intHolisticLimit) ? true : false;
                if(blHolisticStatus === false) {
                    //Do edit distance against mycrypto
                    var intHolisticMetric = levenshtein(source, 'mycrypto');
                    blHolisticStatus = (intHolisticMetric > 0 && intHolisticMetric < 3) ? true : false;
                }
            }

            //If it's not in the whitelist and it is blacklisted or levenshtien wants to blacklist it.
            if ( arrWhitelistedDomains.indexOf(strCurrentTab) < 0 && (isBlacklisted === true || blHolisticStatus === true)) {
                console.warn(window.location.href + " is blacklisted by EAL - "+ (isBlacklisted ? "Blacklisted" : "Levenshtein Logic"));
                window.location.href = "https://harrydenley.com/EtherAddressLookup/phishing.html#"+ (window.location.href) +"#"+ (isBlacklisted ? "blacklisted" : "levenshtein");
                return false;
            }
        }

        //Now do the 3rd party domain list check if they have that option enabled.
        objBrowser.runtime.sendMessage({func: "3rd_party_blacklist_domains"}, function(objResponse) {
            if(objResponse && objResponse.hasOwnProperty("resp")) {
                if(objResponse.resp == 1) {
                    objBrowser.runtime.sendMessage({func: "3p_blacklist_domain_list"}, function(objResponse) {
                        if(objResponse && objResponse.hasOwnProperty("resp")) {
                            var obj3rdPartyLists = JSON.parse(objResponse.resp);
                            var strCurrentTab = window.location.hostname;
                            var strCurrentTab = strCurrentTab.replace(/www\./g,'');

                            for(var str3rdPartyIdentifier in obj3rdPartyLists) {

                                if(obj3rdPartyLists[str3rdPartyIdentifier].format == "sha256") {
                                    strCurrentTab = sha256(strCurrentTab);
                                }

                                if(obj3rdPartyLists[str3rdPartyIdentifier].domains.indexOf(strCurrentTab) >= 0) {
                                    console.warn(window.location.href + " is blacklisted by "+ str3rdPartyIdentifier);
                                    window.location.href = "https://harrydenley.com/EtherAddressLookup/phishing-"+ str3rdPartyIdentifier +".html#"+ (window.location.href);
                                    return false;
                                }
                            }
                        }
                    });
                }
            }
        });
    }

    function levenshtein(a, b) {
        if(a.length == 0) return b.length;
        if(b.length == 0) return a.length;

        // swap to save some memory O(min(a,b)) instead of O(a)
        if(a.length > b.length) {
            var tmp = a;
            a = b;
            b = tmp;
        }

        var row = [];
        // init the row
        for(var i = 0; i <= a.length; i++){
            row[i] = i;
        }

        // fill in the rest
        for(var i = 1; i <= b.length; i++){
            var prev = i;
            for(var j = 1; j <= a.length; j++){
                var val;
                if(b.charAt(i-1) == a.charAt(j-1)){
                    val = row[j-1]; // match
                } else {
                    val = Math.min(row[j-1] + 1, // substitution
                        prev + 1,     // insertion
                        row[j] + 1);  // deletion
                }
                row[j - 1] = prev;
                prev = val;
            }
            row[a.length] = prev;
        }

        return row[a.length];
    }
})();
<|endoftext|>


<commit_before>// @flow

import React from 'react';
import {
  compose,
  lifecycle,
  pure,
  setDisplayName,
  withHandlers,
  withState,
} from 'recompose';
import { connect } from 'react-redux';
import { isEqual } from 'lodash';

import { dismissNotification, removeNotification } from '@ncigdc/dux/bannerNotification';
import nciGdcLogo from '@ncigdc/theme/images/NHI_GDC_DataPortal-logo.svg';
import HomeLink from '@ncigdc/components/Links/HomeLink';
import AnalysisLink from '@ncigdc/components/Links/AnalysisLink';
import RepositoryLink from '@ncigdc/components/Links/RepositoryLink';
import CartLink from '@ncigdc/components/Links/CartLink';
import ExploreLink, { defaultExploreQuery } from '@ncigdc/components/Links/ExploreLink';
import ProjectsLink from '@ncigdc/components/Links/ProjectsLink';
import GDCAppsDropdown from '@ncigdc/components/GDCApps/GDCAppsDropdown';
import QuickSearch from '@ncigdc/components/QuickSearch/QuickSearch';
import LoginButton from '@ncigdc/components/LoginButton';
import UserDropdown from '@ncigdc/components/UserDropdown';
import Hidden from '@ncigdc/components/Hidden';
import { setModal } from '@ncigdc/dux/modal';
import { forceLogout } from '@ncigdc/dux/auth';

import SessionExpiredModal from '@ncigdc/components/Modals/SessionExpiredModal';
import withRouter from '@ncigdc/utils/withRouter';
import Banner from '@ncigdc/uikit/Banner';
import { withTheme } from '@ncigdc/theme';
import { AnalysisIcon } from '@ncigdc/theme/icons';
import DatabaseIcon from '@ncigdc/theme/icons/Database';
import ManageSetsLink from '@ncigdc/components/Links/ManageSetsLink';
import { Row } from '@ncigdc/uikit/Flex';

import './Header.css';

const styles = {
  activeNavLink: theme => ({
    backgroundColor: theme.greyScale2,
    color: theme.white,
  }),
  iconPadding: {
    paddingRight: '4px',
  },
};

const Header = ({
  dispatch,
  isCollapsed,
  isInSearchMode,
  notifications,
  setIsCollapsed,
  setIsInSearchMode,
  theme,
  user,
}) => (

    {notifications.map(n => (
      <Banner
        {...n}
        handleOnDismiss={() => dispatch(dismissNotification(n.id))}
        key={n.id}
        />
    ))}

        <button
          className="navbar-toggle"
          onClick={() => setIsCollapsed(!isCollapsed)}
          type="button"
          >

              Toggle navigation

        </button>
        <HomeLink
          className="navbar-brand"
          style={{ padding: 0 }}
          tabIndex="0"
          >

          <Hidden>

GDC Home

          </Hidden>
        </HomeLink>

      <nav
        aria-label="Site Navigation"
        className={`navbar-collapse ${isCollapsed ? 'collapse' : ''}`}
        data-uib-collapse="hc.isCollapsed"
        onClick={() => setIsCollapsed(true)}
        style={{ outline: 'none' }}
        tabIndex="-1"
        >

            <HomeLink activeStyle={styles.activeNavLink(theme)} exact>

              Home
              <Hidden>Home</Hidden>
            </HomeLink>

            <ProjectsLink activeStyle={styles.activeNavLink(theme)} exact>

              Projects
              <Hidden>Projects</Hidden>
            </ProjectsLink>

            <ExploreLink
              activeStyle={styles.activeNavLink(theme)}
              exact
              query={defaultExploreQuery}
              >

              Exploration
              <Hidden>Exploration</Hidden>
            </ExploreLink>

            <AnalysisLink activeStyle={styles.activeNavLink(theme)} exact>
              <Row
                  // needed for handling IE default svg style
                style={{ alignItems: 'center' }}
                >
                <AnalysisIcon style={styles.iconPadding} />
                Analysis
                <Hidden>Analysis</Hidden>
              </Row>
            </AnalysisLink>

            <RepositoryLink activeStyle={styles.activeNavLink(theme)} exact>
              <DatabaseIcon style={styles.iconPadding} />
              Repository
              <Hidden>Repository</Hidden>
            </RepositoryLink>

            <QuickSearch
              isInSearchMode={isInSearchMode}
              setIsInSearchMode={setIsInSearchMode}
              tabIndex="0"
              />

          {!isInSearchMode && (
            <React.Fragment>

                <ManageSetsLink activeStyle={styles.activeNavLink(theme)} />

              {user
                ? (

                    <UserDropdown />

                )
                : (

                    <LoginButton />

                )
              }

                <CartLink>
                  {count => (

                          Cart

                        {count.toLocaleString()}

                  )}
                </CartLink>

                <GDCAppsDropdown />

            </React.Fragment>
          )}

);

export default compose(
  setDisplayName('EnhancedHeader'),
  withState('isCollapsed', 'setIsCollapsed', true),
  withState('isInSearchMode', 'setIsInSearchMode', false),
  withRouter,
  connect(state => ({
    error: state.error,
    notifications: state.bannerNotification,
    user: state.auth.user,
  })),
  withHandlers({
    handleApiError: ({ dispatch }) => ({ status, user }) => {
      if (user && status === 401) {
        dispatch(removeNotification('LOGIN'));
        dispatch(setModal(<SessionExpiredModal />));
        dispatch(forceLogout());
      }
    },
  }),
  lifecycle({
    componentDidMount(): void {
      if (this.props.error) {
        this.props.handleApiError({
          ...this.props.error,
          user: this.props.user,
        });
      }
    },
    componentWillMount() {
      if (!this.props.user) {
        this.props.dispatch(removeNotification('LOGIN'));
      }
    },
    componentWillReceiveProps({
      error: nextError,
      user: nextUser,
    }: Object): void {
      const {
        error,
      } = this.props;
      if (nextError !== error) {
        this.props.handleApiError({
          ...nextError,
          user: nextUser,
        });
      }
    },
    shouldComponentUpdate({
      error: nextError,
      isCollapsed: nextIsCollapsed,
      isInSearchMode: nextIsInSearchMode,
      notifications: nextNotifications,
      user: nextUser,
    }) {
      const {
        error,
        isCollapsed,
        isInSearchMode,
        notifications,
        user,
      } = this.props;

      return !(
        nextError === error &&
        nextIsCollapsed === isCollapsed &&
        nextIsInSearchMode === isInSearchMode &&
        isEqual(nextNotifications, notifications) &&
        nextUser === user
      );
    },
  }),
  withTheme,
  pure
)(Header);
<commit_msg>🐛 PRTL-2905 Add check for location change in Header (#2755)<commit_after>// @flow

import React from 'react';
import {
  compose,
  lifecycle,
  pure,
  setDisplayName,
  withHandlers,
  withState,
} from 'recompose';
import { connect } from 'react-redux';
import { isEqual } from 'lodash';

import { dismissNotification, removeNotification } from '@ncigdc/dux/bannerNotification';
import nciGdcLogo from '@ncigdc/theme/images/NHI_GDC_DataPortal-logo.svg';
import HomeLink from '@ncigdc/components/Links/HomeLink';
import AnalysisLink from '@ncigdc/components/Links/AnalysisLink';
import RepositoryLink from '@ncigdc/components/Links/RepositoryLink';
import CartLink from '@ncigdc/components/Links/CartLink';
import ExploreLink, { defaultExploreQuery } from '@ncigdc/components/Links/ExploreLink';
import ProjectsLink from '@ncigdc/components/Links/ProjectsLink';
import GDCAppsDropdown from '@ncigdc/components/GDCApps/GDCAppsDropdown';
import QuickSearch from '@ncigdc/components/QuickSearch/QuickSearch';
import LoginButton from '@ncigdc/components/LoginButton';
import UserDropdown from '@ncigdc/components/UserDropdown';
import Hidden from '@ncigdc/components/Hidden';
import { setModal } from '@ncigdc/dux/modal';
import { forceLogout } from '@ncigdc/dux/auth';

import SessionExpiredModal from '@ncigdc/components/Modals/SessionExpiredModal';
import withRouter from '@ncigdc/utils/withRouter';
import Banner from '@ncigdc/uikit/Banner';
import { withTheme } from '@ncigdc/theme';
import { AnalysisIcon } from '@ncigdc/theme/icons';
import DatabaseIcon from '@ncigdc/theme/icons/Database';
import ManageSetsLink from '@ncigdc/components/Links/ManageSetsLink';
import { Row } from '@ncigdc/uikit/Flex';

import './Header.css';

const styles = {
  activeNavLink: theme => ({
    backgroundColor: theme.greyScale2,
    color: theme.white,
  }),
  iconPadding: {
    paddingRight: '4px',
  },
};

const Header = ({
  dispatch,
  isCollapsed,
  isInSearchMode,
  notifications,
  setIsCollapsed,
  setIsInSearchMode,
  theme,
  user,
}) => (

    {notifications.map(n => (
      <Banner
        {...n}
        handleOnDismiss={() => dispatch(dismissNotification(n.id))}
        key={n.id}
        />
    ))}

        <button
          className="navbar-toggle"
          onClick={() => setIsCollapsed(!isCollapsed)}
          type="button"
          >

              Toggle navigation

        </button>
        <HomeLink
          className="navbar-brand"
          style={{ padding: 0 }}
          tabIndex="0"
          >

          <Hidden>

GDC Home

          </Hidden>
        </HomeLink>

      <nav
        aria-label="Site Navigation"
        className={`navbar-collapse ${isCollapsed ? 'collapse' : ''}`}
        data-uib-collapse="hc.isCollapsed"
        onClick={() => setIsCollapsed(true)}
        style={{ outline: 'none' }}
        tabIndex="-1"
        >

            <HomeLink activeStyle={styles.activeNavLink(theme)} exact>

              Home
              <Hidden>Home</Hidden>
            </HomeLink>

            <ProjectsLink activeStyle={styles.activeNavLink(theme)} exact>

              Projects
              <Hidden>Projects</Hidden>
            </ProjectsLink>

            <ExploreLink
              activeStyle={styles.activeNavLink(theme)}
              exact
              query={defaultExploreQuery}
              >

              Exploration
              <Hidden>Exploration</Hidden>
            </ExploreLink>

            <AnalysisLink activeStyle={styles.activeNavLink(theme)} exact>
              <Row
                  // needed for handling IE default svg style
                style={{ alignItems: 'center' }}
                >
                <AnalysisIcon style={styles.iconPadding} />
                Analysis
                <Hidden>Analysis</Hidden>
              </Row>
            </AnalysisLink>

            <RepositoryLink activeStyle={styles.activeNavLink(theme)} exact>
              <DatabaseIcon style={styles.iconPadding} />
              Repository
              <Hidden>Repository</Hidden>
            </RepositoryLink>

            <QuickSearch
              isInSearchMode={isInSearchMode}
              setIsInSearchMode={setIsInSearchMode}
              tabIndex="0"
              />

          {!isInSearchMode && (
            <React.Fragment>

                <ManageSetsLink activeStyle={styles.activeNavLink(theme)} />

              {user
                ? (

                    <UserDropdown />

                )
                : (

                    <LoginButton />

                )
              }

                <CartLink>
                  {count => (

                          Cart

                        {count.toLocaleString()}

                  )}
                </CartLink>

                <GDCAppsDropdown />

            </React.Fragment>
          )}

);

export default compose(
  setDisplayName('EnhancedHeader'),
  withState('isCollapsed', 'setIsCollapsed', true),
  withState('isInSearchMode', 'setIsInSearchMode', false),
  withRouter,
  connect(state => ({
    error: state.error,
    notifications: state.bannerNotification,
    user: state.auth.user,
  })),
  withHandlers({
    handleApiError: ({ dispatch }) => ({ status, user }) => {
      if (user && status === 401) {
        dispatch(removeNotification('LOGIN'));
        dispatch(setModal(<SessionExpiredModal />));
        dispatch(forceLogout());
      }
    },
  }),
  lifecycle({
    componentDidMount(): void {
      if (this.props.error) {
        this.props.handleApiError({
          ...this.props.error,
          user: this.props.user,
        });
      }
    },
    componentWillMount() {
      if (!this.props.user) {
        this.props.dispatch(removeNotification('LOGIN'));
      }
    },
    componentWillReceiveProps({
      error: nextError,
      user: nextUser,
    }: Object): void {
      const {
        error,
      } = this.props;
      if (nextError !== error) {
        this.props.handleApiError({
          ...nextError,
          user: nextUser,
        });
      }
    },
    shouldComponentUpdate({
      error: nextError,
      isCollapsed: nextIsCollapsed,
      isInSearchMode: nextIsInSearchMode,
      location: nextLocation,
      notifications: nextNotifications,
      user: nextUser,
    }) {
      const {
        error,
        isCollapsed,
        isInSearchMode,
        location,
        notifications,
        user,
      } = this.props;

      return !(
        nextError === error &&
        nextIsCollapsed === isCollapsed &&
        nextIsInSearchMode === isInSearchMode &&
        isEqual(nextNotifications, notifications) &&
        isEqual(nextLocation, location) &&
        nextUser === user
      );
    },
  }),
  withTheme,
  pure
)(Header);
<|endoftext|>


<commit_before>/**
 * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config ) {
	config.enterMode = CKEDITOR.ENTER_BR;
	config.removePlugins = 'elementspath';
	config.resize_enabled = false;
	config.toolbar = [
		['Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat','-','BulletedList','NumberedList' ]
	];
	// Set the most common block elements.
	config.format_tags = 'p;h1;h2;h3;pre';

	// Simplify the dialog windows.
	config.removeDialogTabs = 'image:advanced;link:advanced';
};
<commit_msg>br fix<commit_after>/**
 * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config ) {

	config.removePlugins = 'elementspath';
	config.resize_enabled = false;
	config.toolbar = [
		['Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat','-','BulletedList','NumberedList' ]
	];
	// Set the most common block elements.
	config.format_tags = 'p;h1;h2;h3;pre';

	// Simplify the dialog windows.
	config.removeDialogTabs = 'image:advanced;link:advanced';
};
<|endoftext|>


<commit_before>var pageData = {};

function buildQuizList (rows) {
    var commenterID = getParameterByName('commenter');
    var classID = getParameterByName('classid');
    if (!rows) {
        // if rows is nil, call the server.
        var rows = apiRequest(
            '/?commenter='
                + commenterID
                + '&page=class'
                + '&cmd=readquizzes'
            , {
                classid:classID
            }
        );
        if (false === rows) return;
    }
    rows.sort(function (a,b) {
        a = parseInt(a.number,10);
        b = parseInt(b.number,10);
        if (a>b) {
            return 1;
        } else if (a<b) {
            return -1;
        } else {
            return 0;
        }
    });
    // Delete children from container
    var container = document.getElementById('quiz-list');
    for (var i=0,ilen=container.childNodes.length;i<ilen;i+=1) {
        container.removeChild(container.childNodes[0]);
    }
    // Rebuild container content
    for (var i=0,ilen=rows.length;i<ilen;i+=1) {
        var nameText = document.createTextNode("Quiz "+rows[i].number);
        var idText = document.createTextNode(rows[i].number);
        var tr = document.createElement('tr');
        var nameAnchor = document.createElement('a');
        var nameTD = document.createElement('td');
        var idTD = document.createElement('td');
        nameAnchor.appendChild(nameText);

        nameAnchor.setAttribute('href', fixPath('/?commenter=' + commenterID + '&page=quiz&classid=' + classID + '&quizno=' + rows[i].number));

        nameTD.appendChild(nameAnchor);
        tr.appendChild(nameTD);
        idTD.appendChild(idText);
        idTD.style.display = 'none';
        tr.appendChild(idTD)
        if (rows[i].numberOfCommentsNeeded) {
            var markerText = document.createTextNode('(' + rows[i].numberOfCommentsNeeded + ')');
            var markerTD = document.createElement('td');
            markerTD.appendChild(markerText);
            tr.appendChild(markerTD);
        }
        container.appendChild(tr);
    }
}

function setRuleButtons () {
    var ruleLangButtons = document.getElementsByClassName('rule-lang-buttons');
    // API call
    var commenterKey = getParameterByName('commenter');
    var rows = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readrulelangs'
    );
    if (false === rows) return;
    var ruleLangButtons = document.getElementById('rule-lang-buttons');
    for (var i=0,ilen=ruleLangButtons.childNodes.length;i<ilen;i+=1) {
        ruleLangButtons.removeChild(ruleLangButtons.childNodes[0]);
    }
    for (var i=0,ilen=rows.length;i<ilen;i+=1) {
        var row = rows[i];
        var button = document.createElement('input');
        button.setAttribute('type', 'button');
        button.setAttribute('class', 'button rule-lang-buttons');
        button.setAttribute('onclick', 'setButtonMode("' + row.lang + '","' + row.langName + '")');
        button.value = 'Glosses: ' + row.langName;
        ruleLangButtons.appendChild(button);
    }
}

function setButtonMode (mode,langName) {
    var ruleLangButtons = document.getElementsByClassName('rule-lang-buttons');
    var returnToMainDisplayButton = document.getElementById('return-to-main-display-button');
    var mainDisplay = document.getElementById('main-display');
    var rulesDisplay = document.getElementById('rules-display');
    var mainDisplayTitle = document.getElementById('main-display-title');
    var rulesDisplayTitle = document.getElementById('rules-display-title');
    if (mode) {
        pageData.lang = mode;
        pageData.langName = langName;
        buildRulesList(mode,langName);
        for (var i=0,ilen=ruleLangButtons.length;i<ilen;i+=1) {
            ruleLangButtons[i].style.display = 'none';
        }
        returnToMainDisplayButton.style.display = 'inline';
        mainDisplay.style.display = 'none';
        mainDisplayTitle.style.display = 'none';
        rulesDisplay.style.display = 'table';
        rulesDisplayTitle.style.display = 'block';
    } else {
        for (var i=0,ilen=ruleLangButtons.length;i<ilen;i+=1) {
            ruleLangButtons[i].style.display = 'inline';
        }
        returnToMainDisplayButton.style.display = 'none';
        mainDisplay.style.display = 'table';
        mainDisplayTitle.style.display = 'block';
        rulesDisplay.style.display = 'none';
        rulesDisplayTitle.style.display = 'none';
    }
}

function buildRulesList () {
    var mode = pageData.lang;
    var langName = pageData.langName;
    var ruleLanguageName = document.getElementById('rule-language');
    ruleLanguageName.innerHTML = langName;
    // API call for list of rules (admin user + current commenter)
    var commenterKey = getParameterByName('commenter');
    var classID = getParameterByName('classid');
    var rulesForLang = document.getElementById('rules-for-lang');
    var rows = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readrules'
        , {
            lang:mode,
            classid:classID
        }
    );
    if (false === rows) return;
    for (var i=0,ilen=rulesForLang.childNodes.length;i<ilen;i+=1) {
        rulesForLang.removeChild(rulesForLang.childNodes[0]);
    }
    for (var i=0,ilen=rows.length;i<ilen;i+=1) {
        var row = rows[i];
        var tr = document.createElement('tr');
        tr.setAttribute('id','rule-' + row.ruleID);
        var needsGloss = ' needs-gloss';
        if (row.hasGloss) {
            needsGloss = '';
        }
        tr.innerHTML = '
' + markdown(row.ruleText) + '
	<input type="button" class="button float-right" value="Save" onclick="saveRule(this)" style="display:none;"/><input type="button" class="button float-right" value="Edit" onclick="editRule(this)" style="display:none;"/><input type="button" class="button no-float" value="Del" onclick="confirmDelete(this,\'deleteRule\')" style="display:none;"/>	';
        rulesForLang.appendChild(tr);
    }
};

function deleteRule (node) {
    // API call
    var rownode = node.parentNode.parentNode;
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=deleteonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang
        }
    );
    if (false === row) return;
    var nextnode = rownode.nextSibling;
    nextnode.parentNode.removeChild(nextnode);
    rownode.parentNode.removeChild(rownode);
};

function setChildHeight (textarea) {
    var height = textarea.parentNode.offsetHeight;
    textarea.style.height = height;
}

function openRule (node) {
    var rownode = node.parentNode;
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var saveButton = rownode.childNodes[1].childNodes[0];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    saveButton.style.display = 'inline';
    // API call
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang
        }
    );
    if (false === row) return;
    if (row.ruleSource) {
        var renderedrule = rownode.childNodes[0].childNodes[0];
        var textarea = document.createElement('textarea');
        textarea.innerHTML = row.ruleSource;
        renderedrule.parentNode.replaceChild(textarea,renderedrule);
        deleteButton.style.display = 'inline';
    }
    var tr = document.createElement('tr');
    tr.innerHTML = '
' + markdown(row.stringOrig) + '
	<textarea>' + row.stringTrans + '</textarea>	'
    rownode.parentNode.insertBefore(tr,rownode.nextSibling);
    node.setAttribute('onclick','void(0);');
    setChildHeight(tr.childNodes[0].childNodes[0]);
    setChildHeight(tr.childNodes[1].childNodes[0]);
};

function saveRule (node) {
    var rownode = node.parentNode.parentNode;
    var orignode = rownode.nextSibling.childNodes[0];
    var textnode = rownode.nextSibling.childNodes[1].childNodes[0];
    var rulenode = rownode.childNodes[0].childNodes[0];
    ruleText = rulenode.tagName === 'TEXTAREA' ? rulenode.value : null;
    var glossText = textnode.value;
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var saveButton = rownode.childNodes[1].childNodes[0];
    var editButton = rownode.childNodes[1].childNodes[1];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    // API call
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=saveonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang,
            glosstext:glossText,
            ruletext:ruleText
        }
    );
    if (false === row) return;
    if (ruleText) {
        var ruleTextNode = document.createElement('div');
        ruleTextNode.innerHTML = markdown(row.ruleText);
        rulenode.parentNode.replaceChild(ruleTextNode,rulenode);
        ruleTextNode.parentNode.setAttribute('onclick','closeRule(this);');
    }
    orignode.innerHTML = '
' + markdown(row.stringOrig) + '
';
    var renderedNode = document.createElement('div');
    renderedNode.innerHTML = markdown(row.stringTrans);
    textnode.parentNode.replaceChild(renderedNode,textnode);
    saveButton.style.display = 'none';
    editButton.style.display = 'inline';
    deleteButton.style.display = 'none';
    node.parentNode.previousSibling.setAttribute('onclick','closeRule(this);');
};

function editRule (node) {
    var rownode = node.parentNode.parentNode;
    var renderednode = rownode.nextSibling.childNodes[1].childNodes[0];
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var saveButton = rownode.childNodes[1].childNodes[0];
    var editButton = rownode.childNodes[1].childNodes[1];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    // API call
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang
        }
    );
    if (false === row) return;
    if (row.ruleSource) {
        var renderedrule = rownode.childNodes[0].childNodes[0];
        var textarea = document.createElement('textarea');
        textarea.innerHTML = row.ruleSource;
        renderedrule.parentNode.replaceChild(textarea,renderedrule);
        deleteButton.style.display = 'inline';
    }
    var textnode = document.createElement('textarea');
    textnode.innerHTML = row.stringTrans;
    renderednode.parentNode.replaceChild(textnode,renderednode);
    saveButton.style.display = 'inline';
    editButton.style.display = 'none';
    node.parentNode.previousSibling.setAttribute('onclick','void(0);');
    setChildHeight(tr.childNodes[0].childNodes[0]);
    setChildHeight(tr.childNodes[1].childNodes[0]);
};

function closeRule (node) {
    var rownode = node.parentNode;
    var saveButton = rownode.childNodes[1].childNodes[0];
    var editButton = rownode.childNodes[1].childNodes[1];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    saveButton.style.display = 'none';
    editButton.style.display = 'none';
    deleteButton.style.display = 'none';
    var contentrownode = rownode.nextSibling;
    contentrownode.parentNode.removeChild(contentrownode);
    node.setAttribute('onclick', 'openRule(this);');
};
<commit_msg>Fix up typos<commit_after>var pageData = {};

function buildQuizList (rows) {
    var commenterID = getParameterByName('commenter');
    var classID = getParameterByName('classid');
    if (!rows) {
        // if rows is nil, call the server.
        var rows = apiRequest(
            '/?commenter='
                + commenterID
                + '&page=class'
                + '&cmd=readquizzes'
            , {
                classid:classID
            }
        );
        if (false === rows) return;
    }
    rows.sort(function (a,b) {
        a = parseInt(a.number,10);
        b = parseInt(b.number,10);
        if (a>b) {
            return 1;
        } else if (a<b) {
            return -1;
        } else {
            return 0;
        }
    });
    // Delete children from container
    var container = document.getElementById('quiz-list');
    for (var i=0,ilen=container.childNodes.length;i<ilen;i+=1) {
        container.removeChild(container.childNodes[0]);
    }
    // Rebuild container content
    for (var i=0,ilen=rows.length;i<ilen;i+=1) {
        var nameText = document.createTextNode("Quiz "+rows[i].number);
        var idText = document.createTextNode(rows[i].number);
        var tr = document.createElement('tr');
        var nameAnchor = document.createElement('a');
        var nameTD = document.createElement('td');
        var idTD = document.createElement('td');
        nameAnchor.appendChild(nameText);

        nameAnchor.setAttribute('href', fixPath('/?commenter=' + commenterID + '&page=quiz&classid=' + classID + '&quizno=' + rows[i].number));

        nameTD.appendChild(nameAnchor);
        tr.appendChild(nameTD);
        idTD.appendChild(idText);
        idTD.style.display = 'none';
        tr.appendChild(idTD)
        if (rows[i].numberOfCommentsNeeded) {
            var markerText = document.createTextNode('(' + rows[i].numberOfCommentsNeeded + ')');
            var markerTD = document.createElement('td');
            markerTD.appendChild(markerText);
            tr.appendChild(markerTD);
        }
        container.appendChild(tr);
    }
}

function setRuleButtons () {
    var ruleLangButtons = document.getElementsByClassName('rule-lang-buttons');
    // API call
    var commenterKey = getParameterByName('commenter');
    var rows = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readrulelangs'
    );
    if (false === rows) return;
    var ruleLangButtons = document.getElementById('rule-lang-buttons');
    for (var i=0,ilen=ruleLangButtons.childNodes.length;i<ilen;i+=1) {
        ruleLangButtons.removeChild(ruleLangButtons.childNodes[0]);
    }
    for (var i=0,ilen=rows.length;i<ilen;i+=1) {
        var row = rows[i];
        var button = document.createElement('input');
        button.setAttribute('type', 'button');
        button.setAttribute('class', 'button rule-lang-buttons');
        button.setAttribute('onclick', 'setButtonMode("' + row.lang + '","' + row.langName + '")');
        button.value = 'Glosses: ' + row.langName;
        ruleLangButtons.appendChild(button);
    }
}

function setButtonMode (mode,langName) {
    var ruleLangButtons = document.getElementsByClassName('rule-lang-buttons');
    var returnToMainDisplayButton = document.getElementById('return-to-main-display-button');
    var mainDisplay = document.getElementById('main-display');
    var rulesDisplay = document.getElementById('rules-display');
    var mainDisplayTitle = document.getElementById('main-display-title');
    var rulesDisplayTitle = document.getElementById('rules-display-title');
    if (mode) {
        pageData.lang = mode;
        pageData.langName = langName;
        buildRulesList(mode,langName);
        for (var i=0,ilen=ruleLangButtons.length;i<ilen;i+=1) {
            ruleLangButtons[i].style.display = 'none';
        }
        returnToMainDisplayButton.style.display = 'inline';
        mainDisplay.style.display = 'none';
        mainDisplayTitle.style.display = 'none';
        rulesDisplay.style.display = 'table';
        rulesDisplayTitle.style.display = 'block';
    } else {
        for (var i=0,ilen=ruleLangButtons.length;i<ilen;i+=1) {
            ruleLangButtons[i].style.display = 'inline';
        }
        returnToMainDisplayButton.style.display = 'none';
        mainDisplay.style.display = 'table';
        mainDisplayTitle.style.display = 'block';
        rulesDisplay.style.display = 'none';
        rulesDisplayTitle.style.display = 'none';
    }
}

function buildRulesList () {
    var mode = pageData.lang;
    var langName = pageData.langName;
    var ruleLanguageName = document.getElementById('rule-language');
    ruleLanguageName.innerHTML = langName;
    // API call for list of rules (admin user + current commenter)
    var commenterKey = getParameterByName('commenter');
    var classID = getParameterByName('classid');
    var rulesForLang = document.getElementById('rules-for-lang');
    var rows = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readrules'
        , {
            lang:mode,
            classid:classID
        }
    );
    if (false === rows) return;
    for (var i=0,ilen=rulesForLang.childNodes.length;i<ilen;i+=1) {
        rulesForLang.removeChild(rulesForLang.childNodes[0]);
    }
    for (var i=0,ilen=rows.length;i<ilen;i+=1) {
        var row = rows[i];
        var tr = document.createElement('tr');
        tr.setAttribute('id','rule-' + row.ruleID);
        var needsGloss = ' needs-gloss';
        if (row.hasGloss) {
            needsGloss = '';
        }
        tr.innerHTML = '
' + markdown(row.ruleText) + '
	<input type="button" class="button float-right" value="Save" onclick="saveRule(this)" style="display:none;"/><input type="button" class="button float-right" value="Edit" onclick="editRule(this)" style="display:none;"/><input type="button" class="button no-float" value="Del" onclick="confirmDelete(this,\'deleteRule\')" style="display:none;"/>	';
        rulesForLang.appendChild(tr);
    }
};

function deleteRule (node) {
    // API call
    var rownode = node.parentNode.parentNode;
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=deleteonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang
        }
    );
    if (false === row) return;
    var nextnode = rownode.nextSibling;
    nextnode.parentNode.removeChild(nextnode);
    rownode.parentNode.removeChild(rownode);
};

function setChildHeight (textarea) {
    var height = textarea.parentNode.offsetHeight;
    textarea.style.height = height;
}

function openRule (node) {
    var rownode = node.parentNode;
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var saveButton = rownode.childNodes[1].childNodes[0];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    saveButton.style.display = 'inline';
    // API call
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang
        }
    );
    if (false === row) return;
    if (row.ruleSource) {
        var renderedrule = rownode.childNodes[0].childNodes[0];
        var textarea = document.createElement('textarea');
        textarea.innerHTML = row.ruleSource;
        renderedrule.parentNode.replaceChild(textarea,renderedrule);
        deleteButton.style.display = 'inline';
    }
    var tr = document.createElement('tr');
    tr.innerHTML = '
' + markdown(row.stringOrig) + '
	<textarea>' + row.stringTrans + '</textarea>	'
    rownode.parentNode.insertBefore(tr,rownode.nextSibling);
    node.setAttribute('onclick','void(0);');
    setChildHeight(rownode.childNodes[0].childNodes[0]);
    setChildHeight(rownode.childNodes[1].childNodes[0]);
};

function saveRule (node) {
    var rownode = node.parentNode.parentNode;
    var orignode = rownode.nextSibling.childNodes[0];
    var textnode = rownode.nextSibling.childNodes[1].childNodes[0];
    var rulenode = rownode.childNodes[0].childNodes[0];
    ruleText = rulenode.tagName === 'TEXTAREA' ? rulenode.value : null;
    var glossText = textnode.value;
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var saveButton = rownode.childNodes[1].childNodes[0];
    var editButton = rownode.childNodes[1].childNodes[1];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    // API call
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=saveonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang,
            glosstext:glossText,
            ruletext:ruleText
        }
    );
    if (false === row) return;
    if (ruleText) {
        var ruleTextNode = document.createElement('div');
        ruleTextNode.innerHTML = markdown(row.ruleText);
        rulenode.parentNode.replaceChild(ruleTextNode,rulenode);
        ruleTextNode.parentNode.setAttribute('onclick','closeRule(this);');
    }
    orignode.innerHTML = '
' + markdown(row.stringOrig) + '
';
    var renderedNode = document.createElement('div');
    renderedNode.innerHTML = markdown(row.stringTrans);
    textnode.parentNode.replaceChild(renderedNode,textnode);
    saveButton.style.display = 'none';
    editButton.style.display = 'inline';
    deleteButton.style.display = 'none';
    node.parentNode.previousSibling.setAttribute('onclick','closeRule(this);');
};

function editRule (node) {
    var rownode = node.parentNode.parentNode;
    var renderednode = rownode.nextSibling.childNodes[1].childNodes[0];
    var ruleID = rownode.id.split('-').slice(-1)[0];
    var saveButton = rownode.childNodes[1].childNodes[0];
    var editButton = rownode.childNodes[1].childNodes[1];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    // API call
    var commenterKey = getParameterByName('commenter');
    var row = apiRequest(
        '/?commenter='
            + commenterKey
            + '&page=class'
            + '&cmd=readonerule'
        ,{
            ruleid:ruleID,
            lang:pageData.lang
        }
    );
    if (false === row) return;
    if (row.ruleSource) {
        var renderedrule = rownode.childNodes[0].childNodes[0];
        var textarea = document.createElement('textarea');
        textarea.innerHTML = row.ruleSource;
        renderedrule.parentNode.replaceChild(textarea,renderedrule);
        deleteButton.style.display = 'inline';
    }
    var textnode = document.createElement('textarea');
    textnode.innerHTML = row.stringTrans;
    renderednode.parentNode.replaceChild(textnode,renderednode);
    saveButton.style.display = 'inline';
    editButton.style.display = 'none';
    node.parentNode.previousSibling.setAttribute('onclick','void(0);');
    setChildHeight(rownode.childNodes[0].childNodes[0]);
    setChildHeight(rownode.childNodes[1].childNodes[0]);
};

function closeRule (node) {
    var rownode = node.parentNode;
    var saveButton = rownode.childNodes[1].childNodes[0];
    var editButton = rownode.childNodes[1].childNodes[1];
    var deleteButton = rownode.childNodes[1].childNodes[2];
    saveButton.style.display = 'none';
    editButton.style.display = 'none';
    deleteButton.style.display = 'none';
    var contentrownode = rownode.nextSibling;
    contentrownode.parentNode.removeChild(contentrownode);
    node.setAttribute('onclick', 'openRule(this);');
};
<|endoftext|>


<commit_before>(function(app) {
  'use strict';

  var IScroll = require('iscroll');
  var dom = app.dom || require('./dom.js');
  var Location = app.Location || require('../models/location.js');

  var List = function(el, props) {
    this.el = el;
    this._locations = props.locations;
    this._selectedLocations = props.selectedLocations;
    this._itemElements = {};
    this._iScroll = null;
  };

  List.prototype.init = function() {
    this.el.addEventListener(dom.supportsTouch() ? 'tap' : 'click', this._onclick.bind(this));
    this._locations.on('reset', this._resetLocations.bind(this));
    this._selectedLocations.on('reset', this._resetSelectedLocations.bind(this));
    this._selectedLocations.on('add', this._addSelectedLocation.bind(this));
    this._selectedLocations.on('remove', this._removeSelectedLocation.bind(this));
    if (dom.supportsTouch()) {
      this._disableNativeScroll();
      this._disableDoubleTapZoom();
    }
  };

  List.prototype._resetLocations = function(locations) {
    var container = document.createElement('div');

    this._itemElements = locations.slice().sort(function(a, b) {
      return (a.name < b.name || a.key === Location.KEY_CURRENT_LOCATION ? -1 : 1);
    }).reduce(function(ret, location) {
      var el = this._createItemElement(location);
      dom.toggleClass(el, 'list-selected', this._selectedLocations.includes(location));
      container.appendChild(el);
      ret[location.key] = el;
      return ret;
    }.bind(this), {});

    this.el.replaceChild(container, this.el.firstElementChild);

    if (dom.supportsTouch()) {
      if (this._iScroll) {
        this._iScroll.destroy();
      }
      this._iScroll = this._createIScroll();
    }
  };

  List.prototype._resetSelectedLocations = function(selectedLocations) {
    this._locations.forEach(function(location) {
      var el = this._itemElements[location.key];
      dom.toggleClass(el, 'list-selected', selectedLocations.indexOf(location) !== -1);
    }.bind(this));
  };

  List.prototype._addSelectedLocation = function(location) {
    var el = this._itemElements[location.key];
    if (el) {
      el.classList.add('list-selected');
    }
  };

  List.prototype._removeSelectedLocation = function(location) {
    var el = this._itemElements[location.key];
    if (el) {
      el.classList.remove('list-selected');
    }
  };

  List.prototype._createItemElement = function(location) {
    var el = document.createElement('div');
    el.classList.add('list-item');
    el.setAttribute('data-key', location.key);
    var textLength = location.name.length;
    if (textLength >= 20) {
      el.style.fontSize = '11px';
    } else if (textLength >= 17) {
      el.style.fontSize = '14px';
    }
    el.textContent = location.name;
    return el;
  };

  List.prototype._createIScroll = function() {
    return new IScroll(this.el, {
      tap: true,
      scrollbars: true,
      shrinkScrollbars: 'scale',
      fadeScrollbars: true,
    });
  };

  List.prototype._onclick = function(event) {
    event.preventDefault();
    var target = event.target;
    if (!target.classList.contains('list-item')) {
      return;
    }
    var key = target.getAttribute('data-key');
    if (!Location.isValidKey(key)) {
      return;
    }
    var location = this._locations.find(function(location) {
      return (location.key === key);
    });
    if (!location) {
      return;
    }
    // toggle selection of location
    if (this._selectedLocations.includes(location)) {
      this._selectedLocations.remove(location);
    } else {
      this._selectedLocations.add(location);
    }
  };

  List.prototype._disableNativeScroll = function() {
    this.el.style.overflowY = 'hidden';
  };

  List.prototype._disableDoubleTapZoom = function() {
    this.el.addEventListener('touchstart', function(event) {
      event.preventDefault();
    });
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = List;
  } else {
    app.List = List;
  }
})(this.app || (this.app = {}));
<commit_msg>Remove unnecessary check<commit_after>(function(app) {
  'use strict';

  var IScroll = require('iscroll');
  var dom = app.dom || require('./dom.js');
  var Location = app.Location || require('../models/location.js');

  var List = function(el, props) {
    this.el = el;
    this._locations = props.locations;
    this._selectedLocations = props.selectedLocations;
    this._itemElements = {};
    this._iScroll = null;
  };

  List.prototype.init = function() {
    this.el.addEventListener(dom.supportsTouch() ? 'tap' : 'click', this._onclick.bind(this));
    this._locations.on('reset', this._resetLocations.bind(this));
    this._selectedLocations.on('reset', this._resetSelectedLocations.bind(this));
    this._selectedLocations.on('add', this._addSelectedLocation.bind(this));
    this._selectedLocations.on('remove', this._removeSelectedLocation.bind(this));
    if (dom.supportsTouch()) {
      this._disableNativeScroll();
      this._disableDoubleTapZoom();
    }
  };

  List.prototype._resetLocations = function(locations) {
    var container = document.createElement('div');

    this._itemElements = locations.slice().sort(function(a, b) {
      return (a.name < b.name || a.key === Location.KEY_CURRENT_LOCATION ? -1 : 1);
    }).reduce(function(ret, location) {
      var el = this._createItemElement(location);
      dom.toggleClass(el, 'list-selected', this._selectedLocations.includes(location));
      container.appendChild(el);
      ret[location.key] = el;
      return ret;
    }.bind(this), {});

    this.el.replaceChild(container, this.el.firstElementChild);

    if (dom.supportsTouch()) {
      if (this._iScroll) {
        this._iScroll.destroy();
      }
      this._iScroll = this._createIScroll();
    }
  };

  List.prototype._resetSelectedLocations = function(selectedLocations) {
    this._locations.forEach(function(location) {
      var el = this._itemElements[location.key];
      dom.toggleClass(el, 'list-selected', selectedLocations.indexOf(location) !== -1);
    }.bind(this));
  };

  List.prototype._addSelectedLocation = function(location) {
    var el = this._itemElements[location.key];
    if (el) {
      el.classList.add('list-selected');
    }
  };

  List.prototype._removeSelectedLocation = function(location) {
    var el = this._itemElements[location.key];
    if (el) {
      el.classList.remove('list-selected');
    }
  };

  List.prototype._createItemElement = function(location) {
    var el = document.createElement('div');
    el.classList.add('list-item');
    el.setAttribute('data-key', location.key);
    var textLength = location.name.length;
    if (textLength >= 20) {
      el.style.fontSize = '11px';
    } else if (textLength >= 17) {
      el.style.fontSize = '14px';
    }
    el.textContent = location.name;
    return el;
  };

  List.prototype._createIScroll = function() {
    return new IScroll(this.el, {
      tap: true,
      scrollbars: true,
      shrinkScrollbars: 'scale',
      fadeScrollbars: true,
    });
  };

  List.prototype._onclick = function(event) {
    event.preventDefault();
    var target = event.target;
    if (!target.classList.contains('list-item')) {
      return;
    }
    var key = target.getAttribute('data-key');
    var location = this._locations.find(function(location) {
      return (location.key === key);
    });
    if (!location) {
      return;
    }
    // toggle selection of location
    if (this._selectedLocations.includes(location)) {
      this._selectedLocations.remove(location);
    } else {
      this._selectedLocations.add(location);
    }
  };

  List.prototype._disableNativeScroll = function() {
    this.el.style.overflowY = 'hidden';
  };

  List.prototype._disableDoubleTapZoom = function() {
    this.el.addEventListener('touchstart', function(event) {
      event.preventDefault();
    });
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = List;
  } else {
    app.List = List;
  }
})(this.app || (this.app = {}));
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const React = require('react')
const ImmutableComponent = require('./immutableComponent')
const Immutable = require('immutable')
const electron = global.require('electron')
const ipc = electron.ipcRenderer

// Actions
const WindowActions = require('../actions/windowActions')
const AppActions = require('../actions/appActions')
const loadOpenSearch = require('../lib/openSearch').loadOpenSearch
const contextMenus = require('../contextMenus')
const getSetting = require('../settings').getSetting

// Components
const NavigationBar = require('./navigationBar')
const Frame = require('./frame')
const TabPages = require('./tabPages')
const TabsToolbar = require('./tabsToolbar')
const UpdateBar = require('./updateBar')
const Button = require('./button')
const SiteInfo = require('./siteInfo')
const ReleaseNotes = require('./releaseNotes')

// Constants
const Config = require('../constants/config')
const AppConfig = require('../constants/appConfig')
const messages = require('../constants/messages')
const settings = require('../constants/settings')

// State handling
const FrameStateUtil = require('../state/frameStateUtil')

class Main extends ImmutableComponent {
  registerSwipeListener () {
    // Navigates back/forward on OS X two-finger swipe
    var trackingFingers = false
    var deltaX = 0
    var deltaY = 0
    var startTime = 0

    this.mainWindow.addEventListener('wheel', (e) => {
      if (trackingFingers) {
        deltaX = deltaX + e.deltaX
        deltaY = deltaY + e.deltaY
      }
    })

    ipc.on('scroll-touch-begin', function () {
      trackingFingers = true
      startTime = (new Date()).getTime()
    })
    ipc.on('scroll-touch-end', function () {
      var time = (new Date()).getTime() - startTime
      var xVelocity = deltaX / time
      var yVelocity = deltaY / time
      if (trackingFingers && Math.abs(yVelocity) < 1) {
        if (xVelocity > 4) {
          electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_FORWARD)
        } else if (xVelocity < -4) {
          electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_BACK)
        }
      }
      trackingFingers = false
      deltaX = 0
      deltaY = 0
      startTime = 0
    })

    ipc.on(messages.CHANGE_SETTING, function (e, key, value) {
      AppActions.changeSetting(key, value)
    })
  }

  loadOpenSearch () {
    let engine = getSetting(this.props.appState.get('settings'), settings.DEFAULT_SEARCH_ENGINE)
    if (this.lastLoadedOpenSearch === undefined || engine !== this.lastLoadedOpenSearch) {
      loadOpenSearch(engine).then(searchDetail => WindowActions.setSearchDetail(searchDetail))
      this.lastLoadedOpenSearch = engine
    }
  }

  componentDidUpdate () {
    this.loadOpenSearch()
  }

  componentDidMount () {
    this.registerSwipeListener()
    ipc.on(messages.STOP_LOAD, () => {
      electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_STOP)
    })
    ipc.on(messages.CONTEXT_MENU_OPENED, (e, nodeProps) => {
      contextMenus.onMainContextMenu(nodeProps)
    })
    ipc.on(messages.SHORTCUT_NEW_FRAME, (event, url, options = {}) => {
      if (options.singleFrame) {
        const frameProps = self.props.windowState.get('frames').find(frame => frame.get('location') === url)
        if (frameProps) {
          WindowActions.setActiveFrame(frameProps)
          return
        }
      }

      let openInForeground = getSetting(self.props.appState.get('settings'), settings.SWITCH_TO_NEW_TABS) === true || options.openInForeground
      WindowActions.newFrame({
        location: url || Config.defaultUrl,
        isPrivate: !!options.isPrivate,
        isPartitioned: !!options.isPartitioned
      }, openInForeground)

      // Focus URL bar when adding tab via shortcut
      electron.remote.getCurrentWebContents().send(messages.SHORTCUT_FOCUS_URL)
    })

    ipc.on(messages.SHORTCUT_CLOSE_FRAME, (e, i) => typeof i !== 'undefined'
      ? WindowActions.closeFrame(self.props.windowState.get('frames'), FrameStateUtil.getFrameByKey(self.props.windowState, i))
      : WindowActions.closeFrame(self.props.windowState.get('frames'), FrameStateUtil.getActiveFrame(this.props.windowState)))
    ipc.on(messages.SHORTCUT_UNDO_CLOSED_FRAME, () => WindowActions.undoClosedFrame())

    const self = this
    ipc.on(messages.SHORTCUT_SET_ACTIVE_FRAME_BY_INDEX, (e, i) =>
      WindowActions.setActiveFrame(FrameStateUtil.getFrameByIndex(self.props.windowState, i)))

    ipc.on(messages.SHORTCUT_SET_ACTIVE_FRAME_TO_LAST, () =>
      WindowActions.setActiveFrame(self.props.windowState.getIn(['frames', self.props.windowState.get('frames').size - 1])))

    ipc.on(messages.BLOCKED_RESOURCE, (e, blockType, details) => {
      const filteredFrameProps = this.props.windowState.get('frames').filter(frame => frame.get('location') === details.firstPartyUrl)
      filteredFrameProps.forEach(frameProps =>
        WindowActions.setBlockedBy(frameProps, blockType, details.url))
    })

    ipc.on(messages.SHORTCUT_ACTIVE_FRAME_BACK, this.onBack.bind(this))
    ipc.on(messages.SHORTCUT_ACTIVE_FRAME_FORWARD, this.onForward.bind(this))

    this.loadOpenSearch()

    window.addEventListener('mousemove', (e) => {
      self.checkForTitleMode(e.pageY)
    })
  }

  checkForTitleMode (pageY) {
    const height = document.querySelector('#navigator').getBoundingClientRect().bottom
    if (pageY <= height && this.props.windowState.getIn(['ui', 'mouseInTitlebar']) !== true) {
      WindowActions.setMouseInTitlebar(true)
    } else if (pageY === undefined || pageY > height && this.props.windowState.getIn(['ui', 'mouseInTitlebar']) !== false) {
      WindowActions.setMouseInTitlebar(false)
    }
  }

  get activeFrame () {
    return this.frames[this.props.windowState.get('activeFrameKey')]
  }

  onBack () {
    this.activeFrame.goBack()
  }

  onForward () {
    this.activeFrame.goForward()
  }

  onBraveMenu () {
    // TODO
  }

  onHamburgerMenu () {
    let settings = {}
    Object.keys(AppConfig.resourceNames).forEach((name) => {
      let value = AppConfig.resourceNames[name]
      let enabled = this.props.appState.getIn([value, 'enabled'])
      settings[value] = enabled === undefined ? AppConfig[value].enabled : enabled
    })
    // whether the current page is bookmarked. needed to re-initialize the
    // application menu.
    settings.bookmarked = this.navBar.bookmarked
    contextMenus.onHamburgerMenu(settings)
  }

  onMainFocus () {
    // When the main container is in focus, set the URL bar to inactive.
    WindowActions.setUrlBarActive(false)
  }

  onHideSiteInfo () {
    WindowActions.setSiteInfoVisible(false)
  }

  onHideReleaseNotes () {
    WindowActions.setReleaseNotesVisible(false)
  }

  get enableAds () {
    let enabled = this.props.appState.getIn(['adInsertion', 'enabled'])
    if (enabled === undefined) {
      enabled = AppConfig.adInsertion.enabled
    }
    return enabled
  }

  render () {
    const comparatorByKeyAsc = (a, b) => a.get('key') > b.get('key')
      ? 1 : b.get('key') > a.get('key') ? -1 : 0

    // Sort frames by key so that the order of the frames do not change which could
    // cause unexpected reloading when a user moves tabs.
    // All frame operations work off of frame keys and not index though so unsorted frames
    // can be passed everywhere other than the Frame elements.
    const sortedFrames = this.props.windowState.get('frames').sort(comparatorByKeyAsc)

    const activeFrame = FrameStateUtil.getActiveFrame(this.props.windowState)

    this.frames = {}
    const settingsState = this.props.appState.get('settings') || new Immutable.Map()

    return
 this.mainWindow = node}>

        <NavigationBar
          ref={node => this.navBar = node}
          navbar={activeFrame && activeFrame.get('navbar')}
          frames={this.props.windowState.get('frames')}
          sites={this.props.appState.get('sites')}
          activeFrame={activeFrame}
          mouseInTitlebar={this.props.windowState.getIn(['ui', 'mouseInTitlebar'])}
          searchSuggestions={activeFrame && activeFrame.getIn(['navbar', 'urlbar', 'searchSuggestions'])}
          settings={settingsState}
          searchDetail={this.props.windowState.get('searchDetail')}
        />
        { this.props.windowState.getIn(['ui', 'siteInfo', 'isVisible'])
          ? <SiteInfo frameProps={activeFrame}
              siteInfo={this.props.windowState.getIn(['ui', 'siteInfo'])}
              onHide={this.onHideSiteInfo.bind(this)} /> : null
        }
        { this.props.windowState.getIn(['ui', 'releaseNotes', 'isVisible'])
          ? <ReleaseNotes
              metadata={this.props.appState.getIn(['updates', 'metadata'])}
              onHide={this.onHideReleaseNotes.bind(this)} /> : null
        }

          <Button iconClass='braveMenu'
            className='navbutton'
            onClick={this.onBraveMenu.bind(this)} />

        <TabPages frames={this.props.windowState.get('frames')}
          tabPageIndex={this.props.windowState.getIn(['ui', 'tabs', 'tabPageIndex'])}
        />
        <TabsToolbar
          paintTabs={getSetting(settingsState, settings.PAINT_TABS)}
          tabs={this.props.windowState.getIn(['ui', 'tabs'])}
          frames={this.props.windowState.get('frames')}
          sites={this.props.appState.get('sites')}
          key='tab-bar'
          activeFrame={activeFrame}
          onMenu={this.onHamburgerMenu.bind(this)}
        />
        <UpdateBar updates={this.props.appState.get('updates')} />

        {
          sortedFrames.map(frame =>
            <Frame
              ref={node => this.frames[frame.get('key')] = node}
              prefOpenInForeground={getSetting(settingsState, settings.SWITCH_TO_NEW_TABS)}
              frames={this.props.windowState.get('frames')}
              frame={frame}
              key={frame.get('key')}
              settings={settingsState || new Immutable.Map()}
              enableAds={this.enableAds}
              isPreview={frame.get('key') === this.props.windowState.get('previewFrameKey')}
              isActive={FrameStateUtil.isFrameKeyActive(this.props.windowState, frame.get('key'))}
            />)
        }

  }
}

module.exports = Main
<commit_msg>Fix pinned tabs counting for page count<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const React = require('react')
const ImmutableComponent = require('./immutableComponent')
const Immutable = require('immutable')
const electron = global.require('electron')
const ipc = electron.ipcRenderer

// Actions
const WindowActions = require('../actions/windowActions')
const AppActions = require('../actions/appActions')
const loadOpenSearch = require('../lib/openSearch').loadOpenSearch
const contextMenus = require('../contextMenus')
const getSetting = require('../settings').getSetting

// Components
const NavigationBar = require('./navigationBar')
const Frame = require('./frame')
const TabPages = require('./tabPages')
const TabsToolbar = require('./tabsToolbar')
const UpdateBar = require('./updateBar')
const Button = require('./button')
const SiteInfo = require('./siteInfo')
const ReleaseNotes = require('./releaseNotes')

// Constants
const Config = require('../constants/config')
const AppConfig = require('../constants/appConfig')
const messages = require('../constants/messages')
const settings = require('../constants/settings')

// State handling
const FrameStateUtil = require('../state/frameStateUtil')

class Main extends ImmutableComponent {
  registerSwipeListener () {
    // Navigates back/forward on OS X two-finger swipe
    var trackingFingers = false
    var deltaX = 0
    var deltaY = 0
    var startTime = 0

    this.mainWindow.addEventListener('wheel', (e) => {
      if (trackingFingers) {
        deltaX = deltaX + e.deltaX
        deltaY = deltaY + e.deltaY
      }
    })

    ipc.on('scroll-touch-begin', function () {
      trackingFingers = true
      startTime = (new Date()).getTime()
    })
    ipc.on('scroll-touch-end', function () {
      var time = (new Date()).getTime() - startTime
      var xVelocity = deltaX / time
      var yVelocity = deltaY / time
      if (trackingFingers && Math.abs(yVelocity) < 1) {
        if (xVelocity > 4) {
          electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_FORWARD)
        } else if (xVelocity < -4) {
          electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_BACK)
        }
      }
      trackingFingers = false
      deltaX = 0
      deltaY = 0
      startTime = 0
    })

    ipc.on(messages.CHANGE_SETTING, function (e, key, value) {
      AppActions.changeSetting(key, value)
    })
  }

  loadOpenSearch () {
    let engine = getSetting(this.props.appState.get('settings'), settings.DEFAULT_SEARCH_ENGINE)
    if (this.lastLoadedOpenSearch === undefined || engine !== this.lastLoadedOpenSearch) {
      loadOpenSearch(engine).then(searchDetail => WindowActions.setSearchDetail(searchDetail))
      this.lastLoadedOpenSearch = engine
    }
  }

  componentDidUpdate () {
    this.loadOpenSearch()
  }

  componentDidMount () {
    this.registerSwipeListener()
    ipc.on(messages.STOP_LOAD, () => {
      electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_STOP)
    })
    ipc.on(messages.CONTEXT_MENU_OPENED, (e, nodeProps) => {
      contextMenus.onMainContextMenu(nodeProps)
    })
    ipc.on(messages.SHORTCUT_NEW_FRAME, (event, url, options = {}) => {
      if (options.singleFrame) {
        const frameProps = self.props.windowState.get('frames').find(frame => frame.get('location') === url)
        if (frameProps) {
          WindowActions.setActiveFrame(frameProps)
          return
        }
      }

      let openInForeground = getSetting(self.props.appState.get('settings'), settings.SWITCH_TO_NEW_TABS) === true || options.openInForeground
      WindowActions.newFrame({
        location: url || Config.defaultUrl,
        isPrivate: !!options.isPrivate,
        isPartitioned: !!options.isPartitioned
      }, openInForeground)

      // Focus URL bar when adding tab via shortcut
      electron.remote.getCurrentWebContents().send(messages.SHORTCUT_FOCUS_URL)
    })

    ipc.on(messages.SHORTCUT_CLOSE_FRAME, (e, i) => typeof i !== 'undefined'
      ? WindowActions.closeFrame(self.props.windowState.get('frames'), FrameStateUtil.getFrameByKey(self.props.windowState, i))
      : WindowActions.closeFrame(self.props.windowState.get('frames'), FrameStateUtil.getActiveFrame(this.props.windowState)))
    ipc.on(messages.SHORTCUT_UNDO_CLOSED_FRAME, () => WindowActions.undoClosedFrame())

    const self = this
    ipc.on(messages.SHORTCUT_SET_ACTIVE_FRAME_BY_INDEX, (e, i) =>
      WindowActions.setActiveFrame(FrameStateUtil.getFrameByIndex(self.props.windowState, i)))

    ipc.on(messages.SHORTCUT_SET_ACTIVE_FRAME_TO_LAST, () =>
      WindowActions.setActiveFrame(self.props.windowState.getIn(['frames', self.props.windowState.get('frames').size - 1])))

    ipc.on(messages.BLOCKED_RESOURCE, (e, blockType, details) => {
      const filteredFrameProps = this.props.windowState.get('frames').filter(frame => frame.get('location') === details.firstPartyUrl)
      filteredFrameProps.forEach(frameProps =>
        WindowActions.setBlockedBy(frameProps, blockType, details.url))
    })

    ipc.on(messages.SHORTCUT_ACTIVE_FRAME_BACK, this.onBack.bind(this))
    ipc.on(messages.SHORTCUT_ACTIVE_FRAME_FORWARD, this.onForward.bind(this))

    this.loadOpenSearch()

    window.addEventListener('mousemove', (e) => {
      self.checkForTitleMode(e.pageY)
    })
  }

  checkForTitleMode (pageY) {
    const height = document.querySelector('#navigator').getBoundingClientRect().bottom
    if (pageY <= height && this.props.windowState.getIn(['ui', 'mouseInTitlebar']) !== true) {
      WindowActions.setMouseInTitlebar(true)
    } else if (pageY === undefined || pageY > height && this.props.windowState.getIn(['ui', 'mouseInTitlebar']) !== false) {
      WindowActions.setMouseInTitlebar(false)
    }
  }

  get activeFrame () {
    return this.frames[this.props.windowState.get('activeFrameKey')]
  }

  onBack () {
    this.activeFrame.goBack()
  }

  onForward () {
    this.activeFrame.goForward()
  }

  onBraveMenu () {
    // TODO
  }

  onHamburgerMenu () {
    let settings = {}
    Object.keys(AppConfig.resourceNames).forEach((name) => {
      let value = AppConfig.resourceNames[name]
      let enabled = this.props.appState.getIn([value, 'enabled'])
      settings[value] = enabled === undefined ? AppConfig[value].enabled : enabled
    })
    // whether the current page is bookmarked. needed to re-initialize the
    // application menu.
    settings.bookmarked = this.navBar.bookmarked
    contextMenus.onHamburgerMenu(settings)
  }

  onMainFocus () {
    // When the main container is in focus, set the URL bar to inactive.
    WindowActions.setUrlBarActive(false)
  }

  onHideSiteInfo () {
    WindowActions.setSiteInfoVisible(false)
  }

  onHideReleaseNotes () {
    WindowActions.setReleaseNotesVisible(false)
  }

  get enableAds () {
    let enabled = this.props.appState.getIn(['adInsertion', 'enabled'])
    if (enabled === undefined) {
      enabled = AppConfig.adInsertion.enabled
    }
    return enabled
  }

  render () {
    const comparatorByKeyAsc = (a, b) => a.get('key') > b.get('key')
      ? 1 : b.get('key') > a.get('key') ? -1 : 0

    // Sort frames by key so that the order of the frames do not change which could
    // cause unexpected reloading when a user moves tabs.
    // All frame operations work off of frame keys and not index though so unsorted frames
    // can be passed everywhere other than the Frame elements.
    const sortedFrames = this.props.windowState.get('frames').sort(comparatorByKeyAsc)

    const activeFrame = FrameStateUtil.getActiveFrame(this.props.windowState)

    this.frames = {}
    const settingsState = this.props.appState.get('settings') || new Immutable.Map()
    const nonPinnedFrames = this.props.windowState.get('frames').filter(frame => !frame.get('isPinned'))
    return
 this.mainWindow = node}>

        <NavigationBar
          ref={node => this.navBar = node}
          navbar={activeFrame && activeFrame.get('navbar')}
          frames={this.props.windowState.get('frames')}
          sites={this.props.appState.get('sites')}
          activeFrame={activeFrame}
          mouseInTitlebar={this.props.windowState.getIn(['ui', 'mouseInTitlebar'])}
          searchSuggestions={activeFrame && activeFrame.getIn(['navbar', 'urlbar', 'searchSuggestions'])}
          settings={settingsState}
          searchDetail={this.props.windowState.get('searchDetail')}
        />
        { this.props.windowState.getIn(['ui', 'siteInfo', 'isVisible'])
          ? <SiteInfo frameProps={activeFrame}
              siteInfo={this.props.windowState.getIn(['ui', 'siteInfo'])}
              onHide={this.onHideSiteInfo.bind(this)} /> : null
        }
        { this.props.windowState.getIn(['ui', 'releaseNotes', 'isVisible'])
          ? <ReleaseNotes
              metadata={this.props.appState.getIn(['updates', 'metadata'])}
              onHide={this.onHideReleaseNotes.bind(this)} /> : null
        }

          <Button iconClass='braveMenu'
            className='navbutton'
            onClick={this.onBraveMenu.bind(this)} />

        <TabPages frames={nonPinnedFrames}
          tabPageIndex={this.props.windowState.getIn(['ui', 'tabs', 'tabPageIndex'])}
        />
        <TabsToolbar
          paintTabs={getSetting(settingsState, settings.PAINT_TABS)}
          tabs={this.props.windowState.getIn(['ui', 'tabs'])}
          frames={this.props.windowState.get('frames')}
          sites={this.props.appState.get('sites')}
          key='tab-bar'
          activeFrame={activeFrame}
          onMenu={this.onHamburgerMenu.bind(this)}
        />
        <UpdateBar updates={this.props.appState.get('updates')} />

        {
          sortedFrames.map(frame =>
            <Frame
              ref={node => this.frames[frame.get('key')] = node}
              prefOpenInForeground={getSetting(settingsState, settings.SWITCH_TO_NEW_TABS)}
              frames={this.props.windowState.get('frames')}
              frame={frame}
              key={frame.get('key')}
              settings={settingsState || new Immutable.Map()}
              enableAds={this.enableAds}
              isPreview={frame.get('key') === this.props.windowState.get('previewFrameKey')}
              isActive={FrameStateUtil.isFrameKeyActive(this.props.windowState, frame.get('key'))}
            />)
        }

  }
}

module.exports = Main
<|endoftext|>