<commit_before>module.exports = {

    incoming: function (message, bot, builder) {
        console.log('conversations/state')
        console.log(global.conversations);
        console.log('************');
        console.log('users');
        console.log(global.users);
        console.log('agents');
        console.log(global.agent);

        if (message.text === 'help') {
            // user initiated connect to agent
            // send something like 'hold on while I connect you'
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { findingAgent: true });
            message.text = '';
            return message
        };

        // find out who is talking / add new convo if not found
        if (message.user.isStaff) {
            console.log('is staff');
            var thisAgent = global.agent.filter(function (value) {
                return value === message.address.conversation.id;
            })
            // if (!global.agent.includes(message.address.conversation.id)) {
            if (thisAgent[0] !== message.address.conversation.id) {
                global.agent.push(message.address.conversation.id);

            };

            // };
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { address: message.address })

            // } else if (!global.users.includes(message.address.conversation.id)) {

        };
        if (!message.user.isStaff) {
            console.log('not staff');
            var thisUser = global.users.filter(function (value) {
                return value === message.address.conversation.id;
            });
            if (thisUser[0] !== message.address.conversation.id) {
                global.users.push(message.address.conversation.id);

            }

            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], {
                transcript: global.conversations[message.address.conversation.id].transcript.push(message),
                address: message.address
            })

            // this needs to be an array of message objects and an indication of where messages should be routed
        }
        if (global.conversation[message.address.conversation.id].findingAgent) {
            console.log('getting agent');
            var myAgent = global.conversations[global.agent[0]].address;
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { agentAddress: myAgent, findingAgent: false })

        }

        // who should they be talking to

        // make it so

        // if talking to Agent/waiting for agent, suppress default bot functionality (how if on a prompt and it's looking for a certain response? override somehow)

    }

}
<commit_msg>user convo info disappears<commit_after>module.exports = {

    incoming: function (message, bot, builder) {
        console.log('conversations/state')
        console.log(global.conversations);
        console.log('************');
        console.log('users');
        console.log(global.users);
        console.log('agents');
        console.log(global.agent);

        if (message.text === 'help') {
            // user initiated connect to agent
            // send something like 'hold on while I connect you'
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { findingAgent: true });
            message.text = 'hold on while I connect you';
            return message
        };

        // find out who is talking / add new convo if not found
        if (message.user.isStaff) {
            console.log('is staff');
            var thisAgent = global.agent.filter(function (value) {
                return value === message.address.conversation.id;
            })
            if (thisAgent[0] !== message.address.conversation.id) {
                global.agent.push(message.address.conversation.id);

            };

            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { address: message.address })

        };
        if (!message.user.isStaff) {
            console.log('not staff');
            var thisUser = global.users.filter(function (value) {
                return value === message.address.conversation.id;
            });
            if (thisUser[0] !== message.address.conversation.id) {
                global.users.push(message.address.conversation.id);

            }

            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], {
                transcript: global.conversations[message.address.conversation.id].transcript.push(message),
                address: message.address
            })

            // this needs to be an array of message objects and an indication of where messages should be routed
        }
        if (global.conversation[message.address.conversation.id].findingAgent) {
            console.log('getting agent');
            var myAgent = global.conversations[global.agent[0]].address;
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { agentAddress: myAgent, findingAgent: false })

        }

        // who should they be talking to

        // make it so

        // if talking to Agent/waiting for agent, suppress default bot functionality (how if on a prompt and it's looking for a certain response? override somehow)

    }

}
<|endoftext|>


<commit_before>const config = require('./config');
const MobileDetect = require('mobile-detect');
const serialize = require('serialize-javascript');
const serveStatic = require('serve-static');
const webpack = require('webpack');

module.exports = (opts) => {
  opts = opts || {};
  opts.getAuth = opts.getAuth || ((req, callback) => callback(null, {}));
  const middlewares = [];

  function webpackRuntime(configPath) {
    const webpackDevMiddleware = require('webpack-dev-middleware');
    const webpackHotMiddleware = require('webpack-hot-middleware');
    const webpackConfig = require(configPath);

    const compiler = webpack(webpackConfig);
    middlewares.push(webpackDevMiddleware(compiler, {
      noInfo: true,
      publicPath: webpackConfig.output.publicPath,
    }));
    middlewares.push(webpackHotMiddleware(compiler));
  }

  if (opts.hot) {
    webpackRuntime('./webpack.desktop.config');
    webpackRuntime('./webpack.mobile.config');
  }

  if (opts.localBundle) {
    middlewares.push(serveStatic(`${__dirname}/dist`));
  }

  middlewares.push((req, res) => {
    const cdn = `//${config.cloudfront.domain}`;
    function path(name) {
      // 2016. 04. 19. [heekyu] do not use goommerce-react's build config
      // use gommerce's config(opts.cdnPath)
      if (opts.cdnPath) {
        return `${opts.cdnPath}/${name}`;
      }
      if (opts.hot || opts.localBundle) {
        return `/${name}`;
      }
      return `//${config.cloudfront.domain}/app/${config.bundle.version}/${name}`;
    }
    const md = new MobileDetect(req.headers['user-agent']);

    /* copy viewport content from aliexpress */
    function sendMobile(initialState) {
      res.send(`
        <!DOCTYPE html>

            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, user-scalable=0, width=device-width">
            <title>${config.title}</title>
            <link rel="stylesheet" href="${cdn}/vendor/owl.carousel.css">

      `);
    }

    function send(initialState, gaid) {
      res.send(`
        <!DOCTYPE html>

            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>${config.title}</title>
            <link rel="stylesheet" href="${cdn}/vendor/owl.carousel.css">
            <link href="//fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet" type="text/css">
	        <link href="//fonts.googleapis.com/css?family=Roboto:400,500,700|Roboto+Condensed:400,700" rel="stylesheet" type="text/css">

            ${gaid ? `<script>window.gaid="${gaid}"</script>` : ''}

      `);
    }

    if (req.method === 'GET' && req.accepts('html')) {
      opts.getAuth(req, (err, auth) => {
        const host = req.get('host');
        const initialState = {
          currency: { activeCurrency: req.currency },
        };
        if (!err) {
          initialState.auth = auth;
        }
        if (req.i18n) {
          initialState.i18n = req.i18n;
          initialState.i18n.activeLocale = req.locale;
        }
        if (host === config.mobileSite) {
          return sendMobile(initialState);
        }
        const mobileRedirectKey = 'mobile_redirect';
        if (!req.cookies[mobileRedirectKey] && config.mobileSite && md.mobile() && !md.tablet()) {
          req.cookies[mobileRedirectKey] = true;
          // 2016. 04. 08. [heekyu] Use this on local test
          // return sendMobile(initialState);
          return res.redirect(`//${config.mobileSite}/`);
        }
        var gaid = config.ga; // eslint-disable-line
        if (gaid) {
          // 2016. 04. 19. [heekyu] TODO remove common logic
          for (var i = 0; i < (auth.roles || []).length; i++) { // eslint-disable-line
            const role = auth.roles[i];
            if (role.type === 'admin') {
              gaid = null;
              break;
            }
          }
        }

        return send(initialState, gaid);
      });
    }
  });
  return middlewares;
};
<commit_msg>when auth is not<commit_after>const config = require('./config');
const MobileDetect = require('mobile-detect');
const serialize = require('serialize-javascript');
const serveStatic = require('serve-static');
const webpack = require('webpack');

module.exports = (opts) => {
  opts = opts || {};
  opts.getAuth = opts.getAuth || ((req, callback) => callback(null, {}));
  const middlewares = [];

  function webpackRuntime(configPath) {
    const webpackDevMiddleware = require('webpack-dev-middleware');
    const webpackHotMiddleware = require('webpack-hot-middleware');
    const webpackConfig = require(configPath);

    const compiler = webpack(webpackConfig);
    middlewares.push(webpackDevMiddleware(compiler, {
      noInfo: true,
      publicPath: webpackConfig.output.publicPath,
    }));
    middlewares.push(webpackHotMiddleware(compiler));
  }

  if (opts.hot) {
    webpackRuntime('./webpack.desktop.config');
    webpackRuntime('./webpack.mobile.config');
  }

  if (opts.localBundle) {
    middlewares.push(serveStatic(`${__dirname}/dist`));
  }

  middlewares.push((req, res) => {
    const cdn = `//${config.cloudfront.domain}`;
    function path(name) {
      // 2016. 04. 19. [heekyu] do not use goommerce-react's build config
      // use gommerce's config(opts.cdnPath)
      if (opts.cdnPath) {
        return `${opts.cdnPath}/${name}`;
      }
      if (opts.hot || opts.localBundle) {
        return `/${name}`;
      }
      return `//${config.cloudfront.domain}/app/${config.bundle.version}/${name}`;
    }
    const md = new MobileDetect(req.headers['user-agent']);

    /* copy viewport content from aliexpress */
    function sendMobile(initialState) {
      res.send(`
        <!DOCTYPE html>

            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, user-scalable=0, width=device-width">
            <title>${config.title}</title>
            <link rel="stylesheet" href="${cdn}/vendor/owl.carousel.css">

      `);
    }

    function send(initialState, gaid) {
      res.send(`
        <!DOCTYPE html>

            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>${config.title}</title>
            <link rel="stylesheet" href="${cdn}/vendor/owl.carousel.css">
            <link href="//fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet" type="text/css">
	        <link href="//fonts.googleapis.com/css?family=Roboto:400,500,700|Roboto+Condensed:400,700" rel="stylesheet" type="text/css">

            ${gaid ? `<script>window.gaid="${gaid}"</script>` : ''}

      `);
    }

    if (req.method === 'GET' && req.accepts('html')) {
      opts.getAuth(req, (err, auth) => {
        const host = req.get('host');
        const initialState = {
          currency: { activeCurrency: req.currency },
        };
        if (!err) {
          initialState.auth = auth;
        }
        if (req.i18n) {
          initialState.i18n = req.i18n;
          initialState.i18n.activeLocale = req.locale;
        }
        if (host === config.mobileSite) {
          return sendMobile(initialState);
        }
        const mobileRedirectKey = 'mobile_redirect';
        if (!req.cookies[mobileRedirectKey] && config.mobileSite && md.mobile() && !md.tablet()) {
          req.cookies[mobileRedirectKey] = true;
          // 2016. 04. 08. [heekyu] Use this on local test
          // return sendMobile(initialState);
          return res.redirect(`//${config.mobileSite}/`);
        }
        var gaid = config.ga; // eslint-disable-line
        if (gaid && auth) {
          // 2016. 04. 19. [heekyu] TODO remove common logic
          for (var i = 0; i < (auth.roles || []).length; i++) { // eslint-disable-line
            const role = auth.roles[i];
            if (role.type === 'admin') {
              gaid = null;
              break;
            }
          }
        }

        return send(initialState, gaid);
      });
    }
  });
  return middlewares;
};
<|endoftext|>


