<commit_before>
    var   cmds = require('../')
        , fs = require('graceful-fs')
        , path = require('path')
        , cmd = require('../../util/process')
        , util = require('../../util/util')

var internal = {};

exports.post_build = function(flow, config, done) {

    flow.log(3,'build - running cpp post process');

    //the post build is so that we can move the binary file
    //from the output path if needed etc, run extra scripts and so on
    var source_path = util.normalize(path.join(flow.project.paths.build, 'cpp/' + flow.project.paths.binary.source));

    flow.log(3,'build - moving binary from %s to %s', source_path, flow.project.paths.binary.full);

        if(flow.timing) console.time('build - binary copy');
    util.copy_path(flow, source_path, flow.project.paths.binary.full);
        if(flow.timing) console.timeEnd('build - binary copy');

    if(flow.target_desktop) {
        internal.post_build_desktop(flow, source_path, done);
    } else {
        internal.post_build_mobile(flow, source_path, done);
    }

} //post_build

internal.post_build_mobile = function(flow, source_path, done) {

        //run platform specific build chains
    if(flow.target == 'android') {
        internal.build_android(flow, done);
        return;
    }

        //other platforms end here
    if(done) {
        done();
    }

} //post_build_mobile

    //runs ant, and such
internal.build_android = function(flow, done) {

    //handle ability to compile store build, vs debug test build
    var build_type = flow.project.prepared.source.project.app.mobile.android.build_type;

        //where to build from
    var project_root = path.join(flow.project.paths.build, flow.config.build.android.project);
        //a build file to remove
    var build_meta_file = path.join(project_root,'bin/build.prop');

        //remove build meta data to ensure build happens
    if(fs.existsSync(build_meta_file)) {
        fs.unlinkSync(build_meta_file);
    }

    var args = [build_type];
    var opt = {
        cwd: project_root,
        quiet:false
    }

            if(flow.timing) console.time('build - android - ant');

    cmd.exec(flow, flow.config.build.android.ant_path, args, opt, function(code,out,err){

            if(flow.timing) console.timeEnd('build - android - ant');

        if(code != 0) {
            flow.log(1,'build - android - stopping because ant failed to build, exit code %d', code);
            return flow.project.failed = true;
        }

            //now move the apk out into the user bin folder
        var apk_name = flow.project.prepared.source.project.app.name + '-' + build_type + '.apk';
        var apk_path = path.join(project_root, 'bin/' + apk_name);
        var apk_dest = path.join(flow.project.paths.output, apk_name);

            if(flow.timing) console.time('build - apk copy');
        util.copy_path(flow, apk_path, apk_dest);
            if(flow.timing) console.timeEnd('build - apk copy');

        if(done) {
            done(code,out,err);
        }

    });

} //build_android

internal.post_build_desktop = function(flow, source_path, done) {

    if(flow.system == 'mac' || flow.system == 'linux') {

                if(flow.timing) console.time('build - binary chmod');

        cmd.exec(flow, 'chmod', ['+x',flow.project.paths.binary.full], {quiet:true}, function(code,out,err){

                if(flow.timing) console.timeEnd('build - binary chmod');

            if(done) {
                done(code,out,err);
            }

        }); //exec

    } else {

        if(done) {
            done();
        }

    }

} //post_build_desktop

exports.post_haxe = function(flow, config, done) {

    flow.log(2, 'android specifics', flow.project.prepared.source.project.app.mobile.android);

            if(flow.timing) console.time('build - hxcpp');

    var cpp_path = path.join(flow.project.paths.build, 'cpp/');
        cpp_path = path.resolve(flow.run_path, cpp_path);

    exports.build_hxcpp(flow, config, cpp_path, function(err) {

            if(flow.timing) console.timeEnd('build - hxcpp');

        if(err) {
            flow.log(1, '\n build - stopping because of errors in hxcpp compile \n');
            return flow.project.failed = true;
        }

        done();

    }); //run hxcpp

} //exports

exports.build_hxcpp = function(flow, config, run_path, done) {

    var hxcpp_file = 'Build.xml';
    var args = [hxcpp_file];

    if(run_path) {
        run_path = util.normalize(run_path, true);
    }

    if(flow.flags.debug) {
        args.push("-Ddebug");
    }

    if(flow.flags.log > 2) {
        args.push('-verbose');
    }

    args.push('-D' + flow.target);

    if(flow.target_cpp){
        switch(flow.target_arch) {
            case '64':
                args.push('-DHXCPP_M64');
                break;
            case 'armv6':
                args.push('-DHXCPP_ARMV6');
                break;
            case 'armv7':
                args.push('-DHXCPP_ARMV7');
                break;
            case 'x86':
                args.push('-DHXCPP_X86');
                break;
        }
    }

    if(flow.target == 'android') {
        args.push('-Dandroid-' + flow.project.parsed.project.app.mobile.android.sdk_target);
    }

    flow.log(2, 'build - running hxcpp ...');
    flow.log(3, 'haxelib run hxcpp %s', args.join(' ') );
    flow.log(3, 'running hxcpp from %s', run_path );

    var opt = {
        quiet : false,
        cwd: run_path
    }

    cmd.exec(flow, 'haxelib', ['run','hxcpp'].concat(args), opt, done);

} //build_hxcpp
<commit_msg>cleaning up android log info on any build target<commit_after>
    var   cmds = require('../')
        , fs = require('graceful-fs')
        , path = require('path')
        , cmd = require('../../util/process')
        , util = require('../../util/util')

var internal = {};

exports.post_build = function(flow, config, done) {

    flow.log(3,'build - running cpp post process');

    //the post build is so that we can move the binary file
    //from the output path if needed etc, run extra scripts and so on
    var source_path = util.normalize(path.join(flow.project.paths.build, 'cpp/' + flow.project.paths.binary.source));

    flow.log(3,'build - moving binary from %s to %s', source_path, flow.project.paths.binary.full);

        if(flow.timing) console.time('build - binary copy');
    util.copy_path(flow, source_path, flow.project.paths.binary.full);
        if(flow.timing) console.timeEnd('build - binary copy');

    if(flow.target_desktop) {
        internal.post_build_desktop(flow, source_path, done);
    } else {
        internal.post_build_mobile(flow, source_path, done);
    }

} //post_build

internal.post_build_mobile = function(flow, source_path, done) {

        //run platform specific build chains
    if(flow.target == 'android') {
        internal.build_android(flow, done);
        return;
    }

        //other platforms end here
    if(done) {
        done();
    }

} //post_build_mobile

    //runs ant, and such
internal.build_android = function(flow, done) {

    flow.log(2, 'android specifics', flow.project.prepared.source.project.app.mobile.android);

    //handle ability to compile store build, vs debug test build
    var build_type = flow.project.prepared.source.project.app.mobile.android.build_type;

        //where to build from
    var project_root = path.join(flow.project.paths.build, flow.config.build.android.project);
        //a build file to remove
    var build_meta_file = path.join(project_root,'bin/build.prop');

        //remove build meta data to ensure build happens
    if(fs.existsSync(build_meta_file)) {
        fs.unlinkSync(build_meta_file);
    }

    var args = [build_type];
    var opt = {
        cwd: project_root,
        quiet:false
    }

            if(flow.timing) console.time('build - android - ant');

    cmd.exec(flow, flow.config.build.android.ant_path, args, opt, function(code,out,err){

            if(flow.timing) console.timeEnd('build - android - ant');

        if(code != 0) {
            flow.log(1,'build - android - stopping because ant failed to build, exit code %d', code);
            return flow.project.failed = true;
        }

            //now move the apk out into the user bin folder
        var apk_name = flow.project.prepared.source.project.app.name + '-' + build_type + '.apk';
        var apk_path = path.join(project_root, 'bin/' + apk_name);
        var apk_dest = path.join(flow.project.paths.output, apk_name);

            if(flow.timing) console.time('build - apk copy');
        util.copy_path(flow, apk_path, apk_dest);
            if(flow.timing) console.timeEnd('build - apk copy');

        if(done) {
            done(code,out,err);
        }

    });

} //build_android

internal.post_build_desktop = function(flow, source_path, done) {

    if(flow.system == 'mac' || flow.system == 'linux') {

                if(flow.timing) console.time('build - binary chmod');

        cmd.exec(flow, 'chmod', ['+x',flow.project.paths.binary.full], {quiet:true}, function(code,out,err){

                if(flow.timing) console.timeEnd('build - binary chmod');

            if(done) {
                done(code,out,err);
            }

        }); //exec

    } else {

        if(done) {
            done();
        }

    }

} //post_build_desktop

exports.post_haxe = function(flow, config, done) {

            if(flow.timing) console.time('build - hxcpp');

    var cpp_path = path.join(flow.project.paths.build, 'cpp/');
        cpp_path = path.resolve(flow.run_path, cpp_path);

    exports.build_hxcpp(flow, config, cpp_path, function(err) {

            if(flow.timing) console.timeEnd('build - hxcpp');

        if(err) {
            flow.log(1, '\n build - stopping because of errors in hxcpp compile \n');
            return flow.project.failed = true;
        }

        done();

    }); //run hxcpp

} //exports

