<commit_before>import {
	Category,
	Attack,
	Pokemon
} from '../models';
import CategoryType from './CategoryType';
import AttackType from './AttackType';
import {
	GraphQLObjectType,
	GraphQLID,
	GraphQLInt,
	GraphQLString,
	GraphQLList
} from 'graphql';

const PokemonType = new GraphQLObjectType({
	name : 'pokemon',
	fields : () => ({
		id : {
			type : GraphQLID
		},
		name : {
			type : GraphQLString
		},
		number : {
			type : GraphQLInt
		},
		attack : {
			type : new GraphQLList(AttackType),
			resolve: (pokemon) => {
				return Attack.find({
					_id: {
						$in: pokemon.attacks.map((id) => id.toString())
					}
				});
			}
		},
		categories : {
			type : new GraphQLList(CategoryType),
			resolve: (pokemon) => {
				return Category.find({
					_id: {
						$in: pokemon.categories.map((id) => id.toString())
					}
				});
			}
		},
		preEvolution : {
			type : PokemonType,
			resolve: (pokemon) => {
				return Pokemon.findOne({
					_id: pokemon.preEvolution.toString()
				});
			}
		},
		evolution : {
			type : PokemonType,
			resolve: (pokemon) => {
				return Pokemon.findOne({
					_id: pokemon.evolution.toString()
				});
			}
		}
	})
});

export default PokemonType;<commit_msg>Change attack attribute for attacks<commit_after>import {
	Category,
	Attack,
	Pokemon
} from '../models';
import CategoryType from './CategoryType';
import AttackType from './AttackType';
import {
	GraphQLObjectType,
	GraphQLID,
	GraphQLInt,
	GraphQLString,
	GraphQLList
} from 'graphql';

const PokemonType = new GraphQLObjectType({
	name : 'pokemon',
	fields : () => ({
		id : {
			type : GraphQLID
		},
		name : {
			type : GraphQLString
		},
		number : {
			type : GraphQLInt
		},
		attacks : {
			type : new GraphQLList(AttackType),
			resolve: (pokemon) => {
				return Attack.find({
					_id: {
						$in: pokemon.attacks.map((id) => id.toString())
					}
				});
			}
		},
		categories : {
			type : new GraphQLList(CategoryType),
			resolve: (pokemon) => {
				return Category.find({
					_id: {
						$in: pokemon.categories.map((id) => id.toString())
					}
				});
			}
		},
		preEvolution : {
			type : PokemonType,
			resolve: (pokemon) => {
				return Pokemon.findOne({
					_id: pokemon.preEvolution.toString()
				});
			}
		},
		evolution : {
			type : PokemonType,
			resolve: (pokemon) => {
				return Pokemon.findOne({
					_id: pokemon.evolution.toString()
				});
			}
		}
	})
});

export default PokemonType;<|endoftext|>


<commit_before>import gulp from 'gulp';
import autoprefixer from 'autoprefixer';
import eslint from 'gulp-eslint';
import rimraf from 'rimraf';
import browserSync, { reload } from 'browser-sync';
import sourcemaps from 'gulp-sourcemaps';
import postcss from 'gulp-postcss';
import nested from 'postcss-nested';
import vars from 'postcss-simple-vars';
import extend from 'postcss-simple-extend';
import cssnano from 'cssnano';
import imagemin from 'gulp-imagemin';
import pngquant from 'imagemin-pngquant';
import runSequence from 'run-sequence';
import ghPages from 'gulp-gh-pages';
import path from 'path';
import cp from 'child_process';
import webpack from 'webpack';
import config from './config';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import env from 'gulp-env';

const paths = {
  bundle: 'app.js',
  srcJsx: 'src/app.js',
  srcServer: 'src/server.js',
  srcCss: 'src/**/*.css',
  srcFonts: 'src/fonts/**',
  srcImg: 'src/images/**',
  srcPublic: 'src/public/**',
  srcLint: ['src/**/*.js', 'test/**/*.js'],
  dist: 'dist/public',
  distDeploy: './dist/public/**/*'
};

gulp.task('clean', cb => {
  rimraf('dist', cb);
});

gulp.task('browserSync', ['serve'], () => {
  const bundler = webpack(config[0]);
  browserSync({
    proxy: {
      target: 'localhost:5000',
      middleware: [
        webpackDevMiddleware(bundler, {
          publicPath: '/',
          stats: config[0].stats
        }),
        webpackHotMiddleware(bundler),
      ],
    },
    files: [
      'dist/public/**/*.css',
      'dist/public/**/*.html'
    ],
  });
});

var webpackConfig = {};

gulp.task('serve', (done) => {
  console.log("Stats : " + JSON.stringify(config.stats));
  const bundler = webpack(config);
  function start() {
    const server = cp.fork('server.js', {
      cwd : path.join(__dirname, './dist'),
      env: Object.assign({NODE_ENV: 'development'}, process.env),
      silent: false
    });
    server.once('message', message => {
      if (message.match(/^online$/)) {
        console.log("Server is online...");
        if(!webpackConfig.isGulpTaskDone) {
          done();
          webpackConfig.isGulpTaskDone = true;
        }
      }
    });
    server.once('error', err => console.log("Server startup failed " + err));
    process.on('exit', () => server.kill('SIGTERM'));
    return server;
  }
  function bundle(err, stats) {
    if (err) {
      console.log('Bundle errors! ' + err);
    }
    console.log(stats.toString(config[0].stats));

    if(!webpackConfig.serverInstance) {
      webpackConfig.serverInstance = start();
    } else {
      webpackConfig.serverInstance.kill('SIGTERM');
      webpackConfig.serverInstance = start();
    }
  }
  bundler.watch(200, bundle);
});

gulp.task('server-bundle', (done) => {
  webpack(config, function(err, stats) {
		if(err) throw new gutil.PluginError("webpack:build", err);
		console.log("[webpack:build]" + stats.toString({
			colors: true
		}));
		done();
	});

});

gulp.task('styles', () => {
  gulp.src(paths.srcCss)
    .pipe(sourcemaps.init())
    .pipe(postcss([vars, extend, nested, autoprefixer, cssnano]))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(paths.dist))
    .pipe(reload({stream: true}));
});

gulp.task('public', () => {
  gulp.src(paths.srcPublic)
    .pipe(gulp.dest(paths.dist));
});

gulp.task('fonts', () => {
  gulp.src(paths.srcFonts)
    .pipe(gulp.dest(paths.dist + '/fonts'));
});

gulp.task('images', () => {
  gulp.src(paths.srcImg)
   .pipe(imagemin({
     progressive: true,
     svgoPlugins: [{removeViewBox: false}],
     use: [pngquant()]
   }))
    .pipe(gulp.dest(paths.dist + '/images'));
});

// There are too many linting error. this needs to be disabled
// for now. It is causing wathc to fail.
// After we fix all of the linting errors, we can enable it.
//    gulp.task('lint', () => {
//      gulp.src(paths.srcLint)
//        .pipe(eslint())
//        .pipe(eslint.format());
//    });

gulp.task('watchTask', () => {
  gulp.watch(paths.srcFonts, ['fonts']);
  gulp.watch(paths.srcCss, ['styles']);
  gulp.watch(paths.srcPublic, ['public']);
  paths.srcLint.forEach((src) => {
    gulp.watch(src, ['lint']);
  })
});

gulp.task('deploy', function () {
  return gulp.src(paths.distDeploy)
    .pipe(ghPages());
});

gulp.task('watch', cb => {
  runSequence('clean', ['set-env','browserSync', 'watchTask', 'public', 'styles', 'fonts', 'images'], cb);
});

gulp.task('set-env', function () {
  //Only use localhost if WF_SERVER is not set
  var wf_server = process.env.WF_SERVER || 'http://localhost:8080/api/';
  env({
    vars: {
      WF_SERVER: wf_server
    }
  });
});

gulp.task('build', cb => {
  process.env.DEBUG = false;
  runSequence('clean', ['server-bundle', 'styles', 'fonts','public', 'images'], cb);
});
<commit_msg>correcting issue causing watch to fail for new linting rules<commit_after>import gulp from 'gulp';
import autoprefixer from 'autoprefixer';
import eslint from 'gulp-eslint';
import rimraf from 'rimraf';
import browserSync, { reload } from 'browser-sync';
import sourcemaps from 'gulp-sourcemaps';
import postcss from 'gulp-postcss';
import nested from 'postcss-nested';
import vars from 'postcss-simple-vars';
import extend from 'postcss-simple-extend';
import cssnano from 'cssnano';
import imagemin from 'gulp-imagemin';
import pngquant from 'imagemin-pngquant';
import runSequence from 'run-sequence';
import ghPages from 'gulp-gh-pages';
import path from 'path';
import cp from 'child_process';
import webpack from 'webpack';
import config from './config';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import env from 'gulp-env';

const paths = {
  bundle: 'app.js',
  srcJsx: 'src/app.js',
  srcServer: 'src/server.js',
  srcCss: 'src/**/*.css',
  srcFonts: 'src/fonts/**',
  srcImg: 'src/images/**',
  srcPublic: 'src/public/**',
  srcLint: ['src/**/*.js', 'test/**/*.js'],
  dist: 'dist/public',
  distDeploy: './dist/public/**/*'
};

gulp.task('clean', cb => {
  rimraf('dist', cb);
});

gulp.task('browserSync', ['serve'], () => {
  const bundler = webpack(config[0]);
  browserSync({
    proxy: {
      target: 'localhost:5000',
      middleware: [
        webpackDevMiddleware(bundler, {
          publicPath: '/',
          stats: config[0].stats
        }),
        webpackHotMiddleware(bundler),
      ],
    },
    files: [
      'dist/public/**/*.css',
      'dist/public/**/*.html'
    ],
  });
});

var webpackConfig = {};

gulp.task('serve', (done) => {
  console.log("Stats : " + JSON.stringify(config.stats));
  const bundler = webpack(config);
  function start() {
    const server = cp.fork('server.js', {
      cwd : path.join(__dirname, './dist'),
      env: Object.assign({NODE_ENV: 'development'}, process.env),
      silent: false
    });
    server.once('message', message => {
      if (message.match(/^online$/)) {
        console.log("Server is online...");
        if(!webpackConfig.isGulpTaskDone) {
          done();
          webpackConfig.isGulpTaskDone = true;
        }
      }
    });
    server.once('error', err => console.log("Server startup failed " + err));
    process.on('exit', () => server.kill('SIGTERM'));
    return server;
  }
  function bundle(err, stats) {
    if (err) {
      console.log('Bundle errors! ' + err);
    }
    console.log(stats.toString(config[0].stats));

    if(!webpackConfig.serverInstance) {
      webpackConfig.serverInstance = start();
    } else {
      webpackConfig.serverInstance.kill('SIGTERM');
      webpackConfig.serverInstance = start();
    }
  }
  bundler.watch(200, bundle);
});

gulp.task('server-bundle', (done) => {
  webpack(config, function(err, stats) {
		if(err) throw new gutil.PluginError("webpack:build", err);
		console.log("[webpack:build]" + stats.toString({
			colors: true
		}));
		done();
	});

});

gulp.task('styles', () => {
  gulp.src(paths.srcCss)
    .pipe(sourcemaps.init())
    .pipe(postcss([vars, extend, nested, autoprefixer, cssnano]))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(paths.dist))
    .pipe(reload({stream: true}));
});