<commit_before># Mozilla User Preferences

/* Do not edit this file.
 *
 * If you make changes to this file while the application is running,
 * the changes will be overwritten when the application exits.
 *
 * To make a manual change to preferences, you can visit the URL about:config
 * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
 */

user_pref("app.update.auto", false);
user_pref("app.update.enabled", false);
user_pref("app.update.lastUpdateTime.addon-background-update-timer", 1216566538);
user_pref("app.update.lastUpdateTime.background-update-timer", 1216566535);
user_pref("app.update.lastUpdateTime.blocklist-background-update-timer", 1216566538);
user_pref("app.update.lastUpdateTime.microsummary-generator-update-timer", 1232574822);
user_pref("app.update.lastUpdateTime.search-engine-update-timer", 1216566539);
user_pref("browser.bookmarks.livemark_refresh_seconds", 31536000);
user_pref("browser.cache.disk.capacity", 0);
user_pref("browser.cache.disk.enable", false);
user_pref("browser.cache.disk.smart_size.enabled", false);
user_pref("browser.cache.disk.smart_size.first_run", false);
user_pref("browser.cache.offline.enable", false);
user_pref("browser.chrome.favicons", false);
user_pref("browser.chrome.image_icons.max_size", 0);
user_pref("browser.chrome.site_icons", false);
user_pref("browser.download.manager.retention", 1);
user_pref("browser.download.useDownloadDir", false);
user_pref("browser.formfill.enable", false);
user_pref("browser.history_expire_days.mirror", 0);
user_pref("browser.microsummary.updateGenerators", false);
user_pref("browser.migration.version", 5);
user_pref("browser.places.importBookmarksHTML", false);
user_pref("browser.places.importDefaults", false);
user_pref("browser.places.leftPaneFolderId", -1);
user_pref("browser.places.migratePostDataAnnotations", false);
user_pref("browser.places.smartBookmarksVersion", 2);
user_pref("browser.places.updateRecentTagsUri", false);
user_pref("browser.preferences.advanced.selectedTabIndex", 0);
user_pref("browser.privatebrowsing.autostart", true);
user_pref("browser.rights.3.shown", true);
user_pref("browser.safebrowsing.enabled", false);
user_pref("browser.safebrowsing.malware.enabled", false);
user_pref("browser.search.suggest.enabled", false);
user_pref("browser.search.update", false);
user_pref("browser.sessionstore.privacy_level", 2);
user_pref("browser.shell.checkDefaultBrowser", false);
user_pref("browser.startup.homepage", "https://check.torproject.org/?lang=en-US&small=1");
user_pref("browser.startup.homepage_override.buildID", "20110325121920");
user_pref("browser.startup.homepage_override.mstone", "rv:2.0");
user_pref("browser.urlbar.autocomplete.enabled", false);
user_pref("browser.zoom.siteSpecific", false);
user_pref("capability.policy.maonoscript.javascript.enabled", "allAccess");
user_pref("capability.policy.maonoscript.sites", "addons.mozilla.org about: about:addons about:blank about:blocked about:certerror about:config about:crashes about:credits about:home about:neterror about:plugins about:privatebrowsing about:sessionrestore chrome: resource:");
user_pref("dom.event.contextmenu.enabled", false);
user_pref("dom.storage.enabled", false);
user_pref("extensions.bootstrappedAddons", "{}");
user_pref("extensions.bprivacy.DataDir", "/Users/erinn/Library/Preferences/Macromedia");
user_pref("extensions.bprivacy.donotaskforfolder", true);
user_pref("extensions.bprivacy.donotaskonexit", true);
user_pref("extensions.bprivacy.initiated", true);
user_pref("extensions.checkCompatibility.4.*", false);
user_pref("extensions.checkUpdateSecurity", true);
user_pref("extensions.databaseSchema", 3);
user_pref("extensions.enabledAddons", "https-everywhere@eff.org:0.9.9.development.4,{73a6fe31-595d-460b-a920-fcc0f8843232}:2.1.0.3,{d40f5e7b-d2cf-4856-b441-cc613eeffbe3}:1.50,{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.3.3-alpha");
user_pref("extensions.enabledItems", "langpack-en-US@firefox.mozilla.org:,{73a6fe31-595d-460b-a920-fcc0f8843232}:1.9.9.57,{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.4,{972ce4c6-7e08-4474-a285-3208198ce6fd}:3.5.8");
user_pref("extensions.enabledScopes", 1);
user_pref("extensions.pendingOperations", false);
user_pref("extensions.torbutton.fresh_install", false);
user_pref("extensions.torbutton.locked_mode", true);
user_pref("extensions.torbutton.proxies_applied", true);
user_pref("extensions.torbutton.restore_tor", true);
user_pref("extensions.torbutton.saved.auto_update", false);
user_pref("extensions.torbutton.saved.share_proxy_settings", false);
user_pref("extensions.torbutton.saved.socks_version", 5);
user_pref("extensions.torbutton.settings_applied", true);
user_pref("extensions.torbutton.socks_host", "127.0.0.1");
user_pref("extensions.torbutton.socks_port", 9050);
user_pref("extensions.torbutton.tor_enabled", true);
user_pref("extensions.torbutton.tor_memory_jar", true);
user_pref("extensions.torbutton.tz_string", "UTC+00:00");
user_pref("extensions.update.enabled", true);
user_pref("extensions.update.notifyUser", false);
user_pref("general.appname.override", "Netscape");
user_pref("general.appversion.override", "5.0 (Windows; en-US)");
user_pref("general.buildID.override", "0");
user_pref("general.oscpu.override", "Windows NT 6.1");
user_pref("general.platform.override", "Win32");
user_pref("general.productSub.override", "20100401");
user_pref("general.useragent.override", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3");
user_pref("general.useragent.vendor", "");
user_pref("general.useragent.vendorSub", "");
user_pref("geo.enabled", false);
user_pref("geo.wifi.uri", "");
user_pref("intl.accept_languages", "en-us, en");
user_pref("intl.charsetmenu.browser.cache", "UTF-8");
user_pref("network.cookie.cookieBehavior", 1);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("network.cookie.prefsMigrated", true);
user_pref("network.hosts.pop_server", "");
user_pref("network.protocol-handler.external-default", false);
user_pref("network.protocol-handler.external.mailto", false);
user_pref("network.protocol-handler.external.news", false);
user_pref("network.protocol-handler.external.nntp", false);
user_pref("network.protocol-handler.external.snews", false);
user_pref("network.protocol-handler.warn-external.mailto", true);
user_pref("network.protocol-handler.warn-external.news", true);
user_pref("network.protocol-handler.warn-external.nntp", true);
user_pref("network.protocol-handler.warn-external.snews", true);
user_pref("network.proxy.socks", "127.0.0.1");
user_pref("network.proxy.socks_port", 9050);
user_pref("network.proxy.socks_remote_dns", true);
user_pref("network.proxy.type", 1);
user_pref("network.security.ports.banned", "8118,8123,9050,9051");
user_pref("noscript.ABE.enabled", false);
user_pref("noscript.ABE.notify", false);
user_pref("noscript.ABE.wanIpAsLocal", false);
user_pref("noscript.autoReload", false);
user_pref("noscript.contentBlocker", true);
user_pref("noscript.default", "about:blank about:credits addons.mozilla.org flashgot.net google.com gstatic.com googlesyndication.com informaction.com yahoo.com yimg.com maone.net noscript.net hotmail.com msn.com passport.com passport.net passportimages.com live.com");
user_pref("noscript.firstRunRedirection", false);
user_pref("noscript.global", true);
user_pref("noscript.gtemp", "");
user_pref("noscript.opacizeObject", 3);
user_pref("noscript.forbidWebGL", true);
user_pref("noscript.options.tabSelectedIndexes", "5,0,0");
user_pref("noscript.policynames", "");
user_pref("noscript.secureCookies", true);
user_pref("noscript.showAllowPage", false);
user_pref("noscript.showBaseDomain", false);
user_pref("noscript.showDistrust", false);
user_pref("noscript.showRecentlyBlocked", false);
user_pref("noscript.showRevokeTemp", false);
user_pref("noscript.showTemp", false);
user_pref("noscript.showTempAllowPage", false);
user_pref("noscript.showTempToPerm", false);
user_pref("noscript.showUntrusted", false);
user_pref("noscript.subscription.lastCheck", -142148139);
user_pref("noscript.temp", "");
user_pref("noscript.untrusted", "");
user_pref("places.history.enabled", false);
user_pref("places.history.expiration.transient_current_max_pages", 120795);
user_pref("plugin.disable_full_page_plugin_for_types", "application/asx,video/x-ms-asf-plugin,application/x-mplayer2,video/x-ms-asf,video/x-ms-wm,audio/x-ms-wma,audio/x-ms-wax,video/x-ms-wmv,video/x-ms-wvx,application/x-drm-v2,application/x-drm");
user_pref("plugin.expose_full_path", true);
user_pref("plugin.scan.4xPluginFolder", false);
user_pref("plugin.scan.Acrobat", "99.0");
user_pref("plugin.scan.Quicktime", "99.0");
user_pref("plugin.scan.SunJRE", "99.0");
user_pref("plugin.scan.WindowsMediaPlayer", "99.0");
user_pref("plugin.scan.plid.all", false);
user_pref("privacy.sanitize.migrateFx3Prefs", true);
user_pref("security.enable_java", false);
user_pref("signon.rememberSignons", false);
user_pref("urlclassifier.keyupdatetime.https://sb-ssl.google.com/safebrowsing/newkey", 1235166825);
user_pref("urlclassifier.tableversion.goog-black-enchash", "1.55536");
user_pref("urlclassifier.tableversion.goog-black-url", "1.23256");
user_pref("urlclassifier.tableversion.goog-white-domain", "1.481");
user_pref("urlclassifier.tableversion.goog-white-url", "1.371");
user_pref("xpinstall.whitelist.add", "");
user_pref("xpinstall.whitelist.add.36", "");
<commit_msg>update prefs.js (closes: #3545, #3818, #3339)<commit_after># Mozilla User Preferences

/* Do not edit this file.
 *
 * If you make changes to this file while the application is running,
 * the changes will be overwritten when the application exits.
 *
 * To make a manual change to preferences, you can visit the URL about:config
 * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
 */

user_pref("app.update.auto", false);
user_pref("app.update.enabled", false);
user_pref("app.update.lastUpdateTime.addon-background-update-timer", 1216566538);
user_pref("app.update.lastUpdateTime.background-update-timer", 1216566535);
user_pref("app.update.lastUpdateTime.blocklist-background-update-timer", 1216566538);
user_pref("app.update.lastUpdateTime.microsummary-generator-update-timer", 1232574822);
user_pref("app.update.lastUpdateTime.search-engine-update-timer", 1216566539);
user_pref("browser.bookmarks.livemark_refresh_seconds", 31536000);
user_pref("browser.cache.disk.capacity", 0);
user_pref("browser.cache.disk.enable", false);
user_pref("browser.cache.disk.smart_size.enabled", false);
user_pref("browser.cache.disk.smart_size.first_run", false);
user_pref("browser.cache.offline.enable", false);
user_pref("browser.chrome.favicons", false);
user_pref("browser.chrome.image_icons.max_size", 0);
user_pref("browser.chrome.site_icons", false);
user_pref("browser.download.manager.retention", 1);
user_pref("browser.download.useDownloadDir", false);
user_pref("browser.formfill.enable", false);
user_pref("browser.history_expire_days.mirror", 0);
user_pref("browser.microsummary.updateGenerators", false);
user_pref("browser.migration.version", 5);
user_pref("browser.places.importBookmarksHTML", false);
user_pref("browser.places.importDefaults", false);
user_pref("browser.places.leftPaneFolderId", -1);
user_pref("browser.places.migratePostDataAnnotations", false);
user_pref("browser.places.smartBookmarksVersion", 2);
user_pref("browser.places.updateRecentTagsUri", false);
user_pref("browser.preferences.advanced.selectedTabIndex", 0);
user_pref("browser.privatebrowsing.autostart", false);
user_pref("browser.rights.3.shown", true);
user_pref("browser.safebrowsing.enabled", false);
user_pref("browser.safebrowsing.malware.enabled", false);
user_pref("browser.search.suggest.enabled", false);
user_pref("browser.search.update", false);
user_pref("browser.sessionstore.privacy_level", 2);
user_pref("browser.shell.checkDefaultBrowser", false);
user_pref("browser.startup.homepage", "https://check.torproject.org/?lang=en-US&small=1");
user_pref("browser.startup.homepage_override.buildID", "20110325121920");
user_pref("browser.startup.homepage_override.mstone", "rv:2.0");
user_pref("browser.urlbar.autocomplete.enabled", true);
user_pref("browser.zoom.siteSpecific", false);
user_pref("capability.policy.maonoscript.javascript.enabled", "allAccess");
user_pref("capability.policy.maonoscript.sites", "addons.mozilla.org about: about:addons about:blank about:blocked about:certerror about:config about:crashes about:credits about:home about:neterror about:plugins about:privatebrowsing about:sessionrestore chrome: resource:");
user_pref("dom.event.contextmenu.enabled", false);
user_pref("dom.storage.enabled", false);
user_pref("extensions.bootstrappedAddons", "{}");
user_pref("extensions.bprivacy.DataDir", "/Users/erinn/Library/Preferences/Macromedia");
user_pref("extensions.bprivacy.donotaskforfolder", true);
user_pref("extensions.bprivacy.donotaskonexit", true);
user_pref("extensions.bprivacy.initiated", true);
user_pref("extensions.checkCompatibility.4.*", false);
user_pref("extensions.checkUpdateSecurity", true);
user_pref("extensions.databaseSchema", 3);
user_pref("extensions.enabledAddons", "https-everywhere@eff.org:0.9.9.development.4,{73a6fe31-595d-460b-a920-fcc0f8843232}:2.1.0.3,{d40f5e7b-d2cf-4856-b441-cc613eeffbe3}:1.50,{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.3.3-alpha");
user_pref("extensions.enabledItems", "langpack-en-US@firefox.mozilla.org:,{73a6fe31-595d-460b-a920-fcc0f8843232}:1.9.9.57,{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.4,{972ce4c6-7e08-4474-a285-3208198ce6fd}:3.5.8");
user_pref("extensions.enabledScopes", 1);
user_pref("extensions.pendingOperations", false);
user_pref("extensions.torbutton.fresh_install", false);
user_pref("extensions.torbutton.locked_mode", true);
user_pref("extensions.torbutton.proxies_applied", true);
user_pref("extensions.torbutton.restore_tor", true);
user_pref("extensions.torbutton.saved.auto_update", false);
user_pref("extensions.torbutton.saved.share_proxy_settings", false);
user_pref("extensions.torbutton.saved.socks_version", 5);
user_pref("extensions.torbutton.settings_applied", true);
user_pref("extensions.torbutton.socks_host", "127.0.0.1");
user_pref("extensions.torbutton.socks_port", 9050);
user_pref("extensions.torbutton.tor_enabled", true);
user_pref("extensions.torbutton.tor_memory_jar", true);
user_pref("extensions.torbutton.tz_string", "UTC+00:00");
user_pref("extensions.update.enabled", true);
user_pref("extensions.update.notifyUser", false);
user_pref("general.appname.override", "Netscape");
user_pref("general.appversion.override", "5.0 (Windows; en-US)");
user_pref("general.buildID.override", "0");
user_pref("general.oscpu.override", "Windows NT 6.1");
user_pref("general.platform.override", "Win32");
user_pref("general.productSub.override", "20100401");
user_pref("general.useragent.override", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3");
user_pref("general.useragent.vendor", "");
user_pref("general.useragent.vendorSub", "");
user_pref("geo.enabled", false);
user_pref("geo.wifi.uri", "");
user_pref("intl.accept_languages", "en-us, en");
user_pref("intl.charsetmenu.browser.cache", "UTF-8");
user_pref("network.cookie.cookieBehavior", 1);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("network.cookie.prefsMigrated", true);
user_pref("network.hosts.pop_server", "");
user_pref("network.protocol-handler.external-default", false);
user_pref("network.protocol-handler.external.mailto", false);
user_pref("network.protocol-handler.external.news", false);
user_pref("network.protocol-handler.external.nntp", false);
user_pref("network.protocol-handler.external.snews", false);
user_pref("network.protocol-handler.warn-external.mailto", true);
user_pref("network.protocol-handler.warn-external.news", true);
user_pref("network.protocol-handler.warn-external.nntp", true);
user_pref("network.protocol-handler.warn-external.snews", true);
user_pref("network.proxy.socks", "127.0.0.1");
user_pref("network.proxy.socks_port", 9050);
user_pref("network.proxy.socks_remote_dns", true);
user_pref("network.proxy.type", 1);
user_pref("network.security.ports.banned", "8118,8123,9050,9051");
user_pref("noscript.ABE.enabled", false);
user_pref("noscript.ABE.notify", false);
user_pref("noscript.ABE.wanIpAsLocal", false);
user_pref("noscript.autoReload", false);
user_pref("noscript.contentBlocker", true);
user_pref("noscript.default", "about:blank about:credits addons.mozilla.org flashgot.net google.com gstatic.com googlesyndication.com informaction.com yahoo.com yimg.com maone.net noscript.net hotmail.com msn.com passport.com passport.net passportimages.com live.com");
user_pref("noscript.firstRunRedirection", false);
user_pref("noscript.global", true);
user_pref("noscript.gtemp", "");
user_pref("noscript.opacizeObject", 3);
user_pref("noscript.forbidWebGL", true);
user_pref("noscript.options.tabSelectedIndexes", "5,0,0");
user_pref("noscript.policynames", "");
user_pref("noscript.secureCookies", true);
user_pref("noscript.showAllowPage", false);
user_pref("noscript.showBaseDomain", false);
user_pref("noscript.showDistrust", false);
user_pref("noscript.showRecentlyBlocked", false);
user_pref("noscript.showRevokeTemp", false);
user_pref("noscript.showTemp", false);
user_pref("noscript.showTempAllowPage", false);
user_pref("noscript.showTempToPerm", false);
user_pref("noscript.showUntrusted", false);
user_pref("noscript.STS.enabled", false);
user_pref("noscript.subscription.lastCheck", -142148139);
user_pref("noscript.temp", "");
user_pref("noscript.untrusted", "");
user_pref("places.history.enabled", false);
user_pref("places.history.expiration.transient_current_max_pages", 120795);
user_pref("plugin.disable_full_page_plugin_for_types", "application/asx,video/x-ms-asf-plugin,application/x-mplayer2,video/x-ms-asf,video/x-ms-wm,audio/x-ms-wma,audio/x-ms-wax,video/x-ms-wmv,video/x-ms-wvx,application/x-drm-v2,application/x-drm");
user_pref("plugin.expose_full_path", true);
user_pref("plugin.scan.4xPluginFolder", false);
user_pref("plugin.scan.Acrobat", "99.0");
user_pref("plugin.scan.Quicktime", "99.0");
user_pref("plugin.scan.SunJRE", "99.0");
user_pref("plugin.scan.WindowsMediaPlayer", "99.0");
user_pref("plugin.scan.plid.all", false);
user_pref("privacy.sanitize.migrateFx3Prefs", true);
user_pref("security.enable_java", false);
user_pref("signon.rememberSignons", false);
user_pref("urlclassifier.keyupdatetime.https://sb-ssl.google.com/safebrowsing/newkey", 1235166825);
user_pref("urlclassifier.tableversion.goog-black-enchash", "1.55536");
user_pref("urlclassifier.tableversion.goog-black-url", "1.23256");
user_pref("urlclassifier.tableversion.goog-white-domain", "1.481");
user_pref("urlclassifier.tableversion.goog-white-url", "1.371");
user_pref("xpinstall.whitelist.add", "");
user_pref("xpinstall.whitelist.add.36", "");
<|endoftext|>


<commit_before>//Author: Ribo Mo
(function ($) {
    "use strict";

    var GRID_WIDTH = 200;

    $.fn.nestedGrid = function (options) {
        $.fn.nestedGrid.Options = $.extend($.fn.nestedGrid.defaultOptions, options);
        this.each(function () {
            var $table = $(this);
            setGrid($table, options);
        });
    };

    // Provide default options for plugin
    $.fn.nestedGrid.defaultOptions = {
        ajax: {
            method: "post",
            dataType: "json"
        }
    };

    // Reload the grid
    $.fn.nestedGrid.reloadGrid = function ($container) {
        var data = $container.children().data("data");
        var fields = $container.children().data("fields");
        var tableName = $container.children().data("table");
        var newGrid = new Grid(data, fields, tableName);
        $container.html(newGrid.$grid);
    };

    // Pass in selector and this function will make it a grid!
    var setGrid = function ($table, userSettings) {
        var options = $.fn.nestedGrid.Options;

        // generate from AJAX
        if (!options.data) {
            var request = $.ajax(options.ajax);
            return request.success(function (result) {
                var grid = new Grid(result.data, result.fields, result.tableName);
                $table.html(grid.$grid);
            });
        }
        else {
            var grid = new Grid(userSettings.data, userSettings.fields, userSettings.tableName);
            $table.html(grid.$grid);
        }
    };

    function Grid(data, fields, tableName) {
        this.data = data;
        this.fields = fields;
        this.tableName = tableName;
        this.$grid = null;
        this.init();
    }

    Grid.prototype = {
        init: function () {
            this.$grid = $("<table>");
            this.$grid.append(this.createHeader());
            this.$grid.append(this.createBody());
            this.$grid.addClass("nestedGrid");
            this.$grid.data("table", this.tableName);
            this.$grid.data("data", this.data);
            this.$grid.data("fields", this.fields);
        },

        createHeader: function () {
            var fields = showTopLevelFields(this.fields);
            var $fieldData = [];
            $fieldData.push($("<th>"));
            for (var i = 0; i < fields.length; i++) {
                var $field = $("<th>").append(fields[i]);
                $field.width(GRID_WIDTH);
                $fieldData.push($field);
            }
            $fieldData.push($("<th>").append("action"));
            return $("<thead><tr>").append($fieldData);
        },

        createBody: function () {
            var rows = [];
            for (var i = 0; i < this.data.length; i++) {
                var row = new Row(this.data[i], this.fields, this.$grid);

                // Add Strap
                if (i % 2 == 0) {
                    row.$row.addClass("odd-row");
                } else {
                    row.$row.addClass("even-row");
                }
                rows = rows.concat(rows, row.getRow());
            }
            return $("<tbody>").append(rows);
        }

    };

    // Constructor for Row
    function Row(data, fields, $grid) {
        this.data = data;
        this.fields = fields;
        this.$grid = $grid;
        this.$row = null;
        this.topLevelFields = null;
        this.$subgrid = null;
        this.init();
    }

    Row.prototype = {
        init: function () {
            this.$row = $("<tr>");
            this.topLevelFields = showTopLevelFields(this.fields);
            this.createRow();
        },

        //Return $row selector and $subgrid selector
        getRow: function () {
            var result = [];
            result.push(this.$row);
            if (this.$subgrid) {
                result.push(this.$subgrid);
            }
            return result;
        },

        createRow: function () {
            var $rowData = [];
            var $subgridTrigger = this.createSubgridTrigger();
            $rowData.push($subgridTrigger);
            $rowData = $rowData.concat(this.createCells());
            $rowData.push(this.createSaveDeleteField());
            this.$row.append($rowData);

            // Event delegation
            this.$row.on("click", ".save-link", this.editEvent().saveClickEvent);
            this.$row.on("click", ".delete-link", this.editEvent().deleteClickEvent);
            this.$row.on("click", ".text-field", this.editRow);
            //this.$row.on("click", ".text-field", this.fieldClickEvent());

            // Add subgrid
            if (this.isSubgridExist()) {
                this.$subgrid = this.createSubgrid();
                var that = this;
                this.$row.on("click", ".subgrid-trigger", function () {
                    that.$subgrid.fadeToggle();
                    var $this = $(this);
                    if ($this.hasClass("expand")) {
                        $this.removeClass("expand");
                        $this.addClass("collapse");
                    }
                    else {
                        $this.removeClass("collapse");
                        $this.addClass("expand");
                    }
                });
            }
        },

        // Add subgrid to existing grid
        createSubgrid: function () {
            var that = this;
            var subgridInfo = function (fields) {
                var result = {
                    fields: [],
                    table: []
                };
                for (var i = 0; i < fields.length; i++) {
                    if (fields[i].indexOf(".") !== -1) {
                        var data = fields[i].split(".");
                        result["fields"].push(data[1]);
                        if (result["table"].indexOf(data[0]) === -1) {
                            result["table"] = data[0];
                        }
                    }
                }
                return result;
            }(this.fields);
            var maxCol = function () {
                var maxCol = 0;
                that.$row.find('td').each(function () {
                    maxCol += 1;
                });
                return maxCol;
            }();
            var subgridData = this.data[this.getSubgridName()[0]];
            var subgrid = new Grid(subgridData, subgridInfo.fields, subgridInfo.table);
            subgrid.$grid.addClass("subgrid");
            var $insertCell = $("<td>").append(subgrid.$grid).attr("colspan", maxCol);
            var $insertRow = $("<tr>").append($insertCell).addClass("collapse");
            $insertRow.hide();
            return $insertRow;
        },

        // Return all the data contain in the fields
        createCells: function () {
            var fields = this.topLevelFields;
            var $result = [];
            for (var i = 0; i < fields.length; i++) {
                var $fieldData = $("<td>").append(this.data[fields[i]]).addClass("text-field");
                $result.push($fieldData);
            }
            return $result;
        },

        // Event handlers for save and delete
        fieldClickEvent: function () {
            //Change normal field to text box which allows user to edit.
            var changeField2TextBox = function changeField2TextBox($field) {
                var text = $field.text();
                var $textBox = $("<input>").attr("type", "text").attr("value", text).css("width", "95%");
                $field.text('').append($textBox);
                $field.focusout(function () {
                    var text = $textBox.val();
                    $textBox.parent().text(text);
                    $textBox.remove();
                });
                $textBox.select();
            };
            return function () {
                if (($(this)).has("input").length === 0) {
                    changeField2TextBox($(this));
                }
            };
        },

        // Allow user to edit data in the row
        editRow: function () {
            var removeEditing = function(){
                $(this).find(".text-field").each(function () {
                    var textBox = $(this).find("input");
                    $(this).text(textBox.val());
                    textBox.remove();
                });
                $(this).removeClass("editing");
            };

            var $row = $(this).parent();

            if ($row.hasClass("editing")) {
            } else {
                // If there's another row in editing status, cancel the editing state.
                // Make sure editing row is unique.
                var $grid = $row.parent().parent();
                var $editingRows = $grid.find(".editing");
                if ($editingRows.length !== 0) {
                    $editingRows.each(removeEditing);
                    $("html").off("click");
                }

                // Replace text with input
                $row.find(".text-field").each(function () {
                    if (($(this)).has("input").length === 0) {
                        $row.addClass("editing");
                        var text = $(this).text();
                        var $textBox = $("<input>").attr("type", "text").attr("value", text);
                        $(this).text('').append($textBox);
                    }
                });

                // When user clicked elsewhere, remove editing status.
                $("html").click(function (event) {
                    if (!$(event.target).closest(".nestedGrid").length && !$(event.target).is(".nestedGrid")) {
                        removeEditing.bind(this)();
                        console.log("lalla");
                        $("html").off("click");
                    }
                });
            }
        },

        // Add trigger
        createSubgridTrigger: function () {
            if (this.isSubgridExist()) {
                var $expand = $("<div>").addClass("subgrid-trigger").addClass("expand");
                return $("<td>").append($expand);
            }
            else {
                return $("<td>");
            }
        },

        createSaveDeleteField: function () {
            var $editField = $("<td>");
            var $save = $("<a>").append("save").attr("href", "#").addClass("save-link");
            var $delete = $("<a>").append("delete").attr("href", "#").addClass("delete-link");
            $editField.append($save).append(" ").append($delete);
            return $editField;
        },

        // Event Handlers for edit and delete button
        editEvent: function () {
            var that = this;
            var getData = function () {
                var obj = {};
                var i = 0;
                that.$row.find("td.data").each(function () {
                    obj[that.topLevelFields[i]] = $(this).text();
                    i++;
                });
                return obj;
            };
            var getTableName = function () {
                return that.$row.parent().parent().data("table");
            };
            var options = $.fn.nestedGrid.Options;
            return {
                saveClickEvent: function () {
                    var newData = getData();
                    var object = {
                        purpose: "edit",
                        tableName: getTableName(),
                        new: newData,
                        old: that.data
                    };
                    console.log(object.new);
                    console.log(object.old);
                    //Pass data to server
                    $.ajax({
                        method: "post",
                        url: options.ajax.url,
                        dataType: "json",
                        data: JSON.stringify(object)
                    });
                    that.reloadRow();
                },
                deleteClickEvent: function () {
                    var object = {
                        purpose: "delete",
                        tableName: getTableName(),
                        old: that.data
                    };
                    console.log(object.old);
                    that.$row.remove();
                    $.ajax({
                        method: "post",
                        url: options.ajax.url,
                        dataType: "json",
                        data: JSON.stringify(object)
                    });
                    $.fn.nestedGrid.reloadGrid(that.$grid.parent());
                }
            }
        },

        getSubgridName: function () {
            var result = [];
            for (var i = 0; i < this.fields.length; i++) {
                if (this.fields[i].indexOf(".") !== -1) {
                    var data = this.fields[i].split(".");
                    if (result.indexOf(data[0]) === -1) {
                        result.push(data[0]);
                    }
                }
            }
            return result;
        },

        isSubgridExist: function () {
            return this.data[this.getSubgridName()[0]] !== undefined;
        },

        reloadRow: function () {
            var row = new Row(this.data, this.fields, this.$grid);
            this.$row.html(row.$row.html());
            this.$subgrid.html(row.$subgrid.html());
        }
    };

    $.fn.nestedGrid.reloadGrid = function ($container) {
        var data = $container.children().data("data");
        var fields = $container.children().data("fields");
        var tableName = $container.children().data("table");
        var newGrid = new Grid(data, fields, tableName);
        $container.html(newGrid.$grid);
    };

    //Only show fields that are in top level
    function showTopLevelFields(fields) {
        var result = [];
        for (var i = 0; i < fields.length; i++) {
            if (fields[i].indexOf(".") === -1) {
                result.push(fields[i]);
            }
        }
        return result;
    }
}(jQuery));<commit_msg>Remove console log<commit_after>//Author: Ribo Mo
(function ($) {
    "use strict";

    var GRID_WIDTH = 200;

    $.fn.nestedGrid = function (options) {
        $.fn.nestedGrid.Options = $.extend($.fn.nestedGrid.defaultOptions, options);
        this.each(function () {
            var $table = $(this);
            setGrid($table, options);
        });
    };

    // Provide default options for plugin
    $.fn.nestedGrid.defaultOptions = {
        ajax: {
            method: "post",
            dataType: "json"
        }
    };

    // Reload the grid
    $.fn.nestedGrid.reloadGrid = function ($container) {
        var data = $container.children().data("data");
        var fields = $container.children().data("fields");
        var tableName = $container.children().data("table");
        var newGrid = new Grid(data, fields, tableName);
        $container.html(newGrid.$grid);
    };

    // Pass in selector and this function will make it a grid!
    var setGrid = function ($table, userSettings) {
        var options = $.fn.nestedGrid.Options;

        // generate from AJAX
        if (!options.data) {
            var request = $.ajax(options.ajax);
            return request.success(function (result) {
                var grid = new Grid(result.data, result.fields, result.tableName);
                $table.html(grid.$grid);
            });
        }
        else {
            var grid = new Grid(userSettings.data, userSettings.fields, userSettings.tableName);
            $table.html(grid.$grid);
        }
    };

    function Grid(data, fields, tableName) {
        this.data = data;
        this.fields = fields;
        this.tableName = tableName;
        this.$grid = null;
        this.init();
    }

    Grid.prototype = {
        init: function () {
            this.$grid = $("<table>");
            this.$grid.append(this.createHeader());
            this.$grid.append(this.createBody());
            this.$grid.addClass("nestedGrid");
            this.$grid.data("table", this.tableName);
            this.$grid.data("data", this.data);
            this.$grid.data("fields", this.fields);
        },

        createHeader: function () {
            var fields = showTopLevelFields(this.fields);
            var $fieldData = [];
            $fieldData.push($("<th>"));
            for (var i = 0; i < fields.length; i++) {
                var $field = $("<th>").append(fields[i]);
                $field.width(GRID_WIDTH);
                $fieldData.push($field);
            }
            $fieldData.push($("<th>").append("action"));
            return $("<thead><tr>").append($fieldData);
        },

        createBody: function () {
            var rows = [];
            for (var i = 0; i < this.data.length; i++) {
                var row = new Row(this.data[i], this.fields, this.$grid);

                // Add Strap
                if (i % 2 == 0) {
                    row.$row.addClass("odd-row");
                } else {
                    row.$row.addClass("even-row");
                }
                rows = rows.concat(rows, row.getRow());
            }
            return $("<tbody>").append(rows);
        }

    };

    // Constructor for Row
    function Row(data, fields, $grid) {
        this.data = data;
        this.fields = fields;
        this.$grid = $grid;
        this.$row = null;
        this.topLevelFields = null;
        this.$subgrid = null;
        this.init();
    }

    Row.prototype = {
        init: function () {
            this.$row = $("<tr>");
            this.topLevelFields = showTopLevelFields(this.fields);
            this.createRow();
        },

        //Return $row selector and $subgrid selector
        getRow: function () {
            var result = [];
            result.push(this.$row);
            if (this.$subgrid) {
                result.push(this.$subgrid);
            }
            return result;
        },

        createRow: function () {
            var $rowData = [];
            var $subgridTrigger = this.createSubgridTrigger();
            $rowData.push($subgridTrigger);
            $rowData = $rowData.concat(this.createCells());
            $rowData.push(this.createSaveDeleteField());
            this.$row.append($rowData);

            // Event delegation
            this.$row.on("click", ".save-link", this.editEvent().saveClickEvent);
            this.$row.on("click", ".delete-link", this.editEvent().deleteClickEvent);
            this.$row.on("click", ".text-field", this.editRow);
            //this.$row.on("click", ".text-field", this.fieldClickEvent());

            // Add subgrid
            if (this.isSubgridExist()) {
                this.$subgrid = this.createSubgrid();
                var that = this;
                this.$row.on("click", ".subgrid-trigger", function () {
                    that.$subgrid.fadeToggle();
                    var $this = $(this);
                    if ($this.hasClass("expand")) {
                        $this.removeClass("expand");
                        $this.addClass("collapse");
                    }
                    else {
                        $this.removeClass("collapse");
                        $this.addClass("expand");
                    }
                });
            }
        },

        // Add subgrid to existing grid
        createSubgrid: function () {
            var that = this;
            var subgridInfo = function (fields) {
                var result = {
                    fields: [],
                    table: []
                };
                for (var i = 0; i < fields.length; i++) {
                    if (fields[i].indexOf(".") !== -1) {
                        var data = fields[i].split(".");
                        result["fields"].push(data[1]);
                        if (result["table"].indexOf(data[0]) === -1) {
                            result["table"] = data[0];
                        }
                    }
                }
                return result;
            }(this.fields);
            var maxCol = function () {
                var maxCol = 0;
                that.$row.find('td').each(function () {
                    maxCol += 1;
                });
                return maxCol;
            }();
            var subgridData = this.data[this.getSubgridName()[0]];
            var subgrid = new Grid(subgridData, subgridInfo.fields, subgridInfo.table);
            subgrid.$grid.addClass("subgrid");
            var $insertCell = $("<td>").append(subgrid.$grid).attr("colspan", maxCol);
            var $insertRow = $("<tr>").append($insertCell).addClass("collapse");
            $insertRow.hide();
            return $insertRow;
        },

        // Return all the data contain in the fields
        createCells: function () {
            var fields = this.topLevelFields;
            var $result = [];
            for (var i = 0; i < fields.length; i++) {
                var $fieldData = $("<td>").append(this.data[fields[i]]).addClass("text-field");
                $result.push($fieldData);
            }
            return $result;
        },

        // Event handlers for save and delete
        fieldClickEvent: function () {
            //Change normal field to text box which allows user to edit.
            var changeField2TextBox = function changeField2TextBox($field) {
                var text = $field.text();
                var $textBox = $("<input>").attr("type", "text").attr("value", text).css("width", "95%");
                $field.text('').append($textBox);
                $field.focusout(function () {
                    var text = $textBox.val();
                    $textBox.parent().text(text);
                    $textBox.remove();
                });
                $textBox.select();
            };
            return function () {
                if (($(this)).has("input").length === 0) {
                    changeField2TextBox($(this));
                }
            };
        },

        // Allow user to edit data in the row
        editRow: function () {
            var removeEditing = function(){
                $(this).find(".text-field").each(function () {
                    var textBox = $(this).find("input");
                    $(this).text(textBox.val());
                    textBox.remove();
                });
                $(this).removeClass("editing");
            };

            var $row = $(this).parent();

            if ($row.hasClass("editing")) {
            } else {
                // If there's another row in editing status, cancel the editing state.
                // Make sure editing row is unique.
                var $grid = $row.parent().parent();
                var $editingRows = $grid.find(".editing");
                if ($editingRows.length !== 0) {
                    $editingRows.each(removeEditing);
                    $("html").off("click");
                }

                // Replace text with input
                $row.find(".text-field").each(function () {
                    if (($(this)).has("input").length === 0) {
                        $row.addClass("editing");
                        var text = $(this).text();
                        var $textBox = $("<input>").attr("type", "text").attr("value", text);
                        $(this).text('').append($textBox);
                    }
                });

                // When user clicked elsewhere, remove editing status.
                $("html").click(function (event) {
                    if (!$(event.target).closest(".nestedGrid").length && !$(event.target).is(".nestedGrid")) {
                        removeEditing.bind(this)();
                        $("html").off("click");
                    }
                });
            }
        },

        // Add trigger
        createSubgridTrigger: function () {
            if (this.isSubgridExist()) {
                var $expand = $("<div>").addClass("subgrid-trigger").addClass("expand");
                return $("<td>").append($expand);
            }
            else {
                return $("<td>");
            }
        },

        createSaveDeleteField: function () {
            var $editField = $("<td>");
            var $save = $("<a>").append("save").attr("href", "#").addClass("save-link");
            var $delete = $("<a>").append("delete").attr("href", "#").addClass("delete-link");
            $editField.append($save).append(" ").append($delete);
            return $editField;
        },

        // Event Handlers for edit and delete button
        editEvent: function () {
            var that = this;
            var getData = function () {
                var obj = {};
                var i = 0;
                that.$row.find("td.data").each(function () {
                    obj[that.topLevelFields[i]] = $(this).text();
                    i++;
                });
                return obj;
            };
            var getTableName = function () {
                return that.$row.parent().parent().data("table");
            };
            var options = $.fn.nestedGrid.Options;
            return {
                saveClickEvent: function () {
                    var newData = getData();
                    var object = {
                        purpose: "edit",
                        tableName: getTableName(),
                        new: newData,
                        old: that.data
                    };
                    console.log(object.new);
                    console.log(object.old);
                    //Pass data to server
                    $.ajax({
                        method: "post",
                        url: options.ajax.url,
                        dataType: "json",
                        data: JSON.stringify(object)
                    });
                    that.reloadRow();
                },
                deleteClickEvent: function () {
                    var object = {
                        purpose: "delete",
                        tableName: getTableName(),
                        old: that.data
                    };
                    console.log(object.old);
                    that.$row.remove();
                    $.ajax({
                        method: "post",
                        url: options.ajax.url,
                        dataType: "json",
                        data: JSON.stringify(object)
                    });
                    $.fn.nestedGrid.reloadGrid(that.$grid.parent());
                }
            }
        },

        getSubgridName: function () {
            var result = [];
            for (var i = 0; i < this.fields.length; i++) {
                if (this.fields[i].indexOf(".") !== -1) {
                    var data = this.fields[i].split(".");
                    if (result.indexOf(data[0]) === -1) {
                        result.push(data[0]);
                    }
                }
            }
            return result;
        },

        isSubgridExist: function () {
            return this.data[this.getSubgridName()[0]] !== undefined;
        },

        reloadRow: function () {
            var row = new Row(this.data, this.fields, this.$grid);
            this.$row.html(row.$row.html());
            this.$subgrid.html(row.$subgrid.html());
        }
    };

    $.fn.nestedGrid.reloadGrid = function ($container) {
        var data = $container.children().data("data");
        var fields = $container.children().data("fields");
        var tableName = $container.children().data("table");
        var newGrid = new Grid(data, fields, tableName);
        $container.html(newGrid.$grid);
    };

    //Only show fields that are in top level
    function showTopLevelFields(fields) {
        var result = [];
        for (var i = 0; i < fields.length; i++) {
            if (fields[i].indexOf(".") === -1) {
                result.push(fields[i]);
            }
        }
        return result;
    }
}(jQuery));<|endoftext|>


<commit_before>/*
Copyright (C) 2010, Oleg Efimov <efimovov@gmail.com>

See license text in LICENSE file
*/

// Require modules
var
  sys = require('sys'),
  mysql = require('../deps/Sannis-node-mysql-libmysqlclient/mysql-libmysqlclient'),
  conn;

/*function fetchAllAsyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    factor = cfg.do_not_run_sync_if_async_exists ? 1 : 2,
    res,
    rows;

  start_time = new Date();

  res = conn.querySync("SELECT * FROM " + cfg.test_table + ";");

  res.fetchAll(function (err, rows) {
    //res.freeSync();

    total_time = ((new Date()) - start_time) / 1000;
    sys.puts("**** " + (factor * cfg.insert_rows_count) + " rows async (fetchAll) selected in " + total_time + "s (" + Math.round(factor * cfg.insert_rows_count / total_time) + "/s)");

    // Finish benchmark
    conn.closeSync();
    callback.apply();
  });
}*/

function fetchObjectLoopSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    factor = cfg.do_not_run_sync_if_async_exists ? 1 : 2,
    res,
    row,
    rows = [];

  start_time = new Date();

  res = conn.querySync("SELECT * FROM " + cfg.test_table + ";");

  while ((row = res.fetchObjectSync())) {
    rows.push(row);
  }

  res.freeSync();

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + (factor * cfg.insert_rows_count) + " rows sync (fetchObject in loop) selected in " + total_time + "s (" + Math.round(factor * cfg.insert_rows_count / total_time) + "/s)");

  //fetchAllAsyncBenchmark(callback, cfg);
  // Finish benchmark
  conn.closeSync();
  callback.apply();
}

function fetchAllSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    factor = cfg.do_not_run_sync_if_async_exists ? 1 : 2,
    res,
    rows;

  start_time = new Date();

  res = conn.querySync("SELECT * FROM " + cfg.test_table + ";");

  rows = res.fetchAllSync();

  res.freeSync();

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + (factor * cfg.insert_rows_count) + " rows sync (fetchAll) selected in " + total_time + "s (" + Math.round(factor * cfg.insert_rows_count / total_time) + "/s)");

  fetchObjectLoopSyncBenchmark(callback, cfg);
}

function insertAsyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0;

  start_time = new Date();

  function insertAsync() {
    i += 1;
    if (i <= cfg.insert_rows_count) {
      conn.query(cfg.insert_query, function (res) {
        insertAsync();
      });
    } else {
      total_time = ((new Date()) - start_time) / 1000;
      sys.puts("**** " + cfg.insert_rows_count + " async insertions in " + total_time + "s (" + Math.round(cfg.insert_rows_count / total_time) + "/s)");

      setTimeout(function () {
        fetchAllSyncBenchmark(callback, cfg);
      }, cfg.delay_before_select);
    }
  }

  insertAsync();
}

function insertSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0,
    res;

  start_time = new Date();

  for (i = 0; i < cfg.insert_rows_count; i += 1) {
    res = conn.querySync(cfg.insert_query);
  }

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + cfg.insert_rows_count + " sync insertions in " + total_time + "s (" + Math.round(cfg.insert_rows_count / total_time) + "/s)");

  insertAsyncBenchmark(callback, cfg);
}

function reconnectSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0;

  start_time = new Date();

  for (i = 0; i < cfg.reconnect_count; i += 1) {
    conn.closeSync();
    conn.connectSync(cfg.host, cfg.user, cfg.password, cfg.database);
  }

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + cfg.reconnect_count + " sync reconnects in " + total_time + "s (" + Math.round(cfg.reconnect_count / total_time) + "/s)");

  if (cfg.do_not_run_sync_if_async_exists) {
    insertAsyncBenchmark(callback, cfg);
  } else {
    insertSyncBenchmark(callback, cfg);
  }
}

function escapeBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0,
    escaped_string;

  start_time = new Date();

  for (i = 0; i < cfg.escape_count; i += 1) {
    escaped_string = conn.escapeSync(cfg.string_to_escape);
  }

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + cfg.escape_count + " escapes in " + total_time + "s (" + Math.round(cfg.escape_count / total_time) + "/s)");

  reconnectSyncBenchmark(callback, cfg);
}

function startBenchmark(callback, cfg) {
  var
    start_time,
    total_time;

  start_time = new Date();

  conn = mysql.createConnectionSync();
  conn.connectSync(cfg.host, cfg.user, cfg.password, cfg.database);

  conn.querySync("DROP TABLE IF EXISTS " + cfg.test_table + ";");
  conn.querySync(cfg.create_table_query);

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** Benchmark initialization time is " + total_time + "s");

  escapeBenchmark(callback, cfg);
}

exports.run = function (callback, cfg) {
  startBenchmark(callback, cfg);
};

<commit_msg>Add half-async reconnect benchmark for Sannis/node-mysql-libmysqlclient<commit_after>/*
Copyright (C) 2010, Oleg Efimov <efimovov@gmail.com>

See license text in LICENSE file
*/

// Require modules
var
  sys = require('sys'),
  mysql = require('../deps/Sannis-node-mysql-libmysqlclient/mysql-libmysqlclient'),
  conn;

