<commit_before>/*

browser_launcher.js
===================

This file more or less figures out how to launch any browser on any platform.

*/

var path = require('path')
  , rimraf = require('rimraf')
  , async = require('async')
  , exec = require('child_process').exec
  , fs = require('fs')

var fileExists = fs.exists || path.exists

// Find the temporary directory for the system
var tempDir = function(){
  var platform = process.platform
  if (platform === 'win32')
    return 'C:\\Windows\\Temp'
  else
    return '/tmp'
}()

var userHomeDir = process.env.HOME || process.env.USERPROFILE

// Async function that tells whether the executable specified for said browser exists on the system
function browserExeExists(cb){
  var browser = this
  if (browser.exe instanceof Array)
    async.filter(browser.exe, fileExists, function(exes){
      cb(exes.length > 0)
    })
  else
    fileExists(browser.exe, cb)
}

// Async function that tells whether an executable is findable by the `where` command on Windows
function findableByWhere(cb){
  exec('where ' + this.exe, function(err, exePath){
    cb(!!exePath)
  })
}

// Async function that tells whether an executable is findable by the `which` command on Unix
function findableByWhich(cb){
  exec('which ' + this.exe, function(err, exePath){
    cb(!!exePath)
  })
}

function setupFirefoxProfile(profileDir, done){
  rimraf(profileDir, function(){
    // using prefs.js to suppress the check default browser popup
    // and the welcome start page
    var prefs = [
      'user_pref("browser.shell.checkDefaultBrowser", false);'
      , 'user_pref("browser.cache.disk.smart_size.first_run", false);'
    ]
    fs.mkdir(profileDir, function(){
      fs.writeFile(profileDir + '/prefs.js', prefs.join('\n'), function(){
        done()
      })
    })
  })
}

// Return the catalogue of the browsers that Testem supports for the platform. Each "browser object"
// will contain these fields:
//
// * `name` - the display name of the browser
// * `exe` - path to the executable to use to launch the browser
// * `setup(app, done)` - any initial setup needed before launching the executable(this is async,
//        the second parameter `done()` must be invoked when done).
// * `supported(cb)` - an async function which tells us whether the browser is supported by the current machine.
function browsersForPlatform(){
  var platform = process.platform
  if (platform === 'win32'){
    return  [
      {
        name: "IE7",
        exe: "C:\\Program Files\\Internet Explorer\\iexplore.exe",
        setup: function(app, done){
          app.server.ieCompatMode = 'EmulateIE7'
          done()
        },
        supported: browserExeExists
      },
      {
        name: "IE8",
        exe: "C:\\Program Files\\Internet Explorer\\iexplore.exe",
        setup: function(app, done){
          app.server.ieCompatMode = 'EmulateIE8'
          done()
        },
        supported: browserExeExists
      },
      {
        name: "IE9",
        exe: "C:\\Program Files\\Internet Explorer\\iexplore.exe",
        setup: function(app, done){
          app.server.ieCompatMode = '9'
          done()
        },
        supported: browserExeExists
      },
      {
        name: "Firefox",
        exe: [
          "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
          "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"
        ],
        args: ["-profile", tempDir + "\\testem.firefox"],
        setup: function(app, done){
          setupFirefoxProfile(tempDir + '/testem.firefox', done)
        },
        supported: browserExeExists
      },
      {
        name: "Chrome",
        exe: [
          userHomeDir + "\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
          userHomeDir + "\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
          "C:\\Program Files\\Google\\Chrome\\Application\\Chrome.exe",
          "C:\\Program Files (x86)\\Google\\Chrome\\Application\\Chrome.exe"
        ],
        args: ["--user-data-dir=" + tempDir + "\\testem.chrome", "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '\\testem.chrome', done)
        },
        supported: browserExeExists
      },
      {
        name: "Safari",
        exe: [
          "C:\\Program Files\\Safari\\safari.exe",
          "C:\\Program Files (x86)\\Safari\\safari.exe"
        ],
        supported: browserExeExists
      },
      {
        name: "Opera",
        exe: [
          "C:\\Program Files\\Opera\\opera.exe",
          "C:\\Program Files (x86)\\Opera\\opera.exe"
        ],
        args: ["-pd", tempDir + "\\testem.opera"],
        setup: function(app, done){
          rimraf(tempDir + '\\testem.opera', done)
        },
        supported: browserExeExists
      },
      {
        name: 'PhantomJS',
        exe: 'phantomjs',
        args: function(app){
          return [path.dirname(__dirname) + '/assets/phantom.js', app.config.get('port')]
        },
        supported: findableByWhere
      }
    ]
  }else if (platform === 'darwin'){
    return [
      {
        name: "Chrome",
        exe: "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome",
        args: ["--user-data-dir=" + tempDir + "/testem.chrome", "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.chrome', done)
        },
        supported: browserExeExists
      },
      {
        name: "Firefox",
        exe: "/Applications/Firefox.app/Contents/MacOS/firefox",
        args: ["-profile", tempDir + "/testem.firefox"],
        setup: function(app, done){
          setupFirefoxProfile(tempDir + '/testem.firefox', done)
        },
        supported: browserExeExists
      },
      {
        name: "Safari",
        exe: "/Applications/Safari.app/Contents/MacOS/Safari",
        setup: function(app, done){
          var host = app.config.get('host')
          fs.writeFile(tempDir + '/testem.safari.html', "<script>window.location = 'http://" + host + ":" + app.config.get('port') + "/'</script>", done)
        },
        args: function(app){
          return [tempDir + '/testem.safari.html']
        },
        supported: browserExeExists
      },
      {
        name: "Opera",
        exe: "/Applications/Opera.app/Contents/MacOS/Opera",
        args: ["-pd", tempDir + "/testem.opera"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.opera', done)
        },
        supported: browserExeExists
      },
      {
        name: 'PhantomJS',
        exe: 'phantomjs',
        args: function(app){
          return [path.dirname(__dirname) + '/assets/phantom.js', app.config.get('port')]
        },
        supported: findableByWhich
      }
    ]
  }else if (platform === 'linux'){
    return [
      {
        name: 'Firefox',
        exe: 'firefox',
        args: ["-no-remote", "-profile", tempDir + "/testem.firefox"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.firefox', function(err){
            if (!err){
              fs.mkdir(tempDir + '/testem.firefox', done)
            }else{
              done()
            }
          })
        },
        supported: findableByWhich
      },
      {
        name: 'Chrome',
        exe: 'google-chrome',
        args: ["--user-data-dir=" + tempDir + "/testem.chrome",
          "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.chrome', done)
        },
        supported: findableByWhich
      },
      {
        name: 'Chromium',
        exe: 'chromium',
        args: ["--user-data-dir=" + tempDir + "/testem.chromium",
          "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.chromium', done)
        },
        supported: findableByWhich
      },
      {
        name: 'PhantomJS',
        exe: 'phantomjs',
        args: function(app){
          return [path.dirname(__dirname) + '/assets/phantom.js', app.config.get('port')]
        },
        supported: findableByWhich
      }
    ]
  }else{
    return []
  }
}

// Returns the avaliable browsers on the current machine.
function getAvailableBrowsers(cb){
  var browsers = browsersForPlatform()
  browsers.forEach(function(b){
    b.protocol = 'browser'
  })
  async.filter(browsers, function(browser, cb){
    browser.supported(cb)
  }, function(available){
    cb(available)
  })
}

exports.getAvailableBrowsers = getAvailableBrowsers
<commit_msg>Search a list of potential command names for each browser<commit_after>/*

browser_launcher.js
===================

This file more or less figures out how to launch any browser on any platform.

*/

var path = require('path')
  , rimraf = require('rimraf')
  , async = require('async')
  , exec = require('child_process').exec
  , fs = require('fs')

var fileExists = fs.exists || path.exists

// Find the temporary directory for the system
var tempDir = function(){
  var platform = process.platform
  if (platform === 'win32')
    return 'C:\\Windows\\Temp'
  else
    return '/tmp'
}()

var userHomeDir = process.env.HOME || process.env.USERPROFILE

// Async function that tells whether the executable specified for said browser exists on the system
function browserExeExists(cb){
  var browser = this
  if (browser.exe instanceof Array)
    async.filter(browser.exe, fileExists, function(exes){
      if (exes.length > 0)
        browser.exe = exes[0] // commit to the first match
      cb(exes.length > 0)
    })
  else
    fileExists(browser.exe, cb)
}

// Async function that tells whether an executable is findable by the `where` command on Windows
function findableByWhere(cb){
  exec('where ' + this.exe, function(err, exePath){
    cb(!!exePath)
  })
}

// Async function that tells whether an executable is findable by the `which` command on Unix
function findableByWhich(cb){
  var browser = this
  function which(exe, cb){
    exec('which ' + exe, function(err, exePath){
      cb(!!exePath)
    })
  }
  if (browser.exe instanceof Array)
    async.filter(browser.exe, which, function(exes){
      if (exes.length > 0)
        browser.exe = exes[0] // commit to the first match
      cb(exes.length > 0)
    })
  else
    exec('which ' + browser.exe, function(err, exePath){
      cb(!!exePath)
    })
}

function setupFirefoxProfile(profileDir, done){
  rimraf(profileDir, function(){
    // using prefs.js to suppress the check default browser popup
    // and the welcome start page
    var prefs = [
      'user_pref("browser.shell.checkDefaultBrowser", false);'
      , 'user_pref("browser.cache.disk.smart_size.first_run", false);'
    ]
    fs.mkdir(profileDir, function(){
      fs.writeFile(profileDir + '/prefs.js', prefs.join('\n'), function(){
        done()
      })
    })
  })
}

