Disable logging sql when creating tables

--- test/helpers/fixtures/index.js
+++ test/helpers/fixtures/index.js
@@ -5,6 +5,8 @@
     specificFixtures = [specificFixtures];
   }

+  var prevSetting = sequelize.options.logging;
+  sequelize.options.logging = false;
   try {
     yield exports.unload();

@@ -20,8 +22,12 @@
   } catch (e) {
     console.error(e);
   }
+  sequelize.options.logging = prevSetting;
 };

 exports.unload = function *() {
+  var prevSetting = sequelize.options.logging;
+  sequelize.options.logging = false;
   yield sequelize.sync({ force: true });
+  sequelize.options.logging = prevSetting;
 };

<|original_code|>
var fixtures = require('node-require-directory')(__dirname);

exports.load = function *(specificFixtures) {
  if (typeof specificFixtures === 'string') {
    specificFixtures = [specificFixtures];
  }

  try {
    yield exports.unload();

    var keys = Object.keys(fixtures).filter(function(key) {
      if (specificFixtures && specificFixtures.indexOf(key) === -1) {
        return false;
      }
      return true;
    });
    for (var i = 0; i < keys.length; ++i) {
      exports[keys[i]] = yield fixtures[keys[i]].load();
    }
  } catch (e) {
    console.error(e);
  }
};

exports.unload = function *() {
  yield sequelize.sync({ force: true });
};

<|edits_diff|>
--- test/helpers/fixtures/index.js
+++ test/helpers/fixtures/index.js
@@ -5,6 +5,8 @@
     specificFixtures = [specificFixtures];
   }

+  var prevSetting = sequelize.options.logging;
+  sequelize.options.logging = false;
   try {
     yield exports.unload();

@@ -20,8 +22,11 @@
   } catch (e) {
     console.error(e);
   }
+  sequelize.options.logging = prevSetting;
 };

 exports.unload = function *() {
+  var prevSetting = sequelize.options.logging;
+  sequelize.options.logging = false;
   yield sequelize.sync({ force: true });
 };
<|current_version|>
var fixtures = require('node-require-directory')(__dirname);

exports.load = function *(specificFixtures) {
  if (typeof specificFixtures === 'string') {
    specificFixtures = [specificFixtures];
  }

  var prevSetting = sequelize.options.logging;
  sequelize.options.logging = false;
  try {
    yield exports.unload();

    var keys = Object.keys(fixtures).filter(function(key) {
      if (specificFixtures && specificFixtures.indexOf(key) === -1) {
        return false;
      }
      return true;
    });
    for (var i = 0; i < keys.length; ++i) {
      exports[keys[i]] = yield fixtures[keys[i]].load();
    }
  } catch (e) {
    console.error(e);
  }
  sequelize.options.logging = prevSetting;
};

exports.unload = function *() {
  var prevSetting = sequelize.options.logging;
  sequelize.options.logging = false;
  yield sequelize.sync({ force: true });
};

<|next_version|>
var fixtures = require('node-require-directory')(__dirname);

exports.load = function *(specificFixtures) {
  if (typeof specificFixtures === 'string') {
    specificFixtures = [specificFixtures];
  }

  var prevSetting = sequelize.options.logging;
  sequelize.options.logging = false;
  try {
    yield exports.unload();

    var keys = Object.keys(fixtures).filter(function(key) {
      if (specificFixtures && specificFixtures.indexOf(key) === -1) {
        return false;
      }
      return true;
    });
    for (var i = 0; i < keys.length; ++i) {
      exports[keys[i]] = yield fixtures[keys[i]].load();
    }
  } catch (e) {
    console.error(e);
  }
  sequelize.options.logging = prevSetting;
};

exports.unload = function *() {
  var prevSetting = sequelize.options.logging;
  sequelize.options.logging = false;
  yield sequelize.sync({ force: true });
  sequelize.options.logging = prevSetting;
};


Add onClick event to space placeLabel

Add onClick event to space placeLabel

--- components/Cards/SpaceListingCard/SpaceListingCard.js
+++ components/Cards/SpaceListingCard/SpaceListingCard.js
@@ -11,6 +11,7 @@
     placeHref,
     location,
     size,
+    onPlaceLabelClick,
     ...rest,
   } = props;

@@ -18,6 +19,7 @@
     <DestinationListingCard
       carouselOverlay={ placeLabel && placeHref && (
         <Link
+          onPlaceLabelClick={ onPlaceLabelClick }
           href={ placeHref }
           className={ css.placeLink }
           iconClassName={ css.placeLinkIcon }
@@ -38,6 +40,7 @@
   size: PropTypes.node,
   price: PropTypes.node,
   priceUnit: PropTypes.node,
+  onPlaceLabelClick: PropTypes.func,
 };

 export default SpaceListingCard;

<|original_code|>
import React, { PropTypes } from 'react';

import DestinationListingCard from '../DestinationListingCard/DestinationListingCard';
import Link from '../../Link/Link';

import css from './SpaceListingCard.css';

const SpaceListingCard = (props) => {
  const {
    placeLabel,
    placeHref,
    location,
    size,
    ...rest,
  } = props;

  return (
    <DestinationListingCard
      carouselOverlay={ placeLabel && placeHref && (
        <Link
          href={ placeHref }
          className={ css.placeLink }
          iconClassName={ css.placeLinkIcon }
        >
          { placeLabel }
        </Link>
      ) }
      information={ [location, size] }
      { ...rest }
    />
  );
};

SpaceListingCard.propTypes = {
  placeLabel: PropTypes.node,
  placeHref: PropTypes.string,
  location: PropTypes.node,
  size: PropTypes.node,
  price: PropTypes.node,
  priceUnit: PropTypes.node,
};

export default SpaceListingCard;
<|edits_diff|>
--- components/Cards/SpaceListingCard/SpaceListingCard.js
+++ components/Cards/SpaceListingCard/SpaceListingCard.js
@@ -11,6 +11,7 @@
     placeHref,
     location,
     size,
+    onPlaceLabelClick,
     ...rest,
   } = props;

@@ -18,6 +19,7 @@
     <DestinationListingCard
       carouselOverlay={ placeLabel && placeHref && (
         <Link
+          onPlaceLabelClick={ onPlaceLabelClick }
           href={ placeHref }
           className={ css.placeLink }
           iconClassName={ css.placeLinkIcon }
<|current_version|>
import React, { PropTypes } from 'react';

import DestinationListingCard from '../DestinationListingCard/DestinationListingCard';
import Link from '../../Link/Link';

import css from './SpaceListingCard.css';

const SpaceListingCard = (props) => {
  const {
    placeLabel,
    placeHref,
    location,
    size,
    onPlaceLabelClick,
    ...rest,
  } = props;

  return (
    <DestinationListingCard
      carouselOverlay={ placeLabel && placeHref && (
        <Link
          onPlaceLabelClick={ onPlaceLabelClick }
          href={ placeHref }
          className={ css.placeLink }
          iconClassName={ css.placeLinkIcon }
        >
          { placeLabel }
        </Link>
      ) }
      information={ [location, size] }
      { ...rest }
    />
  );
};

SpaceListingCard.propTypes = {
  placeLabel: PropTypes.node,
  placeHref: PropTypes.string,
  location: PropTypes.node,
  size: PropTypes.node,
  price: PropTypes.node,
  priceUnit: PropTypes.node,
};

export default SpaceListingCard;
<|next_version|>
import React, { PropTypes } from 'react';

import DestinationListingCard from '../DestinationListingCard/DestinationListingCard';
import Link from '../../Link/Link';

import css from './SpaceListingCard.css';

const SpaceListingCard = (props) => {
  const {
    placeLabel,
    placeHref,
    location,
    size,
    onPlaceLabelClick,
    ...rest,
  } = props;

  return (
    <DestinationListingCard
      carouselOverlay={ placeLabel && placeHref && (
        <Link
          onPlaceLabelClick={ onPlaceLabelClick }
          href={ placeHref }
          className={ css.placeLink }
          iconClassName={ css.placeLinkIcon }
        >
          { placeLabel }
        </Link>
      ) }
      information={ [location, size] }
      { ...rest }
    />
  );
};

SpaceListingCard.propTypes = {
  placeLabel: PropTypes.node,
  placeHref: PropTypes.string,
  location: PropTypes.node,
  size: PropTypes.node,
  price: PropTypes.node,
  priceUnit: PropTypes.node,
  onPlaceLabelClick: PropTypes.func,
};

export default SpaceListingCard;


Add system date for reference to other component

--- ui/src/main/webapp/launcher.js
+++ ui/src/main/webapp/launcher.js
@@ -25,8 +25,10 @@
             success: function(result, request) {
                 var text = Ext.JSON.decode(result.responseText);
                 Ext.getCmp('idUser').setValue(text.id);
+                Ext.getCmp('systemDate').setValue(text.currentDate);
                 Ext.getCmp('bottomPanelUsername').setText(text.userName);
                 Ext.getCmp('bottomPanelSystemDate').setText(text.currentDate);
+
             }
         });
     }

<|original_code|>
Ext.application({
    name: 'logbook',
    appFolder: 'app',

    controllers: [
        'main.DashboardController',
        'entri.EntriLogBookController',
        'utility.EmailTemplateController',
        'utility.UserProfileController'
    ],

    launch: function() {
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: [{
                xtype: 'dashboardPanel'
            }]
        });
        this.call_ajax();
    },
    call_ajax: function() {
        Ext.Ajax.request({
            url: '/logbook/ui/json/utility/userprofile/current-username',
            method: 'GET',
            success: function(result, request) {
                var text = Ext.JSON.decode(result.responseText);
                Ext.getCmp('idUser').setValue(text.id);
                Ext.getCmp('bottomPanelUsername').setText(text.userName);
                Ext.getCmp('bottomPanelSystemDate').setText(text.currentDate);
            }
        });
    }
});

<|edits_diff|>
--- ui/src/main/webapp/launcher.js
+++ ui/src/main/webapp/launcher.js
@@ -25,6 +25,7 @@
             success: function(result, request) {
                 var text = Ext.JSON.decode(result.responseText);
                 Ext.getCmp('idUser').setValue(text.id);
+                Ext.getCmp('systemDate').setValue(text.currentDate);
                 Ext.getCmp('bottomPanelUsername').setText(text.userName);
                 Ext.getCmp('bottomPanelSystemDate').setText(text.currentDate);
             }