/*function fetchAllAsyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    factor = cfg.do_not_run_sync_if_async_exists ? 1 : 2,
    res,
    rows;

  start_time = new Date();

  res = conn.querySync("SELECT * FROM " + cfg.test_table + ";");

  res.fetchAll(function (err, rows) {
    //res.freeSync();

    total_time = ((new Date()) - start_time) / 1000;
    sys.puts("**** " + (factor * cfg.insert_rows_count) + " rows async (fetchAll) selected in " + total_time + "s (" + Math.round(factor * cfg.insert_rows_count / total_time) + "/s)");

    // Finish benchmark
    conn.closeSync();
    callback.apply();
  });
}*/

function fetchObjectLoopSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    factor = cfg.do_not_run_sync_if_async_exists ? 1 : 2,
    res,
    row,
    rows = [];

  start_time = new Date();

  res = conn.querySync("SELECT * FROM " + cfg.test_table + ";");

  while ((row = res.fetchObjectSync())) {
    rows.push(row);
  }

  res.freeSync();

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + (factor * cfg.insert_rows_count) + " rows sync (fetchObject in loop) selected in " + total_time + "s (" + Math.round(factor * cfg.insert_rows_count / total_time) + "/s)");

  //fetchAllAsyncBenchmark(callback, cfg);
  // Finish benchmark
  conn.closeSync();
  callback.apply();
}

function fetchAllSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    factor = cfg.do_not_run_sync_if_async_exists ? 1 : 2,
    res,
    rows;

  start_time = new Date();

  res = conn.querySync("SELECT * FROM " + cfg.test_table + ";");

  rows = res.fetchAllSync();

  res.freeSync();

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + (factor * cfg.insert_rows_count) + " rows sync (fetchAll) selected in " + total_time + "s (" + Math.round(factor * cfg.insert_rows_count / total_time) + "/s)");

  fetchObjectLoopSyncBenchmark(callback, cfg);
}

function insertAsyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0;

  start_time = new Date();

  function insertAsync() {
    i += 1;
    if (i <= cfg.insert_rows_count) {
      conn.query(cfg.insert_query, function (res) {
        insertAsync();
      });
    } else {
      total_time = ((new Date()) - start_time) / 1000;
      sys.puts("**** " + cfg.insert_rows_count + " async insertions in " + total_time + "s (" + Math.round(cfg.insert_rows_count / total_time) + "/s)");

      setTimeout(function () {
        fetchAllSyncBenchmark(callback, cfg);
      }, cfg.delay_before_select);
    }
  }

  insertAsync();
}

function insertSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0,
    res;

  start_time = new Date();

  for (i = 0; i < cfg.insert_rows_count; i += 1) {
    res = conn.querySync(cfg.insert_query);
  }

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + cfg.insert_rows_count + " sync insertions in " + total_time + "s (" + Math.round(cfg.insert_rows_count / total_time) + "/s)");

  insertAsyncBenchmark(callback, cfg);
}

function reconnectHalfAsyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0;

    start_time = new Date();

    function reconnectAsync() {
      i += 1;
      if (i <= cfg.reconnect_count) {
        conn.closeSync();
        conn.connect(cfg.host, cfg.user, cfg.password, cfg.database, function (err, result) {
          reconnectAsync();
        });
      } else {
        total_time = ((new Date()) - start_time) / 1000;
        sys.puts("**** " + cfg.reconnect_count + " half-async reconnects in " + total_time + "s (" + Math.round(cfg.reconnect_count / total_time) + "/s)");

        if (cfg.do_not_run_sync_if_async_exists) {
          insertAsyncBenchmark(callback, cfg);
        } else {
          insertSyncBenchmark(callback, cfg);
        }
      }
    }

    reconnectAsync();
}

function reconnectSyncBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0;

  start_time = new Date();

  for (i = 0; i < cfg.reconnect_count; i += 1) {
    conn.closeSync();
    conn.connectSync(cfg.host, cfg.user, cfg.password, cfg.database);
  }

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + cfg.reconnect_count + " sync reconnects in " + total_time + "s (" + Math.round(cfg.reconnect_count / total_time) + "/s)");

  reconnectHalfAsyncBenchmark(callback, cfg);
}

function escapeBenchmark(callback, cfg) {
  var
    start_time,
    total_time,
    i = 0,
    escaped_string;

  start_time = new Date();

  for (i = 0; i < cfg.escape_count; i += 1) {
    escaped_string = conn.escapeSync(cfg.string_to_escape);
  }

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** " + cfg.escape_count + " escapes in " + total_time + "s (" + Math.round(cfg.escape_count / total_time) + "/s)");

  reconnectSyncBenchmark(callback, cfg);
}

function startBenchmark(callback, cfg) {
  var
    start_time,
    total_time;

  start_time = new Date();

  conn = mysql.createConnectionSync();
  conn.connectSync(cfg.host, cfg.user, cfg.password, cfg.database);

  conn.querySync("DROP TABLE IF EXISTS " + cfg.test_table + ";");
  conn.querySync(cfg.create_table_query);

  total_time = ((new Date()) - start_time) / 1000;
  sys.puts("**** Benchmark initialization time is " + total_time + "s");

  escapeBenchmark(callback, cfg);
}

exports.run = function (callback, cfg) {
  startBenchmark(callback, cfg);
};

<|endoftext|>


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