// Return the catalogue of the browsers that Testem supports for the platform. Each "browser object"
// will contain these fields:
//
// * `name` - the display name of the browser
// * `exe` - path to the executable to use to launch the browser
// * `setup(app, done)` - any initial setup needed before launching the executable(this is async,
//        the second parameter `done()` must be invoked when done).
// * `supported(cb)` - an async function which tells us whether the browser is supported by the current machine.
function browsersForPlatform(){
  var platform = process.platform
  if (platform === 'win32'){
    return  [
      {
        name: "IE7",
        exe: "C:\\Program Files\\Internet Explorer\\iexplore.exe",
        setup: function(app, done){
          app.server.ieCompatMode = 'EmulateIE7'
          done()
        },
        supported: browserExeExists
      },
      {
        name: "IE8",
        exe: "C:\\Program Files\\Internet Explorer\\iexplore.exe",
        setup: function(app, done){
          app.server.ieCompatMode = 'EmulateIE8'
          done()
        },
        supported: browserExeExists
      },
      {
        name: "IE9",
        exe: "C:\\Program Files\\Internet Explorer\\iexplore.exe",
        setup: function(app, done){
          app.server.ieCompatMode = '9'
          done()
        },
        supported: browserExeExists
      },
      {
        name: "Firefox",
        exe: [
          "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
          "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"
        ],
        args: ["-profile", tempDir + "\\testem.firefox"],
        setup: function(app, done){
          setupFirefoxProfile(tempDir + '/testem.firefox', done)
        },
        supported: browserExeExists
      },
      {
        name: "Chrome",
        exe: [
          userHomeDir + "\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
          userHomeDir + "\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
          "C:\\Program Files\\Google\\Chrome\\Application\\Chrome.exe",
          "C:\\Program Files (x86)\\Google\\Chrome\\Application\\Chrome.exe"
        ],
        args: ["--user-data-dir=" + tempDir + "\\testem.chrome", "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '\\testem.chrome', done)
        },
        supported: browserExeExists
      },
      {
        name: "Safari",
        exe: [
          "C:\\Program Files\\Safari\\safari.exe",
          "C:\\Program Files (x86)\\Safari\\safari.exe"
        ],
        supported: browserExeExists
      },
      {
        name: "Opera",
        exe: [
          "C:\\Program Files\\Opera\\opera.exe",
          "C:\\Program Files (x86)\\Opera\\opera.exe"
        ],
        args: ["-pd", tempDir + "\\testem.opera"],
        setup: function(app, done){
          rimraf(tempDir + '\\testem.opera', done)
        },
        supported: browserExeExists
      },
      {
        name: 'PhantomJS',
        exe: 'phantomjs',
        args: function(app){
          return [path.dirname(__dirname) + '/assets/phantom.js', app.config.get('port')]
        },
        supported: findableByWhere
      }
    ]
  }else if (platform === 'darwin'){
    return [
      {
        name: "Chrome",
        exe: "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome",
        args: ["--user-data-dir=" + tempDir + "/testem.chrome", "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.chrome', done)
        },
        supported: browserExeExists
      },
      {
        name: "Firefox",
        exe: "/Applications/Firefox.app/Contents/MacOS/firefox",
        args: ["-profile", tempDir + "/testem.firefox"],
        setup: function(app, done){
          setupFirefoxProfile(tempDir + '/testem.firefox', done)
        },
        supported: browserExeExists
      },
      {
        name: "Safari",
        exe: "/Applications/Safari.app/Contents/MacOS/Safari",
        setup: function(app, done){
          var host = app.config.get('host')
          fs.writeFile(tempDir + '/testem.safari.html', "<script>window.location = 'http://" + host + ":" + app.config.get('port') + "/'</script>", done)
        },
        args: function(app){
          return [tempDir + '/testem.safari.html']
        },
        supported: browserExeExists
      },
      {
        name: "Opera",
        exe: "/Applications/Opera.app/Contents/MacOS/Opera",
        args: ["-pd", tempDir + "/testem.opera"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.opera', done)
        },
        supported: browserExeExists
      },
      {
        name: 'PhantomJS',
        exe: 'phantomjs',
        args: function(app){
          return [path.dirname(__dirname) + '/assets/phantom.js', app.config.get('port')]
        },
        supported: findableByWhich
      }
    ]
  }else if (platform === 'linux'){
    return [
      {
        name: 'Firefox',
        exe: 'firefox',
        args: ["-no-remote", "-profile", tempDir + "/testem.firefox"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.firefox', function(err){
            if (!err){
              fs.mkdir(tempDir + '/testem.firefox', done)
            }else{
              done()
            }
          })
        },
        supported: findableByWhich
      },
      {
        name: 'Chrome',
        exe: 'google-chrome',
        args: ["--user-data-dir=" + tempDir + "/testem.chrome",
          "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.chrome', done)
        },
        supported: findableByWhich
      },
      {
        name: 'Chromium',
        exe: ['chromium', 'chromium-browser'],
        args: ["--user-data-dir=" + tempDir + "/testem.chromium",
          "--no-default-browser-check", "--no-first-run"],
        setup: function(app, done){
          rimraf(tempDir + '/testem.chromium', done)
        },
        supported: findableByWhich
      },
      {
        name: 'PhantomJS',
        exe: 'phantomjs',
        args: function(app){
          return [path.dirname(__dirname) + '/assets/phantom.js', app.config.get('port')]
        },
        supported: findableByWhich
      }
    ]
  }else{
    return []
  }
}

// Returns the avaliable browsers on the current machine.
function getAvailableBrowsers(cb){
  var browsers = browsersForPlatform()
  browsers.forEach(function(b){
    b.protocol = 'browser'
  })
  async.filter(browsers, function(browser, cb){
    browser.supported(cb)
  }, function(available){
    cb(available)
  })
}

exports.getAvailableBrowsers = getAvailableBrowsers
<|endoftext|>


<commit_before>var Util, DOM, CloudCmd;

(function (Util, DOM) {
    'use strict';

     CloudCmd.Listeners = new ListenersProto(CloudCmd, Util, DOM);

     function ListenersProto(CloudCmd, Util, DOM){
        var Info                = DOM.CurrentInfo,
            Storage             = DOM.Storage,
            Events              = DOM.Events,
            getConfig           = CloudCmd.getConfig;

        this.analytics          = function() {
            getConfig(function(config) {
                var analytics   = config.analytics,
                    online      = config.online;

                if (analytics && online) {
                    Events.addOnce('mousemove', function(){
                        var FIVE_SECONDS    = 5000,
                            lUrl            = CloudCmd.LIBDIRCLIENT + 'analytics.js';

                        setTimeout(function(){
                            DOM.jsload(lUrl);
                        }, FIVE_SECONDS);
                    });
                }
            });
        };

        this.init = function () {
            appStorage();
            contextMenu();
            dragndrop();
            unload();
            pop();
            online();
        };

        this.initKeysPanel          = function() {
            var i, lButton, id, n, f,
                lKeysPanel = {},

                lFuncs =[
                    null,
                    CloudCmd.Help,              /* f1  */
                    DOM.renameCurrent,          /* f2  */
                    CloudCmd.View,              /* f3  */
                    CloudCmd.Edit,              /* f4  */
                    DOM.copyCurrent,            /* f5  */
                    DOM.moveCurrent,            /* f6  */
                    DOM.promptNewDir,           /* f7  */
                    DOM.promptDeleteSelected,   /* f8  */
                    CloudCmd.Menu,              /* f9  */
                    CloudCmd.Config             /* f10 */
                ];

            n = lFuncs.length;
            for (i = 1; i <= n; i++) {
                id                  = 'f' + i,
                lButton             = DOM.getById(id);
                lKeysPanel[id]      = lButton;

                if (lButton)
                    if (i === 1 || i === 3 || i === 4 || i === 9 || i === 10)
                        Events.addOnce('click', lFuncs[i], lButton);
                    else
                        Events.addClick(lFuncs[i], lButton);
            }

            id                      = '~',
            lButton                 = DOM.getById(id);
            lKeysPanel[id]          = lButton;
            Events.addOnce('click', CloudCmd.Console, lButton);

            id                      = 'contact',
            lButton                 = DOM.getById(id);
            lKeysPanel[id]          = lButton;

            Events.addOnce('click', CloudCmd.Contact, lButton);

            return lKeysPanel;
        };

        /**
         * функция меняет ссыки на ajax-овые
         * @param pPanelID
         */
        this.changeLinks            = function(pPanelID) {
            /* назначаем кнопку очистить кэш и показываем её */
            var lClearStorage = DOM.getByClass('clear-storage')[0];
                Events.addClick(Storage.clear, lClearStorage);

            /* меняем ссылки на ajax-запросы */
            var lPanel  = DOM.getById(pPanelID),
                a       = DOM.getByTag('a', lPanel),

                /* right mouse click function varible */
                lOnContextMenu_f = function(pEvent){
                    var target,
                        isFunc      = Util.isFunction(CloudCmd.Menu),
                        ret         = true,
                        Key         = CloudCmd.Key;

                    Key && Key.unsetBind();

                    /* getting html element
                     * currentTarget - DOM event
                     * target        - jquery event
                     */
                    target = pEvent.currentTarget || pEvent.target;
                    DOM.setCurrentFile(target);

                    if (isFunc) {
                        CloudCmd.Menu({
                            x: pEvent.clientX,
                            y: pEvent.clientY
                        });

                        /* disabling browsers menu*/
                        ret = false;
                        DOM.Images.showLoad();
                    }

                    return ret;
                },

            /* drag and drop function varible
             * download file from browser to descktop
             * in Chrome (HTML5)
             */
                lOnDragStart_f = function(pEvent) {
                    var lElement    = pEvent.target,
                        EXT         = 'json',
                        isDir       = Info.isDir,
                        lLink       = lElement.href,
                        lName       = lElement.textContent;

                    /* if it's directory - adding json extension */
                    if (isDir) {
                        lName       += '.' + EXT;
                        lLink       += '?' + EXT;
                    }

                    pEvent.dataTransfer.setData('DownloadURL',
                        'application/octet-stream'  + ':' +
                        lName                       + ':' +
                        lLink);
                },

                lSetCurrentFile_f = function(pEvent){
                    var pElement    = pEvent.target,
                        lTag        = pElement.tagName;

                    if (lTag !== 'LI')
                        do {
                            pElement    = pElement.parentElement;
                            lTag        = pElement.tagName;
                        } while(lTag !== 'LI');

                    DOM.setCurrentFile(pElement);
                },

                lUrl                = CloudCmd.HOST,
                lLoadDirOnce        = CloudCmd.loadDir();

            /* ставим загрузку гифа на клик*/
            Events.addClick( CloudCmd.refresh, a[0].parentElement );

            /* start from 1 cous 0 is a refresh and it's setted up */
            for(var i = 1, n = a.length; i < n ; i++){
                /* убираем адрес хоста*/
                var ai              = a[i],
                    lLink           = Util.removeStr(ai.href, lUrl),
                    lLoadDir        = CloudCmd.loadDir(lLink),
                    /* устанавливаем обработчики на строку
                     * на двойное нажатие на левую кнопку мышки */
                    lLi = ai.parentElement.parentElement;

                /* if we in path - set click event */
                if (lLi.className === 'path')
                    Events.addClick( lLoadDir, ai );
                else {
                    Events.add({
                        'click'         : DOM.preventDefault,
                        'mousedown'     : lSetCurrentFile_f,
                        'contextmenu'   : lOnContextMenu_f
                        }, lLi);

                    Events.add('dragstart', lOnDragStart_f, ai);

                    /* если ссылка на папку, а не файл */
                    if(ai.target !== '_blank'){
                        Events.add({
                            'dblclick' : lLoadDirOnce,
                            'touchend' : lLoadDirOnce
                            }, lLi);
                    }

                    lLi.id = (ai.title ? ai.title : ai.textContent) +
                        '(' + pPanelID + ')';
                }
            }
        };

        function appStorage() {
            getConfig(function(config) {
                var isAppStorage  = config.appStorage,
                    appStorage    = window.applicationStorage;

                if (isAppStorage && appStorage)
                    Events.add('updateready', function() {
                        var ret = confirm('An update is available. Reload now?');

                        if (ret)
                            location.reload();

                    }, appStorage);
                });
        }

        function contextMenu() {
            Events.addContextMenu(function(pEvent){
                CloudCmd.Menu.ENABLED || DOM.preventDefault(pEvent);
            }, document);
        }

        function dragndrop() {
            var panels          = DOM.getByClass('panel'),
                i               = 0,
                n               = panels.length,
                preventDefault  = function (event) {
                    event.stopPropagation();
                    event.preventDefault();
                },
                toggle          = function () {
                    for (i = 0; i < n; i++)
                        DOM.toggleClass(panels[i], 'selected-panel');
                },
                onDrop          = function (event) {
                    var reader, file, files,
                         dir    = Info.dirPath,
                         load   = function(file){
                            return function(event) {
                                var path    = dir + file.name,
                                    data    = event.target.result;

                                DOM.RESTful.save(path, data, CloudCmd.refresh);
                            };
                        };

                    preventDefault(event);
                    toggle();

                    files               = event.dataTransfer.files;

                    if (files.length) {
                        n               = files.length;

                        for (i = 0; i < n; i++) {
                            reader          = new FileReader();
                            file            = files[i];
                            Events.add('load', load(file), reader);
                            reader.readAsArrayBuffer(file);
                        }
                    }
                };

            Events.add(['dragenter', 'dragleave'], toggle);

            for (i = 0; i < n; i++) {
                Events.add('dragover', preventDefault, panels[i]);
                Events.add('drop', onDrop, panels[i]);
            }
        }

        function unload() {
            DOM.Events.add(['unload', 'beforeunload'], function (pEvent) {
                var lRet,
                    Key     = CloudCmd.Key,
                    lIsBind = Key && Key.isBind();

                if(!lIsBind) {
                    DOM.preventDefault(pEvent);
                    lRet = 'Please make sure that you saved all work.';
                }

                return lRet;
            });
        }

        function pop() {
            Events.add("popstate", function(pEvent) {
                var lPath   = pEvent.state + '?json';

                if (pEvent.state) {
                    lPath   = pEvent.state + '?json';
                    CloudCmd.ajaxLoad(lPath, {nohistory: true});
                } else
                    CloudCmd.route(location.hash);

                return true;
            });
        }

        function online() {
            var cssSet = Util.retFunc(DOM.cssSet, {
                    id      :'local-droids-font',
                    element : document.head,
                    inner   :   '@font-face {font-family: "Droid Sans Mono";'           +
                                'font-style: normal;font-weight: normal;'               +
                                'src: local("Droid Sans Mono"), local("DroidSansMono"),'+
                                ' url("/font/DroidSansMono.woff") format("woff");}'
                });

            if (navigator.onLine)
                Events.addOnce('offline', cssSet);
            else
                cssSet();
        }

     }

})(Util, DOM);
<commit_msg>refactor(listeners) initKeysPanel<commit_after>var Util, DOM, CloudCmd;