gulp.task('public', () => {
  gulp.src(paths.srcPublic)
    .pipe(gulp.dest(paths.dist));
});

gulp.task('fonts', () => {
  gulp.src(paths.srcFonts)
    .pipe(gulp.dest(paths.dist + '/fonts'));
});

gulp.task('images', () => {
  gulp.src(paths.srcImg)
   .pipe(imagemin({
     progressive: true,
     svgoPlugins: [{removeViewBox: false}],
     use: [pngquant()]
   }))
    .pipe(gulp.dest(paths.dist + '/images'));
});

// There are too many linting error. this needs to be disabled
// for now. It is causing watch to fail.
// After we fix all of the linting errors, we can enable it.
//    gulp.task('lint', () => {
//      gulp.src(paths.srcLint)
//        .pipe(eslint())
//        .pipe(eslint.format());
//    });

gulp.task('watchTask', () => {
  gulp.watch(paths.srcFonts, ['fonts']);
  gulp.watch(paths.srcCss, ['styles']);
  gulp.watch(paths.srcPublic, ['public']);
  paths.srcLint.forEach((src) => {
    gulp.watch(src, ['lint']);
  })
});

gulp.task('deploy', function () {
  return gulp.src(paths.distDeploy)
    .pipe(ghPages());
});

gulp.task('watch', cb => {
  runSequence('clean', ['set-env','browserSync', 'watchTask', 'public', 'styles', 'fonts', 'images'], cb);
});

gulp.task('set-env', function () {
  //Only use localhost if WF_SERVER is not set
  var wf_server = process.env.WF_SERVER || 'http://localhost:8080/api/';
  env({
    vars: {
      WF_SERVER: wf_server
    }
  });
});

gulp.task('build', cb => {
  process.env.DEBUG = false;
  runSequence('clean', ['server-bundle', 'styles', 'fonts','public', 'images'], cb);
});
<|endoftext|>


<commit_before>var _manifest;
var _offlineView;
var _mainView;

function configureHost(url, zOrder, display) {
    var webView = document.createElement(cordova.platformId === "windows8" ? "iframe" : "x-ms-webview");
    var style = webView.style;
    style.position = "absolute";
    style.top = 0;
    style.left = 0;
    style.zIndex = zOrder;
    style.width = window.innerWidth + "px";
    style.height = window.innerHeight + "px";
    if (display) {
        style.display = display;
    }

    if (url) {
        webView.src = url;
    }

    document.body.appendChild(webView);

    return webView;
}

function configureOfflineSupport(offlinePage) {
    var url = new Windows.Foundation.Uri('ms-appx:///www/' + offlinePage);
    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(url).then(
        function (file) {
            _offlineView = configureHost(url.absoluteUri, 10001, 'none');
        },
        function (err) {
            var message = 'It looks like you are offline. Please reconnect to use this application.';
            var offlinePageTemplate = '
' + message + '
';
            _offlineView = configureHost(null, 10001, 'none');
            _offlineView.contentDocument.write(offlinePageTemplate);
        }).done(function () {
            // handle network connectivity change events
            document.addEventListener('offline', function (e) {
                _offlineView.style.display = "block";
                console.log('The application is currently offline.');
            }, false);
            document.addEventListener('online', function () { _offlineView.style.display = "none"; }, false);
        });
}

function _loadManifestAsync(fileName, successCallback, errorCallback) {
    var configFile = "ms-appx:///www/" + fileName;
    var uri = new Windows.Foundation.Uri(configFile);
    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(
        function (file) {
            Windows.Storage.FileIO.readTextAsync(file).then(function (data) {
                _manifest = JSON.parse(data);
                if (successCallback) {
                    successCallback(_manifest);
                }
            });
        },
        errorCallback);
}

module.exports = {
    initialize: function (successCallback, errorCallback, args) {
        _manifest = args[0];
    },

    load: function (successCallback, errorCallback, args) {
        if (args && args.length > 0) {
            _loadManifestAsync(args[0], successCallback, errorCallback);
        }
        else if (_manifest) {
            successCallback(_manifest);
        }
        else {
            errorCallback("Manifest has not been loaded!");
        }
    }
}; // exports

cordova.commandProxy.add("HostedWebApp", module.exports);

_loadManifestAsync('manifest.json',
    function (manifest) {
        _mainView = configureHost(manifest.start_url, 10000);
        configureOfflineSupport('Xoffline.html');
    },
    function () {

    });<commit_msg>Completed offline support for Windows platform<commit_after>var _manifest;
var _offlineView;
var _mainView;

// creates a webview to host content
function configureHost(url, zOrder, display) {
    var webView = document.createElement(cordova.platformId === 'windows8' ? 'iframe' : 'x-ms-webview');
    var style = webView.style;
    style.position = 'absolute';
    style.top = 0;
    style.left = 0;
    style.zIndex = zOrder;
    style.width = window.innerWidth + 'px';
    style.height = window.innerHeight + 'px';
    if (display) {
        style.display = display;
    }

    if (url) {
        webView.src = url;
    }

    document.body.appendChild(webView);

    return webView;
}

// handle network connectivity change events
function connectivityEvent(evt) {
    if (evt.type === 'offline') {
        _offlineView.style.display = 'block';
        console.log('The application is currently offline.');
    } else if (evt.type === 'online') {
        _offlineView.style.display = 'none';
        console.log('The application is currently online.');
    }
}

// sets up a secondary webview to host the offline page
function configureOfflineSupport(offlinePage) {
    var offlinePageUrl = '///www/' + offlinePage;
    var url = new Windows.Foundation.Uri('ms-appx:' + offlinePageUrl);
    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(url).then(
        function (file) {
            _offlineView = configureHost('ms-appx-web:' + offlinePageUrl, 10001, 'none');
        },
        function (err) {
            var message = 'It looks like you are offline. Please reconnect to use this application.';
            var offlinePageTemplate = '
' + message + '
';
            _offlineView = configureHost(null, 10001, 'none');

            if (cordova.platformId === 'windows8') {
                _offlineView.style.backgroundColor = 'white';
                _offlineView.contentDocument.write(offlinePageTemplate);
            } else {
                _offlineView.navigateToString(offlinePageTemplate);
            }
        }).done(function () {
            document.addEventListener('offline', connectivityEvent, false);
            document.addEventListener('online', connectivityEvent, false);
        });
}

// loads the W3C manifest file
function _loadManifestAsync(fileName, successCallback, errorCallback) {
    var configFile = 'ms-appx:///www/' + fileName;
    var uri = new Windows.Foundation.Uri(configFile);
    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(
        function (file) {
            Windows.Storage.FileIO.readTextAsync(file).then(function (data) {
                _manifest = JSON.parse(data);
                if (successCallback) {
                    successCallback(_manifest);
                }
            });
        },
        errorCallback);
}

module.exports = {
    load: function (successCallback, errorCallback, args) {
        if (args && args.length > 0) {
            _loadManifestAsync(args[0], successCallback, errorCallback);
        }
        else if (_manifest) {
            successCallback(_manifest);
        }
        else {
            errorCallback('Manifest has not been loaded!');
        }
    }
}; // exports

cordova.commandProxy.add('HostedWebApp', module.exports);

_loadManifestAsync('manifest.json',
    function (manifest) {
        _mainView = configureHost(manifest.start_url, 10000);
        configureOfflineSupport('offline.html');
    },
    function () {

    });<|endoftext|>


<commit_before>var _manifest;
var _manifestError;
var _offlineView;
var _mainView;
var _zIndex = 10000;
var _enableOfflineSupport = true;
var _lastKnownLocation;
var _lastKnownLocationFailed = false;
var _whiteList = [];

// creates a webview to host content
function configureHost(url, zOrder, display) {
    var webView = document.createElement(cordova.platformId === 'windows8' ? 'iframe' : 'x-ms-webview');
    var style = webView.style;
    style.position = 'absolute';
    style.top = 0;
    style.left = 0;
    style.zIndex = zOrder;
    style.width = '100%';
    style.height = '100%';
    if (display) {
        style.display = display;
    }

    if (url) {
        webView.src = url;
    }

    webView.addEventListener("MSWebViewNavigationCompleted", navigationCompletedEvent, false);
    webView.addEventListener("MSWebViewNavigationStarting", navigationStartingEvent, false);

    document.body.appendChild(webView);

    return webView;
}

// handles webview's navigation starting event
function navigationStartingEvent(evt) {
    if (evt.uri && evt.uri !== "") {
        var isInWhitelist = false;
        for (var i = 0; i < _whiteList.length; i++) {
            var rule = _whiteList[i];
            if (rule.test(evt.uri)) {
                isInWhitelist = true;
                break;
            }
        }

        // if the url to navigate to does not match any of the rules in the whitelist, open it outside de app
        if (!isInWhitelist) {
            evt.stopImmediatePropagation();
            evt.preventDefault();
            console.log("Popping out URL: " + evt.uri);
            Windows.System.Launcher.launchUriAsync(new Windows.Foundation.Uri(evt.uri));
        }
    }
}

// handles webview's navigation completed event
function navigationCompletedEvent(evt) {
    if (evt.uri && evt.uri !== "") {
        if (evt.isSuccess) {
            _lastKnownLocationFailed = false;
            if (_offlineView) {
                _offlineView.style.display = 'none';
            }
        } else {
            _lastKnownLocationFailed = true;
        }

        _lastKnownLocation = evt.uri;
    }
}

// handles network connectivity change events
function connectivityEvent(evt) {
    console.log('Received a network connectivity change notification. The device is currently ' + evt.type + '.');
    if (_enableOfflineSupport) {
        if (evt.type === 'offline') {
            _offlineView.style.display = 'block';
        } else if (evt.type === 'online') {
            if (_lastKnownLocationFailed) {
                if (_lastKnownLocation) {
                    console.log("Reload last known location: '" + _lastKnownLocation + "'");
                    _mainView.src = _lastKnownLocation;
                }
            } else {
                _offlineView.style.display = 'none';
            }
        }
    }
}

// sets up a secondary webview to host the offline page
function configureOfflineSupport(offlinePage) {
    var offlinePageUrl = '///www/' + offlinePage;
    var url = new Windows.Foundation.Uri('ms-appx:' + offlinePageUrl);
    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(url).then(
        function (file) {
            _offlineView = configureHost('ms-appx-web:' + offlinePageUrl, 10001, 'none');
        },
        function (err) {
            var message = 'It looks like you are offline. Please reconnect to use this application.';
            var offlinePageTemplate = '
' + message + '
';
            _offlineView = configureHost(null, _zIndex + 1, 'none');

            if (cordova.platformId === 'windows8') {
                _offlineView.style.backgroundColor = 'white';
                _offlineView.contentDocument.write(offlinePageTemplate);
            } else {
                _offlineView.navigateToString(offlinePageTemplate);
            }
        }).done(function () {
            document.addEventListener('offline', connectivityEvent, false);
            document.addEventListener('online', connectivityEvent, false);
        });
}

// escapes regular expression reserved symbols
function escapeRegex(str) {
    return ("" + str).replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}