<|current_version|>
Ext.application({
    name: 'logbook',
    appFolder: 'app',

    controllers: [
        'main.DashboardController',
        'entri.EntriLogBookController',
        'utility.EmailTemplateController',
        'utility.UserProfileController'
    ],

    launch: function() {
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: [{
                xtype: 'dashboardPanel'
            }]
        });
        this.call_ajax();
    },
    call_ajax: function() {
        Ext.Ajax.request({
            url: '/logbook/ui/json/utility/userprofile/current-username',
            method: 'GET',
            success: function(result, request) {
                var text = Ext.JSON.decode(result.responseText);
                Ext.getCmp('idUser').setValue(text.id);
                Ext.getCmp('systemDate').setValue(text.currentDate);
                Ext.getCmp('bottomPanelUsername').setText(text.userName);
                Ext.getCmp('bottomPanelSystemDate').setText(text.currentDate);
            }
        });
    }
});

<|next_version|>
Ext.application({
    name: 'logbook',
    appFolder: 'app',

    controllers: [
        'main.DashboardController',
        'entri.EntriLogBookController',
        'utility.EmailTemplateController',
        'utility.UserProfileController'
    ],

    launch: function() {
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: [{
                xtype: 'dashboardPanel'
            }]
        });
        this.call_ajax();
    },
    call_ajax: function() {
        Ext.Ajax.request({
            url: '/logbook/ui/json/utility/userprofile/current-username',
            method: 'GET',
            success: function(result, request) {
                var text = Ext.JSON.decode(result.responseText);
                Ext.getCmp('idUser').setValue(text.id);
                Ext.getCmp('systemDate').setValue(text.currentDate);
                Ext.getCmp('bottomPanelUsername').setText(text.userName);
                Ext.getCmp('bottomPanelSystemDate').setText(text.currentDate);

            }
        });
    }
});


Add addMasterListItems to customerInvoice reducer

--- src/pages/dataTableUtilities/reducer/getReducer.js
+++ src/pages/dataTableUtilities/reducer/getReducer.js
@@ -27,6 +27,7 @@
   sortData,
   openBasicModal,
   closeBasicModal,
+  addMasterListItems,
 } from './reducerMethods';

 /**
@@ -47,6 +48,7 @@
   deselectAll,
   openBasicModal,
   closeBasicModal,
+  addMasterListItems,
 };

 const PAGE_REDUCERS = {

<|original_code|>
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  editTotalQuantity,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editTotalQuantity,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
};

const PAGE_REDUCERS = {
  customerInvoice,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;

<|edits_diff|>
--- src/pages/dataTableUtilities/reducer/getReducer.js
+++ src/pages/dataTableUtilities/reducer/getReducer.js
@@ -27,6 +27,7 @@
   sortData,
   openBasicModal,
   closeBasicModal,
+  addMasterListItems,
 } from './reducerMethods';

 /**
<|current_version|>
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  editTotalQuantity,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editTotalQuantity,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
};

const PAGE_REDUCERS = {
  customerInvoice,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;

<|next_version|>
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  editTotalQuantity,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editTotalQuantity,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
};

const PAGE_REDUCERS = {
  customerInvoice,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;


Add window size and devicePixelRatio to platform sample output

Enyo-DCO-1.1-Signed-Off-By: Ben Combee (ben.combee@palm.com)

--- samples/PlatformSample.js
+++ samples/PlatformSample.js
@@ -10,6 +10,11 @@
 		]},
 		{tag: "br"},
 		{kind: "onyx.Groupbox", components: [
+			{kind: "onyx.GroupboxHeader", content: "Window"},
+			{name: "windowAttr", content: "", style: "padding: 8px;"}
+		]},
+		{tag: "br"},
+		{kind: "onyx.Groupbox", components: [
 			{kind: "onyx.GroupboxHeader", content: "enyo.platform"},
 			{name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
 		]}
@@ -17,6 +22,8 @@
 	create: function() {
 		this.inherited(arguments);
 		this.$.uaString.setContent(navigator.userAgent);
+		this.$.windowAttr.setContent("size: " + window.innerWidth + "x" + window.innerHeight +
+			", devicePixelRatio: " + window.devicePixelRatio);
 		this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform));
 	}
 });

<|original_code|>
enyo.kind({
	name: "enyo.sample.PlatformSample",
	kind: "FittableRows",
	classes: "enyo-fit platform-sample",
	components: [
		{classes: "platform-sample-divider", content: "Enyo Platform Detection"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "User-Agent String"},
			{name: "uaString", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "enyo.platform"},
			{name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
		]}
	],
	create: function() {
		this.inherited(arguments);
		this.$.uaString.setContent(navigator.userAgent);
		this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform));
	}
});
<|edits_diff|>
--- samples/PlatformSample.js
+++ samples/PlatformSample.js
@@ -7,6 +7,11 @@
 		{kind: "onyx.Groupbox", components: [
 			{kind: "onyx.GroupboxHeader", content: "User-Agent String"},
 			{name: "uaString", content: "", style: "padding: 8px;"}
+		]},
+		{tag: "br"},
+		{kind: "onyx.Groupbox", components: [
+			{kind: "onyx.GroupboxHeader", content: "Window"},
+			{name: "windowAttr", content: "", style: "padding: 8px;"}
 		]},
 		{tag: "br"},
 		{kind: "onyx.Groupbox", components: [
<|current_version|>
enyo.kind({
	name: "enyo.sample.PlatformSample",
	kind: "FittableRows",
	classes: "enyo-fit platform-sample",
	components: [
		{classes: "platform-sample-divider", content: "Enyo Platform Detection"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "User-Agent String"},
			{name: "uaString", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "Window"},
			{name: "windowAttr", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "enyo.platform"},
			{name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
		]}
	],
	create: function() {
		this.inherited(arguments);
		this.$.uaString.setContent(navigator.userAgent);
		this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform));
	}
});
<|next_version|>
enyo.kind({
	name: "enyo.sample.PlatformSample",
	kind: "FittableRows",
	classes: "enyo-fit platform-sample",
	components: [
		{classes: "platform-sample-divider", content: "Enyo Platform Detection"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "User-Agent String"},
			{name: "uaString", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "Window"},
			{name: "windowAttr", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "enyo.platform"},
			{name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
		]}
	],
	create: function() {
		this.inherited(arguments);
		this.$.uaString.setContent(navigator.userAgent);
		this.$.windowAttr.setContent("size: " + window.innerWidth + "x" + window.innerHeight +
			", devicePixelRatio: " + window.devicePixelRatio);
		this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform));
	}
});


Disable context menu entry if not on imagewq

--- content/imageforward.js
+++ content/imageforward.js
@@ -6,10 +6,15 @@
         }
         window.removeEventListener('load', gImageForward.onLoad, false);
         window.addEventListener('unload', gImageForward.onUnload, false);
+        document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", gImageForward.onPopupShowing, false);
     },

     onUnload: function() {
         window.removeEventListener('unload', gImageForward.onUnload, false);
+    },
+
+    onPopupShowing: function(anEvent) {
+        document.getElementById("imageForwardContextMenuItem").disabled = !gContextMenu.onImage;
     },

     onClick: function() {

<|original_code|>
var gImageForward = {

    onLoad: function() {
        if ('undefined' == typeof gBrowser) {
            return;
        }
        window.removeEventListener('load', gImageForward.onLoad, false);
        window.addEventListener('unload', gImageForward.onUnload, false);
    },

    onUnload: function() {
        window.removeEventListener('unload', gImageForward.onUnload, false);
    },

    onClick: function() {
    }

};

window.addEventListener('load', gImageForward.onLoad, false);

<|edits_diff|>
--- content/imageforward.js
+++ content/imageforward.js
@@ -6,6 +6,7 @@
         }
         window.removeEventListener('load', gImageForward.onLoad, false);
         window.addEventListener('unload', gImageForward.onUnload, false);
+        document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", gImageForward.onPopupShowing, false);
     },

     onUnload: function() {
<|current_version|>
var gImageForward = {

    onLoad: function() {
        if ('undefined' == typeof gBrowser) {
            return;
        }
        window.removeEventListener('load', gImageForward.onLoad, false);
        window.addEventListener('unload', gImageForward.onUnload, false);
        document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", gImageForward.onPopupShowing, false);
    },

    onUnload: function() {
        window.removeEventListener('unload', gImageForward.onUnload, false);
    },

    onClick: function() {
    }

};

window.addEventListener('load', gImageForward.onLoad, false);

<|next_version|>
var gImageForward = {

    onLoad: function() {
        if ('undefined' == typeof gBrowser) {
            return;
        }
        window.removeEventListener('load', gImageForward.onLoad, false);
        window.addEventListener('unload', gImageForward.onUnload, false);
        document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", gImageForward.onPopupShowing, false);
    },

    onUnload: function() {
        window.removeEventListener('unload', gImageForward.onUnload, false);
    },

    onPopupShowing: function(anEvent) {
        document.getElementById("imageForwardContextMenuItem").disabled = !gContextMenu.onImage;
    },

    onClick: function() {
    }

};

window.addEventListener('load', gImageForward.onLoad, false);


Add Completed Event to Piece Bank

Add Completed Event to Piece Bank

--- lib/piece-bank.js
+++ lib/piece-bank.js
@@ -1,3 +1,4 @@
+var events = require('events')
 var banks = {};

 module.exports = function(infoHash) {
@@ -8,6 +9,7 @@
 		banks[engine.infoHash] = {
 			downloaded: 0,
 			total: engine.torrent.pieces.length,
+			ev: new events.EventEmitter(),
 			pieceLength: engine.torrent.pieceLength,
 			map: Array.apply(null, Array(engine.torrent.pieces.length)).map(function () { return false })
 		};
@@ -20,6 +22,8 @@
 	newObj.update = function(piece) {
 		banks[infoHash].downloaded++;
 		banks[infoHash].map[piece] = true;
+		if (banks[infoHash].downloaded == banks[infoHash].total)
+			banks[infoHash].ev.emit('completed')
 	};

 	newObj.filePercent = function(offset, length) {

<|original_code|>
var banks = {};

module.exports = function(infoHash) {

	var newObj = {};

	newObj.create = function(engine) {
		banks[engine.infoHash] = {
			downloaded: 0,
			total: engine.torrent.pieces.length,
			pieceLength: engine.torrent.pieceLength,
			map: Array.apply(null, Array(engine.torrent.pieces.length)).map(function () { return false })
		};
	};

	newObj.clear = function() {
		delete banks[infoHash];
	};

	newObj.update = function(piece) {
		banks[infoHash].downloaded++;
		banks[infoHash].map[piece] = true;
	};

	newObj.filePercent = function(offset, length) {
		var distance = Math.ceil(length / banks[infoHash].pieceLength);
		offset = Math.floor(offset / banks[infoHash].pieceLength) -1;
		var downloaded = 0;
		for (var i = offset; i <= offset + distance && i < banks[infoHash].total; i++) {
			if (banks[infoHash].map[i])
				downloaded++;
		}
		return downloaded / distance;
	};

	newObj.get = function() {
		return banks[infoHash];
	};

	return newObj;
};

<|edits_diff|>
--- lib/piece-bank.js
+++ lib/piece-bank.js
@@ -1,3 +1,4 @@
+var events = require('events')
 var banks = {};

 module.exports = function(infoHash) {
@@ -8,6 +9,7 @@
 		banks[engine.infoHash] = {
 			downloaded: 0,
 			total: engine.torrent.pieces.length,
+			ev: new events.EventEmitter(),
 			pieceLength: engine.torrent.pieceLength,
 			map: Array.apply(null, Array(engine.torrent.pieces.length)).map(function () { return false })
 		};
<|current_version|>
var events = require('events')
var banks = {};

module.exports = function(infoHash) {

	var newObj = {};

	newObj.create = function(engine) {
		banks[engine.infoHash] = {
			downloaded: 0,
			total: engine.torrent.pieces.length,
			ev: new events.EventEmitter(),
			pieceLength: engine.torrent.pieceLength,
			map: Array.apply(null, Array(engine.torrent.pieces.length)).map(function () { return false })
		};
	};

	newObj.clear = function() {
		delete banks[infoHash];
	};

	newObj.update = function(piece) {
		banks[infoHash].downloaded++;
		banks[infoHash].map[piece] = true;
	};

	newObj.filePercent = function(offset, length) {
		var distance = Math.ceil(length / banks[infoHash].pieceLength);
		offset = Math.floor(offset / banks[infoHash].pieceLength) -1;
		var downloaded = 0;
		for (var i = offset; i <= offset + distance && i < banks[infoHash].total; i++) {
			if (banks[infoHash].map[i])
				downloaded++;
		}
		return downloaded / distance;
	};

	newObj.get = function() {
		return banks[infoHash];
	};

	return newObj;
};

<|next_version|>
var events = require('events')
var banks = {};

module.exports = function(infoHash) {

	var newObj = {};

	newObj.create = function(engine) {
		banks[engine.infoHash] = {
			downloaded: 0,
			total: engine.torrent.pieces.length,
			ev: new events.EventEmitter(),
			pieceLength: engine.torrent.pieceLength,
			map: Array.apply(null, Array(engine.torrent.pieces.length)).map(function () { return false })
		};
	};

	newObj.clear = function() {
		delete banks[infoHash];
	};

	newObj.update = function(piece) {
		banks[infoHash].downloaded++;
		banks[infoHash].map[piece] = true;
		if (banks[infoHash].downloaded == banks[infoHash].total)
			banks[infoHash].ev.emit('completed')
	};

	newObj.filePercent = function(offset, length) {
		var distance = Math.ceil(length / banks[infoHash].pieceLength);
		offset = Math.floor(offset / banks[infoHash].pieceLength) -1;
		var downloaded = 0;
		for (var i = offset; i <= offset + distance && i < banks[infoHash].total; i++) {
			if (banks[infoHash].map[i])
				downloaded++;
		}
		return downloaded / distance;
	};

	newObj.get = function() {
		return banks[infoHash];
	};

	return newObj;
};


Add jsdoc to two stack queue

Add jsdoc to two stack queue

--- src/two-stack-queue/index.js
+++ src/two-stack-queue/index.js
@@ -7,6 +7,7 @@
 'use strict';

 /**
+ * Creates a queue implemented with two stacks.
  * @constructor
  */
 function TwoStackQueue() {
@@ -14,10 +15,18 @@
   this.outbox = [];
 }

