<commit_before>var uri = require('url')
  , State = require('../state')
  , swizzleRedirect = require('../utils/swizzle-redirect')
  , swizzleRender = require('../utils/swizzle-render')
  , swizzleEnd = require('../utils/swizzle-end')
  , flatten = require('utils-flatten')
  , merge = require('utils-merge')
  , utils = require('../utils')
  , validate = require('../validate')
  , debug = require('debug')('flowstate')
  , SessionStore = require('../store/session');

var uid = require('uid-safe').sync;

  // TIPS: Generally, push a state before redirecting (unless wizard style
  //  alternatively, handler can lazily push, for its own state, to preserve storage
  //  which could be done based on the presence of a returnTo (which is not the handlers URL)

/**
 * Load state.
 *
 * This middleware is used to load state associated with a request.  The state
 * will be made available at `req.state`.
 *
 * HTTP is a stateless protocol.  In order to support stateful interactions, the
 * client and server need to operate in coordination.  The server is responsible
 * for persisting state associated with a request.  The client is responsible for
 * indicating that state in subsequent requests to the server (via a `state`
 * parameter in the query or body, by default).  The server then loads the
 * previously persisted state in order to continue processing the transaction.
 *
 * Options:
 *
 *     name   set req.state only if the state name is equal to the option value
 *     required   require state, failing otherwise (default: false)
 *
 * Examples:
 *
 *     app.get('/login',
 *       flowstate.loadState(),
 *       function(req, res, next) {
 *         res.locals.failureCount = req.state.failureCount;
 *         res.render('login');
 *       });
 *
 *     app.get('/login/callback',
 *       flowstate.loadState({ name: 'oauth2-redirect', required: true }),
 *       function(req, res, next) {
 *         // ...
 *       });
 *
 * @return {Function}
 * @api public
 */
module.exports = function(options) {
  options = options || {}

  var store = options.store || new SessionStore(options);
  var getHandle = options.getHandle || function(req) {
    return (req.query && req.query.state) || (req.body && req.body.state);
  }
  var validateRedirect = validate.origin;
  var generateHandle = options.genh || function() { return uid(8); }

  var mutationMethods = options.mutationMethods === undefined
    ? ['POST', 'PUT', 'PATCH', 'DELETE']
    : options.mutationMethods

  return function state(req, res, next) {
    // self-awareness
    if (req.state) { return next(); }

    // expose store
    req.stateStore = store;

    req.pushState = function(data, url, options, cb) {
      if (typeof options == 'function') {
        cb = options;
        options = undefined;
      }
      options = options || {};

      data.location = uri.resolve(utils.originalURL(req), url);
      if (req.state.returnTo && !req.state.external) {
        data.returnTo = req.state.returnTo;
      } else if (req.state.resumeState) {
        data.resumeState = req.state.resumeState;
      }

      var state = new State(req, data);
      req._stateStack.push(state);

      if (cb) {
        if (typeof store.set == 'function') { state.handle = options.handle || generateHandle(); }
        state.save(options, function(err) {
          if (err) { return cb(err); }
          return cb(null, state.handle);
        });
      }
    }

    res.resumeState = function(yields, cb) {
      if (typeof yields == 'function') {
        cb = yields;
        yields = undefined;
      }

      req.state.complete();

      if (req.state.returnTo) {
        // TODO: underscore the parameters, adn redirect with query
        this.redirect(req.state.returnTo);
      } else if (req.state.resumeState) {
        var self = this;
        store.get(req, req.state.resumeState, function(err, data) {
          if (err) { return cb(err); }  // FIXME: this should be next?

          var state = new State(req, data, req.state.resumeState);
          merge(state, yields);
          req._stateStack.push(state);
          self.redirect(state.location);
        });
      } else {
        cb();
      }
    }

    // swizzle redirect to commit the state
    swizzleRedirect(res, function(url, cb) {
      if ((mutationMethods.indexOf(req.method) != -1) && !req.state.isModified()) {
        req.state.complete();
      }

      commit(function(err, returnTo, state) {
        if (err) { return next(err); } // FIXME: This should call cb? No

        if (!returnTo && !state) { return cb(); }
        var l = uri.parse(url, true);
        delete l.search;
        if (returnTo) { l.query.return_to = returnTo; }
        else if (state) { l.query.state = state; }
        return cb(null, uri.format(l));
      });
    });

    // swizzle render to commit the state
    swizzleRender(res, function(cb) {
      // TODO: dont' complete the state if it is flagged to continue
      if ((mutationMethods.indexOf(req.method) != -1) && (Math.floor(res.statusCode / 100) == 2)) {
        req.state.complete();
      }

      commit(function(err, returnTo, state) {
        if (err) { return next(err); } // FIXME: This should call cb?

        if (returnTo) { res.locals.returnTo = returnTo; }
        else if (state) { res.locals.state = state; }
        cb();
      });
    });

    swizzleEnd(res, function(cb) {
      commit(function() {
        cb();
      });
    });

    function generate() {
      var data = {
        location: utils.originalURLWithoutQuery(req)
      };

      var returnTo = (options.external ? utils.originalURL(req) : undefined)
        || (req.query && req.query.return_to)
        || (req.body && req.body.return_to)
        || (req.header ? req.header('referer') : undefined);
      if (returnTo) {
        var valid = validateRedirect(returnTo, req);
        if (valid) {
          data.returnTo = returnTo;
        }
      }

      req.state = new State(req, data, undefined, options.external);
      req._stateStack = [ req.state ];
    }

    function inflate(state, h) {
      req.state = new State(req, state, h);
      req._stateStack = [ req.state ];
    }

    function commit(cb) {
      var stack = req._stateStack
        , i = 0;

      function iter(err, returnTo, resumeState) {
        if (err) { return next(err); } // TODO: Test case for this

        var state = stack[i++];
        if (!state) { return cb(null, returnTo, resumeState); }

        if (state.isComplete()) {
          debug('destroying %O (%s)', state, state.handle);
          state.destroy(function(err) {
            if (err) { return iter(err); }
            debug('destroyed');
            iter(null, undefined, state.resumeState);
          });
        } else if (state.isModified() || (i > 1 && !state.isSaved())) {
          debug('saving %O (%s)', state, state.handle);
          if (!state.handle && (typeof store.set == 'function')) {
            state.handle = generateHandle();
          }
          state.save(function(err) {
            if (err) { return iter(err); }
            debug('saved (%s)', state.handle);
            iter(null, undefined, state.handle);
          });
        } else if (state.isNew()) {
          iter(null, state.returnTo, state.resumeState);
        } else { // current
          iter(null, undefined, state.handle);
        }
      }
      iter();
    }

    // Initialize a state if the browser didn't send a state handle, or the
    // endpoint indicated that state, if any, is external to this app.
    //
    // The latter case is common with federated protocols, such as OpenID
    // Connect and OAuth 2.0, in which clients make requests that initiate
    // stateful transactions within the app making use of this middleware.
    // These requests may have a `state` parameter, but its value is meant to be
    // included when the browser is redirected back to the client so the client
    // can maintain its state.
    var h = getHandle(req);
    if (!h || options.external) {
      generate();
      next();
      return;
    }

    store.get(req, h, function(err, state) {
      if (err) { return next(err); }

      if (!state) {
        generate();
        next();
        return;
      }

      var url = utils.originalURLWithoutQuery(req);
      if (state.location !== url) {
        // The referened state is not intended for the endpoint that was
        // requested.
        //
        // A new state will be initialized which, when complete, will trigger
        // the referenced state to resume.  This process is managed by building
        // a logical stack of states as the browser is redirected or navigated
        // to a series of pages, where a reference to the current state is
        // relayed with each request.  Once a request is processed which does
        // not result in a further redirect, the stack unwinds by popping the
        // state to be resumed.
        inflate({ location: url, resumeState: h });
      } else {
        inflate(state, h);
      }

      next();
    });
  };
};
<commit_msg>Clean up.<commit_after>var uri = require('url')
  , State = require('../state')
  , swizzleRedirect = require('../utils/swizzle-redirect')
  , swizzleRender = require('../utils/swizzle-render')
  , swizzleEnd = require('../utils/swizzle-end')
  , flatten = require('utils-flatten')
  , merge = require('utils-merge')
  , utils = require('../utils')
  , validate = require('../validate')
  , debug = require('debug')('flowstate')
  , SessionStore = require('../store/session');

var uid = require('uid-safe').sync;

  // TIPS: Generally, push a state before redirecting (unless wizard style
  //  alternatively, handler can lazily push, for its own state, to preserve storage
  //  which could be done based on the presence of a returnTo (which is not the handlers URL)

/**
 * Load state.
 *
 * This middleware is used to load state associated with a request.  The state
 * will be made available at `req.state`.
 *
 * HTTP is a stateless protocol.  In order to support stateful interactions, the
 * client and server need to operate in coordination.  The server is responsible
 * for persisting state associated with a request.  The client is responsible for
 * indicating that state in subsequent requests to the server (via a `state`
 * parameter in the query or body, by default).  The server then loads the
 * previously persisted state in order to continue processing the transaction.
 *
 * Options:
 *
 *     name   set req.state only if the state name is equal to the option value
 *     required   require state, failing otherwise (default: false)
 *
 * Examples:
 *
 *     app.get('/login',
 *       flowstate.loadState(),
 *       function(req, res, next) {
 *         res.locals.failureCount = req.state.failureCount;
 *         res.render('login');
 *       });
 *
 *     app.get('/login/callback',
 *       flowstate.loadState({ name: 'oauth2-redirect', required: true }),
 *       function(req, res, next) {
 *         // ...
 *       });
 *
 * @return {Function}
 * @api public
 */
