<commit_before>/**@module request/register */
"use strict";

var revalidator = require( 'revalidator' );
var Q           = require( 'q' );
var _           = require( 'lodash' )._;
var uri         = require( 'uri-js' );

var regex    = require( '../regex' );
var error    = require( '../error' );
var database = require( '../database' );
var mailer   = require( '../mailer' );
var util     = require( '../utilities' );
var server   = require( '../../server' );
var config   = require( '../config' );
var app      = server.app;

var schema = {
    properties: {

        email: {
            type: 'string',
            format: 'email',
            required: true
        },

        firstName: {
            type: 'string',
            allowEmpty: false,
            required: true
        },

        lastName: {
            type: 'string',
            allowEmpty: false,
            required: true
        },

        password: {
            type: 'string',
            pattern: regex.sha256,
            required: true,
            messages: {
                pattern: "not a valid hash"
            }
        },

        appData: {
            type: 'object',
            required: false,
            description: "The user added data to go into the database along with the user"
        }

    }
};

function validateRegisterRequest( req ) {
    return Q.Promise( function ( resolve, reject ) {

        var validation = revalidator.validate( req.headers.bridge, schema );

        if ( validation.valid === false ) {
            var firstError = validation.errors[ 0 ];

            var errorCode;

            switch ( firstError.property ) {
                case 'email':
                    errorCode = 'emailInvalid';
                    break;
                case 'password':
                    errorCode = 'passwordInvalid';
                    break;
                case 'firstName':
                    errorCode = 'firstNameInvalid';
                    break;
                case 'lastName':
                    errorCode = 'lastNameInvalid';
                    break;
                default:
                    errorCode = 'malformedRequest';
                    break;
            }

            var regError = error.createError( 400, errorCode, firstError.property + " : " + firstError.message );

            reject( regError );
            return;
        }

        resolve();

    } );
}

function getUserObject( req ) {
    return Q.Promise( function ( resolve, reject ) {
        resolve( req.headers.bridge );
    } );
}

/**
 * Sends a email to verify a registration request.
 * *NOTE* ONLY used when email verification is turned on.
 *
 * @param  {User}  user             A user object in the form of the DB Table relating to the user
 *                                  where each column is a variable my the column name.
 *
 * @param  {Object} emailVariables  The variables that get fed into the email template to fill in
 *                                  the template variables.
 *
 * @return {Promise}   A Q style promise object
 */
function sendVerificationEmail( user, emailVariables ) {
    return Q.Promise( function ( resolve, reject ) {

        if ( config.server.emailVerification === true ) {

            var viewName = config.mailer.verificationEmail.viewName;

            var url = uri.parse( app.get( 'rootURL' ) );

            var mail = {
                to      : user.email,
                subject : config.mailer.verificationEmail.subject
            };

            if ( !_.isObject( emailVariables ) ) {
                emailVariables = {};
            }

            emailVariables.verificationURL = uri.parse( app.get( 'rootURL' ) );

            var fragment = uri.serialize( {
                path: '/account-verification',
                query: 'hash=' + user.hash
            } );

            //emailVariables.verificationURL.path = "/";
            emailVariables.verificationURL.fragment = fragment;
            emailVariables.verificationURL = uri.serialize( emailVariables.verificationURL );

            mailer.sendMail( viewName, emailVariables, mail )
            .then( function() {
                resolve();
            } )
            .fail( function( err ) {
                database.query( "DELETE FROM users WHERE EMAIL = ?", [ user.email ] )
                .then( function() {
                    reject( err );
                } )
                .fail( function( dbErr ) {
                    reject( 500, 'could not delete new user upon email failing to send', dbErr );
                } );
            } );
        } else {
            resolve();
        }

    } );
}

function sendReponse( res ) {
    return Q.Promise( function ( resolve, reject ) {

        res.send( {
            content: "User registered successfully!"
        } );

        res.status( 200 );

        resolve();
    } );
}

module.exports = function ( req, res, next ) {

    // Validate the structure of the request against the registration schema
    validateRegisterRequest( req )

    // Get the user object out of the request
    .then( function () {
        return getUserObject( req );
    } )

    // Register the user object using the re
    .then( function ( user ) {
        return database.registerUser( req, user );
    } )

    // Run the user extension function. This should work as a promise
    .then( function() {
        var userFunc = app.get( 'registerMiddleware' );
        if ( _.isFunction( userFunc ) ) {
            return userFunc( req.   bridge.user, req, res );
        }
    } )

    // Send the verification email using the user object
    .then( function ( emailVariables ) {
        return sendVerificationEmail( req.bridge.user, emailVariables );
    } )

    // Send the successful response message
    .then( function () {
        return sendReponse( res );
    } )

    // Catch any errors that occurred in the above middle ware
    .fail( function ( err ) {
        next( err );
    } );
};
<commit_msg>Made a small modifcation to the mailer in an attempt to fix the verification URL for emails<commit_after>/**@module request/register */
"use strict";

var revalidator = require( 'revalidator' );
var Q           = require( 'q' );
var _           = require( 'lodash' )._;
var uri         = require( 'uri-js' );

var regex    = require( '../regex' );
var error    = require( '../error' );
var database = require( '../database' );
var mailer   = require( '../mailer' );
var util     = require( '../utilities' );
var server   = require( '../../server' );
var config   = require( '../config' );
var app      = server.app;

var schema = {
    properties: {

        email: {
            type: 'string',
            format: 'email',
            required: true
        },

        firstName: {
            type: 'string',
            allowEmpty: false,
            required: true
        },

        lastName: {
            type: 'string',
            allowEmpty: false,
            required: true
        },

        password: {
            type: 'string',
            pattern: regex.sha256,
            required: true,
            messages: {
                pattern: "not a valid hash"
            }
        },

        appData: {
            type: 'object',
            required: false,
            description: "The user added data to go into the database along with the user"
        }

    }
};

function validateRegisterRequest( req ) {
    return Q.Promise( function ( resolve, reject ) {

        var validation = revalidator.validate( req.headers.bridge, schema );

        if ( validation.valid === false ) {
            var firstError = validation.errors[ 0 ];

            var errorCode;

            switch ( firstError.property ) {
                case 'email':
                    errorCode = 'emailInvalid';
                    break;
                case 'password':
                    errorCode = 'passwordInvalid';
                    break;
                case 'firstName':
                    errorCode = 'firstNameInvalid';
                    break;
                case 'lastName':
                    errorCode = 'lastNameInvalid';
                    break;
                default:
                    errorCode = 'malformedRequest';
                    break;
            }

            var regError = error.createError( 400, errorCode, firstError.property + " : " + firstError.message );

            reject( regError );
            return;
        }

        resolve();

    } );
}

function getUserObject( req ) {
    return Q.Promise( function ( resolve, reject ) {
        resolve( req.headers.bridge );
    } );
}

/**
 * Sends a email to verify a registration request.
 * *NOTE* ONLY used when email verification is turned on.
 *
 * @param  {User}  user             A user object in the form of the DB Table relating to the user
 *                                  where each column is a variable my the column name.
 *
 * @param  {Object} emailVariables  The variables that get fed into the email template to fill in
 *                                  the template variables.
 *
 * @return {Promise}   A Q style promise object
 */
function sendVerificationEmail( user, emailVariables ) {
    return Q.Promise( function ( resolve, reject ) {

        if ( config.server.emailVerification === true ) {

            var viewName = config.mailer.verificationEmail.viewName;

            var url = uri.parse( app.get( 'rootURL' ) );

            var mail = {
                to      : user.email,
                subject : config.mailer.verificationEmail.subject
            };

            if ( !_.isObject( emailVariables ) ) {
                emailVariables = {};
            }

            emailVariables.verificationURL = uri.parse( app.get( 'rootURL' ) );

            var fragment = uri.serialize( {
                path: '/account-verification',
                query: 'hash=' + user.hash
            } );

            emailVariables.verificationURL.fragment = fragment;
            emailVariables.verificationURL = uri.serialize( emailVariables.verificationURL );

            mailer.sendMail( viewName, emailVariables, mail )
            .then( function() {
                resolve();
            } )
            .fail( function( err ) {
                database.query( "DELETE FROM users WHERE EMAIL = ?", [ user.email ] )
                .then( function() {
                    reject( err );
                } )
                .fail( function( dbErr ) {
                    reject( 500, 'could not delete new user upon email failing to send', dbErr );
                } );
            } );
        } else {
            resolve();
        }

    } );
}

function sendReponse( res ) {
    return Q.Promise( function ( resolve, reject ) {

        res.send( {
            content: "User registered successfully!"
        } );

        res.status( 200 );

        resolve();
    } );
}

module.exports = function ( req, res, next ) {

    // Validate the structure of the request against the registration schema
    validateRegisterRequest( req )

    // Get the user object out of the request
    .then( function () {
        return getUserObject( req );
    } )

    // Register the user object using the re
    .then( function ( user ) {
        return database.registerUser( req, user );
    } )

    // Run the user extension function. This should work as a promise
    .then( function() {
        var userFunc = app.get( 'registerMiddleware' );
        if ( _.isFunction( userFunc ) ) {
            return userFunc( req.   bridge.user, req, res );
        }
    } )

    // Send the verification email using the user object
    .then( function ( emailVariables ) {
        return sendVerificationEmail( req.bridge.user, emailVariables );
    } )

    // Send the successful response message
    .then( function () {
        return sendReponse( res );
    } )

    // Catch any errors that occurred in the above middle ware
    .fail( function ( err ) {
        next( err );
    } );
};
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');

function isTicketingAdmin (args, cb) {
  var seneca = this;
  var plugin = args.role;
  var userId, dojoId;
  if(args.user) userId = args.user.id;

  if (args.params) {
    if(args.params.query) dojoId = args.params.query.dojoId;
    if(args.params.eventInfo && _.isUndefined(dojoId)) dojoId = args.params.eventInfo.dojoId;
    if(args.params.query && _.isUndefined(dojoId)) dojoId = args.params.query.id;
  } else {
    if(args.query) dojoId = args.query.dojoId;
    if(args.eventInfo && _.isUndefined(dojoId)) dojoId = args.eventInfo.dojoId;
    if(args.query && _.isUndefined(dojoId)) dojoId = args.query.id;
  }

  var isTicketingAdmin = false;
  //  Could also check the opposite way, from child to Parent
  seneca.act({role: 'cd-dojos', cmd: 'load_usersdojos', query: { userId: userId, dojoId: dojoId }},
    function (err, response) {
      var userDojoEntity = response[0];
      if (err) {
        seneca.log.error(seneca.customValidatorLogFormatter('cd-events', 'isTicketingAdmin', err, {userId: userId, dojoId: dojoId}));
        return cb(null, {'allowed': false});
      }
      isTicketingAdmin = _.find(userDojoEntity.userPermissions, function (userPermission) {
        return userPermission.name === 'ticketing-admin';
      });
      return cb(null, {'allowed': !!isTicketingAdmin});
  });
}