exports.build_hxcpp = function(flow, config, run_path, done) {

    var hxcpp_file = 'Build.xml';
    var args = [hxcpp_file];

    if(run_path) {
        run_path = util.normalize(run_path, true);
    }

    if(flow.flags.debug) {
        args.push("-Ddebug");
    }

    if(flow.flags.log > 2) {
        args.push('-verbose');
    }

    args.push('-D' + flow.target);

    if(flow.target_cpp){
        switch(flow.target_arch) {
            case '64':
                args.push('-DHXCPP_M64');
                break;
            case 'armv6':
                args.push('-DHXCPP_ARMV6');
                break;
            case 'armv7':
                args.push('-DHXCPP_ARMV7');
                break;
            case 'x86':
                args.push('-DHXCPP_X86');
                break;
        }
    }

    if(flow.target == 'android') {
        args.push('-Dandroid-' + flow.project.parsed.project.app.mobile.android.sdk_target);
    }

    flow.log(2, 'build - running hxcpp ...');
    flow.log(3, 'haxelib run hxcpp %s', args.join(' ') );
    flow.log(3, 'running hxcpp from %s', run_path );

    var opt = {
        quiet : false,
        cwd: run_path
    }

    cmd.exec(flow, 'haxelib', ['run','hxcpp'].concat(args), opt, done);

} //build_hxcpp
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.app',
  name: 'AppConfig',

  properties: [
    {
      class: 'String',
      name: 'name'
    },
    {
      class: 'String',
      name: 'version'
    },
    {
      class: 'String',
      name: 'privacy',
      value: 'Privacy Policy'
    },
    {
      class: 'String',
      name: 'privacyUrl'
    },
    {
      class: 'String',
      name: 'copyright'
    },
    {
      class: 'String',
      name: 'url'
    },
    {
      class: 'String',
      name: 'urlLabel',
      value: 'FOAM Powered'
    },
    {
      class:'String',
      name: 'termsAndCondLabel',
      value: 'Terms and Conditions'
    },
    {
      class: 'String',
      name: 'termsAndCondLink'
    },
    {
      class: 'Enum',
      of: 'foam.nanos.app.Mode',
      name: 'mode'
    },
    {
      class: 'String',
      name: 'appLink',
      value: 'https://www.apple.com/lae/ios/app-store/'
    },
    {
      class: 'String',
      name: 'playLink',
      value: 'https://play.google.com/store?hl=en'
    }
  ]
});
<commit_msg>set default url in AppConfig<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.app',
  name: 'AppConfig',

  properties: [
    {
      class: 'String',
      name: 'name'
    },
    {
      class: 'String',
      name: 'version'
    },
    {
      class: 'String',
      name: 'privacy',
      value: 'Privacy Policy'
    },
    {
      class: 'String',
      name: 'privacyUrl'
    },
    {
      class: 'String',
      name: 'copyright'
    },
    {
      class: 'String',
      name: 'url',
      value: 'http://localhost:8080/'
    },
    {
      class: 'String',
      name: 'urlLabel',
      value: 'FOAM Powered'
    },
    {
      class:'String',
      name: 'termsAndCondLabel',
      value: 'Terms and Conditions'
    },
    {
      class: 'String',
      name: 'termsAndCondLink'
    },
    {
      class: 'Enum',
      of: 'foam.nanos.app.Mode',
      name: 'mode'
    },
    {
      class: 'String',
      name: 'appLink',
      value: 'https://www.apple.com/lae/ios/app-store/'
    },
    {
      class: 'String',
      name: 'playLink',
      value: 'https://play.google.com/store?hl=en'
    }
  ]
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.client',
  name: 'Client',

  implements: [ 'foam.box.Context' ],

  documentation: 'Client for connecting to NANOS server.',

  requires: [
    'foam.box.HTTPBox',
    'foam.dao.ClientDAO',
    'foam.dao.EasyDAO',
    'foam.nanos.auth.Country',
    'foam.nanos.auth.Group',
    'foam.nanos.auth.Language',
    'foam.nanos.auth.Permission',
    'foam.nanos.auth.Region',
    'foam.nanos.auth.User',
    'foam.nanos.boot.NSpec',
    'foam.nanos.cron.Cron',
    'foam.nanos.export.ExportDriverRegistry',
    'foam.nanos.menu.Menu',
    'foam.nanos.pm.PMInfo',
    'foam.nanos.script.Script',
    'foam.nanos.test.Test',
    'foam.nanos.auth.WebAuthService',
    'foam.nanos.auth.ClientAuthService'
  ],

  exports: [
    'countryDAO',
    'cronDAO',
    'exportDriverRegistryDAO',
    'groupDAO',
    'languageDAO',
    'menuDAO',
    'nSpecDAO',
    'permissionDAO',
    'pmInfoDAO',
    'regionDAO',
    'scriptDAO',
    'testDAO',
    'userDAO',
    'webAuth'
  ],

  properties: [
    {
      name: 'webAuth',
      factory: function() {
        return this.ClientAuthService.create({
          delegate: this.HTTPBox.create({
            method: 'POST',
            url: 'http://localhost:8080/webAuth'
          })
        });
      }
    },

    {
      name: 'nSpecDAO',
      factory: function() {
        return this.ClientDAO.create({
          of: this.NSpec,
          delegate: this.HTTPBox.create({
            method: 'POST',
            url: 'http://localhost:8080/nSpecDAO'
          })});
        /*
        return this.createDAO({
          of: this.NSpec,
          seqNo: true,
          testData: [
            { name: 'http',   serve: false, serviceClass: 'foam.nanos.http.NanoHttpServer' },
            { name: 'pmlog',  serve: false, serviceClass: 'foam.nanos.pm.DAOPMLogger' },
            { name: 'auth',   serve: true,  serviceClass: 'foam.nanos.auth.UserAndGroupAuthService' },
            { name: 'test',   serve: true,  serviceClass: 'foam.nanos.test.TestRunner' },
            { name: 'script', serve: true,  serviceClass: 'foam.nanos.script.ScriptRunner' },
            { name: 'cron',   serve: true,  serviceClass: 'foam.nanos.cron.CronRunner' }
          ]
        });
        */
      }
    },

    {
      name: 'countryDAO',
      factory: function() {
        return this.createDAO({
          of: this.Country,
          testData: [
            { code: 'BR', name: 'Brazil' },
            { code: 'CA', name: 'Canada' },
            { code: 'CN', name: 'China' },
            { code: 'IN', name: 'India' },
            { code: 'JM', name: 'Jamacia' },
            { code: 'LB', name: 'Lebanon' },
            { code: 'MX', name: 'Mexico' },
            { code: 'MY', name: 'Malaysia' },
            { code: 'RS', name: 'Serbia' },
            { code: 'TT', name: 'Trinidad and Tobago' },
            { code: 'UK', name: 'United Kingdom' },
            { code: 'US', name: 'USA' },
            { code: 'ZA', name: 'South Africa' }
          ]
        });
      }
    },

    // TODO: change to client DAO
    {
      name: 'exportDriverRegistryDAO',
      factory: function() {
        return this.createDAO({
          of: this.ExportDriverRegistry,
          testData: [
            { id: 'CSV',  driverName: 'net.nanopay.export.CSVDriver' },
            { id: 'JSON', driverName: 'net.nanopay.export.JSONDriver' },
            { id: 'XML',  driverName: 'net.nanopay.export.XMLDriver' }
          ]
        });
      }
    },

    {
      name: 'regionDAO',
      factory: function() {
        return this.createDAO({
          of: this.Region,
          testData: [
            { countryId: 'CA', code: 'ON', name: 'Ontario' },
            { countryId: 'CA', code: 'PQ', name: 'Quebec' }
          ]
        });
      }
    },

    {
      name: 'menuDAO',
      factory: function() {
        return this.createDAO({

          of: this.Menu,
          testData: [
            { id: 'admin',                           label: 'Admin',          handler: { class: 'foam.nanos.menu.TabsMenu' /*SubMenu*/ } },
              { parent: 'admin', id: 'auth',         label: 'Authentication', handler: { class: 'foam.nanos.menu.TabsMenu' } },
                { parent: 'auth', id: 'users',       label: 'Users',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'userDAO' } },
                { parent: 'auth', id: 'groups',      label: 'Groups',         handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'groupDAO' } },
                { parent: 'auth', id: 'permissions', label: 'Permissions',    handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'permissionDAO' }  },
                { parent: 'auth', id: 'countries',   label: 'Countries',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'countryDAO' } },
                { parent: 'auth', id: 'regions',     label: 'Regions',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'regionDAO' } },
                { parent: 'auth', id: 'lang',        label: 'Languages',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'languageDAO' } },
              { parent: 'admin', id: 'nspec',        label: 'Nano Services',  handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'nSpecDAO' }  },
              { parent: 'admin', id: 'export',       label: 'Export Drivers', handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'exportDriverRegistryDAO' }  },
              { parent: 'admin', id: 'menus',        label: 'Menus',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'menuDAO', summaryView: { class: 'foam.u2.view.TreeView', relationship: MenuRelationship, formatter: function() { this.add(this.data.label); } }  } },
              { parent: 'admin', id: 'scripts',      label: 'Scripts',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'scriptDAO' } },
              { parent: 'admin', id: 'tests',        label: 'Tests',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'testDAO' } },
              { parent: 'admin', id: 'cron',         label: 'Cron Jobs',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'cronDAO' } },
              { parent: 'admin', id: 'pm',           label: 'Performance',    handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'pmInfoDAO' } },
              { parent: 'admin', id: 'log',          label: 'View Logs' },
              /*
            { id: 'support',                         label: 'Support',         handler: { class: 'foam.nanos.menu.TabsMenu' } },
              { parent: 'support', id: 'api',        label: 'API Reference' },
              { parent: 'support', id: 'context',    label: 'Context Walker' }
              */
          ]
        }).orderBy(this.Menu.ORDER, this.Menu.ID);
      }
    },

    {
      name: 'userDAO',
      factory: function() {
        return this.createDAO({
          of: this.User,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'Simon', lastName: 'Alexander', phone: '16133195312' }
          ]
        });
      }
    },

    {
      name: 'languageDAO',
      factory: function() {
        return this.createDAO({
          of: this.Language,
          testData: [
            { code: 'en', name: 'English' },
            { code: 'fr', name: 'French' }
          ]
        });
      }
    },

    {
      name: 'groupDAO',
      factory: function() {
        return this.createDAO({
          of: this.Group,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'nanoPay Admin', lastName: 'nanoPay administration users' },
            { id: 2, firstName: 'Admin',         lastName: 'Administration users' },
            { id: 3, firstName: 'Tester',        lastName: 'Testers' },
            { id: 3, firstName: 'End User',      lastName: 'End users' }
          ]
        });
      }
    },

      {
        name: 'permissionDAO',
        factory: function() {
          return this.createDAO({
            of: this.Permission,
            testData: [
              { id: '*',         description: 'Do anything global permission.' },
              { id: 'menu.auth', description: 'Perform authentication related configuration.' }
            ]
          });
        }
      },

        {
          name: 'scriptDAO',
          factory: function() {
            return this.ClientDAO.create({
              of: this.Script,
              delegate: this.HTTPBox.create({
                method: 'POST',
                url: 'http://localhost:8080/scriptDAO'
              })});
              /*

            return this.createDAO({
              of: this.Script,
              seqNo: true,
              testData: [
              ]
            });*/
          }
        },

        {
          name: 'pmInfoDAO',
          factory: function() {
            return this.ClientDAO.create({
              of: this.PMInfo,
              delegate: this.HTTPBox.create({
                method: 'POST',
                url: 'http://localhost:8080/pmInfoDAO'
              })});
          }
        },

        {
          name: 'cronDAO',
          factory: function() {
            return this.createDAO({
              of: this.Cron,
              seqNo: true,
              testData: [
              ]
            });
          }
        },

        {
          name: 'testDAO',
          factory: function() {
            return this.ClientDAO.create({
                      of: this.NSpec,
                      delegate: this.HTTPBox.create({
                        method: 'POST',
                        url: 'http://localhost:8080/testDAO'
                      })});

            /*
            return this.createDAO({
              of: this.Test,
              seqNo: true,
              testData: [
              ]
            });
            */
          }
        }

  ],

  methods: [
    function createDAO(config) {
      config.daoType = 'MDAO'; // 'IDB';
      config.cache   = true;

      return this.EasyDAO.create(config);
    }
  ]
});
<commit_msg>Fixed testDAO to contain Test objects.<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.client',
  name: 'Client',

  implements: [ 'foam.box.Context' ],

  documentation: 'Client for connecting to NANOS server.',

  requires: [
    'foam.box.HTTPBox',
    'foam.dao.ClientDAO',
    'foam.dao.EasyDAO',
    'foam.nanos.auth.Country',
    'foam.nanos.auth.Group',
    'foam.nanos.auth.Language',
    'foam.nanos.auth.Permission',
    'foam.nanos.auth.Region',
    'foam.nanos.auth.User',
    'foam.nanos.boot.NSpec',
    'foam.nanos.cron.Cron',
    'foam.nanos.export.ExportDriverRegistry',
    'foam.nanos.menu.Menu',
    'foam.nanos.pm.PMInfo',
    'foam.nanos.script.Script',
    'foam.nanos.test.Test',
    'foam.nanos.auth.WebAuthService',
    'foam.nanos.auth.ClientAuthService'
  ],

  exports: [
    'countryDAO',
    'cronDAO',
    'exportDriverRegistryDAO',
    'groupDAO',
    'languageDAO',
    'menuDAO',
    'nSpecDAO',
    'permissionDAO',
    'pmInfoDAO',
    'regionDAO',
    'scriptDAO',
    'testDAO',
    'userDAO',
    'webAuth'
  ],

  properties: [
    {
      name: 'webAuth',
      factory: function() {
        return this.ClientAuthService.create({
          delegate: this.HTTPBox.create({
            method: 'POST',
            url: 'http://localhost:8080/webAuth'
          })
        });
      }
    },

    {
      name: 'nSpecDAO',
      factory: function() {
        return this.ClientDAO.create({
          of: this.NSpec,
          delegate: this.HTTPBox.create({
            method: 'POST',
            url: 'http://localhost:8080/nSpecDAO'
          })});
        /*
        return this.createDAO({
          of: this.NSpec,
          seqNo: true,
          testData: [
            { name: 'http',   serve: false, serviceClass: 'foam.nanos.http.NanoHttpServer' },
            { name: 'pmlog',  serve: false, serviceClass: 'foam.nanos.pm.DAOPMLogger' },
            { name: 'auth',   serve: true,  serviceClass: 'foam.nanos.auth.UserAndGroupAuthService' },
            { name: 'test',   serve: true,  serviceClass: 'foam.nanos.test.TestRunner' },
            { name: 'script', serve: true,  serviceClass: 'foam.nanos.script.ScriptRunner' },
            { name: 'cron',   serve: true,  serviceClass: 'foam.nanos.cron.CronRunner' }
          ]
        });
        */
      }
    },

    {
      name: 'countryDAO',
      factory: function() {
        return this.createDAO({
          of: this.Country,
          testData: [
            { code: 'BR', name: 'Brazil' },
            { code: 'CA', name: 'Canada' },
            { code: 'CN', name: 'China' },
            { code: 'IN', name: 'India' },
            { code: 'JM', name: 'Jamacia' },
            { code: 'LB', name: 'Lebanon' },
            { code: 'MX', name: 'Mexico' },
            { code: 'MY', name: 'Malaysia' },
            { code: 'RS', name: 'Serbia' },
            { code: 'TT', name: 'Trinidad and Tobago' },
            { code: 'UK', name: 'United Kingdom' },
            { code: 'US', name: 'USA' },
            { code: 'ZA', name: 'South Africa' }
          ]
        });
      }
    },

    // TODO: change to client DAO
    {
      name: 'exportDriverRegistryDAO',
      factory: function() {
        return this.createDAO({
          of: this.ExportDriverRegistry,
          testData: [
            { id: 'CSV',  driverName: 'net.nanopay.export.CSVDriver' },
            { id: 'JSON', driverName: 'net.nanopay.export.JSONDriver' },
            { id: 'XML',  driverName: 'net.nanopay.export.XMLDriver' }
          ]
        });
      }
    },

    {
      name: 'regionDAO',
      factory: function() {
        return this.createDAO({
          of: this.Region,
          testData: [
            { countryId: 'CA', code: 'ON', name: 'Ontario' },
            { countryId: 'CA', code: 'PQ', name: 'Quebec' }
          ]
        });
      }
    },

    {
      name: 'menuDAO',
      factory: function() {
        return this.createDAO({

          of: this.Menu,
          testData: [
            { id: 'admin',                           label: 'Admin',          handler: { class: 'foam.nanos.menu.TabsMenu' /*SubMenu*/ } },
              { parent: 'admin', id: 'auth',         label: 'Authentication', handler: { class: 'foam.nanos.menu.TabsMenu' } },
                { parent: 'auth', id: 'users',       label: 'Users',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'userDAO' } },
                { parent: 'auth', id: 'groups',      label: 'Groups',         handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'groupDAO' } },
                { parent: 'auth', id: 'permissions', label: 'Permissions',    handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'permissionDAO' }  },
                { parent: 'auth', id: 'countries',   label: 'Countries',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'countryDAO' } },
                { parent: 'auth', id: 'regions',     label: 'Regions',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'regionDAO' } },
                { parent: 'auth', id: 'lang',        label: 'Languages',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'languageDAO' } },
              { parent: 'admin', id: 'nspec',        label: 'Nano Services',  handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'nSpecDAO' }  },
              { parent: 'admin', id: 'export',       label: 'Export Drivers', handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'exportDriverRegistryDAO' }  },
              { parent: 'admin', id: 'menus',        label: 'Menus',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'menuDAO', summaryView: { class: 'foam.u2.view.TreeView', relationship: MenuRelationship, formatter: function() { this.add(this.data.label); } }  } },
              { parent: 'admin', id: 'scripts',      label: 'Scripts',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'scriptDAO' } },
              { parent: 'admin', id: 'tests',        label: 'Tests',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'testDAO' } },
              { parent: 'admin', id: 'cron',         label: 'Cron Jobs',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'cronDAO' } },
              { parent: 'admin', id: 'pm',           label: 'Performance',    handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'pmInfoDAO' } },
              { parent: 'admin', id: 'log',          label: 'View Logs' },
              /*
            { id: 'support',                         label: 'Support',         handler: { class: 'foam.nanos.menu.TabsMenu' } },
              { parent: 'support', id: 'api',        label: 'API Reference' },
              { parent: 'support', id: 'context',    label: 'Context Walker' }
              */
          ]
        }).orderBy(this.Menu.ORDER, this.Menu.ID);
      }
    },

    {
      name: 'userDAO',
      factory: function() {
        return this.createDAO({
          of: this.User,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'Simon', lastName: 'Alexander', phone: '16133195312' }
          ]
        });
      }
    },

    {
      name: 'languageDAO',
      factory: function() {
        return this.createDAO({
          of: this.Language,
          testData: [
            { code: 'en', name: 'English' },
            { code: 'fr', name: 'French' }
          ]
        });
      }
    },

    {
      name: 'groupDAO',
      factory: function() {
        return this.createDAO({
          of: this.Group,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'nanoPay Admin', lastName: 'nanoPay administration users' },
            { id: 2, firstName: 'Admin',         lastName: 'Administration users' },
            { id: 3, firstName: 'Tester',        lastName: 'Testers' },
            { id: 3, firstName: 'End User',      lastName: 'End users' }
          ]
        });
      }
    },

      {
        name: 'permissionDAO',
        factory: function() {
          return this.createDAO({
            of: this.Permission,
            testData: [
              { id: '*',         description: 'Do anything global permission.' },
              { id: 'menu.auth', description: 'Perform authentication related configuration.' }
            ]
          });
        }
      },

        {
          name: 'scriptDAO',
          factory: function() {
            return this.ClientDAO.create({
              of: this.Script,
              delegate: this.HTTPBox.create({
                method: 'POST',
                url: 'http://localhost:8080/scriptDAO'
              })});
              /*

            return this.createDAO({
              of: this.Script,
              seqNo: true,
              testData: [
              ]
            });*/
          }
        },

        {
          name: 'pmInfoDAO',
          factory: function() {
            return this.ClientDAO.create({
              of: this.PMInfo,
              delegate: this.HTTPBox.create({
                method: 'POST',
                url: 'http://localhost:8080/pmInfoDAO'
              })});
          }
        },

        {
          name: 'cronDAO',
          factory: function() {
            return this.createDAO({
              of: this.Cron,
              seqNo: true,
              testData: [
              ]
            });
          }
        },

        {
          name: 'testDAO',
          factory: function() {
            return this.ClientDAO.create({
              of: this.Test,
              delegate: this.HTTPBox.create({
              method: 'POST',
              url: 'http://localhost:8080/testDAO'
            })});

            /*
            return this.createDAO({
              of: this.Test,
              seqNo: true,
              testData: [
              ]
            });
            */
          }
        }

  ],

  methods: [
    function createDAO(config) {
      config.daoType = 'MDAO'; // 'IDB';
      config.cache   = true;

      return this.EasyDAO.create(config);
    }
  ]
});
<|endoftext|>


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