// converts a string pattern to a regular expression
function convertPatternToRegex(pattern, excludeLineStart, excludeLineEnd) {
    var isNot = (pattern[0] == '!');
    if (isNot) { pattern = pattern.substr(1) };

    var regexBody = escapeRegex(pattern);

    excludeLineStart = !!excludeLineStart;
    excludeLineEnd = !!excludeLineEnd;

    regexBody = regexBody.replace(/\\\?/g, ".?").replace(/\\\*/g, ".*?");
    if (isNot) { regexBody = "((?!" + regexBody + ").)*"; }
    if (!excludeLineStart) { regexBody = "^" + regexBody; }
    if (!excludeLineEnd) { regexBody += "\/?$"; }

    return new RegExp(regexBody);
}

// initializes an array of the access rules defined in the manifest
function configureWhiteList(manifest) {
    if (manifest) {
        // Add base access rule based on the start_url and the scope
        var baseUrlPattern = new Windows.Foundation.Uri(manifest.start_url);
        if (manifest.scope && manifest.scope.length) {
            baseUrlPattern = baseUrlPattern.combineUri(manifest.scope);
        }

        baseUrlPattern = baseUrlPattern.combineUri('*');
        _whiteList.push(convertPatternToRegex(baseUrlPattern.absoluteUri));

        // add additional access rules
        if (manifest.mjs_access_whitelist && manifest.mjs_access_whitelist instanceof Array) {
            manifest.mjs_access_whitelist.forEach(function (rule) {
                _whiteList.push(convertPatternToRegex(rule.url));
            });
        }
    }
}

// hides the extended splash screen
function hideExtendedSplashScreen(e) {
    var extendedSplashScreen = document.getElementById("extendedSplashScreen");
    extendedSplashScreen.style.display = "none";
}

module.exports = {
    // loads the W3C manifest file and parses it
    loadManifest: function (successCallback, errorCallback, args) {
        var manifestFileName = (args && args instanceof Array && args.length > 0) ? args[0] : 'manifest.json';
        var configFile = 'ms-appx:///www/' + manifestFileName;
        var uri = new Windows.Foundation.Uri(configFile);
        Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(
            function (file) {
                Windows.Storage.FileIO.readTextAsync(file).then(function (data) {
                    try {
                        _manifest = JSON.parse(data);
                        cordova.fireDocumentEvent("manifestLoaded", { manifest: _manifest });
                        if (successCallback) {
                            successCallback(_manifest);
                        }
                    } catch (err) {
                        _manifestError = 'Error parsing manifest file: ' + manifestFileName + ' - ' + err.message;
                        console.log(_manifestError);
                    }
                });
            },
            function (err) {
                _manifestError = 'Error reading manifest file: ' + manifestFileName + ' - ' + err;
                console.log(_manifestError);
                if (errorCallback) {
                    errorCallback(err);
                }
            });
    },

    // returns the currently loaded manifest
    getManifest: function (successCallback, errorCallback) {
        if (_manifest) {
            if (successCallback) {
                successCallback(_manifest);
            }
        } else {
            if (errorCallback) {
                errorCallback(new Error(_manifestError));
            }
        }
    },

    // enables offline page support
    enableOfflinePage: function () {
        _enableOfflineSupport = true;
    },

    // disables offline page support
    disableOfflinePage: function () {
        _enableOfflineSupport = false;
    },

    getWebView: function () {
      return _mainView;
    }
}; // exports

cordova.commandProxy.add('HostedWebApp', module.exports);

module.exports.loadManifest(
    function (manifest) {
        configureOfflineSupport('offline.html');
        configureWhiteList(manifest);
        _mainView = configureHost(manifest ? manifest.start_url : 'about:blank', _zIndex);
        _mainView.addEventListener("MSWebViewDOMContentLoaded", hideExtendedSplashScreen, false);

        cordova.fireDocumentEvent("webviewCreated", { webView: _mainView });
    });
<commit_msg>Added handler for the hardware back button in the Windows platform<commit_after>var _manifest;
var _manifestError;
var _offlineView;
var _mainView;
var _zIndex = 10000;
var _enableOfflineSupport = true;
var _lastKnownLocation;
var _lastKnownLocationFailed = false;
var _whiteList = [];

// creates a webview to host content
function configureHost(url, zOrder, display) {
    var webView = document.createElement(cordova.platformId === 'windows8' ? 'iframe' : 'x-ms-webview');
    var style = webView.style;
    style.position = 'absolute';
    style.top = 0;
    style.left = 0;
    style.zIndex = zOrder;
    style.width = '100%';
    style.height = '100%';
    if (display) {
        style.display = display;
    }

    if (url) {
        webView.src = url;
    }

    webView.addEventListener("MSWebViewNavigationCompleted", navigationCompletedEvent, false);
    webView.addEventListener("MSWebViewNavigationStarting", navigationStartingEvent, false);

    document.body.appendChild(webView);

    return webView;
}

// handles webview's navigation starting event
function navigationStartingEvent(evt) {
    if (evt.uri && evt.uri !== "") {
        var isInWhitelist = false;
        for (var i = 0; i < _whiteList.length; i++) {
            var rule = _whiteList[i];
            if (rule.test(evt.uri)) {
                isInWhitelist = true;
                break;
            }
        }

        // if the url to navigate to does not match any of the rules in the whitelist, open it outside de app
        if (!isInWhitelist) {
            evt.stopImmediatePropagation();
            evt.preventDefault();
            console.log("Popping out URL: " + evt.uri);
            Windows.System.Launcher.launchUriAsync(new Windows.Foundation.Uri(evt.uri));
        }
    }
}

// handles webview's navigation completed event
function navigationCompletedEvent(evt) {
    if (evt.uri && evt.uri !== "") {
        if (evt.isSuccess) {
            _lastKnownLocationFailed = false;
            if (_offlineView) {
                _offlineView.style.display = 'none';
            }
        } else {
            _lastKnownLocationFailed = true;
        }

        _lastKnownLocation = evt.uri;
    }
}

// handles network connectivity change events
function connectivityEvent(evt) {
    console.log('Received a network connectivity change notification. The device is currently ' + evt.type + '.');
    if (_enableOfflineSupport) {
        if (evt.type === 'offline') {
            _offlineView.style.display = 'block';
        } else if (evt.type === 'online') {
            if (_lastKnownLocationFailed) {
                if (_lastKnownLocation) {
                    console.log("Reload last known location: '" + _lastKnownLocation + "'");
                    _mainView.src = _lastKnownLocation;
                }
            } else {
                _offlineView.style.display = 'none';
            }
        }
    }
}

// sets up a secondary webview to host the offline page
function configureOfflineSupport(offlinePage) {
    var offlinePageUrl = '///www/' + offlinePage;
    var url = new Windows.Foundation.Uri('ms-appx:' + offlinePageUrl);
    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(url).then(
        function (file) {
            _offlineView = configureHost('ms-appx-web:' + offlinePageUrl, 10001, 'none');
        },
        function (err) {
            var message = 'It looks like you are offline. Please reconnect to use this application.';
            var offlinePageTemplate = '
' + message + '
';
            _offlineView = configureHost(null, _zIndex + 1, 'none');

            if (cordova.platformId === 'windows8') {
                _offlineView.style.backgroundColor = 'white';
                _offlineView.contentDocument.write(offlinePageTemplate);
            } else {
                _offlineView.navigateToString(offlinePageTemplate);
            }
        }).done(function () {
            document.addEventListener('offline', connectivityEvent, false);
            document.addEventListener('online', connectivityEvent, false);
        });
}

// escapes regular expression reserved symbols
function escapeRegex(str) {
    return ("" + str).replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}

// converts a string pattern to a regular expression
function convertPatternToRegex(pattern, excludeLineStart, excludeLineEnd) {
    var isNot = (pattern[0] == '!');
    if (isNot) { pattern = pattern.substr(1) };

    var regexBody = escapeRegex(pattern);

    excludeLineStart = !!excludeLineStart;
    excludeLineEnd = !!excludeLineEnd;

    regexBody = regexBody.replace(/\\\?/g, ".?").replace(/\\\*/g, ".*?");
    if (isNot) { regexBody = "((?!" + regexBody + ").)*"; }
    if (!excludeLineStart) { regexBody = "^" + regexBody; }
    if (!excludeLineEnd) { regexBody += "\/?$"; }

    return new RegExp(regexBody);
}

// initializes an array of the access rules defined in the manifest
function configureWhiteList(manifest) {
    if (manifest) {
        // Add base access rule based on the start_url and the scope
        var baseUrlPattern = new Windows.Foundation.Uri(manifest.start_url);
        if (manifest.scope && manifest.scope.length) {
            baseUrlPattern = baseUrlPattern.combineUri(manifest.scope);
        }

        baseUrlPattern = baseUrlPattern.combineUri('*');
        _whiteList.push(convertPatternToRegex(baseUrlPattern.absoluteUri));

        // add additional access rules
        if (manifest.mjs_access_whitelist && manifest.mjs_access_whitelist instanceof Array) {
            manifest.mjs_access_whitelist.forEach(function (rule) {
                _whiteList.push(convertPatternToRegex(rule.url));
            });
        }
    }
}

// hides the extended splash screen
function hideExtendedSplashScreen(e) {
    var extendedSplashScreen = document.getElementById("extendedSplashScreen");
    extendedSplashScreen.style.display = "none";
}

// handle the hardware backbutton
function navigateBack(e) {
    if (!_mainView.canGoBack) {
        return false;
    }

    try {
        _mainView.goBack();
    } catch (err) {
        return false;
    }

    return true;
}

module.exports = {
    // loads the W3C manifest file and parses it
    loadManifest: function (successCallback, errorCallback, args) {
        var manifestFileName = (args && args instanceof Array && args.length > 0) ? args[0] : 'manifest.json';
        var configFile = 'ms-appx:///www/' + manifestFileName;
        var uri = new Windows.Foundation.Uri(configFile);
        Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(
            function (file) {
                Windows.Storage.FileIO.readTextAsync(file).then(function (data) {
                    try {
                        _manifest = JSON.parse(data);
                        cordova.fireDocumentEvent("manifestLoaded", { manifest: _manifest });
                        if (successCallback) {
                            successCallback(_manifest);
                        }
                    } catch (err) {
                        _manifestError = 'Error parsing manifest file: ' + manifestFileName + ' - ' + err.message;
                        console.log(_manifestError);
                    }
                });
            },
            function (err) {
                _manifestError = 'Error reading manifest file: ' + manifestFileName + ' - ' + err;
                console.log(_manifestError);
                if (errorCallback) {
                    errorCallback(err);
                }
            });
    },

    // returns the currently loaded manifest
    getManifest: function (successCallback, errorCallback) {
        if (_manifest) {
            if (successCallback) {
                successCallback(_manifest);
            }
        } else {
            if (errorCallback) {
                errorCallback(new Error(_manifestError));
            }
        }
    },

    // enables offline page support
    enableOfflinePage: function () {
        _enableOfflineSupport = true;
    },

    // disables offline page support
    disableOfflinePage: function () {
        _enableOfflineSupport = false;
    },

    getWebView: function () {
      return _mainView;
    }
}; // exports

cordova.commandProxy.add('HostedWebApp', module.exports);

module.exports.loadManifest(
    function (manifest) {
        configureOfflineSupport('offline.html');
        configureWhiteList(manifest);
        _mainView = configureHost(manifest ? manifest.start_url : 'about:blank', _zIndex);
        _mainView.addEventListener("MSWebViewDOMContentLoaded", hideExtendedSplashScreen, false);

        cordova.fireDocumentEvent("webviewCreated", { webView: _mainView });
        WinJS.Application.onbackclick = navigateBack;
    });