module.exports = isTicketingAdmin;
<commit_msg>Fix issue where a dojo-admin would not be able to use manage-event-us… (#163)<commit_after>'use strict';
var _ = require('lodash');
var async = require('async');

function isTicketingAdmin (args, cb) {
  var seneca = this;
  var plugin = args.role;
  var userId, dojoId, eventId, sessionId;
  if(args.user) userId = args.user.id;

  if (args.params) {
    if(args.params.query) dojoId = args.params.query.dojoId;
    if(args.params.eventInfo && _.isUndefined(dojoId)) dojoId = args.params.eventInfo.dojoId;
    if(args.params.query && _.isUndefined(dojoId)) dojoId = args.params.query.id;
    if(args.params.query && _.isUndefined(dojoId)) eventId = args.params.query.eventId;
    if(args.params.query && _.isUndefined(dojoId) && _.isUndefined(eventId)) sessionId = args.params.query.sessionId;
  } else {
    if(args.query) dojoId = args.query.dojoId;
    if(args.eventInfo && _.isUndefined(dojoId)) dojoId = args.eventInfo.dojoId;
    if(args.query && _.isUndefined(dojoId)) dojoId = args.query.id;
  }

  var isTicketingAdmin = false;
  //  Could also check the opposite way, from child to Parent
  function checkPrerequisites (wfCb) {
    function getEventFromSession (_wCb) {
      if (sessionId) { // We need to get the dojoId associated
        seneca.act({role: 'cd-events', cmd: 'loadSession', id: sessionId}, function (err, session) {
          if (err) return cb(err);
          if (session.eventId) {
            eventId = session.eventId;
            return _wCb();
          } else {
            return cb(null, {'allowed': false});
          }
        });
      } else {
        return _wCb();
      }
    }
    function getDojoFromEvent (_wCb) {
      if (eventId) { // We need to get the dojoId associated
        seneca.act({role: 'cd-events', cmd: 'getEvent', id: eventId}, function (err, event) {
          if (err) return cb(err);
          if (event.dojoId) {
            dojoId = event.dojoId;
            return _wCb();
          } else {
            return cb(null, {'allowed': false});
          }
        });
      } else {
        return _wCb();
      }
    }
    if (_.isUndefined(dojoId) && (eventId || sessionId)) {
      async.waterfall([
        getEventFromSession,
        getDojoFromEvent
      ], wfCb);
    } else {
      return wfCb();
    }
  }
  function verifyPermissions(wfCb) {
    if (_.isUndefined(dojoId)) return cb(null, {'allowed': false});
    seneca.act({role: 'cd-dojos', cmd: 'load_usersdojos', query: { userId: userId, dojoId: dojoId, deleted: 0 }},
    function (err, response) {
      var userDojoEntity = response[0];
      if (err) {
        seneca.log.error(seneca.customValidatorLogFormatter('cd-events', 'isTicketingAdmin', err, {userId: userId, dojoId: dojoId}));
        return cb(null, {'allowed': false});
      }
      isTicketingAdmin = _.find(userDojoEntity.userPermissions, function (userPermission) {
        return userPermission.name === 'ticketing-admin';
      });
      return cb(null, {'allowed': !!isTicketingAdmin});
    });
  }
  async.waterfall([
    checkPrerequisites,
    verifyPermissions
  ]);
}

module.exports = isTicketingAdmin;
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');

function init() {

  var TIME_10_MINS_MS = 10 * 60 * 1000;

  function treatmentnotify() {
    return treatmentnotify;
  }

  treatmentnotify.label = 'Treatment Notifications';
  treatmentnotify.pluginType = 'notification';

  treatmentnotify.checkNotifications = function checkNotifications (sbx) {

    var now = Date.now();

    var lastMBG = sbx.lastEntry(sbx.data.mbgs);
    var lastTreatment = sbx.lastEntry(sbx.data.treatments);

    //TODO: figure out why date is x here #CleanUpDataModel
    var lastMBGTime = lastMBG ? lastMBG.mills : 0;
    var mbgAgo = (lastMBGTime && lastMBGTime <= now) ? now - lastMBGTime : -1;
    var mbgCurrent = mbgAgo !== -1 && mbgAgo < TIME_10_MINS_MS;

    var lastTreatmentTime = lastTreatment ? lastTreatment.mills : 0;
    var treatmentAgo = (lastTreatmentTime && lastTreatmentTime <= now) ? now - lastTreatmentTime : -1;
    var treatmentCurrent = treatmentAgo !== -1 && treatmentAgo < TIME_10_MINS_MS;

    if (mbgCurrent || treatmentCurrent) {

      var mbgMessage = mbgCurrent ? 'Meter BG ' + sbx.scaleBg(lastMBG.y) + ' ' + sbx.unitsLabel : '';
      var treatmentMessage = treatmentCurrent ? 'Treatment: ' + lastTreatment.eventType : '';
      autoSnoozeAlarms(mbgMessage, treatmentMessage, sbx);
      //and add some info notifications
      //the notification providers (push, websockets, etc) are responsible to not sending the same notifications repeatedly
      if (mbgCurrent) { requestMBGNotify(lastMBG, sbx); }
      if (treatmentCurrent) { requestTreatmentNotify(lastTreatment, sbx); }
    }
  };

  function autoSnoozeAlarms(mbgMessage, treatmentMessage, sbx) {
    var snoozeLength = (sbx.extendedSettings.snoozeMins && Number(sbx.extendedSettings.snoozeMins) * 60 * 1000) || TIME_10_MINS_MS;
    sbx.notifications.requestSnooze({
      level: sbx.notifications.levels.URGENT
      , title: 'Snoozing alarms since there was a recent treatment'
      , message: _.trim([mbgMessage, treatmentMessage].join('\n'))
      , lengthMills: snoozeLength
    });
  }

  function requestMBGNotify (lastMBG, sbx) {
    console.info('requestMBGNotify for', lastMBG);
    sbx.notifications.requestNotify({
      level: sbx.notifications.levels.INFO
      , title: 'Calibration' //assume all MGBs are calibrations for now
      //TODO: figure out why mbg is y here #CleanUpDataModel
      , message: 'Meter BG: ' + sbx.scaleBg(lastMBG.y) + ' ' + sbx.unitsLabel
      , plugin: treatmentnotify
      , pushoverSound: 'magic'
    });
  }

  function requestTreatmentNotify (lastTreatment, sbx) {
    var message = (lastTreatment.glucose ? 'BG: ' + lastTreatment.glucose + ' (' + lastTreatment.glucoseType + ')' : '') +
      (lastTreatment.carbs ? '\nCarbs: ' + lastTreatment.carbs + 'g' : '') +

      //TODO: find a better way to connect split treatments
      //(preBolusCarbs ? '\nCarbs: ' + preBolusCarbs + ' (in ' + treatment.preBolus + ' minutes)' : '')+

      (lastTreatment.insulin ? '\nInsulin: ' + sbx.roundInsulinForDisplayFormat(lastTreatment.insulin) + 'U' : '')+
      (lastTreatment.enteredBy ? '\nEntered By: ' + lastTreatment.enteredBy : '') +

      //TODO: find a better way to store timeAdjustment
      //(timeAdjustment ? '\nEvent Time: ' + timeAdjustment : '') +

      (lastTreatment.notes ? '\nNotes: ' + lastTreatment.notes : '');

    sbx.notifications.requestNotify({
      level: sbx.notifications.levels.INFO
      , title: lastTreatment.eventType
      , message: message
      , plugin: treatmentnotify
    });

  }

  return treatmentnotify();

}

module.exports = init;<commit_msg>some refactoring for treatmentnotify.checkNotifications<commit_after>'use strict';

var _ = require('lodash');

var TIME_10_MINS_MS = 10 * 60 * 1000;

function init() {

  function treatmentnotify() {
    return treatmentnotify;
  }

  treatmentnotify.label = 'Treatment Notifications';
  treatmentnotify.pluginType = 'notification';

  treatmentnotify.checkNotifications = function checkNotifications (sbx) {
    var lastMBG = sbx.lastEntry(sbx.data.mbgs);
    var lastTreatment = sbx.lastEntry(sbx.data.treatments);

    var mbgCurrent = isCurrent(lastMBG);
    var treatmentCurrent = isCurrent(lastTreatment);

    if (mbgCurrent || treatmentCurrent) {
      var mbgMessage = mbgCurrent ? 'Meter BG ' + sbx.scaleBg(lastMBG.y) + ' ' + sbx.unitsLabel : '';
      var treatmentMessage = treatmentCurrent ? 'Treatment: ' + lastTreatment.eventType : '';
      autoSnoozeAlarms(mbgMessage, treatmentMessage, sbx);
      //and add some info notifications
      //the notification providers (push, websockets, etc) are responsible to not sending the same notifications repeatedly
      if (mbgCurrent) { requestMBGNotify(lastMBG, sbx); }
      if (treatmentCurrent) { requestTreatmentNotify(lastTreatment, sbx); }
    }
  };

  function autoSnoozeAlarms(mbgMessage, treatmentMessage, sbx) {
    var snoozeLength = (sbx.extendedSettings.snoozeMins && Number(sbx.extendedSettings.snoozeMins) * 60 * 1000) || TIME_10_MINS_MS;
    sbx.notifications.requestSnooze({
      level: sbx.notifications.levels.URGENT
      , title: 'Snoozing alarms since there was a recent treatment'
      , message: _.trim([mbgMessage, treatmentMessage].join('\n'))
      , lengthMills: snoozeLength
    });
  }

  function requestMBGNotify (lastMBG, sbx) {
    console.info('requestMBGNotify for', lastMBG);
    sbx.notifications.requestNotify({
      level: sbx.notifications.levels.INFO
      , title: 'Calibration' //assume all MGBs are calibrations for now
      //TODO: figure out why mbg is y here #CleanUpDataModel
      , message: 'Meter BG: ' + sbx.scaleBg(lastMBG.y) + ' ' + sbx.unitsLabel
      , plugin: treatmentnotify
      , pushoverSound: 'magic'
    });
  }

  function requestTreatmentNotify (lastTreatment, sbx) {
    var message = (lastTreatment.glucose ? 'BG: ' + lastTreatment.glucose + ' (' + lastTreatment.glucoseType + ')' : '') +
      (lastTreatment.carbs ? '\nCarbs: ' + lastTreatment.carbs + 'g' : '') +

      //TODO: find a better way to connect split treatments
      //(preBolusCarbs ? '\nCarbs: ' + preBolusCarbs + ' (in ' + treatment.preBolus + ' minutes)' : '')+

      (lastTreatment.insulin ? '\nInsulin: ' + sbx.roundInsulinForDisplayFormat(lastTreatment.insulin) + 'U' : '')+
      (lastTreatment.enteredBy ? '\nEntered By: ' + lastTreatment.enteredBy : '') +

      //TODO: find a better way to store timeAdjustment
      //(timeAdjustment ? '\nEvent Time: ' + timeAdjustment : '') +

      (lastTreatment.notes ? '\nNotes: ' + lastTreatment.notes : '');

    sbx.notifications.requestNotify({
      level: sbx.notifications.levels.INFO
      , title: lastTreatment.eventType
      , message: message
      , plugin: treatmentnotify
    });

  }

  return treatmentnotify();

}

function isCurrent(last) {
  var now = Date.now();
  var lastTime = last ? last.mills : 0;
  var ago = (lastTime && lastTime <= now) ? now - lastTime : -1;
  return ago !== -1 && ago < TIME_10_MINS_MS;
}

module.exports = init;<|endoftext|>


<commit_before>/*jshint node: true, -W106 */
'use strict';

/*
* Name : socket.js
* Module : Lib::PresentationTier::Routes
* Location : /lib/presentationTier
*
* History :
*
* Version   Date         Programmer         Description
* =========================================================
* 0.0.1     2015-05-20   Matteo Furlan      Working version with addRoutingPath
* 0.0.1     2015-05-18   Samuele Zanella    Initial code
* =========================================================
*/

var Express = require('express');

function Routes(exprApp, norrisNamespace) {
	if(exprApp===undefined || norrisNamespace===undefined || exprApp.lazyrouter===undefined ||
		typeof norrisNamespace !=='string' || norrisNamespace.length < 1 ||
		norrisNamespace.indexOf('/')!==0) {
		console.log('Error: 911');
		return;
	}

	this._baseURL='';
	this._norrisNamespace = norrisNamespace;
	this._exprApp=exprApp;
    this._routes.addRoutingPath(norrisNamespace,'pageList'); //page is pageList.ejs;
}

Routes.prototype.addRoutingPath = function(namespace, filename) {
	if(namespace===undefined || typeof namespace !=='string' || namespace.length < 1 ||
		namespace.indexOf('/')!==0 || filename === undefined || typeof filename !== 'string' ||
		filename.length <= 0) {
		console.log('Error: 912');
		return false;
	}

	var app = Express();
    app.set('view engine', 'ejs');
    app.set('views', __dirname + '/views');

    app.use('/',Express.static(__dirname + '/../../frontend/app/views'));

	var nspNorris=this._norrisNamespace;
	var baseURL='';
	var handle = function (req, res) {
		var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
		baseURL=req.protocol + '://' + req.get('host');
		var norrisNamespace=req.protocol + '://' + req.get('host')+nspNorris;
		res.render(filename,{fullURL:fullUrl, norrisNamespace : norrisNamespace});
	};
	this._baseURL=baseURL;

	app.get(namespace, handle);
	this._exprApp.use(namespace, app);

	return true;
};

module.exports = Routes;<commit_msg>fix error _routes<commit_after>/*jshint node: true, -W106 */
'use strict';

/*
* Name : socket.js
* Module : Lib::PresentationTier::Routes
* Location : /lib/presentationTier
*
* History :
*
* Version   Date         Programmer         Description
* =========================================================
* 0.0.1     2015-05-20   Matteo Furlan      Working version with addRoutingPath
* 0.0.1     2015-05-18   Samuele Zanella    Initial code
* =========================================================
*/

var Express = require('express');

function Routes(exprApp, norrisNamespace) {
	if(exprApp===undefined || norrisNamespace===undefined || exprApp.lazyrouter===undefined ||
		typeof norrisNamespace !=='string' || norrisNamespace.length < 1 ||
		norrisNamespace.indexOf('/')!==0) {
		console.log('Error: 911');
		return;
	}

	this._baseURL='';
	this._norrisNamespace = norrisNamespace;
	this._exprApp=exprApp;
    this.addRoutingPath(norrisNamespace,'pageList'); //page is pageList.ejs;
}

Routes.prototype.addRoutingPath = function(namespace, filename) {
	if(namespace===undefined || typeof namespace !=='string' || namespace.length < 1 ||
		namespace.indexOf('/')!==0 || filename === undefined || typeof filename !== 'string' ||
		filename.length <= 0) {
		console.log('Error: 912');
		return false;
	}

	var app = Express();
    app.set('view engine', 'ejs');
    app.set('views', __dirname + '/views');

    app.use('/',Express.static(__dirname + '/../../frontend/app/views'));

	var nspNorris=this._norrisNamespace;
	var baseURL='';
	var handle = function (req, res) {
		var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
		baseURL=req.protocol + '://' + req.get('host');
		var norrisNamespace=req.protocol + '://' + req.get('host')+nspNorris;
		res.render(filename,{fullURL:fullUrl, norrisNamespace : norrisNamespace});
	};
	this._baseURL=baseURL;

	app.get(namespace, handle);
	this._exprApp.use(namespace, app);

	return true;
};

module.exports = Routes;<|endoftext|>


<commit_before>Vue.component('api-resource', {
	props: ['key', 'path', 'index'],
    computed: {
        sanitisePath : function() {
            return 'resource_'+this.index.split('/').join('').split('{').join('').split('}').join('');
        },
        pathEntry : {
            get : function() {
                 return this.index
            },
            set : function(newVal) {
                this.$parent.renamePath(this.index, newVal);
            }
        }
    },
	data: function() {
		return {}
	},
    methods : {
		removePath : function(target) {
            this.$parent.removePath(target);
	    },
        addOperation : function(template) {
            var methods = ['get','post','put','delete','head','patch','options'];
            var index = 0;
            while (this.path[methods[index]] && index<methods.length) {
                index++;
            }
            if (index<methods.length) {
                var op = {};
                op.summary = template.summary || '';
                op.description = template.description || '';
                op.parameters = template.parameters || [];
                op.operationId = template.operationId || '';
                Vue.set(this.path, methods[index], op);
            }
        },
        removeOperation : function(target) {
            this.$root.save();
            Vue.delete(this.path, target);
        },
        renameOperation : function(oldMethod, newMethod) {
            if (this.path[newMethod]) {
                Vue.set(this.path, 'temp', this.path[newMethod]);
                Vue.delete(this.path, newMethod);
            }
            Vue.set(this.path, newMethod, this.path[oldMethod]);
            Vue.delete(this.path, oldMethod);
            if (this.path.temp) {
                Vue.set(this.path, oldMethod, this.path.temp);
                Vue.delete(this.path, 'temp');
            }
        }
    },
	template: '#template-resource'
});
<commit_msg>Fix add Operation<commit_after>Vue.component('api-resource', {
	props: ['key', 'path', 'index'],
    computed: {
        sanitisePath : function() {
            return 'resource_'+this.index.split('/').join('').split('{').join('').split('}').join('');
        },
        pathEntry : {
            get : function() {
                 return this.index
            },
            set : function(newVal) {
                this.$parent.renamePath(this.index, newVal);
            }
        }
    },
	data: function() {
		return {}
	},
    methods : {
		removePath : function(target) {
            this.$parent.removePath(target);
	    },
        addOperation : function(template) {
            var methods = ['get','post','put','delete','head','patch','options'];
            var index = 0;
            while (this.path[methods[index]] && index<methods.length) {
                index++;
            }
            if (index<methods.length) {
                var op = {};
                op.summary = template && template.summary || '';
                op.description = template && template.description || '';
                op.parameters = template && template.parameters || [];
                op.operationId = template && template.operationId || '';
                Vue.set(this.path, methods[index], op);
            }
        },
        removeOperation : function(target) {
            this.$root.save();
            Vue.delete(this.path, target);
        },
        renameOperation : function(oldMethod, newMethod) {
            if (this.path[newMethod]) {
                Vue.set(this.path, 'temp', this.path[newMethod]);
                Vue.delete(this.path, newMethod);
            }
            Vue.set(this.path, newMethod, this.path[oldMethod]);
            Vue.delete(this.path, oldMethod);
            if (this.path.temp) {
                Vue.set(this.path, oldMethod, this.path.temp);
                Vue.delete(this.path, 'temp');
            }
        }
    },
	template: '#template-resource'
});
<|endoftext|>


<commit_before>var web3 = require('ethereum.js');
var fs = require('fs');

var args = process.argv.slice(2);
var printHelp = function(){
	console.log("usage: eth-uil.js [command] [args]");
	console.log("compile [fileName] - compiles the specified file");
	console.log("deploy [fileName] - compiles the specified file and creates a contract on the blockchain");
    console.log("cmd [contract address] [path to abi] [command] [args*] - calls a method on a contract (i.e. cmd 0x3d8ef... simple-storage.abi set 40)");
	console.log("watch-blocks - prints current block number whenever a new block is created");
}

var compileFile = function(fileName){
	var detectFileType = function(fileName){
		var fileParts = fileName.split('.');
		var extension = fileParts[fileParts.length - 1];
		if(extension == "sol"){
			return "solidity";
		}else if(extension == "se"){
			return "serpent";
		}else if(extension == "lll"){
			return "lll";
		}else{
			console.log("unknown file type: " + extension);
			process.exit(1);
		}
	}

	var fileType = detectFileType(fileName);
	var fileContents = fs.readFileSync(fileName, {encoding: "utf8"});
	console.log("compiling " + fileType + " code at " + fileName + "...");

	var compiled;
	if(fileType == "solidity"){
		compiled = web3.eth.compile.solidity(fileContents);
	}

	return compiled;
}

var deploy = function(byteCode){
	var address = web3.eth.sendTransaction({code: byteCode});
	return address;
}

var watchBlocks = function(){
	console.log("current block: " + web3.eth.blockNumber);
	web3.eth.filter('chain').watch(function(res){
        var numTransactions = web3.eth.getBlockTransactionCount(web3.eth.blockNumber);
        console.log("last block number: " + web3.eth.blockNumber + "; " + numTransactions + " transactions");
    });
}

var watchPending = function(){
    web3.eth.defaultBlock = 0;
    web3.eth.filter('pending').watch(function(res){
        console.log("block: " + web3.eth.blockNumber);
        var numTransactions = web3.eth.getBlockTransactionCount(web3.eth.blockNumber);
        console.log("num transactions: " + numTransactions)
        for(var i = 0; i < numTransactions; i++){
            var tx = web3.eth.getTransaction(web3.eth.blockNumber, i);
            console.log("from: " + tx["from"]);
            console.log("to: " + tx["to"]);
        }
    });
}

if(args.length == 0){
	printHelp();
	process.exit(1);
}

var cmd = args[0];

if(cmd == "help"){
	printHelp();
	process.exit(0);
}

web3.setProvider(new web3.providers.HttpSyncProvider('http://127.0.0.1:8080'));

if(cmd == "compile"){
	if(args.length < 2){
		printHelp();
		process.exit(1);
	}
	var fileName = args[1];
	var result = compileFile(fileName);
	if(result){
		console.log("compilation successful");
		console.log(result);
		process.exit(0);
	}else{
		console.log("compilation error");
		process.exit(1);
	}
}

if(cmd == "deploy"){
	if(args.length < 2){
		printHelp();
		process.exit(1);
	}
	var fileName = args[1];
	var result = compileFile(fileName);
	if(result){
		console.log("compilation successful");
		console.log("deploying code to blockchain...");
		var address = deploy(result);
		console.log("deployed contract at " + address);
		process.exit(0);
	}else{
		console.log("compilation error");
		process.exit(1);
	}
}

if(cmd == "check-contract"){
	if(args.length < 2){
		printHelp();
		process.exit(1);
	}

	var address = args[1];
	var result = web3.eth.getData(address);
	if(web3.toAscii(result)){
		console.log("true");
	}else{
		console.log("false");
	}
	process.exit(0);
}

if(cmd == "cmd"){
	if(args.length < 4){
		printHelp();
		process.exit(1);
	}

	var address = args[1];
	var abi = JSON.parse(fs.readFileSync(args[2], {encoding: "utf8"}));
    var contract_cmd = args[3];

    var contractClass = web3.eth.contract(abi);
	var contract = new contractClass(address);

	var contract_cmd_args = args.slice(4);
	if(contract_cmd_args.length > 0){
        var result = contract[contract_cmd].apply(null, contract_cmd_args);
    } else {
        var result = contract.call()[contract_cmd]();
    }

	if(result){
		console.log(result);
	}
	process.exit(0);
}

if(cmd == "watch-blocks"){
	watchBlocks();
}

if(cmd == "watch-pending"){
    watchPending();
}
<commit_msg>added address, balance and send-ether functions<commit_after>var web3 = require('ethereum.js');
var fs = require('fs');

var args = process.argv.slice(2);
var printHelp = function(){
	console.log("usage: eth-uil.js [command] [args]");
	console.log("compile [fileName] - compiles the specified file");
	console.log("deploy [fileName] - compiles the specified file and creates a contract on the blockchain");
    console.log("cmd [contract address] [path to abi] [command] [args*] - calls a method on a contract (i.e. cmd 0x3d8ef... simple-storage.abi set 40)");
	console.log("watch-blocks - prints current block number whenever a new block is created");
    console.log("address - shows the address of the first account owned by the connected Ethereum node");
    console.log("balance - shows the current balance of the first account owned by the connected Ethereum node");
    console.log("send-ether [amount] [recipient] - sends ether to the specified address");
}

var compileFile = function(fileName){
	var detectFileType = function(fileName){
		var fileParts = fileName.split('.');
		var extension = fileParts[fileParts.length - 1];
		if(extension == "sol"){
			return "solidity";
		}else if(extension == "se"){
			return "serpent";
		}else if(extension == "lll"){
			return "lll";
		}else{
			console.log("unknown file type: " + extension);
			process.exit(1);
		}
	}

	var fileType = detectFileType(fileName);
	var fileContents = fs.readFileSync(fileName, {encoding: "utf8"});
	console.log("compiling " + fileType + " code at " + fileName + "...");

	var compiled;
	if(fileType == "solidity"){
		compiled = web3.eth.compile.solidity(fileContents);
	}

	return compiled;
}

var deploy = function(byteCode){
	var address = web3.eth.sendTransaction({code: byteCode});
	return address;
}

var watchBlocks = function(){
	console.log("current block: " + web3.eth.blockNumber);
	web3.eth.filter('chain').watch(function(res){
        var numTransactions = web3.eth.getBlockTransactionCount(web3.eth.blockNumber);
        var block = web3.eth.getBlock(web3.eth.blockNumber);
        console.log("-- " + web3.eth.blockNumber + " --");
        console.log("numTransactions: " + numTransactions);
        console.log(block);
    });
}

var watchPending = function(){
    web3.eth.defaultBlock = 0;
    web3.eth.filter('pending').watch(function(res){
        console.log("block: " + web3.eth.blockNumber);
        var numTransactions = web3.eth.getBlockTransactionCount(web3.eth.blockNumber);
        console.log("num transactions: " + numTransactions)
        for(var i = 0; i < numTransactions; i++){
            var tx = web3.eth.getTransaction(web3.eth.blockNumber, i);
            console.log("from: " + tx["from"]);
            console.log("to: " + tx["to"]);
        }
    });
}

if(args.length == 0){
	printHelp();
	process.exit(1);
}

var cmd = args[0];

if(cmd == "help"){
	printHelp();
	process.exit(0);
}

web3.setProvider(new web3.providers.HttpSyncProvider('http://127.0.0.1:8080'));

if(cmd == "compile"){
	if(args.length < 2){
		printHelp();
		process.exit(1);
	}
	var fileName = args[1];
	var result = compileFile(fileName);
	if(result){
		console.log("compilation successful");
		console.log(result);
		process.exit(0);
	}else{
		console.log("compilation error");
		process.exit(1);
	}
}

if(cmd == "deploy"){
	if(args.length < 2){
		printHelp();
		process.exit(1);
	}
	var fileName = args[1];
	var result = compileFile(fileName);
	if(result){
		console.log("compilation successful");
		console.log("deploying code to blockchain...");
		var address = deploy(result);
		console.log("deployed contract at " + address);
		process.exit(0);
	}else{
		console.log("compilation error");
		process.exit(1);
	}
}

if(cmd == "check-contract"){
	if(args.length < 2){
		printHelp();
		process.exit(1);
	}

	var address = args[1];
	var result = web3.eth.getData(address);
	if(web3.toAscii(result)){
		console.log("true");
	}else{
		console.log("false");
	}
	process.exit(0);
}

if(cmd == "cmd"){
	if(args.length < 4){
		printHelp();
		process.exit(1);
	}

	var address = args[1];
	var abi = JSON.parse(fs.readFileSync(args[2], {encoding: "utf8"}));
    var contract_cmd = args[3];

    var contractClass = web3.eth.contract(abi);
	var contract = new contractClass(address);

	var contract_cmd_args = args.slice(4);
	if(contract_cmd_args.length > 0){
        var result = contract[contract_cmd].apply(null, contract_cmd_args);
    } else {
        var result = contract.call()[contract_cmd]();
    }

	if(result){
		console.log(result.toNumber());

	}
	process.exit(0);
}

if(cmd == "watch-blocks"){
	watchBlocks();
}

if(cmd == "watch-pending"){
    watchPending();
}

if(cmd == "balance"){
    console.log(web3.eth.getBalance(web3.eth.accounts[0]).toNumber());
    process.exit(0);
}

if(cmd == "address"){
    console.log(web3.eth.accounts[0]);
    process.exit(0);
}

if(cmd == "send-ether"){
    if(args.length < 2){
        printHelp();
        process.exit(1);
    }

    var amount = web3.toWei(args[1], "ether");
    var address = args[2];
    web3.eth.sendTransaction({to:address, value:amount});
    process.exit(0);
}
<|endoftext|>


<commit_before>import React from 'react';

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

    this.state = {
      previewUrl: 'http://localhost:8000'
    };
  }

  render() {
    return (

          <input type="text" className="form-control" placeholder="URL" value={this.state.previewUrl} onChange={(e) => this.handlePreviewUrlChange(e)} />

            <button className="btn btn-outline-secondary" type="button" onClick={(e) => this.handlePreviewGo(e)}>Go</button>

         this.previewIframe = iframe} onLoad={(e) => this.handlePreviewChange(e)} src="http://localhost:8000">

    );
  }

  handlePreviewUrlChange(ev) {
    this.setState({previewUrl: ev.target.value});
  }

  handlePreviewChange(ev) {
    try {
      let url = ev.target.contentWindow.location.toString();
      this.setState({previewUrl: url});
    } catch(e) {
      // Nothing here.
    }
  }

  handlePreviewGo() {
    this.previewIframe.src = this.previewUrl;
  }
}