/**
  * @constructor
  * @extends DOM_markup_style
  */

cls.DOMView = function(id, name, container_class)
{

  this.createView = function(container)
  {
    if (this._create_view_no_data_timeout)
    {
      clearTimeout(this._create_view_no_data_timeout);
      this._create_view_no_data_timeout = 0;
    }
    if (dom_data.has_data())
    {
      var model = window.dominspections.active;
      var scrollTop = container.scrollTop;
      container.clearAndRender(window.templates.inspected_dom_node(window.dom_data,
                                                                   model && model.target,
                                                                   true));
      if (!window.helpers.scroll_dom_target_into_view())
      {
        container.scrollTop = scrollTop;
      }
      if (model == window.dom_data)
      {
        if (!this._modebar)
        {
          this._modebar = UI.get_instance().get_modebar('dom');
        }
        if (this._modebar)
        {
          this._modebar.set_content(model.id,
                                    window.templates.breadcrumb(model, model.target),
                                    true);
        }
      }
    }
    else
    {
      this._create_view_no_data_timeout = setTimeout(this._create_view_no_data, 100, container);
    }
  };

  this._create_view_no_data_timeout = 0;

  this._create_view_no_data = function(container)
  {
    if(!dom_data.getDataRuntimeId())
    {
      container.innerHTML =
        "

" +
          ui_strings.S_INFO_WINDOW_HAS_NO_RUNTIME +
        "

";
    }
    else
    {
      container.innerHTML = "

";
    }
  }

  this.ondestroy = function()
  {
    window.hostspotlighter.clearSpotlight();
  }

  this._on_setting_change = function(msg)
  {
    if( msg.id == this.id )
    {
      switch (msg.key)
      {
        case 'dom-tree-style':
        {
          this.update();
          break;
        }
      }
    }
  }

  messages.addListener('setting-changed', this._on_setting_change.bind(this));
  this.init(id, name, container_class);

}