(function (Util, DOM) {
    'use strict';

     CloudCmd.Listeners = new ListenersProto(CloudCmd, Util, DOM);

     function ListenersProto(CloudCmd, Util, DOM){
        var Info                = DOM.CurrentInfo,
            Storage             = DOM.Storage,
            Events              = DOM.Events,
            getConfig           = CloudCmd.getConfig;

        this.analytics          = function() {
            getConfig(function(config) {
                var analytics   = config.analytics,
                    online      = config.online;

                if (analytics && online) {
                    Events.addOnce('mousemove', function(){
                        var FIVE_SECONDS    = 5000,
                            lUrl            = CloudCmd.LIBDIRCLIENT + 'analytics.js';

                        setTimeout(function(){
                            DOM.jsload(lUrl);
                        }, FIVE_SECONDS);
                    });
                }
            });
        };

        this.init = function () {
            appStorage();
            contextMenu();
            dragndrop();
            unload();
            pop();
            online();
        };

        this.initKeysPanel          = function() {
            var button, id, name, func,
                keysElement     = DOM.getByClass('keyspanel')[0],
                keysPanel       = {},

                clickFuncs      = {
                    'f2'        : DOM.renameCurrent,
                    'f5'        : DOM.copyCurrent,
                    'f6'        : DOM.moveCurrent,
                    'f7'        : DOM.promptNewDir,
                    'f8'        : DOM.promptDeleteSelected
                },

                onceClickFuncs  = {
                    'f1'        : 'Help',
                    'f3'        : 'View',
                    'f4'        : 'Edit',
                    'f9'        : 'Menu',
                    'f10'       : 'Config',
                    '~'         : 'Console',
                    'contact'   : 'Contact'
                };

            if (keysElement)
                Events.addClick(function(event) {
                    var element = event.target,
                        id      = element.id,
                        func    = clickFuncs[id];

                    Util.exec(func);

                }, keysElement);

            for (id in onceClickFuncs) {
                button  = DOM.getById(id);

                if (button) {
                    name            = onceClickFuncs[id];
                    func            = CloudCmd[name];
                    keysPanel[id]   = button;

                    Events.addOnce('click', func, button);
                }
            }

            return keysPanel;
        };

        /**
         * функция меняет ссыки на ajax-овые
         * @param pPanelID
         */
        this.changeLinks            = function(pPanelID) {
            /* назначаем кнопку очистить кэш и показываем её */
            var lClearStorage = DOM.getByClass('clear-storage')[0];
                Events.addClick(Storage.clear, lClearStorage);

            /* меняем ссылки на ajax-запросы */
            var lPanel  = DOM.getById(pPanelID),
                a       = DOM.getByTag('a', lPanel),

                /* right mouse click function varible */
                lOnContextMenu_f = function(pEvent){
                    var target,
                        isFunc      = Util.isFunction(CloudCmd.Menu),
                        ret         = true,
                        Key         = CloudCmd.Key;

                    Key && Key.unsetBind();

                    /* getting html element
                     * currentTarget - DOM event
                     * target        - jquery event
                     */
                    target = pEvent.currentTarget || pEvent.target;
                    DOM.setCurrentFile(target);

                    if (isFunc) {
                        CloudCmd.Menu({
                            x: pEvent.clientX,
                            y: pEvent.clientY
                        });

                        /* disabling browsers menu*/
                        ret = false;
                        DOM.Images.showLoad();
                    }

                    return ret;
                },

            /* drag and drop function varible
             * download file from browser to descktop
             * in Chrome (HTML5)
             */
                lOnDragStart_f = function(pEvent) {
                    var lElement    = pEvent.target,
                        EXT         = 'json',
                        isDir       = Info.isDir,
                        lLink       = lElement.href,
                        lName       = lElement.textContent;

                    /* if it's directory - adding json extension */
                    if (isDir) {
                        lName       += '.' + EXT;
                        lLink       += '?' + EXT;
                    }

                    pEvent.dataTransfer.setData('DownloadURL',
                        'application/octet-stream'  + ':' +
                        lName                       + ':' +
                        lLink);
                },

                lSetCurrentFile_f = function(pEvent){
                    var pElement    = pEvent.target,
                        lTag        = pElement.tagName;

                    if (lTag !== 'LI')
                        do {
                            pElement    = pElement.parentElement;
                            lTag        = pElement.tagName;
                        } while(lTag !== 'LI');

                    DOM.setCurrentFile(pElement);
                },

                lUrl                = CloudCmd.HOST,
                lLoadDirOnce        = CloudCmd.loadDir();

            /* ставим загрузку гифа на клик*/
            Events.addClick( CloudCmd.refresh, a[0].parentElement );

            /* start from 1 cous 0 is a refresh and it's setted up */
            for(var i = 1, n = a.length; i < n ; i++){
                /* убираем адрес хоста*/
                var ai              = a[i],
                    lLink           = Util.removeStr(ai.href, lUrl),
                    lLoadDir        = CloudCmd.loadDir(lLink),
                    /* устанавливаем обработчики на строку
                     * на двойное нажатие на левую кнопку мышки */
                    lLi = ai.parentElement.parentElement;

                /* if we in path - set click event */
                if (lLi.className === 'path')
                    Events.addClick( lLoadDir, ai );
                else {
                    Events.add({
                        'click'         : DOM.preventDefault,
                        'mousedown'     : lSetCurrentFile_f,
                        'contextmenu'   : lOnContextMenu_f
                        }, lLi);

                    Events.add('dragstart', lOnDragStart_f, ai);

                    /* если ссылка на папку, а не файл */
                    if(ai.target !== '_blank'){
                        Events.add({
                            'dblclick' : lLoadDirOnce,
                            'touchend' : lLoadDirOnce
                            }, lLi);
                    }

                    lLi.id = (ai.title ? ai.title : ai.textContent) +
                        '(' + pPanelID + ')';
                }
            }
        };

        function appStorage() {
            getConfig(function(config) {
                var isAppStorage  = config.appStorage,
                    appStorage    = window.applicationStorage;

                if (isAppStorage && appStorage)
                    Events.add('updateready', function() {
                        var ret = confirm('An update is available. Reload now?');

                        if (ret)
                            location.reload();

                    }, appStorage);
                });
        }

        function contextMenu() {
            Events.addContextMenu(function(pEvent){
                CloudCmd.Menu.ENABLED || DOM.preventDefault(pEvent);
            }, document);
        }

        function dragndrop() {
            var panels          = DOM.getByClass('panel'),
                i               = 0,
                n               = panels.length,
                preventDefault  = function (event) {
                    event.stopPropagation();
                    event.preventDefault();
                },
                toggle          = function () {
                    for (i = 0; i < n; i++)
                        DOM.toggleClass(panels[i], 'selected-panel');
                },
                onDrop          = function (event) {
                    var reader, file, files,
                         dir    = Info.dirPath,
                         load   = function(file){
                            return function(event) {
                                var path    = dir + file.name,
                                    data    = event.target.result;

                                DOM.RESTful.save(path, data, CloudCmd.refresh);
                            };
                        };

                    preventDefault(event);
                    toggle();

                    files               = event.dataTransfer.files;

                    if (files.length) {
                        n               = files.length;

                        for (i = 0; i < n; i++) {
                            reader          = new FileReader();
                            file            = files[i];
                            Events.add('load', load(file), reader);
                            reader.readAsArrayBuffer(file);
                        }
                    }
                };

            Events.add(['dragenter', 'dragleave'], toggle);

            for (i = 0; i < n; i++) {
                Events.add('dragover', preventDefault, panels[i]);
                Events.add('drop', onDrop, panels[i]);
            }
        }

        function unload() {
            DOM.Events.add(['unload', 'beforeunload'], function (pEvent) {
                var lRet,
                    Key     = CloudCmd.Key,
                    lIsBind = Key && Key.isBind();

                if(!lIsBind) {
                    DOM.preventDefault(pEvent);
                    lRet = 'Please make sure that you saved all work.';
                }

                return lRet;
            });
        }

        function pop() {
            Events.add("popstate", function(pEvent) {
                var lPath   = pEvent.state + '?json';

                if (pEvent.state) {
                    lPath   = pEvent.state + '?json';
                    CloudCmd.ajaxLoad(lPath, {nohistory: true});
                } else
                    CloudCmd.route(location.hash);

                return true;
            });
        }

        function online() {
            var cssSet = Util.retFunc(DOM.cssSet, {
                    id      :'local-droids-font',
                    element : document.head,
                    inner   :   '@font-face {font-family: "Droid Sans Mono";'           +
                                'font-style: normal;font-weight: normal;'               +
                                'src: local("Droid Sans Mono"), local("DroidSansMono"),'+
                                ' url("/font/DroidSansMono.woff") format("woff");}'
                });

            if (navigator.onLine)
                Events.addOnce('offline', cssSet);
            else
                cssSet();
        }

     }

})(Util, DOM);
<|endoftext|>


