<commit_before>var gulp = require('gulp');
var wiredep = require('wiredep');
var merge = require('gulp-merge');
var sourcemaps = require('gulp-sourcemaps');
var ts = require('gulp-typescript');
var runSequence = require('run-sequence');
var changed = require('gulp-changed');
var less = require('gulp-less');
var connect = require('gulp-connect');
var open = require('open');
var serveStatic = require('serve-static');
var inject = require('gulp-inject');
var gp = require('gulp-plumber');
var plumber = function() {
    return gp({ errorHandler: function(err) {
        console.log(err);
        this.emit('end');
    }})
};
var debug = require('gulp-debug');
var proxy = require('proxy-middleware');
var url = require('url');
var es = require('event-stream');
var ngTemplates = require('gulp-angular-templatecache');
var rev = require("gulp-rev");
var rimraf = require('rimraf');
var concat = require('gulp-concat');
var ngAnnotate = require('gulp-ng-annotate');
var uglify = require('gulp-uglify');
var minifyCss = require('gulp-minify-css');

var JS_SCRIPT_SOURCE = 'src/**/*.js';
var TS_SCRIPT_SOURCE = 'src/**/*.ts';
var STYLE_SOURCE = 'src/**/*.less';
var TEMPLATES_SOURCE = ['src/**/*.html', '!src/index.html'];
var INDEX_SOURCE = 'src/index.html';
var PORT = 4567;

var tsProject = ts.createProject({
    declartionFiles: true,
    noExternalResolve: true,
    sortProject: true
});

function scripts() {
    var tsResult = gulp.src(TS_SCRIPT_SOURCE)
        .pipe(plumber())
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject, null, ts.reporter.longReporter()));
    return [
        tsResult.dts,
        merge([
            tsResult.js,
            gulp.src(JS_SCRIPT_SOURCE)
                .pipe(plumber())
                .pipe(changed('dist/scripts'))
        ])
    ];
}

gulp.task('scripts', [], function() {
    var r = scripts();
    return merge([
        r[0]
            .pipe(gulp.dest('dist/definitions')),
        r[1]
            .pipe(sourcemaps.write())
            .pipe(gulp.dest('dist/scripts'))
    ]);
});
gulp.task('scripts-release', [], function() {
    var r = scripts();
    return merge([
        r[0]
            .pipe(gulp.dest('dist/definitions')),
        merge([
            gulp.src(wiredep().js)
                .pipe(plumber())
                .pipe(sourcemaps.init()),
            r[1]
                .pipe(ngAnnotate()),
            gulp.src(TEMPLATES_SOURCE)
                .pipe(plumber())
                .pipe(ngTemplates({
                    module: 'app'
                }))
                .pipe(debug()) // don't know why this helps, but it does....
        ])
            .pipe(concat('scripts.js'))
            .pipe(uglify())
            .pipe(rev())
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest('dist/scripts'))
    ]);
});

gulp.task('templates', [], function () {
    return gulp.src(TEMPLATES_SOURCE)
        .pipe(plumber())
        .pipe(changed('dist'))
        .pipe(gulp.dest('dist'));
});

function styles(){
    return gulp.src(STYLE_SOURCE)
        .pipe(plumber())
        .pipe(changed('dist/styles'))
        .pipe(sourcemaps.init())
        // we run wiredep twice, once to really pull in bower components (bower: block), and once to just reference the (bower-refonly: block)
        .pipe(wiredep.stream())
        .pipe(wiredep.stream({
            fileTypes:{
                less: {
                    block: /(([ \t]*)\/\/\s*bower-refonly:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
                    replace: {
                        less: '@import (reference) "{{filePath}}";'
                    }
                }
            }
        }))
        .pipe(less());
}

gulp.task('styles', ['fonts'], function () {
    return styles()
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('dist/styles'));
});
gulp.task('styles-release', ['fonts'], function () {
    return merge([
            styles(),
            gulp.src(wiredep().css)
                .pipe(plumber())
        ])
        .pipe(concat('styles.css'))
        .pipe(minifyCss())
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('dist/styles'));
});
gulp.task('fonts', [], function() {
    return gulp.src('bower_components/bootstrap-less/fonts/*')
        .pipe(plumber())
        .pipe(gulp.dest('dist/fonts'));
});

gulp.task('index', ['scripts', 'styles', 'templates'], function() {
    return gulp.src(INDEX_SOURCE)
        .pipe(plumber())
        .pipe(wiredep.stream())
        .pipe(inject(gulp.src(['dist/scripts/**/*.js', 'dist/styles/**/*.css'], { read: false}), { ignorePath: 'dist' }))
        .pipe(gulp.dest('./dist'));
});

gulp.task('index-release', ['scripts-release', 'styles-release'], function() {
    return gulp.src(INDEX_SOURCE)
        .pipe(plumber())
        .pipe(inject(gulp.src(['dist/scripts/**/scripts-*.js', 'dist/styles/**/styles-*.css'], { read: false}), { ignorePath: 'dist' }))
        .pipe(gulp.dest('./dist'));
});

gulp.task('server', ['index'], function() {
    connect.server({
        livereload: { port: 8785 },
        port: PORT,
        root: ['dist', '.'],
        middleware: function(c, opt) {
            return [
                c().use('/bower_components', c.static('./bower_components')),
                c().use('/api', proxy(url.parse('http://localhost:63915/api')))
            ];
        }
    });
});
gulp.task('server-release', ['index-release'], function() {
    connect.server({
        port: PORT,
        root: 'dist',
        middleware: function(c, opt) {
            return [
                c().use('/api', proxy(url.parse('http://localhost:63915/api')))
            ];
        }
    });
});

gulp.task('open', ['server'], function() {
    open('http://localhost:' + PORT);
});

gulp.task('open-release', ['server-release'], function() {
    open('http://localhost:' + PORT);
});

gulp.task('reload', [], function() {
    // not working, don't know why
    return gulp.src('dist/index.html').pipe(connect.reload())
});

gulp.task('watch', ['scripts'], function() {
    gulp.watch([TS_SCRIPT_SOURCE, JS_SCRIPT_SOURCE], function() { runSequence('scripts', 'index', 'reload'); });
    gulp.watch(STYLE_SOURCE, function() { runSequence('styles', 'index', 'reload'); });
    gulp.watch(TEMPLATES_SOURCE, function() { runSequence('templates', 'reload'); });
    gulp.watch(INDEX_SOURCE, function() { runSequence('index', 'reload'); });
});

gulp.task('clean', function(callback) {
    rimraf('dist', callback);
});

gulp.task('default', function(callback) {
    return runSequence('clean', 'open', 'watch', callback);
});
gulp.task('release', function(callback) {
    return runSequence('clean', 'open-release', callback);
});
<commit_msg>Allow variables split for less imports<commit_after>var gulp = require('gulp');
var wiredep = require('wiredep');
var merge = require('gulp-merge');
var sourcemaps = require('gulp-sourcemaps');
var ts = require('gulp-typescript');
var runSequence = require('run-sequence');
var changed = require('gulp-changed');
var less = require('gulp-less');
var connect = require('gulp-connect');
var open = require('open');
var serveStatic = require('serve-static');
var inject = require('gulp-inject');
var gp = require('gulp-plumber');
var plumber = function() {
    return gp({ errorHandler: function(err) {
        console.log(err);
        this.emit('end');
    }})
};
var debug = require('gulp-debug');
var proxy = require('proxy-middleware');
var url = require('url');
var es = require('event-stream');
var ngTemplates = require('gulp-angular-templatecache');
var rev = require("gulp-rev");
var rimraf = require('rimraf');
var concat = require('gulp-concat');
var ngAnnotate = require('gulp-ng-annotate');
var uglify = require('gulp-uglify');
var minifyCss = require('gulp-minify-css');

var JS_SCRIPT_SOURCE = 'src/**/*.js';
var TS_SCRIPT_SOURCE = 'src/**/*.ts';
var STYLE_SOURCE = 'src/**/*.less';
var TEMPLATES_SOURCE = ['src/**/*.html', '!src/index.html'];
var INDEX_SOURCE = 'src/index.html';
var PORT = 4567;

var tsProject = ts.createProject({
    declartionFiles: true,
    noExternalResolve: true,
    sortProject: true
});

function scripts() {
    var tsResult = gulp.src(TS_SCRIPT_SOURCE)
        .pipe(plumber())
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject, null, ts.reporter.longReporter()));
    return [
        tsResult.dts,
        merge([
            tsResult.js,
            gulp.src(JS_SCRIPT_SOURCE)
                .pipe(plumber())
                .pipe(changed('dist/scripts'))
        ])
    ];
}