cls.DocumentSelect = function(id)
{

  var selected_value = "";

  this.getSelectedOptionText = function()
  {
    var selected_rt_id = dom_data.getDataRuntimeId();
    if(selected_rt_id)
    {
      var rt = runtimes.getRuntime(selected_rt_id);
      if( rt )
      {
        return rt['title'] || helpers.shortenURI(rt.uri).uri;
      }
    }
    return '';
  }

  this.getSelectedOptionValue = function()
  {

  }

  this.templateOptionList = function(select_obj)
  {

    // TODO this is a relict of protocol 3, needs cleanup
    var active_window_id = runtimes.getActiveWindowId();

    if( active_window_id )
    {
      var
      _runtimes = runtimes.getRuntimes(active_window_id),
      rt = null,
      i = 0;

      // remove the extension runtimes from the document
      // selector dropdown in the DOM view
      _runtimes = _runtimes.filter(function(runtime)
      {
        return ["extensionjs"].indexOf(runtime.description) == -1;
      });
      for( ; ( rt = _runtimes[i] ) && !rt['selected']; i++);
      if( !rt && _runtimes[0] )
      {
        opera.postError(ui_strings.DRAGONFLY_INFO_MESSAGE + 'no runtime selected')
        return;
      }
      return templates.runtimes(_runtimes, 'dom');
    }

  }

  this.checkChange = function(target_ele)
  {
    var rt_id = parseInt(target_ele.getAttribute('runtime-id'));

    if( rt_id != dom_data.getDataRuntimeId() )
    {
      if(rt_id)
      {
        dom_data.get_dom(rt_id);
      }
      else
      {
        opera.postError(ui_strings.DRAGONFLY_INFO_MESSAGE +
          "missing runtime id in cls.DocumentSelect.checkChange")
      }
      return true;
    }
    return false;
  }

  // this.updateElement

  this.init(id);
}

cls.DOMView.create_ui_widgets = function()
{

  new Settings
  (
    // id
    'dom',
    // kel-value map
    {

      'find-with-click': true,
      'highlight-on-hover': true,
      'update-on-dom-node-inserted': false,
      'force-lowercase': true,
      'show-comments': true,
      'show-whitespace-nodes': true,
      'dom-tree-style': false,
      'show-siblings-in-breadcrumb': false,
      'show-id_and_classes-in-breadcrumb': true,
      'scroll-into-view-on-spotlight': true,
      'lock-selected-elements': false
    },
    // key-label map
    {
      'find-with-click': ui_strings.S_SWITCH_FIND_ELEMENT_BY_CLICKING,
      // TODO change to highlight
      'highlight-on-hover': ui_strings.S_SWITCH_HIGHLIGHT_SELECTED_OR_HOVERED_ELEMENT,
      'update-on-dom-node-inserted': ui_strings.S_SWITCH_UPDATE_DOM_ON_NODE_REMOVE,
      'force-lowercase': ui_strings.S_SWITCH_USE_LOWER_CASE_TAG_NAMES,
      'show-comments': ui_strings.S_SWITCH_SHOW_COMMENT_NODES,
      'show-whitespace-nodes': ui_strings.S_SWITCH_SHOW_WHITE_SPACE_NODES,
      'dom-tree-style': ui_strings.S_SWITCH_SHOW_DOM_INTREE_VIEW,
      'show-siblings-in-breadcrumb': ui_strings.S_SWITCH_SHOW_SIBLINGS_IN_BREAD_CRUMB,
      'show-id_and_classes-in-breadcrumb': ui_strings.S_SWITCH_SHOW_ID_AND_CLASSES_IN_BREAD_CRUMB,
      'scroll-into-view-on-spotlight': ui_strings.S_SWITCH_SCROLL_INTO_VIEW_ON_FIRST_SPOTLIGHT,
      'lock-selected-elements': ui_strings.S_SWITCH_LOCK_SELECTED_ELEMENTS

    },
    // settings map
    {
      checkboxes:
      [
        'force-lowercase',
        'dom-tree-style',
        'show-comments',
        'show-whitespace-nodes',
        'find-with-click',
        'highlight-on-hover',
        'update-on-dom-node-inserted',
        'show-siblings-in-breadcrumb',
        'show-id_and_classes-in-breadcrumb',
        'scroll-into-view-on-spotlight',
        'lock-selected-elements'
      ],
      contextmenu:
      [
        'dom-tree-style',
        'show-comments',
        'lock-selected-elements'
      ]
    },
    null,
    "document",
    // default callback map on setting change
    // called as method of the settings object
    {
      "lock-selected-elements": function(value)
      {
        if (value && !this.get('highlight-on-hover'))
        {
          this.set('highlight-on-hover', true, true);
        }
      },
    }
  );

  new ToolbarConfig
  (
    'dom',
    [
      {
        handler: 'dom-inspection-snapshot',
        title: ui_strings.S_BUTTON_LABEL_GET_THE_WOHLE_TREE
      },
      {
        handler: 'dom-inspection-export',
        title: ui_strings.S_BUTTON_LABEL_EXPORT_DOM
      }
    ],
    null,
    /*
    [
      {
        handler: 'dom-text-search',
        shortcuts: 'dom-text-search',
        title: ui_strings.S_INPUT_DEFAULT_TEXT_SEARCH
      }
    ], */
    null,
    [
      {
        handler: 'select-window',
        title: ui_strings.S_BUTTON_LABEL_SELECT_WINDOW,
        type: 'dropdown',
        class: 'window-select-dropdown',
        template: window['cst-selects']['document-select'].getTemplate()
      }
    ],
    true
  )

  var broker = ActionBroker.get_instance();
  var contextmenu = ContextMenu.get_instance();

  var dom_element_common_items = [
    {
      label: ui_strings.M_CONTEXTMENU_EDIT_MARKUP,
      handler: contextmenu_edit_markup
    },
    {
      label: ui_strings.M_CONTEXTMENU_REMOVE_NODE,
      handler: contextmenu_remove_node
    }
  ];

  contextmenu.register("dom-element", [
    {
      callback: function(event, target)
      {
        var target = event.target;
        if (target.has_attr("parent-node-chain", "ref-id").hasClass("non-editable"))
        {
          return;
        }

        var menu = [];
        while (target != document && !/^(?:key|value|text|node)$/i.test(target.nodeName))
        {
          target = target.parentNode;
        }

        switch (target.nodeName.toLowerCase())
        {
        case "node":
          var toggle = target.parentNode.querySelector("[handler='get-children']");
          var is_open = toggle ? toggle.hasClass("open") : null;
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_ADD_ATTRIBUTE,
              handler: contextmenu_add_attribute
            }
          ]
          .concat(ContextMenu.separator)
          .concat(dom_element_common_items);

          if (toggle)
          {
            menu.extend([
              ContextMenu.separator,
              {
                label: is_open ? ui_strings.M_CONTEXTMENU_COLLAPSE_SUBTREE
                               : ui_strings.M_CONTEXTMENU_EXPAND_SUBTREE,
                handler: function contextmenu_expand_collapse_subtree(event, target) {
                  broker.dispatch_action("dom", "expand-collapse-whole-node", event, event.target);
                }
              }
            ]);
          }
          break;

        case "key":
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_EDIT_ATTRIBUTE,
              handler: contextmenu_edit_dom
            },
            {
              label: ui_strings.M_CONTEXTMENU_ADD_ATTRIBUTE,
              handler: contextmenu_add_attribute
            }/*,
            {
              label: "Remove attribute", // Add ui string
              handler: contextmenu_remove_attribute
            }*/
          ]
          .concat(ContextMenu.separator)
          .concat(dom_element_common_items);
          break;

        case "value":
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_EDIT_ATTRIBUTE_VALUE,
              handler: contextmenu_edit_dom
            },
            {
              label: ui_strings.M_CONTEXTMENU_ADD_ATTRIBUTE,
              handler: contextmenu_add_attribute
            }
          ]
          .concat(ContextMenu.separator)
          .concat(dom_element_common_items);
          break;

        case "text":
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_EDIT_TEXT,
              handler: contextmenu_edit_dom
            }
          ];
          break;
        }

        return menu;
      }
    }
  ]);

  function contextmenu_edit_dom(event, target)
  {
    broker.dispatch_action("dom", "edit-dom", event, event.target);
  }

  function contextmenu_edit_markup(event, target)
  {
    target = event.target;
    while (target && target.nodeName.toLowerCase() != "node")
    {
      target = target.parentNode;
    }

    if (target)
    {
      broker.dispatch_action("dom", "edit-dom", event, target);
    }
  }

  function contextmenu_add_attribute(event, target)
  {
    broker.dispatch_action("dom", "insert-attribute-edit", event, event.target);
  }

  function contextmenu_remove_attribute(event, target)
  {
    broker.dispatch_action("dom", "remove-attribute", event, event.target);
  }

  function contextmenu_remove_node(event, target)
  {
    broker.dispatch_action("dom", "remove-node", event, event.target);
  }

  new Switches
  (
    'dom',
    [
      'find-with-click',
      'highlight-on-hover',
      'update-on-dom-node-inserted'
    ]
  );

  new Search('dom', [Searchbar]);

};
<commit_msg>Fixed an exception in some circumstances.<commit_after>window.cls || (window.cls = {});