<commit_before>/* global CloudCmd */
/* global Util */
/* global DOM */
/* global rendy */
/* global spero */
/* global remedy */

(function(CloudCmd, Util, DOM, rendy) {
    'use strict';

    CloudCmd.Operation = OperationProto;

    function OperationProto(operation, data) {
        var Name        = 'Operation',
            Loaded,
            RESTful     = DOM.RESTful,

            copyFn      = RESTful.cp,
            moveFn      = RESTful.mv,
            deleteFn    = RESTful.delete,

            Images      = DOM.Images,
            Dialog      = DOM.Dialog,

            Operation   = this;

        function rmLastSlash(str) {
            return str.replace(/\/$/, '');
        }

        function init() {
            Images.show.load();

            Util.exec.series([
                DOM.loadSocket,
                function(callback) {
                    var Files = DOM.Files;

                    Files.get('config', function(error, config) {
                        if (error)
                            alert(error);
                        else if (config.progress)
                            load(function() {
                                create(callback);
                            });
                        else
                            callback();
                    });
                },
                function() {
                    Loaded = true;
                    Images.hide();
                    Operation.show(operation, data);
                }
            ]);
        }

        function create(callback) {
            spero(function() {
                 spero.on('connect', function() {
                    copyFn = function(data, callback) {
                        setListeners(spero, callback);
                        spero.copy(data.from, data.to, data.names);
                    };
                });

                spero.on('disconnect', function() {
                    copyFn = DOM.RESTful.cp;
                });
            });

            remedy(function() {
                 remedy.on('connect', function() {
                    deleteFn = function(from, files, callback) {
                        from = from.replace(/\?.*/, '');

                        setListeners(remedy, callback);
                        remedy.remove(from, files);
                    };
                });

                remedy.on('disconnect', function() {
                    deleteFn = DOM.RESTful.remove;
                });
            });

            Util.exec(callback);
        }

        function setListeners(emitter, callback) {
            var listeners = {
                progress: function(value) {
                    Images.setProgress(value);
                },

                end: function() {
                    callback();
                    events.forEach(function(name) {
                        emitter.removeListener(name, listeners[name]);
                    });
                },

                error: function(data) {
                    var msg = data + '\n Continue?',
                        is = confirm(msg);

                    if (is)
                        spero.continue();
                    else
                        spero.abort();
                }
            },
            events = Object.keys(listeners);

            events.forEach(function(name) {
                emitter.on(name, listeners[name]);
            });
        }

        this.hide   = function() {
            CloudCmd.View.hide();
        };

        this.show = function(operation, data) {
            if (Loaded)
                switch(operation) {
                case 'copy':
                    Operation.copy(data);
                    break;

                case 'move':
                    Operation.move(data);
                    break;

                case 'delete':
                    Operation.delete();
                    break;

                case 'delete:silent':
                    Operation.deleteShift();
                }
        };

        this.copy           = function(data) {
            processFiles(data, copyFn, message('Copy'));
        };

        this.move           = function(data) {
            processFiles(data, moveFn, message('Rename/Move'));
        };

        this.delete         = function() {
            promptDelete();
        };

        this.deleteSilent   = function() {
            deleteSilent();
        };

         /**
         * prompt and delete current file or selected files
         *
         * @currentFile
         */
        function promptDelete() {
            var ret, type, isDir, msg,
                name        = '',
                msgAsk      = 'Do you really want to delete the ',
                msgSel      = 'selected ',
                files       = DOM.getSelectedFiles(),
                names       = DOM.getSelectedNames(files),
                i, n        = names && names.length,
                current     = DOM.getCurrentFile();

            if (n) {
                for (i = 0; i < 5 && i < n; i++)
                    name += '\n' + names[i];

                if (n >= 5)
                    name   += '\n...';

                msg    = msgAsk + msgSel + n + ' files/directoris?\n' + name ;
            } else {
                isDir       = DOM.isCurrentIsDir(current);

                if (isDir)
                    type    = 'directory';
                else
                    type    = 'file';

                 type += ' ';

                name   = DOM.getCurrentName(current);
                msg    = msgAsk + msgSel + type + name + '?';
            }

            if (name !== '..')
                ret  = Dialog.confirm(msg);
            else
                Dialog.alert('No files selected!');

            if (ret)
                deleteSilent(files);

            return ret;
        }

        /**
         * delete current or selected files
         *
         * @files
         */
        function deleteSilent(files) {
            var n, names,
                query       = '?files',
                Info        = DOM.CurrentInfo,
                path        = Info.dirPath,
                current     = Info.element;

            Images.show();

            if (!files)
                files       = DOM.getSelectedFiles();

            names       = DOM.getSelectedNames(files),
            n           = names && names.length;

            if (!n)
                names   = [Info.name];

            deleteFn(path + query, names, function() {
                var Storage     = DOM.Storage,
                    dirPath     = Info.dirPath,
                    dir         = rmLastSlash(dirPath);

                if (n > 1)
                    DOM.deleteSelected(files);
                else
                    DOM.deleteCurrent(current);

                Storage.removeMatch(dir);
            });
        }

        /*
         * process files (copy or move)
         * @param data
         * @param operation
         */
        function processFiles(data, operation, message) {
             var name, files,
                Info        = DOM.CurrentInfo,
                panel,
                shouldAsk,
                sameName,
                ok,
                tmpl        = '"{{ name }}" already exist. Overwrite?',

                from        = '',
                to          = '',

                names       = [];

            if (data) {
                from        = data.from;
                to          = data.to;
                names       = data.names;
                panel       = Info.panel;
            } else {
                from        = Info.dirPath;
                to          = DOM.getNotCurrentDirPath();
                names       = DOM.getSelectedNames();
                data        = {};
                shouldAsk   = true;
                panel       = Info.panelPassive;
            }

            if (!names.length)
                names.push(DOM.getCurrentName());

            name    = names[0];

            sameName    = !!DOM.getCurrentByName(name, panel);

            if (name === '..') {
                Dialog.alert('No files selected!');
            } else {
                if (shouldAsk)
                    to = message(to, names);

                ok = from !== to && to;

                if (ok && shouldAsk && sameName)
                    ok = Dialog.confirm(rendy(tmpl, {
                        name: name
                    }));

                if (ok) {
                    Images.show.load('top');

                    files   = {
                        from    : from,
                        to      : to,
                        names   : names
                    };

                    operation(files, function() {
                        var path = rmLastSlash(from);

                        DOM.Storage.remove(path, function() {
                            var panel           = Info.panel,
                                panelPassive    = Info.panelPassive,
                                setCurrent      = function() {
                                    var current;

                                    if (!name)
                                        name = data.names[0];

                                    current = DOM.getCurrentByName(name);
                                    DOM.setCurrentFile(current);
                                };

                            if (!Info.isOnePanel)
                                CloudCmd.refresh(panelPassive, {
                                    noCurrent: true
                                });

                            CloudCmd.refresh(panel, setCurrent);
                        });
                    });
                }
            }
        }

        function message(msg) {
            return function(to, names) {
                var ret,
                    n       = names.length,
                    name    = names[0];

                msg += ' ';

                if (names.length > 1)
                    msg     += n + ' file(s)';
                else
                    msg     += '"' + name + '"';

                msg         += ' to';

                ret = Dialog.prompt(msg, to);

                return ret;
            };
        }

        function load(callback) {
            var files = [
                '/spero/spero.js',
                '/remedy/remedy.js'
            ];

            DOM.load.parallel(files, function(error) {
                if (error) {
                    Dialog.alert(error.message);
                } else {
                    Loaded = true;
                    Util.timeEnd(Name + ' load');
                    Util.exec(callback);
                }
            });

            Util.time(Name + ' load');
        }

        init();
    }

})(CloudCmd, Util, DOM, rendy);
<commit_msg>fix(operation) loading image<commit_after>/* global CloudCmd */
/* global Util */
/* global DOM */
/* global rendy */
/* global spero */
/* global remedy */