+/**
+ * Push a value to the queue.
+ * @param {Object} value The value to push.
+ */
 TwoStackQueue.prototype.push = function (value) {
   this.inbox.push(value);
 };

+/**
+ * Pops a value from the queue and returns it.
+ * @return {Object} The popped value.
+ */
 TwoStackQueue.prototype.pop = function () {
   if (!this.outbox.length) {
     if (!this.inbox.length) {

<|original_code|>
/**
 * @license
 * js-interview-questions <http://github.com/Tyriar/js-interview-questions>
 * Copyright 2015 Daniel Imms <http://www.growingwiththeweb.com>
 * Released under the MIT license <http://github.com/Tyriar/js-interview-questions/blob/master/LICENSE>
 */
'use strict';

/**
 * @constructor
 */
function TwoStackQueue() {
  this.inbox = [];
  this.outbox = [];
}

TwoStackQueue.prototype.push = function (value) {
  this.inbox.push(value);
};

TwoStackQueue.prototype.pop = function () {
  if (!this.outbox.length) {
    if (!this.inbox.length) {
      return undefined;
    }
    while (this.inbox.length) {
      this.outbox.push(this.inbox.pop());
    }
  }
  return this.outbox.pop();
};

module.exports = TwoStackQueue;

<|edits_diff|>
--- src/two-stack-queue/index.js
+++ src/two-stack-queue/index.js
@@ -7,6 +7,7 @@
 'use strict';

 /**
+ * Creates a queue implemented with two stacks.
  * @constructor
  */
 function TwoStackQueue() {
@@ -14,6 +15,10 @@
   this.outbox = [];
 }

+/**
+ * Push a value to the queue.
+ * @param {Object} value The value to push.
+ */
 TwoStackQueue.prototype.push = function (value) {
   this.inbox.push(value);
 };
<|current_version|>
/**
 * @license
 * js-interview-questions <http://github.com/Tyriar/js-interview-questions>
 * Copyright 2015 Daniel Imms <http://www.growingwiththeweb.com>
 * Released under the MIT license <http://github.com/Tyriar/js-interview-questions/blob/master/LICENSE>
 */
'use strict';

/**
 * Creates a queue implemented with two stacks.
 * @constructor
 */
function TwoStackQueue() {
  this.inbox = [];
  this.outbox = [];
}

/**
 * Push a value to the queue.
 * @param {Object} value The value to push.
 */
TwoStackQueue.prototype.push = function (value) {
  this.inbox.push(value);
};

TwoStackQueue.prototype.pop = function () {
  if (!this.outbox.length) {
    if (!this.inbox.length) {
      return undefined;
    }
    while (this.inbox.length) {
      this.outbox.push(this.inbox.pop());
    }
  }
  return this.outbox.pop();
};

module.exports = TwoStackQueue;

<|next_version|>
/**
 * @license
 * js-interview-questions <http://github.com/Tyriar/js-interview-questions>
 * Copyright 2015 Daniel Imms <http://www.growingwiththeweb.com>
 * Released under the MIT license <http://github.com/Tyriar/js-interview-questions/blob/master/LICENSE>
 */
'use strict';

/**
 * Creates a queue implemented with two stacks.
 * @constructor
 */
function TwoStackQueue() {
  this.inbox = [];
  this.outbox = [];
}

/**
 * Push a value to the queue.
 * @param {Object} value The value to push.
 */
TwoStackQueue.prototype.push = function (value) {
  this.inbox.push(value);
};

/**
 * Pops a value from the queue and returns it.
 * @return {Object} The popped value.
 */
TwoStackQueue.prototype.pop = function () {
  if (!this.outbox.length) {
    if (!this.inbox.length) {
      return undefined;
    }
    while (this.inbox.length) {
      this.outbox.push(this.inbox.pop());
    }
  }
  return this.outbox.pop();
};

module.exports = TwoStackQueue;


Add previous fix for iPhone

Add previous fix for iPhone

--- conferenceX/static/js/index.js
+++ conferenceX/static/js/index.js
@@ -37,10 +37,12 @@

     /* Fix scrolling when modals are opened */
     $.featherlight.defaults.afterOpen = function(event) {
+        $("body").css("position", "relative");
         $("body").css("overflow", "hidden");
     };

     $.featherlight.defaults.afterClose = function(event) {
+        $("body").css("position", "static");
         $("body").css("overflow", "scroll");
     };
 });

<|original_code|>
$(document).ready(function(){
    $('.parallax').parallax();

    /* Adjust scrollto to compensate for the navbar */
    $('.scrollto').click(function(){
        var link = $(this).attr("href");
        $('html, body').animate({
            scrollTop: $(link).offset().top - $('#navbar').height()
        }, 200);
    });

    /* Move hamburger sideNav to right */
    $(".button-collapse").sideNav({
        edge: 'right', // Choose the horizontal origin
    });

    /* B&W effects */
    $(".featured-image").hover(
        function(){
            $(this).css("-webkit-filter", "grayscale(0%)");
            $(this).css("filter", "grayscale(0%)");
        },
        function(){
            $(this).css("-webkit-filter", "grayscale(100%)");
            $(this).css("filter", "grayscale(100%)");
        }
    );

    /* Prevent accidental google maps scrolling */
    $("#google-maps").click(function() {
        $("#google-maps iframe").css("pointer-events", "auto");
    });

    $("#google-maps").mouseleave(function() {
        $("#google-maps iframe").css("pointer-events", "none");
    });

    /* Fix scrolling when modals are opened */
    $.featherlight.defaults.afterOpen = function(event) {
        $("body").css("overflow", "hidden");
    };

    $.featherlight.defaults.afterClose = function(event) {
        $("body").css("overflow", "scroll");
    };
});

<|edits_diff|>
--- conferenceX/static/js/index.js
+++ conferenceX/static/js/index.js
@@ -37,6 +37,7 @@

     /* Fix scrolling when modals are opened */
     $.featherlight.defaults.afterOpen = function(event) {
+        $("body").css("position", "relative");
         $("body").css("overflow", "hidden");
     };

<|current_version|>
$(document).ready(function(){
    $('.parallax').parallax();

    /* Adjust scrollto to compensate for the navbar */
    $('.scrollto').click(function(){
        var link = $(this).attr("href");
        $('html, body').animate({
            scrollTop: $(link).offset().top - $('#navbar').height()
        }, 200);
    });

    /* Move hamburger sideNav to right */
    $(".button-collapse").sideNav({
        edge: 'right', // Choose the horizontal origin
    });

    /* B&W effects */
    $(".featured-image").hover(
        function(){
            $(this).css("-webkit-filter", "grayscale(0%)");
            $(this).css("filter", "grayscale(0%)");
        },
        function(){
            $(this).css("-webkit-filter", "grayscale(100%)");
            $(this).css("filter", "grayscale(100%)");
        }
    );

    /* Prevent accidental google maps scrolling */
    $("#google-maps").click(function() {
        $("#google-maps iframe").css("pointer-events", "auto");
    });

    $("#google-maps").mouseleave(function() {
        $("#google-maps iframe").css("pointer-events", "none");
    });

    /* Fix scrolling when modals are opened */
    $.featherlight.defaults.afterOpen = function(event) {
        $("body").css("position", "relative");
        $("body").css("overflow", "hidden");
    };

    $.featherlight.defaults.afterClose = function(event) {
        $("body").css("overflow", "scroll");
    };
});

<|next_version|>
$(document).ready(function(){
    $('.parallax').parallax();

    /* Adjust scrollto to compensate for the navbar */
    $('.scrollto').click(function(){
        var link = $(this).attr("href");
        $('html, body').animate({
            scrollTop: $(link).offset().top - $('#navbar').height()
        }, 200);
    });

    /* Move hamburger sideNav to right */
    $(".button-collapse").sideNav({
        edge: 'right', // Choose the horizontal origin
    });

    /* B&W effects */
    $(".featured-image").hover(
        function(){
            $(this).css("-webkit-filter", "grayscale(0%)");
            $(this).css("filter", "grayscale(0%)");
        },
        function(){
            $(this).css("-webkit-filter", "grayscale(100%)");
            $(this).css("filter", "grayscale(100%)");
        }
    );

    /* Prevent accidental google maps scrolling */
    $("#google-maps").click(function() {
        $("#google-maps iframe").css("pointer-events", "auto");
    });

    $("#google-maps").mouseleave(function() {
        $("#google-maps iframe").css("pointer-events", "none");
    });

    /* Fix scrolling when modals are opened */
    $.featherlight.defaults.afterOpen = function(event) {
        $("body").css("position", "relative");
        $("body").css("overflow", "hidden");
    };

    $.featherlight.defaults.afterClose = function(event) {
        $("body").css("position", "static");
        $("body").css("overflow", "scroll");
    };
});


[Glitch] Fix not showing custom emojis in share page emoji picker

Port e02a13f64e5c2c93fa73a67a4ce32a7d1df24760 to glitch-soc

--- app/javascript/flavours/glitch/containers/compose_container.js
+++ app/javascript/flavours/glitch/containers/compose_container.js
@@ -7,6 +7,7 @@
 import { getLocale } from 'mastodon/locales';
 import Compose from 'flavours/glitch/features/standalone/compose';
 import initialState from 'flavours/glitch/util/initial_state';
+import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';

 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
@@ -16,6 +17,8 @@
 if (initialState) {
   store.dispatch(hydrateStore(initialState));
 }
+
+store.dispatch(fetchCustomEmojis());

 export default class TimelineContainer extends React.PureComponent {

<|original_code|>
import React from 'react';
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
import configureStore from 'flavours/glitch/store/configureStore';
import { hydrateStore } from 'flavours/glitch/actions/store';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from 'mastodon/locales';
import Compose from 'flavours/glitch/features/standalone/compose';
import initialState from 'flavours/glitch/util/initial_state';

const { localeData, messages } = getLocale();
addLocaleData(localeData);

const store = configureStore();

if (initialState) {
  store.dispatch(hydrateStore(initialState));
}

export default class TimelineContainer extends React.PureComponent {

  static propTypes = {
    locale: PropTypes.string.isRequired,
  };

  render () {
    const { locale } = this.props;

    return (
      <IntlProvider locale={locale} messages={messages}>
        <Provider store={store}>
          <Compose />
        </Provider>
      </IntlProvider>
    );
  }

}

<|edits_diff|>
--- app/javascript/flavours/glitch/containers/compose_container.js
+++ app/javascript/flavours/glitch/containers/compose_container.js
@@ -7,6 +7,7 @@
 import { getLocale } from 'mastodon/locales';
 import Compose from 'flavours/glitch/features/standalone/compose';
 import initialState from 'flavours/glitch/util/initial_state';
+import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';

 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
<|current_version|>
import React from 'react';
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
import configureStore from 'flavours/glitch/store/configureStore';
import { hydrateStore } from 'flavours/glitch/actions/store';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from 'mastodon/locales';
import Compose from 'flavours/glitch/features/standalone/compose';
import initialState from 'flavours/glitch/util/initial_state';
import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';

const { localeData, messages } = getLocale();
addLocaleData(localeData);

const store = configureStore();

if (initialState) {
  store.dispatch(hydrateStore(initialState));
}

export default class TimelineContainer extends React.PureComponent {

  static propTypes = {
    locale: PropTypes.string.isRequired,
  };

  render () {
    const { locale } = this.props;

    return (
      <IntlProvider locale={locale} messages={messages}>
        <Provider store={store}>
          <Compose />
        </Provider>
      </IntlProvider>
    );
  }

}

<|next_version|>
import React from 'react';
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
import configureStore from 'flavours/glitch/store/configureStore';
import { hydrateStore } from 'flavours/glitch/actions/store';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from 'mastodon/locales';
import Compose from 'flavours/glitch/features/standalone/compose';
import initialState from 'flavours/glitch/util/initial_state';
import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';

const { localeData, messages } = getLocale();
addLocaleData(localeData);

const store = configureStore();

if (initialState) {
  store.dispatch(hydrateStore(initialState));
}

store.dispatch(fetchCustomEmojis());

export default class TimelineContainer extends React.PureComponent {

  static propTypes = {
    locale: PropTypes.string.isRequired,
  };

  render () {
    const { locale } = this.props;

    return (
      <IntlProvider locale={locale} messages={messages}>
        <Provider store={store}>
          <Compose />
        </Provider>
      </IntlProvider>
    );
  }

}


Remove unneeded moment locales from bundle

--- config/webpack.common.js
+++ config/webpack.common.js
@@ -2,6 +2,7 @@

 var autoprefixer = require('autoprefixer');
 var path = require('path');
+var webpack = require('webpack');

 module.exports = {
   module: {
@@ -35,4 +36,7 @@
     extensions: ['', '.js', '.json'],
     modulesDirectories: ['node_modules', 'app'],
   },
+  plugins: [
+    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|fi|sv/),
+  ],
 };

<|original_code|>
/* eslint-disable no-var */

var autoprefixer = require('autoprefixer');
var path = require('path');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
      },
      {
        test: /\.gif$/,
        loader: 'url?limit=100000&mimetype=image/gif',
      },
      {
        test: /\.jpg$/,
        loader: 'file',
      },
      {
        test: /\.woff|\.woff2|\.svg|.eot|\.ttf/,
        loader: 'url?prefix=font/&limit=10000',
      },
    ],
  },
  postcss: [
    autoprefixer({ browsers: ['last 2 version', 'ie 9'] }),
  ],
  resolve: {
    alias: {
      app: path.resolve(__dirname, '../app'),
      tests: path.resolve(__dirname, '../tests'),
    },
    extensions: ['', '.js', '.json'],
    modulesDirectories: ['node_modules', 'app'],
  },
};