export default ApplicationPreviewContainer;

<commit_msg>Use properties where it makes sense<commit_after>import PropTypes from 'prop-types';
import React from 'react';

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

    this.state = {
      // TODO(andremedeiros): Figure out how to pull this from the actual host.
      previewUrl: this.props.previewHomepage
    };
  }

  render() {
    return (

          <input type="text" className="form-control" placeholder="URL" value={this.state.previewUrl} onChange={(e) => this.handlePreviewUrlChange(e)} />

            <button className="btn btn-outline-secondary" type="button" onClick={(e) => this.handlePreviewGo(e)}>Go</button>

         this.previewIframe = iframe} onLoad={(e) => this.handlePreviewChange(e)} src={this.props.previewHomepage}>

    );
  }

  handlePreviewUrlChange(ev) {
    this.setState({previewUrl: ev.target.value});
  }

  handlePreviewChange(ev) {
    try {
      let url = ev.target.contentWindow.location.toString();
      this.setState({previewUrl: url});
    } catch(e) {
      // Nothing here.
    }
  }

  handlePreviewGo() {
    this.previewIframe.src = this.state.previewUrl;
  }
}

ApplicationPreviewContainer.propTypes = {
  previewHomepage: PropTypes.string
};

ApplicationPreviewContainer.defaultProps = {
  previewHomepage: 'http://localhost:8000'
};