/**
  * @constructor
  * @extends DOM_markup_style
  */

cls.DOMView = function(id, name, container_class)
{

  this.createView = function(container)
  {
    if (this._create_view_no_data_timeout)
    {
      clearTimeout(this._create_view_no_data_timeout);
      this._create_view_no_data_timeout = 0;
    }
    if (dom_data.has_data())
    {
      var model = window.dominspections.active;
      var scrollTop = container.scrollTop;
      container.clearAndRender(window.templates.inspected_dom_node(window.dom_data,
                                                                   model && model.target,
                                                                   true));
      if (!window.helpers.scroll_dom_target_into_view())
      {
        container.scrollTop = scrollTop;
      }
      if (model == window.dom_data)
      {
        if (!this._modebar)
        {
          this._modebar = UI.get_instance().get_modebar('dom');
        }
        if (this._modebar)
        {
          this._modebar.set_content(model.id,
                                    window.templates.breadcrumb(model, model.target),
                                    true);
        }
      }
    }
    else
    {
      this._create_view_no_data_timeout = setTimeout(this._create_view_no_data, 100, container);
    }
  };

  this._create_view_no_data_timeout = 0;

  this._create_view_no_data = function(container)
  {
    if(!dom_data.getDataRuntimeId())
    {
      container.innerHTML =
        "

" +
          ui_strings.S_INFO_WINDOW_HAS_NO_RUNTIME +
        "

";
    }
    else
    {
      container.innerHTML = "

";
    }
  }

  this.ondestroy = function()
  {
    window.hostspotlighter.clearSpotlight();
  }

  this._on_setting_change = function(msg)
  {
    if( msg.id == this.id )
    {
      switch (msg.key)
      {
        case 'dom-tree-style':
        {
          this.update();
          break;
        }
      }
    }
  }

  messages.addListener('setting-changed', this._on_setting_change.bind(this));
  this.init(id, name, container_class);

}

cls.DocumentSelect = function(id)
{

  var selected_value = "";

  this.getSelectedOptionText = function()
  {
    var selected_rt_id = dom_data.getDataRuntimeId();
    if(selected_rt_id)
    {
      var rt = runtimes.getRuntime(selected_rt_id);
      if( rt )
      {
        return rt['title'] || helpers.shortenURI(rt.uri).uri;
      }
    }
    return '';
  }

  this.getSelectedOptionValue = function()
  {

  }

  this.templateOptionList = function(select_obj)
  {

    // TODO this is a relict of protocol 3, needs cleanup
    var active_window_id = runtimes.getActiveWindowId();

    if( active_window_id )
    {
      var
      _runtimes = runtimes.getRuntimes(active_window_id),
      rt = null,
      i = 0;

      // remove the extension runtimes from the document
      // selector dropdown in the DOM view
      _runtimes = _runtimes.filter(function(runtime)
      {
        return ["extensionjs"].indexOf(runtime.description) == -1;
      });
      for( ; ( rt = _runtimes[i] ) && !rt['selected']; i++);
      if( !rt && _runtimes[0] )
      {
        opera.postError(ui_strings.DRAGONFLY_INFO_MESSAGE + 'no runtime selected')
        return;
      }
      return templates.runtimes(_runtimes, 'dom');
    }

  }

  this.checkChange = function(target_ele)
  {
    var rt_id = parseInt(target_ele.getAttribute('runtime-id'));

    if( rt_id != dom_data.getDataRuntimeId() )
    {
      if(rt_id)
      {
        dom_data.get_dom(rt_id);
      }
      else
      {
        opera.postError(ui_strings.DRAGONFLY_INFO_MESSAGE +
          "missing runtime id in cls.DocumentSelect.checkChange")
      }
      return true;
    }
    return false;
  }

  // this.updateElement

  this.init(id);
}

cls.DOMView.create_ui_widgets = function()
{

  new Settings
  (
    // id
    'dom',
    // kel-value map
    {

      'find-with-click': true,
      'highlight-on-hover': true,
      'update-on-dom-node-inserted': false,
      'force-lowercase': true,
      'show-comments': true,
      'show-whitespace-nodes': true,
      'dom-tree-style': false,
      'show-siblings-in-breadcrumb': false,
      'show-id_and_classes-in-breadcrumb': true,
      'scroll-into-view-on-spotlight': true,
      'lock-selected-elements': false
    },
    // key-label map
    {
      'find-with-click': ui_strings.S_SWITCH_FIND_ELEMENT_BY_CLICKING,
      // TODO change to highlight
      'highlight-on-hover': ui_strings.S_SWITCH_HIGHLIGHT_SELECTED_OR_HOVERED_ELEMENT,
      'update-on-dom-node-inserted': ui_strings.S_SWITCH_UPDATE_DOM_ON_NODE_REMOVE,
      'force-lowercase': ui_strings.S_SWITCH_USE_LOWER_CASE_TAG_NAMES,
      'show-comments': ui_strings.S_SWITCH_SHOW_COMMENT_NODES,
      'show-whitespace-nodes': ui_strings.S_SWITCH_SHOW_WHITE_SPACE_NODES,
      'dom-tree-style': ui_strings.S_SWITCH_SHOW_DOM_INTREE_VIEW,
      'show-siblings-in-breadcrumb': ui_strings.S_SWITCH_SHOW_SIBLINGS_IN_BREAD_CRUMB,
      'show-id_and_classes-in-breadcrumb': ui_strings.S_SWITCH_SHOW_ID_AND_CLASSES_IN_BREAD_CRUMB,
      'scroll-into-view-on-spotlight': ui_strings.S_SWITCH_SCROLL_INTO_VIEW_ON_FIRST_SPOTLIGHT,
      'lock-selected-elements': ui_strings.S_SWITCH_LOCK_SELECTED_ELEMENTS

    },
    // settings map
    {
      checkboxes:
      [
        'force-lowercase',
        'dom-tree-style',
        'show-comments',
        'show-whitespace-nodes',
        'find-with-click',
        'highlight-on-hover',
        'update-on-dom-node-inserted',
        'show-siblings-in-breadcrumb',
        'show-id_and_classes-in-breadcrumb',
        'scroll-into-view-on-spotlight',
        'lock-selected-elements'
      ],
      contextmenu:
      [
        'dom-tree-style',
        'show-comments',
        'lock-selected-elements'
      ]
    },
    null,
    "document",
    // default callback map on setting change
    // called as method of the settings object
    {
      "lock-selected-elements": function(value)
      {
        if (value && !this.get('highlight-on-hover'))
        {
          this.set('highlight-on-hover', true, true);
        }
      },
    }
  );

  new ToolbarConfig
  (
    'dom',
    [
      {
        handler: 'dom-inspection-snapshot',
        title: ui_strings.S_BUTTON_LABEL_GET_THE_WOHLE_TREE
      },
      {
        handler: 'dom-inspection-export',
        title: ui_strings.S_BUTTON_LABEL_EXPORT_DOM
      }
    ],
    null,
    /*
    [
      {
        handler: 'dom-text-search',
        shortcuts: 'dom-text-search',
        title: ui_strings.S_INPUT_DEFAULT_TEXT_SEARCH
      }
    ], */
    null,
    [
      {
        handler: 'select-window',
        title: ui_strings.S_BUTTON_LABEL_SELECT_WINDOW,
        type: 'dropdown',
        class: 'window-select-dropdown',
        template: window['cst-selects']['document-select'].getTemplate()
      }
    ],
    true
  )

  var broker = ActionBroker.get_instance();
  var contextmenu = ContextMenu.get_instance();

  var dom_element_common_items = [
    {
      label: ui_strings.M_CONTEXTMENU_EDIT_MARKUP,
      handler: contextmenu_edit_markup
    },
    {
      label: ui_strings.M_CONTEXTMENU_REMOVE_NODE,
      handler: contextmenu_remove_node
    }
  ];

  contextmenu.register("dom-element", [
    {
      callback: function(event, target)
      {
        var target = event.target;
        var ele = target.has_attr("parent-node-chain", "ref-id");
        if (ele && ele.hasClass("non-editable"))
        {
          return;
        }

        var menu = [];
        while (target != document && !/^(?:key|value|text|node)$/i.test(target.nodeName))
        {
          target = target.parentNode;
        }

        switch (target.nodeName.toLowerCase())
        {
        case "node":
          var toggle = target.parentNode.querySelector("[handler='get-children']");
          var is_open = toggle ? toggle.hasClass("open") : null;
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_ADD_ATTRIBUTE,
              handler: contextmenu_add_attribute
            }
          ]
          .concat(ContextMenu.separator)
          .concat(dom_element_common_items);

          if (toggle)
          {
            menu.extend([
              ContextMenu.separator,
              {
                label: is_open ? ui_strings.M_CONTEXTMENU_COLLAPSE_SUBTREE
                               : ui_strings.M_CONTEXTMENU_EXPAND_SUBTREE,
                handler: function contextmenu_expand_collapse_subtree(event, target) {
                  broker.dispatch_action("dom", "expand-collapse-whole-node", event, event.target);
                }
              }
            ]);
          }
          break;

        case "key":
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_EDIT_ATTRIBUTE,
              handler: contextmenu_edit_dom
            },
            {
              label: ui_strings.M_CONTEXTMENU_ADD_ATTRIBUTE,
              handler: contextmenu_add_attribute
            }/*,
            {
              label: "Remove attribute", // Add ui string
              handler: contextmenu_remove_attribute
            }*/
          ]
          .concat(ContextMenu.separator)
          .concat(dom_element_common_items);
          break;

        case "value":
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_EDIT_ATTRIBUTE_VALUE,
              handler: contextmenu_edit_dom
            },
            {
              label: ui_strings.M_CONTEXTMENU_ADD_ATTRIBUTE,
              handler: contextmenu_add_attribute
            }
          ]
          .concat(ContextMenu.separator)
          .concat(dom_element_common_items);
          break;

        case "text":
          menu = [
            {
              label: ui_strings.M_CONTEXTMENU_EDIT_TEXT,
              handler: contextmenu_edit_dom
            }
          ];
          break;
        }

        return menu;
      }
    }
  ]);

  function contextmenu_edit_dom(event, target)
  {
    broker.dispatch_action("dom", "edit-dom", event, event.target);
  }

  function contextmenu_edit_markup(event, target)
  {
    target = event.target;
    while (target && target.nodeName.toLowerCase() != "node")
    {
      target = target.parentNode;
    }

    if (target)
    {
      broker.dispatch_action("dom", "edit-dom", event, target);
    }
  }

  function contextmenu_add_attribute(event, target)
  {
    broker.dispatch_action("dom", "insert-attribute-edit", event, event.target);
  }

  function contextmenu_remove_attribute(event, target)
  {
    broker.dispatch_action("dom", "remove-attribute", event, event.target);
  }

  function contextmenu_remove_node(event, target)
  {
    broker.dispatch_action("dom", "remove-node", event, event.target);
  }

  new Switches
  (
    'dom',
    [
      'find-with-click',
      'highlight-on-hover',
      'update-on-dom-node-inserted'
    ]
  );

  new Search('dom', [Searchbar]);

};
<|endoftext|>