<|edits_diff|>
--- config/webpack.common.js
+++ config/webpack.common.js
@@ -2,6 +2,7 @@

 var autoprefixer = require('autoprefixer');
 var path = require('path');
+var webpack = require('webpack');

 module.exports = {
   module: {
<|current_version|>
/* eslint-disable no-var */

var autoprefixer = require('autoprefixer');
var path = require('path');
var webpack = require('webpack');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
      },
      {
        test: /\.gif$/,
        loader: 'url?limit=100000&mimetype=image/gif',
      },
      {
        test: /\.jpg$/,
        loader: 'file',
      },
      {
        test: /\.woff|\.woff2|\.svg|.eot|\.ttf/,
        loader: 'url?prefix=font/&limit=10000',
      },
    ],
  },
  postcss: [
    autoprefixer({ browsers: ['last 2 version', 'ie 9'] }),
  ],
  resolve: {
    alias: {
      app: path.resolve(__dirname, '../app'),
      tests: path.resolve(__dirname, '../tests'),
    },
    extensions: ['', '.js', '.json'],
    modulesDirectories: ['node_modules', 'app'],
  },
};

<|next_version|>
/* eslint-disable no-var */

var autoprefixer = require('autoprefixer');
var path = require('path');
var webpack = require('webpack');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
      },
      {
        test: /\.gif$/,
        loader: 'url?limit=100000&mimetype=image/gif',
      },
      {
        test: /\.jpg$/,
        loader: 'file',
      },
      {
        test: /\.woff|\.woff2|\.svg|.eot|\.ttf/,
        loader: 'url?prefix=font/&limit=10000',
      },
    ],
  },
  postcss: [
    autoprefixer({ browsers: ['last 2 version', 'ie 9'] }),
  ],
  resolve: {
    alias: {
      app: path.resolve(__dirname, '../app'),
      tests: path.resolve(__dirname, '../tests'),
    },
    extensions: ['', '.js', '.json'],
    modulesDirectories: ['node_modules', 'app'],
  },
  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|fi|sv/),
  ],
};


Add timeout since webpack wont reload on computer without it

--- build/webpack-dev-server.js
+++ build/webpack-dev-server.js
@@ -9,8 +9,13 @@
   contentBase: paths.project(config.get('dir_src')),
   hot: true,
   quiet: false,
+  watchOptions: {
+    aggregateTimeout: 300,
+    poll: 1000
+  },
   noInfo: false,
   lazy: false,
+
   stats: {
     colors: true
   },

<|original_code|>
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import config from '../config';
import webpackConfig from './webpack/development_hot';

const paths = config.get('utils_paths');

const devServer = new WebpackDevServer(webpack(webpackConfig), {
  contentBase: paths.project(config.get('dir_src')),
  hot: true,
  quiet: false,
  noInfo: false,
  lazy: false,
  stats: {
    colors: true
  },
  historyApiFallback: true
});

export default devServer;

<|edits_diff|>
--- build/webpack-dev-server.js
+++ build/webpack-dev-server.js
@@ -9,6 +9,10 @@
   contentBase: paths.project(config.get('dir_src')),
   hot: true,
   quiet: false,
+  watchOptions: {
+    aggregateTimeout: 300,
+    poll: 1000
+  },
   noInfo: false,
   lazy: false,
   stats: {
<|current_version|>
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import config from '../config';
import webpackConfig from './webpack/development_hot';

const paths = config.get('utils_paths');

const devServer = new WebpackDevServer(webpack(webpackConfig), {
  contentBase: paths.project(config.get('dir_src')),
  hot: true,
  quiet: false,
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  },
  noInfo: false,
  lazy: false,
  stats: {
    colors: true
  },
  historyApiFallback: true
});

export default devServer;

<|next_version|>
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import config from '../config';
import webpackConfig from './webpack/development_hot';

const paths = config.get('utils_paths');

const devServer = new WebpackDevServer(webpack(webpackConfig), {
  contentBase: paths.project(config.get('dir_src')),
  hot: true,
  quiet: false,
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  },
  noInfo: false,
  lazy: false,

  stats: {
    colors: true
  },
  historyApiFallback: true
});

export default devServer;


Add method chaining to Undoer

Add method chaining to Undoer