<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular
    .module('dopplerRelay')
    .controller('BillingCtrl', BillingCtrl);

  BillingCtrl.$inject = [
    '$scope',
    '$location',
    '$rootScope',
    'auth',
    '$translate',
    '$timeout',
    'settings',
    'utils'
  ];

  function BillingCtrl($scope, $location, $rootScope, auth, $translate, $timeout, settings, utils) {
    var vm = this;
    $rootScope.setSubmenues([
      { text: 'submenu_my_profile', url: 'settings/my-profile', active: false },
    ]);
    vm.checkExpDate = checkExpDate;
    vm.submitBilling = submitBilling;

    vm.cc = {number:'', type:{}, mask:''};
    vm.maskOptions = {
  	  allowInvalidValue:true //allows us to watch the value
    };
    $scope.$watch('vm.cc.number', function(newNumber){
      vm.cc.type = getCreditCardType(newNumber);
      vm.cc.mask = getMaskType(vm.cc.type);
  	});

    function getMaskType(cardType){
    	var masks = {
      	'mastercard': '9999 9999 9999 9999',
        'visa': '9999 9999 9999 9999',
        'amex': '9999 999999 99999',
        'unknown': '9999 9999 9999 9999'
    	};
      return masks[cardType];
    }

    function getCreditCardType(creditCardNumber) {
    	// start without knowing the credit card type
    	var result = "unknown";

    	// first check for MasterCard
    	if (/^5[1-5]/.test(creditCardNumber)) {
        	result = "mastercard";
    	}
    	// then check for Visa
    	else if (/^4/.test(creditCardNumber)) {
    		result = "visa";
    	}
    	// then check for AmEx
    	else if (/^3[47]/.test(creditCardNumber)) {
    		result = "amex";
    	}
    	return result;
    }

    function checkExpDate(input) {
      var currentDate = new Date();
      var currentYear = currentDate.getFullYear().toString().slice(2);
      var currentMonth = currentDate.getMonth() + 1;
      console.log(input);
      if (input.$modelValue) {
        var year = input.$modelValue.slice(2);
        var month = input.$modelValue.slice(0,2);
      }

      if (year < currentYear || month > 12) {
        utils.setServerValidationToField($scope, $scope.form.expDate, 'ilegal_date');
      }
      if (year == currentYear && month < currentMonth) {
        utils.setServerValidationToField($scope, $scope.form.expDate, 'ilegal_date');
      }
    }

    function submitBilling(form) {
      vm.submitted = true;
      if (!form.$valid) {
        return;
      }
    }

  }

})();
<commit_msg>DR-1122 Changes requested by PR<commit_after>(function() {
  'use strict';

  angular
    .module('dopplerRelay')
    .controller('BillingCtrl', BillingCtrl);

  BillingCtrl.$inject = [
    '$scope',
    '$location',
    '$rootScope',
    'auth',
    '$translate',
    '$timeout',
    'settings',
    'utils'
  ];

  function BillingCtrl($scope, $location, $rootScope, auth, $translate, $timeout, settings, utils) {
    var vm = this;
    $rootScope.setSubmenues([
      { text: 'submenu_my_profile', url: 'settings/my-profile', active: false },
    ]);
    vm.checkExpDate = checkExpDate;
    vm.submitBilling = submitBilling;

    vm.cc = {number: '', type: {}, mask: ''};
    vm.maskOptions = {
      allowInvalidValue: true //allows us to watch the value
    };

    $scope.$watch('vm.cc.number', fillCreditCardProperties);

    function fillCreditCardProperties(newNumber) {
      vm.cc.type = getCreditCardType(newNumber);
      vm.cc.mask = getMaskType(vm.cc.type);
    }

    function getMaskType(cardType){
    	var masks = {
    	   'mastercard': '9999 9999 9999 9999',
         'visa': '9999 9999 9999 9999',
         'amex': '9999 999999 99999',
         'unknown': '9999 9999 9999 9999'
    	};
      return masks[cardType];
    }

    function getCreditCardType(creditCardNumber) {
    	// start without knowing the credit card type
    	var result = "unknown";

    	// first check for MasterCard
    	if (/^5[1-5]/.test(creditCardNumber)) {
        	result = "mastercard";
    	}
    	// then check for Visa
    	else if (/^4/.test(creditCardNumber)) {
    		result = "visa";
    	}
    	// then check for AmEx
    	else if (/^3[47]/.test(creditCardNumber)) {
    		result = "amex";
    	}
    	return result;
    }

    function checkExpDate(input) {
      var currentDate = new Date();
      var currentYear = currentDate.getFullYear().toString().slice(2);
      var currentMonth = currentDate.getMonth() + 1;
      if (input.$modelValue) {
        var year = input.$modelValue.slice(2);
        var month = input.$modelValue.slice(0,2);
      }

      if (year < currentYear || month > 12) {
        utils.setServerValidationToField($scope, $scope.form.expDate, 'ilegal_date');
      }
      if (year == currentYear && month < currentMonth) {
        utils.setServerValidationToField($scope, $scope.form.expDate, 'ilegal_date');
      }
    }

    function submitBilling(form) {
      vm.submitted = true;
      if (!form.$valid) {
        return;
      }
    }

  }

})();
<|endoftext|>