<commit_before>export { getRandomIntInclusive, fill_numberArray, generate_numberArray };

import * as FloatValue from "../Unpacker/FloatValue.js";
import * as Recyclable from "./Recyclable.js";

/**
 * Return a random integer between min and max. (This function comes from MDN's Math.random().)
 *
 * @param {number} min The the minimum integer. (inclusive)
 * @param {number} max The the maximum integer. (inclusive)
 */
function getRandomIntInclusive( min, max ) {
  let minReal = Math.min( min, max );
  let maxReal = Math.max( min, max );
  let minInt = Math.ceil( minReal );
  let maxInt  = Math.floor( maxReal );
  let kindsInt = maxInt - minInt + 1;
  return Math.floor( ( Math.random() * kindsInt ) + minInt );
}

/**
 * This method will try to let neighbor channel's value bounds has obviously more
 * different.
 *
 *
 * @param {number[]|Recyclable.NumberArray_withBounds} io_numberArray
 *   The number array to be filled. If it is an instance of Recyclable.NumberArray_withBounds,
 * its .boundsArray_byChannel will be filled.
 *
 * @param {number} height        The length of axis0 of the io_numberArray.
 * @param {number} width         The length of axis1 of the io_numberArray.
 * @param {number} channelCount  The length of axis2 of the io_numberArray.
 *
 * @param {number} valueBegin
 *   The first value of filled sequence.
 *
 * @param {number} valueStep
 *   The incremental value of every next filled value in the sequence.
 *
 * @param {number} randomOffsetMin
 *   Every element of the generated number array will been shifted from the sequence id between
 * [ randomOffsetMin, randomOffsetMax ] (inclusive) randomly.
 *
 * @param {number} randomOffsetMax
 *   Every element of the generated number array will been shifted from the sequence id between
 * [ randomOffsetMin, randomOffsetMax ] (inclusive) randomly.
 *
 * @param {number} divisorForRemainder
 *   The generated value will be divided by divisorForRemainder. The remainder will be the real
 * output value. This is used for restricted the value bounds.
 *
 * @return {number[]|Recyclable.NumberArray_withBounds}
 *   Return the io_numberArray.
 */
function fill_numberArray( io_numberArray,
  height, width, channelCount,
  valueBegin = 0, valueStep = 1,
  randomOffsetMin = 0, randomOffsetMax = 0, divisorForRemainder = ( 2 ** 26 ) ) {

    // (Codes copied from getRandomIntInclusive())
    const randomOffsetMinReal = Math.min( randomOffsetMin, randomOffsetMax );
    const randomOffsetMaxReal = Math.max( randomOffsetMin, randomOffsetMax );
    const randomOffsetMinInt = Math.ceil( randomOffsetMinReal );
    const randomOffsetMaxInt  = Math.floor( randomOffsetMaxReal );
    const randomOffsetKindsInt = randomOffsetMaxInt - randomOffsetMinInt + 1;

    io_numberArray.length = height * width * channelCount;

    let valueStepPerChannel = valueStep * channelCount;
    let valueNoRandBegin = valueBegin;
    let valueNoRand;
    let randomOffset;
    let value;

    let arrayIndex = 0;

    try {
      if ( io_numberArray instanceof Recyclable.NumberArray_withBounds ) {
      io_numberArray.boundsArray_byChannel.length = channelCount;
      io_numberArray.boundsArray_byChannel.set_all_by_PositiveInfinity_NegativeInfinity();

      for ( let h = 0; h < height; ++h ) {
        for ( let w = 0; w < width; ++w ) {

          valueNoRand = valueNoRandBegin;
          for ( let c = 0; c < channelCount; ++c, ++arrayIndex ) {

//!!! (2022/08/04 Temp Remarked) for re-producible random.
            // randomOffset = Math.floor( ( Math.random() * randomOffsetKindsInt ) + randomOffsetMinInt );
            if ( ( arrayIndex % 2 ) == 0 )
              randomOffset = randomOffsetMinInt;
            else
              randomOffset = randomOffsetMaxInt;

            value = ( valueNoRand + randomOffset ) % divisorForRemainder;
            io_numberArray[ arrayIndex ] = value;
            io_numberArray.boundsArray_byChannel.enlarge_one_byN( c, value );

            valueNoRand += valueStepPerChannel;
          }
          valueNoRandBegin += valueStep;
        }
      }

    } else {

      for ( let h = 0; h < height; ++h ) {
        for ( let w = 0; w < width; ++w ) {

          valueNoRand = valueNoRandBegin;
          for ( let c = 0; c < channelCount; ++c, ++arrayIndex ) {

//!!! (2022/08/04 Temp Remarked) for re-producible random.
            // randomOffset = Math.floor( ( Math.random() * randomOffsetKindsInt ) + randomOffsetMinInt );
            if ( ( arrayIndex % 2 ) == 0 )
              randomOffset = randomOffsetMinInt;
            else
              randomOffset = randomOffsetMaxInt;

            value = ( valueNoRand + randomOffset ) % divisorForRemainder;
            io_numberArray[ arrayIndex ] = value;
            valueNoRand += valueStepPerChannel;
          }
          valueNoRandBegin += valueStep;
        }
      }
    }

  } catch ( e ) {
    debugger;
    throw e;
  }

  return io_numberArray;
}

/**
 *
 * @param {number} height        The length of axis0 of the io_numberArray.
 * @param {number} width         The length of axis1 of the io_numberArray.
 * @param {number} channelCount  The length of axis2 of the io_numberArray.
 *
 * @return {number[]}
 *   Return a number array.
 *
 * @see fill_integerArray()
 */
function generate_numberArray(
  height, width, channelCount,
  valueBegin = 0, valueStep = 1,
  randomOffsetMin = 0, randomOffsetMax = 0, divisorForRemainder = ( 2 ** 26 )
) {

  let numberArray = new Array();
  return fill_numberArray( numberArray,
    height, width, channelCount,
    valueBegin, valueStep,
    randomOffsetMin, randomOffsetMax, divisorForRemainder );
}
<commit_msg>io_numberArray instanceof Array<commit_after>export { getRandomIntInclusive, fill_numberArray, generate_numberArray };

import * as FloatValue from "../Unpacker/FloatValue.js";
import * as Recyclable from "./Recyclable.js";

/**
 * Return a random integer between min and max. (This function comes from MDN's Math.random().)
 *
 * @param {number} min The the minimum integer. (inclusive)
 * @param {number} max The the maximum integer. (inclusive)
 */
function getRandomIntInclusive( min, max ) {
  let minReal = Math.min( min, max );
  let maxReal = Math.max( min, max );
  let minInt = Math.ceil( minReal );
  let maxInt  = Math.floor( maxReal );
  let kindsInt = maxInt - minInt + 1;
  return Math.floor( ( Math.random() * kindsInt ) + minInt );
}

/**
 * This method will try to let neighbor channel's value bounds has obviously more
 * different.
 *
 *
 * @param {number[]|Recyclable.NumberArray_withBounds} io_numberArray
 *   The number array to be filled. If it is an instance of Recyclable.NumberArray_withBounds,
 * its .boundsArray_byChannel will be filled.
 *
 * @param {number} height        The length of axis0 of the io_numberArray.
 * @param {number} width         The length of axis1 of the io_numberArray.
 * @param {number} channelCount  The length of axis2 of the io_numberArray.
 *
 * @param {number} valueBegin
 *   The first value of filled sequence.
 *
 * @param {number} valueStep
 *   The incremental value of every next filled value in the sequence.
 *
 * @param {number} randomOffsetMin
 *   Every element of the generated number array will been shifted from the sequence id between
 * [ randomOffsetMin, randomOffsetMax ] (inclusive) randomly.
 *
 * @param {number} randomOffsetMax
 *   Every element of the generated number array will been shifted from the sequence id between
 * [ randomOffsetMin, randomOffsetMax ] (inclusive) randomly.
 *
 * @param {number} divisorForRemainder
 *   The generated value will be divided by divisorForRemainder. The remainder will be the real
 * output value. This is used for restricted the value bounds.
 *
 * @return {number[]|Recyclable.NumberArray_withBounds}
 *   Return the io_numberArray.
 */