gulp.task('scripts', [], function() {
    var r = scripts();
    return merge([
        r[0]
            .pipe(gulp.dest('dist/definitions')),
        r[1]
            .pipe(sourcemaps.write())
            .pipe(gulp.dest('dist/scripts'))
    ]);
});
gulp.task('scripts-release', [], function() {
    var r = scripts();
    return merge([
        r[0]
            .pipe(gulp.dest('dist/definitions')),
        merge([
            gulp.src(wiredep().js)
                .pipe(plumber())
                .pipe(sourcemaps.init()),
            r[1]
                .pipe(ngAnnotate()),
            gulp.src(TEMPLATES_SOURCE)
                .pipe(plumber())
                .pipe(ngTemplates({
                    module: 'app'
                }))
                .pipe(debug()) // don't know why this helps, but it does....
        ])
            .pipe(concat('scripts.js'))
            .pipe(uglify())
            .pipe(rev())
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest('dist/scripts'))
    ]);
});

gulp.task('templates', [], function () {
    return gulp.src(TEMPLATES_SOURCE)
        .pipe(plumber())
        .pipe(changed('dist'))
        .pipe(gulp.dest('dist'));
});

function styles(){
    return gulp.src(STYLE_SOURCE)
        .pipe(plumber())
        .pipe(changed('dist/styles'))
        .pipe(sourcemaps.init())
        // we run wiredep twice, once to really pull in bower components (bower: block), and once to just reference the (bower-refonly: block)
        .pipe(wiredep.stream())
        .pipe(wiredep.stream({
            fileTypes:{
                less: {
                    block: /(([ \t]*)\/\/\s*bower-refonly:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
                    replace: {
                        less: '@import (reference) "{{filePath}}";'
                    }
                }
            }
        }))
        .pipe(wiredep.stream({
            exclude: [ /!(variables\.less)/ ],
            fileTypes:{
                less: {
                    block: /(([ \t]*)\/\/\s*bower-variablesonly:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
                }
            }
        }))
        .pipe(wiredep.stream({
            exclude: [ /variables\.less/ ],
            fileTypes:{
                less: {
                    block: /(([ \t]*)\/\/\s*bower-novariables:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
                }
            }
        }))
        .pipe(less());
}

gulp.task('styles', ['fonts'], function () {
    return styles()
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('dist/styles'));
});
gulp.task('styles-release', ['fonts'], function () {
    return merge([
            styles(),
            gulp.src(wiredep().css)
                .pipe(plumber())
        ])
        .pipe(concat('styles.css'))
        .pipe(minifyCss())
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('dist/styles'));
});
gulp.task('fonts', [], function() {
    return gulp.src('bower_components/bootstrap-less/fonts/*')
        .pipe(plumber())
        .pipe(gulp.dest('dist/fonts'));
});

gulp.task('index', ['scripts', 'styles', 'templates'], function() {
    return gulp.src(INDEX_SOURCE)
        .pipe(plumber())
        .pipe(wiredep.stream())
        .pipe(inject(gulp.src(['dist/scripts/**/*.js', 'dist/styles/**/*.css'], { read: false}), { ignorePath: 'dist' }))
        .pipe(gulp.dest('./dist'));
});

gulp.task('index-release', ['scripts-release', 'styles-release'], function() {
    return gulp.src(INDEX_SOURCE)
        .pipe(plumber())
        .pipe(inject(gulp.src(['dist/scripts/**/scripts-*.js', 'dist/styles/**/styles-*.css'], { read: false}), { ignorePath: 'dist' }))
        .pipe(gulp.dest('./dist'));
});

gulp.task('server', ['index'], function() {
    connect.server({
        livereload: { port: 8785 },
        port: PORT,
        root: ['dist', '.'],
        middleware: function(c, opt) {
            return [
                c().use('/bower_components', c.static('./bower_components')),
                c().use('/api', proxy(url.parse('http://localhost:63915/api')))
            ];
        }
    });
});
gulp.task('server-release', ['index-release'], function() {
    connect.server({
        port: PORT,
        root: 'dist',
        middleware: function(c, opt) {
            return [
                c().use('/api', proxy(url.parse('http://localhost:63915/api')))
            ];
        }
    });
});

gulp.task('open', ['server'], function() {
    open('http://localhost:' + PORT);
});

gulp.task('open-release', ['server-release'], function() {
    open('http://localhost:' + PORT);
});

gulp.task('reload', [], function() {
    // not working, don't know why
    return gulp.src('dist/index.html').pipe(connect.reload())
});

gulp.task('watch', ['scripts'], function() {
    gulp.watch([TS_SCRIPT_SOURCE, JS_SCRIPT_SOURCE], function() { runSequence('scripts', 'index', 'reload'); });
    gulp.watch(STYLE_SOURCE, function() { runSequence('styles', 'index', 'reload'); });
    gulp.watch(TEMPLATES_SOURCE, function() { runSequence('templates', 'reload'); });
    gulp.watch(INDEX_SOURCE, function() { runSequence('index', 'reload'); });
});

gulp.task('clean', function(callback) {
    rimraf('dist', callback);
});

gulp.task('default', function(callback) {
    return runSequence('clean', 'open', 'watch', callback);
});
gulp.task('release', function(callback) {
    return runSequence('clean', 'open-release', callback);
});
<|endoftext|>


<commit_before>// -*- Mode: JavaScript QUnit; tab-width: 4; -*-

// Requires

/*<CommonJS>*/
if (typeof assert == 'undefined' && typeof require != 'undefined') {
	require.paths.push('Test/lib');
	var assert = require('assert');

	if (typeof	test == 'undefined')
		var		test = require('SG-Assert-Helpers')
		.		test;
}
/*</CommonJS>*/

var ok = assert.ok;
var equal = assert.equal;

// Local testing sugar

if (typeof	normalizeCSSText == 'undefined')
	var		normalizeCSSText = require('SG-Assert-Helpers')
	.		normalizeCSSText;

if (typeof	matchesMock == 'undefined')
	var		matchesMock = require('SG-Assert-Helpers')
	.		matchesMock;

// API

if (typeof API != 'object') var API = {};
if (typeof exports == 'undefined') exports = this;
else API = exports;

API ["DOM styleSheet"] = function(newSheet){
	if (!newSheet) throw new Error("API test requires passing a newSheet function");

	var I = {};

	I ["test Exists"] = function(){ok( newSheet )}

	I ["test new sheet conforms to basic api"] = function(){

		// console.log(newSheet)
		// console.log(''+newSheet)

		var sheet = newSheet(CSS_MOCK.raw);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		ok(sheet, "must actually create a sheet");

		matchesMock(sheet, CSS_MOCK.parsed)
	}

	I ["test webkit animation"] = function(){

		var sheet = newSheet(WEBKIT_ANIMATION_MOCK_1.raw);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		ok(sheet, "must actually create a sheet");

		matchesMock(sheet, WEBKIT_ANIMATION_MOCK_1.parsed)
	}

	I ["test updating values updates cssText"] = function(){

		var style = '#selector{color:green}';
		var sheet = newSheet(style);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		equal(sheet.cssRules[0].style.color, 'green');
		matchesMock(sheet.cssRules[0].cssText, style);

		sheet.cssRules[0].style.color = 'blue';
		equal(sheet.cssRules[0].style.color, 'blue');

		sheet.toString();

		matchesMock(sheet.cssRules[0].cssText.toString(), '#selector{color:blue}');
		matchesMock(''+sheet.cssRules[0].cssText, '#selector{color:blue}');
	}

	return I;
};

API ["DOM style attribute"] = function(newStyle){
	if (!newStyle) throw new Error("API test requires passing a newStyle function");

	var I = {};

	I ["test Exists"] = function(){ok( newStyle )}

	I ["test new sheet conforms to basic api"] = function(){

		// console.log(newStyle)
		// console.log(''+newStyle)

		var sheet = newStyle(STYLE_MOCK_1.raw);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		ok(sheet, "must actually create a style");

		matchesMock(sheet, STYLE_MOCK_1.parsed)
	}

	I ["test updating values updates cssText"] = function(){

		var style = 'color:green';
		var sheet = newStyle(style);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		equal(sheet.style.color, 'green');
		matchesMock(sheet.style.cssText, style);

		sheet.style.color = 'blue';
		equal(sheet.style.color, 'blue');

		sheet.toString();

		matchesMock(sheet.style.cssText.toString(), 'color:blue');
		matchesMock(''+sheet.style.cssText, 'color:blue');

	}

	return I;
};

// Mock

var CSS_MOCK = {raw:"",parsed:{}};
var styleSheet = CSS_MOCK.parsed;

// styleSheet
styleSheet.cssRules = [];
styleSheet.cssRules.cssText = "";

// cssRule
styleSheet.cssRules[0] = {};
styleSheet.cssRules[0].selectorText = "#selector";
styleSheet.cssRules.cssText +=
styleSheet.cssRules[0].cssText = "#selector { color: green; background-color: rgb(0, 255, 0); }";
CSS_MOCK.raw += styleSheet.cssRules[0].cssText;

// style
styleSheet.cssRules[0].style = {};
styleSheet.cssRules[0].style.cssText = "color: green; background-color: rgb(0, 255, 0);";
styleSheet.cssRules[0].style[styleSheet.cssRules[0].style[0] = 'color'] = "green";
styleSheet.cssRules[0].style.backgroundColor =
styleSheet.cssRules[0].style[styleSheet.cssRules[0].style[1] = 'background-color'] = "rgb(0, 255, 0)";
styleSheet.cssRules[0].style.length = 2;

// cssRule
styleSheet.cssRules[1] = {};
styleSheet.cssRules[1].selectorText = "#selector2";
styleSheet.cssRules.cssText +=
styleSheet.cssRules[1].cssText = "#selector2 { color: blue; background-color: rgb(128, 0, 128); }";
CSS_MOCK.raw += styleSheet.cssRules[1].cssText;

// style
styleSheet.cssRules[1].style = {};
styleSheet.cssRules[1].style.cssText = "color: blue; background-color: rgb(128, 0, 128);";
styleSheet.cssRules[1].style[styleSheet.cssRules[1].style[0] = 'color'] = "blue";
styleSheet.cssRules[1].style.backgroundColor =
styleSheet.cssRules[1].style[styleSheet.cssRules[1].style[1] = 'background-color'] = "rgb(128, 0, 128)";
styleSheet.cssRules[1].style.length = 2;

var STYLE_MOCK_1 = { parsed:{style:{}} };
var style = STYLE_MOCK_1.parsed.style;

STYLE_MOCK_1.raw =
style.cssText = "color: green; background-color: rgb(0, 255, 0);";

style[style[0] = "color"] = "green";
style.backgroundColor =
style[style[1] = "background-color"] = "rgb(0, 255, 0)";

style.length = 2;

var WEBKIT_ANIMATION_MOCK_1 = {

	raw:'\
@-webkit-keyframes my-animation {\
	0% { background-color:blue }\
	100% { background-color:green }\
}\
',

	parsed:{
		cssRules:{
			length:1,
			0:{//WebKitCSSKeyframesRule
				// type:8,

				name:"my-animation",

				cssText:'@-webkit-keyframes my-animation { 0% { background-color:blue } 100% { background-color:green } }',

				cssRules:{

					length:2,

					0:{//WebKitCSSKeyframeRule
						// type:9,
						cssText: "0% { background-color: blue; }",
						keyText: "0%",
						style: {
							cssText: "background-color: blue; ",

							"background-color": "blue",
							backgroundColor: "blue",

							0: "background-color",
							length: 1
						}
					},
					1:{//WebKitCSSKeyframeRule
						// type:9,
						cssText: "100% { background-color: green; }",
						keyText: "100%",
						style: {
							cssText: "background-color: green; ",

							"background-color": "green",
							backgroundColor: "green",

							0: "background-color",
							length: 1
						}
					}
				},

				// length:2,
				0:{//WebKitCSSKeyframeRule
					// type:9,
					cssText: "0% { background-color: blue; }",
					keyText: "0%",
					style: {
						cssText: "background-color: blue; ",

						"background-color": "blue",
						backgroundColor: "blue",

						0: "background-color",
						length: 1
					}
				},
				1:{//WebKitCSSKeyframeRule
					// type:9,
					cssText: "100% { background-color: green; }",
					keyText: "100%",
					style: {
						cssText: "background-color: green; ",

						"background-color": "green",
						backgroundColor: "green",

						0: "background-color",
						length: 1
					}
				}

			}
		}
	}

};

<commit_msg>Tons of new tests for block comments. Many fail :'(<commit_after>// -*- Mode: JavaScript QUnit; tab-width: 4; -*-

// Requires

/*<CommonJS>*/
if (typeof assert == 'undefined' && typeof require != 'undefined') {
	require.paths.push('Test/lib');
	var assert = require('assert');

	if (typeof	test == 'undefined')
		var		test = require('SG-Assert-Helpers')
		.		test;
}
/*</CommonJS>*/

var ok = assert.ok;
var equal = assert.equal;

// Local testing sugar

if (typeof	normalizeCSSText == 'undefined')
	var		normalizeCSSText = require('SG-Assert-Helpers')
	.		normalizeCSSText;

if (typeof	matchesMock == 'undefined')
	var		matchesMock = require('SG-Assert-Helpers')
	.		matchesMock;

// API

if (typeof API != 'object') var API = {};
if (typeof exports == 'undefined') exports = this;
else API = exports;

API ["DOM styleSheet"] = function(newSheet){
	if (!newSheet) throw new Error("API test requires passing a newSheet function");

	var I = {};

	I ["test Exists"] = function(){ok( newSheet )}

	I ["test new sheet conforms to basic api"] = function(){

		// console.log(newSheet)
		// console.log(''+newSheet)

		var sheet = newSheet(CSS_MOCK.raw);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		ok(sheet, "must actually create a sheet");

		matchesMock(sheet, CSS_MOCK.parsed)
	}

	I ["test webkit animation"] = function(){

		var sheet = newSheet(WEBKIT_ANIMATION_MOCK_1.raw);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		ok(sheet, "must actually create a sheet");

		matchesMock(sheet, WEBKIT_ANIMATION_MOCK_1.parsed)
	}

	for (var i = 0; i < MOCK_COMMENTS.length; ++i)
		I ["test comments " + MOCK_COMMENTS[i].raw] =
			newMockTest(MOCK_COMMENTS[i].raw, MOCK_COMMENTS[i].parsed, newSheet)

	for (var i = 0; i < MOCK_COMMENTS_2.length; ++i)
		I ["test comments " + MOCK_COMMENTS_2[i].raw] =
			newMockTest(MOCK_COMMENTS_2[i].raw, MOCK_COMMENTS_2[i].parsed, newSheet)

	I ["test updating values updates cssText"] = function(){

		var style = '#selector{color:green}';
		var sheet = newSheet(style);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		equal(sheet.cssRules[0].style.color, 'green');
		matchesMock(sheet.cssRules[0].cssText, style);

		sheet.cssRules[0].style.color = 'blue';
		equal(sheet.cssRules[0].style.color, 'blue');

		sheet.toString();

		matchesMock(sheet.cssRules[0].cssText.toString(), '#selector{color:blue}');
		matchesMock(''+sheet.cssRules[0].cssText, '#selector{color:blue}');
	}

	return I;
};

API ["DOM style attribute"] = function(newStyle){
	if (!newStyle) throw new Error("API test requires passing a newStyle function");

	var I = {};

	I ["test Exists"] = function(){ok( newStyle )}

	I ["test new sheet conforms to basic api"] = function(){

		// console.log(newStyle)
		// console.log(''+newStyle)

		var sheet = newStyle(STYLE_MOCK_1.raw);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		ok(sheet, "must actually create a style");

		matchesMock(sheet, STYLE_MOCK_1.parsed)
	}

	I ["test updating values updates cssText"] = function(){

		var style = 'color:green';
		var sheet = newStyle(style);
		if (!sheet.cssRules) sheet.cssRules = sheet.rules;

		equal(sheet.style.color, 'green');
		matchesMock(sheet.style.cssText, style);

		sheet.style.color = 'blue';
		equal(sheet.style.color, 'blue');

		sheet.toString();

		matchesMock(sheet.style.cssText.toString(), 'color:blue');
		matchesMock(''+sheet.style.cssText, 'color:blue');

	}

	return I;
};

function newMockTest(raw, parser, newSheet){
	return function(){
		matchesMock(newSheet(raw), parser)
	}
}

// //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  // //
// Mock

var CSS_MOCK = {raw:"",parsed:{}};
var styleSheet = CSS_MOCK.parsed;

// styleSheet
styleSheet.cssRules = [];
styleSheet.cssRules.cssText = "";

// cssRule
styleSheet.cssRules[0] = {};
styleSheet.cssRules[0].selectorText = "#selector";
styleSheet.cssRules.cssText +=
styleSheet.cssRules[0].cssText = "#selector { color: green; background-color: rgb(0, 255, 0); }";
CSS_MOCK.raw += styleSheet.cssRules[0].cssText;

// style
styleSheet.cssRules[0].style = {};
styleSheet.cssRules[0].style.cssText = "color: green; background-color: rgb(0, 255, 0);";
styleSheet.cssRules[0].style[styleSheet.cssRules[0].style[0] = 'color'] = "green";
styleSheet.cssRules[0].style.backgroundColor =
styleSheet.cssRules[0].style[styleSheet.cssRules[0].style[1] = 'background-color'] = "rgb(0, 255, 0)";
styleSheet.cssRules[0].style.length = 2;

// cssRule
styleSheet.cssRules[1] = {};
styleSheet.cssRules[1].selectorText = "#selector2";
styleSheet.cssRules.cssText +=
styleSheet.cssRules[1].cssText = "#selector2 { color: blue; background-color: rgb(128, 0, 128); }";
CSS_MOCK.raw += styleSheet.cssRules[1].cssText;

// style
styleSheet.cssRules[1].style = {};
styleSheet.cssRules[1].style.cssText = "color: blue; background-color: rgb(128, 0, 128);";
styleSheet.cssRules[1].style[styleSheet.cssRules[1].style[0] = 'color'] = "blue";
styleSheet.cssRules[1].style.backgroundColor =
styleSheet.cssRules[1].style[styleSheet.cssRules[1].style[1] = 'background-color'] = "rgb(128, 0, 128)";
styleSheet.cssRules[1].style.length = 2;

// //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  // //

var STYLE_MOCK_1 = { parsed:{style:{}} };
var style = STYLE_MOCK_1.parsed.style;

STYLE_MOCK_1.raw =
style.cssText = "color: green; background-color: rgb(0, 255, 0);";

style[style[0] = "color"] = "green";
style.backgroundColor =
style[style[1] = "background-color"] = "rgb(0, 255, 0)";

style.length = 2;

// //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  // //

var WEBKIT_ANIMATION_MOCK_1 = {

	raw:'\
@-webkit-keyframes my-animation {\
	0% { background-color:blue }\
	100% { background-color:green }\
}\
',

	parsed:{
		cssRules:{
			length:1,
			0:{//WebKitCSSKeyframesRule
				// type:8,

				name:"my-animation",

				cssText:'@-webkit-keyframes my-animation { 0% { background-color:blue } 100% { background-color:green } }',

				cssRules:{

					length:2,

					0:{//WebKitCSSKeyframeRule
						// type:9,
						cssText: "0% { background-color: blue; }",
						keyText: "0%",
						style: {
							cssText: "background-color: blue; ",

							"background-color": "blue",
							backgroundColor: "blue",

							0: "background-color",
							length: 1
						}
					},
					1:{//WebKitCSSKeyframeRule
						// type:9,
						cssText: "100% { background-color: green; }",
						keyText: "100%",
						style: {
							cssText: "background-color: green; ",

							"background-color": "green",
							backgroundColor: "green",

							0: "background-color",
							length: 1
						}
					}
				},

				// length:2,
				0:{//WebKitCSSKeyframeRule
					// type:9,
					cssText: "0% { background-color: blue; }",
					keyText: "0%",
					style: {
						cssText: "background-color: blue; ",

						"background-color": "blue",
						backgroundColor: "blue",

						0: "background-color",
						length: 1
					}
				},
				1:{//WebKitCSSKeyframeRule
					// type:9,
					cssText: "100% { background-color: green; }",
					keyText: "100%",
					style: {
						cssText: "background-color: green; ",

						"background-color": "green",
						backgroundColor: "green",

						0: "background-color",
						length: 1
					}
				}

			}
		}
	}

};

// //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  // //

var	comment, MOCK_COMMENTS = []
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:red}', parsed:{ cssRules:{ length:1, 0:{ cssText:"b{color:red}", style:{ length:1, 0:"color", color:"red" } } } } }
comment = "/*a*/"
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:''+comment+'b{color:red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b'+comment+'{color:red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{'+comment+'color:red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color'+comment+':red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:'+comment+'red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:red'+comment+'}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:red}'+comment+'', parsed:MOCK_COMMENTS[0].parsed }