<commit_before>(function(window) {

  function now() {
    if(window.performance) {
      return window.performance.now();
    }
    return (new Date()).getTime();
  }

  function Renderer() {
    this.content = document.createElement("div");
    this.content.className = "__root";
    this.elementCache = {"__root": this.content};
    this.prevTree = {};
    this.tree = {};
    this.postRenders = [];
    this.lastDiff = {};
    var self = this;
    this.handleEvent = function handleEvent(e) {
      var id = e.currentTarget._id;
      var elem = self.tree[id];
      if(!elem) return;
      var handler = elem[e.type];
      if(handler) { handler(e, elem); }
    };
  }

  Renderer.prototype = {
    reset: function() {
      this.prevTree = this.tree;
      this.tree = {};
    },

    domify: function domify() {
      var fakePrev = {}; //create an empty object once instead of every instance of the loop
      var elements = this.tree;
      var prevElements = this.prevTree;
      var diff = this.lastDiff;
      var elemKeys = Object.keys(diff);
      var elementCache = this.elementCache;
      for(var i = 0, len = elemKeys.length; i < len; i++) {
        var id = elemKeys[i];
        var cur = elements[id];
        var prev = prevElements[id] || fakePrev;
        var type = diff[id];
        var div;
        if(type === "replaced") {
          var me = elementCache[id];
          if(me.parentNode) me.parentNode.removeChild(me);
          div = document.createElement(cur.t || "div");
          div._id = id;
          elementCache[id] = div;
        } else if(type === "added") {
          div = document.createElement(cur.t || "div");
          div._id = id;
          elementCache[id] = div;
        } else if(type === "updated" || type === "moved") {
          div = elementCache[id];
        } else {
          //NOTE: Batching the removes such that you only remove the parent
          //didn't actually make this faster surprisingly. Given that this
          //strategy is much simpler and there's no noticable perf difference
          //we'll just do the dumb thing and remove all the children one by one.
          var me = elementCache[id]
          if(me.parentNode) me.parentNode.removeChild(me);
          elementCache[id] = null;
          continue;
        }

        var style = div.style;
        if(cur.c !== prev.c) div.className = cur.c;
        if(cur.draggable !== prev.draggable) div.draggable = cur.draggable;
        if(cur.contentEditable !== prev.contentEditable) div.contentEditable = cur.contentEditable || "inherit";
        if(cur.colspan !== prev.colspan) div.colSpan = cur.colspan;
        if(cur.placeholder !== prev.placeholder) div.placeholder = cur.placeholder;
        if(cur.selected !== prev.selected) div.selected = cur.selected;

        if(cur.left !== prev.left)  style.left = cur.left;
        if(cur.top !== prev.top) style.top = cur.top;
        if(cur.height !== prev.height) style.height = cur.height;
        if(cur.width !== prev.width)  style.width = cur.width;
        if(cur.zIndex !== prev.zIndex) style.zIndex = cur.zIndex;

        if(cur.backgroundColor !== prev.backgroundColor) style.backgroundColor = cur.backgroundColor || "transparent";
        if(cur.backgroundImage !== prev.backgroundImage) {
          style.backgroundImage = "url('" + cur.backgroundImage + "')";
        }
        if(cur.border !== prev.border) style.border = cur.border || "none";
        if(cur.borderRadius !== prev.borderRadius) style.borderRadius = cur.borderRadius || 0;
        if(cur.opacity !== prev.opacity) style.opacity = cur.opacity || 1;
        if(cur.fontSize !== prev.fontSize) style.fontSize = cur.fontSize;
        if(cur.textAlign !== prev.textAlign) style.justifyContent = cur.textAlign;
        if(cur.verticalAlign !== prev.verticalAlign) style.alignItems = cur.verticalAlign;
        if(cur.color !== prev.color) style.color = cur.color || "inherit";
        if(cur.fontFamily !== prev.fontFamily) style.fontFamily = cur.fontFamily || "inherit";
        if(cur.value !== prev.value) div.value = cur.value;
        if(cur.t === "input" && cur.type !== prev.type) div.type = cur.type;
        if(cur.text !== prev.text) div.textContent = cur.text;
        //events
        if(cur.dblclick !== prev.dblclick) div.ondblclick = cur.dblclick !== undefined ? this.handleEvent : undefined;
        if(cur.click !== prev.click) div.onclick = cur.click !== undefined ? this.handleEvent : undefined;
        if(cur.contextmenu !== prev.contextmenu) div.oncontextmenu = cur.contextmenu !== undefined ? this.handleEvent : undefined;
        if(cur.mousedown !== prev.mousedown) div.onmousedown = cur.mousedown !== undefined ? this.handleEvent : undefined;
        if(cur.mousemove !== prev.mousemove) div.onmousemove = cur.mousemove !== undefined ? this.handleEvent : undefined;
        if(cur.mouseup !== prev.mouseup) div.onmouseup = cur.mouseup !== undefined ? this.handleEvent : undefined;
        if(cur.mousein !== prev.mousein) div.onmousein = cur.mousein !== undefined ? this.handleEvent : undefined;
        if(cur.mouseout !== prev.mouseout) div.onmouseout = cur.mouseout !== undefined ? this.handleEvent : undefined;
        if(cur.mouseleave !== prev.mouseleave) div.onmouseleave = cur.mouseleave !== undefined ? this.handleEvent : undefined;
        if(cur.mousewheel !== prev.mousewheel) div.onmouseheel = cur.mousewheel !== undefined ? this.handleEvent : undefined;
        if(cur.dragover !== prev.dragover) div.ondragover = cur.dragover !== undefined ? this.handleEvent : undefined;
        if(cur.dragstart !== prev.dragstart) div.ondragstart = cur.dragstart !== undefined ? this.handleEvent : undefined;
        if(cur.dragend !== prev.dragend) div.ondragend = cur.dragend !== undefined ? this.handleEvent : undefined;
        if(cur.drag !== prev.drag) div.ondrag = cur.drag !== undefined ? this.handleEvent : undefined;
        if(cur.drop !== prev.drop) div.ondrop = cur.drop !== undefined ? this.handleEvent : undefined;
        if(cur.scroll !== prev.scroll) div.onscroll = cur.scroll !== undefined ? this.handleEvent : undefined;
        if(cur.focus !== prev.focus) div.onfocus = cur.focus !== undefined ? this.handleEvent : undefined;
        if(cur.blur !== prev.blur) div.onblur = cur.blur !== undefined ? this.handleEvent : undefined;
        if(cur.input !== prev.input) div.oninput = cur.input !== undefined ? this.handleEvent : undefined;
        if(cur.keydown !== prev.keydown) div.onkeydown = cur.keydown !== undefined ? this.handleEvent : undefined;

        if(type === "added" || type === "replaced" || type === "moved") {
          var parentEl = elementCache[cur.parent];
          if(cur.ix >= parentEl.children.length) {
            parentEl.appendChild(div);
          } else {
            parentEl.insertBefore(div, parentEl.children[cur.ix]);
          }
        }
      }
    },

    diff: function diff() {
      var a = this.prevTree;
      var b = this.tree;
      var as = Object.keys(a);
      var bs = Object.keys(b);
      var updated = {};
      for(var i = 0, len = as.length; i < len; i++) {
        var curA = a[as[i]];
        var curB = b[as[i]];
        if(curB === undefined) {
          updated[as[i]] = "removed";
          continue;
        }
        if(curA.t !== curB.t) {
          updated[as[i]] = "replaced";
          continue;
        }
        if(curA.ix !== curB.ix) {
          updated[as[i]] = "moved";
          continue;
        }
        if(curA.c === curB.c
           && curA.placeholder === curB.placeholder
           && curA.selected === curB.selected
           && curA.value === curB.value
           && curA.text === curB.text
           && curA.top === curB.top
           && curA.left === curB.left
           && curA.width === curB.width
           && curA.height === curB.height
           && curA.zIndex === curB.zIndex
           && curA.backgroundColor === curB.backgroundColor
           && curA.backgroundImage === curB.backgroundImage
           && curA.color === curB.color
           && curA.colspan === curB.colspan
           && curA.border === curB.border
           && curA.borderRadius === curB.borderRadius
           && curA.opacity === curB.opacity
           && curA.fontFamily === curB.fontFamily
           && curA.fontSize === curB.fontSize
           && curA.textAlign === curB.textAlign
           && curA.verticalAlign === curB.verticalAlign) {
          continue;
        }
        updated[as[i]] = "updated";
      }
      for(var i = 0, len = bs.length; i < len; i++) {
        var curA = a[bs[i]];
        var curB = b[bs[i]];
        if(curA === undefined) {
          updated[bs[i]] = "added";
          continue;
        }
        if(curA.t !== curB.t) {
          updated[bs[i]] = "replaced";
          continue;
        }
        if(curA.ix !== curB.ix) {
          updated[bs[i]] = "moved";
          continue;
        }
        if(curA.c === curB.c
           && curA.placeholder === curB.placeholder
           && curA.selected === curB.selected
           && curA.value === curB.value
           && curA.text === curB.text
           && curA.top === curB.top
           && curA.left === curB.left
           && curA.width === curB.width
           && curA.height === curB.height
           && curA.zIndex === curB.zIndex
           && curA.backgroundColor === curB.backgroundColor
           && curA.backgroundImage === curB.backgroundImage
           && curA.color === curB.color
           && curA.colspan === curB.colspan
           && curA.border === curB.border
           && curA.borderRadius === curB.borderRadius
           && curA.opacity === curB.opacity
           && curA.fontFamily === curB.fontFamily
           && curA.fontSize === curB.fontSize
           && curA.textAlign === curB.textAlign
           && curA.verticalAlign === curB.verticalAlign) {
          continue;
        }
        updated[bs[i]] = "updated";
      }
      this.lastDiff = updated;
      return updated;
    },

    prepare: function prepare(elem) {
      var tree = this.tree;
      if(!elem.parent) elem.parent = "__root";
      tree[elem.id] = elem;
      if(elem.postRender) {
        this.postRenders.push(elem);
      }
      var children = elem.children;
      if(children) {
        for(var childIx = 0, len = children.length; childIx < len; childIx++) {
          var child = children[childIx];
          if(child === undefined) continue;
          if(!child.id) { child.id = elem.id + "__" + childIx; }
          child.parent = elem.id;
          child.ix = childIx;
          this.prepare(child);
        }
      }
      return tree;
    },

    postDomify: function postRender() {
      var postRenders = this.postRenders;
      var diff = this.lastDiff;
      var elementCache = this.elementCache;
      for(var i = 0, len = postRenders.length; i < len; i++) {
        var elem = postRenders[i];
        var id = elem.id;
        if(diff[id] === "updated" || diff[id] === "added") {
          elem.postRender(elementCache[elem.id], elem);
        }
      }
    },

    render: function(elem) {
      var start = now();
      this.reset();
      var post = this.prepare(elem);
      var prepare = now();
      var d = this.diff();
      var diff = now();
      this.domify();
      var domify = now();
      this.postDomify();
      var postDomify = now();
      var time = now() - start;
      if(time > 5) {
        console.log("slow render (> 5ms): ", time, {prepare: prepare - start,
                                                    diff: diff - prepare,
                                                    domify: domify - diff,
                                                    postDomify: postDomify - domify});
      }
    }

  };

  function test() {
    console.time("build");
    var root = {children: [], id: "testRoot"};
    for(var i = 0; i < 100; i++) {
      var me = {id: "blah" + i};
      var children = [];
      for(var x = 0; x < 100; x++) {
        children[x] = {text: "foo" + x};
      }
      me.children = children;
      root.children[i] = me;
    }
    console.log(root);
    var tree = {};
    prepare(tree, root);
    console.timeEnd("build");
    console.time("diff scratch");
    var d = diff({}, tree);
    console.timeEnd("diff scratch");
    console.time("draw scratch");
    render(tree, d);
    console.timeEnd("draw scratch");
    console.time("diff equal");
    var d2 = diff(tree, tree);
    console.timeEnd("diff equal");
    console.time("draw equal");
    render(tree, d2);
    console.timeEnd("draw equal");
    return [d,d2];
  }

  window.microReact = {Renderer: Renderer};

})(window);
<commit_msg>position fixes<commit_after>(function(window) {

  function now() {
    if(window.performance) {
      return window.performance.now();
    }
    return (new Date()).getTime();
  }

  function Renderer() {
    this.content = document.createElement("div");
    this.content.className = "__root";
    this.elementCache = {"__root": this.content};
    this.prevTree = {};
    this.tree = {};
    this.postRenders = [];
    this.lastDiff = {};
    var self = this;
    this.handleEvent = function handleEvent(e) {
      var id = e.currentTarget._id;
      var elem = self.tree[id];
      if(!elem) return;
      var handler = elem[e.type];
      if(handler) { handler(e, elem); }
    };
  }

  Renderer.prototype = {
    reset: function() {
      this.prevTree = this.tree;
      this.tree = {};
    },

    domify: function domify() {
      var fakePrev = {}; //create an empty object once instead of every instance of the loop
      var elements = this.tree;
      var prevElements = this.prevTree;
      var diff = this.lastDiff;
      var elemKeys = Object.keys(diff);
      var elementCache = this.elementCache;
      for(var i = 0, len = elemKeys.length; i < len; i++) {
        var id = elemKeys[i];
        var cur = elements[id];
        var prev = prevElements[id] || fakePrev;
        var type = diff[id];
        var div;
        if(type === "replaced") {
          var me = elementCache[id];
          if(me.parentNode) me.parentNode.removeChild(me);
          div = document.createElement(cur.t || "div");
          div._id = id;
          elementCache[id] = div;
        } else if(type === "added") {
          div = document.createElement(cur.t || "div");
          div._id = id;
          elementCache[id] = div;
        } else if(type === "updated" || type === "moved") {
          div = elementCache[id];
        } else {
          //NOTE: Batching the removes such that you only remove the parent
          //didn't actually make this faster surprisingly. Given that this
          //strategy is much simpler and there's no noticable perf difference
          //we'll just do the dumb thing and remove all the children one by one.
          var me = elementCache[id]
          if(me.parentNode) me.parentNode.removeChild(me);
          elementCache[id] = null;
          continue;
        }

        var style = div.style;
        if(cur.c !== prev.c) div.className = cur.c;
        if(cur.draggable !== prev.draggable) div.draggable = cur.draggable;
        if(cur.contentEditable !== prev.contentEditable) div.contentEditable = cur.contentEditable || "inherit";
        if(cur.colspan !== prev.colspan) div.colSpan = cur.colspan;
        if(cur.placeholder !== prev.placeholder) div.placeholder = cur.placeholder;
        if(cur.selected !== prev.selected) div.selected = cur.selected;

        if(cur.left !== prev.left)  style.left = cur.left === undefined ? "auto" : cur.left;
        if(cur.top !== prev.top) style.top = cur.top === undefined ? "auto" : cur.top;
        if(cur.height !== prev.height) style.height = cur.height === undefined ? "auto" : cur.height;
        if(cur.width !== prev.width)  style.width = cur.width === undefined ? "auto" : cur.width;
        if(cur.zIndex !== prev.zIndex) style.zIndex = cur.zIndex;

        if(cur.backgroundColor !== prev.backgroundColor) style.backgroundColor = cur.backgroundColor || "transparent";
        if(cur.backgroundImage !== prev.backgroundImage) {
          style.backgroundImage = "url('" + cur.backgroundImage + "')";
        }
        if(cur.border !== prev.border) style.border = cur.border || "none";
        if(cur.borderRadius !== prev.borderRadius) style.borderRadius = cur.borderRadius || 0;
        if(cur.opacity !== prev.opacity) style.opacity = cur.opacity || 1;
        if(cur.fontSize !== prev.fontSize) style.fontSize = cur.fontSize;
        if(cur.textAlign !== prev.textAlign) style.justifyContent = cur.textAlign;
        if(cur.verticalAlign !== prev.verticalAlign) style.alignItems = cur.verticalAlign;
        if(cur.color !== prev.color) style.color = cur.color || "inherit";
        if(cur.fontFamily !== prev.fontFamily) style.fontFamily = cur.fontFamily || "inherit";
        if(cur.value !== prev.value) div.value = cur.value;
        if(cur.t === "input" && cur.type !== prev.type) div.type = cur.type;
        if(cur.text !== prev.text) div.textContent = cur.text;
        //events
        if(cur.dblclick !== prev.dblclick) div.ondblclick = cur.dblclick !== undefined ? this.handleEvent : undefined;
        if(cur.click !== prev.click) div.onclick = cur.click !== undefined ? this.handleEvent : undefined;
        if(cur.contextmenu !== prev.contextmenu) div.oncontextmenu = cur.contextmenu !== undefined ? this.handleEvent : undefined;
        if(cur.mousedown !== prev.mousedown) div.onmousedown = cur.mousedown !== undefined ? this.handleEvent : undefined;
        if(cur.mousemove !== prev.mousemove) div.onmousemove = cur.mousemove !== undefined ? this.handleEvent : undefined;
        if(cur.mouseup !== prev.mouseup) div.onmouseup = cur.mouseup !== undefined ? this.handleEvent : undefined;
        if(cur.mousein !== prev.mousein) div.onmousein = cur.mousein !== undefined ? this.handleEvent : undefined;
        if(cur.mouseout !== prev.mouseout) div.onmouseout = cur.mouseout !== undefined ? this.handleEvent : undefined;
        if(cur.mouseleave !== prev.mouseleave) div.onmouseleave = cur.mouseleave !== undefined ? this.handleEvent : undefined;
        if(cur.mousewheel !== prev.mousewheel) div.onmouseheel = cur.mousewheel !== undefined ? this.handleEvent : undefined;
        if(cur.dragover !== prev.dragover) div.ondragover = cur.dragover !== undefined ? this.handleEvent : undefined;
        if(cur.dragstart !== prev.dragstart) div.ondragstart = cur.dragstart !== undefined ? this.handleEvent : undefined;
        if(cur.dragend !== prev.dragend) div.ondragend = cur.dragend !== undefined ? this.handleEvent : undefined;
        if(cur.drag !== prev.drag) div.ondrag = cur.drag !== undefined ? this.handleEvent : undefined;
        if(cur.drop !== prev.drop) div.ondrop = cur.drop !== undefined ? this.handleEvent : undefined;
        if(cur.scroll !== prev.scroll) div.onscroll = cur.scroll !== undefined ? this.handleEvent : undefined;
        if(cur.focus !== prev.focus) div.onfocus = cur.focus !== undefined ? this.handleEvent : undefined;
        if(cur.blur !== prev.blur) div.onblur = cur.blur !== undefined ? this.handleEvent : undefined;
        if(cur.input !== prev.input) div.oninput = cur.input !== undefined ? this.handleEvent : undefined;
        if(cur.keydown !== prev.keydown) div.onkeydown = cur.keydown !== undefined ? this.handleEvent : undefined;

        if(type === "added" || type === "replaced" || type === "moved") {
          var parentEl = elementCache[cur.parent];
          if(cur.ix >= parentEl.children.length) {
            parentEl.appendChild(div);
          } else {
            parentEl.insertBefore(div, parentEl.children[cur.ix]);
          }
        }
      }
    },

    diff: function diff() {
      var a = this.prevTree;
      var b = this.tree;
      var as = Object.keys(a);
      var bs = Object.keys(b);
      var updated = {};
      for(var i = 0, len = as.length; i < len; i++) {
        var curA = a[as[i]];
        var curB = b[as[i]];
        if(curB === undefined) {
          updated[as[i]] = "removed";
          continue;
        }
        if(curA.t !== curB.t) {
          updated[as[i]] = "replaced";
          continue;
        }
        if(curA.ix !== curB.ix) {
          updated[as[i]] = "moved";
          continue;
        }
        if(curA.c === curB.c
           && curA.placeholder === curB.placeholder
           && curA.selected === curB.selected
           && curA.value === curB.value
           && curA.text === curB.text
           && curA.top === curB.top
           && curA.left === curB.left
           && curA.width === curB.width
           && curA.height === curB.height
           && curA.zIndex === curB.zIndex
           && curA.backgroundColor === curB.backgroundColor
           && curA.backgroundImage === curB.backgroundImage
           && curA.color === curB.color
           && curA.colspan === curB.colspan
           && curA.border === curB.border
           && curA.borderRadius === curB.borderRadius
           && curA.opacity === curB.opacity
           && curA.fontFamily === curB.fontFamily
           && curA.fontSize === curB.fontSize
           && curA.textAlign === curB.textAlign
           && curA.verticalAlign === curB.verticalAlign) {
          continue;
        }
        updated[as[i]] = "updated";
      }
      for(var i = 0, len = bs.length; i < len; i++) {
        var curA = a[bs[i]];
        var curB = b[bs[i]];
        if(curA === undefined) {
          updated[bs[i]] = "added";
          continue;
        }
        if(curA.t !== curB.t) {
          updated[bs[i]] = "replaced";
          continue;
        }
        if(curA.ix !== curB.ix) {
          updated[bs[i]] = "moved";
          continue;
        }
        if(curA.c === curB.c
           && curA.placeholder === curB.placeholder
           && curA.selected === curB.selected
           && curA.value === curB.value
           && curA.text === curB.text
           && curA.top === curB.top
           && curA.left === curB.left
           && curA.width === curB.width
           && curA.height === curB.height
           && curA.zIndex === curB.zIndex
           && curA.backgroundColor === curB.backgroundColor
           && curA.backgroundImage === curB.backgroundImage
           && curA.color === curB.color
           && curA.colspan === curB.colspan
           && curA.border === curB.border
           && curA.borderRadius === curB.borderRadius
           && curA.opacity === curB.opacity
           && curA.fontFamily === curB.fontFamily
           && curA.fontSize === curB.fontSize
           && curA.textAlign === curB.textAlign
           && curA.verticalAlign === curB.verticalAlign) {
          continue;
        }
        updated[bs[i]] = "updated";
      }
      this.lastDiff = updated;
      return updated;
    },

    prepare: function prepare(elem) {
      var tree = this.tree;
      if(!elem.parent) elem.parent = "__root";
      tree[elem.id] = elem;
      if(elem.postRender) {
        this.postRenders.push(elem);
      }
      var children = elem.children;
      if(children) {
        for(var childIx = 0, len = children.length; childIx < len; childIx++) {
          var child = children[childIx];
          if(child === undefined) continue;
          if(!child.id) { child.id = elem.id + "__" + childIx; }
          child.parent = elem.id;
          child.ix = childIx;
          this.prepare(child);
        }
      }
      return tree;
    },

    postDomify: function postRender() {
      var postRenders = this.postRenders;
      var diff = this.lastDiff;
      var elementCache = this.elementCache;
      for(var i = 0, len = postRenders.length; i < len; i++) {
        var elem = postRenders[i];
        var id = elem.id;
        if(diff[id] === "updated" || diff[id] === "added") {
          elem.postRender(elementCache[elem.id], elem);
        }
      }
    },

    render: function(elem) {
      var start = now();
      this.reset();
      var post = this.prepare(elem);
      var prepare = now();
      var d = this.diff();
      var diff = now();
      this.domify();
      var domify = now();
      this.postDomify();
      var postDomify = now();
      var time = now() - start;
      if(time > 5) {
        console.log("slow render (> 5ms): ", time, {prepare: prepare - start,
                                                    diff: diff - prepare,
                                                    domify: domify - diff,
                                                    postDomify: postDomify - domify});
      }
    }

  };

  function test() {
    console.time("build");
    var root = {children: [], id: "testRoot"};
    for(var i = 0; i < 100; i++) {
      var me = {id: "blah" + i};
      var children = [];
      for(var x = 0; x < 100; x++) {
        children[x] = {text: "foo" + x};
      }
      me.children = children;
      root.children[i] = me;
    }
    console.log(root);
    var tree = {};
    prepare(tree, root);
    console.timeEnd("build");
    console.time("diff scratch");
    var d = diff({}, tree);
    console.timeEnd("diff scratch");
    console.time("draw scratch");
    render(tree, d);
    console.timeEnd("draw scratch");
    console.time("diff equal");
    var d2 = diff(tree, tree);
    console.timeEnd("diff equal");
    console.time("draw equal");
    render(tree, d2);
    console.timeEnd("draw equal");
    return [d,d2];
  }

  window.microReact = {Renderer: Renderer};

})(window);
<|endoftext|>