(function(CloudCmd, Util, DOM, rendy) {
    'use strict';

    CloudCmd.Operation = OperationProto;

    function OperationProto(operation, data) {
        var Name        = 'Operation',
            Loaded,
            RESTful     = DOM.RESTful,

            copyFn      = RESTful.cp,
            moveFn      = RESTful.mv,
            deleteFn    = RESTful.delete,

            Images      = DOM.Images,
            Dialog      = DOM.Dialog,

            showLoad    = Images.show.load.bind(null, 'top'),

            Operation   = this;

        function rmLastSlash(str) {
            return str.replace(/\/$/, '');
        }

        function init() {
            showLoad();

            Util.exec.series([
                DOM.loadSocket,
                function(callback) {
                    var Files = DOM.Files;

                    Files.get('config', function(error, config) {
                        if (error)
                            alert(error);
                        else if (config.progress)
                            load(function() {
                                create(callback);
                            });
                        else
                            callback();
                    });
                },
                function() {
                    Loaded = true;
                    Images.hide();
                    Operation.show(operation, data);
                }
            ]);
        }

        function create(callback) {
            spero(function() {
                 spero.on('connect', function() {
                    copyFn = function(data, callback) {
                        setListeners(spero, callback);
                        spero.copy(data.from, data.to, data.names);
                    };
                });

                spero.on('disconnect', function() {
                    copyFn = DOM.RESTful.cp;
                });
            });

            remedy(function() {
                 remedy.on('connect', function() {
                    deleteFn = function(from, files, callback) {
                        from = from.replace(/\?.*/, '');

                        setListeners(remedy, callback);
                        remedy.remove(from, files);
                    };
                });

                remedy.on('disconnect', function() {
                    deleteFn = DOM.RESTful.remove;
                });
            });

            Util.exec(callback);
        }

        function setListeners(emitter, callback) {
            var wasError,
                listeners = {
                    progress: function(value) {
                        Images.setProgress(value);
                    },

                    end: function() {
                        if (!wasError)
                            callback();

                        Images
                            .hide()
                            .clearProgress();

                        events.forEach(function(name) {
                            emitter.removeListener(name, listeners[name]);
                        });
                    },

                    error: function(error) {
                        var msg = error + '\n Continue?',
                            is = confirm(msg);

                        if (is) {
                            emitter.continue();
                        } else {
                            wasError = true;
                            emitter.abort();
                        }
                    }
            },
            events = Object.keys(listeners);

            events.forEach(function(name) {
                emitter.on(name, listeners[name]);
            });
        }

        this.hide   = function() {
            CloudCmd.View.hide();
        };

        this.show = function(operation, data) {
            if (Loaded)
                switch(operation) {
                case 'copy':
                    Operation.copy(data);
                    break;

                case 'move':
                    Operation.move(data);
                    break;

                case 'delete':
                    Operation.delete();
                    break;

                case 'delete:silent':
                    Operation.deleteShift();
                }
        };

        this.copy           = function(data) {
            processFiles(data, copyFn, message('Copy'));
        };

        this.move           = function(data) {
            processFiles(data, moveFn, message('Rename/Move'));
        };

        this.delete         = function() {
            promptDelete();
        };

        this.deleteSilent   = function() {
            deleteSilent();
        };

         /**
         * prompt and delete current file or selected files
         *
         * @currentFile
         */
        function promptDelete() {
            var ret, type, isDir, msg,
                name        = '',
                msgAsk      = 'Do you really want to delete the ',
                msgSel      = 'selected ',
                files       = DOM.getSelectedFiles(),
                names       = DOM.getSelectedNames(files),
                i, n        = names && names.length,
                current     = DOM.getCurrentFile();

            if (n) {
                for (i = 0; i < 5 && i < n; i++)
                    name += '\n' + names[i];

                if (n >= 5)
                    name   += '\n...';

                msg    = msgAsk + msgSel + n + ' files/directoris?\n' + name ;
            } else {
                isDir       = DOM.isCurrentIsDir(current);

                if (isDir)
                    type    = 'directory';
                else
                    type    = 'file';

                 type += ' ';

                name   = DOM.getCurrentName(current);
                msg    = msgAsk + msgSel + type + name + '?';
            }

            if (name !== '..')
                ret  = Dialog.confirm(msg);
            else
                Dialog.alert('No files selected!');

            if (ret)
                deleteSilent(files);

            return ret;
        }

        /**
         * delete current or selected files
         *
         * @files
         */
        function deleteSilent(files) {
            var n, names,
                query       = '?files',
                Info        = DOM.CurrentInfo,
                path        = Info.dirPath,
                current     = Info.element;

            showLoad();

            if (!files)
                files       = DOM.getSelectedFiles();

            names       = DOM.getSelectedNames(files),
            n           = names && names.length;

            if (!n)
                names   = [Info.name];

            deleteFn(path + query, names, function() {
                var Storage     = DOM.Storage,
                    dirPath     = Info.dirPath,
                    dir         = rmLastSlash(dirPath);

                if (n > 1)
                    DOM.deleteSelected(files);
                else
                    DOM.deleteCurrent(current);

                Storage.removeMatch(dir);
            });
        }

        /*
         * process files (copy or move)
         * @param data
         * @param operation
         */
        function processFiles(data, operation, message) {
             var name, files,
                Info        = DOM.CurrentInfo,
                panel,
                shouldAsk,
                sameName,
                ok,
                tmpl        = '"{{ name }}" already exist. Overwrite?',

                from        = '',
                to          = '',

                names       = [];

            if (data) {
                from        = data.from;
                to          = data.to;
                names       = data.names;
                panel       = Info.panel;
            } else {
                from        = Info.dirPath;
                to          = DOM.getNotCurrentDirPath();
                names       = DOM.getSelectedNames();
                data        = {};
                shouldAsk   = true;
                panel       = Info.panelPassive;
            }

            if (!names.length)
                names.push(DOM.getCurrentName());

            name    = names[0];

            sameName    = !!DOM.getCurrentByName(name, panel);

            if (name === '..') {
                Dialog.alert('No files selected!');
            } else {
                if (shouldAsk)
                    to = message(to, names);

                ok = from !== to && to;

                if (ok && shouldAsk && sameName)
                    ok = Dialog.confirm(rendy(tmpl, {
                        name: name
                    }));

                if (ok) {
                    showLoad();

                    files   = {
                        from    : from,
                        to      : to,
                        names   : names
                    };

                    operation(files, function() {
                        var path = rmLastSlash(from);

                        DOM.Storage.remove(path, function() {
                            var panel           = Info.panel,
                                panelPassive    = Info.panelPassive,
                                setCurrent      = function() {
                                    var current;

                                    if (!name)
                                        name = data.names[0];

                                    current = DOM.getCurrentByName(name);
                                    DOM.setCurrentFile(current);
                                };

                            if (!Info.isOnePanel)
                                CloudCmd.refresh(panelPassive, {
                                    noCurrent: true
                                });

                            CloudCmd.refresh(panel, setCurrent);
                        });
                    });
                }
            }
        }

        function message(msg) {
            return function(to, names) {
                var ret,
                    n       = names.length,
                    name    = names[0];

                msg += ' ';

                if (names.length > 1)
                    msg     += n + ' file(s)';
                else
                    msg     += '"' + name + '"';

                msg         += ' to';

                ret = Dialog.prompt(msg, to);

                return ret;
            };
        }

        function load(callback) {
            var files = [
                '/spero/spero.js',
                '/remedy/remedy.js'
            ];

            DOM.load.parallel(files, function(error) {
                if (error) {
                    Dialog.alert(error.message);
                } else {
                    Loaded = true;
                    Util.timeEnd(Name + ' load');
                    Util.exec(callback);
                }
            });

            Util.time(Name + ' load');
        }

        init();
    }

})(CloudCmd, Util, DOM, rendy);
<|endoftext|>


<commit_before>// Copyright & License details are available under JXCORE_LICENSE file

var fs = require('fs');
var path = require('path');
var jxtools = require('jxtools');
var fname = 'io.jxcore.node.jx';
var dname = 'io.jxcore.node';

var unpack = function (cb) {

  var commands = [];

  var folder = path.join(process.cwd(), dname);
  if (fs.existsSync(folder)) {
    commands.push({
      name: 'remove_plugin',
      command: 'cordova plugins remove ' + dname,
      caption: 'Removing plugin from project...',
      skip_error: true
    });
    commands.push({
      name: 'remove_dir',
      command: jxtools.fs.getRmdirCommand(folder),
      caption: 'Removing previous plugin\'s folder...'
    });
  }

  // extract package
  commands.push({
    name: 'extract',
    command: process.execPath + ' ' + fname,
    caption: 'Extracting plugin package...'
  });

  // add plugin
  commands.push({
    name: 'add_plugin',
    command: 'cordova plugins add ' + dname,
    caption: 'Adding plugin to project...'
  });

  jxtools.fs.execMultiple(commands, function (ret) {
    if (ret.errors)
      jxcore.utils.console.error(ret.errors);
    else
      jxcore.utils.console.info("OK");
  });
};

exports.run = function (cb) {

  var localFile = path.join(process.cwd(), fname);

  var parsedArgv = jxcore.utils.argv.parse();

  if (fs.existsSync(localFile) && !parsedArgv.force) {
    jxcore.utils.console.warn('Skipping the download, since file', fname, 'already exists.');
    jxcore.utils.console.log('If you want to force downloading, use --force option.');
    unpack(cb);
    return;
  }

  var url = 'https://raw.githubusercontent.com/jxcore/jxcore-cordova-release/master/0.0.5/' + fname;
  jxtools.http.download(url, fname, function (err) {
    if (!err)
      unpack(cb);
  });

};<commit_msg>wrap in quotes<commit_after>// Copyright & License details are available under JXCORE_LICENSE file

var fs = require('fs');
var path = require('path');
var jxtools = require('jxtools');
var fname = 'io.jxcore.node.jx';
var dname = 'io.jxcore.node';