--- static/undoer.js
+++ static/undoer.js
@@ -6,12 +6,14 @@

 Undoer.prototype.record = function (f) {
   this.actions.push(f)
+  return this
 }

 Undoer.prototype.run = function () {
   while (this.actions.length > 0) {
     this.actions.pop()()
   }
+  return this
 }

 Undoer.prototype.onoff = function (target) {
@@ -21,4 +23,5 @@
   this.record(function () {
     target.off.apply(target, args)
   })
+  return this
 }

<|original_code|>
// See <http://chris-spencer.co.uk/2012/12/20/The-Mighty-Undoer>

function Undoer() {
  this.actions = []
}

Undoer.prototype.record = function (f) {
  this.actions.push(f)
}

Undoer.prototype.run = function () {
  while (this.actions.length > 0) {
    this.actions.pop()()
  }
}

Undoer.prototype.onoff = function (target) {
  var args = Array.prototype.slice.call(arguments, 1)
  target.on.apply(target, args)
  // this.record(target.off.bind.apply(target, args))
  this.record(function () {
    target.off.apply(target, args)
  })
}

<|edits_diff|>
--- static/undoer.js
+++ static/undoer.js
@@ -6,12 +6,14 @@

 Undoer.prototype.record = function (f) {
   this.actions.push(f)
+  return this
 }

 Undoer.prototype.run = function () {
   while (this.actions.length > 0) {
     this.actions.pop()()
   }
+  return this
 }

 Undoer.prototype.onoff = function (target) {
<|current_version|>
// See <http://chris-spencer.co.uk/2012/12/20/The-Mighty-Undoer>

function Undoer() {
  this.actions = []
}

Undoer.prototype.record = function (f) {
  this.actions.push(f)
  return this
}

Undoer.prototype.run = function () {
  while (this.actions.length > 0) {
    this.actions.pop()()
  }
  return this
}

Undoer.prototype.onoff = function (target) {
  var args = Array.prototype.slice.call(arguments, 1)
  target.on.apply(target, args)
  // this.record(target.off.bind.apply(target, args))
  this.record(function () {
    target.off.apply(target, args)
  })
}

<|next_version|>
// See <http://chris-spencer.co.uk/2012/12/20/The-Mighty-Undoer>

function Undoer() {
  this.actions = []
}

Undoer.prototype.record = function (f) {
  this.actions.push(f)
  return this
}

Undoer.prototype.run = function () {
  while (this.actions.length > 0) {
    this.actions.pop()()
  }
  return this
}

Undoer.prototype.onoff = function (target) {
  var args = Array.prototype.slice.call(arguments, 1)
  target.on.apply(target, args)
  // this.record(target.off.bind.apply(target, args))
  this.record(function () {
    target.off.apply(target, args)
  })
  return this
}


Add line and column number to comment-no-loud failing tests

These were missed previously.

--- src/rules/comment-no-loud/__tests__/index.js
+++ src/rules/comment-no-loud/__tests__/index.js
@@ -21,6 +21,8 @@
       /* comment */
     `,
       description: "One line with optional ending",
+      line: 2,
+      column: 7,
       message: messages.expected
     },
     {
@@ -30,6 +32,8 @@
         */
     `,
       description: "Multline comment with optional ending on next line",
+      line: 2,
+      column: 9,
       message: messages.expected
     }
   ]

<|original_code|>
import rule, { ruleName, messages } from "..";

testRule(rule, {
  ruleName,
  config: [true],
  syntax: "scss",

  accept: [
    {
      code: "// comment",
      description: "Double slash comments"
    },
    {
      code: "//* comment",
      description: "Double slash comments with first character as asterix"
    }
  ],
  reject: [
    {
      code: `
      /* comment */
    `,
      description: "One line with optional ending",
      message: messages.expected
    },
    {
      code: `
        /* comment line 1
           comment line 2
        */
    `,
      description: "Multline comment with optional ending on next line",
      message: messages.expected
    }
  ]
});

<|edits_diff|>
--- src/rules/comment-no-loud/__tests__/index.js
+++ src/rules/comment-no-loud/__tests__/index.js
@@ -21,6 +21,8 @@
       /* comment */
     `,
       description: "One line with optional ending",
+      line: 2,
+      column: 7,
       message: messages.expected
     },
     {
<|current_version|>
import rule, { ruleName, messages } from "..";

testRule(rule, {
  ruleName,
  config: [true],
  syntax: "scss",

  accept: [
    {
      code: "// comment",
      description: "Double slash comments"
    },
    {
      code: "//* comment",
      description: "Double slash comments with first character as asterix"
    }
  ],
  reject: [
    {
      code: `
      /* comment */
    `,
      description: "One line with optional ending",
      line: 2,
      column: 7,
      message: messages.expected
    },
    {
      code: `
        /* comment line 1
           comment line 2
        */
    `,
      description: "Multline comment with optional ending on next line",
      message: messages.expected
    }
  ]
});

<|next_version|>
import rule, { ruleName, messages } from "..";

testRule(rule, {
  ruleName,
  config: [true],
  syntax: "scss",

  accept: [
    {
      code: "// comment",
      description: "Double slash comments"
    },
    {
      code: "//* comment",
      description: "Double slash comments with first character as asterix"
    }
  ],
  reject: [
    {
      code: `
      /* comment */
    `,
      description: "One line with optional ending",
      line: 2,
      column: 7,
      message: messages.expected
    },
    {
      code: `
        /* comment line 1
           comment line 2
        */
    `,
      description: "Multline comment with optional ending on next line",
      line: 2,
      column: 9,
      message: messages.expected
    }
  ]
});


Add Swagger doc route to fetch Swagger docs

--- config/router.js
+++ config/router.js
@@ -7,10 +7,14 @@
  */

 const express = require('express');
+const apiDocs = require('./apiDocs');

 module.exports.bootstrap = (app) => {
   let api = require('../api');

+  app.use('/swagger.json', (req, res) => {
+    res.status(200).json(apiDocs);
+  });
   app.use('/api/shorties', api.controllers.shorty);

   return app;

<|original_code|>
'use strict';

/**
 * config/router.js
 *
 * Bootstraps all Express routing.
 */

const express = require('express');

module.exports.bootstrap = (app) => {
  let api = require('../api');

  app.use('/api/shorties', api.controllers.shorty);

  return app;
};

<|edits_diff|>
--- config/router.js
+++ config/router.js
@@ -7,6 +7,7 @@
  */

 const express = require('express');
+const apiDocs = require('./apiDocs');

 module.exports.bootstrap = (app) => {
   let api = require('../api');
<|current_version|>
'use strict';

/**
 * config/router.js
 *
 * Bootstraps all Express routing.
 */

const express = require('express');
const apiDocs = require('./apiDocs');

module.exports.bootstrap = (app) => {
  let api = require('../api');

  app.use('/api/shorties', api.controllers.shorty);

  return app;
};

<|next_version|>
'use strict';

/**
 * config/router.js
 *
 * Bootstraps all Express routing.
 */

const express = require('express');
const apiDocs = require('./apiDocs');

module.exports.bootstrap = (app) => {
  let api = require('../api');

  app.use('/swagger.json', (req, res) => {
    res.status(200).json(apiDocs);
  });
  app.use('/api/shorties', api.controllers.shorty);

  return app;
};


Add header to stats table.

Add header to stats table.

--- src/client/app/components/stats/stats.template.js
+++ src/client/app/components/stats/stats.template.js
@@ -20,10 +20,16 @@
                 ${{
                     any: finance.getKeyStatistics({ symbol }).then(data => {
                         const labels = Object.keys(data);
+                        const headerClasses = "fw6 bb b--black-20 tl pb1 pr1 bg-black-10 tr";
                         const trClasses = "pv1 pr1 bb b--black-20 tr";

                         return hyperHTML.wire()`

+

+                                    Label
+                                    Value
+

+