var expect = require('chai').expect;
var MemoryFS = require('memory-fs');

var LevelDbSerializer = require('../../lib/cache-serializers').LevelDbSerializer;
var mkdirp = require('mkdirp');
var Promise = require('bluebird');
var rimraf = require('rimraf');
var webpack = require('webpack');

function wrapModule(code) {
  return '(function(exports, require, module, __filename, __dirname) {' +
    code +
  '})';
}

function callModule(fn, filename) {
  var module = {exports: {}};
  fn(module.exports, Object.assign(function(modulename) {
    if (/\W/.test(modulename[0])) {
      return require(path.join(path.dirname(filename), modulename));
    }
    return require(modulename);
  }, require), module, filename, path.dirname(filename));
  return module.exports;
}

exports.compile = function(fixturePath, options) {
  var configPath = path.join(__dirname, '..', 'fixtures', fixturePath, 'webpack.config.js');
  var compiler = webpack(callModule(vm.runInThisContext(wrapModule(fs.readFileSync(configPath, 'utf8')), {filename: configPath}), configPath));
  var outputfs = compiler.outputFileSystem = new MemoryFS();
  var readdir = Promise.promisify(outputfs.readdir, {context: outputfs});
  var readFile = Promise.promisify(outputfs.readFile, {context: outputfs});
  var stat = Promise.promisify(outputfs.stat, {context: outputfs});
  var fsReaddir = Promise.promisify(fs.readdir, {context: fs});
  var fsReadFile = Promise.promisify(fs.readFile, {context: fs});
  var fsStat = Promise.promisify(fs.stat, {context: fs});
  var run = Promise.promisify(compiler.run, {context: compiler});

  return run()
  .then(function(stats) {
    return Promise.all([
      readdir(compiler.options.output.path)
      .map(function(name) {
        var fullname = path.join(compiler.options.output.path, name);
        return stat(fullname)
        .then(function(stat) {
          if (stat.isFile()) {
            return readFile(fullname)
            .then(function(file) {return [name, file];});
          }
        });
      }),
      fsReaddir(compiler.options.output.path)
      .map(function(name) {
        var fullname = path.join(compiler.options.output.path, name);
        return fsStat(fullname)
        .then(function(stat) {
          if (stat.isFile()) {
            return fsReadFile(fullname)
            .then(function(file) {return [name, file];});
          }
        });
      }),
    ])
    .then(function(files) {
      return files[0].concat(files[1]);
    })
    .reduce(function(carry, values) {
      if (values) {
        carry[values[0]] = values[1];
      }
      return carry;
    }, {})
    .then(function(carry) {
      if (options && options.exportStats) {
        var statsJson = stats.toJson({
          errors: true,
          warnings: true,
        });
        return {
          out: carry,
          warnings: statsJson.warnings,
          errors: statsJson.errors,
        };
      }
      if (options && options.exportCompilation) {
        return {
          out: carry,
          compilation: stats.compilation,
        };
      }
      else {
        return carry;
      }
    });
  })
  ;
};

exports.compileTwiceEqual = function(fixturePath, compileOptions) {
  var run1 = exports.compile(fixturePath, compileOptions);
  return run1
  .then(function() {
    var run2 = exports.compile(fixturePath, compileOptions);
    return Promise.all([run1, run2]);
  })
  .then(function(runs) {
    expect(runs[0]).to.eql(runs[1]);
  });
};

exports.itCompilesTwice = function(fixturePath, compileOptions) {
  before(function() {
    return exports.clean(fixturePath);
  });

  it('builds identical ' + fixturePath + ' fixture', function() {
    this.timeout(10000);
    return exports.compileTwiceEqual(fixturePath, compileOptions);
  });
};

exports.writeFiles = function(fixturePath, files) {
  var configPath = path.join(__dirname, '..', 'fixtures', fixturePath);

  fsUnlink = Promise.promisify(fs.unlink, {context: fs});
  _fsWriteFile = Promise.promisify(fs.writeFile, {context: fs});
  fsMkdirp = Promise.promisify(mkdirp);
  fsWriteFile = function(file, content, encode) {
    return fsMkdirp(path.dirname(file))
    .then(function() {
      return _fsWriteFile(file, content, encode);
    });
  };
  fsRimraf = Promise.promisify(rimraf);

  return Promise.all(Object.keys(files).map(function(key) {
    if (files[key] === null) {
      return fsRimraf(path.join(configPath, key)).catch(function() {});
    }
    return fsWriteFile(path.join(configPath, key), files[key]);
  }));
};

exports.readFiles = function(outputPath) {
  outputPath = path.join(__dirname, '..', 'fixtures', outputPath);

  var fsReaddir = Promise.promisify(fs.readdir, {context: fs});
  var fsReadFile = Promise.promisify(fs.readFile, {context: fs});
  var fsStat = Promise.promisify(fs.stat, {context: fs});

  return fsReaddir(outputPath)
  .map(function(name) {
    var fullname = path.join(outputPath, name);
    return fsStat(fullname)
    .then(function(stat) {
      if (stat.isFile()) {
        return fsReadFile(fullname)
        .then(function(file) {return [name, file];});
      }
    });
  })
  .reduce(function(carry, values) {
    if (values) {
      carry[values[0]] = values[1];
    }
    return carry;
  }, {});
};

exports.itCompiles = function(name, fixturePath, fnA, fnB, expectHandle) {
  if (!fnA) {
    expectHandle = fixturePath;
    fixturePath = name;
    fnB = function() {};
    fnA = function() {};
  }
  if (!fnB) {
    expectHandle = fnA;
    fnB = function() {};
    fnA = function() {};
  }
  if (!expectHandle) {
    expectHandle = fnB;
    fnB = fnA;
  }

  before(function() {
    return exports.clean(fixturePath);
  });

  it(name, function() {
    this.timeout(20000);
    this.slow(4000);
    var run1;
    var setup1, setup2;
    return Promise.resolve()
    .then(function() {
      return fnA();
    })
    .then(function(_setup1) {
      setup1 = _setup1;
      run1 = exports.compile(fixturePath, setup1);
      return run1;
    })
    // Delay enough time so that file timestamps are different.
    .then(function() {
      // return new Promise(function(resolve) {setTimeout(resolve, 1000);});
    })
    .then(function() {
      return fnB();
    })
    .then(function(_setup2) {
      setup2 = _setup2;
      var run2 = exports.compile(fixturePath, setup2);
      return Promise.all([run1, run2]);
    })
    .then(function(runs) {
      expectHandle({
        run1: runs[0],
        run2: runs[1],
        setup1: setup1,
        setup2: setup2,
      });
    });
  });
};

exports.itCompilesWithCache = function(name, fixturePath, fnA, fnB, expectHandle) {
  before(function() {
    return exports.clean(fixturePath);
  });

  it(name, function() {
    this.timeout(20000);
    this.slow(4000);
    var cache1, cache2;
    return Promise.resolve()
    .then(function() {
      return fnA();
    })
    .then(function() {
      return exports.compile(fixturePath);
    })
    .then(function() {
      // return new Promise(function(resolve) {setTimeout(resolve, 1000);});
    })
    .then(function() {
      var serializer = new LevelDbSerializer({
        cacheDirPath: path.join(__dirname, '../', 'fixtures', fixturePath, 'tmp/cache/md5')
      });
      return serializer.read().then(function(_cache) { cache1 = _cache; });
    })
    .then(function() {
      return fnB();
    })
    .then(function() {
      return exports.compile(fixturePath);
    })
    .then(function() {
      // return new Promise(function(resolve) {setTimeout(resolve, 1000);});
    })
    .then(function() {
      var serializer = new LevelDbSerializer({
        cacheDirPath: path.join(__dirname, '../', 'fixtures', fixturePath, 'tmp/cache/md5')
      });
      return serializer.read().then(function(_cache) { cache2 = _cache; });
    })
    .then(function() {
      return expectHandle(cache1, cache2);
    });
  });
}

exports.itCompilesChange = function(fixturePath, filesA, filesB, expectHandle) {
  exports.itCompiles('builds changes in ' + fixturePath + ' fixture', fixturePath, function() {
    return exports.writeFiles(fixturePath, filesA);
  }, function() {
    return exports.writeFiles(fixturePath, filesB);
  }, expectHandle);
  before(function() {
    return exports.clean(fixturePath);
  });
};

exports.itCompilesHardModules = function(fixturePath, filesA, filesB, expectHandle) {
  if (typeof filesA === 'function' || Array.isArray(filesA)) {
    filesB = filesA;
    filesA = {};
  }
  if (typeof filesB === 'function' || Array.isArray(filesB)) {
    expectHandle = filesB;
    filesB = filesA;
  }
  exports.itCompiles('builds hard modules in ' + fixturePath + ' fixture', fixturePath, function() {
    return exports.writeFiles(fixturePath, filesA)
    .then(function() {return {exportCompilation: true};});
  }, function() {
    return exports.writeFiles(fixturePath, filesB)
    .then(function() {return {exportCompilation: true};});
  }, function(out) {
    var hardModules = [];
    var shortener = new (require('webpack/lib/RequestShortener'))(path.resolve(__dirname, '../fixtures', fixturePath));
    function walk(compilation) {
      compilation.modules.forEach(function(module) {
        if (module.isHard && module.isHard()) {
          hardModules.push(module.readableIdentifier(shortener));
        }
      });
      compilation.children.forEach(walk);
    }
    walk(out.run2.compilation);
    if (typeof expectHandle === 'function') {
      return expectHandle(out, hardModules);
    }
    else {
      // console.log(hardModules);
      expectHandle.forEach(function(handle) {
        if (handle instanceof RegExp) {
          expect(hardModules).to.satisfy(function(modules) {
            return modules.reduce(function(carry, module) {
              return carry || handle.test(module);
            }, false);
          });
        }
        else {
          expect(hardModules).to.include(handle);
        }
      });
    }
  });
  before(function() {
    return exports.clean(fixturePath);
  });
};

exports.clean = function(fixturePath) {
  var tmpPath = path.join(__dirname, '..', 'fixtures', fixturePath, 'tmp');
  return Promise.promisify(rimraf)(tmpPath);
};

exports.describeWP2 = function() {
  var wpVersion = Number(require('webpack/package.json').version[0]);
  if (wpVersion > 1) {
    describe.apply(null, arguments);
  }
  else {
    describe.skip.apply(null, arguments);
  }
};
<commit_msg>Return empty array when test util readdir errors<commit_after>var fs = require('fs');
var path = require('path');
var vm = require('vm');