module.exports = function(options) {
  options = options || {}

  var store = options.store || new SessionStore(options);
  var getHandle = options.getHandle || function(req) {
    return (req.query && req.query.state) || (req.body && req.body.state);
  }
  var validateRedirect = validate.origin;
  var generateHandle = options.genh || function() { return uid(8); }

  var mutationMethods = options.mutationMethods === undefined
    ? ['POST', 'PUT', 'PATCH', 'DELETE']
    : options.mutationMethods

  return function state(req, res, next) {
    // self-awareness
    if (req.state) { return next(); }

    // expose store
    req.stateStore = store;

    req.pushState = function(data, url, options, cb) {
      if (typeof options == 'function') {
        cb = options;
        options = undefined;
      }
      options = options || {};

      data.location = uri.resolve(utils.originalURL(req), url);
      if (req.state.returnTo && !req.state.external) {
        data.returnTo = req.state.returnTo;
      } else if (req.state.resumeState) {
        data.resumeState = req.state.resumeState;
      }

      var state = new State(req, data);
      req._stateStack.push(state);

      if (cb) {
        if (typeof store.set == 'function') { state.handle = options.handle || generateHandle(); }
        state.save(options, function(err) {
          if (err) { return cb(err); }
          return cb(null, state.handle);
        });
      }
    }

    res.resumeState = function(yields, cb) {
      if (typeof yields == 'function') {
        cb = yields;
        yields = undefined;
      }

      req.state.complete();

      if (req.state.returnTo) {
        // TODO: underscore the parameters, adn redirect with query
        this.redirect(req.state.returnTo);
      } else if (req.state.resumeState) {
        var self = this;
        store.get(req, req.state.resumeState, function(err, data) {
          if (err) { return cb(err); }  // FIXME: this should be next?

          var state = new State(req, data, req.state.resumeState);
          merge(state, yields);
          req._stateStack.push(state);
          self.redirect(state.location);
        });
      } else {
        cb();
      }
    }

    // swizzle redirect to commit the state
    swizzleRedirect(res, function(url, cb) {
      if ((mutationMethods.indexOf(req.method) != -1) && !req.state.isModified()) {
        req.state.complete();
      }

      commit(function(err, returnTo, state) {
        if (err) { return next(err); }

        if (!returnTo && !state) { return cb(); }
        var l = uri.parse(url, true);
        delete l.search;
        if (returnTo) { l.query.return_to = returnTo; }
        else if (state) { l.query.state = state; }
        return cb(null, uri.format(l));
      });
    });

    // swizzle render to commit the state
    swizzleRender(res, function(cb) {
      // TODO: dont' complete the state if it is flagged to continue
      if ((mutationMethods.indexOf(req.method) != -1) && (Math.floor(res.statusCode / 100) == 2)) {
        req.state.complete();
      }

      commit(function(err, returnTo, state) {
        if (err) { return next(err); } // FIXME: This should call cb?

        if (returnTo) { res.locals.returnTo = returnTo; }
        else if (state) { res.locals.state = state; }
        cb();
      });
    });

    swizzleEnd(res, function(cb) {
      commit(function() {
        cb();
      });
    });

    function generate() {
      var data = {
        location: utils.originalURLWithoutQuery(req)
      };

      var returnTo = (options.external ? utils.originalURL(req) : undefined)
        || (req.query && req.query.return_to)
        || (req.body && req.body.return_to)
        || (req.header ? req.header('referer') : undefined);
      if (returnTo) {
        var valid = validateRedirect(returnTo, req);
        if (valid) {
          data.returnTo = returnTo;
        }
      }

      req.state = new State(req, data, undefined, options.external);
      req._stateStack = [ req.state ];
    }

    function inflate(state, h) {
      req.state = new State(req, state, h);
      req._stateStack = [ req.state ];
    }

    function commit(cb) {
      var stack = req._stateStack
        , i = 0;

      function iter(err, returnTo, resumeState) {
        if (err) { return cb(err); } // TODO: Test case for this

        var state = stack[i++];
        if (!state) { return cb(null, returnTo, resumeState); }

        if (state.isComplete()) {
          debug('destroying %O (%s)', state, state.handle);
          state.destroy(function(err) {
            if (err) { return iter(err); }
            debug('destroyed');
            iter(null, undefined, state.resumeState);
          });
        } else if (state.isModified() || (i > 1 && !state.isSaved())) {
          debug('saving %O (%s)', state, state.handle);
          if (!state.handle && (typeof store.set == 'function')) {
            state.handle = generateHandle();
          }
          state.save(function(err) {
            if (err) { return iter(err); }
            debug('saved (%s)', state.handle);
            iter(null, undefined, state.handle);
          });
        } else if (state.isNew()) {
          iter(null, state.returnTo, state.resumeState);
        } else { // current
          iter(null, undefined, state.handle);
        }
      }
      iter();
    }

    // Initialize a state if the browser didn't send a state handle, or the
    // endpoint indicated that state, if any, is external to this app.
    //
    // The latter case is common with federated protocols, such as OpenID
    // Connect and OAuth 2.0, in which clients make requests that initiate
    // stateful transactions within the app making use of this middleware.
    // These requests may have a `state` parameter, but its value is meant to be
    // included when the browser is redirected back to the client so the client
    // can maintain its state.
    var h = getHandle(req);
    if (!h || options.external) {
      generate();
      next();
      return;
    }

    store.get(req, h, function(err, state) {
      if (err) { return next(err); }

      if (!state) {
        generate();
        next();
        return;
      }

      var url = utils.originalURLWithoutQuery(req);
      if (state.location !== url) {
        // The referened state is not intended for the endpoint that was
        // requested.
        //
        // A new state will be initialized which, when complete, will trigger
        // the referenced state to resume.  This process is managed by building
        // a logical stack of states as the browser is redirected or navigated
        // to a series of pages, where a reference to the current state is
        // relayed with each request.  Once a request is processed which does
        // not result in a further redirect, the stack unwinds by popping the
        // state to be resumed.
        inflate({ location: url, resumeState: h });
      } else {
        inflate(state, h);
      }

      next();
    });
  };
};
<|endoftext|>


<commit_before>'use strict';
const expect = require('chai').expect;
const Adapter = require('./lib/adapterSim');
const Server = require('../lib/server');
const Client = require('./lib/mqttClient');

let port = 1883;

describe('MQTT server', () => {
    let adapter;
    let server;
    const states   = {};

    before('MQTT server: Start MQTT server', done => {
        adapter = new Adapter({
            port: ++port,
            defaultQoS: 1,
            onchange: true
        });
        server = new Server(adapter, states);
        done();
    });

    it('MQTT server: Check if connected to MQTT broker', done => {
        const client = new Client(isConnected => {
            if (done) {
                expect(isConnected).to.be.true;
                client.destroy();
                done();
                done = null;
            }
        },
        null,
        {
            url: 'localhost:' + port,
            clientId: 'testClient1',
        }
        );
    });

    it('MQTT server: Check if subscribes stored', () => {
        let client;
        const data = 1;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa');
                    setTimeout(() => client.destroy(), 200); // let time to send it out
                } else {
                    adapter.setForeignState('mqtt.0.aaa', data);
                    server.onStateChange('mqtt.0.aaa', {val: data, ack: false});
                    setTimeout(() => resolve(), 100);
                }
            },
            null,
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient2',
                resubscribe: false
            }
            );
        })
            .then(() => {
                new Promise(resolve => {
                    client = new Client(
                        () => {

                        },
                        (topic, message) => {
                            if (topic === 'aaa') {
                                expect(topic).to.be.equal('aaa');
                                expect(message.toString()).to.be.equal(data.toString());
                                client.destroy();
                                resolve();
                            }
                        },
                        {
                            url: 'localhost:' + port,
                            clean: false,
                            clientId: 'testClient2',
                            resubscribe: false
                        }
                    );
                });
            });
    });

    it('MQTT server: Check if QoS1 retransmitted', done => {
        let client;
        const data = 1;
        let sendPacket;
        let count = 0;
        const id = 'aaa2';
        let allowPuback = false;
        let receiveFunc;
        new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient3',
                resubscribe: false
            }
            );
            sendPacket = client.client._sendPacket;
            client.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS1 called for ' + JSON.stringify(packet));
                // ignore puback
                if (packet.cmd === 'puback' && !allowPuback) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb, cbStorePut);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    adapter.setForeignState('mqtt.0.' + id, data);
                    server.onStateChange('mqtt.0.' + id, {val: data, ack: false});
                    setTimeout(() => resolve(), 1000);
                });
            })
            .then(() => {
                console.log(`[${new Date().toISOString()} continue tests`);
                expect(count).to.be.equal(1);
                allowPuback = true;
                receiveFunc = () => {
                    client.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if QoS2 retransmitted', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa3';
        let sendPacket;
        let count = 0;
        let allowPubrec = false;
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 2});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
            receiverClient.client.on('packetreceive', packet => {
               console.log('Receiving client received ' + JSON.stringify(packet));
            });
            sendPacket = receiverClient.client._sendPacket;
            receiverClient.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS2 called for ' + JSON.stringify(packet));
                // ignore pubrec
                if (packet.cmd === 'pubrec' && !allowPubrec) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    emitterClient.publish(id, data.toString(), 2, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 500);
                });
            })
            .then(() => {
                expect(count).to.be.equal(1);
                allowPubrec = true;
                receiveFunc = () => {
                    receiverClient.destroy();
                    emitterClient.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if message with QoS1 received', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa4';
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data, packet) => receiveFunc && receiveFunc(topic, data, packet),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    receiveFunc = (topic, data, packet) => {
                        expect(data).to.be.ok;
                        expect(topic).to.be.ok;
                        expect(packet.qos).to.be.equal(1);
                        receiverClient.destroy();
                        emitterClient.destroy();
                        done();
                    };
                    emitterClient.publish(id, data.toString(), 1, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 100);
                });
            });
    }).timeout(1000);

    // check unsubscribe
    it('MQTT server: Check if unsubscribes works', () => {
        let client;
        const data = 1;
        let count = 0;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa6');
                    setTimeout(() => {
                        adapter.setForeignState('mqtt.0.aaa6', data);
                        server.onStateChange('mqtt.0.aaa6', {val: data, ack: false});
                    }, 500);
                }
            },
            (id, topic, packet) => {
                if (id.indexOf('aaa6') !== -1) {
                    console.log('Received ' + topic.toString());
                    count++;
                    expect(count).to.be.equal(1);
                    setTimeout(() => resolve(), 100);
                }
            },
            {
                url: 'localhost:' + port,
                clean: true,
                clientId: 'testClient6',
                resubscribe: false
            }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    client.unsubscribe('aaa6');
                    client.unsubscribe('#');
                    setTimeout(() => {
                        console.log('Resend data');
                        adapter.setForeignState('mqtt.0.aaa6', 2);
                        server.onStateChange('mqtt.0.aaa6', {val: 2, ack: false});
                        // wait 1 second to not receive the update
                        setTimeout(() => {
                            console.log('Done');
                            client.destroy();
                            resolve();
                        }, 1000);
                    }, 300);
                });
            });
    }).timeout(3000);

    after('MQTT server: Stop MQTT server', done => {
        server.destroy(done);
    }).timeout(3000);
});
<commit_msg>* try fix<commit_after>'use strict';
const expect = require('chai').expect;
const Adapter = require('./lib/adapterSim');
const Server = require('../lib/server');
const Client = require('./lib/mqttClient');