export default ApplicationPreviewContainer;

<|endoftext|>


<commit_before>var fastScroll = (function() {

	// Used to track the enabling of hover effects
	var enableTimer = 0;

	/*
	 * Listen for a scroll and use that to remove
	 * the possibility of hover effects
	 */

	window.addEventListener('scroll', function() {
		clearTimeout(enableTimer);
		removeHoverClass();
		enableTimer = setTimeout(addHoverClass, 200); // 200 is a bit snappier
	}, false);

	/**
	 * Removes the hover class from the body. Hover styles
	 * are reliant on this class being present
	 */
	function removeHoverClass() {
		document.body.style.pointerEvents = 'none';
	}

	/**
	 * Adds the hover class to the body. Hover styles
	 * are reliant on this class being present
	 */
	function addHoverClass() {
		document.body.style.pointerEvents = 'auto';
	}
})();
<commit_msg>Only apply body style if necessary<commit_after>var fastScroll = (function() {

	// Used to track the enabling of hover effects
	var enableTimer = 0;

	/*
	 * Listen for a scroll and use that to remove
	 * the possibility of hover effects
	 */

	window.addEventListener('scroll', function() {
		clearTimeout(enableTimer);
		removeHoverClass();
		enableTimer = setTimeout(addHoverClass, 200); // 200 is a bit snappier
	}, false);

	/**
	 * Removes the hover class from the body. Hover styles
	 * are reliant on this class being present
	 */
	function removeHoverClass() {
		if ('none' !== document.body.style.pointerEvents) {
			document.body.style.pointerEvents = 'none';
		}
	}

	/**
	 * Adds the hover class to the body. Hover styles
	 * are reliant on this class being present
	 */
	function addHoverClass() {
		document.body.style.pointerEvents = 'auto';
	}
})();
<|endoftext|>