<commit_before>const path = require('path')

module.exports = {
  entry: './src/index.tsx',
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  watch: true,
}
<commit_msg>Adding lighter-weight source maps.<commit_after>const path = require('path')

module.exports = {
  entry: './src/index.tsx',
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  watch: true,
}
<|endoftext|>


<commit_before>ZBase.registerView((function() {
  var widget_list = null;
  var edit_view = null;

  // REMOVEME
  var goToURL = function(path) {
    var kPathPrefix = "/a/reports/";
    var report_id = path.substr(kPathPrefix.length);
    loadReport(report_id);
  }
  // REMOVEME END

  var loadReport = function(report_id) {
    if (widget_list) {
      widget_list.destroy();
      widget_list = null;
    }

    $.showLoader();
    $.httpGet("/api/v1/documents/" + report_id, function(r) {
      if (r.status == 200) {
        var doc = JSON.parse(r.response);
        if (doc.content.length == 0) {
          doc.content = null;
        } else {
          doc.content = JSON.parse(doc.content);
        }

        // load required widgets
        var required_widgets = findRequiredWidgets(doc);
        ReportWidgetFactory.loadWidgets(required_widgets, function() {
          render(doc);
          $.hideLoader();
        });
      } else {
        $.fatalError();
      }
    });
  };

  var destroy = function() {
    //if (docsync) {
    //  docsync.close();
    //}

    if (widget_list) {
      widget_list.destroy();
    }

    if (edit_view) {
      edit_view.destroy();
    }
  };

  var render = function(doc) {
    var readonly = !doc.is_writable;
    var page = $.getTemplate(
        "views/report",
        "zbase_report_main_tpl");

    $.handleLinks(page);
    $.replaceViewport(page);

    setReportName(doc.name);
    setReportDescription(doc.content.description);

    widget_list = WidgetList(doc.content.widgets);
    widget_list.onWidgetEdit(function(widget_id) {
      showWidgetEditor(widget_id);
    });

    // handle display mode
    $(".zbase_report z-dropdown.mode").addEventListener("change", function() {
      widget_list.setEditable(this.getValue() == "editing");
    }, false);

    if (readonly) {
      $(".readonly_hint").classList.remove("hidden");
    } else {
      initNameEditing();
      initDescriptionEditing();
      initShareDocModal(doc.uuid);
    }

    showReportView();

    //// setup docsync
    //docsync = DocSync(
    //    getDocument,
    //    "/api/v1/documents/" + doc_id,
    //    $(".zbase_report_infobar"));
  };

  var showReportView = function(doc) {
    //showLoader?
    if (edit_view) {
      edit_view.destroy();
    }
    var viewport = $(".zbase_report_viewport");
    viewport.innerHTML = "";

    if (widget_list) {
      widget_list.render(viewport);
      widget_list.setEditable(true);
    } else {
      $.fatalError();
    }
  };

  var showWidgetEditor = function(widget_id) {
    if (!widget_list) {
      $.fatalError();
      return;
    }

    var conf = widget_list.getWidgetConfig(widget_id);
    edit_view = ReportWidgetFactory.getWidgetEditor(conf);

    edit_view.onSave(function(config) {
      widget_list.updateWidgetConfig(widget_id, config);
      showReportView();
    });

    edit_view.onCancel(function() {
      showReportView();
    });

    showEditView();
  };

  var showEditView = function() {
    var viewport = $(".zbase_report_viewport");
    viewport.innerHTML = "";
    edit_view.render(viewport);
  };

  var findRequiredWidgets = function(doc) {
    var widgets = [];

    if (doc.content.hasOwnProperty("widgets")) {
      for (var i = 0; i < doc.content.widgets.length; i++) {
        if (widgets.indexOf(doc.content.widgets[i].type) == -1) {
          widgets.push(doc.content.widgets[i].type);
        }
      }
    }

    return widgets;
  };

  //var setEditable = function(is_editable) {
  //  widget_list.setEditable(is_editable);

  //  if (is_editable) {
  //    $(".writable_report_actions").classList.remove("hidden");
  //    $(".zbase_report_pane .report_name").classList.add("editable");
  //    $(".zbase_report_pane .report_description").classList.add("editable");
  //  } else {
  //    $(".writable_report_actions").classList.add("hidden");
  //    $(".zbase_report_pane .report_name").classList.remove("editable");
  //    $(".zbase_report_pane .report_description").classList.remove("editable");
  //  }
  //};

  var initShareDocModal = function(doc_id) {
    var modal = ShareDocModal(
        $(".zbase_report_pane"),
        doc_id,
        "http://zbase.io/a/report/" + doc_id);

    $.onClick($(".zbase_report_pane .link.share"), function() {
      modal.show();
    });
  };

  var initNameEditing = function() {
    var modal = $(".zbase_report_pane z-modal.rename_report");
    var name_input = $("input.report_name", modal);

    $.onClick($(".zbase_report_pane .report_name.editable"), function() {
      modal.show();
      name_input.focus();
    });

    $.onClick($("button.submit", modal), function() {
      setReportName($.escapeHTML(name_input.value));
      docsync.saveDocument();
      modal.close();
    });
  };

  var initDescriptionEditing = function() {
    var modal = $(".zbase_report_pane z-modal.edit_description");
    var textarea = $("textarea.report_description", modal);

    var showModal = function() {
      modal.show();
      textarea.focus();
    };

    $.onClick($(".zbase_report_pane .report_description.editable"), showModal);
    $.onClick($(".zbase_report_pane .link.add_description"), showModal);

    $.onClick($("button.submit", modal), function() {
      setReportDescription($.escapeHTML(textarea.value));
      docsync.saveDocument();
      modal.close();
    });
  };

  //var initContentEditing = function(page) {
  //  var edit_pane = $(".zbase_report_pane .edit_content_pane");
  //  var report_ui = $(".zbase_report_pane .report_ui");

  //  var closeEditPane = function() {
  //    updateReportContent();
  //    edit_pane.classList.add("hidden");
  //    report_ui.classList.remove("hidden");
  //    $(".error_note", edit_pane).classList.add("hidden");
  //  };

  //  $.onClick($(".zbase_report_pane .link.edit"), function() {
  //    report_ui.classList.add("hidden");
  //    edit_pane.classList.remove("hidden");
  //  });

  //  $.onClick($(".submit", edit_pane), function() {
  //    try {
  //      var content = JSON.parse(
  //          $.escapeHTML($("z-codeeditor", edit_pane).getValue()));
  //      description = content.description;
  //      widget_list.setJSON(content.widgets);
  //      docsync.saveDocument();
  //      closeEditPane();
  //    } catch (e) {
  //      $(".error_note", edit_pane).classList.remove("hidden");
  //    }
  //  });
  //  $.onClick($(".close", edit_pane), closeEditPane);
  //};

  var setReportName = function(name) {
    var escaped_name = $.escapeHTML(name);
    $("zbase-breadcrumbs-section.report_name").innerHTML = escaped_name;
    $(".zbase_report_pane .report_name").innerHTML = escaped_name;
    $(".zbase_report_pane z-modal input.report_name").value = escaped_name;
  };

  var setReportDescription = function(description) {
    var escaped_description = $.escapeHTML(description);

    //FIXME
    var readonly = false;
    if (!readonly && escaped_description.length == 0) {
      // display edit link
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.remove("hidden");
    } else {
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.add("hidden");
    }

    $(".zbase_report_pane .report_description").innerHTML = escaped_description;
    $(".zbase_report_pane z-modal textarea.report_description").innerHTML =
      escaped_description;
  };

  //var setReportContent = function() {
  //  var content = {
  //    description: description,
  //    widgets: widget_list.getJSON()
  //  };

  //  $(".zbase_report_pane .edit_content_pane z-codeeditor").setValue(
  //      JSON.stringify(content));
  //};

  //var updateReportContent = function() {
  //  setReportContent();
  //  setReportDescription();
  //};

  var getDocument = function() {
    var widgets = [];
    if (widget_list) {
      widgets = widget_list.getJSON();
    }

    return {
      content: JSON.stringify({
          description: $(".zbase_report_pane .report_description").innerText,
          widgets: widgets}),
      name: $(".zbase_report_pane input.report_name").value
    };
  };

  return {
    name: "report",
    loadView: function(params) { goToURL(params.path); },
    unloadView: destroy,
    handleNavigationChange: goToURL
  };

})());
<commit_msg>init WidgetList with doc.content.widgets or empty array<commit_after>ZBase.registerView((function() {
  var widget_list = null;
  var edit_view = null;

  // REMOVEME
  var goToURL = function(path) {
    var kPathPrefix = "/a/reports/";
    var report_id = path.substr(kPathPrefix.length);
    loadReport(report_id);
  }
  // REMOVEME END

  var loadReport = function(report_id) {
    if (widget_list) {
      widget_list.destroy();
      widget_list = null;
    }

    $.showLoader();
    $.httpGet("/api/v1/documents/" + report_id, function(r) {
      if (r.status == 200) {
        var doc = JSON.parse(r.response);
        if (doc.content.length == 0) {
          doc.content = null;
        } else {
          doc.content = JSON.parse(doc.content);
        }

        // load required widgets
        var required_widgets = findRequiredWidgets(doc);
        ReportWidgetFactory.loadWidgets(required_widgets, function() {
          render(doc);
          $.hideLoader();
        });
      } else {
        $.fatalError();
      }
    });
  };

  var destroy = function() {
    //if (docsync) {
    //  docsync.close();
    //}

    if (widget_list) {
      widget_list.destroy();
    }

    if (edit_view) {
      edit_view.destroy();
    }
  };

  var render = function(doc) {
    var readonly = !doc.is_writable;
    var page = $.getTemplate(
        "views/report",
        "zbase_report_main_tpl");

    $.handleLinks(page);
    $.replaceViewport(page);

    setReportName(doc.name);
    setReportDescription(doc.content.description);

    var widgets = [];
    if (doc.content.hasOwnProperty("widgets")) {
      widgets = doc.content.widgets;
    }
    widget_list = WidgetList(widgets);
    widget_list.onWidgetEdit(function(widget_id) {
      showWidgetEditor(widget_id);
    });

    // handle display mode
    $(".zbase_report z-dropdown.mode").addEventListener("change", function() {
      widget_list.setEditable(this.getValue() == "editing");
    }, false);

    if (readonly) {
      $(".readonly_hint").classList.remove("hidden");
    } else {
      initNameEditing();
      initDescriptionEditing();
      initShareDocModal(doc.uuid);
    }

    showReportView();

    //// setup docsync
    //docsync = DocSync(
    //    getDocument,
    //    "/api/v1/documents/" + doc_id,
    //    $(".zbase_report_infobar"));
  };

  var showReportView = function(doc) {
    //showLoader?
    if (edit_view) {
      edit_view.destroy();
    }
    var viewport = $(".zbase_report_viewport");
    viewport.innerHTML = "";

    if (widget_list) {
      widget_list.render(viewport);
      widget_list.setEditable(true);
    } else {
      $.fatalError();
    }
  };

  var showWidgetEditor = function(widget_id) {
    if (!widget_list) {
      $.fatalError();
      return;
    }

    var conf = widget_list.getWidgetConfig(widget_id);
    edit_view = ReportWidgetFactory.getWidgetEditor(conf);

    edit_view.onSave(function(config) {
      widget_list.updateWidgetConfig(widget_id, config);
      showReportView();
    });

    edit_view.onCancel(function() {
      showReportView();
    });

    showEditView();
  };

  var showEditView = function() {
    var viewport = $(".zbase_report_viewport");
    viewport.innerHTML = "";
    edit_view.render(viewport);
  };

  var findRequiredWidgets = function(doc) {
    var widgets = [];

    if (doc.content.hasOwnProperty("widgets")) {
      for (var i = 0; i < doc.content.widgets.length; i++) {
        if (widgets.indexOf(doc.content.widgets[i].type) == -1) {
          widgets.push(doc.content.widgets[i].type);
        }
      }
    }

    return widgets;
  };

  //var setEditable = function(is_editable) {
  //  widget_list.setEditable(is_editable);

  //  if (is_editable) {
  //    $(".writable_report_actions").classList.remove("hidden");
  //    $(".zbase_report_pane .report_name").classList.add("editable");
  //    $(".zbase_report_pane .report_description").classList.add("editable");
  //  } else {
  //    $(".writable_report_actions").classList.add("hidden");
  //    $(".zbase_report_pane .report_name").classList.remove("editable");
  //    $(".zbase_report_pane .report_description").classList.remove("editable");
  //  }
  //};

  var initShareDocModal = function(doc_id) {
    var modal = ShareDocModal(
        $(".zbase_report_pane"),
        doc_id,
        "http://zbase.io/a/report/" + doc_id);

    $.onClick($(".zbase_report_pane .link.share"), function() {
      modal.show();
    });
  };

  var initNameEditing = function() {
    var modal = $(".zbase_report_pane z-modal.rename_report");
    var name_input = $("input.report_name", modal);

    $.onClick($(".zbase_report_pane .report_name.editable"), function() {
      modal.show();
      name_input.focus();
    });

    $.onClick($("button.submit", modal), function() {
      setReportName($.escapeHTML(name_input.value));
      docsync.saveDocument();
      modal.close();
    });
  };

  var initDescriptionEditing = function() {
    var modal = $(".zbase_report_pane z-modal.edit_description");
    var textarea = $("textarea.report_description", modal);

    var showModal = function() {
      modal.show();
      textarea.focus();
    };

    $.onClick($(".zbase_report_pane .report_description.editable"), showModal);
    $.onClick($(".zbase_report_pane .link.add_description"), showModal);

    $.onClick($("button.submit", modal), function() {
      setReportDescription($.escapeHTML(textarea.value));
      docsync.saveDocument();
      modal.close();
    });
  };

  //var initContentEditing = function(page) {
  //  var edit_pane = $(".zbase_report_pane .edit_content_pane");
  //  var report_ui = $(".zbase_report_pane .report_ui");

  //  var closeEditPane = function() {
  //    updateReportContent();
  //    edit_pane.classList.add("hidden");
  //    report_ui.classList.remove("hidden");
  //    $(".error_note", edit_pane).classList.add("hidden");
  //  };

  //  $.onClick($(".zbase_report_pane .link.edit"), function() {
  //    report_ui.classList.add("hidden");
  //    edit_pane.classList.remove("hidden");
  //  });

  //  $.onClick($(".submit", edit_pane), function() {
  //    try {
  //      var content = JSON.parse(
  //          $.escapeHTML($("z-codeeditor", edit_pane).getValue()));
  //      description = content.description;
  //      widget_list.setJSON(content.widgets);
  //      docsync.saveDocument();
  //      closeEditPane();
  //    } catch (e) {
  //      $(".error_note", edit_pane).classList.remove("hidden");
  //    }
  //  });
  //  $.onClick($(".close", edit_pane), closeEditPane);
  //};

  var setReportName = function(name) {
    var escaped_name = $.escapeHTML(name);
    $("zbase-breadcrumbs-section.report_name").innerHTML = escaped_name;
    $(".zbase_report_pane .report_name").innerHTML = escaped_name;
    $(".zbase_report_pane z-modal input.report_name").value = escaped_name;
  };

  var setReportDescription = function(description) {
    var escaped_description = $.escapeHTML(description);

    //FIXME
    var readonly = false;
    if (!readonly && escaped_description.length == 0) {
      // display edit link
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.remove("hidden");
    } else {
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.add("hidden");
    }

    $(".zbase_report_pane .report_description").innerHTML = escaped_description;
    $(".zbase_report_pane z-modal textarea.report_description").innerHTML =
      escaped_description;
  };

  //var setReportContent = function() {
  //  var content = {
  //    description: description,
  //    widgets: widget_list.getJSON()
  //  };

  //  $(".zbase_report_pane .edit_content_pane z-codeeditor").setValue(
  //      JSON.stringify(content));
  //};

  //var updateReportContent = function() {
  //  setReportContent();
  //  setReportDescription();
  //};

  var getDocument = function() {
    var widgets = [];
    if (widget_list) {
      widgets = widget_list.getJSON();
    }

    return {
      content: JSON.stringify({
          description: $(".zbase_report_pane .report_description").innerText,
          widgets: widgets}),
      name: $(".zbase_report_pane input.report_name").value
    };
  };

  return {
    name: "report",
    loadView: function(params) { goToURL(params.path); },
    unloadView: destroy,
    handleNavigationChange: goToURL
  };

})());
<|endoftext|>