comment = "\
/******************************\n\
 * lol, Block Comment\n\
******************************/\n\
"
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:''+comment+'b{color:red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b'+comment+'{color:red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{'+comment+'color:red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color'+comment+':red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:'+comment+'red}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:red'+comment+'}', parsed:MOCK_COMMENTS[0].parsed }
MOCK_COMMENTS[MOCK_COMMENTS.length] = { raw:'b{color:red}'+comment+'', parsed:MOCK_COMMENTS[0].parsed }

var MOCK_COMMENTS_2 = []
for (var i = 0; i < MOCK_COMMENTS.length; ++i){
	MOCK_COMMENTS_2[MOCK_COMMENTS_2.length] = {
		raw: MOCK_COMMENTS[i].raw + MOCK_COMMENTS[i].raw,
		parsed: {
			cssRules: {
				length: 2,
				0: MOCK_COMMENTS[i].parsed.cssRules[0],
				1: MOCK_COMMENTS[i].parsed.cssRules[0]
			}
		}
	}
}

// //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  // //
<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/Credit',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/DeveloperError',
        '../Core/Event',
        '../Core/Rectangle',
        '../Core/WebMercatorTilingScheme',
        './ImageryProvider'
    ], function(
        Credit,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Event,
        Rectangle,
        WebMercatorTilingScheme,
        ImageryProvider) {
    "use strict";

    var trailingSlashRegex = /\/$/;
    var defaultCredit = new Credit('MapQuest, Open Street Map and contributors, CC-BY-SA');

    /**
     * Provides tiled imagery hosted by OpenStreetMap or another provider of Slippy tiles.  Please be aware
     * that a default-constructed instance of this class will connect to OpenStreetMap's volunteer-run
     * servers, so you must conform to their
     * {@link http://wiki.openstreetmap.org/wiki/Tile_usage_policy|Tile Usage Policy}.
     *
     * @alias OpenStreetMapImageryProvider
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     * @param {String} [options.url='//a.tile.openstreetmap.org'] The OpenStreetMap server url.
     * @param {String} [options.fileExtension='png'] The file extension for images on the server.
     * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL.
     * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
     * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
     * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
     * @param {Ellipsoid} [options.ellipsoid] The ellipsoid.  If not specified, the WGS84 ellipsoid is used.
     * @param {Credit|String} [options.credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
     *
     * @see ArcGisMapServerImageryProvider
     * @see BingMapsImageryProvider
     * @see GoogleEarthImageryProvider
     * @see SingleTileImageryProvider
     * @see TileMapServiceImageryProvider
     * @see WebMapServiceImageryProvider
     * @see WebMapTileServiceImageryProvider
     * @see UrlTemplateImageryProvider
     *
     * @see {@link http://wiki.openstreetmap.org/wiki/Main_Page|OpenStreetMap Wiki}
     * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
     *
     * @example
     * // OpenStreetMap tile provider
     * var osm = new Cesium.OpenStreetMapImageryProvider({
     *     url : '//a.tile.openstreetmap.org/'
     * });
     */
    var OpenStreetMapImageryProvider = function OpenStreetMapImageryProvider(options) {
        options = defaultValue(options, {});

        var url = defaultValue(options.url, '//a.tile.openstreetmap.org/');

        if (!trailingSlashRegex.test(url)) {
            url = url + '/';
        }

        this._url = url;
        this._fileExtension = defaultValue(options.fileExtension, 'png');
        this._proxy = options.proxy;
        this._tileDiscardPolicy = options.tileDiscardPolicy;

        this._tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid });

        this._tileWidth = 256;
        this._tileHeight = 256;

        this._minimumLevel = defaultValue(options.minimumLevel, 0);
        this._maximumLevel = options.maximumLevel;

        this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle);

        // Check the number of tiles at the minimum level.  If it's more than four,
        // throw an exception, because starting at the higher minimum
        // level will cause too many tiles to be downloaded and rendered.
        var swTile = this._tilingScheme.positionToTileXY(Rectangle.southwest(this._rectangle), this._minimumLevel);
        var neTile = this._tilingScheme.positionToTileXY(Rectangle.northeast(this._rectangle), this._minimumLevel);
        var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
        if (tileCount > 4) {
            throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.');
        }

        this._errorEvent = new Event();

        this._ready = true;

        var credit = defaultValue(options.credit, defaultCredit);
        if (typeof credit === 'string') {
            credit = new Credit(credit);
        }
        this._credit = credit;
    };

    function buildImageUrl(imageryProvider, x, y, level) {
        var url = imageryProvider._url + level + '/' + x + '/' + y + '.' + imageryProvider._fileExtension;

        var proxy = imageryProvider._proxy;
        if (defined(proxy)) {
            url = proxy.getURL(url);
        }

        return url;
    }

    defineProperties(OpenStreetMapImageryProvider.prototype, {
        /**
         * Gets the URL of the service hosting the imagery.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {String}
         * @readonly
         */
        url : {
            get : function() {
                return this._url;
            }
        },

        /**
         * Gets the proxy used by this provider.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Proxy}
         * @readonly
         */
        proxy : {
            get : function() {
                return this._proxy;
            }
        },

        /**
         * Gets the width of each tile, in pixels. This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        tileWidth : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileWidth;
            }
        },

        /**
         * Gets the height of each tile, in pixels.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        tileHeight: {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileHeight;
            }
        },

        /**
         * Gets the maximum level-of-detail that can be requested.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        maximumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._maximumLevel;
            }
        },

        /**
         * Gets the minimum level-of-detail that can be requested.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        minimumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._minimumLevel;
            }
        },

        /**
         * Gets the tiling scheme used by this provider.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {TilingScheme}
         * @readonly
         */
        tilingScheme : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tilingScheme;
            }
        },

        /**
         * Gets the rectangle, in radians, of the imagery provided by this instance.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Rectangle}
         * @readonly
         */
        rectangle : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('rectangle must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._rectangle;
            }
        },

        /**
         * Gets the tile discard policy.  If not undefined, the discard policy is responsible
         * for filtering out "missing" tiles via its shouldDiscardImage function.  If this function
         * returns undefined, no tiles are filtered.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {TileDiscardPolicy}
         * @readonly
         */
        tileDiscardPolicy : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileDiscardPolicy;
            }
        },

        /**
         * Gets an event that is raised when the imagery provider encounters an asynchronous error.  By subscribing
         * to the event, you will be notified of the error and can potentially recover from it.  Event listeners
         * are passed an instance of {@link TileProviderError}.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Event}
         * @readonly
         */
        errorEvent : {
            get : function() {
                return this._errorEvent;
            }
        },

        /**
         * Gets a value indicating whether or not the provider is ready for use.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Boolean}
         * @readonly
         */
        ready : {
            get : function() {
                return this._ready;
            }
        },

        /**
         * Gets the credit to display when this imagery provider is active.  Typically this is used to credit
         * the source of the imagery.  This function should not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Credit}
         * @readonly
         */
        credit : {
            get : function() {
                return this._credit;
            }
        },

        /**
         * Gets a value indicating whether or not the images provided by this imagery provider
         * include an alpha channel.  If this property is false, an alpha channel, if present, will
         * be ignored.  If this property is true, any images without an alpha channel will be treated
         * as if their alpha is 1.0 everywhere.  When this property is false, memory usage
         * and texture upload time are reduced.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Boolean}
         * @readonly
         */
        hasAlphaChannel : {
            get : function() {
                return true;
            }
        }
    });

    /**
     * Gets the credits to be displayed when a given tile is displayed.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level;
     * @returns {Credit[]} The credits to be displayed when the tile is displayed.
     *
     * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready.
     */
    OpenStreetMapImageryProvider.prototype.getTileCredits = function(x, y, level) {
        return undefined;
    };

    /**
     * Requests the image for a given tile.  This function should
     * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level.
     * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or
     *          undefined if there are too many active requests to the server, and the request
     *          should be retried later.  The resolved image may be either an
     *          Image or a Canvas DOM object.
     *
     * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready.
     */
    OpenStreetMapImageryProvider.prototype.requestImage = function(x, y, level) {
        //>>includeStart('debug', pragmas.debug);
        if (!this._ready) {
            throw new DeveloperError('requestImage must not be called before the imagery provider is ready.');
        }
        //>>includeEnd('debug');

        var url = buildImageUrl(this, x, y, level);
        return ImageryProvider.loadImage(this, url);
    };

    /**
     * Picking features is not currently supported by this imagery provider, so this function simply returns
     * undefined.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level.
     * @param {Number} longitude The longitude at which to pick features.
     * @param {Number} latitude  The latitude at which to pick features.
     * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous
     *                   picking completes.  The resolved value is an array of {@link ImageryLayerFeatureInfo}
     *                   instances.  The array may be empty if no features are found at the given location.
     *                   It may also be undefined if picking is not supported.
     */
    OpenStreetMapImageryProvider.prototype.pickFeatures = function() {
        return undefined;
    };

    return OpenStreetMapImageryProvider;
});
<commit_msg>have openStreetMapImageryProdider use urlTemplateImageryProvider<commit_after>/*global define*/
define([
        '../Core/Credit',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/DeveloperError',
        '../Core/Event',
        '../Core/Rectangle',
        '../Core/WebMercatorTilingScheme',
        './ImageryProvider',
        './UrlTemplateImageryProvider'
], function(
        Credit,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Event,
        Rectangle,
        WebMercatorTilingScheme,
        ImageryProvider,
        UrlTemplateImageryProvider
        ) {
    "use strict";

    var trailingSlashRegex = /\/$/;
    var defaultCredit = new Credit('MapQuest, Open Street Map and contributors, CC-BY-SA');

    /**
     * Provides tiled imagery hosted by OpenStreetMap or another provider of Slippy tiles.  Please be aware
     * that a default-constructed instance of this class will connect to OpenStreetMap's volunteer-run
     * servers, so you must conform to their
     * {@link http://wiki.openstreetmap.org/wiki/Tile_usage_policy|Tile Usage Policy}.
     *
     * @alias OpenStreetMapImageryProvider
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     * @param {String} [options.url='//a.tile.openstreetmap.org'] The OpenStreetMap server url.
     * @param {String} [options.fileExtension='png'] The file extension for images on the server.
     * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL.
     * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
     * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
     * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
     * @param {Ellipsoid} [options.ellipsoid] The ellipsoid.  If not specified, the WGS84 ellipsoid is used.
     * @param {Credit|String} [options.credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
     *
     * @see ArcGisMapServerImageryProvider
     * @see BingMapsImageryProvider
     * @see GoogleEarthImageryProvider
     * @see SingleTileImageryProvider
     * @see TileMapServiceImageryProvider
     * @see WebMapServiceImageryProvider
     * @see WebMapTileServiceImageryProvider
     * @see UrlTemplateImageryProvider
     *
     * @see {@link http://wiki.openstreetmap.org/wiki/Main_Page|OpenStreetMap Wiki}
     * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
     *
     * @example
     * // OpenStreetMap tile provider
     * var osm = new Cesium.OpenStreetMapImageryProvider({
     *     url : '//a.tile.openstreetmap.org/'
     * });
     */
    var OpenStreetMapImageryProvider = function OpenStreetMapImageryProvider(options) {
        options = defaultValue(options, {});

        var url = defaultValue(options.url, '//a.tile.openstreetmap.org/');

        if (!trailingSlashRegex.test(url)) {
            url = url + '/';
        }

        this._url = url;
        var fileExtension = defaultValue(options.fileExtension, 'png');
        //this._proxy = options.proxy;
        this._tileDiscardPolicy = options.tileDiscardPolicy;

        var tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid });

        var tileWidth = 256;
        var tileHeight = 256;

        var minimumLevel = defaultValue(options.minimumLevel, 0);
        var maximumLevel = options.maximumLevel;

        var rectangle = defaultValue(options.rectangle, tilingScheme.rectangle);

        // Check the number of tiles at the minimum level.  If it's more than four,
        // throw an exception, because starting at the higher minimum
        // level will cause too many tiles to be downloaded and rendered.
        var swTile = tilingScheme.positionToTileXY(Rectangle.southwest(rectangle), minimumLevel);
        var neTile = tilingScheme.positionToTileXY(Rectangle.northeast(rectangle), minimumLevel);
        var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
        if (tileCount > 4) {
            throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.');
        }

        this._errorEvent = new Event();

        this._ready = true;

        var credit = defaultValue(options.credit, defaultCredit);
        if (typeof credit === 'string') {
            credit = new Credit(credit);
        }

        var templateUrl = url;
        templateUrl += "/{z}/{x}/{y}." + fileExtension;

        this._imageryProvider = new UrlTemplateImageryProvider({
            url: templateUrl,
            proxy: options.proxy,
            credit: credit,
            tilingScheme: tilingScheme,
            tileWidth: tileWidth,
            tileHeight: tileHeight,
            minimumLevel: minimumLevel,
            maximumLevel: maximumLevel,
            rectangle: rectangle
        });
    };

    function buildImageUrl(imageryProvider, x, y, level) {
        var url = imageryProvider._url + level + '/' + x + '/' + y + '.' + imageryProvider._fileExtension;

        var proxy = imageryProvider._proxy;
        if (defined(proxy)) {
            url = proxy.getURL(url);
        }

        return url;
    }

    defineProperties(OpenStreetMapImageryProvider.prototype, {
        /**
         * Gets the URL of the service hosting the imagery.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {String}
         * @readonly
         */
        url : {
            get : function() {
                return this._url;
            }
        },

        /**
         * Gets the proxy used by this provider.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Proxy}
         * @readonly
         */
        proxy : {
            get : function() {
                return this._imageryProvider._proxy;
            }
        },

        /**
         * Gets the width of each tile, in pixels. This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        tileWidth : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._imageryProvider._tileWidth;
            }
        },

        /**
         * Gets the height of each tile, in pixels.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        tileHeight: {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._imageryProvider._tileHeight;
            }
        },

        /**
         * Gets the maximum level-of-detail that can be requested.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        maximumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._imageryProvider._maximumLevel;
            }
        },

        /**
         * Gets the minimum level-of-detail that can be requested.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Number}
         * @readonly
         */
        minimumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._imageryProvider._minimumLevel;
            }
        },

        /**
         * Gets the tiling scheme used by this provider.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {TilingScheme}
         * @readonly
         */
        tilingScheme : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._imageryProvider._tilingScheme;
            }
        },

        /**
         * Gets the rectangle, in radians, of the imagery provided by this instance.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Rectangle}
         * @readonly
         */
        rectangle : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('rectangle must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._imageryProvider._rectangle;
            }
        },

        /**
         * Gets the tile discard policy.  If not undefined, the discard policy is responsible
         * for filtering out "missing" tiles via its shouldDiscardImage function.  If this function
         * returns undefined, no tiles are filtered.  This function should
         * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {TileDiscardPolicy}
         * @readonly
         */
        tileDiscardPolicy : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileDiscardPolicy;
            }
        },

        /**
         * Gets an event that is raised when the imagery provider encounters an asynchronous error.  By subscribing
         * to the event, you will be notified of the error and can potentially recover from it.  Event listeners
         * are passed an instance of {@link TileProviderError}.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Event}
         * @readonly
         */
        errorEvent : {
            get : function() {
                return this._imageryProvider._errorEvent;
            }
        },

        /**
         * Gets a value indicating whether or not the provider is ready for use.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Boolean}
         * @readonly
         */
        ready : {
            get : function() {
                return this._imageryProvider._ready;
            }
        },

        /**
         * Gets the credit to display when this imagery provider is active.  Typically this is used to credit
         * the source of the imagery.  This function should not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Credit}
         * @readonly
         */
        credit : {
            get : function() {
                return this._imageryProvider._credit;
            }
        },

        /**
         * Gets a value indicating whether or not the images provided by this imagery provider
         * include an alpha channel.  If this property is false, an alpha channel, if present, will
         * be ignored.  If this property is true, any images without an alpha channel will be treated
         * as if their alpha is 1.0 everywhere.  When this property is false, memory usage
         * and texture upload time are reduced.
         * @memberof OpenStreetMapImageryProvider.prototype
         * @type {Boolean}
         * @readonly
         */
        hasAlphaChannel : {
            get : function() {
                return true;
            }
        }
    });

    /**
     * Gets the credits to be displayed when a given tile is displayed.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level;
     * @returns {Credit[]} The credits to be displayed when the tile is displayed.
     *
     * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready.
     */
    OpenStreetMapImageryProvider.prototype.getTileCredits = function(x, y, level) {
        return undefined;
    };

    /**
     * Requests the image for a given tile.  This function should
     * not be called before {@link OpenStreetMapImageryProvider#ready} returns true.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level.
     * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or
     *          undefined if there are too many active requests to the server, and the request
     *          should be retried later.  The resolved image may be either an
     *          Image or a Canvas DOM object.
     *
     * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready.
     */
    OpenStreetMapImageryProvider.prototype.requestImage = function(x, y, level) {
        //>>includeStart('debug', pragmas.debug);
        if (!this._imageryProvider._ready) {
            throw new DeveloperError('requestImage must not be called before the imagery provider is ready.');
        }
        //>>includeEnd('debug');

        //var url = buildImageUrl(this, x, y, level);
        //return ImageryProvider.loadImage(this, url);
        console.log("hello");
        return this._imageryProvider.requestImage(x, y, level);
    };

    /**
     * Picking features is not currently supported by this imagery provider, so this function simply returns
     * undefined.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level.
     * @param {Number} longitude The longitude at which to pick features.
     * @param {Number} latitude  The latitude at which to pick features.
     * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous
     *                   picking completes.  The resolved value is an array of {@link ImageryLayerFeatureInfo}
     *                   instances.  The array may be empty if no features are found at the given location.
     *                   It may also be undefined if picking is not supported.
     */
    OpenStreetMapImageryProvider.prototype.pickFeatures = function() {
        return undefined;
    };

    return OpenStreetMapImageryProvider;
});
<|endoftext|>