let port = 1883;

describe('MQTT server', function () {
    let adapter;
    let server;
    const states   = {};
    this.timeout(3000);

    before('MQTT server: Start MQTT server', done => {
        adapter = new Adapter({
            port: ++port,
            defaultQoS: 1,
            onchange: true
        });
        server = new Server(adapter, states);
        done();
    });

    it('MQTT server: Check if connected to MQTT broker', done => {
        const client = new Client(isConnected => {
            if (done) {
                expect(isConnected).to.be.true;
                client.destroy();
                done();
                done = null;
            }
        },
        null,
        {
            url: 'localhost:' + port,
            clientId: 'testClient1',
        }
        );
    });

    it('MQTT server: Check if subscribes stored', () => {
        let client;
        const data = 1;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa');
                    setTimeout(() => client.destroy(), 200); // let time to send it out
                } else {
                    adapter.setForeignState('mqtt.0.aaa', data);
                    server.onStateChange('mqtt.0.aaa', {val: data, ack: false});
                    setTimeout(() => resolve(), 100);
                }
            },
            null,
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient2',
                resubscribe: false
            }
            );
        })
            .then(() => {
                new Promise(resolve => {
                    client = new Client(
                        () => {

                        },
                        (topic, message) => {
                            if (topic === 'aaa') {
                                expect(topic).to.be.equal('aaa');
                                expect(message.toString()).to.be.equal(data.toString());
                                client.destroy();
                                resolve();
                            }
                        },
                        {
                            url: 'localhost:' + port,
                            clean: false,
                            clientId: 'testClient2',
                            resubscribe: false
                        }
                    );
                });
            });
    });

    it('MQTT server: Check if QoS1 retransmitted', done => {
        let client;
        const data = 1;
        let sendPacket;
        let count = 0;
        const id = 'aaa2';
        let allowPuback = false;
        let receiveFunc;
        new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient3',
                resubscribe: false
            }
            );
            sendPacket = client.client._sendPacket;
            client.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS1 called for ' + JSON.stringify(packet));
                // ignore puback
                if (packet.cmd === 'puback' && !allowPuback) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb, cbStorePut);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    adapter.setForeignState('mqtt.0.' + id, data);
                    server.onStateChange('mqtt.0.' + id, {val: data, ack: false});
                    setTimeout(() => resolve(), 1000);
                });
            })
            .then(() => {
                console.log(`[${new Date().toISOString()} continue tests`);
                expect(count).to.be.equal(1);
                allowPuback = true;
                receiveFunc = () => {
                    client.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if QoS2 retransmitted', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa3';
        let sendPacket;
        let count = 0;
        let allowPubrec = false;
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 2});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
            receiverClient.client.on('packetreceive', packet => {
               console.log('Receiving client received ' + JSON.stringify(packet));
            });
            sendPacket = receiverClient.client._sendPacket;
            receiverClient.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS2 called for ' + JSON.stringify(packet));
                // ignore pubrec
                if (packet.cmd === 'pubrec' && !allowPubrec) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    emitterClient.publish(id, data.toString(), 2, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 500);
                });
            })
            .then(() => {
                expect(count).to.be.equal(1);
                allowPubrec = true;
                receiveFunc = () => {
                    receiverClient.destroy();
                    emitterClient.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if message with QoS1 received', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa4';
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data, packet) => receiveFunc && receiveFunc(topic, data, packet),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    receiveFunc = (topic, data, packet) => {
                        expect(data).to.be.ok;
                        expect(topic).to.be.ok;
                        expect(packet.qos).to.be.equal(1);
                        receiverClient.destroy();
                        emitterClient.destroy();
                        done();
                    };
                    emitterClient.publish(id, data.toString(), 1, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 100);
                });
            });
    }).timeout(1000);

    // check unsubscribe
    it('MQTT server: Check if unsubscribes works', () => {
        let client;
        const data = 1;
        let count = 0;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa6');
                    setTimeout(() => {
                        adapter.setForeignState('mqtt.0.aaa6', data);
                        server.onStateChange('mqtt.0.aaa6', {val: data, ack: false});
                    }, 500);
                }
            },
            (id, topic, packet) => {
                if (id.indexOf('aaa6') !== -1) {
                    console.log('Received ' + topic.toString());
                    count++;
                    expect(count).to.be.equal(1);
                    setTimeout(() => resolve(), 100);
                }
            },
            {
                url: 'localhost:' + port,
                clean: true,
                clientId: 'testClient6',
                resubscribe: false
            }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    client.unsubscribe('aaa6');
                    client.unsubscribe('#');
                    setTimeout(() => {
                        console.log('Resend data');
                        adapter.setForeignState('mqtt.0.aaa6', 2);
                        server.onStateChange('mqtt.0.aaa6', {val: 2, ack: false});
                        // wait 1 second to not receive the update
                        setTimeout(() => {
                            console.log('Done');
                            client.destroy();
                            resolve();
                        }, 1000);
                    }, 300);
                });
            });
    }).timeout(3000);

    after('MQTT server: Stop MQTT server', done => {
        server.destroy(done);
    });
});
<|endoftext|>


<commit_before>/* Copyright (c) 2013-2016 The TagSpaces Authors.
 * Use of this source code is governed by the MIT license which can be found in the LICENSE.txt file. */