<commit_before>ZBase.registerView((function() {
  var kPathPrefix = "/a/reports/";
  var docsync;

  var loadReport = function(params) {
    var query_id = params.path.substr(kPathPrefix.length);

    $.showLoader();
    $.httpGet("/api/v1/documents/" + query_id, function(r) {
      if (r.status == 200) {
        var doc = JSON.parse(r.response);
        renderReport(doc);
        $.hideLoader();
      } else {
        $.fatalError();
      }
    });
  };

  var renderReport = function(doc) {
    var readonly = !doc.is_writable;
    var page = $.getTemplate(
        "views/report",
        "zbase_report_main_tpl");

    if (!readonly) {
      // setup docsync
      docsync = DocSync(
          getDocument,
          "/api/v1/documents/" + doc.uuid,
          $(".zbase_report_infobar", page));
    }

    if (!readonly) {
      $(".zbase_report_pane .report_name", page).classList.add("editable");
      $(".zbase_report_pane .report_description", page).classList.add("editable");
    } else {
      $(".readonly_hint", page).classList.remove("hidden");
      $(".writable_report_actions", page).classList.add("hidden");
    }

    $.handleLinks(page);
    $.replaceViewport(page);

    //report name
    setReportName(doc.name);

    //report description
    var description = "";
    try {
      var content = JSON.parse(doc.content);
      description = content.description;
      setReportContent(doc.content);
    } catch(e) {}
    setReportDescription(description, readonly);

    if (!readonly) {
      //init edit actions
      initNameEditing();
      initDescriptionEditing();
      initShareDocModal(doc.uuid);
      initContentEditing();
    }
  };

  var initShareDocModal = function(doc_id) {
    var modal = ShareDocModal(
        $(".zbase_report_pane"),
        doc_id,
        "http://zbase.io/a/report/" + doc_id);

    $.onClick($(".zbase_report_pane .link.share"), function() {
      modal.show();
    });
  };

  var initNameEditing = function() {
    var modal = $(".zbase_report_pane z-modal.rename_report");
    var name_input = $("input.report_name", modal);

    $.onClick($(".zbase_report_pane .report_name.editable"), function() {
      modal.show();
      name_input.focus();
    });

    $.onClick($("button.submit", modal), function() {
      setReportName($.escapeHTML(name_input.value));
      docsync.saveDocument();
      modal.close();
    });
  };

  var initDescriptionEditing = function() {
    var modal = $(".zbase_report_pane z-modal.edit_description");
    var textarea = $("textarea.report_description", modal);

    var showModal = function() {
      modal.show();
      textarea.focus();
    };

    $.onClick($(".zbase_report_pane .report_description.editable"), showModal);
    $.onClick($(".zbase_report_pane .link.add_description"), showModal);

    $.onClick($("button.submit", modal), function() {
      setReportDescription($.escapeHTML(textarea.value), false);
      docsync.saveDocument();
      modal.close();
    });
  };

  var initContentEditing = function(page) {
    var edit_pane = $(".zbase_report_pane .edit_content_pane");
    var report_ui = $(".zbase_report_pane .report_ui");

    var closeEditPane = function() {
      edit_pane.classList.add("hidden");
      report_ui.classList.remove("hidden");
    };

    $.onClick($(".zbase_report_pane .link.edit"), function() {
      report_ui.classList.add("hidden");
      edit_pane.classList.remove("hidden");
    });

    $.onClick($(".submit", edit_pane), function() {
      var content = $.escapeHTML($("z-codeeditor", edit_pane).getValue());
      try {
        var content_obj = JSON.parse(content);
        setReportDescription(content_obj.description, false);
        setReportContent(content);
        docsync.saveDocument();
        closeEditPane();
      } catch (e) {
        //TODO handle invalid json
      }
    });
    $.onClick($(".close", edit_pane), closeEditPane);
  };

  var setReportName = function(name) {
    var escaped_name = $.escapeHTML(name);
    $("zbase-breadcrumbs-section.report_name").innerHTML = escaped_name;
    $(".zbase_report_pane .report_name").innerHTML = escaped_name;
    $(".zbase_report_pane z-modal input.report_name").value = escaped_name;
  };

  var setReportDescription = function(description, readonly) {
    var escaped_description = (description == undefined ||description.length == 0) ?
        "" : $.escapeHTML(description);

    //display link if no description
    if (!readonly && escaped_description.length == 0) {
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.remove("hidden");
    } else {
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.add("hidden");
    }

    $(".zbase_report_pane .report_description").innerHTML = escaped_description;
    $(".zbase_report_pane z-modal textarea.report_description").innerHTML =
      escaped_description;
  };

  var setReportContent = function(content) {
    $(".zbase_report_pane .edit_content_pane z-codeeditor").setValue(content);
  };

  var getDocument = function() {
    return {
      content: $(".zbase_report_pane .edit_content_pane z-codeeditor").getValue(),
      name: $(".zbase_report_pane input.report_name").value
    };
  };

  var destroy = function() {
    if (docsync) {
      docsync.close();
    }
  };

  return {
    name: "report",
    loadView: loadReport,
    unloadView: destroy,
    handleNavigationChange: loadReport
  };

})());
<commit_msg>make content visible within view<commit_after>ZBase.registerView((function() {
  var kPathPrefix = "/a/reports/";
  var content = {};
  var docsync;
  var readonly;

  var loadReport = function(params) {
    var query_id = params.path.substr(kPathPrefix.length);

    $.showLoader();
    $.httpGet("/api/v1/documents/" + query_id, function(r) {
      if (r.status == 200) {
        var doc = JSON.parse(r.response);
        renderReport(doc);
        $.hideLoader();
      } else {
        $.fatalError();
      }
    });
  };

  var renderReport = function(doc) {
    readonly = !doc.is_writable;
    var page = $.getTemplate(
        "views/report",
        "zbase_report_main_tpl");

    if (!readonly) {
      // setup docsync
      docsync = DocSync(
          getDocument,
          "/api/v1/documents/" + doc.uuid,
          $(".zbase_report_infobar", page));
    }

    if (!readonly) {
      $(".zbase_report_pane .report_name", page).classList.add("editable");
      $(".zbase_report_pane .report_description", page).classList.add("editable");
    } else {
      $(".readonly_hint", page).classList.remove("hidden");
      $(".writable_report_actions", page).classList.add("hidden");
    }

    $.handleLinks(page);
    $.replaceViewport(page);

    //report name
    setReportName(doc.name);

    //report content
    try {
      content = JSON.parse(doc.content);
    } catch(e) {}
    updateReportContent();

    if (!readonly) {
      //init edit actions
      initNameEditing();
      initDescriptionEditing();
      initShareDocModal(doc.uuid);
      initContentEditing();
    }
  };

  var initShareDocModal = function(doc_id) {
    var modal = ShareDocModal(
        $(".zbase_report_pane"),
        doc_id,
        "http://zbase.io/a/report/" + doc_id);

    $.onClick($(".zbase_report_pane .link.share"), function() {
      modal.show();
    });
  };

  var initNameEditing = function() {
    var modal = $(".zbase_report_pane z-modal.rename_report");
    var name_input = $("input.report_name", modal);

    $.onClick($(".zbase_report_pane .report_name.editable"), function() {
      modal.show();
      name_input.focus();
    });

    $.onClick($("button.submit", modal), function() {
      setReportName($.escapeHTML(name_input.value));
      docsync.saveDocument();
      modal.close();
    });
  };

  var initDescriptionEditing = function() {
    var modal = $(".zbase_report_pane z-modal.edit_description");
    var textarea = $("textarea.report_description", modal);

    var showModal = function() {
      modal.show();
      textarea.focus();
    };

    $.onClick($(".zbase_report_pane .report_description.editable"), showModal);
    $.onClick($(".zbase_report_pane .link.add_description"), showModal);

    $.onClick($("button.submit", modal), function() {
      content.description = $.escapeHTML(textarea.value);
      updateReportContent();
      docsync.saveDocument();
      modal.close();
    });
  };

  var initContentEditing = function(page) {
    var edit_pane = $(".zbase_report_pane .edit_content_pane");
    var report_ui = $(".zbase_report_pane .report_ui");

    var closeEditPane = function() {
      edit_pane.classList.add("hidden");
      report_ui.classList.remove("hidden");
    };

    $.onClick($(".zbase_report_pane .link.edit"), function() {
      report_ui.classList.add("hidden");
      edit_pane.classList.remove("hidden");
    });

    $.onClick($(".submit", edit_pane), function() {
      var new_content = $.escapeHTML($("z-codeeditor", edit_pane).getValue());
      try {
        content = JSON.parse(new_content);
        updateReportContent();
        docsync.saveDocument();
        closeEditPane();
      } catch (e) {
        //TODO handle invalid json
      }
    });
    $.onClick($(".close", edit_pane), closeEditPane);
  };

  var setReportName = function(name) {
    var escaped_name = $.escapeHTML(name);
    $("zbase-breadcrumbs-section.report_name").innerHTML = escaped_name;
    $(".zbase_report_pane .report_name").innerHTML = escaped_name;
    $(".zbase_report_pane z-modal input.report_name").value = escaped_name;
  };

  var setReportDescription = function() {
    var escaped_description = $.escapeHTML(content.description);

    if (!readonly && escaped_description.length == 0) {
      // display edit link
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.remove("hidden");
    } else {
      $(".zbase_report_pane .sidebar_content .link.add_description")
        .classList.add("hidden");
    }

    $(".zbase_report_pane .report_description").innerHTML = escaped_description;
    $(".zbase_report_pane z-modal textarea.report_description").innerHTML =
      escaped_description;
  };

  var setReportContent = function() {
    $(".zbase_report_pane .edit_content_pane z-codeeditor").setValue(
        JSON.stringify(content));
  };

  var updateReportContent = function(readonly) {
    setReportContent();
    setReportDescription(readonly);
  };

  var getDocument = function() {
    return {
      content: JSON.stringify(content),
      name: $(".zbase_report_pane input.report_name").value
    };
  };

  var destroy = function() {
    if (docsync) {
      docsync.close();
    }
  };

  return {
    name: "report",
    loadView: loadReport,
    unloadView: destroy,
    handleNavigationChange: loadReport
  };

})());
<|endoftext|>