var unpack = function (cb) {

  var commands = [];

  var folder = path.join(process.cwd(), dname);
  if (fs.existsSync(folder)) {
    commands.push({
      name: 'remove_plugin',
      command: 'cordova plugins remove ' + dname,
      caption: 'Removing plugin from project...',
      skip_error: true
    });
    commands.push({
      name: 'remove_dir',
      command: jxtools.fs.getRmdirCommand(folder),
      caption: 'Removing previous plugin\'s folder...'
    });
  }

  // extract package
  commands.push({
    name: 'extract',
    command: '"' + process.execPath + '" ' + fname,
    caption: 'Extracting plugin package...'
  });

  // add plugin
  commands.push({
    name: 'add_plugin',
    command: 'cordova plugins add ' + dname,
    caption: 'Adding plugin to project...'
  });

  jxtools.fs.execMultiple(commands, function (ret) {
    if (ret.errors)
      jxcore.utils.console.error(ret.errors);
    else
      jxcore.utils.console.info("OK");
  });
};

exports.run = function (cb) {

  var localFile = path.join(process.cwd(), fname);

  var parsedArgv = jxcore.utils.argv.parse();

  if (fs.existsSync(localFile) && !parsedArgv.force) {
    jxcore.utils.console.warn('Skipping the download, since file', fname, 'already exists.');
    jxcore.utils.console.log('If you want to force downloading, use --force option.');
    unpack(cb);
    return;
  }

  var url = 'https://raw.githubusercontent.com/jxcore/jxcore-cordova-release/master/0.0.5/' + fname;
  jxtools.http.download(url, fname, function (err) {
    if (!err)
      unpack(cb);
  });

};<|endoftext|>


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

var Vow = require('vow');
var Table = require('cli-table');
var prompt = require('prompt');
var chalk = require('chalk');
var assign = require('lodash.assign');

var Checker = require('../checker');
var utils = require('../utils');

prompt.message = '';
prompt.delimiter = '';
prompt.start();

/**
 * Script that walks the user through the autoconfig flow
 *
 * @type {String[]}
 * @private
 */
var prompts = [
    {
        name: chalk.green('Please choose a preset number:'),
        require: true,
        pattern: /\d+/
    },
    {
        name: 'Create an (e)xception for this rule, or (f)ix the errors yourself?',
        require: true,
        pattern: /(e|f)/
    }
];

/**
 * JSCS Configuration Generator
 *
 * @name Generator
 */
function Generator() {
    this._config = {};
}

/**
 * Generates a configuration object based for the given path
 * based on the best fitting preset
 *
 * @param  {String} path - The path containing file(s) used to guide the configuration
 *
 * @return {Promise} Resolved with the generated, JSCS configuration
 */
Generator.prototype.generate = function(path) {
    var checker = getChecker();
    var _path = utils.normalizePath(path, checker.getConfiguration().getBasePath());
    var presetNames = Object.keys(checker.getConfiguration().getRegisteredPresets());
    var statsForPresets;

    console.log('Checking', _path, 'against the presets');

    return Vow
    .all(presetNames.map(this._checkAgainstPreset.bind(this, _path)))
    .then(function(resultsPerPreset) {
        statsForPresets = this._generateStatsForPresets(resultsPerPreset, presetNames);
        return statsForPresets;
    }.bind(this))
    .then(this._showErrorCounts.bind(this))
    .then(this._getUserPresetChoice.bind(this, prompts[0]))
    .then(function showViolatedRules(choiceObj) {
        var presetIndex = choiceObj[prompts[0].name] - 1;
        var presetName = statsForPresets[presetIndex].name;

        console.log('You chose the ' + presetName + ' preset');

        this._config.preset = presetName;

        var errorList = statsForPresets[presetIndex].errors;
        errorList = getUniqueErrorNames(errorList);

        var violatedRuleCount = errorList.length;

        if (!violatedRuleCount) { return this._config; }

        console.log(_path + ' violates ' + violatedRuleCount + ' rule' + (violatedRuleCount > 1 ? 's' : ''));

        var errorPrompts = generateRuleHandlingPrompts(errorList);

        return this._getUserViolationChoices(errorPrompts)
        .then(this._handleViolatedRules.bind(this, errorPrompts, errorList))
        .then(function() {
            return this._config;
        }.bind(this));
    }.bind(this))
    .then(function flushConfig() {
        fs.writeFileSync(process.cwd() + '/.jscsrc', JSON.stringify(this._config, null, '\t'));
        console.log('Generated a .jscsrc configuration file in ' + process.cwd());
    }.bind(this));
};

/**
 * @private
 * @param  {Object[][]} resultsPerPreset - List of error objects for each preset's run of checkPath
 * @param  {String[]} presetNames
 * @return {Object[]} Aggregated datapoints for each preset
 */
Generator.prototype._generateStatsForPresets = function(resultsPerPreset, presetNames) {
    return resultsPerPreset.map(function(presetResults, idx) {
        var errorCollection = [].concat.apply([], presetResults);

        var presetStats = {
            name: presetNames[idx],
            sum: 0,
            errors: []
        };

        errorCollection.forEach(function(error) {
            presetStats.sum += error.getErrorCount();
            presetStats.errors = presetStats.errors.concat(error.getErrorList());
        });

        return presetStats;
    });
};

/**
 * @private
 * @param  {Object[]} statsForPresets
 */
Generator.prototype._showErrorCounts = function(statsForPresets) {
    var table = getTable();

    statsForPresets.forEach(function(presetStats, idx) {
        table.push([idx + 1, presetStats.name, presetStats.sum]);
    });

    console.log(table.toString());
};

/**
 * Prompts the user to choose a preset
 *
 * @private
 * @param {Object} prompt
 * @return {Promise}
 */
Generator.prototype._getUserPresetChoice = function(prompt) {
    return this._showPrompt(prompt);
};

/**
 * Prompts the user to nullify rules or fix violations themselves
 *
 * @private
 * @param  {Object[]} errorPrompts
 * @return {Promise}
 */
Generator.prototype._getUserViolationChoices = function(errorPrompts) {
    return this._showPrompt(errorPrompts);
};

/** @private */
Generator.prototype._showPrompt = utils.promisify(prompt.get.bind(prompt));

/**
 * @private
 * @param  {Object[]} errorPrompts
 * @param  {String[]} errorList
 * @param  {Object[]} choices
 */
Generator.prototype._handleViolatedRules = function(errorPrompts, errorList, choices) {
    errorPrompts.forEach(function(errorPrompt, idx) {
        var associatedRuleName = errorList[idx];
        var userChoice = choices[errorPrompt.name];

        if (userChoice.toLowerCase() === 'e') {
            this._config[associatedRuleName] = null;
        }
    }, this);
};

/**
 * @private
 * @param  {String} path
 * @param  {String} presetName
 * @return {Promise}
 */
Generator.prototype._checkAgainstPreset = function(path, presetName) {
    var checker = getChecker();

    checker.configure({preset: presetName});

    return checker.checkPath(path);
};

/**
 * @private
 * @return {lib/Checker}
 */
function getChecker() {
    var checker = new Checker();
    checker.registerDefaultRules();
    return checker;
}

/**
 * @private
 * @param  {String[]} violatedRuleNames
 * @return {Object[]}
 */
function generateRuleHandlingPrompts(violatedRuleNames) {
    return violatedRuleNames.map(function(ruleName) {
        var prompt = assign({}, prompts[1]);
        prompt.name = chalk.green(ruleName) + ': ' + prompt.name;
        return prompt;
    });
}

/**
 * @private
 * @param  {Object[]} errorsList
 * @return {String[]}
 */
function getUniqueErrorNames(errorsList) {
    var errorNameLUT = {};

    errorsList.forEach(function(error) {
        errorNameLUT[error.rule] = true;
    });

    return Object.keys(errorNameLUT);
}

/**
 * @private
 * @return {Object}
 */
function getTable() {
    return new Table({
        chars: {
            top: '', 'top-mid': '', 'top-left': '', 'top-right': '',
            bottom: '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '',
            left: '', 'left-mid': '',
            mid: '', 'mid-mid': '',
            right: '', 'right-mid': '' ,
            middle: ' '
        },
        style: {
            'padding-left': 0,
            'padding-right': 0
        },
        head: ['', 'Preset', '#Errors']
    });
}

module.exports = Generator;
<commit_msg>Configuration: show number of violated rules when using auto-configuration<commit_after>var fs = require('fs');

var Vow = require('vow');
var Table = require('cli-table');
var prompt = require('prompt');
var chalk = require('chalk');
var assign = require('lodash.assign');

var Checker = require('../checker');
var utils = require('../utils');

prompt.message = '';
prompt.delimiter = '';
prompt.start();

/**
 * Script that walks the user through the autoconfig flow
 *
 * @type {String[]}
 * @private
 */
var prompts = [
    {
        name: chalk.green('Please choose a preset number:'),
        require: true,
        pattern: /\d+/
    },
    {
        name: 'Create an (e)xception for this rule, or (f)ix the errors yourself?',
        require: true,
        pattern: /(e|f)/
    }
];

/**
 * JSCS Configuration Generator
 *
 * @name Generator
 */
function Generator() {
    this._config = {};
}

/**
 * Generates a configuration object based for the given path
 * based on the best fitting preset
 *
 * @param  {String} path - The path containing file(s) used to guide the configuration
 *
 * @return {Promise} Resolved with the generated, JSCS configuration
 */
