<commit_before>/*global define*/
/*jslint white:true,browser: true*/
define([
    'bluebird',
    'kb_widget/widgetMount'
], function (
    Promise,
    WidgetMount
) {
    'use strict';

    function factory(config) {
        var widgetMount, runtime = config.runtime,
            routeListener;
        var container;

        function attach(node) {
            container = node.appendChild(document.createElement('div'));
            container.style.display = 'flex';
            container.style.flex = '1 1 0px';
            container.style['flex-direction'] = 'column';
            container.style['overflow-y'] = 'auto';

            return Promise.try(function () {
                widgetMount = WidgetMount.make({
                    runtime: config.runtime,
                    node: container
                });
            });
        }

        function start() {
            routeListener = runtime.recv('app', 'route-widget', function (data) {
                if (data.routeHandler.route.widget) {
                    widgetMount.unmount()
                        .then(function () {
                            return runtime.sendp('ui', 'clearButtons');
                        })
                        .then(function () {
                            return widgetMount.mount(data.routeHandler.route.widget, data.routeHandler.params);
                        })
                        .catch(function (err) {
                            // need a catch-all widget to mount here??
                            console.error('ERROR mounting widget');
                            console.error(err);
                            widgetMount.unmount()
                                .then(function () {
                                    return widgetMount.mountWidget('error', {
                                        title: 'ERROR',
                                        error: err
                                    });
                                })
                                .catch(function (err2) {
                                    console.error('ERROR mounting error widget!');
                                    console.error(err2);
                                    console.error(err);
                                });
                        });
                } else {
                    console.warn('No widget in route');
                }
            });
        }

        function stop() {
            if (routeListener) {
                runtime.drop(routeListener);
            }
        }

        return {
            attach: attach,
            start: start,
            stop: stop
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<commit_msg>add extra info to console.error for widget mount error<commit_after>/*global define*/
/*jslint white:true,browser: true*/
define([
    'bluebird',
    'kb_widget/widgetMount'
], function (
    Promise,
    WidgetMount
) {
    'use strict';

    function factory(config) {
        var widgetMount, runtime = config.runtime,
            routeListener;
        var container;

        function attach(node) {
            container = node.appendChild(document.createElement('div'));
            container.style.display = 'flex';
            container.style.flex = '1 1 0px';
            container.style['flex-direction'] = 'column';
            container.style['overflow-y'] = 'auto';

            return Promise.try(function () {
                widgetMount = WidgetMount.make({
                    runtime: config.runtime,
                    node: container
                });
            });
        }

        function start() {
            routeListener = runtime.recv('app', 'route-widget', function (data) {
                if (data.routeHandler.route.widget) {
                    widgetMount.unmount()
                        .then(function () {
                            return runtime.sendp('ui', 'clearButtons');
                        })
                        .then(function () {
                            return widgetMount.mount(data.routeHandler.route.widget, data.routeHandler.params);
                        })
                        .catch(function (err) {
                            // need a catch-all widget to mount here??
                            console.error('ERROR mounting widget', data);
                            console.error(err);
                            widgetMount.unmount()
                                .then(function () {
                                    return widgetMount.mountWidget('error', {
                                        title: 'ERROR',
                                        error: err
                                    });
                                })
                                .catch(function (err2) {
                                    console.error('ERROR mounting error widget!');
                                    console.error(err2);
                                    console.error(err);
                                });
                        });
                } else {
                    console.warn('No widget in route');
                }
            });
        }

        function stop() {
            if (routeListener) {
                runtime.drop(routeListener);
            }
        }

        return {
            attach: attach,
            start: start,
            stop: stop
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});
<|endoftext|>


<commit_before>'use strict';

var browserify = require('browserify')
  , path = require('path')
  , fs = require('fs');

require('http').createServer(function statical(req, res) {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');

  switch (req.url) {
    case '/':
      req.url = '/index.html';
    break;

    case '/dist/requests.js':
      var compiler
        , stream;

      res.setHeader('Content-Type', 'text/javascript');

      compiler = browserify({ debug: true, standalone: 'Requests' });
      compiler.add(path.join(__dirname, '..', 'browser.js'));

      stream = compiler.bundle();

      stream.pipe(res);
      stream.pipe(fs.createWriteStream(path.join(__dirname, '..', req.url)));
    return;

    case '/stream':
      res.write('first \n');
      setTimeout(function () {
        res.write('second \n');

        setTimeout(function () {
          res.end('final chunk');
        }, 10000);
      }, 100);
    return;
  }

  if (!fs.existsSync(__dirname + req.url)) {
    res.write('<script src="/dist/requests.js"></script>');
    return res.end('Nope, doesn\'t exist.');
  }

  require('fs').createReadStream(__dirname + req.url).pipe(res);
}).listen(+process.argv[2] || 8080, function listening() {
  console.log('Development server is now running on:');
  console.log('');
  console.log('  http://localhost:'+ this.address().port);
  console.log('');
});
<commit_msg>[test] Force flusing<commit_after>'use strict';

var browserify = require('browserify')
  , path = require('path')
  , fs = require('fs');

require('http').createServer(function statical(req, res) {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');

  switch (req.url) {
    case '/':
      req.url = '/index.html';
    break;

    case '/dist/requests.js':
      var compiler
        , stream;

      res.setHeader('Content-Type', 'text/javascript');

      compiler = browserify({ debug: true, standalone: 'Requests' });
      compiler.add(path.join(__dirname, '..', 'browser.js'));

      stream = compiler.bundle();

      stream.pipe(res);
      stream.pipe(fs.createWriteStream(path.join(__dirname, '..', req.url)));
    return;

    case '/stream':
      res.write('[first chunk]');
      setTimeout(function () {
        res.write('[second chunk]');

        setTimeout(function () {
          res.end('[final chunk]');
        }, 10000);
      }, 100);
    return;
  }

  if (!fs.existsSync(__dirname + req.url)) {
    res.write('<script src="/dist/requests.js"></script>');
    return res.end('Nope, doesn\'t exist.');
  }

  require('fs').createReadStream(__dirname + req.url).pipe(res);
}).on('connection', function connection(socket) {
  //
  // Force buffer flusing when we call our write.
  //
  socket.setNoDelay(true);
}).listen(+process.argv[2] || 8080, function listening() {
  console.log('Development server is now running on:');
  console.log('');
  console.log('  http://localhost:'+ this.address().port);
  console.log('');
});
<|endoftext|>


<commit_before>exports.productionVersionId = "9f86362a1e78";<commit_msg>Incrementing Production Version.<commit_after>exports.productionVersionId = "dc60c170ca31";<|endoftext|>


<commit_before>/*
The follwoing code adapted from node's test-dns.js license is as follows
*/

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var dns = require('../dns'),
    net = require('net'),
    isIP = net.isIP,
    isIPv4 = net.isIPv4,
    isIPv6 = net.isIPv6;

var platform = require('../lib/platform');

platform.cache = false;

function checkWrap(test, req) {
  test.ok(typeof req === 'object');
}

var fixed = false;

var fixupDns = function () {
  platform.name_servers = [{
    address: '8.8.8.8',
    port: 53,
  }];

  platform.search_path = [];

  fixed = true;
};

platform.on('ready', fixupDns);

if (platform.ready)
  fixupDns();

exports.setUp = function (cb) {
  var checkReady = function() {
    if (fixed) {
      cb();
    } else {
      process.nextTick(checkReady);
    }
  }
  checkReady();
};

exports.resolve4 = function (test) {
  var req = dns.resolve4('www.google.com', function(err, ips) {
    test.ifError(err);

    test.ok(ips.length > 0);

    for (var i = 0; i < ips.length; i++) {
      test.ok(isIPv4(ips[i]));
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.resolve6 = function (test) {
  var req = dns.resolve6('ipv6.google.com', function(err, ips) {
    test.ifError(err);

    test.ok(ips.length > 0);

    for (var i = 0; i < ips.length; i++) {
      test.ok(isIPv6(ips[i]));
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.reverse_ipv4 = function (test) {
  var req = dns.reverse('8.8.8.8', function(err, domains) {
    test.ifError(err);

    test.ok(domains.length > 0);

    for (var i = 0; i < domains.length; i++) {
      test.ok(domains[i]);
      test.ok(typeof domains[i] === 'string');
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.reverse_ipv6 = function (test) {
  var req = dns.reverse('2001:4860:4860::8888', function(err, domains) {
    test.ifError(err);

    test.ok(domains.length > 0);

    for (var i = 0; i < domains.length; i++) {
      test.ok(domains[i]);
      test.ok(typeof domains[i] === 'string');
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.reverse_bogus = function (test) {
  var error;

  try {
    var req = dns.reverse('bogus ip', function() {
      test.ok(false);
    });
  } catch (e) {
    error = e;
  }

  test.ok(error instanceof Error);
  test.strictEqual(error.errno, 'ENOTIMP');

  test.done();
};

exports.resolveMx = function (test) {
  var req = dns.resolveMx('gmail.com', function(err, result) {
    test.ifError(err);

    test.ok(result.length > 0);

    for (var i = 0; i < result.length; i++) {
      var item = result[i];
      test.ok(item);
      test.ok(typeof item === 'object');

      test.ok(item.exchange);
      test.ok(typeof item.exchange === 'string');

      test.ok(typeof item.priority === 'number');
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.resolveNs = function (test) {
  var req = dns.resolveNs('google.com', function(err, names) {
    test.ifError(err);

    if (names) {
      test.ok(names.length > 0);

      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        test.ok(name);
        test.ok(typeof name === 'string');
      }
    } else {
      test.ok(names);
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.resolveSrv = function (test) {
  var req = dns.resolveSrv('_jabber._tcp.google.com', function(err, result) {
    test.ifError(err);

    test.ok(result.length > 0);

    for (var i = 0; i < result.length; i++) {
      var item = result[i];
      test.ok(item);
      test.ok(typeof item === 'object');

      test.ok(item.name);
      test.ok(typeof item.name === 'string');

      test.ok(typeof item.port === 'number');
      test.ok(typeof item.priority === 'number');
      test.ok(typeof item.weight === 'number');
    }

    test.done();
  });

  checkWrap(test, req);
};

/*
exports.resolveCname = function (test) {
  var req = dns.resolveCname('www.google.com', function(err, names) {
    test.ifError(err);

    test.ok(names.length > 0);

    for (var i = 0; i < names.length; i++) {
      var name = names[i];
      test.ok(name);
      test.ok(typeof name === 'string');
    }

    test.done();
  });

  checkWrap(test, req);
};
*/

exports.resolveTxt = function (test) {
  var req = dns.resolveTxt('google.com', function(err, records) {
    test.ifError(err);
    test.equal(records.length, 1);
    test.equal(records[0].indexOf('v=spf1'), 0);
    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ipv4_explicit = function (test) {
  var req = dns.lookup('www.google.com', 4, function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv4(ip));
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ipv4_implicit = function (test) {
  var req = dns.lookup('www.google.com', function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv4(ip));
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ipv6_explicit = function (test) {
  var req = dns.lookup('ipv6.google.com', 6, function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};

/*
// TODO XXX FIXME Doesn't google require ipv6 for this test to pass?
exports.lookup_ipv6_implicit = function (test) {
  var req = dns.lookup('ipv6.google.com', function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};
//*/

exports.lookup_failure = function (test) {
  var req = dns.lookup('does.not.exist', 4, function(err, ip, family) {
    test.ok(err instanceof Error);
    test.strictEqual(err.errno, dns.NOTFOUND);
    test.strictEqual(err.errno, 'ENOTFOUND');

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_null = function (test) {
  var req = dns.lookup(null, function(err, ip, family) {
    test.ifError(err);
    test.strictEqual(ip, null);
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ip_ipv4 = function (test) {
  var req = dns.lookup('127.0.0.1', function(err, ip, family) {
    test.ifError(err);
    test.strictEqual(ip, '127.0.0.1');
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

//*
exports.lookup_ip_ipv6 = function (test) {
  var req = dns.lookup('::1', function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};
//*/

exports.lookup_localhost_ipv4 = function (test) {
  var req = dns.lookup('localhost', 4, function(err, ip, family) {
    test.ifError(err);
    test.strictEqual(ip, '127.0.0.1');
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_longname = function (test) {
  var name, request;

  var name = '************';
  name += name + '***************'
  name += name + '***************'
  name += name + '***************'
  name += name + '***************'
  name += name + '***************'

  request = dns.lookup(name, 4, function (err, ip, family) {
    test.ok(err, "we should fail");
    test.strictEqual(err.errno, dns.NOTFOUND);

    test.done();
  });
  checkWrap(test, request);
};

exports.lookup_without_nameservers = function(test) {
  platform.name_servers = [];
  dns.lookup('www.google.com', function(err) {
    test.ok(err, 'we should fail');
    test.strictEqual(err.errno, dns.TIMEOUT);
    test.done();
    fixupDns();
  });
};

/* Disabled because it appears to be not working on linux. */
/*
exports.lookup_localhost_ipv6 = function (test) {
  var req = dns.lookup('localhost', 6, function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};
//*/
<commit_msg>Fixed test failing for recursive process.nextTick<commit_after>/*
The follwoing code adapted from node's test-dns.js license is as follows
*/

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var dns = require('../dns'),
    net = require('net'),
    isIP = net.isIP,
    isIPv4 = net.isIPv4,
    isIPv6 = net.isIPv6;

var platform = require('../lib/platform');

platform.cache = false;

function checkWrap(test, req) {
  test.ok(typeof req === 'object');
}

var fixed = false;

var fixupDns = function () {
  platform.name_servers = [{
    address: '8.8.8.8',
    port: 53,
  }];

  platform.search_path = [];

  fixed = true;
};

platform.on('ready', fixupDns);

if (platform.ready)
  fixupDns();

exports.setUp = function (cb) {
  var checkReady = function() {
    if (fixed) {
      cb();
    } else {
      setImmediate(checkReady);
    }
  }
  checkReady();
};

exports.resolve4 = function (test) {
  var req = dns.resolve4('www.google.com', function(err, ips) {
    test.ifError(err);

    test.ok(ips.length > 0);

    for (var i = 0; i < ips.length; i++) {
      test.ok(isIPv4(ips[i]));
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.resolve6 = function (test) {
  var req = dns.resolve6('ipv6.google.com', function(err, ips) {
    test.ifError(err);

    test.ok(ips.length > 0);

    for (var i = 0; i < ips.length; i++) {
      test.ok(isIPv6(ips[i]));
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.reverse_ipv4 = function (test) {
  var req = dns.reverse('8.8.8.8', function(err, domains) {
    test.ifError(err);

    test.ok(domains.length > 0);

    for (var i = 0; i < domains.length; i++) {
      test.ok(domains[i]);
      test.ok(typeof domains[i] === 'string');
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.reverse_ipv6 = function (test) {
  var req = dns.reverse('2001:4860:4860::8888', function(err, domains) {
    test.ifError(err);

    test.ok(domains.length > 0);

    for (var i = 0; i < domains.length; i++) {
      test.ok(domains[i]);
      test.ok(typeof domains[i] === 'string');
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.reverse_bogus = function (test) {
  var error;

  try {
    var req = dns.reverse('bogus ip', function() {
      test.ok(false);
    });
  } catch (e) {
    error = e;
  }

  test.ok(error instanceof Error);
  test.strictEqual(error.errno, 'ENOTIMP');

  test.done();
};

exports.resolveMx = function (test) {
  var req = dns.resolveMx('gmail.com', function(err, result) {
    test.ifError(err);

    test.ok(result.length > 0);

    for (var i = 0; i < result.length; i++) {
      var item = result[i];
      test.ok(item);
      test.ok(typeof item === 'object');

      test.ok(item.exchange);
      test.ok(typeof item.exchange === 'string');

      test.ok(typeof item.priority === 'number');
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.resolveNs = function (test) {
  var req = dns.resolveNs('google.com', function(err, names) {
    test.ifError(err);

    if (names) {
      test.ok(names.length > 0);

      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        test.ok(name);
        test.ok(typeof name === 'string');
      }
    } else {
      test.ok(names);
    }

    test.done();
  });

  checkWrap(test, req);
};

exports.resolveSrv = function (test) {
  var req = dns.resolveSrv('_jabber._tcp.google.com', function(err, result) {
    test.ifError(err);

    test.ok(result.length > 0);

    for (var i = 0; i < result.length; i++) {
      var item = result[i];
      test.ok(item);
      test.ok(typeof item === 'object');

      test.ok(item.name);
      test.ok(typeof item.name === 'string');

      test.ok(typeof item.port === 'number');
      test.ok(typeof item.priority === 'number');
      test.ok(typeof item.weight === 'number');
    }

    test.done();
  });

  checkWrap(test, req);
};

/*
exports.resolveCname = function (test) {
  var req = dns.resolveCname('www.google.com', function(err, names) {
    test.ifError(err);

    test.ok(names.length > 0);

    for (var i = 0; i < names.length; i++) {
      var name = names[i];
      test.ok(name);
      test.ok(typeof name === 'string');
    }

    test.done();
  });

  checkWrap(test, req);
};
*/

exports.resolveTxt = function (test) {
  var req = dns.resolveTxt('google.com', function(err, records) {
    test.ifError(err);
    test.equal(records.length, 1);
    test.equal(records[0].indexOf('v=spf1'), 0);
    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ipv4_explicit = function (test) {
  var req = dns.lookup('www.google.com', 4, function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv4(ip));
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ipv4_implicit = function (test) {
  var req = dns.lookup('www.google.com', function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv4(ip));
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ipv6_explicit = function (test) {
  var req = dns.lookup('ipv6.google.com', 6, function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};

/*
// TODO XXX FIXME Doesn't google require ipv6 for this test to pass?
exports.lookup_ipv6_implicit = function (test) {
  var req = dns.lookup('ipv6.google.com', function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};
//*/

exports.lookup_failure = function (test) {
  var req = dns.lookup('does.not.exist', 4, function(err, ip, family) {
    test.ok(err instanceof Error);
    test.strictEqual(err.errno, dns.NOTFOUND);
    test.strictEqual(err.errno, 'ENOTFOUND');

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_null = function (test) {
  var req = dns.lookup(null, function(err, ip, family) {
    test.ifError(err);
    test.strictEqual(ip, null);
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_ip_ipv4 = function (test) {
  var req = dns.lookup('127.0.0.1', function(err, ip, family) {
    test.ifError(err);
    test.strictEqual(ip, '127.0.0.1');
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

//*
exports.lookup_ip_ipv6 = function (test) {
  var req = dns.lookup('::1', function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};
//*/

exports.lookup_localhost_ipv4 = function (test) {
  var req = dns.lookup('localhost', 4, function(err, ip, family) {
    test.ifError(err);
    test.strictEqual(ip, '127.0.0.1');
    test.strictEqual(family, 4);

    test.done();
  });

  checkWrap(test, req);
};

exports.lookup_longname = function (test) {
  var name, request;

  var name = '************';
  name += name + '***************'
  name += name + '***************'
  name += name + '***************'
  name += name + '***************'
  name += name + '***************'

  request = dns.lookup(name, 4, function (err, ip, family) {
    test.ok(err, "we should fail");
    test.strictEqual(err.errno, dns.NOTFOUND);

    test.done();
  });
  checkWrap(test, request);
};

exports.lookup_without_nameservers = function(test) {
  platform.name_servers = [];
  dns.lookup('www.google.com', function(err) {
    test.ok(err, 'we should fail');
    test.strictEqual(err.errno, dns.TIMEOUT);
    test.done();
    fixupDns();
  });
};

/* Disabled because it appears to be not working on linux. */
/*
exports.lookup_localhost_ipv6 = function (test) {
  var req = dns.lookup('localhost', 6, function(err, ip, family) {
    test.ifError(err);
    test.ok(net.isIPv6(ip));
    test.strictEqual(family, 6);

    test.done();
  });

  checkWrap(test, req);
};
//*/
<|endoftext|>


<commit_before>/*!
 * Rails 3 Client Side Validations - v3.1.0
 * https://github.com/bcardarella/client_side_validations
 *
 * Copyright (c) 2011 Brian Cardarella
 * Licensed under the MIT license
 * http://www.opensource.org/licenses/mit-license.php
 */

(function ($) {
  $.fn.validate = function () {
    return this.filter('form[data-validate]').each(function () {
      var form = $(this),
          settings = window['ClientSideValidations']['forms'][form.attr('id')],
          addError = function (element, message) {
            ClientSideValidations.formBuilders[settings.type].add(element, settings, message);
          },
          removeError = function (element) {
            ClientSideValidations.formBuilders[settings.type].remove(element, settings);
          };

      // Set up the events for the form
      form
        .submit(                      function ()          { return form.isValid(settings.validators); })
        .bind('ajax:beforeSend',      function (eventData) { if(eventData.target == this) return form.isValid(settings.validators); })
        // Callbacks
        .bind('form:validate:after',  function (eventData) { ClientSideValidations.callbacks.form.after( form, eventData); } )
        .bind('form:validate:before', function (eventData) { ClientSideValidations.callbacks.form.before(form, eventData); } )
        .bind('form:validate:fail',   function (eventData) { ClientSideValidations.callbacks.form.fail(  form, eventData); } )
        .bind('form:validate:pass',   function (eventData) { ClientSideValidations.callbacks.form.pass(  form, eventData); } )

        // Set up the events for each validatable form element
        .find('[data-validate="true"]:input:enabled:not(:radio)')
          .live('focusout',                function ()          { $(this).isValid(settings.validators); })
          .live('change',                  function ()          { $(this).data('changed', true); })
          // Callbacks
          .live('element:validate:after',  function (eventData) { ClientSideValidations.callbacks.element.after( $(this), eventData); })
          .live('element:validate:before', function (eventData) { ClientSideValidations.callbacks.element.before($(this), eventData); })
          .live('element:validate:fail',   function (eventData, message) {
            var element = $(this);
            ClientSideValidations.callbacks.element.fail(element, message, function () {
              addError(element, message);
            }, eventData); })
          .live('element:validate:pass',   function (eventData) {
            var element = $(this);
            ClientSideValidations.callbacks.element.pass(element, function () {
              removeError(element);
            }, eventData); })
        // Checkboxes - Live events don't support filter
        .end().find('[data-validate="true"]:checkbox')
          .live('click', function () { $(this).isValid(settings.validators); })
        // Inputs for confirmations
        .end().find('[id*=_confirmation]').each(function () {
          var confirmationElement = $(this),
              element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validate="true"]:input');

          if (element[0]) {
            $('#' + confirmationElement.attr('id'))
              .live('focusout', function () {
                element.data('changed', true).isValid(settings.validators);
              })
              .live('keyup', function () {
                element.data('changed', true).isValid(settings.validators);
              });
          }
        });

    });
  };

  $.fn.isValid = function (validators) {
    if ($(this[0]).is('form')) {
      return validateForm($(this[0]), validators);
    } else {
      return validateElement($(this[0]), validators[this[0].name]);
    }
  };

  var validateForm = function (form, validators) {
    var valid = true;

    form.trigger('form:validate:before').find('[data-validate="true"]:input:enabled').each(function() {
      if (!$(this).isValid(validators)) { valid = false; }
    });

    if (valid) {
      form.trigger('form:validate:pass');
    } else {
      form.trigger('form:validate:fail');
    }

    form.trigger('form:validate:after');
    return valid;
  },
    validateElement = function (element, validators) {
      element.trigger('element:validate:before');

      if (element.data('changed') !== false) {
        var valid = true;
        element.data('changed', false);

        // Because 'length' is defined on the list of validators we cannot call jQuery.each on
        for (kind in ClientSideValidations.validators.local) {
          if (validators[kind] && (message = ClientSideValidations.validators.all()[kind](element, validators[kind]))) {
            element.trigger('element:validate:fail', message).data('valid', false);
            valid = false;
            break;
          }
        }

        if (valid) {
          for (kind in ClientSideValidations.validators.remote) {
            if (validators[kind] && (message = ClientSideValidations.validators.all()[kind](element, validators[kind]))) {
              element.trigger('element:validate:fail', message).data('valid', false);
              valid = false;
              break;
            }
          }
        }

        if (valid) { element.data('valid', null); element.trigger('element:validate:pass'); }
      }

      element.trigger('element:validate:after');
      return element.data('valid') === false ? false : true;
    };

  // Main hook
  // If new forms are dynamically introduced into the DOM the .validate() method
  // must be invoked on that form
  $(function () { $('form[data-validate]').validate(); });
})(jQuery);

var ClientSideValidations = {
  forms: {},
  validators: {
    all: function() { return jQuery.extend({}, ClientSideValidations.validators.local, ClientSideValidations.validators.remote); },
    local: {
      presence: function (element, options) {
        if (/^\s*$/.test(element.val() || "")) {
          return options.message;
        }
      },
      acceptance: function (element, options) {
        switch (element.attr('type')) {
          case 'checkbox':
            if (!element.attr('checked')) {
              return options.message;
            }
            break;
          case 'text':
            if (element.val() != (options.accept || '1')) {
              return options.message;
            }
            break;
        }
      },
      format: function (element, options) {
        if ((message = this.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          if (options['with'] && !options['with'].test(element.val())) {
            return options.message;
          } else if (options['without'] && options['without'].test(element.val())) {
            return options.message;
          }
        }
      },
      numericality: function (element, options) {
        if (!/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/.test(element.val())) {
          return options.messages.numericality;
        }

        if (options.only_integer && !/^\d+$/.test(element.val())) {
          return options.messages.only_integer;
        }

        var CHECKS = { greater_than: '>', greater_than_or_equal_to: '>=',
          equal_to: '==', less_than: '<', less_than_or_equal_to: '<=' };

        for (check in CHECKS) {
          if (options[check] !== undefined && !(new Function("return " + element.val() + CHECKS[check] + options[check])())) {
            return options.messages[check];
          }
        }

        if (options.odd && !(parseInt(element.val(), 10) % 2)) {
          return options.messages.odd;
        }

        if (options.even && (parseInt(element.val(), 10) % 2)) {
          return options.messages.even;
        }
      },
      length: function (element, options) {
        var blankOptions = {},
            CHECKS = { is: '==', minimum: '>=', maximum: '<=' },
            tokenizer = options.js_tokenizer || "split('')",
            tokenized_length = new Function("element", "return (element.val()." + tokenizer + " || '').length;")(element);
        if (options.is) {
          blankOptions.message = options.messages.is;
        } else if (options.minimum) {
          blankOptions.message = options.messages.minimum;
        }
        if ((message = this.presence(element, blankOptions)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          for (check in CHECKS) {
            if (options[check] && !(new Function("return " + tokenized_length + CHECKS[check] + options[check])())) {
              return options.messages[check];
            }
          }
        }
      },
      exclusion: function (element, options) {
        var lower = null, upper = null;
        if ((message = this.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          if (options['in']) {
            for (i = 0; i < options['in'].length; i = i + 1) {
              if (options['in'][i] == element.val()) {
                return options.message;
              }
            }
          } else if (options.range) {
            lower = options.range[0];
            upper = options.range[1];
            if (element.val() >= lower && element.val() <= upper) {
              return options.message;
            }
          }
        }
      },
      inclusion: function (element, options) {
        var lower = null, upper = null;
        if ((message = this.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          if (options['in']) {
            for (i = 0; i < options['in'].length; i = i + 1) {
              if (options['in'][i] == element.val()) {
                return;
              }
            }
            return options.message;
          } else if (options.range) {
            lower = options.range[0];
            upper = options.range[1];

            if (element.val() >= lower && element.val() <= upper) {
              return;
            } else {
              return options.message;
            }
          }
        }
      },
      confirmation: function (element, options) {
        if (element.val() !== jQuery('#' + element.attr('id') + '_confirmation').val()) {
          return options.message;
        }
      }
    },
    remote: {
      uniqueness: function (element, options) {
        if ((message = ClientSideValidations.validators.local.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          var data = {},
              name = null;
          data.case_sensitive = !!options.case_sensitive;
          if (options.id) {
            data.id = options.id;
          }

          if (options.scope) {
            data.scope = {};
            for (key in options.scope) {
              var scoped_element = jQuery('[name="' + element.attr('name').replace(/\[\w+\]$/, '[' + key + ']' + '"]'));
              if (scoped_element[0] && scoped_element.val() !== options.scope[key]) {
                data.scope[key] = scoped_element.val();
                scoped_element.unbind('change.' + element.id).bind('change.' + element.id, function() { element.trigger('change'); element.trigger('focusout'); });
              } else {
                data.scope[key] = options.scope[key];
              }
            }
          }

          // Kind of a hack but this will isolate the resource name and attribute.
          // e.g. user[records_attributes][0][title] => records[title]
          // e.g. user[record_attributes][title] => record[title]
          // Server side handles classifying the resource properly
          if (/_attributes\]/.test(element.attr('name'))) {
            name = element.attr('name').match(/\[\w+_attributes\]/g).pop().match(/\[(\w+)_attributes\]/).pop();
            name += /(\[\w+\])$/.exec(element.attr('name'))[1];
          } else {
            name = element.attr('name');
          }

          // Override the name if a nested module class is passed
          if (options['class']) {
            name = options['class'] + '[' + name.split('[')[1];
          }
          data[name] = element.val();

          if (jQuery.ajax({
            url: '/validators/uniqueness',
            data: data,
            async: false
          }).status === 200) {
            return options.message;
          }
        }
      }
    }
  },
  formBuilders: {
    'ActionView::Helpers::FormBuilder': {
      add: function (element, settings, message) {
        if (element.data('valid') !== false && jQuery('label.message[for="' + element.attr('id') + '"]')[0] === undefined) {
          var inputErrorField = jQuery(settings.input_tag),
              labelErrorField = jQuery(settings.label_tag),
              label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)');

          if (element.attr('autofocus')) { element.attr('autofocus', false); }
          element.before(inputErrorField);
          inputErrorField.find('span#input_tag').replaceWith(element);
          inputErrorField.find('label.message').attr('for', element.attr('id'));
          labelErrorField.find('label.message').attr('for', element.attr('id'));
          label.replaceWith(labelErrorField);
          labelErrorField.find('label#label_tag').replaceWith(label);
        }
        jQuery('label.message[for="' + element.attr('id') + '"]').text(message);
      },
      remove: function (element, settings) {
        var errorFieldClass = jQuery(settings.input_tag).attr('class'),
            inputErrorField = element.closest('.' + errorFieldClass),
            label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)'),
            labelErrorField = label.closest('.' + errorFieldClass);

        if (inputErrorField[0]) {
          inputErrorField.find('#' + element.attr('id')).detach();
          inputErrorField.replaceWith(element);
          label.detach();
          labelErrorField.replaceWith(label);
        }
      }
    },
  },
  callbacks: {
    element: {
      after:  function (element, eventData)                    { },
      before: function (element, eventData)                    { },
      fail:   function (element, message, addError, eventData) { addError(); },
      pass:   function (element, removeError, eventData)       { removeError(); }
    },
    form: {
      after:  function (form, eventData) { },
      before: function (form, eventData) { },
      fail:   function (form, eventData) { },
      pass:   function (form, eventData) { }
    }
  }
};
<commit_msg>only_integer check needs to match rails's only_integer check as shown here:   def parse_raw_value_as_an_integer(raw_value)     raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/   end<commit_after>/*!
 * Rails 3 Client Side Validations - v3.1.0
 * https://github.com/bcardarella/client_side_validations
 *
 * Copyright (c) 2011 Brian Cardarella
 * Licensed under the MIT license
 * http://www.opensource.org/licenses/mit-license.php
 */

(function ($) {
  $.fn.validate = function () {
    return this.filter('form[data-validate]').each(function () {
      var form = $(this),
          settings = window['ClientSideValidations']['forms'][form.attr('id')],
          addError = function (element, message) {
            ClientSideValidations.formBuilders[settings.type].add(element, settings, message);
          },
          removeError = function (element) {
            ClientSideValidations.formBuilders[settings.type].remove(element, settings);
          };

      // Set up the events for the form
      form
        .submit(                      function ()          { return form.isValid(settings.validators); })
        .bind('ajax:beforeSend',      function (eventData) { if(eventData.target == this) return form.isValid(settings.validators); })
        // Callbacks
        .bind('form:validate:after',  function (eventData) { ClientSideValidations.callbacks.form.after( form, eventData); } )
        .bind('form:validate:before', function (eventData) { ClientSideValidations.callbacks.form.before(form, eventData); } )
        .bind('form:validate:fail',   function (eventData) { ClientSideValidations.callbacks.form.fail(  form, eventData); } )
        .bind('form:validate:pass',   function (eventData) { ClientSideValidations.callbacks.form.pass(  form, eventData); } )

        // Set up the events for each validatable form element
        .find('[data-validate="true"]:input:enabled:not(:radio)')
          .live('focusout',                function ()          { $(this).isValid(settings.validators); })
          .live('change',                  function ()          { $(this).data('changed', true); })
          // Callbacks
          .live('element:validate:after',  function (eventData) { ClientSideValidations.callbacks.element.after( $(this), eventData); })
          .live('element:validate:before', function (eventData) { ClientSideValidations.callbacks.element.before($(this), eventData); })
          .live('element:validate:fail',   function (eventData, message) {
            var element = $(this);
            ClientSideValidations.callbacks.element.fail(element, message, function () {
              addError(element, message);
            }, eventData); })
          .live('element:validate:pass',   function (eventData) {
            var element = $(this);
            ClientSideValidations.callbacks.element.pass(element, function () {
              removeError(element);
            }, eventData); })
        // Checkboxes - Live events don't support filter
        .end().find('[data-validate="true"]:checkbox')
          .live('click', function () { $(this).isValid(settings.validators); })
        // Inputs for confirmations
        .end().find('[id*=_confirmation]').each(function () {
          var confirmationElement = $(this),
              element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validate="true"]:input');

          if (element[0]) {
            $('#' + confirmationElement.attr('id'))
              .live('focusout', function () {
                element.data('changed', true).isValid(settings.validators);
              })
              .live('keyup', function () {
                element.data('changed', true).isValid(settings.validators);
              });
          }
        });

    });
  };

  $.fn.isValid = function (validators) {
    if ($(this[0]).is('form')) {
      return validateForm($(this[0]), validators);
    } else {
      return validateElement($(this[0]), validators[this[0].name]);
    }
  };

  var validateForm = function (form, validators) {
    var valid = true;

    form.trigger('form:validate:before').find('[data-validate="true"]:input:enabled').each(function() {
      if (!$(this).isValid(validators)) { valid = false; }
    });

    if (valid) {
      form.trigger('form:validate:pass');
    } else {
      form.trigger('form:validate:fail');
    }

    form.trigger('form:validate:after');
    return valid;
  },
    validateElement = function (element, validators) {
      element.trigger('element:validate:before');

      if (element.data('changed') !== false) {
        var valid = true;
        element.data('changed', false);

        // Because 'length' is defined on the list of validators we cannot call jQuery.each on
        for (kind in ClientSideValidations.validators.local) {
          if (validators[kind] && (message = ClientSideValidations.validators.all()[kind](element, validators[kind]))) {
            element.trigger('element:validate:fail', message).data('valid', false);
            valid = false;
            break;
          }
        }

        if (valid) {
          for (kind in ClientSideValidations.validators.remote) {
            if (validators[kind] && (message = ClientSideValidations.validators.all()[kind](element, validators[kind]))) {
              element.trigger('element:validate:fail', message).data('valid', false);
              valid = false;
              break;
            }
          }
        }

        if (valid) { element.data('valid', null); element.trigger('element:validate:pass'); }
      }

      element.trigger('element:validate:after');
      return element.data('valid') === false ? false : true;
    };

  // Main hook
  // If new forms are dynamically introduced into the DOM the .validate() method
  // must be invoked on that form
  $(function () { $('form[data-validate]').validate(); });
})(jQuery);

var ClientSideValidations = {
  forms: {},
  validators: {
    all: function() { return jQuery.extend({}, ClientSideValidations.validators.local, ClientSideValidations.validators.remote); },
    local: {
      presence: function (element, options) {
        if (/^\s*$/.test(element.val() || "")) {
          return options.message;
        }
      },
      acceptance: function (element, options) {
        switch (element.attr('type')) {
          case 'checkbox':
            if (!element.attr('checked')) {
              return options.message;
            }
            break;
          case 'text':
            if (element.val() != (options.accept || '1')) {
              return options.message;
            }
            break;
        }
      },
      format: function (element, options) {
        if ((message = this.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          if (options['with'] && !options['with'].test(element.val())) {
            return options.message;
          } else if (options['without'] && options['without'].test(element.val())) {
            return options.message;
          }
        }
      },
      numericality: function (element, options) {
        if (!/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/.test(element.val())) {
          return options.messages.numericality;
        }

        if (options.only_integer && !/^[+-]?\d+$/.test(element.val())) {
          return options.messages.only_integer;
        }

        var CHECKS = { greater_than: '>', greater_than_or_equal_to: '>=',
          equal_to: '==', less_than: '<', less_than_or_equal_to: '<=' };

        for (check in CHECKS) {
          if (options[check] !== undefined && !(new Function("return " + element.val() + CHECKS[check] + options[check])())) {
            return options.messages[check];
          }
        }

        if (options.odd && !(parseInt(element.val(), 10) % 2)) {
          return options.messages.odd;
        }

        if (options.even && (parseInt(element.val(), 10) % 2)) {
          return options.messages.even;
        }
      },
      length: function (element, options) {
        var blankOptions = {},
            CHECKS = { is: '==', minimum: '>=', maximum: '<=' },
            tokenizer = options.js_tokenizer || "split('')",
            tokenized_length = new Function("element", "return (element.val()." + tokenizer + " || '').length;")(element);
        if (options.is) {
          blankOptions.message = options.messages.is;
        } else if (options.minimum) {
          blankOptions.message = options.messages.minimum;
        }
        if ((message = this.presence(element, blankOptions)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          for (check in CHECKS) {
            if (options[check] && !(new Function("return " + tokenized_length + CHECKS[check] + options[check])())) {
              return options.messages[check];
            }
          }
        }
      },
      exclusion: function (element, options) {
        var lower = null, upper = null;
        if ((message = this.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          if (options['in']) {
            for (i = 0; i < options['in'].length; i = i + 1) {
              if (options['in'][i] == element.val()) {
                return options.message;
              }
            }
          } else if (options.range) {
            lower = options.range[0];
            upper = options.range[1];
            if (element.val() >= lower && element.val() <= upper) {
              return options.message;
            }
          }
        }
      },
      inclusion: function (element, options) {
        var lower = null, upper = null;
        if ((message = this.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          if (options['in']) {
            for (i = 0; i < options['in'].length; i = i + 1) {
              if (options['in'][i] == element.val()) {
                return;
              }
            }
            return options.message;
          } else if (options.range) {
            lower = options.range[0];
            upper = options.range[1];

            if (element.val() >= lower && element.val() <= upper) {
              return;
            } else {
              return options.message;
            }
          }
        }
      },
      confirmation: function (element, options) {
        if (element.val() !== jQuery('#' + element.attr('id') + '_confirmation').val()) {
          return options.message;
        }
      }
    },
    remote: {
      uniqueness: function (element, options) {
        if ((message = ClientSideValidations.validators.local.presence(element, options)) && options.allow_blank === true) {
          return;
        } else if (message) {
          return message;
        } else {
          var data = {},
              name = null;
          data.case_sensitive = !!options.case_sensitive;
          if (options.id) {
            data.id = options.id;
          }

          if (options.scope) {
            data.scope = {};
            for (key in options.scope) {
              var scoped_element = jQuery('[name="' + element.attr('name').replace(/\[\w+\]$/, '[' + key + ']' + '"]'));
              if (scoped_element[0] && scoped_element.val() !== options.scope[key]) {
                data.scope[key] = scoped_element.val();
                scoped_element.unbind('change.' + element.id).bind('change.' + element.id, function() { element.trigger('change'); element.trigger('focusout'); });
              } else {
                data.scope[key] = options.scope[key];
              }
            }
          }

          // Kind of a hack but this will isolate the resource name and attribute.
          // e.g. user[records_attributes][0][title] => records[title]
          // e.g. user[record_attributes][title] => record[title]
          // Server side handles classifying the resource properly
          if (/_attributes\]/.test(element.attr('name'))) {
            name = element.attr('name').match(/\[\w+_attributes\]/g).pop().match(/\[(\w+)_attributes\]/).pop();
            name += /(\[\w+\])$/.exec(element.attr('name'))[1];
          } else {
            name = element.attr('name');
          }

          // Override the name if a nested module class is passed
          if (options['class']) {
            name = options['class'] + '[' + name.split('[')[1];
          }
          data[name] = element.val();

          if (jQuery.ajax({
            url: '/validators/uniqueness',
            data: data,
            async: false
          }).status === 200) {
            return options.message;
          }
        }
      }
    }
  },
  formBuilders: {
    'ActionView::Helpers::FormBuilder': {
      add: function (element, settings, message) {
        if (element.data('valid') !== false && jQuery('label.message[for="' + element.attr('id') + '"]')[0] === undefined) {
          var inputErrorField = jQuery(settings.input_tag),
              labelErrorField = jQuery(settings.label_tag),
              label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)');

          if (element.attr('autofocus')) { element.attr('autofocus', false); }
          element.before(inputErrorField);
          inputErrorField.find('span#input_tag').replaceWith(element);
          inputErrorField.find('label.message').attr('for', element.attr('id'));
          labelErrorField.find('label.message').attr('for', element.attr('id'));
          label.replaceWith(labelErrorField);
          labelErrorField.find('label#label_tag').replaceWith(label);
        }
        jQuery('label.message[for="' + element.attr('id') + '"]').text(message);
      },
      remove: function (element, settings) {
        var errorFieldClass = jQuery(settings.input_tag).attr('class'),
            inputErrorField = element.closest('.' + errorFieldClass),
            label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)'),
            labelErrorField = label.closest('.' + errorFieldClass);

        if (inputErrorField[0]) {
          inputErrorField.find('#' + element.attr('id')).detach();
          inputErrorField.replaceWith(element);
          label.detach();
          labelErrorField.replaceWith(label);
        }
      }
    },
  },
  callbacks: {
    element: {
      after:  function (element, eventData)                    { },
      before: function (element, eventData)                    { },
      fail:   function (element, message, addError, eventData) { addError(); },
      pass:   function (element, removeError, eventData)       { removeError(); }
    },
    form: {
      after:  function (form, eventData) { },
      before: function (form, eventData) { },
      fail:   function (form, eventData) { },
      pass:   function (form, eventData) { }
    }
  }
};
<|endoftext|>


<commit_before>"use strict";

class gsuiSlider extends HTMLElement {
	#min = 0
	#max = 100
	#step = 1
	#scrollStep = 1
	#wheelChange = false
	#mousemoveSize = 0
	#strokeWidth = 4
	#previousval = ""
	#enable = true
	#circ = false
	#axeX = false
	#connected = false
	#pxval = 0
	#pxmoved = 0
	#svgLineLen = 0
	#children = GSUI.getTemplate( "gsui-slider" )
	#elements = GSUI.findElements( this.#children, {
		input: ".gsuiSlider-input",
		line: ".gsuiSlider-line",
		lineColor: ".gsuiSlider-lineColor",
		svg: ".gsuiSlider-svg",
		svgLine: ".gsuiSlider-svgLine",
		svgLineColor: ".gsuiSlider-svgLineColor",
	} )

	constructor() {
		super();

		this.oninput =
		this.onchange =
		this.oninputend =
		this.oninputstart = null;
		this.value = "";
		this._locked = false;
		this.width =
		this.height = 0;
		Object.seal( this );

		this.onwheel = this.#onwheel.bind( this );
		this.onmouseup = this._mouseup.bind( this );
		this.onmousedown = this.#onmousedown.bind( this );
		this.onmousemove = this.#onmousemove.bind( this );
		this.onmouseleave = this.#onmouseleave.bind( this );
	}

	// .........................................................................
	connectedCallback() {
		this.classList.add( "gsuiSlider" );
		if ( this.#children ) {
			const brc = this.getBoundingClientRect();

			this.append( ...this.#children );
			this.width = brc.width;
			this.height = brc.height;
			this.#children = null;
			this.#connected = true;
			this.#setSVGcirc();
			this.#updateVal();
		}
	}
	static get observedAttributes() {
		return [ "type", "min", "max", "step", "scroll-step", "wheel-change", "mousemove-size", "stroke-width" ];
	}
	attributeChangedCallback( prop, prev, val ) {
		if ( prev !== val ) {
			let updateVal;

			switch ( prop ) {
				case "type":
					this.#setType( val );
					this.#setSVGcirc();
					updateVal = true;
					break;
				case "min":
					this.#elements.input.min = this.#min = +val;
					updateVal = true;
					break;
				case "max":
					this.#elements.input.max = this.#max = +val;
					updateVal = true;
					break;
				case "step":
					this.#elements.input.step = this.#step = +val;
					updateVal = true;
					break;
				case "scroll-step":
					this.#scrollStep = +val;
					break;
				case "wheel-change":
					this.#wheelChange = typeof val === "string";
					break;
				case "mousemove-size":
					this.#mousemoveSize = +val;
					break;
				case "stroke-width":
					this.#strokeWidth = +val;
					this.#setSVGcirc();
					break;
			}
			if ( updateVal ) {
				this.#previousval = this.#getInputVal();
				this.#updateVal();
			}
		}
	}

	// .........................................................................
	setValue( val, bymouse ) {
		if ( !this._locked || bymouse ) {
			const prevVal = this.#getInputVal(),
				newVal = ( this.#elements.input.value = val, this.#getInputVal() );

			if ( newVal !== prevVal ) {
				this.#updateVal();
				if ( bymouse && this.oninput ) {
					this.oninput( +newVal );
				}
			}
			if ( !bymouse ) {
				this.#previousval = newVal;
			}
		}
	}
	enable( b ) {
		this.#enable = b;
		this.classList.toggle( "gsuiSlider-disable", !b );
	}

	// .........................................................................
	#setType( type ) {
		const st = this.#elements.lineColor.style,
			circ = type === "circular",
			axeX = type === "linear-x";

		this.#circ = circ;
		this.#axeX = axeX;
		this.classList.toggle( "gsuiSlider-circular", circ );
		this.classList.toggle( "gsuiSlider-linear", !circ );
		if ( !circ ) {
			if ( axeX ) {
				st.left =
				st.width = "";
				st.top = "0";
				st.height = "100%";
			} else {
				st.top =
				st.height = "";
				st.left = "0";
				st.width = "100%";
			}
		}
	}
	#setSVGcirc() {
		if ( this.#circ && this.width && this.height ) {
			const size = Math.min( this.width, this.height ),
				size2 = size / 2,
				circR = ~~( ( size - this.#strokeWidth ) / 2 );

			this.#elements.svg.setAttribute( "viewBox", `0 0 ${ size } ${ size }` );
			this.#elements.svgLine.setAttribute( "cx", size2 );
			this.#elements.svgLine.setAttribute( "cy", size2 );
			this.#elements.svgLine.setAttribute( "r", circR );
			this.#elements.svgLineColor.setAttribute( "cx", size2 );
			this.#elements.svgLineColor.setAttribute( "cy", size2 );
			this.#elements.svgLineColor.setAttribute( "r", circR );
			this.#elements.svgLine.style.strokeWidth =
			this.#elements.svgLineColor.style.strokeWidth = this.#strokeWidth;
			this.#svgLineLen = circR * 2 * Math.PI;
		}
	}
	#getInputVal() {
		const val = this.#elements.input.value;

		return Math.abs( +val ) < .000001 ? "0" : val;
	}
	#getRange() {
		return this.#max - this.#min;
	}
	#getMousemoveSize() {
		return this.#mousemoveSize || (
			this.#circ
				? this.#svgLineLen
				: this.#axeX
					? this.#elements.line.getBoundingClientRect().width
					: this.#elements.line.getBoundingClientRect().height
		);
	}
	#updateVal() {
		this.value = +this.#getInputVal();
		if ( this.#connected ) {
			const len = this.#getRange(),
				prcval = ( this.value - this.#min ) / len,
				prcstart = -this.#min / len,
				prclen = Math.abs( prcval - prcstart ),
				prcmin = Math.min( prcval, prcstart );

			if ( this.#circ ) {
				const line = this.#elements.svgLineColor.style;

				line.transform = `rotate(${ 90 + prcmin * 360 }deg)`;
				line.strokeDasharray = `${ prclen * this.#svgLineLen }, 999999`;
			} else {
				const line = this.#elements.lineColor.style;

				if ( this.#axeX ) {
					line.left = `${ prcmin * 100 }%`;
					line.width = `${ prclen * 100 }%`;
				} else {
					line.bottom = `${ prcmin * 100 }%`;
					line.height = `${ prclen * 100 }%`;
				}
			}
		}
	}
	#onchange() {
		const val = this.#getInputVal();

		if ( this.#previousval !== val ) {
			this.onchange && this.onchange( +val );
			this.#previousval = val;
		}
	}

	// .........................................................................
	#onwheel( e ) {
		if ( this.#enable && this.#wheelChange ) {
			const d = e.deltaY > 0 ? -1 : 1;

			this.setValue( +this.#getInputVal() + this.#scrollStep * d, true );
			return false;
		}
	}
	#onmousedown() {
		if ( this.#enable ) {
			this.#onchange();
			if ( this.oninputstart ) {
				this.oninputstart( this.value );
			}
			this.#pxval = this.#getRange() / this.#getMousemoveSize();
			this.#pxmoved = 0;
			this.requestPointerLock();
		}
	}
	#onmousemove( e ) {
		if ( this._locked ) {
			const bound = this.#getRange() / 5,
				mov = this.#circ || !this.#axeX ? -e.movementY : e.movementX,
				val = +this.#previousval + ( this.#pxmoved + mov ) * this.#pxval;

			if ( this.#min - bound < val && val < this.#max + bound ) {
				this.#pxmoved += mov;
			}
			this.setValue( val, true );
		}
	}
	_mouseup() {
		if ( this._locked ) {
			document.exitPointerLock();
			this._locked = false;
			this.#onchange();
			if ( this.oninputend ) {
				this.oninputend( this.value );
			}
		}
	}
	#onmouseleave() {
		this.#onchange();
	}
}

customElements.define( "gsui-slider", gsuiSlider );

document.addEventListener( "pointerlockchange", () => {
	const el = document.pointerLockElement;

	if ( el ) {
		if ( el.classList.contains( "gsuiSlider" ) ) {
			el._locked = true;
			gsuiSlider._focused = el;
		}
	} else if ( gsuiSlider._focused ) {
		gsuiSlider._focused._mouseup();
	}
} );
<commit_msg>gsuiSlider: static pointerLockChange<commit_after>"use strict";

class gsuiSlider extends HTMLElement {
	#min = 0
	#max = 100
	#step = 1
	#scrollStep = 1
	#wheelChange = false
	#mousemoveSize = 0
	#strokeWidth = 4
	#previousval = ""
	#enable = true
	#circ = false
	#axeX = false
	#locked = false
	#connected = false
	#pxval = 0
	#pxmoved = 0
	#svgLineLen = 0
	#children = GSUI.getTemplate( "gsui-slider" )
	#elements = GSUI.findElements( this.#children, {
		input: ".gsuiSlider-input",
		line: ".gsuiSlider-line",
		lineColor: ".gsuiSlider-lineColor",
		svg: ".gsuiSlider-svg",
		svgLine: ".gsuiSlider-svgLine",
		svgLineColor: ".gsuiSlider-svgLineColor",
	} )
	static focused = null

	constructor() {
		super();

		this.oninput =
		this.onchange =
		this.oninputend =
		this.oninputstart = null;
		this.value = "";
		this.width =
		this.height = 0;
		Object.seal( this );

		this.onwheel = this.#onwheel.bind( this );
		this.onmouseup = this.#onmouseup.bind( this );
		this.onmousedown = this.#onmousedown.bind( this );
		this.onmousemove = this.#onmousemove.bind( this );
		this.onmouseleave = this.#onmouseleave.bind( this );
	}

	// .........................................................................
	connectedCallback() {
		this.classList.add( "gsuiSlider" );
		if ( this.#children ) {
			const brc = this.getBoundingClientRect();

			this.append( ...this.#children );
			this.width = brc.width;
			this.height = brc.height;
			this.#children = null;
			this.#connected = true;
			this.#setSVGcirc();
			this.#updateVal();
		}
	}
	static get observedAttributes() {
		return [ "type", "min", "max", "step", "scroll-step", "wheel-change", "mousemove-size", "stroke-width" ];
	}
	attributeChangedCallback( prop, prev, val ) {
		if ( prev !== val ) {
			let updateVal;

			switch ( prop ) {
				case "type":
					this.#setType( val );
					this.#setSVGcirc();
					updateVal = true;
					break;
				case "min":
					this.#elements.input.min = this.#min = +val;
					updateVal = true;
					break;
				case "max":
					this.#elements.input.max = this.#max = +val;
					updateVal = true;
					break;
				case "step":
					this.#elements.input.step = this.#step = +val;
					updateVal = true;
					break;
				case "scroll-step":
					this.#scrollStep = +val;
					break;
				case "wheel-change":
					this.#wheelChange = typeof val === "string";
					break;
				case "mousemove-size":
					this.#mousemoveSize = +val;
					break;
				case "stroke-width":
					this.#strokeWidth = +val;
					this.#setSVGcirc();
					break;
			}
			if ( updateVal ) {
				this.#previousval = this.#getInputVal();
				this.#updateVal();
			}
		}
	}

	// .........................................................................
	static pointerLockChange() {
		const el = document.pointerLockElement;

		if ( el ) {
			if ( el.classList.contains( "gsuiSlider" ) ) {
				el.#locked = true;
				gsuiSlider.focused = el;
			}
		} else if ( gsuiSlider.focused ) {
			gsuiSlider.focused.#onmouseup();
		}
	}
	setValue( val, bymouse ) {
		if ( !this.#locked || bymouse ) {
			const prevVal = this.#getInputVal(),
				newVal = ( this.#elements.input.value = val, this.#getInputVal() );

			if ( newVal !== prevVal ) {
				this.#updateVal();
				if ( bymouse && this.oninput ) {
					this.oninput( +newVal );
				}
			}
			if ( !bymouse ) {
				this.#previousval = newVal;
			}
		}
	}
	enable( b ) {
		this.#enable = b;
		this.classList.toggle( "gsuiSlider-disable", !b );
	}

	// .........................................................................
	#setType( type ) {
		const st = this.#elements.lineColor.style,
			circ = type === "circular",
			axeX = type === "linear-x";

		this.#circ = circ;
		this.#axeX = axeX;
		this.classList.toggle( "gsuiSlider-circular", circ );
		this.classList.toggle( "gsuiSlider-linear", !circ );
		if ( !circ ) {
			if ( axeX ) {
				st.left =
				st.width = "";
				st.top = "0";
				st.height = "100%";
			} else {
				st.top =
				st.height = "";
				st.left = "0";
				st.width = "100%";
			}
		}
	}
	#setSVGcirc() {
		if ( this.#circ && this.width && this.height ) {
			const size = Math.min( this.width, this.height ),
				size2 = size / 2,
				circR = ~~( ( size - this.#strokeWidth ) / 2 );

			this.#elements.svg.setAttribute( "viewBox", `0 0 ${ size } ${ size }` );
			this.#elements.svgLine.setAttribute( "cx", size2 );
			this.#elements.svgLine.setAttribute( "cy", size2 );
			this.#elements.svgLine.setAttribute( "r", circR );
			this.#elements.svgLineColor.setAttribute( "cx", size2 );
			this.#elements.svgLineColor.setAttribute( "cy", size2 );
			this.#elements.svgLineColor.setAttribute( "r", circR );
			this.#elements.svgLine.style.strokeWidth =
			this.#elements.svgLineColor.style.strokeWidth = this.#strokeWidth;
			this.#svgLineLen = circR * 2 * Math.PI;
		}
	}
	#getInputVal() {
		const val = this.#elements.input.value;

		return Math.abs( +val ) < .000001 ? "0" : val;
	}
	#getRange() {
		return this.#max - this.#min;
	}
	#getMousemoveSize() {
		return this.#mousemoveSize || (
			this.#circ
				? this.#svgLineLen
				: this.#axeX
					? this.#elements.line.getBoundingClientRect().width
					: this.#elements.line.getBoundingClientRect().height
		);
	}
	#updateVal() {
		this.value = +this.#getInputVal();
		if ( this.#connected ) {
			const len = this.#getRange(),
				prcval = ( this.value - this.#min ) / len,
				prcstart = -this.#min / len,
				prclen = Math.abs( prcval - prcstart ),
				prcmin = Math.min( prcval, prcstart );

			if ( this.#circ ) {
				const line = this.#elements.svgLineColor.style;

				line.transform = `rotate(${ 90 + prcmin * 360 }deg)`;
				line.strokeDasharray = `${ prclen * this.#svgLineLen }, 999999`;
			} else {
				const line = this.#elements.lineColor.style;

				if ( this.#axeX ) {
					line.left = `${ prcmin * 100 }%`;
					line.width = `${ prclen * 100 }%`;
				} else {
					line.bottom = `${ prcmin * 100 }%`;
					line.height = `${ prclen * 100 }%`;
				}
			}
		}
	}
	#onchange() {
		const val = this.#getInputVal();

		if ( this.#previousval !== val ) {
			this.onchange && this.onchange( +val );
			this.#previousval = val;
		}
	}

	// .........................................................................
	#onwheel( e ) {
		if ( this.#enable && this.#wheelChange ) {
			const d = e.deltaY > 0 ? -1 : 1;

			this.setValue( +this.#getInputVal() + this.#scrollStep * d, true );
			return false;
		}
	}
	#onmousedown() {
		if ( this.#enable ) {
			this.#onchange();
			if ( this.oninputstart ) {
				this.oninputstart( this.value );
			}
			this.#pxval = this.#getRange() / this.#getMousemoveSize();
			this.#pxmoved = 0;
			this.requestPointerLock();
		}
	}
	#onmousemove( e ) {
		if ( this.#locked ) {
			const bound = this.#getRange() / 5,
				mov = this.#circ || !this.#axeX ? -e.movementY : e.movementX,
				val = +this.#previousval + ( this.#pxmoved + mov ) * this.#pxval;

			if ( this.#min - bound < val && val < this.#max + bound ) {
				this.#pxmoved += mov;
			}
			this.setValue( val, true );
		}
	}
	#onmouseup() {
		if ( this.#locked ) {
			document.exitPointerLock();
			this.#locked = false;
			this.#onchange();
			if ( this.oninputend ) {
				this.oninputend( this.value );
			}
		}
	}
	#onmouseleave() {
		this.#onchange();
	}
}

customElements.define( "gsui-slider", gsuiSlider );

Object.seal( gsuiSlider );

document.addEventListener( "pointerlockchange", gsuiSlider.pointerLockChange );
<|endoftext|>