define(function(require, exports, module) {
  "use strict";

  var extensionID = "editorHTML"; // ID should be equal to the directory name where the ext. is located
  var extensionSupportedFileTypes = ["html", "htm"];

  console.log("Loading " + extensionID);

  var TSCORE = require("tscore");
  var extensionsPath = TSCORE.Config.getExtensionPath();
  var extensionDirectory = extensionsPath + "/" + extensionID;
  var fileDirectory;
  var currentContent;
  var currentFilePath;
  var $containerElement;
  var contentVersion = 0;
  var sourceURL = "";
  var scrapedOn = "";

  function init(filePath, containerElementID) {
    console.log("Initalization HTML Editor...");

    fileDirectory = TSCORE.TagUtils.extractContainingDirectoryPath(filePath);

    $containerElement = $('#' + containerElementID);

    currentFilePath = filePath;

    $containerElement.empty();
    $containerElement.css("background-color", "white");

    var extPath = extensionDirectory + "/index.html";
    $containerElement.append($('', {
      id: "iframeViewer",
      sandbox: "allow-same-origin allow-scripts allow-modals",
      scrolling: "no",
      style: "background-color: white; overflow: hidden;",
      src: extPath + "?cp=" + filePath + "&setLng=" + TSCORE.currentLanguage,
      "nwdisable": "",
      "nwfaketop": ""
    }));

    TSCORE.IO.loadTextFilePromise(filePath).then(function(content) {
        //TSPOSTIO.loadTextFile(content);
        exports.setContent(content);
      },
      function(error) {
        TSCORE.hideLoadingAnimation();
        TSCORE.showAlertDialog("Loading " + filePath + " failed.");
        console.error("Loading file " + filePath + " failed " + error);
      }
    );
  }

  function setFileType(fileType) {

    console.log("setFileType not supported on this extension");
  }

  function viewerMode(isViewerMode) {
    // set readonly
    console.log("viewerMode not supported on this extension");
  }

  function setContent(content) {
    currentContent = content;

    var bodyContent;
    var cleanedBodyContent;
    var bodyRegex = /\]*\>([^]*)\<\/body/m; // jshint ignore:line

    if (content.length > 3) {
      try {
        bodyContent = content.match(bodyRegex)[1];
      } catch (e) {
        console.log("Error parsing the body of the HTML document. " + e);
        bodyContent = content;
      }

      //try {
      //  var scrapedOnRegex = /data-scrapedOn='([^']*)'/m; // jshint ignore:line
      //  scrapedOn = content.match(scrapedOnRegex)[1];
      //} catch (e) {
      //  console.log("Error parsing the meta from the HTML document. " + e);
      //}
      //
      //try {
      //  var sourceURLRegex = /data-sourceUrl='([^']*)'/m; // jshint ignore:line
      //  sourceURL = content.match(sourceURLRegex)[1];
      //} catch (e) {
      //  console.log("Error parsing the meta from the HTML document. " + e);
      //}

      //var titleRegex = /\<title[^>]*\>([^]*)\<\/title/m;
      //var titleContent = content.match( titleRegex )[1];

      // removing all scripts from the document
    } else{
      currentContent = TSCORE.Config.DefaultSettings.newHTMLFileContent;
      bodyContent = currentContent.match(bodyRegex)[1];
    }
    cleanedBodyContent = bodyContent.replace(/


<commit_before>'use strict';
const expect = require('chai').expect;
const Adapter = require('./lib/adapterSim');
const Server = require('../lib/server');
const Client = require('./lib/mqttClient');

let port = 1883;

describe('MQTT server', () => {
    let adapter;
    let server;
    const states   = {};

    before('MQTT server: Start MQTT server', done => {
        adapter = new Adapter({
            port: ++port,
            defaultQoS: 1,
            onchange: true
        });
        server = new Server(adapter, states);
        done();
    });

    it('MQTT server: Check if connected to MQTT broker', done => {
        const client = new Client(isConnected => {
            if (done) {
                expect(isConnected).to.be.true;
                client.destroy();
                done();
                done = null;
            }
        },
        null,
        {
            url: 'localhost:' + port,
            clientId: 'testClient1',
        }
        );
    });

    it('MQTT server: Check if subscribes stored', () => {
        let client;
        const data = 1;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa');
                    setTimeout(() => client.destroy(), 200); // let time to send it out
                } else {
                    adapter.setForeignState('mqtt.0.aaa', data);
                    server.onStateChange('mqtt.0.aaa', {val: data, ack: false});
                    setTimeout(() => resolve(), 100);
                }
            },
            null,
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient2',
                resubscribe: false
            }
            );
        })
            .then(() => {
                new Promise(resolve => {
                    client = new Client(
                        () => {

                        },
                        (topic, message) => {
                            if (topic === 'aaa') {
                                expect(topic).to.be.equal('aaa');
                                expect(message.toString()).to.be.equal(data.toString());
                                client.destroy();
                                resolve();
                            }
                        },
                        {
                            url: 'localhost:' + port,
                            clean: false,
                            clientId: 'testClient2',
                            resubscribe: false
                        }
                    );
                });
            });
    });

    it('MQTT server: Check if QoS1 retransmitted', done => {
        let client;
        const data = 1;
        let sendPacket;
        let count = 0;
        const id = 'aaa2';
        let allowPuback = false;
        let receiveFunc;
        new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient3',
                resubscribe: false
            }
            );
            sendPacket = client.client._sendPacket;
            client.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS1 called for ' + JSON.stringify(packet));
                // ignore puback
                if (packet.cmd === 'puback' && !allowPuback) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb, cbStorePut);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    adapter.setForeignState('mqtt.0.' + id, data);
                    server.onStateChange('mqtt.0.' + id, {val: data, ack: false});
                    setTimeout(() => resolve(), 1000);
                });
            })
            .then(() => {
                console.log(`[${new Date().toISOString()} continue tests`);
                expect(count).to.be.equal(1);
                allowPuback = true;
                receiveFunc = () => {
                    client.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if QoS2 retransmitted', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa3';
        let sendPacket;
        let count = 0;
        let allowPubrec = false;
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 2});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
            receiverClient.client.on('packetreceive', packet => {
               console.log('Receiving client received ' + JSON.stringify(packet));
            });
            sendPacket = receiverClient.client._sendPacket;
            receiverClient.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS2 called for ' + JSON.stringify(packet));
                // ignore pubrec
                if (packet.cmd === 'pubrec' && !allowPubrec) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    emitterClient.publish(id, data.toString(), 2, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 500);
                });
            })
            .then(() => {
                expect(count).to.be.equal(1);
                allowPubrec = true;
                receiveFunc = () => {
                    receiverClient.destroy();
                    emitterClient.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if message with QoS1 received', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa4';
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data, packet) => receiveFunc && receiveFunc(topic, data, packet),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    receiveFunc = (topic, data, packet) => {
                        expect(data).to.be.ok;
                        expect(topic).to.be.ok;
                        expect(packet.qos).to.be.equal(1);
                        receiverClient.destroy();
                        emitterClient.destroy();
                        done();
                    };
                    emitterClient.publish(id, data.toString(), 1); // Send QoS 2
                    setTimeout(() => resolve(), 100);
                });
            });
    }).timeout(1000);

    // check unsubscribe
    it('MQTT server: Check if unsubscribes works', () => {
        let client;
        const data = 1;
        let count = 0;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa6');
                    setTimeout(() => {
                        adapter.setForeignState('mqtt.0.aaa6', data);
                        server.onStateChange('mqtt.0.aaa6', {val: data, ack: false});
                    }, 500);
                }
            },
            (id, topic, packet) => {
                if (id.indexOf('aaa6') !== -1) {
                    console.log('Received ' + topic.toString());
                    count++;
                    expect(count).to.be.equal(1);
                    setTimeout(() => resolve(), 100);
                }
            },
            {
                url: 'localhost:' + port,
                clean: true,
                clientId: 'testClient6',
                resubscribe: false
            }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    client.unsubscribe('aaa6');
                    client.unsubscribe('#');
                    setTimeout(() => {
                        console.log('Resend data');
                        adapter.setForeignState('mqtt.0.aaa6', 2);
                        server.onStateChange('mqtt.0.aaa6', {val: 2, ack: false});
                        // wait 1 second to not receive the update
                        setTimeout(() => {
                            console.log('Done');
                            client.destroy();
                            resolve();
                        }, 1000);
                    }, 300);
                });
            });
    }).timeout(3000);

    after('MQTT server: Stop MQTT server', done => {
        server.destroy(done);
    });
});
<commit_msg>* try fix<commit_after>'use strict';
const expect = require('chai').expect;
const Adapter = require('./lib/adapterSim');
const Server = require('../lib/server');
const Client = require('./lib/mqttClient');

let port = 1883;