var expect = require('chai').expect;
var MemoryFS = require('memory-fs');

var LevelDbSerializer = require('../../lib/cache-serializers').LevelDbSerializer;
var mkdirp = require('mkdirp');
var Promise = require('bluebird');
var rimraf = require('rimraf');
var webpack = require('webpack');

function wrapModule(code) {
  return '(function(exports, require, module, __filename, __dirname) {' +
    code +
  '})';
}

function callModule(fn, filename) {
  var module = {exports: {}};
  fn(module.exports, Object.assign(function(modulename) {
    if (/\W/.test(modulename[0])) {
      return require(path.join(path.dirname(filename), modulename));
    }
    return require(modulename);
  }, require), module, filename, path.dirname(filename));
  return module.exports;
}

exports.compile = function(fixturePath, options) {
  var configPath = path.join(__dirname, '..', 'fixtures', fixturePath, 'webpack.config.js');
  var compiler = webpack(callModule(vm.runInThisContext(wrapModule(fs.readFileSync(configPath, 'utf8')), {filename: configPath}), configPath));
  var outputfs = compiler.outputFileSystem = new MemoryFS();
  var readdir = Promise.promisify(outputfs.readdir, {context: outputfs});
  var readFile = Promise.promisify(outputfs.readFile, {context: outputfs});
  var stat = Promise.promisify(outputfs.stat, {context: outputfs});
  var fsReaddir = Promise.promisify(fs.readdir, {context: fs});
  var fsReadFile = Promise.promisify(fs.readFile, {context: fs});
  var fsStat = Promise.promisify(fs.stat, {context: fs});
  var run = Promise.promisify(compiler.run, {context: compiler});

  return run()
  .then(function(stats) {
    return Promise.all([
      readdir(compiler.options.output.path)
      .catch(function() {return [];})
      .map(function(name) {
        var fullname = path.join(compiler.options.output.path, name);
        return stat(fullname)
        .then(function(stat) {
          if (stat.isFile()) {
            return readFile(fullname)
            .then(function(file) {return [name, file];});
          }
        });
      }),
      fsReaddir(compiler.options.output.path)
      .catch(function() {return [];})
      .map(function(name) {
        var fullname = path.join(compiler.options.output.path, name);
        return fsStat(fullname)
        .then(function(stat) {
          if (stat.isFile()) {
            return fsReadFile(fullname)
            .then(function(file) {return [name, file];});
          }
        });
      }),
    ])
    .then(function(files) {
      return files[0].concat(files[1]);
    })
    .reduce(function(carry, values) {
      if (values) {
        carry[values[0]] = values[1];
      }
      return carry;
    }, {})
    .then(function(carry) {
      if (options && options.exportStats) {
        var statsJson = stats.toJson({
          errors: true,
          warnings: true,
        });
        return {
          out: carry,
          warnings: statsJson.warnings,
          errors: statsJson.errors,
        };
      }
      if (options && options.exportCompilation) {
        return {
          out: carry,
          compilation: stats.compilation,
        };
      }
      else {
        return carry;
      }
    });
  })
  ;
};

exports.compileTwiceEqual = function(fixturePath, compileOptions) {
  var run1 = exports.compile(fixturePath, compileOptions);
  return run1
  .then(function() {
    var run2 = exports.compile(fixturePath, compileOptions);
    return Promise.all([run1, run2]);
  })
  .then(function(runs) {
    expect(runs[0]).to.eql(runs[1]);
  });
};

exports.itCompilesTwice = function(fixturePath, compileOptions) {
  before(function() {
    return exports.clean(fixturePath);
  });

  it('builds identical ' + fixturePath + ' fixture', function() {
    this.timeout(10000);
    return exports.compileTwiceEqual(fixturePath, compileOptions);
  });
};

exports.writeFiles = function(fixturePath, files) {
  var configPath = path.join(__dirname, '..', 'fixtures', fixturePath);

  fsUnlink = Promise.promisify(fs.unlink, {context: fs});
  _fsWriteFile = Promise.promisify(fs.writeFile, {context: fs});
  fsMkdirp = Promise.promisify(mkdirp);
  fsWriteFile = function(file, content, encode) {
    return fsMkdirp(path.dirname(file))
    .then(function() {
      return _fsWriteFile(file, content, encode);
    });
  };
  fsRimraf = Promise.promisify(rimraf);

  return Promise.all(Object.keys(files).map(function(key) {
    if (files[key] === null) {
      return fsRimraf(path.join(configPath, key)).catch(function() {});
    }
    return fsWriteFile(path.join(configPath, key), files[key]);
  }));
};

exports.readFiles = function(outputPath) {
  outputPath = path.join(__dirname, '..', 'fixtures', outputPath);

  var fsReaddir = Promise.promisify(fs.readdir, {context: fs});
  var fsReadFile = Promise.promisify(fs.readFile, {context: fs});
  var fsStat = Promise.promisify(fs.stat, {context: fs});

  return fsReaddir(outputPath)
  .catch(function() {return [];})
  .map(function(name) {
    var fullname = path.join(outputPath, name);
    return fsStat(fullname)
    .then(function(stat) {
      if (stat.isFile()) {
        return fsReadFile(fullname)
        .then(function(file) {return [name, file];});
      }
    });
  })
  .reduce(function(carry, values) {
    if (values) {
      carry[values[0]] = values[1];
    }
    return carry;
  }, {});
};

exports.itCompiles = function(name, fixturePath, fnA, fnB, expectHandle) {
  if (!fnA) {
    expectHandle = fixturePath;
    fixturePath = name;
    fnB = function() {};
    fnA = function() {};
  }
  if (!fnB) {
    expectHandle = fnA;
    fnB = function() {};
    fnA = function() {};
  }
  if (!expectHandle) {
    expectHandle = fnB;
    fnB = fnA;
  }

  before(function() {
    return exports.clean(fixturePath);
  });

  it(name, function() {
    this.timeout(20000);
    this.slow(4000);
    var run1;
    var setup1, setup2;
    return Promise.resolve()
    .then(function() {
      return fnA();
    })
    .then(function(_setup1) {
      setup1 = _setup1;
      run1 = exports.compile(fixturePath, setup1);
      return run1;
    })
    // Delay enough time so that file timestamps are different.
    .then(function() {
      // return new Promise(function(resolve) {setTimeout(resolve, 1000);});
    })
    .then(function() {
      return fnB();
    })
    .then(function(_setup2) {
      setup2 = _setup2;
      var run2 = exports.compile(fixturePath, setup2);
      return Promise.all([run1, run2]);
    })
    .then(function(runs) {
      expectHandle({
        run1: runs[0],
        run2: runs[1],
        setup1: setup1,
        setup2: setup2,
      });
    });
  });
};

exports.itCompilesWithCache = function(name, fixturePath, fnA, fnB, expectHandle) {
  before(function() {
    return exports.clean(fixturePath);
  });

  it(name, function() {
    this.timeout(20000);
    this.slow(4000);
    var cache1, cache2;
    return Promise.resolve()
    .then(function() {
      return fnA();
    })
    .then(function() {
      return exports.compile(fixturePath);
    })
    .then(function() {
      // return new Promise(function(resolve) {setTimeout(resolve, 1000);});
    })
    .then(function() {
      var serializer = new LevelDbSerializer({
        cacheDirPath: path.join(__dirname, '../', 'fixtures', fixturePath, 'tmp/cache/md5')
      });
      return serializer.read().then(function(_cache) { cache1 = _cache; });
    })
    .then(function() {
      return fnB();
    })
    .then(function() {
      return exports.compile(fixturePath);
    })
    .then(function() {
      // return new Promise(function(resolve) {setTimeout(resolve, 1000);});
    })
    .then(function() {
      var serializer = new LevelDbSerializer({
        cacheDirPath: path.join(__dirname, '../', 'fixtures', fixturePath, 'tmp/cache/md5')
      });
      return serializer.read().then(function(_cache) { cache2 = _cache; });
    })
    .then(function() {
      return expectHandle(cache1, cache2);
    });
  });
}

exports.itCompilesChange = function(fixturePath, filesA, filesB, expectHandle) {
  exports.itCompiles('builds changes in ' + fixturePath + ' fixture', fixturePath, function() {
    return exports.writeFiles(fixturePath, filesA);
  }, function() {
    return exports.writeFiles(fixturePath, filesB);
  }, expectHandle);
  before(function() {
    return exports.clean(fixturePath);
  });
};

exports.itCompilesHardModules = function(fixturePath, filesA, filesB, expectHandle) {
  if (typeof filesA === 'function' || Array.isArray(filesA)) {
    filesB = filesA;
    filesA = {};
  }
  if (typeof filesB === 'function' || Array.isArray(filesB)) {
    expectHandle = filesB;
    filesB = filesA;
  }
  exports.itCompiles('builds hard modules in ' + fixturePath + ' fixture', fixturePath, function() {
    return exports.writeFiles(fixturePath, filesA)
    .then(function() {return {exportCompilation: true};});
  }, function() {
    return exports.writeFiles(fixturePath, filesB)
    .then(function() {return {exportCompilation: true};});
  }, function(out) {
    var hardModules = [];
    var shortener = new (require('webpack/lib/RequestShortener'))(path.resolve(__dirname, '../fixtures', fixturePath));
    function walk(compilation) {
      compilation.modules.forEach(function(module) {
        if (module.isHard && module.isHard()) {
          hardModules.push(module.readableIdentifier(shortener));
        }
      });
      compilation.children.forEach(walk);
    }
    walk(out.run2.compilation);
    if (typeof expectHandle === 'function') {
      return expectHandle(out, hardModules);
    }
    else {
      // console.log(hardModules);
      expectHandle.forEach(function(handle) {
        if (handle instanceof RegExp) {
          expect(hardModules).to.satisfy(function(modules) {
            return modules.reduce(function(carry, module) {
              return carry || handle.test(module);
            }, false);
          });
        }
        else {
          expect(hardModules).to.include(handle);
        }
      });
    }
  });
  before(function() {
    return exports.clean(fixturePath);
  });
};

exports.clean = function(fixturePath) {
  var tmpPath = path.join(__dirname, '..', 'fixtures', fixturePath, 'tmp');
  return Promise.promisify(rimraf)(tmpPath);
};

exports.describeWP2 = function() {
  var wpVersion = Number(require('webpack/package.json').version[0]);
  if (wpVersion > 1) {
    describe.apply(null, arguments);
  }
  else {
    describe.skip.apply(null, arguments);
  }
};
<|endoftext|>