${labels.map(label => {
                                     const value = data[label] && data[label].fmt;

<|original_code|>
import { ToastsComponent } from "../toasts/toasts.component.js";

export class StatsTemplate {
    static update(render, { symbol = "" } = {}) {
        if (!symbol) {
            render`

Last Asset Stats

                No stats available for last asset.
            `;

            return;
        }

        workway("node://finance.js").then(async({ namespace: finance }) => {
            /* eslint-disable indent */
            render`

Last Asset Stats ${symbol}

                ${{
                    any: finance.getKeyStatistics({ symbol }).then(data => {
                        const labels = Object.keys(data);
                        const trClasses = "pv1 pr1 bb b--black-20 tr";

                        return hyperHTML.wire()`

${labels.map(label => {
                                    const value = data[label] && data[label].fmt;

                                    if (!value) {
                                        return hyperHTML.wire()`<tr></tr>`;
                                    }

                                    return hyperHTML.wire()`

                                        ${label}
                                        ${value}

`;
                                })
                            }

                        `;
                    }).catch(err => {
                        ToastsComponent.update({ message: `${symbol} Stats ${err.message || err}` });

                        return "Fundamental data not available for the asset.";
                    }),
                    placeholder: "Loading..."
                }}
            `;
            /* eslint-enable indent */
        });
    }
}

<|edits_diff|>
--- src/client/app/components/stats/stats.template.js
+++ src/client/app/components/stats/stats.template.js
@@ -20,6 +20,7 @@
                 ${{
                     any: finance.getKeyStatistics({ symbol }).then(data => {
                         const labels = Object.keys(data);
+                        const headerClasses = "fw6 bb b--black-20 tl pb1 pr1 bg-black-10 tr";
                         const trClasses = "pv1 pr1 bb b--black-20 tr";

                         return hyperHTML.wire()`
<|current_version|>
import { ToastsComponent } from "../toasts/toasts.component.js";

export class StatsTemplate {
    static update(render, { symbol = "" } = {}) {
        if (!symbol) {
            render`

Last Asset Stats

                No stats available for last asset.
            `;

            return;
        }

        workway("node://finance.js").then(async({ namespace: finance }) => {
            /* eslint-disable indent */
            render`

Last Asset Stats ${symbol}

                ${{
                    any: finance.getKeyStatistics({ symbol }).then(data => {
                        const labels = Object.keys(data);
                        const headerClasses = "fw6 bb b--black-20 tl pb1 pr1 bg-black-10 tr";
                        const trClasses = "pv1 pr1 bb b--black-20 tr";

                        return hyperHTML.wire()`

${labels.map(label => {
                                    const value = data[label] && data[label].fmt;

                                    if (!value) {
                                        return hyperHTML.wire()`<tr></tr>`;
                                    }

                                    return hyperHTML.wire()`

                                        ${label}
                                        ${value}

`;
                                })
                            }

                        `;
                    }).catch(err => {
                        ToastsComponent.update({ message: `${symbol} Stats ${err.message || err}` });

                        return "Fundamental data not available for the asset.";
                    }),
                    placeholder: "Loading..."
                }}
            `;
            /* eslint-enable indent */
        });
    }
}

<|next_version|>
import { ToastsComponent } from "../toasts/toasts.component.js";

export class StatsTemplate {
    static update(render, { symbol = "" } = {}) {
        if (!symbol) {
            render`

Last Asset Stats

                No stats available for last asset.
            `;

            return;
        }

        workway("node://finance.js").then(async({ namespace: finance }) => {
            /* eslint-disable indent */
            render`

Last Asset Stats ${symbol}

                ${{
                    any: finance.getKeyStatistics({ symbol }).then(data => {
                        const labels = Object.keys(data);
                        const headerClasses = "fw6 bb b--black-20 tl pb1 pr1 bg-black-10 tr";
                        const trClasses = "pv1 pr1 bb b--black-20 tr";

                        return hyperHTML.wire()`

                                    Label
                                    Value

${labels.map(label => {
                                    const value = data[label] && data[label].fmt;

                                    if (!value) {
                                        return hyperHTML.wire()`<tr></tr>`;
                                    }

                                    return hyperHTML.wire()`

                                        ${label}
                                        ${value}

`;
                                })
                            }

                        `;
                    }).catch(err => {
                        ToastsComponent.update({ message: `${symbol} Stats ${err.message || err}` });

                        return "Fundamental data not available for the asset.";
                    }),
                    placeholder: "Loading..."
                }}
            `;
            /* eslint-enable indent */
        });
    }
}


Add revertUnchanged command, because it's not uncommon.

--- p4.js
+++ p4.js
@@ -33,7 +33,12 @@
     });
 }

+function revertUnchanged(path, done) {
+    runCommand("revert", "-a", done);
+}
+
 exports.edit = edit;
 exports.add = add;
 exports.smartEdit = smartEdit;
 exports.run = runCommand;
+exports.revertUnchanged = revertUnchanged;

<|original_code|>
/*jshint node:true*/
"use strict";

var exec = require("child_process").exec;

function runCommand(command, args, done) {
    if(typeof args === "function") {
        done = args;
        args = "";
    }

    exec("p4 " + command + " " + (args || ""), function(err, stdOut, stdErr) {
        if(err) return done(err);
        if(stdErr) return done(new Error(stdErr));

        done(null, stdOut);
    });
}

function edit(path, done) {
    runCommand("edit", path, done);
}

function add(path, done) {
    runCommand("add", path, done);
}

function smartEdit(path, done) {
    edit(path, function(err) {
        if(!err) return done();

        add(path, done);
    });
}

exports.edit = edit;
exports.add = add;
exports.smartEdit = smartEdit;
exports.run = runCommand;

<|edits_diff|>
--- p4.js
+++ p4.js
@@ -33,6 +33,10 @@
     });
 }

+function revertUnchanged(path, done) {
+    runCommand("revert", "-a", done);
+}
+
 exports.edit = edit;
 exports.add = add;
 exports.smartEdit = smartEdit;
<|current_version|>
/*jshint node:true*/
"use strict";

var exec = require("child_process").exec;

function runCommand(command, args, done) {
    if(typeof args === "function") {
        done = args;
        args = "";
    }

    exec("p4 " + command + " " + (args || ""), function(err, stdOut, stdErr) {
        if(err) return done(err);
        if(stdErr) return done(new Error(stdErr));

        done(null, stdOut);
    });
}

function edit(path, done) {
    runCommand("edit", path, done);
}

function add(path, done) {
    runCommand("add", path, done);
}

function smartEdit(path, done) {
    edit(path, function(err) {
        if(!err) return done();

        add(path, done);
    });
}

function revertUnchanged(path, done) {
    runCommand("revert", "-a", done);
}

exports.edit = edit;
exports.add = add;
exports.smartEdit = smartEdit;
exports.run = runCommand;

<|next_version|>
/*jshint node:true*/
"use strict";

var exec = require("child_process").exec;

function runCommand(command, args, done) {
    if(typeof args === "function") {
        done = args;
        args = "";
    }

    exec("p4 " + command + " " + (args || ""), function(err, stdOut, stdErr) {
        if(err) return done(err);
        if(stdErr) return done(new Error(stdErr));

        done(null, stdOut);
    });
}

function edit(path, done) {
    runCommand("edit", path, done);
}

function add(path, done) {
    runCommand("add", path, done);
}

function smartEdit(path, done) {
    edit(path, function(err) {
        if(!err) return done();

        add(path, done);
    });
}

function revertUnchanged(path, done) {
    runCommand("revert", "-a", done);
}

exports.edit = edit;
exports.add = add;
exports.smartEdit = smartEdit;
exports.run = runCommand;
exports.revertUnchanged = revertUnchanged;


Configure webpack to use the extract text plugin

--- webpack.config.js
+++ webpack.config.js
@@ -1,4 +1,5 @@
 var webpack = require('webpack');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
 module.exports = {
   entry: [
     "./src/components/app.js"
@@ -16,9 +17,16 @@
           presets: ['es2015', 'react']
         },
         exclude: /node_modules/
+      },
+      {
+        test: /\.css/,
+        loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
       }
     ]
   },
   plugins: [
+    new ExtractTextPlugin('styles.css', {
+      allChunks: true
+    })
   ]
 };

<|original_code|>
var webpack = require('webpack');
module.exports = {
  entry: [
    "./src/components/app.js"
  ],
  output: {
    path: __dirname + '/static',
    filename: "bundle.js"
  },
  module: {
    loaders: [
      {
        test: /\.js?$/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        },
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
  ]
};

<|edits_diff|>
--- webpack.config.js
+++ webpack.config.js
@@ -1,4 +1,5 @@
 var webpack = require('webpack');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
 module.exports = {
   entry: [
     "./src/components/app.js"
@@ -16,6 +17,10 @@
           presets: ['es2015', 'react']
         },
         exclude: /node_modules/
+      },
+      {
+        test: /\.css/,
+        loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
       }
     ]
   },
<|current_version|>
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
  entry: [
    "./src/components/app.js"
  ],
  output: {
    path: __dirname + '/static',
    filename: "bundle.js"
  },
  module: {
    loaders: [
      {
        test: /\.js?$/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        },
        exclude: /node_modules/
      },
      {
        test: /\.css/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
      }
    ]
  },
  plugins: [
  ]
};

<|next_version|>
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
  entry: [
    "./src/components/app.js"
  ],
  output: {
    path: __dirname + '/static',
    filename: "bundle.js"
  },
  module: {
    loaders: [
      {
        test: /\.js?$/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        },
        exclude: /node_modules/
      },
      {
        test: /\.css/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('styles.css', {
      allChunks: true
    })
  ]
};


Fix box sizing overrides from normalizer

--- lib/ui/components/common/base.js
+++ lib/ui/components/common/base.js
@@ -15,10 +15,20 @@

 export const Div = styled(DivComponent)`
   display: block;
+  box-sizing: content-box;
+
+  * {
+    box-sizing: content-box;
+  }
 `;

 export const Span = styled(SpanComponent)`
   display: inline-block;
+  box-sizing: content-box;
+
+  * {
+    box-sizing: content-box;
+  }
 `;

<|original_code|>
import React from 'react';
import styled from 'styled-components';

export const DivComponent = (props) => (
  <mimic-div class={ props.className } { ...props }>
    { props.children }
  </mimic-div>
);

export const SpanComponent = (props) => (
  <mimic-span class={ props.className } { ...props }>
    { props.children }
  </mimic-span>
);

export const Div = styled(DivComponent)`
  display: block;
`;

export const Span = styled(SpanComponent)`
  display: inline-block;
`;

<|edits_diff|>
--- lib/ui/components/common/base.js
+++ lib/ui/components/common/base.js
@@ -15,6 +15,11 @@

 export const Div = styled(DivComponent)`
   display: block;
+  box-sizing: content-box;
+
+  * {
+    box-sizing: content-box;
+  }
 `;

 export const Span = styled(SpanComponent)`
<|current_version|>
import React from 'react';
import styled from 'styled-components';

export const DivComponent = (props) => (
  <mimic-div class={ props.className } { ...props }>
    { props.children }
  </mimic-div>
);

export const SpanComponent = (props) => (
  <mimic-span class={ props.className } { ...props }>
    { props.children }
  </mimic-span>
);

export const Div = styled(DivComponent)`
  display: block;
  box-sizing: content-box;

  * {
    box-sizing: content-box;
  }
`;

export const Span = styled(SpanComponent)`
  display: inline-block;
`;

<|next_version|>
import React from 'react';
import styled from 'styled-components';

export const DivComponent = (props) => (
  <mimic-div class={ props.className } { ...props }>
    { props.children }
  </mimic-div>
);

export const SpanComponent = (props) => (
  <mimic-span class={ props.className } { ...props }>
    { props.children }
  </mimic-span>
);

export const Div = styled(DivComponent)`
  display: block;
  box-sizing: content-box;

  * {
    box-sizing: content-box;
  }
`;

export const Span = styled(SpanComponent)`
  display: inline-block;
  box-sizing: content-box;

  * {
    box-sizing: content-box;
  }
`;


Add fetchReport to exported functions

Add fetchReport to exported functions

This is useful if you want to use the library without running the cli.

--- src/index.js
+++ src/index.js
@@ -1,7 +1,9 @@
 import RemoteBrowserTarget from './RemoteBrowserTarget';
+import fetchReport from './fetchReport';
 import uploadReport from './uploadReport';

 export {
   RemoteBrowserTarget,
   uploadReport,
+  fetchReport,
 };

<|original_code|>
import RemoteBrowserTarget from './RemoteBrowserTarget';
import uploadReport from './uploadReport';

export {
  RemoteBrowserTarget,
  uploadReport,
};

<|edits_diff|>
--- src/index.js
+++ src/index.js
@@ -1,4 +1,5 @@
 import RemoteBrowserTarget from './RemoteBrowserTarget';
+import fetchReport from './fetchReport';
 import uploadReport from './uploadReport';

 export {
<|current_version|>
import RemoteBrowserTarget from './RemoteBrowserTarget';
import fetchReport from './fetchReport';
import uploadReport from './uploadReport';

export {
  RemoteBrowserTarget,
  uploadReport,
};

<|next_version|>
import RemoteBrowserTarget from './RemoteBrowserTarget';
import fetchReport from './fetchReport';
import uploadReport from './uploadReport';

export {
  RemoteBrowserTarget,
  uploadReport,
  fetchReport,
};


Sort the album list after loading it

ui: Sort the album list after loading it

--- src/gollery/static/js/sidebar.js
+++ src/gollery/static/js/sidebar.js
@@ -16,9 +16,12 @@
 	},

 	loadAlbums: function() {
+		var sidebar = this;
 		var albumList = $('#album-list');

 		$.getJSON('/albums/', function(data) {
+			data.sort(sidebar.albumCompareFunc);
+
 			$.each(data, function(idx, album) {
 				var li = document.createElement('li');
 				var a = document.createElement('a');
@@ -28,6 +31,10 @@
 				albumList.append(li);
 			});
 		});
+	},
+
+	albumCompareFunc: function(a, b) {
+		return a.name.localeCompare(b.name);
 	}
 };

<|original_code|>
define(['jquery'], function($) {

function Sidebar() {
	var sidebar = this;

	$('#sidebar-toggle-button').click(function() {
		sidebar.toggle();
	});

	sidebar.loadAlbums();
}

Sidebar.prototype = {
	toggle: function() {
		$(document.body).toggleClass('sidebar-toggled');
	},

	loadAlbums: function() {
		var albumList = $('#album-list');

		$.getJSON('/albums/', function(data) {
			$.each(data, function(idx, album) {
				var li = document.createElement('li');
				var a = document.createElement('a');
				a.appendChild(document.createTextNode(album.name));
				a.href = '#browse:' + album.name;
				li.appendChild(a);
				albumList.append(li);
			});
		});
	}
};

return Sidebar;

}); // define

<|edits_diff|>
--- src/gollery/static/js/sidebar.js
+++ src/gollery/static/js/sidebar.js
@@ -16,9 +16,12 @@
 	},

 	loadAlbums: function() {
+		var sidebar = this;
 		var albumList = $('#album-list');

 		$.getJSON('/albums/', function(data) {
+			data.sort(sidebar.albumCompareFunc);
+
 			$.each(data, function(idx, album) {
 				var li = document.createElement('li');
 				var a = document.createElement('a');
<|current_version|>
define(['jquery'], function($) {

function Sidebar() {
	var sidebar = this;

	$('#sidebar-toggle-button').click(function() {
		sidebar.toggle();
	});

	sidebar.loadAlbums();
}

Sidebar.prototype = {
	toggle: function() {
		$(document.body).toggleClass('sidebar-toggled');
	},

	loadAlbums: function() {
		var sidebar = this;
		var albumList = $('#album-list');

		$.getJSON('/albums/', function(data) {
			data.sort(sidebar.albumCompareFunc);

			$.each(data, function(idx, album) {
				var li = document.createElement('li');
				var a = document.createElement('a');
				a.appendChild(document.createTextNode(album.name));
				a.href = '#browse:' + album.name;
				li.appendChild(a);
				albumList.append(li);
			});
		});
	}
};

return Sidebar;

}); // define

<|next_version|>
define(['jquery'], function($) {

function Sidebar() {
	var sidebar = this;

	$('#sidebar-toggle-button').click(function() {
		sidebar.toggle();
	});

	sidebar.loadAlbums();
}

Sidebar.prototype = {
	toggle: function() {
		$(document.body).toggleClass('sidebar-toggled');
	},

	loadAlbums: function() {
		var sidebar = this;
		var albumList = $('#album-list');

		$.getJSON('/albums/', function(data) {
			data.sort(sidebar.albumCompareFunc);

			$.each(data, function(idx, album) {
				var li = document.createElement('li');
				var a = document.createElement('a');
				a.appendChild(document.createTextNode(album.name));
				a.href = '#browse:' + album.name;
				li.appendChild(a);
				albumList.append(li);
			});
		});
	},

	albumCompareFunc: function(a, b) {
		return a.name.localeCompare(b.name);
	}
};

return Sidebar;

}); // define


Implement non reactive coupling tests, only invoke reactive tests within chrome

--- test/all.js
+++ test/all.js
@@ -1,4 +1,5 @@
 var test = require('tape');
+var detect = require('rtc-core/detect');

 test('can import rtc module', function(t) {
   t.plan(1);
@@ -9,6 +10,11 @@
 require('./generators-connection-constraints');
 require('./peerconnection');
 require('./coupling');
+
+// only test reactive coupling in chrome
+if (! detect.moz) {
+  require('./coupling-reactive');
+}
 // require('./data-channel');

 // test the signalling

<|original_code|>
var test = require('tape');

test('can import rtc module', function(t) {
  t.plan(1);
  t.ok(require('../'), 'imported successfully');
});

require('./generators');
require('./generators-connection-constraints');
require('./peerconnection');
require('./coupling');
// require('./data-channel');

// test the signalling
// require('./signalling/all');
<|edits_diff|>
--- test/all.js
+++ test/all.js
@@ -1,4 +1,5 @@
 var test = require('tape');
+var detect = require('rtc-core/detect');

 test('can import rtc module', function(t) {
   t.plan(1);
<|current_version|>
var test = require('tape');
var detect = require('rtc-core/detect');

test('can import rtc module', function(t) {
  t.plan(1);
  t.ok(require('../'), 'imported successfully');
});

require('./generators');
require('./generators-connection-constraints');
require('./peerconnection');
require('./coupling');
// require('./data-channel');

// test the signalling
// require('./signalling/all');
<|next_version|>
var test = require('tape');
var detect = require('rtc-core/detect');

test('can import rtc module', function(t) {
  t.plan(1);
  t.ok(require('../'), 'imported successfully');
});

require('./generators');
require('./generators-connection-constraints');
require('./peerconnection');
require('./coupling');

// only test reactive coupling in chrome
if (! detect.moz) {
  require('./coupling-reactive');
}
// require('./data-channel');

// test the signalling
// require('./signalling/all');


Handle error when chart does not load

Handle error when chart does not load

--- apps/explorer/templates/explorer/_pixels_distributions.js
+++ apps/explorer/templates/explorer/_pixels_distributions.js
@@ -20,6 +20,8 @@
           title: '{% trans "Values" %}',
         }
       );
+    }).fail(function () {
+      document.getElementById('values-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
     });

     $.get('{{ url_scores }}', function (data) {
@@ -31,6 +33,8 @@
           title: '{% trans "Quality scores" %}',
         }
       );
+    }).fail(function () {
+      document.getElementById('scores-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
     });
   }
 </script>

<|original_code|>
{% load i18n %}

<script src="//www.gstatic.com/charts/loader.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(drawCharts);

  function drawCharts() {
    var valuesChart = new google.visualization.Histogram(document.getElementById('values-histogram'));
    var scoresChart = new google.visualization.Histogram(document.getElementById('scores-histogram'));

    $.get('{{ url_values }}', function (data) {
      valuesChart.draw(
        new google.visualization.DataTable(data),
        {
          colors: ['#bd2222'],
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Values" %}',
        }
      );
    });

    $.get('{{ url_scores }}', function (data) {
      scoresChart.draw(
        new google.visualization.DataTable(data),
        {
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Quality scores" %}',
        }
      );
    });
  }
</script>

<|edits_diff|>
--- apps/explorer/templates/explorer/_pixels_distributions.js
+++ apps/explorer/templates/explorer/_pixels_distributions.js
@@ -20,6 +20,8 @@
           title: '{% trans "Values" %}',
         }
       );
+    }).fail(function () {
+      document.getElementById('values-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
     });

     $.get('{{ url_scores }}', function (data) {
<|current_version|>
{% load i18n %}

<script src="//www.gstatic.com/charts/loader.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(drawCharts);

  function drawCharts() {
    var valuesChart = new google.visualization.Histogram(document.getElementById('values-histogram'));
    var scoresChart = new google.visualization.Histogram(document.getElementById('scores-histogram'));

    $.get('{{ url_values }}', function (data) {
      valuesChart.draw(
        new google.visualization.DataTable(data),
        {
          colors: ['#bd2222'],
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Values" %}',
        }
      );
    }).fail(function () {
      document.getElementById('values-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
    });

    $.get('{{ url_scores }}', function (data) {
      scoresChart.draw(
        new google.visualization.DataTable(data),
        {
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Quality scores" %}',
        }
      );
    });
  }
</script>

<|next_version|>
{% load i18n %}

<script src="//www.gstatic.com/charts/loader.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(drawCharts);

  function drawCharts() {
    var valuesChart = new google.visualization.Histogram(document.getElementById('values-histogram'));
    var scoresChart = new google.visualization.Histogram(document.getElementById('scores-histogram'));

    $.get('{{ url_values }}', function (data) {
      valuesChart.draw(
        new google.visualization.DataTable(data),
        {
          colors: ['#bd2222'],
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Values" %}',
        }
      );
    }).fail(function () {
      document.getElementById('values-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
    });

    $.get('{{ url_scores }}', function (data) {
      scoresChart.draw(
        new google.visualization.DataTable(data),
        {
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Quality scores" %}',
        }
      );
    }).fail(function () {
      document.getElementById('scores-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
    });
  }
</script>


Change lint errors to warnings

Change lint errors to warnings

--- .eslintrc.js
+++ .eslintrc.js
@@ -15,6 +15,7 @@
     browser: true
   },
   rules: {
+    'no-console': 'warn'
   },
   overrides: [
     // node files
@@ -51,6 +52,9 @@
       excludedFiles: ['tests/dummy/**/*.js'],
       env: {
         embertest: true
+      },
+      rules: {
+        'ember/new-module-imports': 'warn'
       }
     }
   ]

<|original_code|>
module.exports = {
  root: true,
  parserOptions: {
    ecmaVersion: 2017,
    sourceType: 'module'
  },
  plugins: [
    'ember'
  ],
  extends: [
    'eslint:recommended',
    'plugin:ember/recommended'
  ],
  env: {
    browser: true
  },
  rules: {
  },
  overrides: [
    // node files
    {
      files: [
        'index.js',
        'testem.js',
        'ember-cli-build.js',
        'config/**/*.js',
        'tests/dummy/config/**/*.js'
      ],
      excludedFiles: [
        'app/**',
        'addon/**',
        'tests/dummy/app/**'
      ],
      parserOptions: {
        sourceType: 'script',
        ecmaVersion: 2015
      },
      env: {
        browser: false,
        node: true
      },
      plugins: ['node'],
      rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
        // add your custom rules and overrides for node files here
      })
    },

    // test files
    {
      files: ['tests/**/*.js'],
      excludedFiles: ['tests/dummy/**/*.js'],
      env: {
        embertest: true
      }
    }
  ]
};

<|edits_diff|>
--- .eslintrc.js
+++ .eslintrc.js
@@ -15,6 +15,7 @@
     browser: true
   },
   rules: {
+    'no-console': 'warn'
   },
   overrides: [
     // node files
<|current_version|>
module.exports = {
  root: true,
  parserOptions: {
    ecmaVersion: 2017,
    sourceType: 'module'
  },
  plugins: [
    'ember'
  ],
  extends: [
    'eslint:recommended',
    'plugin:ember/recommended'
  ],
  env: {
    browser: true
  },
  rules: {
    'no-console': 'warn'
  },
  overrides: [
    // node files
    {
      files: [
        'index.js',
        'testem.js',
        'ember-cli-build.js',
        'config/**/*.js',
        'tests/dummy/config/**/*.js'
      ],
      excludedFiles: [
        'app/**',
        'addon/**',
        'tests/dummy/app/**'
      ],
      parserOptions: {
        sourceType: 'script',
        ecmaVersion: 2015
      },
      env: {
        browser: false,
        node: true
      },
      plugins: ['node'],
      rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
        // add your custom rules and overrides for node files here
      })
    },

    // test files
    {
      files: ['tests/**/*.js'],
      excludedFiles: ['tests/dummy/**/*.js'],
      env: {
        embertest: true
      }
    }
  ]
};

<|next_version|>
module.exports = {
  root: true,
  parserOptions: {
    ecmaVersion: 2017,
    sourceType: 'module'
  },
  plugins: [
    'ember'
  ],
  extends: [
    'eslint:recommended',
    'plugin:ember/recommended'
  ],
  env: {
    browser: true
  },
  rules: {
    'no-console': 'warn'
  },
  overrides: [
    // node files
    {
      files: [
        'index.js',
        'testem.js',
        'ember-cli-build.js',
        'config/**/*.js',
        'tests/dummy/config/**/*.js'
      ],
      excludedFiles: [
        'app/**',
        'addon/**',
        'tests/dummy/app/**'
      ],
      parserOptions: {
        sourceType: 'script',
        ecmaVersion: 2015
      },
      env: {
        browser: false,
        node: true
      },
      plugins: ['node'],
      rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
        // add your custom rules and overrides for node files here
      })
    },

    // test files
    {
      files: ['tests/**/*.js'],
      excludedFiles: ['tests/dummy/**/*.js'],
      env: {
        embertest: true
      },
      rules: {
        'ember/new-module-imports': 'warn'
      }
    }
  ]
};


Fix bug where scripts are loaded 3X each.

--- data/dotjs.js
+++ data/dotjs.js
@@ -2,7 +2,14 @@
  * catch the 'load-scripts' event and inject the resilts into the current scope.
  */
 (function() {
+    var scriptsLoaded = false;
+
     self.port.on('load-scripts', function(msg) {
+        // bail if scripts were already loaded
+        // (this is workaround to weird bug where scripts are loaded 3X)
+        if (scriptsLoaded) return;
+        scriptsLoaded = true;
+
         // bail out if we're in an iframe
         if (window.frameElement) return;

<|original_code|>
/*
 * catch the 'load-scripts' event and inject the resilts into the current scope.
 */
(function() {
    self.port.on('load-scripts', function(msg) {
        // bail out if we're in an iframe
        if (window.frameElement) return;

        if (msg.jquery) {
            eval(msg.jquery);
        }

        msg.js.forEach(function(script) {
            eval(script);
        });

        if (msg.coffee) {
            (function() {
                eval(msg.transpiler);
            }).call(window); // coffee-script.js assumes this === window
        }
        msg.coffee.forEach(function(script) {
            eval(CoffeeScript.compile(script));
        });

        msg.css.forEach(function(styles) {
            var headNode = document.querySelector('head');
            var cssNode = document.createElement('style');
            cssNode.innerHTML = styles;
            headNode.appendChild(cssNode);
        });
    });

    if (document.URL.indexOf('http') === 0) {
        self.port.emit('init', document.URL);
    }
})();
<|edits_diff|>
--- data/dotjs.js
+++ data/dotjs.js
@@ -2,6 +2,8 @@
  * catch the 'load-scripts' event and inject the resilts into the current scope.
  */
 (function() {
+    var scriptsLoaded = false;
+
     self.port.on('load-scripts', function(msg) {
         // bail out if we're in an iframe
         if (window.frameElement) return;
<|current_version|>
/*
 * catch the 'load-scripts' event and inject the resilts into the current scope.
 */
(function() {
    var scriptsLoaded = false;

    self.port.on('load-scripts', function(msg) {
        // bail out if we're in an iframe
        if (window.frameElement) return;

        if (msg.jquery) {
            eval(msg.jquery);
        }

        msg.js.forEach(function(script) {
            eval(script);
        });

        if (msg.coffee) {
            (function() {
                eval(msg.transpiler);
            }).call(window); // coffee-script.js assumes this === window
        }
        msg.coffee.forEach(function(script) {
            eval(CoffeeScript.compile(script));
        });

        msg.css.forEach(function(styles) {
            var headNode = document.querySelector('head');
            var cssNode = document.createElement('style');
            cssNode.innerHTML = styles;
            headNode.appendChild(cssNode);
        });
    });

    if (document.URL.indexOf('http') === 0) {
        self.port.emit('init', document.URL);
    }
})();

<|next_version|>
/*
 * catch the 'load-scripts' event and inject the resilts into the current scope.
 */
(function() {
    var scriptsLoaded = false;

    self.port.on('load-scripts', function(msg) {
        // bail if scripts were already loaded
        // (this is workaround to weird bug where scripts are loaded 3X)
        if (scriptsLoaded) return;
        scriptsLoaded = true;

        // bail out if we're in an iframe
        if (window.frameElement) return;

        if (msg.jquery) {
            eval(msg.jquery);
        }

        msg.js.forEach(function(script) {
            eval(script);
        });

        if (msg.coffee) {
            (function() {
                eval(msg.transpiler);
            }).call(window); // coffee-script.js assumes this === window
        }
        msg.coffee.forEach(function(script) {
            eval(CoffeeScript.compile(script));
        });

        msg.css.forEach(function(styles) {
            var headNode = document.querySelector('head');
            var cssNode = document.createElement('style');
            cssNode.innerHTML = styles;
            headNode.appendChild(cssNode);
        });
    });

    if (document.URL.indexOf('http') === 0) {
        self.port.emit('init', document.URL);
    }
})();


Add some logging at install time

Add some logging at install time

Otherwise, it's tough to know if this code executed.

--- src/background.js
+++ src/background.js
@@ -3,15 +3,19 @@
     // Install declarative content rules

     if (details.reason == 'update') {
+        console.info('Upgrade detected, checking data format...');
+
         // Upgrade stored data to a new format when a new version is installed.
         // Delay installing the rules until the data is upgraded in case the new rules code relies
         // on the new format.
         chrome.storage.local.get(null, function (items) {
             _upgradeData(items);
+            console.info('Data upgraded, adding declarativeContent rules');
             hwRules.resetRules();
         });
     }
     else {
+        console.info('Adding declarativeContent rules for new install');
         hwRules.resetRules();
     }

<|original_code|>
/*global chrome, hwRules */
chrome.runtime.onInstalled.addListener(function(details) {
    // Install declarative content rules

    if (details.reason == 'update') {
        // Upgrade stored data to a new format when a new version is installed.
        // Delay installing the rules until the data is upgraded in case the new rules code relies
        // on the new format.
        chrome.storage.local.get(null, function (items) {
            _upgradeData(items);
            hwRules.resetRules();
        });
    }
    else {
        hwRules.resetRules();
    }

    function _upgradeData(items) {
        Object.keys(items).filter(function (domain) {
            var settings = items[domain];

            // For data from previous versions that doesn't have the create/access dates.
            // We'll use 0 as a special value to indicate that the date is not known. This will
            // allow us to know that these sites already have hashwords created for them, as
            // well as show a special string in the options page for such cases.
            if (settings.createDate == null) {
                settings.createDate = 0;
                settings.accessDate = 0;
                return true;
            }

            return false;
        });

        chrome.storage.local.set(items);
    }
});

// Just in case
chrome.runtime.onStartup.addListener(hwRules.resetRules);

<|edits_diff|>
--- src/background.js
+++ src/background.js
@@ -3,11 +3,14 @@
     // Install declarative content rules

     if (details.reason == 'update') {
+        console.info('Upgrade detected, checking data format...');
+
         // Upgrade stored data to a new format when a new version is installed.
         // Delay installing the rules until the data is upgraded in case the new rules code relies
         // on the new format.
         chrome.storage.local.get(null, function (items) {
             _upgradeData(items);
+            console.info('Data upgraded, adding declarativeContent rules');
             hwRules.resetRules();
         });
     }
<|current_version|>
/*global chrome, hwRules */
chrome.runtime.onInstalled.addListener(function(details) {
    // Install declarative content rules

    if (details.reason == 'update') {
        console.info('Upgrade detected, checking data format...');

        // Upgrade stored data to a new format when a new version is installed.
        // Delay installing the rules until the data is upgraded in case the new rules code relies
        // on the new format.
        chrome.storage.local.get(null, function (items) {
            _upgradeData(items);
            console.info('Data upgraded, adding declarativeContent rules');
            hwRules.resetRules();
        });
    }
    else {
        hwRules.resetRules();
    }

    function _upgradeData(items) {
        Object.keys(items).filter(function (domain) {
            var settings = items[domain];

            // For data from previous versions that doesn't have the create/access dates.
            // We'll use 0 as a special value to indicate that the date is not known. This will
            // allow us to know that these sites already have hashwords created for them, as
            // well as show a special string in the options page for such cases.
            if (settings.createDate == null) {
                settings.createDate = 0;
                settings.accessDate = 0;
                return true;
            }

            return false;
        });

        chrome.storage.local.set(items);
    }
});

// Just in case
chrome.runtime.onStartup.addListener(hwRules.resetRules);

<|next_version|>
/*global chrome, hwRules */
chrome.runtime.onInstalled.addListener(function(details) {
    // Install declarative content rules

    if (details.reason == 'update') {
        console.info('Upgrade detected, checking data format...');

        // Upgrade stored data to a new format when a new version is installed.
        // Delay installing the rules until the data is upgraded in case the new rules code relies
        // on the new format.
        chrome.storage.local.get(null, function (items) {
            _upgradeData(items);
            console.info('Data upgraded, adding declarativeContent rules');
            hwRules.resetRules();
        });
    }
    else {
        console.info('Adding declarativeContent rules for new install');
        hwRules.resetRules();
    }

    function _upgradeData(items) {
        Object.keys(items).filter(function (domain) {
            var settings = items[domain];

            // For data from previous versions that doesn't have the create/access dates.
            // We'll use 0 as a special value to indicate that the date is not known. This will
            // allow us to know that these sites already have hashwords created for them, as
            // well as show a special string in the options page for such cases.
            if (settings.createDate == null) {
                settings.createDate = 0;
                settings.accessDate = 0;
                return true;
            }

            return false;
        });

        chrome.storage.local.set(items);
    }
});

// Just in case
chrome.runtime.onStartup.addListener(hwRules.resetRules);