describe('MQTT server', () => {
    let adapter;
    let server;
    const states   = {};

    before('MQTT server: Start MQTT server', done => {
        adapter = new Adapter({
            port: ++port,
            defaultQoS: 1,
            onchange: true
        });
        server = new Server(adapter, states);
        done();
    });

    it('MQTT server: Check if connected to MQTT broker', done => {
        const client = new Client(isConnected => {
            if (done) {
                expect(isConnected).to.be.true;
                client.destroy();
                done();
                done = null;
            }
        },
        null,
        {
            url: 'localhost:' + port,
            clientId: 'testClient1',
        }
        );
    });

    it('MQTT server: Check if subscribes stored', () => {
        let client;
        const data = 1;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa');
                    setTimeout(() => client.destroy(), 200); // let time to send it out
                } else {
                    adapter.setForeignState('mqtt.0.aaa', data);
                    server.onStateChange('mqtt.0.aaa', {val: data, ack: false});
                    setTimeout(() => resolve(), 100);
                }
            },
            null,
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient2',
                resubscribe: false
            }
            );
        })
            .then(() => {
                new Promise(resolve => {
                    client = new Client(
                        () => {

                        },
                        (topic, message) => {
                            if (topic === 'aaa') {
                                expect(topic).to.be.equal('aaa');
                                expect(message.toString()).to.be.equal(data.toString());
                                client.destroy();
                                resolve();
                            }
                        },
                        {
                            url: 'localhost:' + port,
                            clean: false,
                            clientId: 'testClient2',
                            resubscribe: false
                        }
                    );
                });
            });
    });

    it('MQTT server: Check if QoS1 retransmitted', done => {
        let client;
        const data = 1;
        let sendPacket;
        let count = 0;
        const id = 'aaa2';
        let allowPuback = false;
        let receiveFunc;
        new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'testClient3',
                resubscribe: false
            }
            );
            sendPacket = client.client._sendPacket;
            client.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS1 called for ' + JSON.stringify(packet));
                // ignore puback
                if (packet.cmd === 'puback' && !allowPuback) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb, cbStorePut);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    adapter.setForeignState('mqtt.0.' + id, data);
                    server.onStateChange('mqtt.0.' + id, {val: data, ack: false});
                    setTimeout(() => resolve(), 1000);
                });
            })
            .then(() => {
                console.log(`[${new Date().toISOString()} continue tests`);
                expect(count).to.be.equal(1);
                allowPuback = true;
                receiveFunc = () => {
                    client.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if QoS2 retransmitted', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa3';
        let sendPacket;
        let count = 0;
        let allowPubrec = false;
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 2});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data) => receiveFunc && receiveFunc(topic, data),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
            receiverClient.client.on('packetreceive', packet => {
               console.log('Receiving client received ' + JSON.stringify(packet));
            });
            sendPacket = receiverClient.client._sendPacket;
            receiverClient.client._sendPacket = function (packet, cb, cbStorePut) {
                console.log('Overwritten _sendPacket-QoS2 called for ' + JSON.stringify(packet));
                // ignore pubrec
                if (packet.cmd === 'pubrec' && !allowPubrec) {
                    count++;
                    cb && cb();
                    return;
                }
                sendPacket.call(this, packet, cb);
            };
        })
            .then(() => {
                return new Promise(resolve => {
                    emitterClient.publish(id, data.toString(), 2, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 500);
                });
            })
            .then(() => {
                expect(count).to.be.equal(1);
                allowPubrec = true;
                receiveFunc = () => {
                    receiverClient.destroy();
                    emitterClient.destroy();
                    done();
                };
            });
    }).timeout(5000);

    it('MQTT server: Check if message with QoS1 received', done => {
        let receiverClient;
        let emitterClient;
        const data = 1;
        const id = 'aaa4';
        let receiveFunc;
        new Promise(resolve => {
            receiverClient = new Client(isConnected => {
                if (isConnected) {
                    receiverClient.subscribe(id, {qos: 1});
                    setTimeout(() => resolve(), 100);
                }
            },
            (topic, data, packet) => receiveFunc && receiveFunc(topic, data, packet),
            {
                url: 'localhost:' + port,
                clean: false,
                clientId: 'receiverClient',
                resubscribe: false
            }
            );
            emitterClient = new Client(null, null,
                {
                    url: 'localhost:' + port,
                    clean: true,
                    clientId: 'emitterClient',
                    resubscribe: false
                }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    receiveFunc = (topic, data, packet) => {
                        expect(data).to.be.ok;
                        expect(topic).to.be.ok;
                        expect(packet.qos).to.be.equal(1);
                        receiverClient.destroy();
                        emitterClient.destroy();
                        done();
                    };
                    emitterClient.publish(id, data.toString(), 1, () => { }); // Send QoS 2
                    setTimeout(() => resolve(), 100);
                });
            });
    }).timeout(1000);

    // check unsubscribe
    it('MQTT server: Check if unsubscribes works', () => {
        let client;
        const data = 1;
        let count = 0;
        return new Promise(resolve => {
            client = new Client(isConnected => {
                if (isConnected) {
                    client.subscribe('aaa6');
                    setTimeout(() => {
                        adapter.setForeignState('mqtt.0.aaa6', data);
                        server.onStateChange('mqtt.0.aaa6', {val: data, ack: false});
                    }, 500);
                }
            },
            (id, topic, packet) => {
                if (id.indexOf('aaa6') !== -1) {
                    console.log('Received ' + topic.toString());
                    count++;
                    expect(count).to.be.equal(1);
                    setTimeout(() => resolve(), 100);
                }
            },
            {
                url: 'localhost:' + port,
                clean: true,
                clientId: 'testClient6',
                resubscribe: false
            }
            );
        })
            .then(() => {
                return new Promise(resolve => {
                    client.unsubscribe('aaa6');
                    client.unsubscribe('#');
                    setTimeout(() => {
                        console.log('Resend data');
                        adapter.setForeignState('mqtt.0.aaa6', 2);
                        server.onStateChange('mqtt.0.aaa6', {val: 2, ack: false});
                        // wait 1 second to not receive the update
                        setTimeout(() => {
                            console.log('Done');
                            client.destroy();
                            resolve();
                        }, 1000);
                    }, 300);
                });
            });
    }).timeout(3000);

    after('MQTT server: Stop MQTT server', done => {
        server.destroy(done);
    });
});
<|endoftext|>


<commit_before>import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { setupIntl } from 'ember-intl/test-support';
import { fillIn, render, waitFor } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | wait saving', function (hooks) {
  setupRenderingTest(hooks);
  setupIntl(hooks, 'en-us');

  test('it renders', async function (assert) {
    assert.expect(1);
    await render(hbs`<WaitSaving />`);

    assert.dom(this.element).hasText('saving... one moment...');
  });

  test('it in block form', async function (assert) {
    assert.expect(1);
    await render(hbs`
      <WaitSaving>
        template block text
      </WaitSaving>
    `);

    assert.dom(this.element).hasText('template block text');
  });

  test('it traps focus and returns it', async function (assert) {
    await render(hbs`
      {{#if this.show}}
        <WaitSaving />
      {{/if}}
      <input type="text" />
    `);
    await fillIn('input', 'text');
    assert.dom('input').isFocused();
    this.set('show', true);
    await waitFor('[data-test-wait-saving]');
    assert.dom('input').isNotFocused();
    assert.dom('[data-test-wait-saving] [data-test-content]').isFocused();
    this.set('show', false);
    assert.dom('input').isFocused();
  });
});
<commit_msg>Wait for settled in test<commit_after>import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { setupIntl } from 'ember-intl/test-support';
import { fillIn, render, waitFor, settled } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | wait saving', function (hooks) {
  setupRenderingTest(hooks);
  setupIntl(hooks, 'en-us');

  test('it renders', async function (assert) {
    assert.expect(1);
    await render(hbs`<WaitSaving />`);

    assert.dom(this.element).hasText('saving... one moment...');
  });

  test('it in block form', async function (assert) {
    assert.expect(1);
    await render(hbs`
      <WaitSaving>
        template block text
      </WaitSaving>
    `);

    assert.dom(this.element).hasText('template block text');
  });

  test('it traps focus and returns it', async function (assert) {
    await render(hbs`
      {{#if this.show}}
        <WaitSaving />
      {{/if}}
      <input type="text" />
    `);
    await fillIn('input', 'text');
    assert.dom('input').isFocused();
    this.set('show', true);
    await waitFor('[data-test-wait-saving]');
    assert.dom('input').isNotFocused();
    assert.dom('[data-test-wait-saving] [data-test-content]').isFocused();
    this.set('show', false);
    await settled();
    assert.dom('input').isFocused();
  });
});
<|endoftext|>


<commit_before>"use strict";
var vscode = require('vscode');
var beautify = require('js-beautify');
var path = require('path');
var fs = require('fs');

function findRecursive(dir, fileName) {
	var fullPath = path.join(dir, fileName);
	var nextDir = path.dirname(dir);
	var result = fs.existsSync(fullPath) ? fullPath : null;
	if (!result && (nextDir !== dir)) {
		result = findRecursive(nextDir, fileName);
	}
	return result;
}
var dropComments = inText => inText.replace(/(\/\*.*\*\/)|\/\/.*(?:[\r\n]|$)/g, "");

//register on activation
function activate(context) {
	var mergeOpts = function(opts, type) {
		var finOpts = {};
		for (let a in opts) {
			if (a !== 'js' && a !== 'html' && a !== 'css') {
				finOpts[a] = opts[a];
			}
		}
		//merge in the per type settings
		if (type in opts) {
			for (let b in opts[type]) {
				if (b === 'allowed_file_extensions') continue;
				finOpts[b] = opts[type][b];
			}
		}
		return finOpts;
	};
	var getBeautifyType = function(doc) {
		return Promise.resolve()
			.then(() => {
				var type = doc.isUntitled ? "" : doc.fileName.split('.')
					.pop()
					.toLowerCase();
				var cfg = vscode.workspace.getConfiguration('beautify');
				//if a type is set on the window, use that
				//check if the file is in the users json schema set
				var jsSchema = vscode.workspace.getConfiguration('json')
					.schemas;
				if (jsSchema.length) {
					var matcher = [];
					var extMatch = n => ({
						pattern: n.startsWith("**/") ? n : ("**/" + n)
					});
					jsSchema.forEach(schema => {
						if (typeof schema.fileMatch === 'string') {
							matcher.push(extMatch(schema.fileMatch));
						} else {
							var t = schema.fileMatch.map(extMatch);
							matcher = matcher.concat(t);
						}
					});
					if (vscode.languages.match(matcher, doc)) {
						return "js";
					}
				}
				if (cfg.HTMLfiles.indexOf(type) + 1) return "html";
				else if (cfg.CSSfiles.indexOf(type) + 1) return "css";
				else if (cfg.JSfiles.indexOf(type) + 1) return "js";
				else {
					//Ask what they want to do:
					return vscode.window.showQuickPick([{
							label: "JS",
							description: "Does JavaScript and JSON"
						}, {
							label: "CSS"
						}, {
							label: "HTML"
						}], {
							matchOnDescription: true,
							placeHolder: "Couldn't determine type to beautify, pleae choose."
						})
						.then(function(choice) {
							if (!choice || !choice.label) return;
							return choice.label.toLowerCase();
						});
				}
			});
	};
	var doBeautify = function(active, doc, type, opts) {
		var original = doc.getText();
		//get the whole file:
		var range = new vscode.Range(new vscode.Position(0, 0), doc.positionAt(Infinity));
		var result = beautify[type](original, opts);
		//and make the change:
		active.edit(editor => editor.replace(range, result));
	};
	//it's ok to build and pass the re from outside of here, we always run
	//to completion.
	var disposable = vscode.commands.registerCommand('HookyQR.beautify', function() {
		var active = vscode.window.activeTextEditor;
		if (!active) return;
		var doc = active.document;
		if (!doc) return;
		//get a settings file
		var base = vscode.workspace.rootPath;

		if (!doc.isUntitled) base = doc.fileName;

		//get the type of beautify to be done
		getBeautifyType(doc)
			.then(type => {
				if (!type) return; //user skipped the selection
				var beautFile;
				if (base) beautFile = findRecursive(base, ".jsbeautifyrc");
				//walk to find a .jsbeautifyrc
				if (beautFile) fs.readFile(beautFile, function(ee, d) {
					if (!d) d = "{}";
					var opts = {};
					try {
						var unCommented = dropComments(d.toString());
						opts = JSON.parse(unCommented);
						opts = mergeOpts(opts, type);
					} catch (e) {
						vscode.window.showWarningMessage("Found a .jsbeautifyrc file, but it didn't parse correctly.");
						opts = {}; //just use the default opts
					}
					doBeautify(active, doc, type, opts);
				});
				else doBeautify(active, doc, type, {});
			});
	});
	context.subscriptions.push(disposable);
}
exports.activate = activate;
<commit_msg>fix: typo in quick pick placeholder<commit_after>"use strict";
var vscode = require('vscode');
var beautify = require('js-beautify');
var path = require('path');
var fs = require('fs');