Generator.prototype.generate = function(path) {
    var checker = getChecker();
    var _path = utils.normalizePath(path, checker.getConfiguration().getBasePath());
    var presetNames = Object.keys(checker.getConfiguration().getRegisteredPresets());
    var statsForPresets;

    console.log('Checking', _path, 'against the presets');

    return Vow
    .all(presetNames.map(this._checkAgainstPreset.bind(this, _path)))
    .then(function(resultsPerPreset) {
        statsForPresets = this._generateStatsForPresets(resultsPerPreset, presetNames);
        return statsForPresets;
    }.bind(this))
    .then(this._showErrorCounts.bind(this))
    .then(this._getUserPresetChoice.bind(this, prompts[0]))
    .then(function showViolatedRules(choiceObj) {
        var presetIndex = choiceObj[prompts[0].name] - 1;
        var presetName = statsForPresets[presetIndex].name;

        console.log('You chose the ' + presetName + ' preset');

        this._config.preset = presetName;

        var errorList = statsForPresets[presetIndex].errors;
        errorList = getUniqueErrorNames(errorList);

        var violatedRuleCount = errorList.length;

        if (!violatedRuleCount) { return this._config; }

        console.log(_path + ' violates ' + violatedRuleCount + ' rule' + (violatedRuleCount > 1 ? 's' : ''));

        var errorPrompts = generateRuleHandlingPrompts(errorList);

        return this._getUserViolationChoices(errorPrompts)
        .then(this._handleViolatedRules.bind(this, errorPrompts, errorList))
        .then(function() {
            return this._config;
        }.bind(this));
    }.bind(this))
    .then(function flushConfig() {
        fs.writeFileSync(process.cwd() + '/.jscsrc', JSON.stringify(this._config, null, '\t'));
        console.log('Generated a .jscsrc configuration file in ' + process.cwd());
    }.bind(this));
};

/**
 * @private
 * @param  {Object[][]} resultsPerPreset - List of error objects for each preset's run of checkPath
 * @param  {String[]} presetNames
 * @return {Object[]} Aggregated datapoints for each preset
 */
Generator.prototype._generateStatsForPresets = function(resultsPerPreset, presetNames) {
    return resultsPerPreset.map(function(presetResults, idx) {
        var errorCollection = [].concat.apply([], presetResults);

        var presetStats = {
            name: presetNames[idx],
            sum: 0,
            errors: []
        };

        errorCollection.forEach(function(error) {
            presetStats.sum += error.getErrorCount();
            presetStats.errors = presetStats.errors.concat(error.getErrorList());
        });

        return presetStats;
    });
};

/**
 * @private
 * @param  {Object[]} statsForPresets
 */
Generator.prototype._showErrorCounts = function(statsForPresets) {
    var table = getTable();

    statsForPresets.forEach(function(presetStats, idx) {
        table.push([idx + 1, presetStats.name, presetStats.sum, getUniqueErrorNames(presetStats.errors).length]);
    });

    console.log(table.toString());
};

/**
 * Prompts the user to choose a preset
 *
 * @private
 * @param {Object} prompt
 * @return {Promise}
 */
Generator.prototype._getUserPresetChoice = function(prompt) {
    return this._showPrompt(prompt);
};

/**
 * Prompts the user to nullify rules or fix violations themselves
 *
 * @private
 * @param  {Object[]} errorPrompts
 * @return {Promise}
 */
Generator.prototype._getUserViolationChoices = function(errorPrompts) {
    return this._showPrompt(errorPrompts);
};

/** @private */
Generator.prototype._showPrompt = utils.promisify(prompt.get.bind(prompt));

/**
 * @private
 * @param  {Object[]} errorPrompts
 * @param  {String[]} errorList
 * @param  {Object[]} choices
 */
Generator.prototype._handleViolatedRules = function(errorPrompts, errorList, choices) {
    errorPrompts.forEach(function(errorPrompt, idx) {
        var associatedRuleName = errorList[idx];
        var userChoice = choices[errorPrompt.name];

        if (userChoice.toLowerCase() === 'e') {
            this._config[associatedRuleName] = null;
        }
    }, this);
};

/**
 * @private
 * @param  {String} path
 * @param  {String} presetName
 * @return {Promise}
 */
Generator.prototype._checkAgainstPreset = function(path, presetName) {
    var checker = getChecker();

    checker.configure({preset: presetName});

    return checker.checkPath(path);
};

/**
 * @private
 * @return {lib/Checker}
 */
function getChecker() {
    var checker = new Checker();
    checker.registerDefaultRules();
    return checker;
}

/**
 * @private
 * @param  {String[]} violatedRuleNames
 * @return {Object[]}
 */
function generateRuleHandlingPrompts(violatedRuleNames) {
    return violatedRuleNames.map(function(ruleName) {
        var prompt = assign({}, prompts[1]);
        prompt.name = chalk.green(ruleName) + ': ' + prompt.name;
        return prompt;
    });
}

/**
 * @private
 * @param  {Object[]} errorsList
 * @return {String[]}
 */
function getUniqueErrorNames(errorsList) {
    var errorNameLUT = {};

    errorsList.forEach(function(error) {
        errorNameLUT[error.rule] = true;
    });

    return Object.keys(errorNameLUT);
}

/**
 * @private
 * @return {Object}
 */
function getTable() {
    return new Table({
        chars: {
            top: '', 'top-mid': '', 'top-left': '', 'top-right': '',
            bottom: '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '',
            left: '', 'left-mid': '',
            mid: '', 'mid-mid': '',
            right: '', 'right-mid': '' ,
            middle: ' '
        },
        style: {
            'padding-left': 0,
            'padding-right': 0
        },
        head: ['', 'Preset', '#Errors', '#Rules']
    });
}

module.exports = Generator;
<|endoftext|>


<commit_before>var fs = require('fs'),
    async = require('async'),
    node2browser = require('node2browser'),
    makeDir = require('fshelpers').makeDir,
    pathUtil = require('path'),
    services = require('./services.js').services,
    validators = require('./validators.js').validators,
    paths = require('./paths.js'),
    settings = require('./settings'),
    modifyPathsInHTML = require('../tools/modifyPathsInHTML.js');

var templateRegExp;