<commit_before>/*global define*/
define([
        '../../Core/defaultValue',
        '../../Core/defined',
        '../../Core/DeveloperError',
        '../../Core/defineProperties',
        '../../Core/Event',
        '../../Core/wrapFunction',
        '../../DynamicScene/CzmlDataSource',
        '../../DynamicScene/GeoJsonDataSource',
        '../../ThirdParty/when',
        '../getElement'
    ], function(
        defaultValue,
        defined,
        DeveloperError,
        defineProperties,
        Event,
        wrapFunction,
        CzmlDataSource,
        GeoJsonDataSource,
        when,
        getElement) {
    "use strict";
    /*global console*/

    /**
     * A mixin which adds default drag and drop support for CZML files to the Viewer widget.
     * Rather than being called directly, this function is normally passed as
     * a parameter to {@link Viewer#extend}, as shown in the example below.
     * @exports viewerDragDropMixin
     *
     * @param {Viewer} viewer The viewer instance.
     * @param {Object} [options] Configuration options for the mixin.
     * @param {Element|String} [options.dropTarget=viewer.container] The DOM element which will serve as the drop target.
     * @param {Boolean} [options.clearOnDrop=true] When true, dropping files will clear all existing data sources first, when false, new data sources will be loaded after the existing ones.
     *
     * @exception {DeveloperError} viewer is required.
     * @exception {DeveloperError} Element with id <options.dropTarget> does not exist in the document.
     * @exception {DeveloperError} dropTarget is already defined by another mixin.
     * @exception {DeveloperError} dropEnabled is already defined by another mixin.
     * @exception {DeveloperError} onDropError is already defined by another mixin.
     * @exception {DeveloperError} clearOnDrop is already defined by another mixin.
     *
     * @example
     * // Add basic drag and drop support and pop up an alert window on error.
     * var viewer = new Cesium.Viewer('cesiumContainer');
     * viewer.extend(Cesium.viewerDragDropMixin);
     * viewer.onDropError.addEventListener(function(viewerArg, source, error) {
     *     window.alert('Error processing ' + source + ':' + error);
     * });
     */
    var viewerDragDropMixin = function(viewer, options) {
        if (!defined(viewer)) {
            throw new DeveloperError('viewer is required.');
        }
        if (viewer.hasOwnProperty('dropTarget')) {
            throw new DeveloperError('dropTarget is already defined by another mixin.');
        }
        if (viewer.hasOwnProperty('dropEnabled')) {
            throw new DeveloperError('dropEnabled is already defined by another mixin.');
        }
        if (viewer.hasOwnProperty('onDropError')) {
            throw new DeveloperError('onDropError is already defined by another mixin.');
        }
        if (viewer.hasOwnProperty('clearOnDrop')) {
            throw new DeveloperError('clearOnDrop is already defined by another mixin.');
        }

        options = defaultValue(options, defaultValue.EMPTY_OBJECT);

        //Local variables to be closed over by defineProperties.
        var dropEnabled = true;
        var onDropError = new Event();
        var clearOnDrop = defaultValue(options.clearOnDrop, true);
        var dropTarget = defaultValue(options.dropTarget, viewer.container);

        dropTarget = getElement(dropTarget);

        defineProperties(viewer, {
            /**
             * Gets or sets the element to serve as the drop target.
             * @memberof viewerDragDropMixin.prototype
             * @type {Element}
             */
            dropTarget : {
                //TODO See https://github.com/AnalyticalGraphicsInc/cesium/issues/832
                //* @exception {DeveloperError} value is required.
                get : function() {
                    return dropTarget;
                },
                set : function(value) {
                    if (!defined(value)) {
                        throw new DeveloperError('value is required.');
                    }
                    unsubscribe(dropTarget, handleDrop);
                    dropTarget = value;
                    subscribe(dropTarget, handleDrop);
                }
            },

            /**
             * Gets or sets a value indicating if drag and drop support is enabled.
             * @memberof viewerDragDropMixin.prototype
             * @type {Element}
             */
            dropEnabled : {
                get : function() {
                    return dropEnabled;
                },
                set : function(value) {
                    if (value !== dropEnabled) {
                        if (value) {
                            subscribe(dropTarget, handleDrop);
                        } else {
                            unsubscribe(dropTarget, handleDrop);
                        }
                        dropEnabled = value;
                    }
                }
            },

            /**
             * Gets the event that will be raised when an error is encountered during drop processing.
             * @memberof viewerDragDropMixin.prototype
             * @type {Event}
             */
            onDropError : {
                get : function() {
                    return onDropError;
                }
            },

            /**
             * Gets or sets a value indicating if existing data sources should be cleared before adding the newly dropped sources.
             * @memberof viewerDragDropMixin.prototype
             * @type {Boolean}
             */
            clearOnDrop : {
                get : function() {
                    return clearOnDrop;
                },
                set : function(value) {
                    clearOnDrop = value;
                }
            }
        });

        function handleDrop(event) {
            stop(event);

            if (clearOnDrop) {
                viewer.dataSources.removeAll();
            }

            var files = event.dataTransfer.files;
            var length = files.length;
            for ( var i = 0; i < length; i++) {
                var f = files[i];
                var reader = new FileReader();
                reader.onload = createOnLoadCallback(viewer, f.name);
                reader.onerror = createOnDropErrorCallback(viewer, f.name);
                reader.readAsText(f);
            }
        }

        //Enable drop by default;
        subscribe(dropTarget, handleDrop);

        //Wrap the destroy function to make sure all events are unsubscribed from
        viewer.destroy = wrapFunction(viewer, viewer.destroy, function() {
            viewer.dropEnabled = false;
        });

        //Specs need access to handleDrop
        viewer._handleDrop = handleDrop;
    };

    function stop(event) {
        event.stopPropagation();
        event.preventDefault();
    }

    function unsubscribe(dropTarget, handleDrop) {
        var currentTarget = dropTarget;
        if (defined(currentTarget)) {
            currentTarget.removeEventListener('drop', handleDrop, false);
            currentTarget.removeEventListener('dragenter', stop, false);
            currentTarget.removeEventListener('dragover', stop, false);
            currentTarget.removeEventListener('dragexit', stop, false);
        }
    }

    function subscribe(dropTarget, handleDrop) {
        dropTarget.addEventListener('drop', handleDrop, false);
        dropTarget.addEventListener('dragenter', stop, false);
        dropTarget.addEventListener('dragover', stop, false);
        dropTarget.addEventListener('dragexit', stop, false);
    }

    function endsWith(str, suffix) {
        var strLength = str.length;
        var suffixLength = suffix.length;
        return (suffixLength < strLength) && (str.indexOf(suffix, strLength - suffixLength) !== -1);
    }

    function createOnLoadCallback(viewer, source) {
        var DataSource;
        var sourceUpperCase = source.toUpperCase();
        if (endsWith(sourceUpperCase, ".CZML")) {
            DataSource = CzmlDataSource;
        } else if (endsWith(sourceUpperCase, ".GEOJSON") || //
        endsWith(sourceUpperCase, ".JSON") || //
        endsWith(sourceUpperCase, ".TOPOJSON")) {
            DataSource = GeoJsonDataSource;
        } else {
            viewer.onDropError.raiseEvent(viewer, source, 'Unrecognized file extension: ' + source);
        }

        return function(evt) {
            var dataSource = new DataSource();
            try {
                when(dataSource.load(JSON.parse(evt.target.result), source), function() {
                    viewer.dataSources.add(dataSource);
                }, function(error) {
                    viewer.onDropError.raiseEvent(viewer, source, error);
                });
            } catch (error) {
                viewer.onDropError.raiseEvent(viewer, source, error);
            }
        };
    }

    function createOnDropErrorCallback(viewer, name) {
        return function(evt) {
            viewer.onDropError.raiseEvent(viewer, name, evt.target.error);
        };
    }

    return viewerDragDropMixin;
});
<commit_msg>Avoid an error if the file extension is not recognized.<commit_after>/*global define*/
define([
        '../../Core/defaultValue',
        '../../Core/defined',
        '../../Core/DeveloperError',
        '../../Core/defineProperties',
        '../../Core/Event',
        '../../Core/wrapFunction',
        '../../DynamicScene/CzmlDataSource',
        '../../DynamicScene/GeoJsonDataSource',
        '../../ThirdParty/when',
        '../getElement'
    ], function(
        defaultValue,
        defined,
        DeveloperError,
        defineProperties,
        Event,
        wrapFunction,
        CzmlDataSource,
        GeoJsonDataSource,
        when,
        getElement) {
    "use strict";
    /*global console*/

    /**
     * A mixin which adds default drag and drop support for CZML files to the Viewer widget.
     * Rather than being called directly, this function is normally passed as
     * a parameter to {@link Viewer#extend}, as shown in the example below.
     * @exports viewerDragDropMixin
     *
     * @param {Viewer} viewer The viewer instance.
     * @param {Object} [options] Configuration options for the mixin.
     * @param {Element|String} [options.dropTarget=viewer.container] The DOM element which will serve as the drop target.
     * @param {Boolean} [options.clearOnDrop=true] When true, dropping files will clear all existing data sources first, when false, new data sources will be loaded after the existing ones.
     *
     * @exception {DeveloperError} viewer is required.
     * @exception {DeveloperError} Element with id <options.dropTarget> does not exist in the document.
     * @exception {DeveloperError} dropTarget is already defined by another mixin.
     * @exception {DeveloperError} dropEnabled is already defined by another mixin.
     * @exception {DeveloperError} onDropError is already defined by another mixin.
     * @exception {DeveloperError} clearOnDrop is already defined by another mixin.
     *
     * @example
     * // Add basic drag and drop support and pop up an alert window on error.
     * var viewer = new Cesium.Viewer('cesiumContainer');
     * viewer.extend(Cesium.viewerDragDropMixin);
     * viewer.onDropError.addEventListener(function(viewerArg, source, error) {
     *     window.alert('Error processing ' + source + ':' + error);
     * });
     */
    var viewerDragDropMixin = function(viewer, options) {
        if (!defined(viewer)) {
            throw new DeveloperError('viewer is required.');
        }
        if (viewer.hasOwnProperty('dropTarget')) {
            throw new DeveloperError('dropTarget is already defined by another mixin.');
        }
        if (viewer.hasOwnProperty('dropEnabled')) {
            throw new DeveloperError('dropEnabled is already defined by another mixin.');
        }
        if (viewer.hasOwnProperty('onDropError')) {
            throw new DeveloperError('onDropError is already defined by another mixin.');
        }
        if (viewer.hasOwnProperty('clearOnDrop')) {
            throw new DeveloperError('clearOnDrop is already defined by another mixin.');
        }

        options = defaultValue(options, defaultValue.EMPTY_OBJECT);

        //Local variables to be closed over by defineProperties.
        var dropEnabled = true;
        var onDropError = new Event();
        var clearOnDrop = defaultValue(options.clearOnDrop, true);
        var dropTarget = defaultValue(options.dropTarget, viewer.container);

        dropTarget = getElement(dropTarget);

        defineProperties(viewer, {
            /**
             * Gets or sets the element to serve as the drop target.
             * @memberof viewerDragDropMixin.prototype
             * @type {Element}
             */
            dropTarget : {
                //TODO See https://github.com/AnalyticalGraphicsInc/cesium/issues/832
                //* @exception {DeveloperError} value is required.
                get : function() {
                    return dropTarget;
                },
                set : function(value) {
                    if (!defined(value)) {
                        throw new DeveloperError('value is required.');
                    }
                    unsubscribe(dropTarget, handleDrop);
                    dropTarget = value;
                    subscribe(dropTarget, handleDrop);
                }
            },

            /**
             * Gets or sets a value indicating if drag and drop support is enabled.
             * @memberof viewerDragDropMixin.prototype
             * @type {Element}
             */
            dropEnabled : {
                get : function() {
                    return dropEnabled;
                },
                set : function(value) {
                    if (value !== dropEnabled) {
                        if (value) {
                            subscribe(dropTarget, handleDrop);
                        } else {
                            unsubscribe(dropTarget, handleDrop);
                        }
                        dropEnabled = value;
                    }
                }
            },

            /**
             * Gets the event that will be raised when an error is encountered during drop processing.
             * @memberof viewerDragDropMixin.prototype
             * @type {Event}
             */
            onDropError : {
                get : function() {
                    return onDropError;
                }
            },

            /**
             * Gets or sets a value indicating if existing data sources should be cleared before adding the newly dropped sources.
             * @memberof viewerDragDropMixin.prototype
             * @type {Boolean}
             */
            clearOnDrop : {
                get : function() {
                    return clearOnDrop;
                },
                set : function(value) {
                    clearOnDrop = value;
                }
            }
        });

        function handleDrop(event) {
            stop(event);

            if (clearOnDrop) {
                viewer.dataSources.removeAll();
            }

            var files = event.dataTransfer.files;
            var length = files.length;
            for ( var i = 0; i < length; i++) {
                var f = files[i];
                var reader = new FileReader();
                reader.onload = createOnLoadCallback(viewer, f.name);
                reader.onerror = createOnDropErrorCallback(viewer, f.name);
                reader.readAsText(f);
            }
        }

        //Enable drop by default;
        subscribe(dropTarget, handleDrop);

        //Wrap the destroy function to make sure all events are unsubscribed from
        viewer.destroy = wrapFunction(viewer, viewer.destroy, function() {
            viewer.dropEnabled = false;
        });

        //Specs need access to handleDrop
        viewer._handleDrop = handleDrop;
    };

    function stop(event) {
        event.stopPropagation();
        event.preventDefault();
    }

    function unsubscribe(dropTarget, handleDrop) {
        var currentTarget = dropTarget;
        if (defined(currentTarget)) {
            currentTarget.removeEventListener('drop', handleDrop, false);
            currentTarget.removeEventListener('dragenter', stop, false);
            currentTarget.removeEventListener('dragover', stop, false);
            currentTarget.removeEventListener('dragexit', stop, false);
        }
    }

    function subscribe(dropTarget, handleDrop) {
        dropTarget.addEventListener('drop', handleDrop, false);
        dropTarget.addEventListener('dragenter', stop, false);
        dropTarget.addEventListener('dragover', stop, false);
        dropTarget.addEventListener('dragexit', stop, false);
    }

    function endsWith(str, suffix) {
        var strLength = str.length;
        var suffixLength = suffix.length;
        return (suffixLength < strLength) && (str.indexOf(suffix, strLength - suffixLength) !== -1);
    }

    function createOnLoadCallback(viewer, source) {
        var DataSource;
        var sourceUpperCase = source.toUpperCase();
        if (endsWith(sourceUpperCase, ".CZML")) {
            DataSource = CzmlDataSource;
        } else if (endsWith(sourceUpperCase, ".GEOJSON") || //
        endsWith(sourceUpperCase, ".JSON") || //
        endsWith(sourceUpperCase, ".TOPOJSON")) {
            DataSource = GeoJsonDataSource;
        } else {
            viewer.onDropError.raiseEvent(viewer, source, 'Unrecognized file extension: ' + source);
            return undefined;
        }

        return function(evt) {
            var dataSource = new DataSource();
            try {
                when(dataSource.load(JSON.parse(evt.target.result), source), function() {
                    viewer.dataSources.add(dataSource);
                }, function(error) {
                    viewer.onDropError.raiseEvent(viewer, source, error);
                });
            } catch (error) {
                viewer.onDropError.raiseEvent(viewer, source, error);
            }
        };
    }

    function createOnDropErrorCallback(viewer, name) {
        return function(evt) {
            viewer.onDropError.raiseEvent(viewer, name, evt.target.error);
        };
    }

    return viewerDragDropMixin;
});
<|endoftext|>