function findRecursive(dir, fileName) {
	var fullPath = path.join(dir, fileName);
	var nextDir = path.dirname(dir);
	var result = fs.existsSync(fullPath) ? fullPath : null;
	if (!result && (nextDir !== dir)) {
		result = findRecursive(nextDir, fileName);
	}
	return result;
}
var dropComments = inText => inText.replace(/(\/\*.*\*\/)|\/\/.*(?:[\r\n]|$)/g, "");

//register on activation
function activate(context) {
	var mergeOpts = function(opts, type) {
		var finOpts = {};
		for (let a in opts) {
			if (a !== 'js' && a !== 'html' && a !== 'css') {
				finOpts[a] = opts[a];
			}
		}
		//merge in the per type settings
		if (type in opts) {
			for (let b in opts[type]) {
				if (b === 'allowed_file_extensions') continue;
				finOpts[b] = opts[type][b];
			}
		}
		return finOpts;
	};
	var getBeautifyType = function(doc) {
		return Promise.resolve()
			.then(() => {
				var type = doc.isUntitled ? "" : doc.fileName.split('.')
					.pop()
					.toLowerCase();
				var cfg = vscode.workspace.getConfiguration('beautify');
				//if a type is set on the window, use that
				//check if the file is in the users json schema set
				var jsSchema = vscode.workspace.getConfiguration('json')
					.schemas;
				if (jsSchema.length) {
					var matcher = [];
					var extMatch = n => ({
						pattern: n.startsWith("**/") ? n : ("**/" + n)
					});
					jsSchema.forEach(schema => {
						if (typeof schema.fileMatch === 'string') {
							matcher.push(extMatch(schema.fileMatch));
						} else {
							var t = schema.fileMatch.map(extMatch);
							matcher = matcher.concat(t);
						}
					});
					if (vscode.languages.match(matcher, doc)) {
						return "js";
					}
				}
				if (cfg.HTMLfiles.indexOf(type) + 1) return "html";
				else if (cfg.CSSfiles.indexOf(type) + 1) return "css";
				else if (cfg.JSfiles.indexOf(type) + 1) return "js";
				else {
					//Ask what they want to do:
					return vscode.window.showQuickPick([{
							label: "JS",
							description: "Does JavaScript and JSON"
						}, {
							label: "CSS"
						}, {
							label: "HTML"
						}], {
							matchOnDescription: true,
							placeHolder: "Couldn't determine type to beautify, please choose."
						})
						.then(function(choice) {
							if (!choice || !choice.label) return;
							return choice.label.toLowerCase();
						});
				}
			});
	};
	var doBeautify = function(active, doc, type, opts) {
		var original = doc.getText();
		//get the whole file:
		var range = new vscode.Range(new vscode.Position(0, 0), doc.positionAt(Infinity));
		var result = beautify[type](original, opts);
		//and make the change:
		active.edit(editor => editor.replace(range, result));
	};
	//it's ok to build and pass the re from outside of here, we always run
	//to completion.
	var disposable = vscode.commands.registerCommand('HookyQR.beautify', function() {
		var active = vscode.window.activeTextEditor;
		if (!active) return;
		var doc = active.document;
		if (!doc) return;
		//get a settings file
		var base = vscode.workspace.rootPath;

		if (!doc.isUntitled) base = doc.fileName;

		//get the type of beautify to be done
		getBeautifyType(doc)
			.then(type => {
				if (!type) return; //user skipped the selection
				var beautFile;
				if (base) beautFile = findRecursive(base, ".jsbeautifyrc");
				//walk to find a .jsbeautifyrc
				if (beautFile) fs.readFile(beautFile, function(ee, d) {
					if (!d) d = "{}";
					var opts = {};
					try {
						var unCommented = dropComments(d.toString());
						opts = JSON.parse(unCommented);
						opts = mergeOpts(opts, type);
					} catch (e) {
						vscode.window.showWarningMessage("Found a .jsbeautifyrc file, but it didn't parse correctly.");
						opts = {}; //just use the default opts
					}
					doBeautify(active, doc, type, opts);
				});
				else doBeautify(active, doc, type, {});
			});
	});
	context.subscriptions.push(disposable);
}
exports.activate = activate;
<|endoftext|>


<commit_before>;(function(K){

/**
 * setter for class attributes
 * @private
 * @param {boolean} ghost inner use
 	if true, setValue will ignore all flags or validators and force to writing the new value

 * @return {boolean} whether the new value has been successfully set
 */
function setValue(host, attr, value){
	var pass = true,
		setter,
		validator,
		v;

	if(attr[READ_ONLY]){
		pass = false;

	}else{
		validator = getMethod(host, attr, VALIDATOR);

		pass = !validator || validator.call(host, value);
	}

	if(pass && attr[WRITE_ONCE]){
		delete attr[WRITE_ONCE];
		attr[READ_ONLY] = TRUE;
	}

	if(pass){
		setter = getMethod(host, attr, SETTER);

		if(setter){
			// if setter is defined, always set the return value of setter to attr.value
			attr.value = setter.call(host, value);
		}else{

			// mix object values
			attr.value = value;
		}
	}

	return pass;
};

/**
 * getter for class attributes
 */
function getValue(host, attr, undef){
	var getter = getMethod(host, attr, GETTER),
		v = attr.value;

	return getter ?

		  // getter could based on the value of the current value
		  getter.call(host, v)
		: v;
};

function getMethod(host, attr, name){
	var method = attr[name];

	return typeof method === 'string' ? host[method] : method;
};

/**
 * @private
 * @param {Object} host
 * @param {Object} sandbox shadow copy of the attributes of a class instance
 * @param {undefined=} undef
 */
function createGetterSetter(host, sandbox, undef){
	host.set = overloadSetter( function(key, value){
		var attr = sandbox[key];

		return attr ? setValue(this, attr, value) : false;
	});

	host.get = function(key){
		var attr = sandbox[key];

		return attr ? getValue(this, attr) : undef;
	};

	host.addAttr = overloadSetter(function(key, setting){
		sandbox[key] || (sandbox[key] = K.isObject(setting) ?

							// it's important to clone the setting before mixing into the sandbox,
							// or host.set method will ruin all references
							K.clone(setting) :
							{}
						);
	});
};

function createPublicMethod(name){
	return function(){
		var self = this,

			// @private
			// sandbox
			sandbox = createSandBox(self);

		// .set and .get methods won't be available util .setAttrs method excuted
		createGetterSetter(self, sandbox);

		return self[name].apply(self, arguments);
	};
};

function createSandBox(host){
	var class_ = host.constructor,
		sandbox;

	do{
		if(sandbox = class_.ATTRS){
			break;
		}
	} while(class_ = class_.prototype[__SUPER_CLASS]);

	return sandbox ? K.clone(sandbox) : {};
};

var TRUE = true,
	GETTER = 'getter',
	SETTER = 'setter',
	VALIDATOR = 'validator',
	READ_ONLY = 'readOnly',
	WRITE_ONCE = 'writeOnce',

	__SUPER_CLASS = 'superclass',

	NOOP = function(){},

	isPlainObject = K.isPlainObject,
	overloadSetter = K._overloadSetter;

/**

 ATTRS = {
 	attr: {
 		value: 100
 	},

 	attrWithSetter: {
 		setter: function(){}
 	},

 	attrWithProxySetter: {
 		setter: '_setTimeout'
 	},

 	attrWithValidator: {
 		value: 100,
 		validator: function(v){
 			return v <= 100;
 		}
 	}
 };

 */

var attrs = {};

['addAttr', 'get', 'set'].forEach(function(name){
	attrs[name] = createPublicMethod(name);
});

K.Class.EXTS.attrs = attrs;

attrs = null;

})(KM);

