<commit_before>// require ../support/jquery
// require esphinx_ui
// require esphinx/support/ajax
// require esphinx/support/function
// require esphinx/support/array
// require esphinx/observer

"use strict";

var
    jQuery,
    esPhinx,
    Singleton,
    Ajax,
    Constructor;

(function ($module) {

    $module.extend({

        windows: {

            modal: {

                // functions are objects in js
                new: function (contentSource, options) {

                    var
                        ConstructorReference = $module.windows.modal.new,
                        self = this,

                        $ = esPhinx,
                        ajax = Ajax,
                        body = $("body"),

                        modal,
                        mask,
                        main,
                        container,
                        btnClose,
                        btnHide,
                        headers,
                        params,
                        asynchronousAnswer,
                        imgControl,

                        maskTransitionDuration = function (mask) {
                            return parseFloat(mask
                                .css("transition-duration")) * 1000;
                        },

                        restartTransition = function (mask) {
                            mask.css("transition", "opacity 0s");
                        },

                        resolveParams = function () {
                            options = options || {};

                            if (typeof options.windowController !== "boolean") {
                                options.windowController = true;
                            }

                            if (typeof options.remote !== "boolean") {
                                options.remote = true;
                            }
                        },

                        resolveHeaderActions = function (main, options) {
                            var
                                header,
                                actions;

                            if (options.windowController) {
                                header = $("");
                                actions = $("

").addClass("actions");
                                btnClose = $('')
                                    .addClass("btn-close");
                                btnHide = $('')
                                    .addClass("btn-hide");

                                header.append(actions);
                                actions.append(btnClose);
                                actions.append(btnHide);

                                main
                                    .prepend(header)
                                    .css({
                                        "max-height": $(document).height(),
                                        "max-width": $(document).width()
                                    });

                                bindHeaderEventListeners();
                            }
                        },

                        bindHeaderEventListeners = function () {
                            // $(document).off("keydown").on("keydown", function (e) {
                            //     if (e.keyCode === 27) {
                            //         self.hide();
                            //     }
                            // });

                            btnHide.on("click", function () {
                                self.hide();
                            });

                            btnClose.on("click", function () {
                                self.close();
                            });
                        },

                        observeContent = function () {
                            var
                                imgs,
                                length = 0;

                            main.observe(function (observer) {
                                imgs = main.find("img");
                                if (imgs.any()) {
                                    imgs.each(function (img) {
                                        $(img).on("load", function (e) {
                                            // debugger
                                            length += 1;
                                        });
                                    });

                                    FlowControl.new({
                                        condition: function (condition) {
                                            // when processing is synchronous
                                            if (!options.remote) {
                                                if (options.loading) {
                                                    // callback
                                                    options.loading(main);
                                                }
                                                self.show();
                                                // debugger
                                            }

                                            condition(length === imgs.length);
                                        },
                                        ready: function () {
                                            if (!asynchronousAnswer) {
                                                container.html(contentSource);
                                                main.html(container);
                                            }

                                            length = 0;
                                            resolveHeaderActions(main, options);

                                            if (options.complete) {
                                                self.hide(false);

                                                options.complete.call(self);
                                            }
                                        }
                                    })

                                } else {
                                    resolveHeaderActions(main, options);

                                    if (options.complete) {
                                        options.complete.call(self);
                                    }
                                }

                                // talvez tenha que remanejar o disconnect
                                observer.disconnect();
                            });
                        },

                        create = function (remote) {
                            modal = $("

")
                                .addClass("esphinx ui modal");
                            main = $("")
                                .addClass("basicss hidden");
                            mask = $("

")
                                .addClass("basicss fixed transparent mask");
                            container = $("

").addClass("container");

                            modal
                                .append(mask)
                                .append(main);

                            body.append(modal);

                            observeContent();

                            if (options.remote) {
                                headers = options.header || options.headers
                                || null;
                                params = options.param || options.params
                                || null;
                                ajax.new(contentSource, {
                                    params: params,
                                    headers: headers,
                                    progress: function () {
                                        if (options.loading) {
                                            // callback
                                            options.loading(main);
                                            self.show();
                                            // debugger
                                        }
                                    },
                                    success: function (a) {
                                        if (options.success) {
                                            // callback
                                            options.success(main);
                                        }
                                        asynchronousAnswer = a;

                                        container.html(asynchronousAnswer);

                                        // because here the processing is asynchronous, it's not linear
                                        self.hide(false);
                                        main.html(container);
                                    }
                                });
                            } else {
                                container.html(contentSource);
                                main.html(container);
                            }

                        };

                    // global scope (public)
                    this.close = function () {
                        main.hide();

                        restartTransition(mask);
                        if (options.fadeOut) {
                            mask.css("transition", "opacity " + options.fadeOut);
                        }
                        mask.addClass("transparent");

                        setTimeout(function () {
                            modal.remove();
                        }, maskTransitionDuration(mask));

                        self.deleteSingleton();
                    };

                    this.hide = function (animation = true) {
                        main.hide();

                        restartTransition(mask);

                        if (animation) {
                            if (options.fadeOut) {
                                mask.css("transition", "opacity " + options.fadeOut);
                                setTimeout(function () {
                                    modal.css("z-index", -1);
                                }, maskTransitionDuration(mask));
                            }
                        }

                        mask.addClass("transparent");
                    };

                    this.show = function () {
                        modal.css("z-index", 0);

                        restartTransition(mask);
                        if (options.fadeIn) {
                            mask.css("transition", "opacity " + options.fadeIn);
                        }
                        mask.removeClass("transparent");

                        main.centralizeAt(document);
                        main.show();
                    };

                    if (!(this instanceof ConstructorReference)) {
                        self = Singleton.exists(ConstructorReference, arguments);
                        if (!self) {
                            return ConstructorReference.instance(arguments);
                        } else {
                            self.show();
                        }
                    // that "else" will should to exit for the "show" method can be used by who instanciates it
                    } else {
                        resolveParams();
                        create();
                    }

                    return self;
                }

            }

        }

    });

}(esPhinx.ui));
<commit_msg>remove comment<commit_after>// require ../support/jquery
// require esphinx_ui
// require esphinx/support/ajax
// require esphinx/support/function
// require esphinx/support/array
// require esphinx/observer

"use strict";

var
    jQuery,
    esPhinx,
    Singleton,
    Ajax,
    Constructor;

(function ($module) {

    $module.extend({

        windows: {

            modal: {

                // functions are objects in js
                new: function (contentSource, options) {

                    var
                        ConstructorReference = $module.windows.modal.new,
                        self = this,

                        $ = esPhinx,
                        ajax = Ajax,
                        body = $("body"),

                        modal,
                        mask,
                        main,
                        container,
                        btnClose,
                        btnHide,
                        headers,
                        params,
                        asynchronousAnswer,
                        imgControl,

                        maskTransitionDuration = function (mask) {
                            return parseFloat(mask
                                .css("transition-duration")) * 1000;
                        },

                        restartTransition = function (mask) {
                            mask.css("transition", "opacity 0s");
                        },

                        resolveParams = function () {
                            options = options || {};

                            if (typeof options.windowController !== "boolean") {
                                options.windowController = true;
                            }

                            if (typeof options.remote !== "boolean") {
                                options.remote = true;
                            }
                        },

                        resolveHeaderActions = function (main, options) {
                            var
                                header,
                                actions;

                            if (options.windowController) {
                                header = $("");
                                actions = $("

").addClass("actions");
                                btnClose = $('')
                                    .addClass("btn-close");
                                btnHide = $('')
                                    .addClass("btn-hide");

                                header.append(actions);
                                actions.append(btnClose);
                                actions.append(btnHide);

                                main
                                    .prepend(header)
                                    .css({
                                        "max-height": $(document).height(),
                                        "max-width": $(document).width()
                                    });

                                bindHeaderEventListeners();
                            }
                        },

                        bindHeaderEventListeners = function () {
                            // $(document).off("keydown").on("keydown", function (e) {
                            //     if (e.keyCode === 27) {
                            //         self.hide();
                            //     }
                            // });

                            btnHide.on("click", function () {
                                self.hide();
                            });

                            btnClose.on("click", function () {
                                self.close();
                            });
                        },

                        observeContent = function () {
                            var
                                imgs,
                                length = 0;

                            main.observe(function (observer) {
                                imgs = main.find("img");
                                if (imgs.any()) {
                                    imgs.each(function (img) {
                                        $(img).on("load", function (e) {
                                            // debugger
                                            length += 1;
                                        });
                                    });

                                    FlowControl.new({
                                        condition: function (condition) {
                                            // when processing is synchronous
                                            if (!options.remote) {
                                                if (options.loading) {
                                                    options.loading(main);
                                                }
                                                self.show();
                                            }

                                            condition(length === imgs.length);
                                        },
                                        ready: function () {
                                            if (!asynchronousAnswer) {
                                                container.html(contentSource);
                                                main.html(container);
                                            }

                                            length = 0;
                                            resolveHeaderActions(main, options);

                                            if (options.complete) {
                                                self.hide(false);

                                                options.complete.call(self);
                                            }
                                        }
                                    })

                                } else {
                                    resolveHeaderActions(main, options);

                                    if (options.complete) {
                                        options.complete.call(self);
                                    }
                                }

                                // talvez tenha que remanejar o disconnect
                                observer.disconnect();
                            });
                        },

                        create = function (remote) {
                            modal = $("

")
                                .addClass("esphinx ui modal");
                            main = $("")
                                .addClass("basicss hidden");
                            mask = $("

")
                                .addClass("basicss fixed transparent mask");
                            container = $("

").addClass("container");

                            modal
                                .append(mask)
                                .append(main);

                            body.append(modal);

                            observeContent();

                            if (options.remote) {
                                headers = options.header || options.headers
                                || null;
                                params = options.param || options.params
                                || null;
                                ajax.new(contentSource, {
                                    params: params,
                                    headers: headers,
                                    progress: function () {
                                        if (options.loading) {
                                            // callback
                                            options.loading(main);
                                            self.show();
                                            // debugger
                                        }
                                    },
                                    success: function (a) {
                                        if (options.success) {
                                            // callback
                                            options.success(main);
                                        }
                                        asynchronousAnswer = a;

                                        container.html(asynchronousAnswer);

                                        // because here the processing is asynchronous, it's not linear
                                        self.hide(false);
                                        main.html(container);
                                    }
                                });
                            } else {
                                container.html(contentSource);
                                main.html(container);
                            }

                        };

                    // global scope (public)
                    this.close = function () {
                        main.hide();

                        restartTransition(mask);
                        if (options.fadeOut) {
                            mask.css("transition", "opacity " + options.fadeOut);
                        }
                        mask.addClass("transparent");

                        setTimeout(function () {
                            modal.remove();
                        }, maskTransitionDuration(mask));

                        self.deleteSingleton();
                    };

                    this.hide = function (animation = true) {
                        main.hide();

                        restartTransition(mask);

                        if (animation) {
                            if (options.fadeOut) {
                                mask.css("transition", "opacity " + options.fadeOut);
                                setTimeout(function () {
                                    modal.css("z-index", -1);
                                }, maskTransitionDuration(mask));
                            }
                        }

                        mask.addClass("transparent");
                    };

                    this.show = function () {
                        modal.css("z-index", 0);

                        restartTransition(mask);
                        if (options.fadeIn) {
                            mask.css("transition", "opacity " + options.fadeIn);
                        }
                        mask.removeClass("transparent");

                        main.centralizeAt(document);
                        main.show();
                    };

                    if (!(this instanceof ConstructorReference)) {
                        self = Singleton.exists(ConstructorReference, arguments);
                        if (!self) {
                            return ConstructorReference.instance(arguments);
                        } else {
                            self.show();
                        }
                    // that "else" will should to exit for the "show" method can be used by who instanciates it
                    } else {
                        resolveParams();
                        create();
                    }

                    return self;
                }

            }

        }

    });

}(esPhinx.ui));
<|endoftext|>


<commit_before>var Box = require("truffle-box");
var MemoryLogger = require("../memorylogger");
var CommandRunner = require("../commandrunner");
var fs = require("fs-extra");
var path = require("path");
var assert = require("assert");
var Server = require("../server");
var Reporter = require("../reporter");

describe("Solidity Tests", function() {
  var logger = new MemoryLogger();
  var config;

  /**
   * Installs a bare truffle project and deposits a solidity test target
   * in the test directory.
   * @param  {Function} done callback
   * @param  {String}   file Solidity test target
   */
  function initSandbox(done, file) {
    Box.sandbox("default#web3-one", function(err, conf) {
      if (err) return done(err);
      config = conf;
      config.logger = logger;
      config.network = "development";
      config.mocha = {
        reporter: new Reporter(logger)
      };
      const from = path.join(__dirname, file);

      fs.ensureDir(config.test_directory).then(() => {
        fs.copy(from, config.test_directory + `/${file}`);
        done();
      });
    });
  }

  function processErr(err, output) {
    if (err) {
      console.log(output);
      throw new Error(err);
    }
  }

  before(done => Server.start(done));
  after(done => Server.stop(done));

  describe("test with balance", function() {
    before(function(done) {
      this.timeout(5000);
      initSandbox(done, "TestWithBalance.sol");
    });

    it("will run the test and have the correct balance", function(done) {
      this.timeout(70000);

      CommandRunner.run("test", config, function(err) {
        const output = logger.contents();
        processErr(err, output);
        assert(output.includes("1 passing"));
        done();
      });
    });
  });

  describe("tests failing", function() {
    before(function(done) {
      this.timeout(5000);
      initSandbox(done, "TestFailures.sol");
    });

    it("will throw errors correctly", function(done) {
      this.timeout(70000);

      CommandRunner.run("test", config, function(err) {
        const output = logger.contents();
        assert(err, `Tests should error. Output: ${output}`);
        assert(output.includes("2 failing"));
        done();
      });
    });
  });
});
<commit_msg>Use bare-box in solidity tests<commit_after>var Box = require("truffle-box");
var MemoryLogger = require("../memorylogger");
var CommandRunner = require("../commandrunner");
var fs = require("fs-extra");
var path = require("path");
var assert = require("assert");
var Server = require("../server");
var Reporter = require("../reporter");

describe("Solidity Tests", function() {
  var logger = new MemoryLogger();
  var config;

  /**
   * Installs a bare truffle project and deposits a solidity test target
   * in the test directory.
   * @param  {Function} done callback
   * @param  {String}   file Solidity test target
   */
  function initSandbox(done, file) {
    Box.sandbox("bare", function(err, conf) {
      if (err) return done(err);
      config = conf;
      config.logger = logger;
      config.network = "development";
      config.mocha = {
        reporter: new Reporter(logger)
      };
      const from = path.join(__dirname, file);

      fs.ensureDir(config.test_directory).then(() => {
        fs.copy(from, config.test_directory + `/${file}`);
        done();
      });
    });
  }

  function processErr(err, output) {
    if (err) {
      console.log(output);
      throw new Error(err);
    }
  }

  before(done => Server.start(done));
  after(done => Server.stop(done));

  describe("test with balance", function() {
    before(function(done) {
      this.timeout(5000);
      initSandbox(done, "TestWithBalance.sol");
    });

    it("will run the test and have the correct balance", function(done) {
      this.timeout(70000);

      CommandRunner.run("test", config, function(err) {
        const output = logger.contents();
        processErr(err, output);
        assert(output.includes("1 passing"));
        done();
      });
    });
  });

  describe("tests failing", function() {
    before(function(done) {
      this.timeout(5000);
      initSandbox(done, "TestFailures.sol");
    });

    it("will throw errors correctly", function(done) {
      this.timeout(70000);

      CommandRunner.run("test", config, function(err) {
        const output = logger.contents();
        assert(err, `Tests should error. Output: ${output}`);
        assert(output.includes("2 failing"));
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>var fs = require('node-fs'); // Recursive directory creation. https://github.com/bpedro/node-fs

var _ = require('lodash'); // Utilities. http://underscorejs.org/
var Backbone = require('backbone'); // Data model utilities. http://backbonejs.org/
var moment = require('moment'); // Date processing. http://momentjs.com/
var child_process = require('child_process'); // http://nodejs.org/api/child_process.html
var XRegExp = require('xregexp').XRegExp; // Fancy regular expressions. http://xregexp.com/

var BaseModel = require('./baseModel.js').BaseModel;

// Manager of state which is displayed on the console, and responder of commands sent from the
// console.
exports.ConsoleState = BaseModel.extend({
    defaults: {
        isRunning: false,
        uptime: 0,
        fps: null,
        cpu: null,
        memory: null,
        configs: []
    },

    // The interval to update stats.
    _updateStatsTimeout: 0,
    _updateMemoryTimeout: 0,
    _updateStatsRate: 1000,

    // How many updates of historical data to keep.
    _statHistory: 60,
    _statIndex: 0,

    // A console process in which TYPEPERF is run continuously to update CPU usage.
    _cpuConsole: null,

    // A timeout to throttle the speed of updates to the console.
    _updateConsoleTimeout: 0,
    _updateConsoleRate: 1000 / 1,

    // The last time the app was running to compute uptime.
    _startupTime: 0,

    // Set up update loops.
    initialize: function() {
        BaseModel.prototype.initialize.apply(this);

        $$persistence.on('heart', this._onHeart, this);
        this._updateStats();
        this._updateCpu();
        this._updateMemory();
        $$network.transports.socketToConsole.sockets.on('connection', _.bind(this._onConnection, this));
    },

    // Build an object representing the whole configuration of the server. Sent to the console on
    // initial connection, also useful to spew for documentation.
    fullConfig: function(user) {
        var permissions = $$config.permissions ? $$config.permissions[user] : null;
        return {
            network: $$network.attributes,
            persistence: $$persistence.attributes,
            logging: $$logging.attributes,
            permissions: permissions
        };
    },

    // On initial socket connection with the console, listen for commands and send out the config.
    _onConnection: function(socket) {

        var username = null;
        var permissions = null;
        if (socket.handshake.headers.authorization) {
            username = socket.handshake.headers.authorization.match(/username="([^"]+)"/)[1];
            permissions = $$config.permissions ? $$config.permissions[username] : null;
        }

        // Responds to requests for appState updates, but throttle it to _updateConsoleRate.
        var updateConsole = _.bind(this._updateConsole, this);
        socket.on('appStateRequest', _.bind(function() {
            clearTimeout(this._updateConsoleTimeout);
            this._updateConsoleTimeout = setTimeout(updateConsole, this._updateConsoleRate);
        }, this));

        socket.on('start', _.bind(function() {
            if (permissions && !permissions.app) {
                return;
            }

            logger.info('Startup requested from console.');
            $$serverState.saveState('runApp', true);
            $$persistence.startApp(true);
        }, this));

        socket.on('restart-app', _.bind(function() {
            if (permissions && !permissions.app) {
                return;
            }

            logger.info('Restart requested from console.');
            $$serverState.saveState('runApp', true);
            $$persistence.restartApp(true);
        }, this));

        socket.on('shutdown-app', _.bind(function() {
            if (permissions && !permissions.app) {
                return;
            }

            logger.info('Shutdown requested from console.');
            $$serverState.saveState('runApp', false);
            $$persistence.shutdownApp();
        }, this));

        socket.on('restart-pc', _.bind(function() {
            if (permissions && !permissions.computer) {
                return;
            }

            logger.info('Reboot requested from console.');
            $$persistence.restartMachine();
        }, this));

        socket.on('shutdown-pc', _.bind(function() {
            if (permissions && !permissions.computer) {
                return;
            }

            logger.info('Shutdown requested from console.');
            $$persistence.shutdownMachine();
        }, this));

        socket.on('switchConfig', _.bind(function(config) {
            $$serverState.saveState('config', config, $$persistence.restartServer);
        }, this));

        $$network.transports.socketToConsole.sockets.emit('config', this.fullConfig(username), this.get('configs'));
    },

    // Send the console new data on an interval.
    _updateConsole: function() {
        var message = _.clone(this.attributes);
        message.restartCount = $$persistence.get('restartCount');
        message.logs = $$logging.get('logCache');
        message.events = $$logging.get('eventCache');

        $$network.transports.socketToConsole.sockets.emit('appState', message);
    },

    // Update the internal objects which specify the FPS, whether the app is running, memory usage,
    // and uptime.
    _updateStats: function() {
        var fpsHistory = this.get('fps');

        if (!fpsHistory) {
            fpsHistory = [];
            this.set({
                fps: fpsHistory,
            });
        }

        // Update FPS.
        var fps = 1000 / (this._tickSum / this._maxTicks);
        fps *= 100;
        fps = Math.round(fps);
        fps /= 100;
        fpsHistory.push(fps);
        while (fpsHistory.length > this._statHistory) {
            fpsHistory.shift();
        }

        if ($$persistence.processId()) {
            // Update the uptime.
            var wasRunning = this.get('isRunning');
            if (!wasRunning) {
                this._startupTime = Date.now();
            }
            this.set('uptime', Date.now() - this._startupTime);
            this.set('isRunning', true);
        } else {
            // Not running, so reset everything.
            this.set({
                isRunning: false,
                fps: null,
                memory: null,
                uptime: 0
            });
        }

        clearTimeout(this._updateStatsTimeout);
        this._updateStatsTimeout = setTimeout(_.bind(this._updateStats, this), this._updateStatsRate);
    },

    // Request to update the memory.
    _updateMemory: function() {
        var id = $$persistence.processId();
        if (id) {
            child_process.exec('tasklist /FI "PID eq ' + id + '" /FO LIST', _.bind(function(error, stdout, stderror) {
                /*
                // tasklist.exe output looks like this:
                Image Name:   Client.exe
                PID:          12008
                Session Name: Console
                Session#:     1
                Mem Usage:    39,384 K
                */

                stdout = stdout.toString();
                var match = XRegExp.exec(stdout, XRegExp('[\\d,]+\\sK'));
                if (!match) {
                    return;
                }

                match = match[0]; // "39,384 K"
                match = match.replace(',', '').replace(' K', ''); // "39384"
                var memory = parseInt(match) * 1024; // 40329216

                var memoryHistory = this.get('memory');

                if (!memoryHistory) {
                    memoryHistory = [];
                    this.set({
                        memory: memoryHistory
                    });
                }

                memoryHistory.push(memory);
                while (memoryHistory.length > this._statHistory) {
                    memoryHistory.shift();
                }

                clearTimeout(this._updateMemoryTimeout);
                this._updateMemoryTimeout = setTimeout(_.bind(this._updateMemory, this), this._updateStatsRate);

                $$persistence.checkMemory(memory);
            }, this));
        } else {
            clearTimeout(this._updateMemoryTimeout);
            this._updateMemoryTimeout = setTimeout(_.bind(this._updateMemory, this), this._updateStatsRate);
        }
    },

    // Run typeperf to get total CPU usage -- haven't figured out how to get it per process.
    _updateCpu: function() {
        this._cpuConsole = child_process.spawn('typeperf', ['\\Processor(_Total)\\% Processor Time']);
        this._cpuConsole.stdout.on('data', _.bind(function(stdout) {

            stdout = stdout.toString();
            if (stdout && stdout.indexOf(',') === 0) {
                var cpu = parseFloat(stdout.substr(2, stdout.length - 3));
                if (!isNaN(cpu)) {
                    var cpuHistory = this.get('cpu');
                    if (!cpuHistory) {
                        cpuHistory = [];
                        this.set('cpu', cpuHistory);
                    }

                    cpuHistory.push(cpu);
                    while (cpuHistory.length > this._statHistory) {
                        cpuHistory.shift();
                    }
                }
            }
        }, this));
    },

    // Compute FPS in a fast way. http://stackoverflow.com/a/87732/468472
    _maxTicks: 180,
    _tickList: null,
    _tickSum: 0,
    _tickIndex: 0,
    _lastHeart: 0,

    // Update the FPS whenever a heartbeat message is received from the app.
    _onHeart: function(message) {
        if (!this._tickList) {
            this._tickList = [];
            while (this._tickList.length < this._maxTicks) {
                this._tickList.push(0);
            }
        }

        if (!this._lastHeart) {
            this._lastHeart = Date.now();
            this._lastFpsUpdate = this._lastHeart;
            return;
        }

        var newHeart = Date.now();
        var newTick = newHeart - this._lastHeart;
        this._lastHeart = newHeart;

        this._tickSum -= this._tickList[this._tickIndex];
        this._tickSum += newTick;
        this._tickList[this._tickIndex] = newTick;
        if (++this._tickIndex == this._maxTicks) {
            this._tickIndex = 0;
        }
    }
});
<commit_msg>disable cpu usage collection for now<commit_after>var fs = require('node-fs'); // Recursive directory creation. https://github.com/bpedro/node-fs

var _ = require('lodash'); // Utilities. http://underscorejs.org/
var Backbone = require('backbone'); // Data model utilities. http://backbonejs.org/
var moment = require('moment'); // Date processing. http://momentjs.com/
var child_process = require('child_process'); // http://nodejs.org/api/child_process.html
var XRegExp = require('xregexp').XRegExp; // Fancy regular expressions. http://xregexp.com/

var BaseModel = require('./baseModel.js').BaseModel;

// Manager of state which is displayed on the console, and responder of commands sent from the
// console.
exports.ConsoleState = BaseModel.extend({
    defaults: {
        isRunning: false,
        uptime: 0,
        fps: null,
        cpu: null,
        memory: null,
        configs: []
    },

    // The interval to update stats.
    _updateStatsTimeout: 0,
    _updateMemoryTimeout: 0,
    _updateStatsRate: 1000,

    // How many updates of historical data to keep.
    _statHistory: 60,
    _statIndex: 0,

    // A console process in which TYPEPERF is run continuously to update CPU usage.
    _cpuConsole: null,

    // A timeout to throttle the speed of updates to the console.
    _updateConsoleTimeout: 0,
    _updateConsoleRate: 1000 / 1,

    // The last time the app was running to compute uptime.
    _startupTime: 0,

    // Set up update loops.
    initialize: function() {
        BaseModel.prototype.initialize.apply(this);

        $$persistence.on('heart', this._onHeart, this);
        this._updateStats();
        this._updateCpu();
        this._updateMemory();
        $$network.transports.socketToConsole.sockets.on('connection', _.bind(this._onConnection, this));
    },

    // Build an object representing the whole configuration of the server. Sent to the console on
    // initial connection, also useful to spew for documentation.
    fullConfig: function(user) {
        var permissions = $$config.permissions ? $$config.permissions[user] : null;
        return {
            network: $$network.attributes,
            persistence: $$persistence.attributes,
            logging: $$logging.attributes,
            permissions: permissions
        };
    },

    // On initial socket connection with the console, listen for commands and send out the config.
    _onConnection: function(socket) {

        var username = null;
        var permissions = null;
        if (socket.handshake.headers.authorization) {
            username = socket.handshake.headers.authorization.match(/username="([^"]+)"/)[1];
            permissions = $$config.permissions ? $$config.permissions[username] : null;
        }

        // Responds to requests for appState updates, but throttle it to _updateConsoleRate.
        var updateConsole = _.bind(this._updateConsole, this);
        socket.on('appStateRequest', _.bind(function() {
            clearTimeout(this._updateConsoleTimeout);
            this._updateConsoleTimeout = setTimeout(updateConsole, this._updateConsoleRate);
        }, this));

        socket.on('start', _.bind(function() {
            if (permissions && !permissions.app) {
                return;
            }

            logger.info('Startup requested from console.');
            $$serverState.saveState('runApp', true);
            $$persistence.startApp(true);
        }, this));

        socket.on('restart-app', _.bind(function() {
            if (permissions && !permissions.app) {
                return;
            }

            logger.info('Restart requested from console.');
            $$serverState.saveState('runApp', true);
            $$persistence.restartApp(true);
        }, this));

        socket.on('shutdown-app', _.bind(function() {
            if (permissions && !permissions.app) {
                return;
            }

            logger.info('Shutdown requested from console.');
            $$serverState.saveState('runApp', false);
            $$persistence.shutdownApp();
        }, this));

        socket.on('restart-pc', _.bind(function() {
            if (permissions && !permissions.computer) {
                return;
            }

            logger.info('Reboot requested from console.');
            $$persistence.restartMachine();
        }, this));

        socket.on('shutdown-pc', _.bind(function() {
            if (permissions && !permissions.computer) {
                return;
            }

            logger.info('Shutdown requested from console.');
            $$persistence.shutdownMachine();
        }, this));

        socket.on('switchConfig', _.bind(function(config) {
            $$serverState.saveState('config', config, $$persistence.restartServer);
        }, this));

        $$network.transports.socketToConsole.sockets.emit('config', this.fullConfig(username), this.get('configs'));
    },

    // Send the console new data on an interval.
    _updateConsole: function() {
        var message = _.clone(this.attributes);
        message.restartCount = $$persistence.get('restartCount');
        message.logs = $$logging.get('logCache');
        message.events = $$logging.get('eventCache');

        $$network.transports.socketToConsole.sockets.emit('appState', message);
    },

    // Update the internal objects which specify the FPS, whether the app is running, memory usage,
    // and uptime.
    _updateStats: function() {
        var fpsHistory = this.get('fps');

        if (!fpsHistory) {
            fpsHistory = [];
            this.set({
                fps: fpsHistory,
            });
        }

        // Update FPS.
        var fps = 1000 / (this._tickSum / this._maxTicks);
        fps *= 100;
        fps = Math.round(fps);
        fps /= 100;
        fpsHistory.push(fps);
        while (fpsHistory.length > this._statHistory) {
            fpsHistory.shift();
        }

        if ($$persistence.processId()) {
            // Update the uptime.
            var wasRunning = this.get('isRunning');
            if (!wasRunning) {
                this._startupTime = Date.now();
            }
            this.set('uptime', Date.now() - this._startupTime);
            this.set('isRunning', true);
        } else {
            // Not running, so reset everything.
            this.set({
                isRunning: false,
                fps: null,
                memory: null,
                uptime: 0
            });
        }

        clearTimeout(this._updateStatsTimeout);
        this._updateStatsTimeout = setTimeout(_.bind(this._updateStats, this), this._updateStatsRate);
    },

    // Request to update the memory.
    _updateMemory: function() {
        var id = $$persistence.processId();
        if (id) {
            child_process.exec('tasklist /FI "PID eq ' + id + '" /FO LIST', _.bind(function(error, stdout, stderror) {
                /*
                // tasklist.exe output looks like this:
                Image Name:   Client.exe
                PID:          12008
                Session Name: Console
                Session#:     1
                Mem Usage:    39,384 K
                */

                stdout = stdout.toString();
                var match = XRegExp.exec(stdout, XRegExp('[\\d,]+\\sK'));
                if (!match) {
                    return;
                }

                match = match[0]; // "39,384 K"
                match = match.replace(',', '').replace(' K', ''); // "39384"
                var memory = parseInt(match) * 1024; // 40329216

                var memoryHistory = this.get('memory');

                if (!memoryHistory) {
                    memoryHistory = [];
                    this.set({
                        memory: memoryHistory
                    });
                }

                memoryHistory.push(memory);
                while (memoryHistory.length > this._statHistory) {
                    memoryHistory.shift();
                }

                clearTimeout(this._updateMemoryTimeout);
                this._updateMemoryTimeout = setTimeout(_.bind(this._updateMemory, this), this._updateStatsRate);

                $$persistence.checkMemory(memory);
            }, this));
        } else {
            clearTimeout(this._updateMemoryTimeout);
            this._updateMemoryTimeout = setTimeout(_.bind(this._updateMemory, this), this._updateStatsRate);
        }
    },

    // Run typeperf to get total CPU usage -- haven't figured out how to get it per process.
    _updateCpu: function() {
        return;
        this._cpuConsole = child_process.spawn('typeperf', ['\\Processor(_Total)\\% Processor Time']);
        this._cpuConsole.stdout.on('data', _.bind(function(stdout) {

            stdout = stdout.toString();
            if (stdout && stdout.indexOf(',') === 0) {
                var cpu = parseFloat(stdout.substr(2, stdout.length - 3));
                if (!isNaN(cpu)) {
                    var cpuHistory = this.get('cpu');
                    if (!cpuHistory) {
                        cpuHistory = [];
                        this.set('cpu', cpuHistory);
                    }

                    cpuHistory.push(cpu);
                    while (cpuHistory.length > this._statHistory) {
                        cpuHistory.shift();
                    }
                }
            }
        }, this));
    },

    // Compute FPS in a fast way. http://stackoverflow.com/a/87732/468472
    _maxTicks: 180,
    _tickList: null,
    _tickSum: 0,
    _tickIndex: 0,
    _lastHeart: 0,

    // Update the FPS whenever a heartbeat message is received from the app.
    _onHeart: function(message) {
        if (!this._tickList) {
            this._tickList = [];
            while (this._tickList.length < this._maxTicks) {
                this._tickList.push(0);
            }
        }

        if (!this._lastHeart) {
            this._lastHeart = Date.now();
            this._lastFpsUpdate = this._lastHeart;
            return;
        }

        var newHeart = Date.now();
        var newTick = newHeart - this._lastHeart;
        this._lastHeart = newHeart;

        this._tickSum -= this._tickList[this._tickIndex];
        this._tickSum += newTick;
        this._tickList[this._tickIndex] = newTick;
        if (++this._tickIndex == this._maxTicks) {
            this._tickIndex = 0;
        }
    }
});
<|endoftext|>


<commit_before>var fs = require('fs');
var chi<commit_msg>Update character<commit_after>var fs = require('fs');
var chil<|endoftext|>


<commit_before>/*
 *
 * FeatureInfoDisplay.js -- part of Quantum GIS Web Client
 *
 * Copyright (2010-2012), The QGIS Project All rights reserved.
 * Quantum GIS Web Client is released under a BSD license. Please see
 * https://github.com/qgis/qgis-web-client/blob/master/README
 * for the full text of the license and the list of contributors.
 *
*/

/* FeatureInfos are presented to the user in two ways using OpenLayers.Popup classes:
 * If the mouse stops and GetFeatureInfo has results for this mouse position
 * a small box presents the contents of the info field (GetProjectSettings) or the
 * field named "toolbox" (GetCapabilities), this is called hoverPopup throughout this script.
 * If the user clicks in the map the contents of all visible fields (and if activated the wkt geometry)
 * is presented in a popup called clickPopup throughout this script.
 * hoverPopups are disabled when a clickPopup is open, however clicking at another position in the map
 * closes the currently opened clickPopup and opens a new one (if there is GetFeatureInfo response).
 * If the cursor is at a position where there is GetFeatureInfo response it indicates the possibility
 * to click by changing to "hand".
*/

var featureInfoPopupContents;
var closePopupClick = false; // stores if the click results from closing a clickPopup

function showFeatureInfo(evt) {
    if (identifyToolActive) {
        if (!closePopupClick) {
            var map = geoExtMap.map; // gets OL map object
            if (window.DOMParser) {
                var parser = new DOMParser();
                xmlDoc = parser.parseFromString(evt.text, "text/xml");
            } else {
                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async = "false";
                xmlDoc.loadXML(evt.text);
            }
            // open AttributeTree panel
            featureInfoResultLayers = new Array();
            highLightGeometry = new Array();
            parseFIResult(xmlDoc);
            featureInfoResultLayers.reverse();
            highLightGeometry.reverse();
            if (featureInfoResultLayers.length > 0) {
                if (hoverPopup) {removeHoverPopup();}
                if (clickPopup) {removeClickPopup();}
                var text = "";
                if (identificationMode == 'topMostHit') {
                    text += featureInfoResultLayers[0];
                    featureInfoHighlightLayer.addFeatures(highLightGeometry[0]);
                    //feature.geometry.getBounds().getCenterLonLat()
                } else {
                    for (var i = 0; i < featureInfoResultLayers.length; i++) {
                        text += featureInfoResultLayers[i];
                        featureInfoHighlightLayer.addFeatures(highLightGeometry[i]);
                    }
                }
                clickPopup = new OpenLayers.Popup.FramedCloud(
                    null, // id
                    map.getLonLatFromPixel(evt.xy), // lonlat
                    null, //new OpenLayers.Size(1,1), // contentSize
                    text, //contentHTML
                    null, // anchor
                    true,  // closeBox
                    onClickPopupClosed // closeBoxCallBackFunction
                    );
                clickPopup.autoSize = true;
                clickPopup.events.fallThrough = false;
                map.addPopup(clickPopup); //*/
                changeCursorInMap("default");
            }
        } else {
            closePopupClick = false;
        }
        activateGetFeatureInfo(true);
    }
}

function showFeatureInfoHover(evt) {
    var map = geoExtMap.map; // gets OL map object
    if (identifyToolActive) {
        if (hoverPopup) {removeHoverPopup();}
        if (window.DOMParser) {
            var parser = new DOMParser();
            xmlDoc = parser.parseFromString(evt.text, "text/xml");
        } else {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(evt.text);
        }
        var layerNodes = xmlDoc.getElementsByTagName("Layer");
        var text = '';
        var result = false;
		//test if we need to show the feature info layer title
		//either from global setting or from project setting
		var showFILayerTitle = showFeatureInfoLayerTitle;
		if (mapThemeSwitcher) {
			showFILayerTitle = mapThemeSwitcher.activeProjectData.showFeatureInfoLayerTitle;
		}

        for (var i = layerNodes.length - 1; i > -1; --i) {
            //case vector layers
            var featureNodes = layerNodes[i].getElementsByTagName("Feature");
            // show layer display field or if missing, the attribute 'tooltip'
            var tooltipAttributeName = wmsLoader.layerProperties[layerNodes[i].getAttribute("name")].displayField || "tooltip";
            for (var j = 0; j < featureNodes.length; ++j) {
                if (j == 0) {
                    if (showFILayerTitle) {
                        text += '
' + wmsLoader.layerProperties[layerNodes[i].getAttribute("name")].title + '
';
                    }
                    result = true;
                }
                var attribNodes = featureNodes[j].getElementsByTagName("Attribute");
                var attributesDict = {};
                for (var k = 0; k < attribNodes.length; ++k) {
                    attributesDict[attribNodes[k].getAttribute("name")] = attribNodes[k].getAttribute("value");
                }

                var tooltipFieldAvailable = attributesDict.hasOwnProperty(tooltipAttributeName);
                var geometryFieldAvailable = attributesDict.hasOwnProperty('geometry');

                if (tooltipFieldAvailable) {
                    var aValue = attributesDict[tooltipAttributeName]
                    if (aValue.match(/</)) {
                        text += aValue;
                    }
                    else {
                        attribText = '
' + aValue.replace(/\n/, "
");
                        attribText = attribText.replace("\n", "
");
                        text += attribText + '
';
                    }
                    text += '
';
                }
                else if (tooltipTemplates && tooltipTemplates.hasOwnProperty(layerNodes[i].getAttribute("name"))){
                    templateText = tooltipTemplates[layerNodes[i].getAttribute("name")].template;
                    tooltipText = templateText.replace(/<%(\w*)%>/g,function(m,key){
                        var value = attributesDict.hasOwnProperty(key) ? attributesDict[key] : "";
                        return value.replace(/&/g, "&")
                                     .replace(/</g, "<")
                                     .replace(/>/g, ">")
                                     .replace(/"/g, """)
                                     .replace(/'/g, "'");
                    })
                    text += tooltipText+"
";
                } else if (tooltipAttributeName.indexOf('[%') !== -1){ // Look into displayField for template tags...
                    var tooltipText = tooltipAttributeName;
                    var re = new RegExp(/\[%[^"]*"(.*?)"[^"]*%\]/g);
                    var ttmatch;
                    while(ttmatch = re.exec(tooltipAttributeName)){
                        var key = ttmatch[1];
                        var val = attributesDict.hasOwnProperty(key) ? attributesDict[key] : "";
                        tooltipText = tooltipText.replace(ttmatch[0], val);
                    }
                    text += tooltipText+"
";
                }
                if (geometryFieldAvailable) {
                    var feature = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(attributesDict["geometry"]));
                    featureInfoHighlightLayer.addFeatures([feature]);
                }
            }
            //case raster layers
            var rasterAttributeNodes = Array();
            var rasterLayerChildNode = layerNodes[i].firstChild;
            while (rasterLayerChildNode) {
                if (rasterLayerChildNode.nodeName == "Attribute") {
                    rasterAttributeNodes.push(rasterLayerChildNode);
                }
                rasterLayerChildNode = rasterLayerChildNode.nextSibling;
            }
            for (var j = 0; j < rasterAttributeNodes.length; ++j) {
                if (j == 0) {
                    if (showFILayerTitle) {
                        text += '
' + wmsLoader.layerProperties[layerNodes[i].getAttribute("name")].title + '
';
                    }
                    result = true;
                }
                text += '
'+rasterAttributeNodes[j].getAttribute("name")+": "+rasterAttributeNodes[j].getAttribute("value")+'
';
                text += '
';
            }
            if (identificationMode == 'topMostHit' && result) {
                break;
            }
        }

        if (result) {
            changeCursorInMap("pointer");
            if (!clickPopup) {
                // only show hoverPopup if no clickPopup is open
                //get rid of last

                text = text.replace(/
$/,'');
                hoverPopup = new OpenLayers.Popup.FramedCloud(
                    null, // id
                    map.getLonLatFromPixel(evt.xy), // lonlat
                    null, // new OpenLayers.Size(1,1), // contentSize
                    text , //contentHTML
                    null, // anchor
                    false, // closeBox
                    null // closeBoxCallback
                    );
                hoverPopup.autoSize = true;
                hoverPopup.keepInMap = true;
                hoverPopup.panMapIfOutOfView = false;
                hoverPopup.events.on({"click": onHoverPopupClick});
                map.addPopup(hoverPopup);
            }
        } else {
            changeCursorInMap("default");
        }
    }
}

// disable all GetFeatureInfoRequest until we have a reponse
function onBeforeGetFeatureInfoClick(evt){
    activateGetFeatureInfo(false);
}

// reenable GetFeatureInfo
function noFeatureInfoClick(evt){
    activateGetFeatureInfo(true);
}

/* we need this function in order to pass through the click to the map events
 * */
function onHoverPopupClick(evt){
    if (hoverPopup) {removeHoverPopup();}
    var map = geoExtMap.map; // gets OL map object
    evt.xy = map.events.getMousePosition(evt); // non api function of OpenLayers.Events
    map.events.triggerEvent("click", evt);
}

function onClickPopupClosed(evt) {
    removeClickPopup();
    // enable the hover popup for the curent mosue position
    WMSGetFInfoHover.activate();
    var map = geoExtMap.map; // gets OL map object
    evt.xy = map.events.getMousePosition(evt); // non api function of OpenLayers.Events
    map.events.triggerEvent("mousemove", evt);
    closePopupClick = true; // indicate to not open a new clickPopup
}

function removeClickPopup() {
    var map = geoExtMap.map; // gets OL map object
    map.removePopup(clickPopup);
    clickPopup.destroy();
    clickPopup = null;
    featureInfoHighlightLayer.removeAllFeatures();
}

function removeHoverPopup(){
    var map = geoExtMap.map; // gets OL map object
    map.removePopup(hoverPopup);
    hoverPopup.destroy();
    hoverPopup = null;
    featureInfoHighlightLayer.removeAllFeatures();
}

function showFeatureSelected(args) {
    // select feature in layer
    thematicLayer.mergeNewParams({
        "SELECTION": args["layer"] + ":" + args["id"]
    });
    if (args["doZoomToExtent"]){
        geoExtMap.map.zoomToExtent(args["bbox"]);
    }
    else{
        geoExtMap.map.setCenter(new OpenLayers.LonLat(args["x"], args["y"]), args["zoom"]);
    }
}

function clearFeatureSelected() {
    // clear selection
    thematicLayer.mergeNewParams({
        "SELECTION": null
    });
}

function parseFIResult(node) {
    if (node.hasChildNodes()) {
		//test if we need to show the feature info layer title
		//either from global setting or from project setting
		var showFILayerTitle = showFeatureInfoLayerTitle;
		if (mapThemeSwitcher) {
			showFILayerTitle = mapThemeSwitcher.activeProjectData.showFeatureInfoLayerTitle;
		}
        if (node.hasChildNodes() && node.nodeName == "Layer") {
            var hasAttributes = false;
            var rasterData = false;
            var htmlText = "";
			if (showFILayerTitle) {
				htmlText += "
" + wmsLoader.layerProperties[node.getAttribute("name")].title + "
";
			}
            var geoms = new Array();
            var layerChildNode = node.firstChild;
            while (layerChildNode) {
                if (layerChildNode.hasChildNodes() && layerChildNode.nodeName === "Feature") {
                    htmlText += '\n

\n
\n
';
                    //case vector data
                    var attributeNode = layerChildNode.firstChild;
                    while (attributeNode) {
                        if (attributeNode.nodeName == "Attribute") {
                            var attName = attributeNode.getAttribute("name");
                            var attValue = attributeNode.getAttribute("value");
                            if ((attName !== mapInfoFieldName) && ((suppressEmptyValues == true && attValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '') !== "") || suppressEmptyValues == false)) {
                                if (attName === "geometry") {
                                    var feature = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(attValue));
                                    geoms.push(feature);
                                    if (! suppressInfoGeometry) {
                                        htmlText += "\n
";
                                        if (showFieldNamesInClickPopup) {
                                            htmlText += "" + attName + ":	";
                                        }
                                        htmlText += "" + attValue + "
";
                                        hasAttributes = true;
                                    }
                                } else {
                                    htmlText += "\n
";
                                    if (showFieldNamesInClickPopup) {
                                        htmlText += "" + attName + ":	";
                                    }
                                    // add hyperlinks for URLs in attribute values
                                    if (attValue != '' && /http:\/\/.+\..+/i.test(attValue)) {
                                        if (! /\<a./i.test(attValue)) {
                                            //do not reformat already formated tags
                                            attValue = "" + attValue + "";
                                        }
                                    }
                                    htmlText += "" + attValue + "
";
                                    hasAttributes = true;
                                }
                            }
                        }
                        attributeNode = attributeNode.nextSibling;
                    }
                    htmlText += "\n
\n
";
                }
                else if (layerChildNode.nodeName === "Attribute") {
                    //case raster data
                    if (rasterData == false) {
                        htmlText += "\n

\n
\n
";
                    }
                    htmlText += '\n
'+layerChildNode.getAttribute("name") + '	' + layerChildNode.getAttribute("value") + '
';
                    hasAttributes = true;
                    rasterData = true;
                }
                layerChildNode = layerChildNode.nextSibling;
            }
            //htmlText += "\n
";
            if (hasAttributes) {
                if (rasterData) {
                    htmlText += "\n
\n
";
                }
                //alert(htmlText);
                featureInfoResultLayers.push(htmlText);
                highLightGeometry.push(geoms);
            }
        } else {
            var child = node.firstChild;
            while (child) {
                parseFIResult(child);
                child = child.nextSibling;
            }
        }
    }
}

function listLayersWithFeatures(node) {
    if (node.hasChildNodes()) {
        if (node.nodeName == "Layer") {
            featureInfoResultLayers.push(node.getAttribute("name"));
        } else {
            var child = node.firstChild;
            while (child) {
                listLayersWithFeatures(child);
                child = child.nextSibling;
            }
        }
    }
}

function getFeatures(layerName, node) {
    if (node.hasChildNodes()) {
        if (node.nodeName == "Layer" && node.getAttribute("name") == layerName) {
            return node.firstChild;
        } else {
            var child = node.firstChild;
            while (child) {
                getFeatures(layerName, child);
                child = child.nextSibling;
            }
        }
    }
}
<commit_msg>[BUG] Show FeatureInfo even if themeSwitcher<commit_after>/*
 *
 * FeatureInfoDisplay.js -- part of Quantum GIS Web Client
 *
 * Copyright (2010-2012), The QGIS Project All rights reserved.
 * Quantum GIS Web Client is released under a BSD license. Please see
 * https://github.com/qgis/qgis-web-client/blob/master/README
 * for the full text of the license and the list of contributors.
 *
*/

/* FeatureInfos are presented to the user in two ways using OpenLayers.Popup classes:
 * If the mouse stops and GetFeatureInfo has results for this mouse position
 * a small box presents the contents of the info field (GetProjectSettings) or the
 * field named "toolbox" (GetCapabilities), this is called hoverPopup throughout this script.
 * If the user clicks in the map the contents of all visible fields (and if activated the wkt geometry)
 * is presented in a popup called clickPopup throughout this script.
 * hoverPopups are disabled when a clickPopup is open, however clicking at another position in the map
 * closes the currently opened clickPopup and opens a new one (if there is GetFeatureInfo response).
 * If the cursor is at a position where there is GetFeatureInfo response it indicates the possibility
 * to click by changing to "hand".
*/

var featureInfoPopupContents;
var closePopupClick = false; // stores if the click results from closing a clickPopup

function showFeatureInfo(evt) {
    if (identifyToolActive) {
        if (!closePopupClick) {
            var map = geoExtMap.map; // gets OL map object
            if (window.DOMParser) {
                var parser = new DOMParser();
                xmlDoc = parser.parseFromString(evt.text, "text/xml");
            } else {
                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async = "false";
                xmlDoc.loadXML(evt.text);
            }
            // open AttributeTree panel
            featureInfoResultLayers = new Array();
            highLightGeometry = new Array();
            parseFIResult(xmlDoc);
            featureInfoResultLayers.reverse();
            highLightGeometry.reverse();
            if (featureInfoResultLayers.length > 0) {
                if (hoverPopup) {removeHoverPopup();}
                if (clickPopup) {removeClickPopup();}
                var text = "";
                if (identificationMode == 'topMostHit') {
                    text += featureInfoResultLayers[0];
                    featureInfoHighlightLayer.addFeatures(highLightGeometry[0]);
                    //feature.geometry.getBounds().getCenterLonLat()
                } else {
                    for (var i = 0; i < featureInfoResultLayers.length; i++) {
                        text += featureInfoResultLayers[i];
                        featureInfoHighlightLayer.addFeatures(highLightGeometry[i]);
                    }
                }
                clickPopup = new OpenLayers.Popup.FramedCloud(
                    null, // id
                    map.getLonLatFromPixel(evt.xy), // lonlat
                    null, //new OpenLayers.Size(1,1), // contentSize
                    text, //contentHTML
                    null, // anchor
                    true,  // closeBox
                    onClickPopupClosed // closeBoxCallBackFunction
                    );
                clickPopup.autoSize = true;
                clickPopup.events.fallThrough = false;
                map.addPopup(clickPopup); //*/
                changeCursorInMap("default");
            }
        } else {
            closePopupClick = false;
        }
        activateGetFeatureInfo(true);
    }
}

function showFeatureInfoHover(evt) {
    var map = geoExtMap.map; // gets OL map object
    if (identifyToolActive) {
        if (hoverPopup) {removeHoverPopup();}
        if (window.DOMParser) {
            var parser = new DOMParser();
            xmlDoc = parser.parseFromString(evt.text, "text/xml");
        } else {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(evt.text);
        }
        var layerNodes = xmlDoc.getElementsByTagName("Layer");
        var text = '';
        var result = false;
        //test if we need to show the feature info layer title
        //either from global setting or from project setting
        var showFILayerTitle = showFeatureInfoLayerTitle;
        if (mapThemeSwitcher) {
            if (mapThemeSwitcher.activeProjectData != undefined) {
                showFILayerTitle = mapThemeSwitcher.activeProjectData.showFeatureInfoLayerTitle;
            }
        }

        for (var i = layerNodes.length - 1; i > -1; --i) {
            //case vector layers
            var featureNodes = layerNodes[i].getElementsByTagName("Feature");
            // show layer display field or if missing, the attribute 'tooltip'
            var tooltipAttributeName = wmsLoader.layerProperties[layerNodes[i].getAttribute("name")].displayField || "tooltip";
            for (var j = 0; j < featureNodes.length; ++j) {
                if (j == 0) {
                    if (showFILayerTitle) {
                        text += '
' + wmsLoader.layerProperties[layerNodes[i].getAttribute("name")].title + '
';
                    }
                    result = true;
                }
                var attribNodes = featureNodes[j].getElementsByTagName("Attribute");
                var attributesDict = {};
                for (var k = 0; k < attribNodes.length; ++k) {
                    attributesDict[attribNodes[k].getAttribute("name")] = attribNodes[k].getAttribute("value");
                }

                var tooltipFieldAvailable = attributesDict.hasOwnProperty(tooltipAttributeName);
                var geometryFieldAvailable = attributesDict.hasOwnProperty('geometry');

                if (tooltipFieldAvailable) {
                    var aValue = attributesDict[tooltipAttributeName]
                    if (aValue.match(/</)) {
                        text += aValue;
                    }
                    else {
                        attribText = '
' + aValue.replace(/\n/, "
");
                        attribText = attribText.replace("\n", "
");
                        text += attribText + '
';
                    }
                    text += '
';
                }
                else if (tooltipTemplates && tooltipTemplates.hasOwnProperty(layerNodes[i].getAttribute("name"))){
                    templateText = tooltipTemplates[layerNodes[i].getAttribute("name")].template;
                    tooltipText = templateText.replace(/<%(\w*)%>/g,function(m,key){
                        var value = attributesDict.hasOwnProperty(key) ? attributesDict[key] : "";
                        return value.replace(/&/g, "&")
                                     .replace(/</g, "<")
                                     .replace(/>/g, ">")
                                     .replace(/"/g, """)
                                     .replace(/'/g, "'");
                    })
                    text += tooltipText+"
";
                } else if (tooltipAttributeName.indexOf('[%') !== -1){ // Look into displayField for template tags...
                    var tooltipText = tooltipAttributeName;
                    var re = new RegExp(/\[%[^"]*"(.*?)"[^"]*%\]/g);
                    var ttmatch;
                    while(ttmatch = re.exec(tooltipAttributeName)){
                        var key = ttmatch[1];
                        var val = attributesDict.hasOwnProperty(key) ? attributesDict[key] : "";
                        tooltipText = tooltipText.replace(ttmatch[0], val);
                    }
                    text += tooltipText+"
";
                }
                if (geometryFieldAvailable) {
                    var feature = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(attributesDict["geometry"]));
                    featureInfoHighlightLayer.addFeatures([feature]);
                }
            }
            //case raster layers
            var rasterAttributeNodes = Array();
            var rasterLayerChildNode = layerNodes[i].firstChild;
            while (rasterLayerChildNode) {
                if (rasterLayerChildNode.nodeName == "Attribute") {
                    rasterAttributeNodes.push(rasterLayerChildNode);
                }
                rasterLayerChildNode = rasterLayerChildNode.nextSibling;
            }
            for (var j = 0; j < rasterAttributeNodes.length; ++j) {
                if (j == 0) {
                    if (showFILayerTitle) {
                        text += '
' + wmsLoader.layerProperties[layerNodes[i].getAttribute("name")].title + '
';
                    }
                    result = true;
                }
                text += '
'+rasterAttributeNodes[j].getAttribute("name")+": "+rasterAttributeNodes[j].getAttribute("value")+'
';
                text += '
';
            }
            if (identificationMode == 'topMostHit' && result) {
                break;
            }
        }

        if (result) {
            changeCursorInMap("pointer");
            if (!clickPopup) {
                // only show hoverPopup if no clickPopup is open
                //get rid of last

                text = text.replace(/
$/,'');
                hoverPopup = new OpenLayers.Popup.FramedCloud(
                    null, // id
                    map.getLonLatFromPixel(evt.xy), // lonlat
                    null, // new OpenLayers.Size(1,1), // contentSize
                    text , //contentHTML
                    null, // anchor
                    false, // closeBox
                    null // closeBoxCallback
                    );
                hoverPopup.autoSize = true;
                hoverPopup.keepInMap = true;
                hoverPopup.panMapIfOutOfView = false;
                hoverPopup.events.on({"click": onHoverPopupClick});
                map.addPopup(hoverPopup);
            }
        } else {
            changeCursorInMap("default");
        }
    }
}

// disable all GetFeatureInfoRequest until we have a reponse
function onBeforeGetFeatureInfoClick(evt){
    activateGetFeatureInfo(false);
}

// reenable GetFeatureInfo
function noFeatureInfoClick(evt){
    activateGetFeatureInfo(true);
}

/* we need this function in order to pass through the click to the map events
 * */
function onHoverPopupClick(evt){
    if (hoverPopup) {removeHoverPopup();}
    var map = geoExtMap.map; // gets OL map object
    evt.xy = map.events.getMousePosition(evt); // non api function of OpenLayers.Events
    map.events.triggerEvent("click", evt);
}

function onClickPopupClosed(evt) {
    removeClickPopup();
    // enable the hover popup for the curent mosue position
    WMSGetFInfoHover.activate();
    var map = geoExtMap.map; // gets OL map object
    evt.xy = map.events.getMousePosition(evt); // non api function of OpenLayers.Events
    map.events.triggerEvent("mousemove", evt);
    closePopupClick = true; // indicate to not open a new clickPopup
}

function removeClickPopup() {
    var map = geoExtMap.map; // gets OL map object
    map.removePopup(clickPopup);
    clickPopup.destroy();
    clickPopup = null;
    featureInfoHighlightLayer.removeAllFeatures();
}

function removeHoverPopup(){
    var map = geoExtMap.map; // gets OL map object
    map.removePopup(hoverPopup);
    hoverPopup.destroy();
    hoverPopup = null;
    featureInfoHighlightLayer.removeAllFeatures();
}

function showFeatureSelected(args) {
    // select feature in layer
    thematicLayer.mergeNewParams({
        "SELECTION": args["layer"] + ":" + args["id"]
    });
    if (args["doZoomToExtent"]){
        geoExtMap.map.zoomToExtent(args["bbox"]);
    }
    else{
        geoExtMap.map.setCenter(new OpenLayers.LonLat(args["x"], args["y"]), args["zoom"]);
    }
}

function clearFeatureSelected() {
    // clear selection
    thematicLayer.mergeNewParams({
        "SELECTION": null
    });
}

function parseFIResult(node) {
    if (node.hasChildNodes()) {
		//test if we need to show the feature info layer title
		//either from global setting or from project setting
		var showFILayerTitle = showFeatureInfoLayerTitle;
		if (mapThemeSwitcher) {
			showFILayerTitle = mapThemeSwitcher.activeProjectData.showFeatureInfoLayerTitle;
		}
        if (node.hasChildNodes() && node.nodeName == "Layer") {
            var hasAttributes = false;
            var rasterData = false;
            var htmlText = "";
			if (showFILayerTitle) {
				htmlText += "
" + wmsLoader.layerProperties[node.getAttribute("name")].title + "
";
			}
            var geoms = new Array();
            var layerChildNode = node.firstChild;
            while (layerChildNode) {
                if (layerChildNode.hasChildNodes() && layerChildNode.nodeName === "Feature") {
                    htmlText += '\n

\n
\n
';
                    //case vector data
                    var attributeNode = layerChildNode.firstChild;
                    while (attributeNode) {
                        if (attributeNode.nodeName == "Attribute") {
                            var attName = attributeNode.getAttribute("name");
                            var attValue = attributeNode.getAttribute("value");
                            if ((attName !== mapInfoFieldName) && ((suppressEmptyValues == true && attValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '') !== "") || suppressEmptyValues == false)) {
                                if (attName === "geometry") {
                                    var feature = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(attValue));
                                    geoms.push(feature);
                                    if (! suppressInfoGeometry) {
                                        htmlText += "\n
";
                                        if (showFieldNamesInClickPopup) {
                                            htmlText += "" + attName + ":	";
                                        }
                                        htmlText += "" + attValue + "
";
                                        hasAttributes = true;
                                    }
                                } else {
                                    htmlText += "\n
";
                                    if (showFieldNamesInClickPopup) {
                                        htmlText += "" + attName + ":	";
                                    }
                                    // add hyperlinks for URLs in attribute values
                                    if (attValue != '' && /http:\/\/.+\..+/i.test(attValue)) {
                                        if (! /\<a./i.test(attValue)) {
                                            //do not reformat already formated tags
                                            attValue = "" + attValue + "";
                                        }
                                    }
                                    htmlText += "" + attValue + "
";
                                    hasAttributes = true;
                                }
                            }
                        }
                        attributeNode = attributeNode.nextSibling;
                    }
                    htmlText += "\n
\n
";
                }
                else if (layerChildNode.nodeName === "Attribute") {
                    //case raster data
                    if (rasterData == false) {
                        htmlText += "\n

\n
\n
";
                    }
                    htmlText += '\n
'+layerChildNode.getAttribute("name") + '	' + layerChildNode.getAttribute("value") + '
';
                    hasAttributes = true;
                    rasterData = true;
                }
                layerChildNode = layerChildNode.nextSibling;
            }
            //htmlText += "\n
";
            if (hasAttributes) {
                if (rasterData) {
                    htmlText += "\n
\n
";
                }
                //alert(htmlText);
                featureInfoResultLayers.push(htmlText);
                highLightGeometry.push(geoms);
            }
        } else {
            var child = node.firstChild;
            while (child) {
                parseFIResult(child);
                child = child.nextSibling;
            }
        }
    }
}

function listLayersWithFeatures(node) {
    if (node.hasChildNodes()) {
        if (node.nodeName == "Layer") {
            featureInfoResultLayers.push(node.getAttribute("name"));
        } else {
            var child = node.firstChild;
            while (child) {
                listLayersWithFeatures(child);
                child = child.nextSibling;
            }
        }
    }
}

function getFeatures(layerName, node) {
    if (node.hasChildNodes()) {
        if (node.nodeName == "Layer" && node.getAttribute("name") == layerName) {
            return node.firstChild;
        } else {
            var child = node.firstChild;
            while (child) {
                getFeatures(layerName, child);
                child = child.nextSibling;
            }
        }
    }
}
<|endoftext|>