<commit_before>//Event
$(document).ready(function()
{
	document.receiveUserData();
    document.loadSidebar();
});
//Account
document.popLogin = function()
{

    $("#cover").fadeIn(function ()
    {
        $("#form-signin-container").fadeIn();
    });
};
document.hideLogin = function ()
{
    $("#form-signin-container").fadeOut(function ()
    {
       $("#cover").fadeOut();
    });

};
document.login = function ()
{

    $.ajax({
        url: "Login.exec",
        cache: false,
        type: "POST",
        dataType :"json",
        data: {
            username: $("#form-signin-username").val(),
            password: $("#form-signin-password").val()
        },
        success: function (data)
        {
            $("#form-signin-notice").show();
            $("#form-signin-notice").removeClass();
            switch (data.status)
            {
                case 0:

                    $("#form-signin-notice").addClass("alert alert-success");
                    $("#form-signin-notice").text(data.text);
                    document.receiveUserData();
                    document.hideLogin();
                    document.loadSidebar();
                    break;
                case 1:

                    $("#form-signin-notice").addClass("alert alert-info");
                    $("#form-signin-notice").text(data.text);
                    break;

                case 2:

                    $("#form-signin-notice").addClass("alert alert-warning");
                    $("#form-signin-notice").text(data.text);
                    break;

                default:
                    $("#form-signin-notice").addClass("alert alert-danger");
                    $("#form-signin-notice").text(data.text);
                    break;
            }

        }

    });
};