/**
 2012-02-23  Kael:
 - fix a fatal reference exception for .addAttr method

 2012-01-30  Kael:
 - remove .setAttrs methdo. sandbox will be initialized by the first execution of .set, .get, or .addAttr method

 2011-10-24  Kael:
 - setAttrs method will return this
 - prevent addAttr method from affecting the existing attr object

 2011-10-18  Kael:
 TODO:
 - ? A. optimize setAttrs method, lazily initialize presets after they are called

 2011-09-20  Kael:
 - attr setter will return true or false to tell whether the new value has been successfully set

 2011-09-17  Kael:
 - TODO[09-15].A

 2011-09-15  Kael:
 - privatize attributes
 - create .get and .set method

 TODO:
 - √ A. ATTRs inheritance

 */<commit_msg>oop/attrs: overload .get method, that we could get all attributes at once;<commit_after>;(function(K){

/**
 * setter for class attributes
 * @private
 * @param {boolean} ghost inner use
 	if true, setValue will ignore all flags or validators and force to writing the new value

 * @return {boolean} whether the new value has been successfully set
 */
function setValue(host, attr, value){
	var pass = true,
		setter,
		validator,
		v;

	if(attr[READ_ONLY]){
		pass = false;

	}else{
		validator = getMethod(host, attr, VALIDATOR);

		pass = !validator || validator.call(host, value);
	}

	if(pass && attr[WRITE_ONCE]){
		delete attr[WRITE_ONCE];
		attr[READ_ONLY] = TRUE;
	}

	if(pass){
		setter = getMethod(host, attr, SETTER);

		if(setter){
			// if setter is defined, always set the return value of setter to attr.value
			attr.value = setter.call(host, value);
		}else{

			// mix object values
			attr.value = value;
		}
	}

	return pass;
};

/**
 * getter for class attributes
 */
function getValue(host, attr, undef){
	var getter = getMethod(host, attr, GETTER),
		v = attr.value;

	return getter ?

		  // getter could based on the value of the current value
		  getter.call(host, v)
		: v;
};

function getMethod(host, attr, name){
	var method = attr[name];

	return typeof method === 'string' ? host[method] : method;
};

/**
 * @private
 * @param {Object} host
 * @param {Object} sandbox shadow copy of the attributes of a class instance
 * @param {undefined=} undef
 */
function createGetterSetter(host, sandbox, undef){
    function _get(key, sandbox){
		var attr = sandbox[key];

		return attr ? getValue(this, attr) : undef;
	};

	function _getAll(){
        var s = sandbox,
            key,
            ret = {};

        for(key in s){
            ret[key] = _get(key, s);
        }

        return ret;
	};

	host.set = overloadSetter( function(key, value){
		var attr = sandbox[key];

		return attr ? setValue(this, attr, value) : false;
	});

	host.get = function(key){
    	return arguments.length ? _get(key, sandbox) : _getAll();
	};

	host.addAttr = overloadSetter(function(key, setting){
		sandbox[key] || (sandbox[key] = K.isObject(setting) ?

							// it's important to clone the setting before mixing into the sandbox,
							// or host.set method will ruin all references
							K.clone(setting) :
							{}
						);
	});

	host.removeAttr = function(key){
	    delete sandbox[key];
	};
};

function createPublicMethod(name){
	return function(){
		var self = this,

			// @private
			// sandbox
			sandbox = createSandBox(self);

		// .set and .get methods won't be available util .setAttrs method excuted
		createGetterSetter(self, sandbox);

		return self[name].apply(self, arguments);
	};
};

function createSandBox(host){
	var class_ = host.constructor,
		sandbox;

	do{
		if(sandbox = class_.ATTRS){
			break;
		}
	} while(class_ = class_.prototype[__SUPER_CLASS]);

	return sandbox ? K.clone(sandbox) : {};
};

var TRUE = true,
	GETTER = 'getter',
	SETTER = 'setter',
	VALIDATOR = 'validator',
	READ_ONLY = 'readOnly',
	WRITE_ONCE = 'writeOnce',

	__SUPER_CLASS = 'superclass',

	NOOP = function(){},

	isPlainObject = K.isPlainObject,
	overloadSetter = K._overloadSetter;

/**

 ATTRS = {
 	attr: {
 		value: 100
 	},

 	attrWithSetter: {
 		setter: function(){}
 	},

 	attrWithProxySetter: {
 		setter: '_setTimeout'
 	},

 	attrWithValidator: {
 		value: 100,
 		validator: function(v){
 			return v <= 100;
 		}
 	}
 };

 */

var attrs = {};

['addAttr', 'get', 'set'].forEach(function(name){
	attrs[name] = createPublicMethod(name);
});

K.Class.EXTS.attrs = attrs;

attrs = null;

})(KM);

/**
 2012-02-23  Kael:
 - fix a fatal reference exception for .addAttr method

 2012-01-30  Kael:
 - remove .setAttrs methdo. sandbox will be initialized by the first execution of .set, .get, or .addAttr method

 2011-10-24  Kael:
 - setAttrs method will return this
 - prevent addAttr method from affecting the existing attr object

 2011-10-18  Kael:
 TODO:
 - ? A. optimize setAttrs method, lazily initialize presets after they are called

 2011-09-20  Kael:
 - attr setter will return true or false to tell whether the new value has been successfully set

 2011-09-17  Kael:
 - TODO[09-15].A

 2011-09-15  Kael:
 - privatize attributes
 - create .get and .set method

 TODO:
 - √ A. ATTRs inheritance

 */<|endoftext|>


<commit_before>

/*
Maps locale from django to Facebook
scraped like this from FB:
curl https://www.facebook.com/translations/FacebookLocales.xml -s | grep "<representation>" FacebookLocales.xml | sed 's@<\([^<>][^<>]*\)>\([^<>]*\)</\1>@\2@g'
* */
fbLocales = ["af_ZA", "ar_AR", "az_AZ", "be_BY", "bg_BG", "bn_IN", "bs_BA",
    "ca_ES", "cs_CZ", "cy_GB", "da_DK", "de_DE", "el_GR", "en_GB", "en_PI",
    "en_UD", "en_US", "eo_EO", "es_ES", "es_LA", "et_EE", "eu_ES", "fa_IR",
    "fb_LT", "fi_FI", "fo_FO", "fr_CA", "fr_FR", "fy_NL", "ga_IE", "gl_ES",
    "he_IL", "hi_IN", "hr_HR", "hu_HU", "hy_AM", "id_ID", "is_IS", "it_IT",
    "ja_JP", "ka_GE", "ko_KR", "ku_TR", "la_VA", "lt_LT", "lv_LV", "mk_MK",
    "ml_IN", "ms_MY", "nb_NO", "ne_NP", "nl_NL", "nn_NO", "pa_IN", "pl_PL",
    "ps_AF", "pt_BR", "pt_PT", "ro_RO", "ru_RU", "sk_SK", "sl_SI", "sq_AL",
    "sr_RS", "sv_SE", "sw_KE", "ta_IN", "te_IN", "th_TH", "tl_PH", "tr_TR",
    "uk_UA", "vi_VN", "zh_CN", "zh_HK", "zh_TW"];

fbLocaleMapping = {};
for (var i=0; i<fbLocales.length;i++){
    var k = fbLocales[i].split("_")[0];
    fbLocaleMapping[k] = fbLocales[i];
    fbLocaleMapping[fbLocales[i]] = fbLocales[i];
}

/* Define dummy gettext if Django's javascrip_catalog is not being used */
if (typeof gettext != 'function') {
    window.gettext = function(text) {
        return text;
    };
}

facebookClass = function() { this.initialize.apply(this, arguments); };
facebookClass.prototype = {
    initialize: function (appId) {
        this.appId = appId;

        var scope = this;
        function javascriptLoaded() {
            scope.javascriptLoaded.call(scope);
        }

        var iphone = navigator.userAgent.match(/iPhone/i)
        var ipod = navigator.userAgent.match(/iPod/i);
        var ipad = navigator.userAgent.match(/iPad/i);
        var ithing = iphone || ipod || ipad;
        this.ithing = ithing;
    },

    getDefaultScope : function() {
        var defaultScope;
       if (typeof(facebookDefaultScope) != 'undefined') {
            defaultScope = facebookDefaultScope;
       } else {
           defaultScope = ['email', 'user_about_me', 'user_birthday', 'user_website'];
       }
       return defaultScope;
    },

    connect: function (formElement, requiredPerms) {
        if (this.ithing) {
            return formElement.submit();
        }
        requiredPerms = requiredPerms || this.getDefaultScope();
        this.connectLoading(gettext('A Facebook pop-up has opened, please follow the instructions to sign in.'));
        var scope = this;
        FB.login(function(response) {
            if (response.authResponse) {
                //showloading
                scope.connectLoading(gettext('Now loading your profile...'));
                //submit the form
                formElement.submit();
            } else {
                var errorMessage = gettext('Sorry, we couldn\'t log you in. Please try again.');
                scope.connectLoading(errorMessage, true, true);
            }
        },
        {scope: requiredPerms.join(',')}
        );
    },

    connectLoading: function (message, closeable, hideLoading) {
        /*
         * Show a loading lightbox to clarify what's happening to the user
         */
        var facebookMessage = document.getElementById('facebook_message');
        var facebookContainer = document.getElementById('facebook_container');
        if (!facebookMessage) {
            var container = document.createElement('div');
            container.id = 'facebook_container';
            var html = '

\

\

\

{{ message }}
\
                        \

\

\

';
            html = html.replace('{{ message }}', message);
            container.innerHTML = html;
            document.body.appendChild(container);
            facebookMessage = document.getElementById('facebook_message');
            facebookContainer = document.getElementById('facebook_container');
        }
        facebookMessage.innerHTML = message;
        facebookContainer.style.display = message ? 'block' : 'none';
        document.getElementById('facebook_close').style.display = closeable ? 'block' : 'none';
        document.getElementById('facebook_loading').style.display = hideLoading ? 'none' : 'inline';

        //set the correct top
        var requiredTop = this.getViewportScrollY();
        document.getElementById('facebook_lightbox').style.top = requiredTop + 'px';
    },

    load: function () {
        var facebookScript = document.getElementById('facebook_js');
        if (!facebookScript) {
            var e = document.createElement('script');
            e.type = 'text/javascript';
            // gets the locale, tries to get the facebook synonym and
            // the checks if it is a valid FB locale
            var fbLocale = "en_US";
            if(typeof(locale) != 'undefined') {
                if (locale in fbLocaleMapping) {
                    fbLocale = fbLocaleMapping[locale];
                }
            }
            var fbLocation = '//connect.facebook.net/' + fbLocale + '/all.js';
            e.src = document.location.protocol + fbLocation;
            e.async = true;
            e.id = 'facebook_js';
            document.getElementById('fb-root').appendChild(e);
        }
    },

    getViewportScrollY: function() {
        var scrollY = 0;
        if( document.documentElement && document.documentElement.scrollTop ) {
          scrollY = document.documentElement.scrollTop;
        }
        else if( document.body && document.body.scrollTop ) {
          scrollY = document.body.scrollTop;
        }
        else if( window.pageYOffset ) {
          scrollY = window.pageYOffset;
        }
        else if( window.scrollY ) {
          scrollY = window.scrollY;
        }
        return scrollY;
    }
};