function compilePage(url, callback) {
    var src = '',
        translatedSrc = '',
        knownFiles = [],
        viewFiles = [],
        pathModifier = paths.getPathModifier(
            ['noAlamidFiles', 'noServerFiles'],
            ['nodeModules']
        ),
        wrappedPathModifier = function wrappedPathModifier(path) { // the wrapped path modifier is necessary to
            if (knownFiles.indexOf(path) === -1) {                 // prevent additional calls of node2browser.translate
                return pathModifier(path);                         // from adding files to the source code that are
            } else {                                               // already known
                return false;
            }
        };

    function translateFilePath(filePath) {
        var fileName;

        filePath = filePath.replace(paths.patterns.classes(), '');
        filePath = filePath.split('/');
        fileName = filePath.pop();
        fileName = fileName.charAt(0).toLowerCase() +
            fileName.substr(1);
        filePath.push(fileName);
        filePath = filePath.join('/');

        return filePath;
    }

    function collectCorrespondingFiles(files, callback) {
        var filesToTranslate = [],
            filePath,
            fileToTranslate,
            i, l;

        for (i = 0, l = files.length; i < l; i++) {
            filePath = files[i];
            knownFiles.push(filePath);
            if (filePath.search(paths.appModels) !== -1) {
                filePath = filePath.replace(paths.appModels, '');
                filePath = translateFilePath(filePath);
                fileToTranslate = paths.appServices + filePath + '.client.js';
                if (services.client[fileToTranslate]) {
                    filesToTranslate.push(fileToTranslate);
                }
                fileToTranslate = paths.appValidators + filePath + '.client.js';
                if (validators.client[fileToTranslate]) {
                    filesToTranslate.push(fileToTranslate);
                }
            } else if (templateRegExp.test(filePath)) {    // IF TRUE: Its a view or page class that has a template file
                viewFiles.push(filePath);
            }
        }

        if (filesToTranslate.length > 0) {
            translateFiles(filesToTranslate, callback);
        } else {
            callback();
        }
    }

    function reduceKnownFiles(requiredFiles) {
        var reduced = [],
            item,
            i, l;

        for (i = 0, l = requiredFiles.length; i < l; i++) {
            item = requiredFiles[i];
            if (knownFiles.indexOf(item) === -1) {
                reduced.push(item);
            }
        }

        return reduced;
    }

    function translateFiles(files, callback) {
        node2browser.translate(
            files,
            wrappedPathModifier,
            function onFilesTranslated(err, translated, requiredFiles) {
                if (err) throw err;
                translatedSrc += translated;
                requiredFiles = reduceKnownFiles(requiredFiles);
                collectCorrespondingFiles(requiredFiles, callback);  // recursive call to check for recently added models
            }
        );
    }

    function setTemplates(templates, callback) {
        var i,
            template,
            pageURL,
            pathModifier = paths.getPathModifier(
                null,
                ['nodeModules']
            );

        for (i = 0; i < templates.length; i++) {
            template = templates[i];
            if (template) { // Its possible that there is no template, so we do nothing in this case
                template = template
                    .replace(/'/g, "\\'")   // escape single quotes
                    .replace(/(\r\n)|[\r\n]/g, '\\n');   // escape line breaks
                template = modifyPathsInHTML(template, settings.basePath);
                pageURL = viewFiles[i];
                pageURL = pathModifier(pageURL);
                src += "window.modules['node_modules/alamid/templates.js'].setTemplate('" +
                    pageURL + "', '"+ template + "');";
            }
        }
        src += translatedSrc;
        callback();
    }

    function loadTemplates(callback) {
        async.map(viewFiles, function loadTemplate(path, callback) {
            var fileName;

            fileName = pathUtil.basename(path);
            path = path.substr(0, path.length - fileName.length);
            fileName = fileName.charAt(0).toLowerCase() +
                fileName.substr(1, fileName.length - '.class.js'.length) +
                'html';
            path = path.substr(paths.appCompiledPath.length);
            path = paths.appHTML + path + fileName;
            fs.readFile(path, 'utf8', callback);
        }, function onTemplatesLoaded(err, templates) {
            if (err) throw err;
            setTemplates(templates, callback);
        });
    }

    function translateFilesAndLoadTemplates(firstFilesToTranslate, callback) {
        async.series([
            async.apply(translateFiles, firstFilesToTranslate),
            loadTemplates
        ], callback);
    }

    function prepareFileContentsAndDirectories(firstFilesToTranslate, targetPath, callback) {
        async.parallel([
            async.apply(translateFilesAndLoadTemplates, firstFilesToTranslate),
            async.apply(makeDir, pathUtil.dirname(targetPath))
        ], callback);
    }

    function main() {
        var pageName,
            pagePath,
            modulePath,
            targetPath,
            pathToClientService,
            firstFilesToTranslate = [];

        if (url.charAt(0) !== '/') {
            url = '/' + url;
        }
        console.log('compiling page ' + url);

        // Initialize path vars
        templateRegExp = new RegExp(paths.appCompiledPath + '\\/(views|pages)\\/.*\\.class\\.js$', 'i');
        pageName = pathUtil.basename(url);
        pagePath = pathUtil.dirname(url);
        modulePath = paths.appCompiledPath +
            pagePath + '/' +
            pageName.charAt(0).toUpperCase() +      // capitalize the pageName
            pageName.substr(1) + '.class.js';
        modulePath = pathUtil.normalize(modulePath);
        targetPath = paths.appCache + url + '.js';
        targetPath = pathUtil.normalize(targetPath);
        pathToClientService = paths.appServices + url + ".client.js";
        firstFilesToTranslate[0] = modulePath;
        if (services[pathToClientService]) { // IF TRUE: There is a client page service
            firstFilesToTranslate[1] = pathToClientService;
        }

        async.series([
            async.apply(prepareFileContentsAndDirectories, firstFilesToTranslate, targetPath),
            function writeFile(callback) {  // async.apply doesn't work here for some strange reason
                fs.writeFile(targetPath, src, 'utf8', callback);
            }
        ], function finished(err) {
            callback(err, src);
        });
    }

    main(); // init process
}

module.exports = compilePage;<commit_msg>changed view and pages regexp<commit_after>var fs = require('fs'),
    async = require('async'),
    node2browser = require('node2browser'),
    makeDir = require('fshelpers').makeDir,
    pathUtil = require('path'),
    services = require('./services.js').services,
    validators = require('./validators.js').validators,
    paths = require('./paths.js'),
    settings = require('./settings'),
    modifyPathsInHTML = require('../tools/modifyPathsInHTML.js');

var templateRegExp;

function compilePage(url, callback) {
    var src = '',
        translatedSrc = '',
        knownFiles = [],
        viewFiles = [],
        pathModifier = paths.getPathModifier(
            ['noAlamidFiles', 'noServerFiles'],
            ['nodeModules']
        ),
        wrappedPathModifier = function wrappedPathModifier(path) { // the wrapped path modifier is necessary to
            if (knownFiles.indexOf(path) === -1) {                 // prevent additional calls of node2browser.translate
                return pathModifier(path);                         // from adding files to the source code that are
            } else {                                               // already known
                return false;
            }
        };

    function translateFilePath(filePath) {
        var fileName;

        filePath = filePath.replace(paths.patterns.classes(), '');
        filePath = filePath.split('/');
        fileName = filePath.pop();
        fileName = fileName.charAt(0).toLowerCase() +
            fileName.substr(1);
        filePath.push(fileName);
        filePath = filePath.join('/');

        return filePath;
    }

    function collectCorrespondingFiles(files, callback) {
        var filesToTranslate = [],
            filePath,
            fileToTranslate,
            i, l;

        for (i = 0, l = files.length; i < l; i++) {
            filePath = files[i];
            knownFiles.push(filePath);
            if (filePath.search(paths.appModels) !== -1) {
                filePath = filePath.replace(paths.appModels, '');
                filePath = translateFilePath(filePath);
                fileToTranslate = paths.appServices + filePath + '.client.js';
                if (services.client[fileToTranslate]) {
                    filesToTranslate.push(fileToTranslate);
                }
                fileToTranslate = paths.appValidators + filePath + '.client.js';
                if (validators.client[fileToTranslate]) {
                    filesToTranslate.push(fileToTranslate);
                }
            } else if (templateRegExp.test(filePath)) {    // IF TRUE: Its a view or page class that has a template file
                viewFiles.push(filePath);
            }
        }

        if (filesToTranslate.length > 0) {
            translateFiles(filesToTranslate, callback);
        } else {
            callback();
        }
    }

    function reduceKnownFiles(requiredFiles) {
        var reduced = [],
            item,
            i, l;

        for (i = 0, l = requiredFiles.length; i < l; i++) {
            item = requiredFiles[i];
            if (knownFiles.indexOf(item) === -1) {
                reduced.push(item);
            }
        }

        return reduced;
    }

    function translateFiles(files, callback) {
        node2browser.translate(
            files,
            wrappedPathModifier,
            function onFilesTranslated(err, translated, requiredFiles) {
                if (err) throw err;
                translatedSrc += translated;
                requiredFiles = reduceKnownFiles(requiredFiles);
                collectCorrespondingFiles(requiredFiles, callback);  // recursive call to check for recently added models
            }
        );
    }

    function setTemplates(templates, callback) {
        var i,
            template,
            pageURL,
            pathModifier = paths.getPathModifier(
                null,
                ['nodeModules']
            );

        for (i = 0; i < templates.length; i++) {
            template = templates[i];
            if (template) { // Its possible that there is no template, so we do nothing in this case
                template = template
                    .replace(/'/g, "\\'")   // escape single quotes
                    .replace(/(\r\n)|[\r\n]/g, '\\n');   // escape line breaks
                template = modifyPathsInHTML(template, settings.basePath);
                pageURL = viewFiles[i];
                pageURL = pathModifier(pageURL);
                src += "window.modules['node_modules/alamid/templates.js'].setTemplate('" +
                    pageURL + "', '"+ template + "');";
            }
        }
        src += translatedSrc;
        callback();
    }

    function loadTemplates(callback) {
        async.map(viewFiles, function loadTemplate(path, callback) {
            var fileName;

            fileName = pathUtil.basename(path);
            path = path.substr(0, path.length - fileName.length);
            fileName = fileName.charAt(0).toLowerCase() +
                fileName.substr(1, fileName.length - '.class.js'.length) +
                'html';
            path = path.substr(paths.appCompiledPath.length);
            path = paths.appHTML + path + fileName;
            fs.readFile(path, 'utf8', callback);
        }, function onTemplatesLoaded(err, templates) {
            if (err) throw err;
            setTemplates(templates, callback);
        });
    }

    function translateFilesAndLoadTemplates(firstFilesToTranslate, callback) {
        async.series([
            async.apply(translateFiles, firstFilesToTranslate),
            loadTemplates
        ], callback);
    }

    function prepareFileContentsAndDirectories(firstFilesToTranslate, targetPath, callback) {
        async.parallel([
            async.apply(translateFilesAndLoadTemplates, firstFilesToTranslate),
            async.apply(makeDir, pathUtil.dirname(targetPath))
        ], callback);
    }

    function main() {
        var pageName,
            pagePath,
            modulePath,
            targetPath,
            pathToClientService,
            firstFilesToTranslate = [];

        if (url.charAt(0) !== '/') {
            url = '/' + url;
        }
        console.log('compiling page ' + url);

        // Initialize path vars
        templateRegExp = /\/(views|pages)\/.+\.class\.js$/g;
        pageName = pathUtil.basename(url);
        pagePath = pathUtil.dirname(url);
        modulePath = paths.appCompiledPath +
            pagePath + '/' +
            pageName.charAt(0).toUpperCase() +      // capitalize the pageName
            pageName.substr(1) + '.class.js';
        modulePath = pathUtil.normalize(modulePath);
        targetPath = paths.appCache + url + '.js';
        targetPath = pathUtil.normalize(targetPath);
        pathToClientService = paths.appServices + url + ".client.js";
        firstFilesToTranslate[0] = modulePath;
        if (services[pathToClientService]) { // IF TRUE: There is a client page service
            firstFilesToTranslate[1] = pathToClientService;
        }

        async.series([
            async.apply(prepareFileContentsAndDirectories, firstFilesToTranslate, targetPath),
            function writeFile(callback) {  // async.apply doesn't work here for some strange reason
                fs.writeFile(targetPath, src, 'utf8', callback);
            }
        ], function finished(err) {
            callback(err, src);
        });
    }

    main(); // init process
}

module.exports = compilePage;<|endoftext|>


<commit_before>'use strict';

var utils = require('../utils');

/**
 * Config-specific merge-function which creates a new config-object
 * based on given defaults and instance config.
 *
 * @param {Object} config1
 * @param {Object} config2
 * @returns {Object} New object resulting from merging config2 to config1
 */
module.exports = function mergeConfig(config1, config2) {
  // eslint-disable-next-line no-param-reassign
  config2 = config2 || {};
  var config = {};

  utils.forEach(['url', 'method', 'params', 'data'], function valueFromInstanceConfig(prop) {
    if (typeof config2[prop] !== 'undefined') {
      config[prop] = config2[prop];
    }
  });

  utils.forEach(['headers', 'auth', 'proxy'], function mergeInstanceConfigWithDefaults(prop) {
    if (typeof config2[prop] !== 'undefined') {
      if (typeof config2[prop] === 'object') {
        config[prop] = utils.deepMerge(config1[prop], config2[prop]);
      } else {
        config[prop] = config2[prop];
      }
    } else if (typeof config1[prop] !== 'undefined') {
      config[prop] = utils.deepMerge(config1[prop]);
    }
  });

  utils.forEach([
    'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
    'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
    'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength',
    'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken'
  ], function defaultToInstanceConfig(prop) {
    config[prop] = typeof config2[prop] === 'undefined' ? config1[prop] : config2[prop];
  });

  return config;
};
<commit_msg>Slight refactor/namings/comment on mergeConfig<commit_after>'use strict';

var utils = require('../utils');

/**
 * Config-specific merge-function which creates a new config-object
 * by merging two configuration objects together.
 *
 * @param {Object} config1
 * @param {Object} config2
 * @returns {Object} New object resulting from merging config2 to config1
 */
module.exports = function mergeConfig(config1, config2) {
  // eslint-disable-next-line no-param-reassign
  config2 = config2 || {};
  var config = {};

  utils.forEach(['url', 'method', 'params', 'data'], function valueFromConfig2(prop) {
    config[prop] = config2[prop];
  });

  utils.forEach(['headers', 'auth', 'proxy'], function mergeValues(prop) {
    if (typeof config2[prop] !== 'undefined') {
      if (typeof config2[prop] === 'object') {
        config[prop] = utils.deepMerge(config1[prop], config2[prop]);
      } else {
        config[prop] = config2[prop];
      }
    } else if (typeof config1[prop] !== 'undefined') {
      config[prop] = utils.deepMerge(config1[prop]);
    }
  });

  utils.forEach([
    'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
    'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
    'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength',
    'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken'
  ], function defaultToConfig2(prop) {
    config[prop] = typeof config2[prop] === 'undefined' ? config1[prop] : config2[prop];
  });

  return config;
};
<|endoftext|>