function fill_numberArray( io_numberArray,
  height, width, channelCount,
  valueBegin = 0, valueStep = 1,
  randomOffsetMin = 0, randomOffsetMax = 0, divisorForRemainder = ( 2 ** 26 ) ) {

    // (Codes copied from getRandomIntInclusive())
    const randomOffsetMinReal = Math.min( randomOffsetMin, randomOffsetMax );
    const randomOffsetMaxReal = Math.max( randomOffsetMin, randomOffsetMax );
    const randomOffsetMinInt = Math.ceil( randomOffsetMinReal );
    const randomOffsetMaxInt  = Math.floor( randomOffsetMaxReal );
    const randomOffsetKindsInt = randomOffsetMaxInt - randomOffsetMinInt + 1;

    // (Note: If TypedArray, its .length can not be modified.)
    if ( io_numberArray instanceof Array )
      io_numberArray.length = height * width * channelCount;

    let valueStepPerChannel = valueStep * channelCount;
    let valueNoRandBegin = valueBegin;
    let valueNoRand;
    let randomOffset;
    let value;

    let arrayIndex = 0;

    try {
      if ( io_numberArray instanceof Recyclable.NumberArray_withBounds ) {
      io_numberArray.boundsArray_byChannel.length = channelCount;
      io_numberArray.boundsArray_byChannel.set_all_by_PositiveInfinity_NegativeInfinity();

      for ( let h = 0; h < height; ++h ) {
        for ( let w = 0; w < width; ++w ) {

          valueNoRand = valueNoRandBegin;
          for ( let c = 0; c < channelCount; ++c, ++arrayIndex ) {

//!!! (2022/08/04 Temp Remarked) for re-producible random.
            // randomOffset = Math.floor( ( Math.random() * randomOffsetKindsInt ) + randomOffsetMinInt );
            if ( ( arrayIndex % 2 ) == 0 )
              randomOffset = randomOffsetMinInt;
            else
              randomOffset = randomOffsetMaxInt;

            value = ( valueNoRand + randomOffset ) % divisorForRemainder;
            io_numberArray[ arrayIndex ] = value;
            io_numberArray.boundsArray_byChannel.enlarge_one_byN( c, value );

            valueNoRand += valueStepPerChannel;
          }
          valueNoRandBegin += valueStep;
        }
      }

    } else {

      for ( let h = 0; h < height; ++h ) {
        for ( let w = 0; w < width; ++w ) {

          valueNoRand = valueNoRandBegin;
          for ( let c = 0; c < channelCount; ++c, ++arrayIndex ) {

//!!! (2022/08/04 Temp Remarked) for re-producible random.
            // randomOffset = Math.floor( ( Math.random() * randomOffsetKindsInt ) + randomOffsetMinInt );
            if ( ( arrayIndex % 2 ) == 0 )
              randomOffset = randomOffsetMinInt;
            else
              randomOffset = randomOffsetMaxInt;

            value = ( valueNoRand + randomOffset ) % divisorForRemainder;
            io_numberArray[ arrayIndex ] = value;
            valueNoRand += valueStepPerChannel;
          }
          valueNoRandBegin += valueStep;
        }
      }
    }

  } catch ( e ) {
    debugger;
    throw e;
  }

  return io_numberArray;
}

/**
 *
 * @param {number} height        The length of axis0 of the io_numberArray.
 * @param {number} width         The length of axis1 of the io_numberArray.
 * @param {number} channelCount  The length of axis2 of the io_numberArray.
 *
 * @return {number[]}
 *   Return a number array.
 *
 * @see fill_integerArray()
 */
function generate_numberArray(
  height, width, channelCount,
  valueBegin = 0, valueStep = 1,
  randomOffsetMin = 0, randomOffsetMax = 0, divisorForRemainder = ( 2 ** 26 )
) {

  let numberArray = new Array();
  return fill_numberArray( numberArray,
    height, width, channelCount,
    valueBegin, valueStep,
    randomOffsetMin, randomOffsetMax, divisorForRemainder );
}
<|endoftext|>


<commit_before>/**
 * Yii GridView widget.
 *
 * This is the JavaScript widget used by the yii\grid\GridView widget.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
(function ($) {
    $.fn.yiiGridView = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
            return false;
        }
    };

    var defaults = {
        filterUrl: undefined,
        filterSelector: undefined
    };

    var gridData = {};

    var gridEvents = {
        /**
         * beforeFilter event is triggered before filtering the grid.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         *
         * If the handler returns a boolean false, it will stop filter form submission after this event. As
         * a result, afterFilter event will not be triggered.
         */
        beforeFilter: 'beforeFilter',
        /**
         * afterFilter event is triggered after filtering the grid and filtered results are fetched.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         */
        afterFilter: 'afterFilter'
    };

    var methods = {
        init: function (options) {
            return this.each(function () {
                var $e = $(this);
                var settings = $.extend({}, defaults, options || {});
                var id = $e.attr('id');
                if (gridData[id] === undefined) {
                    gridData[id] = {};
                }

                gridData[id] = $.extend(gridData[id], {settings: settings});

                var enterPressed = false;
                $(document).off('change.yiiGridView keydown.yiiGridView', settings.filterSelector)
                    .on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
                        if (event.type === 'keydown') {
                            if (event.keyCode !== 13) {
                                return; // only react to enter key
                            } else {
                                enterPressed = true;
                            }
                        } else {
                            // prevent processing for both keydown and change events
                            if (enterPressed) {
                                enterPressed = false;
                                return;
                            }
                        }

                        methods.applyFilter.apply($e);

                        return false;
                    });
            });
        },

        applyFilter: function () {
            var $grid = $(this), event;
            var settings = gridData[$grid.attr('id')].settings;
            var data = {};
            $.each($(settings.filterSelector).serializeArray(), function () {
                if (!(this.name in data)) {
                    data[this.name] = [];
                }
                data[this.name].push(this.value);
            });

            var namesInFilter = Object.keys(data);

            $.each(yii.getQueryParams(settings.filterUrl), function (name, value) {
                if (namesInFilter.indexOf(name) === -1 && namesInFilter.indexOf(name.replace(/\[\]$/, '')) === -1) {
                    if (!$.isArray(value)) {
                        value = [value];
                    }
                    if (!(name in data)) {
                        data[name] = value;
                    } else {
                        $.each(value, function (i, val) {
                            if ($.inArray(val, data[name])) {
                                data[name].push(val);
                            }
                        });
                    }
                }
            });

            var pos = settings.filterUrl.indexOf('?');
            var url = pos < 0 ? settings.filterUrl : settings.filterUrl.substring(0, pos);

            $grid.find('form.gridview-filter-form').remove();
            var $form = $('<form/>', {
                action: url,
                method: 'get',
                class: 'gridview-filter-form',
                style: 'display:none',
                'data-pjax': ''
            }).appendTo($grid);
            $.each(data, function (name, values) {
                $.each(values, function (index, value) {
                    $form.append($('<input/>').attr({type: 'hidden', name: name, value: value}));
                });
            });

            event = $.Event(gridEvents.beforeFilter);
            $grid.trigger(event);
            if (event.result === false) {
                return;
            }

            $form.submit();

            $grid.trigger(gridEvents.afterFilter);
        },

        setSelectionColumn: function (options) {
            var $grid = $(this);
            var id = $(this).attr('id');
            if (gridData.id === undefined) {
                gridData[id] = {};
            }
            gridData[id].selectionColumn = options.name;
            if (!options.multiple || !options.checkAll) {
                return;
            }
            var checkAll = "#" + id + " input[name='" + options.checkAll + "']";
            var inputs = "#" + id + " input[name='" + options.name + "']";
            $(document).off('click.yiiGridView', checkAll).on('click.yiiGridView', checkAll, function () {
                $grid.find("input[name='" + options.name + "']:enabled").prop('checked', this.checked);
            });
            $(document).off('click.yiiGridView', inputs + ":enabled").on('click.yiiGridView', inputs + ":enabled", function () {
                var all = $grid.find("input[name='" + options.name + "']").length == $grid.find("input[name='" + options.name + "']:checked").length;
                $grid.find("input[name='" + options.checkAll + "']").prop('checked', all);
            });
        },

        getSelectedRows: function () {
            var $grid = $(this);
            var data = gridData[$grid.attr('id')];
            var keys = [];
            if (data.selectionColumn) {
                $grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
                    keys.push($(this).parent().closest('tr').data('key'));
                });
            }
            return keys;
        },

        destroy: function () {
            return this.each(function () {
                $(window).unbind('.yiiGridView');
                $(this).removeData('yiiGridView');
            });
        },

        data: function () {
            var id = $(this).attr('id');
            return gridData[id];
        }
    };
})(window.jQuery);
<commit_msg>YUI Compressor fix<commit_after>/**
 * Yii GridView widget.
 *
 * This is the JavaScript widget used by the yii\grid\GridView widget.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
(function ($) {
    $.fn.yiiGridView = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
            return false;
        }
    };

    var defaults = {
        filterUrl: undefined,
        filterSelector: undefined
    };

    var gridData = {};

    var gridEvents = {
        /**
         * beforeFilter event is triggered before filtering the grid.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         *
         * If the handler returns a boolean false, it will stop filter form submission after this event. As
         * a result, afterFilter event will not be triggered.
         */
        beforeFilter: 'beforeFilter',
        /**
         * afterFilter event is triggered after filtering the grid and filtered results are fetched.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         */
        afterFilter: 'afterFilter'
    };

    var methods = {
        init: function (options) {
            return this.each(function () {
                var $e = $(this);
                var settings = $.extend({}, defaults, options || {});
                var id = $e.attr('id');
                if (gridData[id] === undefined) {
                    gridData[id] = {};
                }

                gridData[id] = $.extend(gridData[id], {settings: settings});

                var enterPressed = false;
                $(document).off('change.yiiGridView keydown.yiiGridView', settings.filterSelector)
                    .on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
                        if (event.type === 'keydown') {
                            if (event.keyCode !== 13) {
                                return; // only react to enter key
                            } else {
                                enterPressed = true;
                            }
                        } else {
                            // prevent processing for both keydown and change events
                            if (enterPressed) {
                                enterPressed = false;
                                return;
                            }
                        }

                        methods.applyFilter.apply($e);

                        return false;
                    });
            });
        },

        applyFilter: function () {
            var $grid = $(this), event;
            var settings = gridData[$grid.attr('id')].settings;
            var data = {};
            $.each($(settings.filterSelector).serializeArray(), function () {
                if (!(this.name in data)) {
                    data[this.name] = [];
                }
                data[this.name].push(this.value);
            });

            var namesInFilter = Object.keys(data);

            $.each(yii.getQueryParams(settings.filterUrl), function (name, value) {
                if (namesInFilter.indexOf(name) === -1 && namesInFilter.indexOf(name.replace(/\[\]$/, '')) === -1) {
                    if (!$.isArray(value)) {
                        value = [value];
                    }
                    if (!(name in data)) {
                        data[name] = value;
                    } else {
                        $.each(value, function (i, val) {
                            if ($.inArray(val, data[name])) {
                                data[name].push(val);
                            }
                        });
                    }
                }
            });

            var pos = settings.filterUrl.indexOf('?');
            var url = pos < 0 ? settings.filterUrl : settings.filterUrl.substring(0, pos);

            $grid.find('form.gridview-filter-form').remove();
            var $form = $('<form/>', {
                action: url,
                method: 'get',
                'class': 'gridview-filter-form',
                style: 'display:none',
                'data-pjax': ''
            }).appendTo($grid);
            $.each(data, function (name, values) {
                $.each(values, function (index, value) {
                    $form.append($('<input/>').attr({type: 'hidden', name: name, value: value}));
                });
            });

            event = $.Event(gridEvents.beforeFilter);
            $grid.trigger(event);
            if (event.result === false) {
                return;
            }

            $form.submit();

            $grid.trigger(gridEvents.afterFilter);
        },

        setSelectionColumn: function (options) {
            var $grid = $(this);
            var id = $(this).attr('id');
            if (gridData.id === undefined) {
                gridData[id] = {};
            }
            gridData[id].selectionColumn = options.name;
            if (!options.multiple || !options.checkAll) {
                return;
            }
            var checkAll = "#" + id + " input[name='" + options.checkAll + "']";
            var inputs = "#" + id + " input[name='" + options.name + "']";
            $(document).off('click.yiiGridView', checkAll).on('click.yiiGridView', checkAll, function () {
                $grid.find("input[name='" + options.name + "']:enabled").prop('checked', this.checked);
            });
            $(document).off('click.yiiGridView', inputs + ":enabled").on('click.yiiGridView', inputs + ":enabled", function () {
                var all = $grid.find("input[name='" + options.name + "']").length == $grid.find("input[name='" + options.name + "']:checked").length;
                $grid.find("input[name='" + options.checkAll + "']").prop('checked', all);
            });
        },

        getSelectedRows: function () {
            var $grid = $(this);
            var data = gridData[$grid.attr('id')];
            var keys = [];
            if (data.selectionColumn) {
                $grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
                    keys.push($(this).parent().closest('tr').data('key'));
                });
            }
            return keys;
        },

        destroy: function () {
            return this.each(function () {
                $(window).unbind('.yiiGridView');
                $(this).removeData('yiiGridView');
            });
        },

        data: function () {
            var id = $(this).attr('id');
            return gridData[id];
        }
    };
})(window.jQuery);
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   xTuple Postbooks - Business Management System Framework
// Copyright: ©2012 OpenMFG LLC, d/b/a xTuple
// ==========================================================================
/*globals SC */