<commit_msg>tested js login flow<commit_after>

/*
Maps locale from django to Facebook
scraped like this from FB:
curl https://www.facebook.com/translations/FacebookLocales.xml -s | grep "<representation>" FacebookLocales.xml | sed 's@<\([^<>][^<>]*\)>\([^<>]*\)</\1>@\2@g'
* */
fbLocales = ["af_ZA", "ar_AR", "az_AZ", "be_BY", "bg_BG", "bn_IN", "bs_BA",
    "ca_ES", "cs_CZ", "cy_GB", "da_DK", "de_DE", "el_GR", "en_GB", "en_PI",
    "en_UD", "en_US", "eo_EO", "es_ES", "es_LA", "et_EE", "eu_ES", "fa_IR",
    "fb_LT", "fi_FI", "fo_FO", "fr_CA", "fr_FR", "fy_NL", "ga_IE", "gl_ES",
    "he_IL", "hi_IN", "hr_HR", "hu_HU", "hy_AM", "id_ID", "is_IS", "it_IT",
    "ja_JP", "ka_GE", "ko_KR", "ku_TR", "la_VA", "lt_LT", "lv_LV", "mk_MK",
    "ml_IN", "ms_MY", "nb_NO", "ne_NP", "nl_NL", "nn_NO", "pa_IN", "pl_PL",
    "ps_AF", "pt_BR", "pt_PT", "ro_RO", "ru_RU", "sk_SK", "sl_SI", "sq_AL",
    "sr_RS", "sv_SE", "sw_KE", "ta_IN", "te_IN", "th_TH", "tl_PH", "tr_TR",
    "uk_UA", "vi_VN", "zh_CN", "zh_HK", "zh_TW"];

fbLocaleMapping = {};
for (var i=0; i<fbLocales.length;i++){
    var k = fbLocales[i].split("_")[0];
    fbLocaleMapping[k] = fbLocales[i];
    fbLocaleMapping[fbLocales[i]] = fbLocales[i];
}

/* Define dummy gettext if Django's javascrip_catalog is not being used */
if (typeof gettext != 'function') {
    window.gettext = function(text) {
        return text;
    };
}

facebookClass = function() { this.initialize.apply(this, arguments); };
facebookClass.prototype = {
    initialize: function (appId) {
        this.appId = appId;

        var scope = this;
        function javascriptLoaded() {
            scope.javascriptLoaded.call(scope);
        }

        var iphone = navigator.userAgent.match(/iPhone/i)
        var ipod = navigator.userAgent.match(/iPod/i);
        var ipad = navigator.userAgent.match(/iPad/i);
        var ithing = iphone || ipod || ipad;
        this.ithing = ithing;
    },

    getDefaultScope : function() {
        var defaultScope;
       if (typeof(facebookDefaultScope) != 'undefined') {
            defaultScope = facebookDefaultScope;
       } else {
           defaultScope = ['email', 'user_about_me', 'user_birthday', 'user_website'];
       }
       return defaultScope;
    },

    connect: function (formElement, requiredPerms) {
        if (this.ithing) {
            return formElement.submit();
        }
        requiredPerms = requiredPerms || this.getDefaultScope();
        this.connectLoading(gettext('A Facebook pop-up has opened, please follow the instructions to sign in.'));
        var scope = this;
        FB.login(function(response) {
            var authResponse = response.authResponse;
            if (authResponse) {
                //showloading
                scope.connectLoading(gettext('Now loading your profile...'));
                //submit the form
                formElement.submit();
            } else {
                var errorMessage = gettext('Sorry, we couldn\'t log you in. Please try again.');
                scope.connectLoading(errorMessage, true, true);
            }
        },
        {scope: requiredPerms.join(',')}
        );
    },

    connectLoading: function (message, closeable, hideLoading) {
        /*
         * Show a loading lightbox to clarify what's happening to the user
         */
        var facebookMessage = document.getElementById('facebook_message');
        var facebookContainer = document.getElementById('facebook_container');
        if (!facebookMessage) {
            var container = document.createElement('div');
            container.id = 'facebook_container';
            var html = '

\

\

\

{{ message }}
\
                        \

\

\

';
            html = html.replace('{{ message }}', message);
            container.innerHTML = html;
            document.body.appendChild(container);
            facebookMessage = document.getElementById('facebook_message');
            facebookContainer = document.getElementById('facebook_container');
        }
        facebookMessage.innerHTML = message;
        facebookContainer.style.display = message ? 'block' : 'none';
        document.getElementById('facebook_close').style.display = closeable ? 'block' : 'none';
        document.getElementById('facebook_loading').style.display = hideLoading ? 'none' : 'inline';

        //set the correct top
        var requiredTop = this.getViewportScrollY();
        document.getElementById('facebook_lightbox').style.top = requiredTop + 'px';
    },

    load: function () {
        var facebookScript = document.getElementById('facebook_js');
        if (!facebookScript) {
            var e = document.createElement('script');
            e.type = 'text/javascript';
            // gets the locale, tries to get the facebook synonym and
            // the checks if it is a valid FB locale
            var fbLocale = "en_US";
            if(typeof(locale) != 'undefined') {
                if (locale in fbLocaleMapping) {
                    fbLocale = fbLocaleMapping[locale];
                }
            }
            var fbLocation = '//connect.facebook.net/' + fbLocale + '/all.js';
            e.src = document.location.protocol + fbLocation;
            e.async = true;
            e.id = 'facebook_js';
            document.getElementById('fb-root').appendChild(e);
        }
    },

    getViewportScrollY: function() {
        var scrollY = 0;
        if( document.documentElement && document.documentElement.scrollTop ) {
          scrollY = document.documentElement.scrollTop;
        }
        else if( document.body && document.body.scrollTop ) {
          scrollY = document.body.scrollTop;
        }
        else if( window.pageYOffset ) {
          scrollY = window.pageYOffset;
        }
        else if( window.scrollY ) {
          scrollY = window.scrollY;
        }
        return scrollY;
    }
};

<|endoftext|>


<commit_before>// O6S - Sigmascape 2.0 Savage
[{
  zoneRegex: /Sigmascape V2\.0 \(Savage\)/,
  timelineFile: 'o6s.txt',
  triggers: [
    {
      id: 'O6S Thing',
      regex: /:1EDD:Alte Roite starts using/,
      infoText: function(data, matches) {
      },
      tts: function(data, matches) {
      },
    },
    {
      id: 'O6S Headmarker',
      regex: /1B:........:(\y{Name}):....:....:00XX:0000:0000:0000:/,
      condition: function(data, matches) { return matches[1] == data.me; },
      infoText: function(data) {
      },
      tts: function(data, matches) {
      },
    },
  ]
}]
<commit_msg>Triggers for o6s (#54)<commit_after>// O6S - Sigmascape 2.0 Savage
[{
  zoneRegex: /Sigmascape V2\.0 \(Savage\)/,
  timelineFile: 'o6s.txt',
  triggers: [
    {
      id: 'O6S Demonic Stone',
      regex: /1B:........:(\y{Name}):....:....:0001:0000:0000:0000:/,
      alarmText: function(data,matches) {
        if (data.me == matches[1])
          return 'Demonic Stone on YOU';
      },
    },
    {
      id: 'O6S Last Kiss',
      regex: /1B:........:(\y{Name}):....:....:0017:0000:0000:0000:/,
      alarmText: function(data,matches) {
        if (data.me == matches[1])
          return 'Last Kiss on YOU';
      },
      infoText: function(data,matches) {
        if (data.me != matches[1])
          return 'Last Kiss on ' +data.ShortName(matches[1]);
      },
      tts: 'last kiss',
    },
  ]
}]
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import {
  View,
  StyleSheet
} from 'react-native'

import InterestsList from '../Components/InterestsList.js'

export default class Interests extends Component {
  render () {
    return (
      <View style={styles.mainContainer}>
        <InterestsList />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  mainContainer: {
    backgroundColor: '#fff',
    flex: 1,
  }
})
<commit_msg>add submit button for interests<commit_after>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
  TouchableHighlight,
  Text
} from 'react-native'

import InterestsList from '../Components/InterestsList.js'

export default class Interests extends Component {
  render () {
    return (
      <View style={styles.mainContainer}>
        <InterestsList />
        <TouchableHighlight style={styles.submit}>
          <Text style={styles.submitText}>Submit</Text>
        </TouchableHighlight>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  mainContainer: {
    backgroundColor: '#fff',
    flex: 1,
  },
  submit: {
    position: 'absolute',
    justifyContent: 'center',
    bottom: 80,
    flex: 1,
    backgroundColor: '#1a49d6'
  },
  submitText: {
    textAlign: 'center'
  }
})
<|endoftext|>