document.logout = function()
{
    $.removeCookie('identification');
    $("#form-signin-username").val("");
    $("#form-signin-password").val("");
    $("#form-signin-notice").hide();
    $("#signin-block").show();
    $("#signed-block").hide();
};

document.receiveUserData = function ()
{
    $.ajax({
        url: "ReceiveUserData.exec",
        cache: false,
        success: function (data)
        {
        	if(data)
    		{
	            $("#signin-block").hide();
	            $("#signed-block").show();
    		}
        	else
    		{
        	    $("#signin-block").show();
        	    $("#signed-block").hide();
    		}

        }

    });
};
//Content Loader
document.loadContent = function (url)
{
    $.ajax({
        url: url,
        success: function (data)
        {
            $("#content").html(data);
          //  document.contentInit();
        }

    });
};

document.loadSidebar = function ()
{
    $.ajax({
        url: "Sidebar.exec",
        dataType: "json",
        cache:false,
        success: function (data)
        {

            $("#sidebar-content").empty();
            $(data).each(function ()
            {
                var li = $("

");
                li.addClass("sidebar-child");
                var a = $("");
                a.attr("href", "#");
                var i = $("");
                i.addClass("icon");
                i.addClass(this.iconName);
                var span = $("");
                span.text(this.title);
                li.append(a);
                a.append(i);
                a.append(span);
                li.attr("onclick", "document.loadContent('" + this.url + "');");

                $("#sidebar-content").append(li);
            });
            $(".sidebar-child")[0].click();
        }

    });
}<commit_msg>Will refresh side-bar when logout<commit_after>//Event
$(document).ready(function()
{
	document.receiveUserData();
    document.loadSidebar();
});
//Account
document.popLogin = function()
{

    $("#cover").fadeIn(function ()
    {
        $("#form-signin-container").fadeIn();
    });
};
document.hideLogin = function ()
{
    $("#form-signin-container").fadeOut(function ()
    {
       $("#cover").fadeOut();
    });

};
document.login = function ()
{

    $.ajax({
        url: "Login.exec",
        cache: false,
        type: "POST",
        dataType :"json",
        data: {
            username: $("#form-signin-username").val(),
            password: $("#form-signin-password").val()
        },
        success: function (data)
        {
            $("#form-signin-notice").show();
            $("#form-signin-notice").removeClass();
            switch (data.status)
            {
                case 0:

                    $("#form-signin-notice").addClass("alert alert-success");
                    $("#form-signin-notice").text(data.text);
                    document.receiveUserData();
                    document.hideLogin();
                    document.loadSidebar();
                    break;
                case 1:

                    $("#form-signin-notice").addClass("alert alert-info");
                    $("#form-signin-notice").text(data.text);
                    break;

                case 2:

                    $("#form-signin-notice").addClass("alert alert-warning");
                    $("#form-signin-notice").text(data.text);
                    break;

                default:
                    $("#form-signin-notice").addClass("alert alert-danger");
                    $("#form-signin-notice").text(data.text);
                    break;
            }

        }

    });
};

document.logout = function()
{
    $.removeCookie('identification');
    $("#form-signin-username").val("");
    $("#form-signin-password").val("");
    $("#form-signin-notice").hide();
    $("#signin-block").show();
    $("#signed-block").hide();
    document.loadSidebar();
};

document.receiveUserData = function ()
{
    $.ajax({
        url: "ReceiveUserData.exec",
        cache: false,
        success: function (data)
        {
        	if(data)
    		{
	            $("#signin-block").hide();
	            $("#signed-block").show();
    		}
        	else
    		{
        	    $("#signin-block").show();
        	    $("#signed-block").hide();
    		}

        }

    });
};
//Content Loader
document.loadContent = function (url)
{
    $.ajax({
        url: url,
        success: function (data)
        {
            $("#content").html(data);
          //  document.contentInit();
        }

    });
};

document.loadSidebar = function ()
{
    $.ajax({
        url: "Sidebar.exec",
        dataType: "json",
        cache:false,
        success: function (data)
        {

            $("#sidebar-content").empty();
            $(data).each(function ()
            {
                var li = $("

");
                li.addClass("sidebar-child");
                var a = $("");
                a.attr("href", "#");
                var i = $("");
                i.addClass("icon");
                i.addClass(this.iconName);
                var span = $("");
                span.text(this.title);
                li.append(a);
                a.append(i);
                a.append(span);
                li.attr("onclick", "document.loadContent('" + this.url + "');");

                $("#sidebar-content").append(li);
            });
            $(".sidebar-child")[0].click();
        }

    });
}<|endoftext|>