<commit_before>/**
 * Main application file
 */

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var express = require('express');
var https = require('https');
var http = require('http');
var config = require('./config/environment');
var fs = require('fs');

// Populate DB with sample data
if(config.seedDB) { require('./config/seed'); }

// Setup server. Only needed for development
 // var options = {
 //      key: fs.readFileSync('./server/config/develop_ssl/server.key'),
 //      cert: fs.readFileSync('./server/config/develop_ssl/server.crt')
 //   };
var app = express();
var server = https.createServer(options, app);
var server_no_ssl = http.createServer(app);

app.use('*',function(req,res,next){
	var isSecure = req.secure || req.headers['x-forwarded-proto'] == 'https';
  if (!isSecure) return res.redirect('https://' + req.headers.host + req.url);
  next();
});

// var socketio = require('socket.io')(server, {
//   serveClient: (config.env === 'production') ? false : true,
//   path: '/socket.io-client'
// });
// require('./config/socketio')(socketio);
require('./config/express')(app);
require('./routes')(app);

// Start server
server.listen(config.port, config.ip, function () {
  console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

server_no_ssl.listen(9001, config.ip);

// Expose app
exports = module.exports = app;<commit_msg>set app server back to the previous configuration for heroku to test https<commit_after>/**
 * Main application file
 */

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var express = require('express');
// var https = require('https');
var http = require('http');
var config = require('./config/environment');
var fs = require('fs');

// Populate DB with sample data
if(config.seedDB) { require('./config/seed'); }

// Setup server. Only needed for development
 // var options = {
 //      key: fs.readFileSync('./server/config/develop_ssl/server.key'),
 //      cert: fs.readFileSync('./server/config/develop_ssl/server.crt')
 //   };
var app = express();
var server = http.createServer(app);
// var server = https.createServer(options, app);

app.use('*',function(req,res,next){
	var isSecure = req.secure || req.headers['x-forwarded-proto'] == 'https';
  if (!isSecure) return res.redirect('https://' + req.headers.host + req.url);
  next();
});

// var socketio = require('socket.io')(server, {
//   serveClient: (config.env === 'production') ? false : true,
//   path: '/socket.io-client'
// });
// require('./config/socketio')(socketio);
require('./config/express')(app);
require('./routes')(app);

// Start server
server.listen(config.port, config.ip, function () {
  console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

// Expose app
exports = module.exports = app;<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const express = require('express')
const helmet = require('helmet')
const session = require('express-session')
const MemoryStore = require('memorystore')(session)
const config = require('./lib/config.js')
const packageJson = require('../package.json')

/*  Env/Cli Config stuff
============================================================================= */
const BASE_URL = config.get('baseUrl')
const GOOGLE_CLIENT_ID = config.get('googleClientId')
const GOOGLE_CLIENT_SECRET = config.get('googleClientSecret')
const PUBLIC_URL = config.get('publicUrl')
const DEBUG = config.get('debug')

/*  Express setup
============================================================================= */
const bodyParser = require('body-parser')
const favicon = require('serve-favicon')
const morgan = require('morgan')
const passport = require('passport')
const errorhandler = require('errorhandler')

const app = express()

// Use default helmet protections and add referrerPolicy
app.use(helmet())
app.use(helmet.referrerPolicy({ policy: 'same-origin' }))

app.locals.title = 'SQLPad'
app.locals.version = packageJson.version
app.set('env', DEBUG ? 'development' : 'production')

if (DEBUG) {
  app.use(errorhandler())
}
app.use(favicon(path.join(__dirname, '../public/images/favicon.ico')))
app.use(bodyParser.json())
app.use(
  bodyParser.urlencoded({
    extended: true
  })
)

// Cookie secrets are generated randomly at server start
// SQLPad (currently) is designed for running as a single instance
// so this should be okay unless SQLPad is frequently restarting
const cookieSecrets = [1, 2, 3, 4].map(n =>
  crypto.randomBytes(64).toString('hex')
)
const ONE_HOUR = 1000 * 60 * 60
app.use(
  session({
    store: new MemoryStore({
      checkPeriod: ONE_HOUR
    }),
    saveUninitialized: false,
    resave: false,
    rolling: true,
    cookie: { maxAge: ONE_HOUR },
    secret: cookieSecrets
  })
)

app.use(passport.initialize())
app.use(passport.session())
app.use(BASE_URL, express.static(path.join(__dirname, '../build')))
if (DEBUG) {
  app.use(morgan('dev'))
}
app.use(function(req, res, next) {
  // Add config ref to req
  // TODO eventually pull UI/db config values here
  req.config = config

  // Bootstrap res.locals with any common variables
  res.locals.message = null
  res.locals.navbarConnections = []
  res.locals.debug = null
  res.locals.query = null
  res.locals.queryMenu = false
  res.locals.session = req.session || null
  res.locals.pageTitle = ''
  res.locals.user = req.user
  res.locals.isAuthenticated = req.isAuthenticated()
  res.locals.baseUrl = BASE_URL
  next()
})

/*  Passport setup
============================================================================= */
require('./middleware/passport.js')

/*  Routes
============================================================================= */
const routers = [
  require('./routes/homepage.js'),
  require('./routes/app.js'),
  require('./routes/version.js'),
  require('./routes/users.js'),
  require('./routes/forgot-password.js'),
  require('./routes/password-reset.js'),
  require('./routes/connections.js'),
  require('./routes/queries.js'),
  require('./routes/query-result.js'),
  require('./routes/download-results.js'), // streams result download to browser
  require('./routes/schema-info.js'),
  require('./routes/config-values.js'),
  require('./routes/tags.js'),
  require('./routes/signup-signin-signout.js')
]

if (GOOGLE_CLIENT_ID && GOOGLE_CLIENT_SECRET && PUBLIC_URL) {
  if (DEBUG) {
    console.log('Enabling Google authentication Strategy.')
  }
  routers.push(require('./routes/oauth.js'))
}

routers.forEach(function(router) {
  app.use(BASE_URL, router)
})

// For any missing api route, return a 404
app.use(BASE_URL + '/api/', function(req, res) {
  console.log('reached catch all api route')
  res.sendStatus(404)
})

// Anything else should render the client-side app
// Client-side routing will take care of things from here
// index-template.html generated by create-react-app must consider BASE_URL
const htmlPath = path.join(__dirname, '../build/index-template.html')
if (fs.existsSync(htmlPath)) {
  const html = fs.readFileSync(htmlPath, 'utf8')
  const baseUrlHtml = html
    .replace(/="\/stylesheets/g, '="' + BASE_URL + '/stylesheets')
    .replace(/="\/javascripts/g, '="' + BASE_URL + '/javascripts')
    .replace(/="\/images/g, '="' + BASE_URL + '/images')
    .replace(/="\/fonts/g, '="' + BASE_URL + '/fonts')
    .replace(/="\/static/g, '="' + BASE_URL + '/static')
  app.use((req, res) => res.send(baseUrlHtml))
} else {
  console.error('\nNO FRONT END TEMPLATE DETECTED')
  console.error('If not running in dev mode please report this issue.\n')
}

module.exports = app
<commit_msg>Use nonUi config for app.js startup<commit_after>const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const express = require('express')
const helmet = require('helmet')
const session = require('express-session')
const MemoryStore = require('memorystore')(session)
const config = require('./lib/config.js')
const packageJson = require('../package.json')
const {
  baseUrl,
  googleClientId,
  googleClientSecret,
  publicUrl,
  debug
} = require('./lib/config/nonUi')()

/*  Express setup
============================================================================= */
const bodyParser = require('body-parser')
const favicon = require('serve-favicon')
const morgan = require('morgan')
const passport = require('passport')
const errorhandler = require('errorhandler')

const app = express()

// Use default helmet protections and add referrerPolicy
app.use(helmet())
app.use(helmet.referrerPolicy({ policy: 'same-origin' }))

app.locals.title = 'SQLPad'
app.locals.version = packageJson.version
app.set('env', debug ? 'development' : 'production')

if (debug) {
  app.use(errorhandler())
}
app.use(favicon(path.join(__dirname, '../public/images/favicon.ico')))
app.use(bodyParser.json())
app.use(
  bodyParser.urlencoded({
    extended: true
  })
)

// Cookie secrets are generated randomly at server start
// SQLPad (currently) is designed for running as a single instance
// so this should be okay unless SQLPad is frequently restarting
const cookieSecrets = [1, 2, 3, 4].map(n =>
  crypto.randomBytes(64).toString('hex')
)
const ONE_HOUR = 1000 * 60 * 60
app.use(
  session({
    store: new MemoryStore({
      checkPeriod: ONE_HOUR
    }),
    saveUninitialized: false,
    resave: false,
    rolling: true,
    cookie: { maxAge: ONE_HOUR },
    secret: cookieSecrets
  })
)

app.use(passport.initialize())
app.use(passport.session())
app.use(baseUrl, express.static(path.join(__dirname, '../build')))
if (debug) {
  app.use(morgan('dev'))
}
app.use(function(req, res, next) {
  // Add config ref to req
  // TODO eventually pull UI/db config values here
  req.config = config

  // Bootstrap res.locals with any common variables
  res.locals.message = null
  res.locals.navbarConnections = []
  res.locals.debug = null
  res.locals.query = null
  res.locals.queryMenu = false
  res.locals.session = req.session || null
  res.locals.pageTitle = ''
  res.locals.user = req.user
  res.locals.isAuthenticated = req.isAuthenticated()
  res.locals.baseUrl = baseUrl
  next()
})

/*  Passport setup
============================================================================= */
require('./middleware/passport.js')

/*  Routes
============================================================================= */
const routers = [
  require('./routes/homepage.js'),
  require('./routes/app.js'),
  require('./routes/version.js'),
  require('./routes/users.js'),
  require('./routes/forgot-password.js'),
  require('./routes/password-reset.js'),
  require('./routes/connections.js'),
  require('./routes/queries.js'),
  require('./routes/query-result.js'),
  require('./routes/download-results.js'), // streams result download to browser
  require('./routes/schema-info.js'),
  require('./routes/config-values.js'),
  require('./routes/tags.js'),
  require('./routes/signup-signin-signout.js')
]

if (googleClientId && googleClientSecret && publicUrl) {
  if (debug) {
    console.log('Enabling Google authentication Strategy.')
  }
  routers.push(require('./routes/oauth.js'))
}

routers.forEach(function(router) {
  app.use(baseUrl, router)
})

// For any missing api route, return a 404
app.use(baseUrl + '/api/', function(req, res) {
  console.log('reached catch all api route')
  res.sendStatus(404)
})

// Anything else should render the client-side app
// Client-side routing will take care of things from here
// index-template.html generated by create-react-app must consider baseUrl
const htmlPath = path.join(__dirname, '../build/index-template.html')
if (fs.existsSync(htmlPath)) {
  const html = fs.readFileSync(htmlPath, 'utf8')
  const baseUrlHtml = html
    .replace(/="\/stylesheets/g, `="${baseUrl}/stylesheets`)
    .replace(/="\/javascripts/g, `="${baseUrl}/javascripts`)
    .replace(/="\/images/g, `="${baseUrl}/images`)
    .replace(/="\/fonts/g, `="${baseUrl}/fonts`)
    .replace(/="\/static/g, `="${baseUrl}/static`)
  app.use((req, res) => res.send(baseUrlHtml))
} else {
  console.error('\nNO FRONT END TEMPLATE DETECTED')
  console.error('If not running in dev mode please report this issue.\n')
}

module.exports = app
<|endoftext|>


<commit_before>'use strict';

if(process.env.NEW_RELIC_APP_NAME) {
  require('newrelic');
}

// dependencies
var express = require('express')
  , app = express()
  , server = require('http').createServer(app)
  , ioServer = require('socket.io').listen(server)
  , path = require('path');
// valid api keys

var gridProperties = {
  dimensions: 32
};

// Get our modules
var ApiKeyHandler = require('./apikeyhandler')
  , ClientValidator = require('./clientvalidator')
  , Grid = require('./grid');

var grid = new Grid(gridProperties.dimensions);

// core app logic
var port = process.env.PORT || 9001;
server.listen(port);

app.use(express.static(path.normalize(__dirname +  '/../dist/')));

app.get('/', function (req, res) {
  res.sendfile(path.normalize(__dirname +  '/../dist/index.html'));
});

// optimizations for production
if(process.env.NODE_ENV === 'production') {

  ioServer.enable('browser client minification');
  ioServer.enable('browser client etag');
  ioServer.enable('browser client gzip');
  ioServer.set('log level', 1);
  ioServer.set('transports', [
      'websocket'
    , 'htmlfile'
    , 'xhr-polling'
    , 'jsonp-polling'
    ]);

}
ioServer.set('log level', 1);

// describe client connection
ioServer.sockets.on('connection', function (socket) {
  ApiKeyHandler.newKey(socket, null, function (socket) { // DIRTY FIX ME
    console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    socket.emit('server ready', { gridArray: grid });
    //Socket listener for user click
    socket.on('clicked', function (data) {
      console.log('***\n' + socket.id + ' clicked');
      if(ClientValidator(data, gridProperties.dimensions)) {
        new ApiKeyHandler(socket, data.apiKey, function() {
          grid.updateGrid(socket, data);
        });
      } else {
        console.warn('warning: user provided invalid data: %s %s %s %s', data.row, data.col, data.color, data.apiKey);
      }
    });
    socket.on('disconnect', function() {
      ApiKeyHandler.delete(socket.id);
      console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    });
  });
});<commit_msg>Server ready event now passes the 2d array instead of the Grid object<commit_after>'use strict';

if(process.env.NEW_RELIC_APP_NAME) {
  require('newrelic');
}

// dependencies
var express = require('express')
  , app = express()
  , server = require('http').createServer(app)
  , ioServer = require('socket.io').listen(server)
  , path = require('path');
// valid api keys

var gridProperties = {
  dimensions: 32
};

// Get our modules
var ApiKeyHandler = require('./apikeyhandler')
  , ClientValidator = require('./clientvalidator')
  , Grid = require('./grid');

var grid = new Grid(gridProperties.dimensions);

// core app logic
var port = process.env.PORT || 9001;
server.listen(port);

app.use(express.static(path.normalize(__dirname +  '/../dist/')));

app.get('/', function (req, res) {
  res.sendfile(path.normalize(__dirname +  '/../dist/index.html'));
});

// optimizations for production
if(process.env.NODE_ENV === 'production') {

  ioServer.enable('browser client minification');
  ioServer.enable('browser client etag');
  ioServer.enable('browser client gzip');
  ioServer.set('log level', 1);
  ioServer.set('transports', [
      'websocket'
    , 'htmlfile'
    , 'xhr-polling'
    , 'jsonp-polling'
    ]);

}
ioServer.set('log level', 1);

// describe client connection
ioServer.sockets.on('connection', function (socket) {
  ApiKeyHandler.newKey(socket, null, function (socket) { // DIRTY FIX ME
    console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    socket.emit('server ready', { gridArray: grid.gridMatrix });
    //Socket listener for user click
    socket.on('clicked', function (data) {
      console.log('***\n' + socket.id + ' clicked');
      if(ClientValidator(data, gridProperties.dimensions)) {
        new ApiKeyHandler(socket, data.apiKey, function() {
          grid.updateGrid(socket, data);
        });
      } else {
        console.warn('warning: user provided invalid data: %s %s %s %s', data.row, data.col, data.color, data.apiKey);
      }
    });
    socket.on('disconnect', function() {
      ApiKeyHandler.delete(socket.id);
      console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    });
  });
});<|endoftext|>


<commit_before>window.templates || (window.templates = {});

templates.network_options_main = function(clearing_cache, caching, tracking, headers)
{
  var checked = true;
  return ["div",
          ["button", "Clear cache", "handler", "network-options-clear-cache"],
          clearing_cache ? ["span", "CLEARING"] : [],
          ["hr"],
          ["div", "Caching behaviour:",
           ["br"],
           ["label", "Standard browser caching behaviour",
            ["input", "type", "radio",
             "name", "network-options-caching",
             "value", "default",
             "handler", "network-options-toggle-caching",
             caching == "default" ? "checked" : "non-checked", "true"
            ]],

           ["br"],
           ["label", "Disable all caching",
            ["input", "type", "radio",
             "name", "network-options-caching",
             "value", "disabled",
             "handler", "network-options-toggle-caching",
             caching == "disabled" ? "checked" : "non-checked", "true"
            ]]
          ],
          ["hr"],
          ["div", "Content tracking behaviour:",
           ["br"],
           ["label", "Don't track content (default)",
            ["input", "type", "radio",
             "name", "network-options-track-bodies",
             "value", "notrack",
             "handler", "network-options-toggle-body-tracking",
             tracking == "notrack" ? "checked" : "non-checked", "true"
            ]],

           ["br"],
           ["label", "Track content (affects speed/memory)",
            ["input", "type", "radio",
             "name", "network-options-track-bodies",
             "value", "track",
             "handler", "network-options-toggle-body-tracking",
             tracking == "track" ? "checked" : "non-checked", "true"
            ]]
          ],

          /*
          ["hr"],
          ["fieldset", ["legend", "Global header rewrites"],
           templates.network_options_header_table(headers)
          ],
          */
          "class", "padding network-options"
         ];
};

templates.network_options_header_table = function(headers)
{
  var fun = function(header) {
      return ["tr",
               ["td", "DEL"],
               ["td", "ON"],
               ["td", ["input", "", "value", header.name]],
               ["td", ["input", "", "value", header.value]]
             ];
  };

  var tpl = ["table",
              ["tr",
                ["th", "X"], ["th", "Y"], ["th", "Name"], ["th", "Value"]],
                headers.map(fun)
            ];
  return tpl;
};

templates.network_request_crafter_main = function(url, request, response)
{
  return ["div",
          ["div",
           ["label", "URL:", ["input", "type", "text",
                              "value", url || "",
                              "handler", "request-crafter-url-change"
                             ]
           ],
           ["textarea", request]
          ],
          ["button", "Send request", "handler", "request-crafter-send"],
          ["hr"],
          ["div", ["pre", ["code", response]]],
          "class", "padding request-crafter"
         ];
};

templates.network_log_main = function(ctx)
{
  return [
    ["div",
     ["div",
      ["div", templates.network_log_url_list(ctx), "id", "left-side-content"],
      ["div",
       ["div", templates.network_log_graph(ctx), "id", "right-side-content"],
       "id", "right-side-container"
      ],
      "id", "main-scroll-content"
     ],
     "class", "network-log",
     "id", "main-scroll-container"
    ],
    ["div", ["div", "id", "scrollbar"], "id", "scroll-bar-container"]
  ];
}

templates.network_log_details = function(ctx, selected)
{
  return  [
    ["div", templates.network_log_url_list(ctx, selected),
     "class", "network-details-url-list"
    ],
    ["div", templates.network_log_request_detail(ctx, selected),
     "class", "network-details-request"
    ]
  ]
}

templates.network_log_request_detail = function(ctx, selected)
{
  var req = ctx.get_resource(selected);
  return [
    ["button", "X", "handler", "close-request-detail"],
    ["table",
     ["tr", ["th", "URL:"], ["td", req.url]],
     ["tr", ["th", "Method:"], ["td", req.method || "-"]],
     ["tr", ["th", "Status:"], ["td", String(req.responsecode || "-")]],
     "class", "resource-detail"
    ],
    ["hr"],
    ["h2", "Request details"],
    templates.network_header_table(req.request_headers),
    ["hr"],
    ["h2", "Response details"],
    templates.network_header_table(req.response_headers),
    ["hr"],
    ["h2", "Body"],
    templates.network_response_body(req)
  ]
}

templates.network_response_body = function(req)
{
  if (!req.responsebody)
  {
    return ["div",
            "Response body not tracked. To always fetch response bodies, toggle the response body option on the \"network options\" tab. To retrieve only this body, click the button.",
            ["button",
             "Get response body",
             "data-resource-id", String(req.id),
             "handler", "get-response-body"
             ]
            ]
  }
  else
  {
    var bodytpl;
    if (["script", "markup", "css", "text"].indexOf(req.type) != -1)
    {
      bodytpl = ["code", ["pre", req.responsebody.content.stringData]];
    }
    else if (req.type == "image")
    {
      bodytpl = ["img", "src", req.responsebody.content.stringData];
    }
    else
    {
      bodytpl = ["span", "not able to show data of type " + req.mime];
    }

    return ["div",
            bodytpl,
            "class", "response-body-content"
           ];
  }
}

templates.network_header_table = function(headers)
{
  if (!headers)
  {
    return ["table", ["tr", ["td", "No headers"]]];
  }

  var rowfun = function(header)
  {
    return ["tr",
            ["th", header.name],
            ["td", header.value]
           ]
  }

  var headers = headers.slice(0); // copy so we can sort withouth nuking original
  headers.sort(function(a, b) {
    if (a.name>b.name) { return 1 }
    else if (b.name>a.name) { return -1 }
    else { return 0 }
  });
  return ["table", headers.map(rowfun),
          "class", "header-list"];
}

templates.network_log_main_table = function(ctx)
{
  return [
    ["div", templates.network_log_url_list(ctx),
     "class", "resourcelist"
    ],
    ["div", templates.network_log_url_list(ctx),
     "class", "timeline"]
  ]
}

templates.network_log_url_list = function(ctx, selected)
{
  var itemfun = function(res) {
    return ["li", templates.network_request_icon(res), ["span", res.url],
            "handler", "select-network-request",
            "data-resource-id", String(res.id),
            "class", selected===res.id ? "selected" : ""
           ]
  }
  return ["ol", ctx.resources.map(itemfun),
          "class", "network-log-url-list"];
}

templates.network_request_icon = function(request)
{
  return ["span", "class", "resource-icon resource-type-" + request.type];
}

templates.network_log_graph = function(ctx, width)
{
  width = width || 1000;
  var rowheight = 36;
  var height = ctx.resources.length * rowheight;

  var gradients = templates.gradient_defs();
  var background = templates.network_log_background(ctx, rowheight);
  var bars = templates.graph_bars(ctx, width, rowheight);
  var grid = templates.grid_lines(ctx, width, height);

  var tpl = ["svg:svg",
             gradients,
             background,
             bars,
             grid,
             "viewBox", "0 0 " + width + " " + height,
             "xmlns", "http://www.w3.org/2000/svg",
             "class", "resource-graph"];

    return tpl;
}

templates.graph_bars = function(ctx, width, height)
{
  var bars = [];
  var basetime = ctx.get_starttime();
  var duration = ctx.get_duration();
  for (var n=0, req; req=ctx.resources[n]; n++)
  {
    var bar = templates.request_bar(n, req, basetime, duration, width, height);
    bars.push(bar);
  }
  return bars;
}

templates.request_bar = function(index, request, basetime, totaltime, contwidth, lineheight)
{
  var y = lineheight * index;
  var barheight = 18;
  var bary = y + (lineheight / 2) - (barheight / 2);
  var multiplier = contwidth / totaltime;

  if (!request.duration) {
    // fixme: request not done, so emit something saner here.
    return [];
  }

  var start = request.starttime;

  var reqwidth = request.duration

  var resstart = start+10//entry.requestfinished.time;
  var reswidth = 30; // reqwidth - (resstart - reqstart);

  var gid = Math.floor(Math.random() * 3);
  var texture = ["gradient-css", "gradient-img", "gradient-js"][gid];

  var tpl = [
    ["rect", "x", String((start-basetime)*multiplier), "y", String(bary),
     "width", String(reqwidth*multiplier), "height", String(barheight),
             "rx", "4", "ry", "4",
             "fill", "#e5e5e5", "stroke", "#969696", "stroke-width", "0.5"],

      ["rect", "x", String((resstart-basetime)*multiplier), "y", String(bary),
             "width", String(reswidth*multiplier), "height", String(barheight),
             "rx", "4", "ry", "4",
             "fill", "url(#" + texture + ")", "stroke", "#4a507d", "stroke-width", "0.5"]

  ];
  return tpl;
};

templates.grid_lines = function(ctx, width, height)
{
  var ret = [];
  var millis = ctx.get_duration();
  var secondwidth = width / (millis / 1000);
  var multiplier = width / millis;

  // Thresholds for whether or not to render grid for every 100 and 500ms.
  // The number is how many pixels per second. So if every second is
  // alloted more than 200px, render the 100ms bars
  const THRESH_100MS = 200;
  const THRESH_500MS = 100;

  ret.push(["line",
            "x1", "0",
            "y1", "0",
            "x2", "0",
            "y2", String(height),
            "stroke", "black",
            "stroke-width", "1",
           ]);

  for (var n=100; n<millis; n+=100)
  {
    var color = null;
    if (!(n % 1000))
    {
      color = "black";
    }
    else if (secondwidth > THRESH_500MS && !(n % 500))
    {
      color = "gray";
    }
    else if (secondwidth > THRESH_100MS && !(n % 100))
    {
      color = "silver";
    }

    if (color) {
      ret.push(["line",
                "x1", String(n*multiplier),
                "y1", "0",
                "x2", String(n*multiplier),
                "y2", String(height),
                "stroke", color,
                "stroke-width", "0.5",
                "opacity", "0.7"
      ]);
    }
  }

  return ret;
};

templates.gradient_defs = function()
{
  return ["defs",
    templates.gradient("img", "#e3ffff", "#92c5ff", "#70a5f0", "#8db8f2"),
    templates.gradient("js", "#d9dfff", "#828bbf", "#6269a0", "#7f88b4"),
    templates.gradient("css", "#ff7d7d", "#d21a1a", "#b40000", "#c32121")
  ];
};

templates.gradient = function(id, c1, c2, c3, c4)
{
  return ["linearGradient",
          ["stop", "offset", "5%", "stop-color", c1],
          ["stop", "offset", "50%", "stop-color", c2],
          ["stop", "offset", "50%", "stop-color", c3],
          ["stop", "offset", "100%", "stop-color", c4],
          "x1", "0",
          "x2", "0",
          "y1", "0",
          "y2", "100%",
          "id", "gradient-" + id
         ];
};

templates.network_log_background = function(ctx, lineheight)
{
  var cnt = ctx.resources.length;
  var tpls = [];
  while (cnt--)
  {
    tpls.push(["rect", "x", "0",
                       "y", String(cnt*lineheight),
                       "width", "100%",
                       "height", String(lineheight),
                       "stroke-width", "0", "fill", (cnt%2 ?  "#dddddd" : "white")]);
  }
  return tpls;
};
<commit_msg>Updated gradients to match up with types we detect. Use colours from icons<commit_after>window.templates || (window.templates = {});

templates.network_options_main = function(clearing_cache, caching, tracking, headers)
{
  var checked = true;
  return ["div",
          ["button", "Clear cache", "handler", "network-options-clear-cache"],
          clearing_cache ? ["span", "CLEARING"] : [],
          ["hr"],
          ["div", "Caching behaviour:",
           ["br"],
           ["label", "Standard browser caching behaviour",
            ["input", "type", "radio",
             "name", "network-options-caching",
             "value", "default",
             "handler", "network-options-toggle-caching",
             caching == "default" ? "checked" : "non-checked", "true"
            ]],

           ["br"],
           ["label", "Disable all caching",
            ["input", "type", "radio",
             "name", "network-options-caching",
             "value", "disabled",
             "handler", "network-options-toggle-caching",
             caching == "disabled" ? "checked" : "non-checked", "true"
            ]]
          ],
          ["hr"],
          ["div", "Content tracking behaviour:",
           ["br"],
           ["label", "Don't track content (default)",
            ["input", "type", "radio",
             "name", "network-options-track-bodies",
             "value", "notrack",
             "handler", "network-options-toggle-body-tracking",
             tracking == "notrack" ? "checked" : "non-checked", "true"
            ]],

           ["br"],
           ["label", "Track content (affects speed/memory)",
            ["input", "type", "radio",
             "name", "network-options-track-bodies",
             "value", "track",
             "handler", "network-options-toggle-body-tracking",
             tracking == "track" ? "checked" : "non-checked", "true"
            ]]
          ],

          /*
          ["hr"],
          ["fieldset", ["legend", "Global header rewrites"],
           templates.network_options_header_table(headers)
          ],
          */
          "class", "padding network-options"
         ];
};

templates.network_options_header_table = function(headers)
{
  var fun = function(header) {
      return ["tr",
               ["td", "DEL"],
               ["td", "ON"],
               ["td", ["input", "", "value", header.name]],
               ["td", ["input", "", "value", header.value]]
             ];
  };

  var tpl = ["table",
              ["tr",
                ["th", "X"], ["th", "Y"], ["th", "Name"], ["th", "Value"]],
                headers.map(fun)
            ];
  return tpl;
};

templates.network_request_crafter_main = function(url, request, response)
{
  return ["div",
          ["div",
           ["label", "URL:", ["input", "type", "text",
                              "value", url || "",
                              "handler", "request-crafter-url-change"
                             ]
           ],
           ["textarea", request]
          ],
          ["button", "Send request", "handler", "request-crafter-send"],
          ["hr"],
          ["div", ["pre", ["code", response]]],
          "class", "padding request-crafter"
         ];
};

templates.network_log_main = function(ctx)
{
  return [
    ["div",
     ["div",
      ["div", templates.network_log_url_list(ctx), "id", "left-side-content"],
      ["div",
       ["div", templates.network_log_graph(ctx), "id", "right-side-content"],
       "id", "right-side-container"
      ],
      "id", "main-scroll-content"
     ],
     "class", "network-log",
     "id", "main-scroll-container"
    ],
    ["div", ["div", "id", "scrollbar"], "id", "scroll-bar-container"]
  ];
}

templates.network_log_details = function(ctx, selected)
{
  return  [
    ["div", templates.network_log_url_list(ctx, selected),
     "class", "network-details-url-list"
    ],
    ["div", templates.network_log_request_detail(ctx, selected),
     "class", "network-details-request"
    ]
  ]
}

templates.network_log_request_detail = function(ctx, selected)
{
  var req = ctx.get_resource(selected);
  return [
    ["button", "X", "handler", "close-request-detail"],
    ["table",
     ["tr", ["th", "URL:"], ["td", req.url]],
     ["tr", ["th", "Method:"], ["td", req.method || "-"]],
     ["tr", ["th", "Status:"], ["td", String(req.responsecode || "-")]],
     "class", "resource-detail"
    ],
    ["hr"],
    ["h2", "Request details"],
    templates.network_header_table(req.request_headers),
    ["hr"],
    ["h2", "Response details"],
    templates.network_header_table(req.response_headers),
    ["hr"],
    ["h2", "Body"],
    templates.network_response_body(req)
  ]
}

templates.network_response_body = function(req)
{
  if (!req.responsebody)
  {
    return ["div",
            "Response body not tracked. To always fetch response bodies, toggle the response body option on the \"network options\" tab. To retrieve only this body, click the button.",
            ["button",
             "Get response body",
             "data-resource-id", String(req.id),
             "handler", "get-response-body"
             ]
            ]
  }
  else
  {
    var bodytpl;
    if (["script", "markup", "css", "text"].indexOf(req.type) != -1)
    {
      bodytpl = ["code", ["pre", req.responsebody.content.stringData]];
    }
    else if (req.type == "image")
    {
      bodytpl = ["img", "src", req.responsebody.content.stringData];
    }
    else
    {
      bodytpl = ["span", "not able to show data of type " + req.mime];
    }

    return ["div",
            bodytpl,
            "class", "response-body-content"
           ];
  }
}

templates.network_header_table = function(headers)
{
  if (!headers)
  {
    return ["table", ["tr", ["td", "No headers"]]];
  }

  var rowfun = function(header)
  {
    return ["tr",
            ["th", header.name],
            ["td", header.value]
           ]
  }

  var headers = headers.slice(0); // copy so we can sort withouth nuking original
  headers.sort(function(a, b) {
    if (a.name>b.name) { return 1 }
    else if (b.name>a.name) { return -1 }
    else { return 0 }
  });
  return ["table", headers.map(rowfun),
          "class", "header-list"];
}

templates.network_log_main_table = function(ctx)
{
  return [
    ["div", templates.network_log_url_list(ctx),
     "class", "resourcelist"
    ],
    ["div", templates.network_log_url_list(ctx),
     "class", "timeline"]
  ]
}

templates.network_log_url_list = function(ctx, selected)
{
  var itemfun = function(res) {
    return ["li", templates.network_request_icon(res), ["span", res.url],
            "handler", "select-network-request",
            "data-resource-id", String(res.id),
            "class", selected===res.id ? "selected" : ""
           ]
  }
  return ["ol", ctx.resources.map(itemfun),
          "class", "network-log-url-list"];
}

templates.network_request_icon = function(request)
{
  return ["span", "class", "resource-icon resource-type-" + request.type];
}

templates.network_log_graph = function(ctx, width)
{
  width = width || 1000;
  var rowheight = 36;
  var height = ctx.resources.length * rowheight;

  var gradients = templates.gradient_defs();
  var background = templates.network_log_background(ctx, rowheight);
  var bars = templates.graph_bars(ctx, width, rowheight);
  var grid = templates.grid_lines(ctx, width, height);

  var tpl = ["svg:svg",
             gradients,
             background,
             bars,
             grid,
             "viewBox", "0 0 " + width + " " + height,
             "xmlns", "http://www.w3.org/2000/svg",
             "class", "resource-graph"];

    return tpl;
}

templates.graph_bars = function(ctx, width, height)
{
  var bars = [];
  var basetime = ctx.get_starttime();
  var duration = ctx.get_duration();
  for (var n=0, req; req=ctx.resources[n]; n++)
  {
    var bar = templates.request_bar(n, req, basetime, duration, width, height);
    bars.push(bar);
  }
  return bars;
}

templates.request_bar = function(index, request, basetime, totaltime, contwidth, lineheight)
{
  var y = lineheight * index;
  var barheight = 18;
  var bary = y + (lineheight / 2) - (barheight / 2);
  var multiplier = contwidth / totaltime;

  if (!request.duration) {
    // fixme: request not done, so emit something saner here.
    return [];
  }

  var start = request.starttime;

  var reqwidth = request.duration

  var resstart = start+10//entry.requestfinished.time;
  var reswidth = 30; // reqwidth - (resstart - reqstart);

  var texture = "gradient-" + (request.type || "unknown");

  var tpl = [
    ["rect", "x", String((start-basetime)*multiplier), "y", String(bary),
     "width", String(reqwidth*multiplier), "height", String(barheight),
             "rx", "4", "ry", "4",
             "fill", "#e5e5e5", "stroke", "#969696", "stroke-width", "0.5"],

      ["rect", "x", String((resstart-basetime)*multiplier), "y", String(bary),
             "width", String(reswidth*multiplier), "height", String(barheight),
             "rx", "4", "ry", "4",
             "fill", "url(#" + texture + ")", "stroke", "#4a507d", "stroke-width", "0.5"]

  ];
  return tpl;
};

templates.grid_lines = function(ctx, width, height)
{
  var ret = [];
  var millis = ctx.get_duration();
  var secondwidth = width / (millis / 1000);
  var multiplier = width / millis;

  // Thresholds for whether or not to render grid for every 100 and 500ms.
  // The number is how many pixels per second. So if every second is
  // alloted more than 200px, render the 100ms bars
  const THRESH_100MS = 200;
  const THRESH_500MS = 100;

  ret.push(["line",
            "x1", "0",
            "y1", "0",
            "x2", "0",
            "y2", String(height),
            "stroke", "black",
            "stroke-width", "1",
           ]);

  for (var n=100; n<millis; n+=100)
  {
    var color = null;
    if (!(n % 1000))
    {
      color = "black";
    }
    else if (secondwidth > THRESH_500MS && !(n % 500))
    {
      color = "gray";
    }
    else if (secondwidth > THRESH_100MS && !(n % 100))
    {
      color = "silver";
    }

    if (color) {
      ret.push(["line",
                "x1", String(n*multiplier),
                "y1", "0",
                "x2", String(n*multiplier),
                "y2", String(height),
                "stroke", color,
                "stroke-width", "0.5",
                "opacity", "0.7"
      ]);
    }
  }

  return ret;
};

templates.gradient_defs = function()
{
  return ["defs",
          templates.gradient("image", "#F1B5B5", "#F1B5B5", "#F1B5B5", "#ffffff"),
          templates.gradient("script", "#FAEFBB","#FAEFBB","#FAEFBB", "#ffffff"),
          templates.gradient("css", "#C4D9F5", "#C4D9F5", "#C4D9F5", "#ffffff"),
          templates.gradient("markup", "#CCD3FF", "#CCD3FF", "#CCD3FF", "#ffffff"),
          templates.gradient("unknown", "#E6E6E6", "#E6E6E6", "#E6E6E6", "#ffffff")
         ];
};

templates.gradient = function(id, c1, c2, c3, c4)
{
  return ["linearGradient",
          ["stop", "offset", "5%", "stop-color", c1],
          ["stop", "offset", "50%", "stop-color", c2],
          ["stop", "offset", "50%", "stop-color", c3],
          ["stop", "offset", "100%", "stop-color", c4],
          "x1", "0",
          "x2", "0",
          "y1", "0",
          "y2", "100%",
          "id", "gradient-" + id
         ];
};

templates.network_log_background = function(ctx, lineheight)
{
  var cnt = ctx.resources.length;
  var tpls = [];
  while (cnt--)
  {
    tpls.push(["rect", "x", "0",
                       "y", String(cnt*lineheight),
                       "width", "100%",
                       "height", String(lineheight),
                       "stroke-width", "0", "fill", (cnt%2 ?  "#dddddd" : "white")]);
  }
  return tpls;
};
<|endoftext|>


<commit_before>'use strict';
/**
 * Created by gjr8050 on 2/24/2017.
 */

const IOEvent = require('event-types').IOEvent;

function socketFactory($socket, $q, HttpConfig) {

    class Socket {

        constructor(credentials) {
            const io = require('socket.io-client')(`http://${location.host}`, {query: HttpConfig.getQueryString(credentials)});
            const ioSocket = io.connect();

            this.socket = $socket({ioSocket: ioSocket});
        }

        /**
         *
         * @param event {string}: event to trigger
         * @param body {any}: data to send
         * @param timeoutDuration=3000 {number}: milliseconds before request fails
         * @returns {Promise}
         */
        request(event, body, timeoutDuration = 3000) {
            return $q((resolve, reject) => {
                const id = ~~(Math.random() * 100000);
                this.socket.emit(event, {reqId: id, body});

                let timer = null;
                if(typeof timeoutDuration === 'number') {
                    timer = setTimeout(()=>reject('Request Timed Out'), timeoutDuration);
                }

                const responseKey = `${event}-${id}`;
                const errorKey = `${IOEvent.serverError}-${id}`;

                function endRequest(socket) {
                    socket.removeAllListeners(responseKey);
                    socket.removeAllListeners(errorKey);
                    clearTimeout(timer);
                }

                this.socket.on(responseKey, (data) => {
                    endRequest(this.socket);
                    resolve(data);
                });

                this.socket.on(errorKey, (err) => {
                    endRequest(this.socket);
                    reject(err);
                })
            });
        }

        get(){
            return this.socket;
        }
    }

    return Socket;
}

module.exports = socketFactory;<commit_msg> HTTPSSSS<commit_after>'use strict';
/**
 * Created by gjr8050 on 2/24/2017.
 */

const IOEvent = require('event-types').IOEvent;

function socketFactory($socket, $q, HttpConfig) {

    class Socket {

        constructor(credentials) {
            const io = require('socket.io-client')(`${location.protocol}//${location.host}`, {query: HttpConfig.getQueryString(credentials)});
            const ioSocket = io.connect();

            this.socket = $socket({ioSocket: ioSocket});
        }

        /**
         *
         * @param event {string}: event to trigger
         * @param body {any}: data to send
         * @param timeoutDuration=3000 {number}: milliseconds before request fails
         * @returns {Promise}
         */
        request(event, body, timeoutDuration = 3000) {
            return $q((resolve, reject) => {
                const id = ~~(Math.random() * 100000);
                this.socket.emit(event, {reqId: id, body});

                let timer = null;
                if(typeof timeoutDuration === 'number') {
                    timer = setTimeout(()=>reject('Request Timed Out'), timeoutDuration);
                }

                const responseKey = `${event}-${id}`;
                const errorKey = `${IOEvent.serverError}-${id}`;

                function endRequest(socket) {
                    socket.removeAllListeners(responseKey);
                    socket.removeAllListeners(errorKey);
                    clearTimeout(timer);
                }

                this.socket.on(responseKey, (data) => {
                    endRequest(this.socket);
                    resolve(data);
                });

                this.socket.on(errorKey, (err) => {
                    endRequest(this.socket);
                    reject(err);
                })
            });
        }

        get(){
            return this.socket;
        }
    }

    return Socket;
}

module.exports = socketFactory;<|endoftext|>


<commit_before>var Url = require('url')
var defaults = require('lodash.defaultsdeep')
var defined = require('defined')

var isProd = require('util/isProd')
var config = require('../../../node_modules/config')

config.services.forEach(function (serviceName) {
  config[serviceName] = defined(config[serviceName], {})
  defaults(config[serviceName], { url: config.url })

  // HACK because of dokku:
  // unset config ports for production server
  if (isProd) {
    config[serviceName].url.port = undefined
  }
})

module.exports = config
<commit_msg>really pesky config bug<commit_after>var Url = require('url')
var defaults = require('lodash.defaultsdeep')
var clone = require('lodash.clone')
var defined = require('defined')

var isProd = require('util/isProd')
var config = require('../../../node_modules/config')

config.services.forEach(function (serviceName) {
  if (config[serviceName] == null) {
    config[serviceName] = {}
  }
  defaults(config[serviceName], { url: clone(config.url) })

  // HACK because of dokku:
  // unset config ports for production server
  if (isProd) {
    delete config[serviceName].url.port
  }
})

module.exports = config
<|endoftext|>


<commit_before>import React from 'react';
import { omit } from 'lodash';
import bem from '../bem';

function Button(props) {
    let { state, label } = props;

    if (state === 'hidden') {
        return null;
    }
    let newProps = omit(props, ['state', 'label']);
    return (
        <button
            {...newProps}
            className={bem('button')
                .extra(props.className)
                .mod(state)}>
            {label}
        </button>
    )
}

export default Button;<commit_msg>simplified code without dependency<commit_after>import React from 'react'
import bem from '../bem'

function Button(props) {
    if (props.state === 'hidden') {
        return null
    }
    let newProps = Object.assign({}, props)
    newProps.state = null

    return (
        <button
            {...newProps}
            className={bem('button')
                .extra(props.className)
                .mod(state)}
        >
            {props.children}
        </button>
    )
}

export default Button
<|endoftext|>


<commit_before>describe('the Waitingpopup jQuery Plugin',function(){

	// Remove any exisiting toastmessage container
	beforeEach(function() {
        $('#waiting_popup').dialog('destroy');
        $('#waiting_popup').remove();

        this.addMatchers({
            waitingPopupCreated : function() { return $('.waitingpopup').length > 0; },
            waitingPopupVisible : function() { return $('.waitingpopup').is(':visible'); }
        });
    });

	//Clean it up after each spec
	afterEach(function() {
        $('#waiting_popup').dialog('destroy');
        $('#waiting_popup').remove();
	});

    describe('Showing and Hiding of the waitingpopup', function() {
        it('opens the waitingpopup window', function() {
            $().waitingpopup({sublableText: 'waiting'});
            $().waitingpopup('open');

            expect().waitingPopupCreated();
            expect().waitingPopupVisible();
        });
        it('closes the waitingpopup window', function() {

            $().waitingpopup({sublableText: 'waiting'});
            $().waitingpopup('open');

            expect().waitingPopupCreated();
            expect().waitingPopupVisible();

            $().waitingpopup('close');
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();
        });
    });

    describe('Ajax binding of the waitingpopup', function() {
        it('binds to jQuery Ajax calls automatically', function() {
            $().waitingpopup({ajaxBinding : true});

            // Ajax Binding should be done right now
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();

            // Doing some ajax stuff
            $.ajax({
                url: 'src/jquery.waitingpopup.js',
                beforeSend: function(XMLHttpRequest) {
                    expect().waitingPopupVisible();
                }
            });
            waits(1000); // Waiting a second

            // Waiting Popup should now be gone
            runs(function() {
                expect().not.waitingPopupVisible();
            });
        });
        it('binds not to jQuery Ajax calls automatically', function() {
            $().waitingpopup({ajaxBinding : false});

            // Ajax Binding should be done right now
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();

            // Doing some ajax stuff
            $.ajax({
                url: 'src/jquery.waitingpopup.js',
                beforeSend: function(XMLHttpRequest) {
                    expect().not.waitingPopupVisible();
                }
            });
            waits(1000); // Waiting a second

            // Waiting Popup should now be gone
            runs(function() {
                expect().not.waitingPopupVisible();
            });
        });
        it('binds to jQuery Ajax calls programmatically', function() {
            $().waitingpopup({ajaxBinding : false});

            // Ajax Binding should be done right now
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();

            // Doing some ajax stuff
            $.ajax({
                url: 'src/jquery.waitingpopup.js',
                beforeSend: function(XMLHttpRequest) {
                    expect().not.waitingPopupVisible();
                }
            });
            waits(1000); // Waiting a second

            runs(function() {
                expect().not.waitingPopupVisible();
            });

            // now enabling ajaxbinding via api call
            runs(function () {
                $().waitingpopup('bindToAjax');

                // Doing some ajax stuff
                $.ajax({
                    url: 'src/jquery.waitingpopup.js',
                    beforeSend: function(XMLHttpRequest) {
                        expect().waitingPopupVisible();
                    }
                });
            });
            waits(1000); // Waiting a second

            runs(function() {
                expect().not.waitingPopupVisible();
            });
        });
    });
});<commit_msg>fixed typo in doc<commit_after>describe('the Waitingpopup jQuery Plugin',function(){

	// Remove any exisiting waitingpopup dialogs
	beforeEach(function() {
        $('#waiting_popup').dialog('destroy');
        $('#waiting_popup').remove();

        this.addMatchers({
            waitingPopupCreated : function() { return $('.waitingpopup').length > 0; },
            waitingPopupVisible : function() { return $('.waitingpopup').is(':visible'); }
        });
    });

	//Clean it up after each spec
	afterEach(function() {
        $('#waiting_popup').dialog('destroy');
        $('#waiting_popup').remove();
	});

    describe('Showing and Hiding of the waitingpopup', function() {
        it('opens the waitingpopup window', function() {
            $().waitingpopup({sublableText: 'waiting'});
            $().waitingpopup('open');

            expect().waitingPopupCreated();
            expect().waitingPopupVisible();
        });
        it('closes the waitingpopup window', function() {

            $().waitingpopup({sublableText: 'waiting'});
            $().waitingpopup('open');

            expect().waitingPopupCreated();
            expect().waitingPopupVisible();

            $().waitingpopup('close');
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();
        });
    });

    describe('Ajax binding of the waitingpopup', function() {
        it('binds to jQuery Ajax calls automatically', function() {
            $().waitingpopup({ajaxBinding : true});

            // Ajax Binding should be done right now
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();

            // Doing some ajax stuff
            $.ajax({
                url: 'src/jquery.waitingpopup.js',
                beforeSend: function(XMLHttpRequest) {
                    expect().waitingPopupVisible();
                }
            });
            waits(1000); // Waiting a second

            // Waiting Popup should now be gone
            runs(function() {
                expect().not.waitingPopupVisible();
            });
        });
        it('binds not to jQuery Ajax calls automatically', function() {
            $().waitingpopup({ajaxBinding : false});

            // Ajax Binding should be done right now
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();

            // Doing some ajax stuff
            $.ajax({
                url: 'src/jquery.waitingpopup.js',
                beforeSend: function(XMLHttpRequest) {
                    expect().not.waitingPopupVisible();
                }
            });
            waits(1000); // Waiting a second

            // Waiting Popup should now be gone
            runs(function() {
                expect().not.waitingPopupVisible();
            });
        });
        it('binds to jQuery Ajax calls programmatically', function() {
            $().waitingpopup({ajaxBinding : false});

            // Ajax Binding should be done right now
            expect().waitingPopupCreated();
            expect().not.waitingPopupVisible();

            // Doing some ajax stuff
            $.ajax({
                url: 'src/jquery.waitingpopup.js',
                beforeSend: function(XMLHttpRequest) {
                    expect().not.waitingPopupVisible();
                }
            });
            waits(1000); // Waiting a second

            runs(function() {
                expect().not.waitingPopupVisible();
            });

            // now enabling ajaxbinding via api call
            runs(function () {
                $().waitingpopup('bindToAjax');

                // Doing some ajax stuff
                $.ajax({
                    url: 'src/jquery.waitingpopup.js',
                    beforeSend: function(XMLHttpRequest) {
                        expect().waitingPopupVisible();
                    }
                });
            });
            waits(1000); // Waiting a second

            runs(function() {
                expect().not.waitingPopupVisible();
            });
        });
    });
});<|endoftext|>


<commit_before>import Orbit from 'orbit/core';
import Evented from 'orbit/evented';

var Transformable = {
  extend: function(object, actions) {
    if (object._requestable === undefined) {
      this._requestable = true;

      Evented.extend(object);

      object.didTransform = function(action, type, data) {
        return object.settle.call(object, 'didTransform', action, type, data);
      };

      object.transform = function(action, type, data) {
        Orbit.assert('_tranform must be defined', object._transform);

        return object._transform.call(object, action, type, data).then(
          function(result) {
            return object.didTransform.call(object, action, type, result).then(
              function() {
                return result;
              }
            );
          },
          function(error) {
            return object.settle.call(object, 'didNotTransform', action, type, data, error).then(
              function() {
                throw error;
              }
            );
          }
        );
      };
    }
    return object;
  }
};

export default Transformable;<commit_msg>Fix typo in assertion<commit_after>import Orbit from 'orbit/core';
import Evented from 'orbit/evented';

var Transformable = {
  extend: function(object, actions) {
    if (object._requestable === undefined) {
      this._requestable = true;

      Evented.extend(object);

      object.didTransform = function(action, type, data) {
        return object.settle.call(object, 'didTransform', action, type, data);
      };

      object.transform = function(action, type, data) {
        Orbit.assert('_transform must be defined', object._transform);

        return object._transform.call(object, action, type, data).then(
          function(result) {
            return object.didTransform.call(object, action, type, result).then(
              function() {
                return result;
              }
            );
          },
          function(error) {
            return object.settle.call(object, 'didNotTransform', action, type, data, error).then(
              function() {
                throw error;
              }
            );
          }
        );
      };
    }
    return object;
  }
};

export default Transformable;<|endoftext|>


<commit_before>import React from 'react'
import createHelper from './createHelper'
import createEagerFactory from './createEagerFactory'

const identity = component => component

const branch = (test, left, right = identity) => BaseComponent =>
  class extends React.Component {
    LeftComponent = null;
    RightComponent = null;

    constructor(props, context) {
      super(props, context)
      this.computeChildComponent(this.props)
    }

    computeChildComponent(props) {
      if (test(props)) {
        this.leftFactory =
          this.leftFactory || createEagerFactory(left(BaseComponent))
        this.factory = this.leftFactory
      } else {
        this.rightFactory =
          this.rightFactory || createEagerFactory(right(BaseComponent))
        this.factory = this.rightFactory
      }
    }

    componentWillReceiveProps(nextProps) {
      this.computeChildComponent(nextProps)
    }

    render() {
      return this.factory(this.props)
    }
  }

export default createHelper(branch, 'branch')
<commit_msg>Fix branch bug<commit_after>import React from 'react'
import createHelper from './createHelper'
import createEagerFactory from './createEagerFactory'

const identity = component => component

const branch = (test, left, right) => BaseComponent =>
  class extends React.Component {
    LeftComponent = null;
    RightComponent = null;

    constructor(props, context) {
      super(props, context)
      this.computeChildComponent(this.props)
    }

    computeChildComponent(props) {
      if (test(props)) {
        this.leftFactory =
          this.leftFactory || createEagerFactory(left(BaseComponent))
        this.factory = this.leftFactory
      } else {
        this.rightFactory =
          this.rightFactory ||
            createEagerFactory((right || identity)(BaseComponent))
        this.factory = this.rightFactory
      }
    }

    componentWillReceiveProps(nextProps) {
      this.computeChildComponent(nextProps)
    }

    render() {
      return this.factory(this.props)
    }
  }

export default createHelper(branch, 'branch')
<|endoftext|>


<commit_before>import URL from './URLShim';
import { PalindromError, PalindromConnectionError } from './palindrom-errors';
/* this package will be empty in the browser bundle,
and will import https://www.npmjs.com/package/websocket in node */
import WebSocket from 'websocket';
import nodeFetch from 'node-fetch';

const CLIENT = 'Client';
const SERVER = 'Server';

/**
 * Replaces http and https to ws and wss in a URL and returns it as a string.
 * @param  {String} remoteUrl HTTP remote address
 * @return {String}           WS address
 */
function toWebSocketURL(remoteUrl) {
    /* replace 'http' strictly in the beginning of the string,
    this covers http and https */
    return remoteUrl.replace(/^http/i, 'ws');
}

export default class PalindromNetworkChannel {
    constructor(
        palindrom,
        remoteUrl,
        useWebSocket,
        onReceive,
        onSend,
        onConnectionError,
        onSocketOpened,
        onFatalError,
        onStateChange
    ) {
        // TODO(tomalec): to be removed once we will achieve better separation of concerns
        this.palindrom = palindrom;

        if (typeof window !== 'undefined' && window.location) {
            this.remoteUrl = new URL(remoteUrl, window.location.href);
        } else {
            // in Node, URL is absolute
            this.remoteUrl = new URL(remoteUrl);
        }

        onReceive && (this.onReceive = onReceive);
        onSend && (this.onSend = onSend);
        onConnectionError && (this.onConnectionError = onConnectionError);
        onFatalError && (this.onFatalError = onFatalError);
        onStateChange && (this.onStateChange = onStateChange);
        onSocketOpened && (this.onSocketOpened = onSocketOpened);

        Object.defineProperty(this, 'useWebSocket', {
            get: function() {
                return useWebSocket;
            },
            set: newValue => {
                useWebSocket = newValue;

                if (newValue == false) {
                    if (this._ws) {
                        this._ws.onclose = function() {
                            //overwrites the previous onclose
                            this._ws = null;
                        };
                        this._ws.close();
                    }
                    // define wsUrl if needed
                } else if (!this.wsUrl) {
                    this.wsUrl = toWebSocketURL(this.remoteUrl.href);
                }
                return useWebSocket;
            }
        });
    }
    get useWebSocket() {
        return this._useWebSocket;
    }
    set useWebSocket(newValue) {
        this._useWebSocket = newValue;

        if (newValue == false) {
            if (this._ws) {
                this._ws.onclose = () => {
                    //overwrites the previous onclose
                    this._ws = null;
                };
                this._ws.close();
            }
            // define wsUrl if needed
        } else if (!this.wsUrl) {
            this.wsUrl = toWebSocketURL(this.remoteUrl.href);
        }
        return this.useWebSocket;
    }

    async _establish(reconnectionPendingData = null) {
        const data = await this._xhr(
            this.remoteUrl.href + (reconnectionPendingData ? '/reconnect' : ''),
            'application/json',
            reconnectionPendingData
        );
        if (this.useWebSocket) {
            this.webSocketUpgrade(this.onSocketOpened);
        }
        return data;
    }

    /**
     * Send any text message by currently established channel
     * @TODO: handle readyState 2-CLOSING & 3-CLOSED (tomalec)
     * @param  {String} msg message to be sent
     * @return {PalindromNetworkChannel}     self
     */
    async send(msg) {
        // send message only if there is a working ws connection
        if (this.useWebSocket && this._ws && this._ws.readyState === 1) {
            this._ws.send(msg);
            this.onSend(msg, this._ws.url,'WS');
        } else {
            const url = this.remoteUrl.href;
            const data = await this._xhr(
                url,
                'application/json-patch+json',
                msg
            );
            this.onReceive(data, url, 'GET');
        }
        return this;
    }

    /**
     * Callback function that will be called once message from remote comes.
     * @param {String} [JSONPatch_sequences] message with Array of JSONPatches that were send by remote.
     * @return {[type]} [description]
     */
    onReceive(/*String_with_JSONPatch_sequences*/) {}

    onSend() {}
    onStateChange() {}
    upgrade(msg) {}

    /**
     * Send a WebSocket upgrade request to the server.
     * For testing purposes WS upgrade url is hard-coded now in Palindrom (replace __default/ID with __default/ID)
     * In future, server should suggest the WebSocket upgrade URL
     * @TODO:(tomalec)[cleanup] hide from public API.
     * @param {Function} [callback] Function to be called once connection gets opened.
     * @returns {WebSocket} created WebSocket
     */
    webSocketUpgrade(onSocketOpenCallback) {
        this.wsUrl = toWebSocketURL(this.remoteUrl.href);
        const upgradeURL = this.wsUrl;

        this.closeConnection();
        // in node, WebSocket will have `w3cwebsocket` prop. In the browser it won't

        const UsedSocket = WebSocket.w3cwebsocket || WebSocket;
        this._ws = new UsedSocket(upgradeURL);
        this._ws.onopen = event => {
            this.onStateChange(this._ws.readyState, upgradeURL);
            onSocketOpenCallback && onSocketOpenCallback(event);
        };
        this._ws.onmessage = event => {
            try {
                var parsedMessage = JSON.parse(event.data);
            } catch (e) {
                this.onFatalError(
                    new PalindromConnectionError(
                        event.data,
                        SERVER,
                        this._ws.url,
                        'WS'
                    )
                );
                return;
            }
            this.onReceive(parsedMessage, this._ws.url, 'WS');
        };
        this._ws.onerror = event => {
            this.onStateChange(this._ws.readyState, upgradeURL, event.data);

            if (!this.useWebSocket) {
                return;
            }

            const message = [
                'WebSocket connection could not be made',
                'readyState: ' + this._ws.readyState
            ].join('\n');

            this.onFatalError(
                new PalindromConnectionError(message, CLIENT, upgradeURL, 'WS')
            );
        };
        this._ws.onclose = event => {
            this.onStateChange(
                this._ws.readyState,
                upgradeURL,
                null,
                event.code,
                event.reason
            );

            const message = [
                'WebSocket connection closed unexpectedly.',
                'reason: ' + event.reason,
                'readyState: ' + this._ws.readyState,
                'stateCode: ' + event.code
            ].join('\n');

            if (event.reason) {
                this.onFatalError(
                    new PalindromConnectionError(
                        message,
                        SERVER,
                        upgradeURL,
                        'WS'
                    )
                );
            } else if (!event.wasClean) {
                this.onConnectionError(
                    new PalindromConnectionError(
                        message,
                        SERVER,
                        upgradeURL,
                        'WS'
                    )
                );
            }
        };
    }
    closeConnection() {
        if (this._ws) {
            this._ws.onclose = () => {};
            this._ws.close();
            this._ws = null;
        }
    }
    /**
     * @param {String} href
     * @throws {Error} network error if occured
     */
    async getPatchUsingHTTP(href) {
        // we don't need to try catch here because we want the error to be thrown at whoever calls getPatchUsingHTTP
        const data = await this._xhr(
            href,
            'application/json-patch+json',
            null,
            true
        );
        this.onReceive(data, href, 'GET');
        return data;
    }

    _setRemoteUrl(remoteUrl) {
        if (
            this.remoteUrlSet &&
            this.remoteUrl &&
            this.remoteUrl != remoteUrl
        ) {
            const message = [
                'Session lost.',
                'Server replied with a different session ID than the already set one.',
                'Possibly a server restart happened while you were working.',
                'Please reload the page.',
                'Previous session ID: ' + this.remoteUrl,
                'New session ID: ' + remoteUrl
            ].join('\n');

            throw new PalindromError(message);
        }
        this.remoteUrlSet = true;
        this.remoteUrl = new URL(remoteUrl, this.remoteUrl.href);
    }

    _handleLocationHeader(res) {
        const location = res.headers.get('x-location') || res.headers.get('location');
        if (location) {
            this._setRemoteUrl(location);
        }
    }
    /**
     * Handles unsecessful HTTP requests
     * @param error
     */
    async _handleFailureResponse(url, method, error) {
        // no sufficient error information, we need to create on our own
        var statusCode = -1;
        var statusText = `An unknown network error has occurred. Raw message: ${
            error.message
        }`;
        var reason = 'Maybe you lost connection with the server';
        // log it for verbosity
        console.error(error);

        const message = [
            statusText,
            'statusCode: ' + statusCode,
            'reason: ' + reason,
            'url: ' + url,
            'HTTP method: ' + method
        ].join('\n');

        this.onConnectionError(
            new PalindromConnectionError(message, CLIENT, url, method)
        );
    }

    /**
     * Internal method to perform XMLHttpRequest
     * @param url (Optional) URL to send the request. If empty string, undefined or null given - the request will be sent to window location
     * @param accept (Optional) HTTP accept header
     * @param data (Optional) Data payload
     * @returns {XMLHttpRequest} performed XHR
     */
    async _xhr(url, accept, data, setReferer) {
        const method = data ? 'PATCH' : 'GET';
        const config = { headers: {}, method, credentials: 'include' };
        const headers = config.headers;

        if (data) {
            headers['Content-Type'] = 'application/json-patch+json';
            config.body = JSON.stringify(data);
        }
        if (accept) {
            headers['Accept'] = accept;
        }
        if (this.remoteUrl && setReferer) {
            headers['X-Referer'] = this.remoteUrl.pathname;
        }

        this.onSend(data, url, method);

        let isomorphicFetch = typeof global !== 'undefined' ?  global.fetch : nodeFetch;

        const response = await isomorphicFetch(url, config);
        const dataPromise = response.json();

        return dataPromise
            .then(data => {
                // if we're here, it's a valid JSON response
                // response.ok is `false` for 4xx responses
                if (response.status < 500) {
                    this._handleLocationHeader(response);
                    return data;
                } else {
                    const error = new Error(`HTTP ${response.status} response: response body is ${JSON.stringify(data)}`);
                    throw error;
                }
            })
            .catch(error => {
                this._handleFailureResponse(url, method, error);
                throw error;
            });
    }
}
<commit_msg>Remove HTTP method picking logic out of `_xhr`,<commit_after>import URL from './URLShim';
import { PalindromError, PalindromConnectionError } from './palindrom-errors';
/* this package will be empty in the browser bundle,
and will import https://www.npmjs.com/package/websocket in node */
import WebSocket from 'websocket';
import nodeFetch from 'node-fetch';

const CLIENT = 'Client';
const SERVER = 'Server';

/**
 * Replaces http and https to ws and wss in a URL and returns it as a string.
 * @param  {String} remoteUrl HTTP remote address
 * @return {String}           WS address
 */
function toWebSocketURL(remoteUrl) {
    /* replace 'http' strictly in the beginning of the string,
    this covers http and https */
    return remoteUrl.replace(/^http/i, 'ws');
}

export default class PalindromNetworkChannel {
    constructor(
        palindrom,
        remoteUrl,
        useWebSocket,
        onReceive,
        onSend,
        onConnectionError,
        onSocketOpened,
        onFatalError,
        onStateChange
    ) {
        // TODO(tomalec): to be removed once we will achieve better separation of concerns
        this.palindrom = palindrom;

        if (typeof window !== 'undefined' && window.location) {
            this.remoteUrl = new URL(remoteUrl, window.location.href);
        } else {
            // in Node, URL is absolute
            this.remoteUrl = new URL(remoteUrl);
        }

        onReceive && (this.onReceive = onReceive);
        onSend && (this.onSend = onSend);
        onConnectionError && (this.onConnectionError = onConnectionError);
        onFatalError && (this.onFatalError = onFatalError);
        onStateChange && (this.onStateChange = onStateChange);
        onSocketOpened && (this.onSocketOpened = onSocketOpened);

        Object.defineProperty(this, 'useWebSocket', {
            get: function() {
                return useWebSocket;
            },
            set: newValue => {
                useWebSocket = newValue;

                if (newValue == false) {
                    if (this._ws) {
                        this._ws.onclose = function() {
                            //overwrites the previous onclose
                            this._ws = null;
                        };
                        this._ws.close();
                    }
                    // define wsUrl if needed
                } else if (!this.wsUrl) {
                    this.wsUrl = toWebSocketURL(this.remoteUrl.href);
                }
                return useWebSocket;
            }
        });
    }
    get useWebSocket() {
        return this._useWebSocket;
    }
    set useWebSocket(newValue) {
        this._useWebSocket = newValue;

        if (newValue == false) {
            if (this._ws) {
                this._ws.onclose = () => {
                    //overwrites the previous onclose
                    this._ws = null;
                };
                this._ws.close();
            }
            // define wsUrl if needed
        } else if (!this.wsUrl) {
            this.wsUrl = toWebSocketURL(this.remoteUrl.href);
        }
        return this.useWebSocket;
    }

    async _establish(reconnectionPendingData = null) {
        const data = await this._xhr(
            reconnectionPendingData ? 'PATCH' : 'GET',
            this.remoteUrl.href + (reconnectionPendingData ? '/reconnect' : ''),
            'application/json',
            reconnectionPendingData
        );
        if (this.useWebSocket) {
            this.webSocketUpgrade(this.onSocketOpened);
        }
        return data;
    }

    /**
     * Send any text message by currently established channel
     * @TODO: handle readyState 2-CLOSING & 3-CLOSED (tomalec)
     * @param  {String} msg message to be sent
     * @return {PalindromNetworkChannel}     self
     */
    async send(msg) {
        // send message only if there is a working ws connection
        if (this.useWebSocket && this._ws && this._ws.readyState === 1) {
            this._ws.send(msg);
            this.onSend(msg, this._ws.url,'WS');
        } else {
            const url = this.remoteUrl.href;
            const data = await this._xhr(
                'PATCH',
                url,
                'application/json-patch+json',
                msg
            );
            this.onReceive(data, url, 'PATCH');
        }
        return this;
    }

    /**
     * Callback function that will be called once message from remote comes.
     * @param {String} [JSONPatch_sequences] message with Array of JSONPatches that were send by remote.
     * @return {[type]} [description]
     */
    onReceive(/*String_with_JSONPatch_sequences*/) {}

    onSend() {}
    onStateChange() {}
    upgrade(msg) {}

    /**
     * Send a WebSocket upgrade request to the server.
     * For testing purposes WS upgrade url is hard-coded now in Palindrom (replace __default/ID with __default/ID)
     * In future, server should suggest the WebSocket upgrade URL
     * @TODO:(tomalec)[cleanup] hide from public API.
     * @param {Function} [callback] Function to be called once connection gets opened.
     * @returns {WebSocket} created WebSocket
     */
    webSocketUpgrade(onSocketOpenCallback) {
        this.wsUrl = toWebSocketURL(this.remoteUrl.href);
        const upgradeURL = this.wsUrl;

        this.closeConnection();
        // in node, WebSocket will have `w3cwebsocket` prop. In the browser it won't

        const UsedSocket = WebSocket.w3cwebsocket || WebSocket;
        this._ws = new UsedSocket(upgradeURL);
        this._ws.onopen = event => {
            this.onStateChange(this._ws.readyState, upgradeURL);
            onSocketOpenCallback && onSocketOpenCallback(event);
        };
        this._ws.onmessage = event => {
            try {
                var parsedMessage = JSON.parse(event.data);
            } catch (e) {
                this.onFatalError(
                    new PalindromConnectionError(
                        event.data,
                        SERVER,
                        this._ws.url,
                        'WS'
                    )
                );
                return;
            }
            this.onReceive(parsedMessage, this._ws.url, 'WS');
        };
        this._ws.onerror = event => {
            this.onStateChange(this._ws.readyState, upgradeURL, event.data);

            if (!this.useWebSocket) {
                return;
            }

            const message = [
                'WebSocket connection could not be made',
                'readyState: ' + this._ws.readyState
            ].join('\n');

            this.onFatalError(
                new PalindromConnectionError(message, CLIENT, upgradeURL, 'WS')
            );
        };
        this._ws.onclose = event => {
            this.onStateChange(
                this._ws.readyState,
                upgradeURL,
                null,
                event.code,
                event.reason
            );

            const message = [
                'WebSocket connection closed unexpectedly.',
                'reason: ' + event.reason,
                'readyState: ' + this._ws.readyState,
                'stateCode: ' + event.code
            ].join('\n');

            if (event.reason) {
                this.onFatalError(
                    new PalindromConnectionError(
                        message,
                        SERVER,
                        upgradeURL,
                        'WS'
                    )
                );
            } else if (!event.wasClean) {
                this.onConnectionError(
                    new PalindromConnectionError(
                        message,
                        SERVER,
                        upgradeURL,
                        'WS'
                    )
                );
            }
        };
    }
    closeConnection() {
        if (this._ws) {
            this._ws.onclose = () => {};
            this._ws.close();
            this._ws = null;
        }
    }
    /**
     * @param {String} href
     * @throws {Error} network error if occured
     * @returns {Promise<Object>} fetched patch
     * @see #_xhr
     */
    async getPatchUsingHTTP(href) {
        // we don't need to try catch here because we want the error to be thrown at whoever calls getPatchUsingHTTP
        const data = await this._xhr(
            'GET',
            href,
            'application/json-patch+json',
            null,
            true
        );
        this.onReceive(data, href, 'GET');
        return data;
    }

    _setRemoteUrl(remoteUrl) {
        if (
            this.remoteUrlSet &&
            this.remoteUrl &&
            this.remoteUrl != remoteUrl
        ) {
            const message = [
                'Session lost.',
                'Server replied with a different session ID than the already set one.',
                'Possibly a server restart happened while you were working.',
                'Please reload the page.',
                'Previous session ID: ' + this.remoteUrl,
                'New session ID: ' + remoteUrl
            ].join('\n');

            throw new PalindromError(message);
        }
        this.remoteUrlSet = true;
        this.remoteUrl = new URL(remoteUrl, this.remoteUrl.href);
    }

    _handleLocationHeader(res) {
        const location = res.headers.get('x-location') || res.headers.get('location');
        if (location) {
            this._setRemoteUrl(location);
        }
    }
    /**
     * Handles unsecessful HTTP requests
     * @param error
     */
    async _handleFailureResponse(url, method, error) {
        // no sufficient error information, we need to create on our own
        var statusCode = -1;
        var statusText = `An unknown network error has occurred. Raw message: ${
            error.message
        }`;
        var reason = 'Maybe you lost connection with the server';
        // log it for verbosity
        console.error(error);

        const message = [
            statusText,
            'statusCode: ' + statusCode,
            'reason: ' + reason,
            'url: ' + url,
            'HTTP method: ' + method
        ].join('\n');

        this.onConnectionError(
            new PalindromConnectionError(message, CLIENT, url, method)
        );
    }

    /**
     * Internal method to perform HTTP Request.
     * Requests PATCH if there is given `data`, GET otherwie.
     * @param {String} method HTTP method to be used
     * @param {String} [url=window.location] URL to send the request. If empty string, undefined or null given - the request will be sent to window location
     * @param {String} [accept] HTTP accept header
     * @param {Object} [data] Data payload
     * @returns {Promise<Object>} promise for fetched JSON data
     */
    async _xhr(method, url, accept, data, setReferer) {
        const config = { headers: {}, method, credentials: 'include' };
        const headers = config.headers;

        if (data) {
            headers['Content-Type'] = 'application/json-patch+json';
            config.body = JSON.stringify(data);
        }
        if (accept) {
            headers['Accept'] = accept;
        }
        if (this.remoteUrl && setReferer) {
            headers['X-Referer'] = this.remoteUrl.pathname;
        }

        this.onSend(data, url, method);

        let isomorphicFetch = typeof global !== 'undefined' ?  global.fetch : nodeFetch;

        const response = await isomorphicFetch(url, config);
        const dataPromise = response.json();

        return dataPromise
            .then(data => {
                // if we're here, it's a valid JSON response
                // response.ok is `false` for 4xx responses
                if (response.status < 500) {
                    this._handleLocationHeader(response);
                    return data;
                } else {
                    const error = new Error(`HTTP ${response.status} response: response body is ${JSON.stringify(data)}`);
                    throw error;
                }
            })
            .catch(error => {
                this._handleFailureResponse(url, method, error);
                throw error;
            });
    }
}
<|endoftext|>