<commit_before>CodeMirror.defineMode("htmlmixed", function(config) {
  var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
  var jsMode = CodeMirror.getMode(config, "javascript");
  var cssMode = CodeMirror.getMode(config, "css");

  function html(stream, state) {
    var style = htmlMode.token(stream, state.htmlState);
    if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
      if (/^script$/i.test(state.htmlState.context.tagName)) {
        state.token = javascript;
        state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
      }
      else if (/^style$/i.test(state.htmlState.context.tagName)) {
        state.token = css;
        state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
      }
    }
    return style;
  }
  function maybeBackup(stream, pat, style) {
    var cur = stream.current();
    var close = cur.search(pat), m;
    if (close > -1) stream.backUp(cur.length - close);
    else if (m = cur.match(/<\/?$/)) {
      stream.backUp(cur[0].length);
      if (!stream.match(pat, false)) stream.match(cur[0]);
    }
    return style;
  }
  function javascript(stream, state) {
    if (stream.match(/^<\/\s*script\s*>/i, false)) {
      state.token = html;
      state.localState = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*script\s*>/,
                       jsMode.token(stream, state.localState));
  }
  function css(stream, state) {
    if (stream.match(/^<\/\s*style\s*>/i, false)) {
      state.token = html;
      state.localState = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*style\s*>/,
                       cssMode.token(stream, state.localState));
  }

  return {
    startState: function() {
      var state = htmlMode.startState();
      return {token: html, localState: null, mode: "html", htmlState: state};
    },

    copyState: function(state) {
      if (state.localState)
        var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
      return {token: state.token, localState: local, mode: state.mode,
              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
    },

    token: function(stream, state) {
      return state.token(stream, state);
    },

    indent: function(state, textAfter) {
      if (state.token == html || /^\s*<\//.test(textAfter))
        return htmlMode.indent(state.htmlState, textAfter);
      else if (state.token == javascript)
        return jsMode.indent(state.localState, textAfter);
      else
        return cssMode.indent(state.localState, textAfter);
    },

    electricChars: "/{}:",

    innerMode: function(state) {
      var mode = state.token == html ? htmlMode : state.token == javascript ? jsMode : cssMode;
      return {state: state.localState || state.htmlState, mode: mode};
    }
  };
}, "xml", "javascript", "css");

CodeMirror.defineMIME("text/html", "htmlmixed");
<commit_msg>[htmlmixed mode] Fix typo bug<commit_after>CodeMirror.defineMode("htmlmixed", function(config) {
  var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
  var jsMode = CodeMirror.getMode(config, "javascript");
  var cssMode = CodeMirror.getMode(config, "css");

  function html(stream, state) {
    var style = htmlMode.token(stream, state.htmlState);
    if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
      if (/^script$/i.test(state.htmlState.context.tagName)) {
        state.token = javascript;
        state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
      }
      else if (/^style$/i.test(state.htmlState.context.tagName)) {
        state.token = css;
        state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
      }
    }
    return style;
  }
  function maybeBackup(stream, pat, style) {
    var cur = stream.current();
    var close = cur.search(pat), m;
    if (close > -1) stream.backUp(cur.length - close);
    else if (m = cur.match(/<\/?$/)) {
      stream.backUp(cur.length);
      if (!stream.match(pat, false)) stream.match(cur[0]);
    }
    return style;
  }
  function javascript(stream, state) {
    if (stream.match(/^<\/\s*script\s*>/i, false)) {
      state.token = html;
      state.localState = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*script\s*>/,
                       jsMode.token(stream, state.localState));
  }
  function css(stream, state) {
    if (stream.match(/^<\/\s*style\s*>/i, false)) {
      state.token = html;
      state.localState = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*style\s*>/,
                       cssMode.token(stream, state.localState));
  }

  return {
    startState: function() {
      var state = htmlMode.startState();
      return {token: html, localState: null, mode: "html", htmlState: state};
    },

    copyState: function(state) {
      if (state.localState)
        var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
      return {token: state.token, localState: local, mode: state.mode,
              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
    },

    token: function(stream, state) {
      return state.token(stream, state);
    },

    indent: function(state, textAfter) {
      if (state.token == html || /^\s*<\//.test(textAfter))
        return htmlMode.indent(state.htmlState, textAfter);
      else if (state.token == javascript)
        return jsMode.indent(state.localState, textAfter);
      else
        return cssMode.indent(state.localState, textAfter);
    },

    electricChars: "/{}:",

    innerMode: function(state) {
      var mode = state.token == html ? htmlMode : state.token == javascript ? jsMode : cssMode;
      return {state: state.localState || state.htmlState, mode: mode};
    }
  };
}, "xml", "javascript", "css");

CodeMirror.defineMIME("text/html", "htmlmixed");
<|endoftext|>


<commit_before>define(['require', 'module', 'jquery', 'underscore', 'backbone', 'epub-fetch/markup_parser'], function (require, module, $, _, Backbone, MarkupParser) {
    console.log('package_document_parser module id: ' + module.id);

    // `PackageDocumentParser` is used to parse the xml of an epub package
    // document and build a javascript object. The constructor accepts an
    // instance of `URI` that is used to resolve paths during the process
    var PackageDocumentParser = function(bookRoot, packageFetcher) {

        var _deferredXmlDom = $.Deferred();
        var _xmlDom;

        packageFetcher.getPackageDom(function(packageDom){
            _xmlDom = packageDom;
            _deferredXmlDom.resolve(packageDom);
        });

        // Parse an XML package document into a javascript object
        this.parse = function(callback) {

            _deferredXmlDom.done(function (xmlDom) {
                var json, cover;

                json = {};
                json.metadata = getJsonMetadata(xmlDom);
                json.bindings = getJsonBindings(xmlDom);
                json.spine = getJsonSpine(xmlDom);
                json.manifest = getJsonManifest(xmlDom);

                // parse the page-progression-direction if it is present
                json.paginate_backwards = paginateBackwards(xmlDom);

                // try to find a cover image
                cover = getCoverHref(xmlDom);
                if (cover) {
                    json.metadata.cover_href = cover;
                }

                $.when(updateMetadataWithIBookProperties(json.metadata)).then(function() {

                    if (json.metadata.layout === "pre-paginated") {
                        json.metadata.fixed_layout = true;
                    }

                    // THIS SHOULD BE LEFT IN (BUT COMMENTED OUT), AS MO SUPPORT IS TEMPORARILY DISABLED
                    // create a map of all the media overlay objects
                    // json.mo_map = this.resolveMediaOverlays(json.manifest);

                    // parse the spine into a proper collection
                    json.spine = parseSpineProperties(json.spine);

                    // return the parse result
                    callback(json);
                });

            });
        };

        function updateMetadataWithIBookProperties(metadata) {

            var dff = $.Deferred();

            //if layout not set
            if(!metadata.layout)
            {
                var absoluteRoot = new URI(bookRoot + "/META-INF/com.apple.ibooks.display-options.xml").absoluteTo(document.URL);

                packageFetcher.relativeToPackageFetchFileContents(absoluteRoot, 'text', function (ibookPropText) {

                    if(ibookPropText) {
                        var parser = new MarkupParser();
                        var propModel = parser.parseXml(ibookPropText);
                        var fixLayoutProp = $("option[name=fixed-layout]", propModel)[0];
                        if(fixLayoutProp) {
                            var fixLayoutVal = $(fixLayoutProp).text();
                            if(fixLayoutVal === "true") {
                                metadata.layout = "pre-paginated";
                                console.log("using com.apple.ibooks.display-options.xml fixed-layout property");
                            }
                        }
                    }

                    dff.resolve();

                }, function (err) {

                    console.log("com.apple.ibooks.display-options.xml not found");
                    dff.resolve();
                });
            }
            else {
                dff.resolve();
            }

            return dff.promise();
        }

        function getJsonSpine(xmlDom) {

            var $spineElements;
            var jsonSpine = [];

            $spineElements = $("spine", xmlDom).children();
            $.each($spineElements, function (spineElementIndex, currSpineElement) {

                var $currSpineElement = $(currSpineElement);
                var spineItem = {

                    idref: $currSpineElement.attr("idref") ? $currSpineElement.attr("idref") : "",
                    linear: $currSpineElement.attr("linear") ? $currSpineElement.attr("linear") : "",
                    properties: $currSpineElement.attr("properties") ? $currSpineElement.attr("properties") : ""
                };

                jsonSpine.push(spineItem);
            });

            return jsonSpine;
        }

        function getJsonMetadata(xmlDom) {

            var $metadata = $("metadata", xmlDom);
            var jsonMetadata = {};

            jsonMetadata.active_class = $("meta[property='media:active-class']", $metadata).text();
            jsonMetadata.author = $("creator", $metadata).text();
            jsonMetadata.description = $("description", $metadata).text();
            jsonMetadata.epub_version =
                $("package", xmlDom).attr("version") ? $("package", xmlDom).attr("version") : "";
            jsonMetadata.id = $("identifier", $metadata).text();
            jsonMetadata.language = $("language", $metadata).text();
            jsonMetadata.layout = $("meta[property='rendition:layout']", $metadata).text();
            jsonMetadata.modified_date = $("meta[property='dcterms:modified']", $metadata).text();
            jsonMetadata.ncx = $("spine", xmlDom).attr("toc") ? $("spine", xmlDom).attr("toc") : "";
            jsonMetadata.orientation = $("meta[property='rendition:orientation']", $metadata).text();
            jsonMetadata.page_prog_dir = $("spine", xmlDom).attr("page-progression-direction") ?
                $("spine", xmlDom).attr("page-progression-direction") : "";
            jsonMetadata.pubdate = $("date", $metadata).text();
            jsonMetadata.publisher = $("publisher", $metadata).text();
            jsonMetadata.rights = $("rights").text();
            jsonMetadata.spread = $("meta[property='rendition:spread']", $metadata).text();
            jsonMetadata.title = $("title", $metadata).text();

            return jsonMetadata;
        }

        function getJsonManifest(xmlDom) {

            var $manifestItems = $("manifest", xmlDom).children();
            var jsonManifest = [];

            $.each($manifestItems, function (manifestElementIndex, currManifestElement) {

                var $currManifestElement = $(currManifestElement);
                var currManifestElementHref = $currManifestElement.attr("href") ? $currManifestElement.attr("href") :
                    "";
                var manifestItem = {

                    contentDocumentURI: currManifestElementHref,
                    href: currManifestElementHref,
                    id: $currManifestElement.attr("id") ? $currManifestElement.attr("id") : "",
                    media_overlay: $currManifestElement.attr("media-overlay") ?
                        $currManifestElement.attr("media-overlay") : "",
                    media_type: $currManifestElement.attr("media-type") ? $currManifestElement.attr("media-type") : "",
                    properties: $currManifestElement.attr("properties") ? $currManifestElement.attr("properties") : ""
                };
                // console.log('pushing manifest item to JSON manifest. currManifestElementHref: [' + currManifestElementHref +
                //     '], manifestItem.contentDocumentURI: [' + manifestItem.contentDocumentURI +
                //     '], manifestItem:');
                // console.log(manifestItem);
                jsonManifest.push(manifestItem);
            });

            return jsonManifest;
        }

        function getJsonBindings(xmlDom) {

            var $bindings = $("bindings", xmlDom).children();
            var jsonBindings = [];

            $.each($bindings, function (bindingElementIndex, currBindingElement) {

                var $currBindingElement = $(currBindingElement);
                var binding = {

                    handler: $currBindingElement.attr("handler") ? $currBindingElement.attr("handler") : "",
                    media_type: $currBindingElement.attr("media-type") ? $currBindingElement.attr("media-type") : ""
                };

                jsonBindings.push(binding);
            });

            return jsonBindings;
        }

        function getCoverHref(xmlDom) {

            var manifest;
            var $imageNode;
            manifest = xmlDom.getElementsByTagName('manifest')[0];

            // epub3 spec for a cover image is like this:
            /*<item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />*/
            $imageNode = $('item[properties~="cover-image"]', manifest);
            if ($imageNode.length === 1 && $imageNode.attr("href")) {
                return $imageNode.attr("href");
            }

            // some epub2's cover image is like this:
            /*<meta name="cover" content="cover-image-item-id" />*/
            var metaNode = $('meta[name="cover"]', xmlDom);
            var contentAttr = metaNode.attr("content");
            if (metaNode.length === 1 && contentAttr) {
                $imageNode = $('item[id="' + contentAttr + '"]', manifest);
                if ($imageNode.length === 1 && $imageNode.attr("href")) {
                    return $imageNode.attr("href");
                }
            }

            // that didn't seem to work so, it think epub2 just uses item with id=cover
            $imageNode = $('#cover', manifest);
            if ($imageNode.length === 1 && $imageNode.attr("href")) {
                return $imageNode.attr("href");
            }

            // seems like there isn't one, thats ok...
            return null;
        }

        function parseSpineProperties(spine) {

            var parsePropertiesString = function (str) {
                var properties = {};
                var allPropStrs = str.split(" "); // split it on white space
                for (var i = 0; i < allPropStrs.length; i++) {
                    // brute force!!!
                    //rendition:orientation landscape | portrait | auto
                    //rendition:spread none | landscape | portrait | both | auto

                    //rendition:page-spread-center
                    //page-spread | left | right
                    //rendition:layout reflowable | pre-paginated
                    if (allPropStrs[i] === "rendition:page-spread-center") properties.page_spread = "center";
                    if (allPropStrs[i] === "page-spread-left") properties.page_spread = "left";
                    if (allPropStrs[i] === "page-spread-right") properties.page_spread = "right";
                    if (allPropStrs[i] === "page-spread-right") properties.page_spread = "right";
                    if (allPropStrs[i] === "rendition:layout-reflowable") properties.fixed_flow = false;
                    if (allPropStrs[i] === "rendition:layout-pre-paginated") properties.fixed_flow = true;
                }
                return properties;

            };

            for (var i = 0; i < spine.length; i++) {
                var props = parsePropertiesString(spine[i].properties);
                // add all the properties to the spine item
                _.extend(spine[i], props);
            }
            return spine;
        }

        // resolve the url of smils on any manifest items that have a MO
        // attribute

        // NOTE: Removed media overlay support for the module refactoring

        // resolveMediaOverlays : function(manifest) {
        //     var that = this;
        //     var momap = {};

        //     // create a bunch of media overlay objects
        //     manifest.forEach( function(item) {
        //         if(item.get("media_type") === "application/smil+xml") {
        //             var url = that.resolveUri(item.get("href"));
        //             var moObject = new EpubParser.MediaOverlay();
        //             moObject.setUrl(url);
        //             moObject.fetch();
        //             momap[item.id] = moObject;
        //         }
        //     });
        //     return momap;
        // },

        // parse the EPUB3 `page-progression-direction` attribute
        function paginateBackwards (xmlDom) {

            return $('spine', xmlDom).attr('page-progression-direction') === "rtl";
        }
    };

    return PackageDocumentParser;
});
<commit_msg>Bug fix: edding missing URI module dependency<commit_after>define(['require', 'module', 'jquery', 'underscore', 'backbone', 'epub-fetch/markup_parser', 'URIjs'], function (require, module, $, _, Backbone, MarkupParser, URI) {
    console.log('package_document_parser module id: ' + module.id);

    // `PackageDocumentParser` is used to parse the xml of an epub package
    // document and build a javascript object. The constructor accepts an
    // instance of `URI` that is used to resolve paths during the process
    var PackageDocumentParser = function(bookRoot, packageFetcher) {

        var _deferredXmlDom = $.Deferred();
        var _xmlDom;

        packageFetcher.getPackageDom(function(packageDom){
            _xmlDom = packageDom;
            _deferredXmlDom.resolve(packageDom);
        });

        // Parse an XML package document into a javascript object
        this.parse = function(callback) {

            _deferredXmlDom.done(function (xmlDom) {
                var json, cover;

                json = {};
                json.metadata = getJsonMetadata(xmlDom);
                json.bindings = getJsonBindings(xmlDom);
                json.spine = getJsonSpine(xmlDom);
                json.manifest = getJsonManifest(xmlDom);

                // parse the page-progression-direction if it is present
                json.paginate_backwards = paginateBackwards(xmlDom);

                // try to find a cover image
                cover = getCoverHref(xmlDom);
                if (cover) {
                    json.metadata.cover_href = cover;
                }

                $.when(updateMetadataWithIBookProperties(json.metadata)).then(function() {

                    if (json.metadata.layout === "pre-paginated") {
                        json.metadata.fixed_layout = true;
                    }

                    // THIS SHOULD BE LEFT IN (BUT COMMENTED OUT), AS MO SUPPORT IS TEMPORARILY DISABLED
                    // create a map of all the media overlay objects
                    // json.mo_map = this.resolveMediaOverlays(json.manifest);

                    // parse the spine into a proper collection
                    json.spine = parseSpineProperties(json.spine);

                    // return the parse result
                    callback(json);
                });

            });
        };

        function updateMetadataWithIBookProperties(metadata) {

            var dff = $.Deferred();

            //if layout not set
            if(!metadata.layout)
            {
                var absoluteRoot = new URI(bookRoot + "/META-INF/com.apple.ibooks.display-options.xml").absoluteTo(document.URL);

                packageFetcher.relativeToPackageFetchFileContents(absoluteRoot, 'text', function (ibookPropText) {

                    if(ibookPropText) {
                        var parser = new MarkupParser();
                        var propModel = parser.parseXml(ibookPropText);
                        var fixLayoutProp = $("option[name=fixed-layout]", propModel)[0];
                        if(fixLayoutProp) {
                            var fixLayoutVal = $(fixLayoutProp).text();
                            if(fixLayoutVal === "true") {
                                metadata.layout = "pre-paginated";
                                console.log("using com.apple.ibooks.display-options.xml fixed-layout property");
                            }
                        }
                    }

                    dff.resolve();

                }, function (err) {

                    console.log("com.apple.ibooks.display-options.xml not found");
                    dff.resolve();
                });
            }
            else {
                dff.resolve();
            }

            return dff.promise();
        }

        function getJsonSpine(xmlDom) {

            var $spineElements;
            var jsonSpine = [];

            $spineElements = $("spine", xmlDom).children();
            $.each($spineElements, function (spineElementIndex, currSpineElement) {

                var $currSpineElement = $(currSpineElement);
                var spineItem = {

                    idref: $currSpineElement.attr("idref") ? $currSpineElement.attr("idref") : "",
                    linear: $currSpineElement.attr("linear") ? $currSpineElement.attr("linear") : "",
                    properties: $currSpineElement.attr("properties") ? $currSpineElement.attr("properties") : ""
                };

                jsonSpine.push(spineItem);
            });

            return jsonSpine;
        }

        function getJsonMetadata(xmlDom) {

            var $metadata = $("metadata", xmlDom);
            var jsonMetadata = {};

            jsonMetadata.active_class = $("meta[property='media:active-class']", $metadata).text();
            jsonMetadata.author = $("creator", $metadata).text();
            jsonMetadata.description = $("description", $metadata).text();
            jsonMetadata.epub_version =
                $("package", xmlDom).attr("version") ? $("package", xmlDom).attr("version") : "";
            jsonMetadata.id = $("identifier", $metadata).text();
            jsonMetadata.language = $("language", $metadata).text();
            jsonMetadata.layout = $("meta[property='rendition:layout']", $metadata).text();
            jsonMetadata.modified_date = $("meta[property='dcterms:modified']", $metadata).text();
            jsonMetadata.ncx = $("spine", xmlDom).attr("toc") ? $("spine", xmlDom).attr("toc") : "";
            jsonMetadata.orientation = $("meta[property='rendition:orientation']", $metadata).text();
            jsonMetadata.page_prog_dir = $("spine", xmlDom).attr("page-progression-direction") ?
                $("spine", xmlDom).attr("page-progression-direction") : "";
            jsonMetadata.pubdate = $("date", $metadata).text();
            jsonMetadata.publisher = $("publisher", $metadata).text();
            jsonMetadata.rights = $("rights").text();
            jsonMetadata.spread = $("meta[property='rendition:spread']", $metadata).text();
            jsonMetadata.title = $("title", $metadata).text();

            return jsonMetadata;
        }

        function getJsonManifest(xmlDom) {

            var $manifestItems = $("manifest", xmlDom).children();
            var jsonManifest = [];

            $.each($manifestItems, function (manifestElementIndex, currManifestElement) {

                var $currManifestElement = $(currManifestElement);
                var currManifestElementHref = $currManifestElement.attr("href") ? $currManifestElement.attr("href") :
                    "";
                var manifestItem = {

                    contentDocumentURI: currManifestElementHref,
                    href: currManifestElementHref,
                    id: $currManifestElement.attr("id") ? $currManifestElement.attr("id") : "",
                    media_overlay: $currManifestElement.attr("media-overlay") ?
                        $currManifestElement.attr("media-overlay") : "",
                    media_type: $currManifestElement.attr("media-type") ? $currManifestElement.attr("media-type") : "",
                    properties: $currManifestElement.attr("properties") ? $currManifestElement.attr("properties") : ""
                };
                // console.log('pushing manifest item to JSON manifest. currManifestElementHref: [' + currManifestElementHref +
                //     '], manifestItem.contentDocumentURI: [' + manifestItem.contentDocumentURI +
                //     '], manifestItem:');
                // console.log(manifestItem);
                jsonManifest.push(manifestItem);
            });

            return jsonManifest;
        }

        function getJsonBindings(xmlDom) {

            var $bindings = $("bindings", xmlDom).children();
            var jsonBindings = [];

            $.each($bindings, function (bindingElementIndex, currBindingElement) {

                var $currBindingElement = $(currBindingElement);
                var binding = {

                    handler: $currBindingElement.attr("handler") ? $currBindingElement.attr("handler") : "",
                    media_type: $currBindingElement.attr("media-type") ? $currBindingElement.attr("media-type") : ""
                };

                jsonBindings.push(binding);
            });

            return jsonBindings;
        }

        function getCoverHref(xmlDom) {

            var manifest;
            var $imageNode;
            manifest = xmlDom.getElementsByTagName('manifest')[0];

            // epub3 spec for a cover image is like this:
            /*<item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />*/
            $imageNode = $('item[properties~="cover-image"]', manifest);
            if ($imageNode.length === 1 && $imageNode.attr("href")) {
                return $imageNode.attr("href");
            }

            // some epub2's cover image is like this:
            /*<meta name="cover" content="cover-image-item-id" />*/
            var metaNode = $('meta[name="cover"]', xmlDom);
            var contentAttr = metaNode.attr("content");
            if (metaNode.length === 1 && contentAttr) {
                $imageNode = $('item[id="' + contentAttr + '"]', manifest);
                if ($imageNode.length === 1 && $imageNode.attr("href")) {
                    return $imageNode.attr("href");
                }
            }

            // that didn't seem to work so, it think epub2 just uses item with id=cover
            $imageNode = $('#cover', manifest);
            if ($imageNode.length === 1 && $imageNode.attr("href")) {
                return $imageNode.attr("href");
            }

            // seems like there isn't one, thats ok...
            return null;
        }

        function parseSpineProperties(spine) {

            var parsePropertiesString = function (str) {
                var properties = {};
                var allPropStrs = str.split(" "); // split it on white space
                for (var i = 0; i < allPropStrs.length; i++) {
                    // brute force!!!
                    //rendition:orientation landscape | portrait | auto
                    //rendition:spread none | landscape | portrait | both | auto

                    //rendition:page-spread-center
                    //page-spread | left | right
                    //rendition:layout reflowable | pre-paginated
                    if (allPropStrs[i] === "rendition:page-spread-center") properties.page_spread = "center";
                    if (allPropStrs[i] === "page-spread-left") properties.page_spread = "left";
                    if (allPropStrs[i] === "page-spread-right") properties.page_spread = "right";
                    if (allPropStrs[i] === "page-spread-right") properties.page_spread = "right";
                    if (allPropStrs[i] === "rendition:layout-reflowable") properties.fixed_flow = false;
                    if (allPropStrs[i] === "rendition:layout-pre-paginated") properties.fixed_flow = true;
                }
                return properties;

            };

            for (var i = 0; i < spine.length; i++) {
                var props = parsePropertiesString(spine[i].properties);
                // add all the properties to the spine item
                _.extend(spine[i], props);
            }
            return spine;
        }

        // resolve the url of smils on any manifest items that have a MO
        // attribute

        // NOTE: Removed media overlay support for the module refactoring

        // resolveMediaOverlays : function(manifest) {
        //     var that = this;
        //     var momap = {};

        //     // create a bunch of media overlay objects
        //     manifest.forEach( function(item) {
        //         if(item.get("media_type") === "application/smil+xml") {
        //             var url = that.resolveUri(item.get("href"));
        //             var moObject = new EpubParser.MediaOverlay();
        //             moObject.setUrl(url);
        //             moObject.fetch();
        //             momap[item.id] = moObject;
        //         }
        //     });
        //     return momap;
        // },

        // parse the EPUB3 `page-progression-direction` attribute
        function paginateBackwards (xmlDom) {

            return $('spine', xmlDom).attr('page-progression-direction') === "rtl";
        }
    };

    return PackageDocumentParser;
});
<|endoftext|>


<commit_before>// Taken from here: https://groups.google.com/forum/#!topic/blockly/djhO2jUb0Xs
// I really tried to get the license conditions from authors, but no luck :(
// Many thanks to Florian Pechwitz <florian.Pechwitz@itizzimo.com> for the code

Blockly.System.blocks['logic_switch_case'] =
    '<block type="logic_switch_case">'
    + '     <value name="CONDITION">'
    + '     </value>'
    + '     <value name="CASECONDITION0">'
    + '     </value>'
    + '     <value name="CASE0">'
    + '     </value>'
    + '     <mutation with_statement="false" items="parameter1"></mutation>'
    + '</block>';

Blockly.Blocks['logic_switch_case'] = {
    init: function() {
        this.setColour(Blockly.Constants.Logic.HUE);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.appendValueInput('CONDITION')
            .appendField(Blockly.Translate('logic_switch_case_is'));
        this.appendValueInput('CASECONDITION0')
            .appendField(Blockly.Translate('logic_switch_case_of'));
        this.appendStatementInput('CASE0')
            .appendField(Blockly.Translate('logic_switch_do'));
        this.setMutator(new Blockly.Mutator(['case_incaseof', 'case_default']));
        this.setTooltip(Blockly.Translate('logic_switch_tootltip'));
        this.caseCount_ = 0;
        this.defaultCount_ = 0;
    },

    mutationToDom: function () {
        if (!this.caseCount_ && !this.defaultCount_) {
            return null;
        }

        var container = document.createElement('mutation');

        if (this.caseCount_) {
            container.setAttribute('case', this.caseCount_);
        }

        if (this.defaultCount_) {
            container.setAttribute('default', 1);
        }
        return container;
    },

    domToMutation: function(xmlElement) {
        this.caseCount_    = parseInt(xmlElement.getAttribute('case'), 10);
        this.defaultCount_ = parseInt(xmlElement.getAttribute('default'), 10);

        for (var x = 1; x <= this.caseCount_; x++) {
            this.appendValueInput('CASECONDITION' + x)
                .appendField(Blockly.Translate('logic_switch_case_of'));
            this.appendStatementInput('CASE' + x)
                .appendField(Blockly.Translate('logic_switch_do'));
        }

        if (this.defaultCount_) {
            this.appendStatementInput('ONDEFAULT')
                .appendField('default');
        }
    },

    decompose: function(workspace) {
        var containerBlock = workspace.newBlock('control_case');//Blockly.Block.obtain(workspace, 'control_case');
        containerBlock.initSvg();

        var connection = containerBlock.getInput('STACK').connection;

        for (var x = 1; x <= this.caseCount_; x++) {
            var caseBlock = workspace.newBlock('case_incaseof');//Blockly.Block.obtain(workspace, 'case_incaseof');
            caseBlock.initSvg();
            connection.connect(caseBlock.previousConnection);
            connection = caseBlock.nextConnection;
        }

        if (this.defaultCount_) {
            var defaultBlock = workspace.newBlock('case_default');//Blockly.Block.obtain(workspace, 'case_default');
            defaultBlock.initSvg();
            connection.connect(defaultBlock.previousConnection);
        }

        return containerBlock;
    },

    compose: function(containerBlock) {
        //Disconnect all input blocks and remove all inputs.
        if (this.defaultCount_) {
            this.removeInput('ONDEFAULT');
        }

        this.defaultCount_ = 0;

        for (var x = this.caseCount_; x > 0; x--) {
            this.removeInput('CASECONDITION' + x);
            this.removeInput('CASE' + x);
        }

        this.caseCount_ = 0;

        var caseBlock = containerBlock.getInputTargetBlock('STACK');

        while (caseBlock) {
            switch(caseBlock.type) {
                case 'case_incaseof':
                    this.caseCount_++;
                    var caseconditionInput = this.appendValueInput('CASECONDITION' + this.caseCount_)
                        .appendField(Blockly.Translate('logic_switch_case_of'));

                    var caseInput = this.appendStatementInput('CASE' + this.caseCount_)
                        .appendField(Blockly.Translate('logic_switch_do'));

                    if (caseBlock.valueConnection_) {
                        caseconditionInput.connection.connect(caseBlock.valueConnection_);
                    }

                    if (caseBlock.statementConnection_) {
                        caseInput.connection.connect(caseBlock.statementConnection_);
                    }
                    break;

                case 'case_default':
                    this.defaultCount_++;
                    var defaultInput = this.appendStatementInput('ONDEFAULT')
                        .appendField('default');

                    if (caseBlock.statementConnection_) {
                        defaultInput.connection.connect(caseBlock.statementConnection_);
                    }
                    break;

                default:
                    throw 'Unknown block type.';
            }

            caseBlock = caseBlock.nextConnection && caseBlock.nextConnection.targetBlock();
        }
    },

    saveConnections: function(containerBlock) {
        var caseBlock = containerBlock.getInputTargetBlock('STACK');
        var x = 1;
        while (caseBlock) {
            switch (caseBlock.type) {
                case'case_incaseof':
                    var caseconditionInput = this.getInput('CASECONDITION' + x);
                    var caseInput = this.getInput('CASE' + x);
                    caseBlock.valueConnection_ = caseconditionInput && caseconditionInput.connection.targetConnection;
                    caseBlock.statementConnection_ = caseInput && caseInput.connection.targetConnection;
                    x++;
                    break;
                case'case_default':
                    var defaultInput = this.getInput('ONDEFAULT');
                    caseBlock.satementConnection_ = defaultInput && defaultInput.connection.targetConnection;
                    break;
                default:
                    throw 'Unknown block type';
            }
            caseBlock = caseBlock.nextConnection &&
                caseBlock.nextConnection.targetBlock();
        }
    }
};

Blockly.Blocks['control_case'] = {
    init: function() {
        this.setColour(180);
        this.appendDummyInput()
            .appendField(Blockly.Translate('logic_switch_case_is'));
        this.appendStatementInput('STACK');
        this.setTooltip(Blockly.Translate('logic_switch_control_case_tootltip'));
        this.contextMenu = false;
    }
};

Blockly.Blocks['case_incaseof'] = {
    init: function() {
        this.setColour(180);
        this.appendDummyInput()
            .appendField(Blockly.Translate('logic_switch_case_of'));
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip(Blockly.Translate('logic_switch_case_incaseof_tootltip'));
        this.contextMenu = false;
    }
};

Blockly.Blocks['case_default'] = {
    init: function() {
        this.setColour(180);
        this.appendDummyInput()
            .appendField('default');
        this.setPreviousStatement(true);
        this.setNextStatement(false);
        this.setTooltip(Blockly.Translate('logic_switch_default_tootltip'));
        this.contextMenu = false;
    }
};

Blockly.JavaScript['logic_switch_case'] = function (block) {
    var code = '';
    var do_n;
    var case_n;
    var switchVariable = Blockly.JavaScript.valueToCode(block, 'CONDITION', Blockly.JavaScript.ORDER_NONE) || null;

    if (switchVariable){
        var pattern = /^[$\w_][._$\d\w]*$/g;

        if (pattern.test(switchVariable)) { // Check to see if the switch is a kind of variable type
            code = '\nswitch (' + switchVariable + ') {\n';
            var case_0 = Blockly.JavaScript.valueToCode(block, 'CASECONDITION0', Blockly.JavaScript.ORDER_NONE) || null;
            var do_0 = Blockly.JavaScript.statementToCode(block, 'CASE0');
            code += '\tcase ' + case_0 + ':\n' + do_0 + '\n\t\tbreak;\n';

            for (var n = 1; n <= block.caseCount_; n++) {
                case_n = Blockly.JavaScript.valueToCode(block, 'CASECONDITION' + n,
                    Blockly.JavaScript.ORDER_NONE) || null;

                if (case_n) {
                    do_n = Blockly.JavaScript.statementToCode(block, 'CASE' + n);
                    code += '\tcase ' + case_n + ':\n' + do_n + '\n\t\tbreak;\n';
                }
            }

            if (block.defaultCount_) {
                do_n = Blockly.JavaScript.statementToCode(block, 'ONDEFAULT');
                code += '\tdefault:\n' + do_n + '\n\t\tbreak;\n';
            }

            code += '}\n';
        } else {
            alert('logic_switch_case: ' + switchVariable + ' is not a variable name');
        }
    }
    return code;
};<commit_msg>Change Regex to allow trigger value as switched value<commit_after>// Taken from here: https://groups.google.com/forum/#!topic/blockly/djhO2jUb0Xs
// I really tried to get the license conditions from authors, but no luck :(
// Many thanks to Florian Pechwitz <florian.Pechwitz@itizzimo.com> for the code

Blockly.System.blocks['logic_switch_case'] =
    '<block type="logic_switch_case">'
    + '     <value name="CONDITION">'
    + '     </value>'
    + '     <value name="CASECONDITION0">'
    + '     </value>'
    + '     <value name="CASE0">'
    + '     </value>'
    + '     <mutation with_statement="false" items="parameter1"></mutation>'
    + '</block>';

Blockly.Blocks['logic_switch_case'] = {
    init: function() {
        this.setColour(Blockly.Constants.Logic.HUE);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.appendValueInput('CONDITION')
            .appendField(Blockly.Translate('logic_switch_case_is'));
        this.appendValueInput('CASECONDITION0')
            .appendField(Blockly.Translate('logic_switch_case_of'));
        this.appendStatementInput('CASE0')
            .appendField(Blockly.Translate('logic_switch_do'));
        this.setMutator(new Blockly.Mutator(['case_incaseof', 'case_default']));
        this.setTooltip(Blockly.Translate('logic_switch_tootltip'));
        this.caseCount_ = 0;
        this.defaultCount_ = 0;
    },

    mutationToDom: function () {
        if (!this.caseCount_ && !this.defaultCount_) {
            return null;
        }

        var container = document.createElement('mutation');

        if (this.caseCount_) {
            container.setAttribute('case', this.caseCount_);
        }

        if (this.defaultCount_) {
            container.setAttribute('default', 1);
        }
        return container;
    },

    domToMutation: function(xmlElement) {
        this.caseCount_    = parseInt(xmlElement.getAttribute('case'), 10);
        this.defaultCount_ = parseInt(xmlElement.getAttribute('default'), 10);

        for (var x = 1; x <= this.caseCount_; x++) {
            this.appendValueInput('CASECONDITION' + x)
                .appendField(Blockly.Translate('logic_switch_case_of'));
            this.appendStatementInput('CASE' + x)
                .appendField(Blockly.Translate('logic_switch_do'));
        }

        if (this.defaultCount_) {
            this.appendStatementInput('ONDEFAULT')
                .appendField('default');
        }
    },

    decompose: function(workspace) {
        var containerBlock = workspace.newBlock('control_case');//Blockly.Block.obtain(workspace, 'control_case');
        containerBlock.initSvg();

        var connection = containerBlock.getInput('STACK').connection;

        for (var x = 1; x <= this.caseCount_; x++) {
            var caseBlock = workspace.newBlock('case_incaseof');//Blockly.Block.obtain(workspace, 'case_incaseof');
            caseBlock.initSvg();
            connection.connect(caseBlock.previousConnection);
            connection = caseBlock.nextConnection;
        }

        if (this.defaultCount_) {
            var defaultBlock = workspace.newBlock('case_default');//Blockly.Block.obtain(workspace, 'case_default');
            defaultBlock.initSvg();
            connection.connect(defaultBlock.previousConnection);
        }

        return containerBlock;
    },

    compose: function(containerBlock) {
        //Disconnect all input blocks and remove all inputs.
        if (this.defaultCount_) {
            this.removeInput('ONDEFAULT');
        }

        this.defaultCount_ = 0;

        for (var x = this.caseCount_; x > 0; x--) {
            this.removeInput('CASECONDITION' + x);
            this.removeInput('CASE' + x);
        }

        this.caseCount_ = 0;

        var caseBlock = containerBlock.getInputTargetBlock('STACK');

        while (caseBlock) {
            switch(caseBlock.type) {
                case 'case_incaseof':
                    this.caseCount_++;
                    var caseconditionInput = this.appendValueInput('CASECONDITION' + this.caseCount_)
                        .appendField(Blockly.Translate('logic_switch_case_of'));

                    var caseInput = this.appendStatementInput('CASE' + this.caseCount_)
                        .appendField(Blockly.Translate('logic_switch_do'));

                    if (caseBlock.valueConnection_) {
                        caseconditionInput.connection.connect(caseBlock.valueConnection_);
                    }

                    if (caseBlock.statementConnection_) {
                        caseInput.connection.connect(caseBlock.statementConnection_);
                    }
                    break;

                case 'case_default':
                    this.defaultCount_++;
                    var defaultInput = this.appendStatementInput('ONDEFAULT')
                        .appendField('default');

                    if (caseBlock.statementConnection_) {
                        defaultInput.connection.connect(caseBlock.statementConnection_);
                    }
                    break;

                default:
                    throw 'Unknown block type.';
            }

            caseBlock = caseBlock.nextConnection && caseBlock.nextConnection.targetBlock();
        }
    },

    saveConnections: function(containerBlock) {
        var caseBlock = containerBlock.getInputTargetBlock('STACK');
        var x = 1;
        while (caseBlock) {
            switch (caseBlock.type) {
                case'case_incaseof':
                    var caseconditionInput = this.getInput('CASECONDITION' + x);
                    var caseInput = this.getInput('CASE' + x);
                    caseBlock.valueConnection_ = caseconditionInput && caseconditionInput.connection.targetConnection;
                    caseBlock.statementConnection_ = caseInput && caseInput.connection.targetConnection;
                    x++;
                    break;
                case'case_default':
                    var defaultInput = this.getInput('ONDEFAULT');
                    caseBlock.satementConnection_ = defaultInput && defaultInput.connection.targetConnection;
                    break;
                default:
                    throw 'Unknown block type';
            }
            caseBlock = caseBlock.nextConnection &&
                caseBlock.nextConnection.targetBlock();
        }
    }
};

Blockly.Blocks['control_case'] = {
    init: function() {
        this.setColour(180);
        this.appendDummyInput()
            .appendField(Blockly.Translate('logic_switch_case_is'));
        this.appendStatementInput('STACK');
        this.setTooltip(Blockly.Translate('logic_switch_control_case_tootltip'));
        this.contextMenu = false;
    }
};

Blockly.Blocks['case_incaseof'] = {
    init: function() {
        this.setColour(180);
        this.appendDummyInput()
            .appendField(Blockly.Translate('logic_switch_case_of'));
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip(Blockly.Translate('logic_switch_case_incaseof_tootltip'));
        this.contextMenu = false;
    }
};

Blockly.Blocks['case_default'] = {
    init: function() {
        this.setColour(180);
        this.appendDummyInput()
            .appendField('default');
        this.setPreviousStatement(true);
        this.setNextStatement(false);
        this.setTooltip(Blockly.Translate('logic_switch_default_tootltip'));
        this.contextMenu = false;
    }
};

Blockly.JavaScript['logic_switch_case'] = function (block) {
    var code = '';
    var do_n;
    var case_n;
    var switchVariable = Blockly.JavaScript.valueToCode(block, 'CONDITION', Blockly.JavaScript.ORDER_NONE) || null;

    if (switchVariable){
        var pattern = /^\(?([._$\d\w"?: ])*\)?$/g;

        if (pattern.test(switchVariable)) { // Check to see if the switch is a kind of variable type
            code = '\nswitch (' + switchVariable + ') {\n';
            var case_0 = Blockly.JavaScript.valueToCode(block, 'CASECONDITION0', Blockly.JavaScript.ORDER_NONE) || null;
            var do_0 = Blockly.JavaScript.statementToCode(block, 'CASE0');
            code += '\tcase ' + case_0 + ':\n' + do_0 + '\n\t\tbreak;\n';

            for (var n = 1; n <= block.caseCount_; n++) {
                case_n = Blockly.JavaScript.valueToCode(block, 'CASECONDITION' + n,
                    Blockly.JavaScript.ORDER_NONE) || null;

                if (case_n) {
                    do_n = Blockly.JavaScript.statementToCode(block, 'CASE' + n);
                    code += '\tcase ' + case_n + ':\n' + do_n + '\n\t\tbreak;\n';
                }
            }

            if (block.defaultCount_) {
                do_n = Blockly.JavaScript.statementToCode(block, 'ONDEFAULT');
                code += '\tdefault:\n' + do_n + '\n\t\tbreak;\n';
            }

            code += '}\n';
        } else {
            alert('logic_switch_case: ' + switchVariable + ' is not a variable name');
        }
    }
    return code;
};
<|endoftext|>