/**
  Registers the child record and set the parent on the child's foreign key
  as soon as it is pushed on to the array.
*/
SC.ChildArray.prototype.pushObject = function(obj) {
  var parent = this.get('record'),
      store = parent.get('store'),
      psk = parent.get('storeKey'),
      csk = obj.get('storeKey'),
      propertyName = this.get('propertyName'),
      path;

  // do what we're here for
  this.insertAt(this.get('length'), obj);

  // register child
  parent.isParentRecord = true;
  store.registerChildToParent(psk, csk, path);
  path = store.parentRecords[psk][csk];
  parent.recordDidChange(path);

  // set the parent on the child's foreign key
  if (parent[propertyName] && parent[propertyName].inverse) {
    var key = parent[propertyName].inverse;
       // value = obj[key].isNested ? parent : parent.get('id');
    obj.set(key, parent);
  }

  return obj;
}
<commit_msg>avoid KVO interference.<commit_after>// ==========================================================================
// Project:   xTuple Postbooks - Business Management System Framework
// Copyright: ©2012 OpenMFG LLC, d/b/a xTuple
// ==========================================================================
/*globals SC */

/**
  Registers the child record and set the parent on the child's foreign key
  as soon as it is pushed on to the array.
*/
SC.ChildArray.prototype.pushObject = function(obj) {
  this.insertAt(this.get('length'), obj);

  var parent = this.get('record'),
      store = parent.get('store'),
      psk = parent.get('storeKey'),
      csk = obj.get('storeKey'),
      propertyName = this.get('propertyName'),
      path;

  // register child
  parent.isParentRecord = true;
  store.registerChildToParent(psk, csk, path);
  path = store.parentRecords[psk][csk];
  parent.recordDidChange(path);

  // set the parent on the child's foreign key
  if (parent[propertyName] && parent[propertyName].inverse) {
    var key = parent[propertyName].inverse;
       // value = obj[key].isNested ? parent : parent.get('id');
    obj.set(key, parent);
  }

  return obj;
}
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { connect } from "react-redux";
import { BrowserRouter, Redirect, Route } from "react-router-dom";

import { Layout, Menu } from "antd";
const { Header, Content, Footer } = Layout;

import { callAPI } from "../../actions/api.actions";

import FileManager from "../FileManager";
import IdiotBoxHeader from "./IdiotBoxHeader";
import MoviesList from "../Movies/MoviesList";
import NewEpisodes from "../NewEpisodes";
import Settings from "../Settings/Settings";
import ShowInfo from "../Shows/ShowInfo/ShowInfo";
import ShowsList from "../Shows/ShowsList";

const IdiotBoxLayout = props => {
    return (
        <BrowserRouter>
            <Layout className="layout">
                <IdiotBoxHeader />
                <Content style={{ padding: "0 50px" }}>

                        <Route
                            path="/"
                            exact
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/newepisodes"
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/filemanager/:setting_key?/:subpath?"
                            render={routeParams => (
                                <FileManager
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/movies"
                            render={routeParams => (
                                <MoviesList
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />
                        <Route path="/settings" component={Settings} />
                        <Route
                            path="/shows"
                            render={routeParams => (
                                <ShowsList
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />
                        <Route
                            path={`/show/:slug/:season_number?`}
                            render={routeParams => (
                                <ShowInfo
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />

                </Content>

                    Idiot Box created by Destin Moulton

            </Layout>
        </BrowserRouter>
    );
};

const mapStateToProps = state => {
    const { settings } = state;
    return {
        settings: settings.settings
    };
};

const mapDispatchToProps = dispatch => {
    return {
        callAPI: (endpoint, params, callback, shouldDispatch) =>
            dispatch(callAPI(endpoint, params, callback, shouldDispatch))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(IdiotBoxLayout);
<commit_msg>Added serverInfo to the FileManager.<commit_after>import React, { Component } from "react";
import { connect } from "react-redux";
import { BrowserRouter, Redirect, Route } from "react-router-dom";

import { Layout, Menu } from "antd";
const { Header, Content, Footer } = Layout;

import { callAPI } from "../../actions/api.actions";

import FileManager from "../FileManager";
import IdiotBoxHeader from "./IdiotBoxHeader";
import MoviesList from "../Movies/MoviesList";
import NewEpisodes from "../NewEpisodes";
import Settings from "../Settings/Settings";
import ShowInfo from "../Shows/ShowInfo/ShowInfo";
import ShowsList from "../Shows/ShowsList";

const IdiotBoxLayout = props => {
    return (
        <BrowserRouter>
            <Layout className="layout">
                <IdiotBoxHeader />
                <Content style={{ padding: "0 50px" }}>

                        <Route
                            path="/"
                            exact
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/newepisodes"
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/filemanager/:setting_key?/:subpath?"
                            render={routeParams => (
                                <FileManager
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                    serverInfo={props.server}
                                />
                            )}
                        />
                        <Route
                            path="/movies"
                            render={routeParams => (
                                <MoviesList
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />
                        <Route path="/settings" component={Settings} />
                        <Route
                            path="/shows"
                            render={routeParams => (
                                <ShowsList
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />
                        <Route
                            path={`/show/:slug/:season_number?`}
                            render={routeParams => (
                                <ShowInfo
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />

                </Content>

                    Idiot Box created by Destin Moulton

            </Layout>
        </BrowserRouter>
    );
};

const mapStateToProps = state => {
    const { server, settings } = state;
    return {
        settings: settings.settings,
        server: server.serverInfo
    };
};

const mapDispatchToProps = dispatch => {
    return {
        callAPI: (endpoint, params, callback, shouldDispatch) =>
            dispatch(callAPI(endpoint, params, callback, shouldDispatch))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(IdiotBoxLayout);
<|endoftext|>


<commit_before>import React from "react";

import { truncate } from "lodash";
import { Col, Icon } from "antd";

import PlayButton from "../PlayButton";
import StatusTagIcons from "./StatusTagIcons";

class MovieThumbInfo extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isMouseOverMovie: false,
            isMouseOverVeil: false
        };
    }

    _handleClick(movie) {
        this.props.onClickMovie(movie);
    }

    _handleClickDelete() {
        this.props.onClickDelete(this.props.movie);
    }

    _handleMouseOverMovie() {
        this.setState({
            isMouseOverMovie: true
        });
    }

    _handleMouseOutMovie() {
        this.setState({
            isMouseOverMovie: false
        });
    }

    render() {
        const {
            directories,
            movie,
            onClickMovie,
            onClickToggleStatusTag
        } = this.props;
        const fullPath = directories.Movies + "/" + movie.file_info.subpath;
        const movieTitle = {
            __html: truncate(movie.title, { length: 30 })
        };

        let veilOptions = null;
        if (this.state.isMouseOverMovie) {
            veilOptions = (

                    <PlayButton
                        filename={movie.file_info.filename}
                        fullPath={fullPath}
                    />

                        <Icon type="delete" className="ib-playbutton-icon" />

            );
        }
        return (

                {veilOptions}

                    <StatusTagIcons
                        movie={movie}
                        onClickToggleStatusTag={onClickToggleStatusTag}
                    />

        );
    }
}

export default MovieThumbInfo;
<commit_msg>Fixed minor bug with class to className.<commit_after>import React from "react";

import { truncate } from "lodash";
import { Col, Icon } from "antd";

import PlayButton from "../PlayButton";
import StatusTagIcons from "./StatusTagIcons";

class MovieThumbInfo extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isMouseOverMovie: false,
            isMouseOverVeil: false
        };
    }

    _handleClick(movie) {
        this.props.onClickMovie(movie);
    }

    _handleClickDelete() {
        this.props.onClickDelete(this.props.movie);
    }

    _handleMouseOverMovie() {
        this.setState({
            isMouseOverMovie: true
        });
    }

    _handleMouseOutMovie() {
        this.setState({
            isMouseOverMovie: false
        });
    }

    render() {
        const {
            directories,
            movie,
            onClickMovie,
            onClickToggleStatusTag
        } = this.props;
        const fullPath = directories.Movies + "/" + movie.file_info.subpath;
        const movieTitle = {
            __html: truncate(movie.title, { length: 30 })
        };

        let veilOptions = null;
        if (this.state.isMouseOverMovie) {
            veilOptions = (

                    <PlayButton
                        filename={movie.file_info.filename}
                        fullPath={fullPath}
                    />

                        <Icon type="delete" className="ib-playbutton-icon" />

            );
        }
        return (

                {veilOptions}

                    <StatusTagIcons
                        movie={movie}
                        onClickToggleStatusTag={onClickToggleStatusTag}
                    />

        );
    }
}

export default MovieThumbInfo;
<|endoftext|>