diff options
Diffstat (limited to 'server')
384 files changed, 3248 insertions, 52849 deletions
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb index daffab258e5..d45b8f29383 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb +++ b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb @@ -18,7 +18,7 @@ <div id="<%= container_id -%>"></div> <script> - (function () { + jQuery(function () { var query = '<%= filter.data -%>'; // do not show widget if the filter contains "my" criterion, @@ -28,17 +28,16 @@ return; } - require(['widgets/issue-filter/widget'], function (IssueFilter) { - window.requestMessages().done(function () { - new IssueFilter({ - el: '#<%= container_id -%>', - query: query, - distributionAxis: '<%= distribution_axis -%>', - displayMode: '<%= display_mode -%>' - }); + var IssueFilterWidget = require('issue-filter-widget'); + window.requestMessages().done(function () { + new IssueFilterWidget({ + el: '#<%= container_id -%>', + query: query, + distributionAxis: '<%= distribution_axis -%>', + displayMode: '<%= display_mode -%>' }); }); - })(); + }); </script> <% else %> diff --git a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb index 0815b95e88e..52ae8442334 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb +++ b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb @@ -24,7 +24,7 @@ <div id="<%= container_id -%>"></div> <script> - (function () { + jQuery(function () { var query = '<%= filter.data -%>'; // do not show widget if the filter contains "my" criterion, @@ -34,22 +34,21 @@ return; } - require(['widgets/issue-filter/widget'], function (IssueFilter) { - window.requestMessages().done(function () { - new IssueFilter({ - el: '#<%= container_id -%>', - query: query, - distributionAxis: '<%= distribution_axis -%>', - displayMode: '<%= display_mode -%>', - <% if period_date %> - periodDate: '<%= period_date -%>', - <% end %> - componentUuid: '<%= @project.uuid -%>', - componentKey: '<%= @project.key -%>' - }); + var IssueFilterWidget = require('issue-filter-widget'); + window.requestMessages().done(function () { + new IssueFilterWidget({ + el: '#<%= container_id -%>', + query: query, + distributionAxis: '<%= distribution_axis -%>', + displayMode: '<%= display_mode -%>', + <% if period_date %> + periodDate: '<%= period_date -%>', + <% end %> + componentUuid: '<%= @project.uuid -%>', + componentKey: '<%= @project.key -%>' }); }); - })(); + }); </script> <% else %> diff --git a/server/sonar-web/.eslintrc b/server/sonar-web/.eslintrc index a9b3b6d0eae..947309967bc 100644 --- a/server/sonar-web/.eslintrc +++ b/server/sonar-web/.eslintrc @@ -188,8 +188,6 @@ "globals": { "define": true, "require": true, - "Templates": true, - "Handlebars": true, "moment": true, "numeral": true, "key": true, diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee deleted file mode 100644 index 2c60d3da7f7..00000000000 --- a/server/sonar-web/Gruntfile.coffee +++ /dev/null @@ -1,383 +0,0 @@ -module.exports = (grunt) -> - require('jit-grunt')(grunt, { - unzip: 'grunt-zip' - replace: 'grunt-text-replace' - }); - require('time-grunt')(grunt); - - useBrowserStack = !!process.env['BROWSERSTACK_USERNAME'] && !!process.env['BROWSERSTACK_ACCESS_KEY'] - expressPort = '<%= grunt.option("port") || 3000 %>' - internPort = '<%= grunt.option("internPort") || 9100 %>' - - grunt.initConfig - pkg: grunt.file.readJSON('package.json') - - SOURCE_PATH: './src/main' - ASSETS_PATH: grunt.option("assetsDir") || './src/main/webapp' - BUILD_PATH: './build' - - less: - build: - options: - cleancss: true - files: - '<%= BUILD_PATH %>/css/sonar.css': [ - '<%= SOURCE_PATH %>/less/jquery-ui.less' - '<%= SOURCE_PATH %>/less/select2.less' - '<%= SOURCE_PATH %>/less/select2-sonar.less' - - '<%= SOURCE_PATH %>/less/init.less' - '<%= SOURCE_PATH %>/less/components.less' - '<%= SOURCE_PATH %>/less/pages.less' - - '<%= SOURCE_PATH %>/less/style.less' - - '<%= SOURCE_PATH %>/less/*.less' - ] - - - babel: - build: - options: - modules: 'amd' - files: [ - expand: true - cwd: '<%= SOURCE_PATH %>/js' - src: [ - '**/*.jsx' - '**/api/**/*.js' - '**/apps/**/*.js' - '**/components/**/*.js' - ] - dest: '<%= BUILD_PATH %>/js' - ext: '.js' - ] - - - concat: - build: - files: - '<%= BUILD_PATH %>/js/sonar.js': [ - '<%= BUILD_PATH %>/js/libs/translate.js' - '<%= BUILD_PATH %>/js/libs/third-party/jquery.js' - '<%= BUILD_PATH %>/js/libs/third-party/jquery-ui.js' - '<%= BUILD_PATH %>/js/libs/third-party/d3.js' - '<%= BUILD_PATH %>/js/libs/third-party/latinize.js' - '<%= BUILD_PATH %>/js/libs/third-party/underscore.js' - '<%= BUILD_PATH %>/js/libs/third-party/backbone.js' - '<%= BUILD_PATH %>/js/libs/third-party/backbone-super.js' - '<%= BUILD_PATH %>/js/libs/third-party/backbone.marionette.js' - '<%= BUILD_PATH %>/js/libs/third-party/handlebars.js' - '<%= BUILD_PATH %>/js/libs/third-party/select2.js' - '<%= BUILD_PATH %>/js/libs/third-party/keymaster.js' - '<%= BUILD_PATH %>/js/libs/third-party/moment.js' - '<%= BUILD_PATH %>/js/libs/third-party/numeral.js' - '<%= BUILD_PATH %>/js/libs/third-party/numeral-languages.js' - '<%= BUILD_PATH %>/js/libs/third-party/bootstrap/tooltip.js' - '<%= BUILD_PATH %>/js/libs/third-party/bootstrap/dropdown.js' - '<%= BUILD_PATH %>/js/libs/third-party/md5.js' - '<%= BUILD_PATH %>/js/libs/select2-jquery-ui-fix.js' - - '<%= BUILD_PATH %>/js/libs/widgets/base.js' - '<%= BUILD_PATH %>/js/libs/widgets/widget.js' - '<%= BUILD_PATH %>/js/libs/widgets/bubble-chart.js' - '<%= BUILD_PATH %>/js/libs/widgets/timeline.js' - '<%= BUILD_PATH %>/js/libs/widgets/stack-area.js' - '<%= BUILD_PATH %>/js/libs/widgets/pie-chart.js' - '<%= BUILD_PATH %>/js/libs/widgets/histogram.js' - '<%= BUILD_PATH %>/js/libs/widgets/word-cloud.js' - '<%= BUILD_PATH %>/js/libs/widgets/tag-cloud.js' - '<%= BUILD_PATH %>/js/libs/widgets/treemap.js' - - '<%= BUILD_PATH %>/js/libs/graphics/pie-chart.js' - '<%= BUILD_PATH %>/js/libs/graphics/barchart.js' - '<%= BUILD_PATH %>/js/libs/sortable.js' - - '<%= BUILD_PATH %>/js/libs/inputs.js' - '<%= BUILD_PATH %>/js/libs/dialogs.js' - '<%= BUILD_PATH %>/js/libs/processes.js' - '<%= BUILD_PATH %>/js/libs/jquery-isolated-scroll.js' - '<%= BUILD_PATH %>/js/libs/handlebars-extensions.js' - - '<%= BUILD_PATH %>/js/libs/application.js' - '<%= BUILD_PATH %>/js/libs/csv.js' - '<%= BUILD_PATH %>/js/libs/dashboard.js' - '<%= BUILD_PATH %>/js/libs/recent-history.js' - '<%= BUILD_PATH %>/js/libs/third-party/require.js' - ] - - - requirejs: - options: - baseUrl: '<%= BUILD_PATH %>/js/' - preserveLicenseComments: false - paths: - 'react': 'libs/third-party/react.min' - 'underscore': 'libs/third-party/shim/underscore-shim' - 'jquery': 'libs/third-party/shim/jquery-shim' - 'backbone': 'libs/third-party/shim/backbone-shim' - 'backbone.marionette': 'libs/third-party/shim/marionette-shim' - 'moment': 'libs/third-party/shim/moment-shim' - - issuesContext: options: - name: 'apps/issues/app-context' - out: '<%= ASSETS_PATH %>/js/apps/issues/app-context.js' - - selectList: options: - name: 'components/common/select-list' - out: '<%= ASSETS_PATH %>/js/components/common/select-list.js' - - app: options: - name: 'apps/<%= grunt.option("app") %>/app' - out: '<%= ASSETS_PATH %>/js/apps/<%= grunt.option("app") %>/app.js' - - widget: options: - name: 'widgets/<%= grunt.option("widget") %>/widget' - out: '<%= ASSETS_PATH %>/js/widgets/<%= grunt.option("widget") %>/widget.js' - - - concurrent: - build: - tasks: [ - 'uglify:build' - # apps - 'build-app:account' - 'build-app:api-documentation' - 'build-app:background-tasks' - 'build-app:coding-rules' - 'build-app:custom-measures' - 'build-app:drilldown' - 'build-app:global-permissions' - 'build-app:groups' - 'build-app:issues' - 'build-app:maintenance' - 'build-app:markdown' - 'build-app:measures' - 'build-app:metrics' - 'build-app:nav' - 'build-app:permission-templates' - 'build-app:projects' - 'build-app:project-permissions' - 'build-app:quality-gates' - 'build-app:quality-profiles' - 'build-app:source-viewer' - 'build-app:system' - 'build-app:users' - 'build-app:update-center' - # widgets - 'build-widget:issue-filter' - # other - 'requirejs:issuesContext' - 'requirejs:selectList' - ] - - - handlebars: - options: - namespace: 'Templates' - processName: (name) -> - pieces = name.split '/' - fileName = pieces[pieces.length - 1] - fileName.split('.')[0] - processPartialName: (name) -> - pieces = name.split '/' - fileName = pieces[pieces.length - 1] - fileName.split('.')[0] - build: - files: - '<%= BUILD_PATH %>/js/components/navigator/templates.js': [ - '<%= SOURCE_PATH %>/js/components/navigator/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/coding-rules/templates.js': [ - '<%= SOURCE_PATH %>/js/components/common/templates/**/*.hbs' - '<%= SOURCE_PATH %>/js/apps/coding-rules/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/quality-gates/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/quality-gates/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/quality-profiles/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/quality-profiles/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/components/source-viewer/templates.js': [ - '<%= SOURCE_PATH %>/js/components/source-viewer/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/components/issue/templates.js': [ - '<%= SOURCE_PATH %>/js/components/common/templates/**/*.hbs' - '<%= SOURCE_PATH %>/js/components/issue/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/issues/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/issues/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/api-documentation/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/api-documentation/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/nav/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/nav/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/widgets/issue-filter/templates.js': [ - '<%= SOURCE_PATH %>/js/widgets/issue-filter/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/components/workspace/templates.js': [ - '<%= SOURCE_PATH %>/js/components/workspace/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/markdown/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/markdown/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/users/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/users/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/groups/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/groups/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/metrics/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/metrics/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/maintenance/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/maintenance/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/account/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/account/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/update-center/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/update-center/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/custom-measures/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/custom-measures/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/global-permissions/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/global-permissions/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/project-permissions/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/project-permissions/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/permission-templates/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/permission-templates/templates/**/*.hbs' - ] - '<%= BUILD_PATH %>/js/apps/projects/templates.js': [ - '<%= SOURCE_PATH %>/js/apps/projects/templates/**/*.hbs' - ] - - - clean: - options: - force: true - css: ['<%= ASSETS_PATH %>/css'] - js: ['<%= ASSETS_PATH %>/js'] - build: ['<%= BUILD_PATH %>'] - - - copy: - js: - expand: true, cwd: '<%= SOURCE_PATH %>/js', src: ['**/*.js'], dest: '<%= BUILD_PATH %>/js' - 'assets-js': - src: '<%= BUILD_PATH %>/js/sonar.js', dest: '<%= ASSETS_PATH %>/js/sonar.js' - 'assets-all-js': - expand: true, cwd: '<%= BUILD_PATH %>/js', src: ['**/*.js'], dest: '<%= ASSETS_PATH %>/js' - 'assets-css': - src: '<%= BUILD_PATH %>/css/sonar.css', dest: '<%= ASSETS_PATH %>/css/sonar.css' - - - uglify: - build: - src: '<%= ASSETS_PATH %>/js/sonar.js' - dest: '<%= ASSETS_PATH %>/js/sonar.js' - - - replace: - lcov: - src: 'target/web-tests/lcov.info' - dest: 'target/web-tests/lcov.info' - replacements: [ - { from: '/build/', to: '/src/main/' } - ] - - - rename: - lcov: - src: 'lcov.info' - dest: 'target/web-tests/lcov.info' - - - intern: - test: - options: - runType: 'runner' - config: 'test/intern' - proxyPort: expressPort - proxyUrl: 'http://localhost:' + expressPort + '/' - useBrowserStack: useBrowserStack - - - watch: - options: - spawn: false - - less: - files: '<%= SOURCE_PATH %>/less/**/*.less' - tasks: ['less:build', 'copy:assets-css'] - - js: - files: ['<%= SOURCE_PATH %>/js/**/*.js', '<%= SOURCE_PATH %>/js/**/*.jsx'] - tasks: ['copy:js', 'babel:build', 'concat:build', 'copy:assets-all-js'] - - handlebars: - files: '<%= SOURCE_PATH %>/**/*.hbs' - tasks: ['handlebars:build', 'copy:assets-all-js'] - - - # Basic tasks - grunt.registerTask 'prepare', - ['clean:css', 'clean:js', 'clean:build', 'less:build', 'handlebars:build', 'copy:js', 'babel:build', 'concat:build'] - - grunt.registerTask 'build-fast-suffix', - ['copy:assets-css', 'copy:assets-all-js'] - - grunt.registerTask 'build-suffix', - ['copy:assets-css', 'copy:assets-js', 'concurrent:build'] - - grunt.registerTask 'test-suffix', - ['intern:test', 'rename:lcov', 'replace:lcov'] - - grunt.registerTask 'coverage-suffix', - ['test-suffix'] - - grunt.registerTask 'build-app', (app) -> - grunt.option 'app', app - grunt.task.run 'requirejs:app' - - grunt.registerTask 'build-widget', (widget) -> - grunt.option 'widget', widget - grunt.task.run 'requirejs:widget' - - # Output tasks - grunt.registerTask 'build-fast', - ['prepare', 'build-fast-suffix'] - - grunt.registerTask 'build', - ['prepare', 'build-suffix'] - - grunt.registerTask 'build-test', - ['prepare', 'build-suffix', 'test-suffix'] - - grunt.registerTask 'build-coverage', - ['prepare', 'build-suffix', 'coverage-suffix'] - - grunt.registerTask 'test', - ['prepare', 'test-suffix'] - - grunt.registerTask 'coverage', - ['prepare', 'coverage-suffix'] - - grunt.registerTask 'default', - ['build'] - - # Development - grunt.registerTask 'dw', - ['build-fast', 'watch'] - - # tasks used by Maven build (see pom.xml) - grunt.registerTask 'maven-quick-build', - ['build-fast'] - - grunt.registerTask 'maven-build', - ['build'] diff --git a/server/sonar-web/gulpfile.js b/server/sonar-web/gulpfile.js new file mode 100644 index 00000000000..eedaca51f1d --- /dev/null +++ b/server/sonar-web/gulpfile.js @@ -0,0 +1,189 @@ +var path = require('path'); + +var glob = require('glob'); +var del = require('del'); +var browserify = require('browserify'); +var watchify = require('watchify'); +var es = require('event-stream'); + +var gulp = require('gulp'); +var buffer = require('vinyl-buffer'); +var concat = require('gulp-concat'); +var gulpif = require('gulp-if'); +var less = require('gulp-less'); +var minifyCss = require('gulp-minify-css'); +var sourcemaps = require('gulp-sourcemaps'); +var uglify = require('gulp-uglify'); + +var source = require('vinyl-source-stream'); + +var argv = require('yargs').argv; +var production = !argv.dev && !argv.fast; +var dev = !!argv.dev && !argv.fast; +var watch = !!argv.watch; +var output = argv.output || './src/main/webapp'; + + +function getAppName (file) { + return file + .substr(0, file.length - 7) + .substr(17); +} + + +function doBrowserify (entry, sourceName, dest, customize) { + var bundler = browserify({ + entries: [entry], + debug: dev, + cache: {}, + packageCache: {} + }); + + // do all .require(), .external() + if (typeof customize === 'function') { + bundler = customize(bundler); + } + + if (watch) { + bundler = watchify(bundler); + } + + var rebundle = function (ids) { + if (ids) { + /* eslint no-console: 0 */ + console.log(ids); + } + return bundler.bundle() + .pipe(source(sourceName)) + .pipe(gulpif(production, buffer())) + .pipe(gulpif(production, uglify())) + .pipe(gulp.dest(path.join(output, dest))); + }; + + bundler.on('update', rebundle); + + return rebundle(); +} + + +gulp.task('scripts-sonar', function () { + return gulp.src([ + 'src/main/js/libs/translate.js', + 'src/main/js/libs/third-party/jquery.js', + 'src/main/js/libs/third-party/jquery-ui.js', + 'src/main/js/libs/third-party/d3.js', + 'src/main/js/libs/third-party/underscore.js', + 'src/main/js/libs/third-party/select2.js', + 'src/main/js/libs/third-party/keymaster.js', + 'src/main/js/libs/third-party/moment.js', + 'src/main/js/libs/third-party/numeral.js', + 'src/main/js/libs/third-party/numeral-languages.js', + 'src/main/js/libs/third-party/bootstrap/tooltip.js', + 'src/main/js/libs/third-party/bootstrap/dropdown.js', + 'src/main/js/libs/select2-jquery-ui-fix.js', + + 'src/main/js/libs/graphics/pie-chart.js', + 'src/main/js/libs/graphics/barchart.js', + 'src/main/js/libs/sortable.js', + + 'src/main/js/libs/inputs.js', + 'src/main/js/libs/jquery-isolated-scroll.js', + + 'src/main/js/libs/application.js' + ]) + .pipe(concat('sonar.js')) + .pipe(gulpif(production, buffer())) + .pipe(gulpif(production, uglify())) + .pipe(gulp.dest(path.join(output, 'js'))); +}); + + +gulp.task('scripts-main', function () { + return doBrowserify( + 'src/main/js/main/app.js', + 'main.js', + 'js/bundles', + function (bundle) { + return bundle + .require('react', { expose: 'react' }) + .require('backbone', { expose: 'backbone' }) + .require('backbone.marionette', { expose: 'backbone.marionette' }); + }); +}); + + +gulp.task('scripts-apps', function (done) { + glob('src/main/js/apps/*/app.js', function (err, files) { + if (err) { + done(err); + } + + var tasks = files.map(function (entry) { + return doBrowserify( + entry, + getAppName(entry) + '.js', + 'js/bundles', + function (bundle) { + return bundle + .external('react') + .external('backbone') + .external('backbone.marionette'); + } + ); + }); + es.merge(tasks).on('end', done); + }); +}); + +gulp.task('scripts-widgets', function () { + return doBrowserify( + 'src/main/js/widgets/widgets.js', + 'widgets.js', + 'js/bundles', + function (bundle) { + return bundle + .external('react') + .external('backbone') + .external('backbone.marionette') + .require('./src/main/js/widgets/issue-filter/widget.js', { expose: 'issue-filter-widget' }); + }); +}); + +gulp.task('styles', function () { + return gulp.src([ + 'src/main/less/jquery-ui.less', + 'src/main/less/select2.less', + 'src/main/less/select2-sonar.less', + + 'src/main/less/init.less', + 'src/main/less/components.less', + 'src/main/less/pages.less', + + 'src/main/less/style.less', + + 'src/main/less/*.less' + ]) + .pipe(gulpif(dev, sourcemaps.init())) + .pipe(less()) + .pipe(gulpif(production, minifyCss())) + .pipe(concat('sonar.css')) + .pipe(gulpif(dev, sourcemaps.write({ includeContent: true }))) + .pipe(gulp.dest(path.join(output, 'css'))); +}); + +gulp.task('clean', function (done) { + del([ + path.join(output, 'js'), + path.join(output, 'css') + ], done); +}); + +gulp.task('scripts', ['scripts-sonar', 'scripts-main', 'scripts-apps', 'scripts-widgets']); + +gulp.task('build', ['clean', 'scripts', 'styles'], function () { + if (watch) { + gulp.watch('src/main/less/**/*.less', ['styles']); + } +}); + +gulp.task('default', ['build']);
\ No newline at end of file diff --git a/server/sonar-web/package.json b/server/sonar-web/package.json index b555da9cf2c..798e66cfdf4 100644 --- a/server/sonar-web/package.json +++ b/server/sonar-web/package.json @@ -5,40 +5,59 @@ "repository": "SonarSource/sonarqube", "license": "LGPL-3.0", "devDependencies": { - "babel": "^5.8.23", - "backbone": "^1.1.2", - "chai": "^3.3.0", - "grunt": "0.4.5", - "grunt-babel": "5.0.1", - "grunt-cli": "0.1.13", - "grunt-concurrent": "1.0.0", - "grunt-contrib-clean": "0.6.0", - "grunt-contrib-concat": "0.5.1", - "grunt-contrib-copy": "0.8.0", - "grunt-contrib-handlebars": "0.9.2", - "grunt-contrib-less": "1.0.1", - "grunt-contrib-requirejs": "0.4.4", - "grunt-contrib-uglify": "0.9.1", - "grunt-contrib-watch": "0.6.1", - "grunt-rename": "^0.1.4", - "grunt-text-replace": "0.4.0", + "babel": "5.8.23", + "babelify": "6.3.0", + "backbone": "1.2.3", + "backbone.marionette": "2.4.3", + "blueimp-md5": "1.1.1", + "browserify": "11.2.0", + "browserify-shim": "3.8.10", + "chai": "3.3.0", + "del": "2.0.2", + "event-stream": "3.3.1", + "glob": "5.0.15", + "gulp": "3.9.0", + "gulp-browserify": "0.5.1", + "gulp-concat": "2.6.0", + "gulp-if": "2.0.0", + "gulp-less": "3.0.3", + "gulp-minify-css": "1.2.1", + "gulp-rename": "1.2.2", + "gulp-sourcemaps": "1.6.0", + "gulp-uglify": "1.4.2", + "handlebars": "2.0.0", + "hbsfy": "2.3.1", "intern": "3.0.0", - "isparta": "^3.0.4", - "jit-grunt": "0.9.1", + "isparta": "3.0.4", "jquery": "2.1.4", - "jsdom": "^6.5.1", - "mocha": "^2.3.3", - "moment": "^2.10.6", + "jsdom": "6.5.1", + "mocha": "2.3.3", + "moment": "2.10.6", "react": "0.13.3", - "sinon": "^1.15.4", - "sinon-chai": "^2.8.0", - "time-grunt": "1.2.1", - "underscore": "1.8.3" + "sinon": "1.15.4", + "sinon-chai": "2.8.0", + "underscore": "1.8.3", + "vinyl-buffer": "1.0.0", + "vinyl-source-stream": "1.1.0", + "watchify": "3.4.0", + "whatwg-fetch": "0.10.0", + "yargs": "3.27.0" }, "scripts": { - "build-fast": "./node_modules/.bin/grunt build-fast", - "build": "./node_modules/.bin/grunt build", + "build-fast": "gulp --fast", + "build": "gulp", "test": "./node_modules/.bin/mocha --opts tests/mocha.opts tests", "coverage": "./node_modules/.bin/babel-node ./node_modules/.bin/isparta cover --dir './target/coverage' --include '**/*.js' --include '**/*.jsx' ./node_modules/.bin/_mocha -- --opts tests/mocha.opts tests" + }, + "browserify-shim": { + "jquery": "global:jQuery", + "underscore": "global:_" + }, + "browserify": { + "transform": [ + "hbsfy", + "babelify", + "browserify-shim" + ] } } diff --git a/server/sonar-web/pom.xml b/server/sonar-web/pom.xml index 1ede3eb9e1b..0c271091a7f 100644 --- a/server/sonar-web/pom.xml +++ b/server/sonar-web/pom.xml @@ -15,7 +15,7 @@ <!-- self-analysis --> <sonar.sources>src/main/js,src/main/less</sonar.sources> <sonar.exclusions>src/main/js/libs/third-party/**/*,src/main/js/libs/require.js</sonar.exclusions> - <grunt.arguments>maven-build --no-color</grunt.arguments> + <npm.script>build</npm.script> </properties> <dependencies> @@ -117,12 +117,12 @@ </execution> <execution> <phase>generate-resources</phase> - <id>grunt build</id> + <id>npm script</id> <goals> - <goal>grunt</goal> + <goal>npm</goal> </goals> <configuration> - <arguments>${grunt.arguments}</arguments> + <arguments>run-script ${npm.script}</arguments> </configuration> </execution> </executions> @@ -222,7 +222,7 @@ <profile> <id>dev</id> <properties> - <grunt.arguments>maven-quick-build</grunt.arguments> + <npm.script>build-fast</npm.script> </properties> </profile> </profiles> diff --git a/server/sonar-web/src/main/js/api/ce.js b/server/sonar-web/src/main/js/api/ce.js index 4fcf075acea..edabd6e9ea7 100644 --- a/server/sonar-web/src/main/js/api/ce.js +++ b/server/sonar-web/src/main/js/api/ce.js @@ -27,5 +27,6 @@ export function cancelAllTasks () { export function getTasksForComponent(componentId) { let url = baseUrl + '/api/ce/component'; - return $.get(url, { componentId }); + let data = { componentId }; + return new Promise((resolve) => $.get(url, data).done(resolve)); } diff --git a/server/sonar-web/src/main/js/api/nav.js b/server/sonar-web/src/main/js/api/nav.js index 86cc425795a..61e7e75ce3f 100644 --- a/server/sonar-web/src/main/js/api/nav.js +++ b/server/sonar-web/src/main/js/api/nav.js @@ -1,6 +1,17 @@ -import $ from 'jquery'; +import { getJSON } from '../helpers/request.js'; export function getGlobalNavigation () { let url = baseUrl + '/api/navigation/global'; - return $.get(url); + return getJSON(url); +} + +export function getComponentNavigation (componentKey) { + let url = baseUrl + '/api/navigation/component'; + let data = { componentKey }; + return getJSON(url, data); +} + +export function getSettingsNavigation () { + let url = baseUrl + '/api/navigation/settings'; + return getJSON(url); } diff --git a/server/sonar-web/src/main/js/api/permissions.jsx b/server/sonar-web/src/main/js/api/permissions.js index 29f4c4147d9..29f4c4147d9 100644 --- a/server/sonar-web/src/main/js/api/permissions.jsx +++ b/server/sonar-web/src/main/js/api/permissions.js diff --git a/server/sonar-web/src/main/js/apps/account/app.js b/server/sonar-web/src/main/js/apps/account/app.js index 0f441abacca..f552632c5f8 100644 --- a/server/sonar-web/src/main/js/apps/account/app.js +++ b/server/sonar-web/src/main/js/apps/account/app.js @@ -1,5 +1,6 @@ import $ from 'jquery'; import ChangePasswordView from './change-password-view'; +import '../../helpers/handlebars-helpers'; var shouldShowAvatars = window.SS && window.SS.lf && window.SS.lf.enableGravatar; var favorites = $('.js-account-favorites tr'); @@ -8,8 +9,8 @@ function showExtraFavorites () { favorites.removeClass('hidden'); } -export default { - start: function () { +class App { + start () { $('html').addClass('dashboard-page'); if (shouldShowAvatars) { @@ -28,4 +29,6 @@ export default { new ChangePasswordView().render(); }); } -}; +} + +window.sonarqube.appStarted.then(options => new App().start(options)); diff --git a/server/sonar-web/src/main/js/apps/account/change-password-view.js b/server/sonar-web/src/main/js/apps/account/change-password-view.js index e8f825f57b4..6bd5d992b21 100644 --- a/server/sonar-web/src/main/js/apps/account/change-password-view.js +++ b/server/sonar-web/src/main/js/apps/account/change-password-view.js @@ -1,9 +1,9 @@ import $ from 'jquery'; import ModalForm from '../../components/common/modal-form'; -import './templates'; +import Template from './templates/account-change-password.hbs'; export default ModalForm.extend({ - template: Templates['account-change-password'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/action-view.js b/server/sonar-web/src/main/js/apps/api-documentation/action-view.js index 5ccac8c097b..9ba96da7f41 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/action-view.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/action-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/api-documentation-action.hbs'; export default Marionette.ItemView.extend({ className: 'panel panel-vertical', - template: Templates['api-documentation-action'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/api-documentation/app.js b/server/sonar-web/src/main/js/apps/api-documentation/app.js index 5451cde9da7..f345685e8da 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/app.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/app.js @@ -8,9 +8,12 @@ import List from './list'; import ListView from './list-view'; import FiltersView from './filters-view'; import SearchView from './search-view'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + // State this.state = new Backbone.Model({ internal: false }); this.state.match = function (test) { @@ -61,9 +64,7 @@ var App = new Marionette.Application(), }; App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); + init.call(App, options); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js b/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js index aa54b532f2b..9ed8d763266 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/api-documentation-filters.hbs'; export default Marionette.ItemView.extend({ - template: Templates['api-documentation-filters'], + template: Template, events: { 'change .js-toggle-internal': 'toggleInternal' diff --git a/server/sonar-web/src/main/js/apps/api-documentation/header-view.js b/server/sonar-web/src/main/js/apps/api-documentation/header-view.js index 818ccfdde47..4b270ebbeec 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/header-view.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/header-view.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/api-documentation-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['api-documentation-header'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/api-documentation/item-view.js b/server/sonar-web/src/main/js/apps/api-documentation/item-view.js index b23ffff12ff..6a8c1143b17 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/item-view.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/item-view.js @@ -1,11 +1,11 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/api-documentation-web-service.hbs'; export default Marionette.ItemView.extend({ tagName: 'a', className: 'list-group-item', - template: Templates['api-documentation-web-service'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/api-documentation/layout.js b/server/sonar-web/src/main/js/apps/api-documentation/layout.js index 229b48ec560..88f40994d2c 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/layout.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/layout.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/api-documentation-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['api-documentation-layout'], + template: Template, regions: { headerRegion: '.search-navigator-workspace-header', diff --git a/server/sonar-web/src/main/js/apps/api-documentation/search-view.js b/server/sonar-web/src/main/js/apps/api-documentation/search-view.js index 1635d8a2abf..737e909ca4a 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/search-view.js +++ b/server/sonar-web/src/main/js/apps/api-documentation/search-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/api-documentation-search.hbs'; export default Marionette.ItemView.extend({ - template: Templates['api-documentation-search'], + template: Template, ui: { input: '.search-box-input' diff --git a/server/sonar-web/src/main/js/apps/background-tasks/app.js b/server/sonar-web/src/main/js/apps/background-tasks/app.js index d69c1b58091..268ca65e336 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/app.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/app.js @@ -1,11 +1,7 @@ import React from 'react'; import Main from './main'; -export default { - start (options) { - window.requestMessages().done(() => { - let el = document.querySelector(options.el); - React.render(<Main options={options}/>, el); - }); - } -}; +window.sonarqube.appStarted.then(options => { + let el = document.querySelector(options.el); + React.render(<Main options={options}/>, el); +}); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/main.js b/server/sonar-web/src/main/js/apps/background-tasks/main.js index 9545e8a76f3..cd981f76044 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/main.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/main.js @@ -29,8 +29,8 @@ export default React.createClass({ }, getComponentFilter() { - if (this.props.options.componentId) { - return { componentId: this.props.options.componentId }; + if (this.props.options.component) { + return { componentId: this.props.options.component.id }; } else { return {}; } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/app.js b/server/sonar-web/src/main/js/apps/coding-rules/app.js index e1e53516f05..61089511594 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/app.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/app.js @@ -5,16 +5,20 @@ import Marionette from 'backbone.marionette'; import State from './models/state'; import Layout from './layout'; import Rules from './models/rules'; -import Facets from 'components/navigator/models/facets'; +import Facets from '../../components/navigator/models/facets'; import Controller from './controller'; -import Router from 'components/navigator/router'; +import Router from '../../components/navigator/router'; import WorkspaceListView from './workspace-list-view'; import WorkspaceHeaderView from './workspace-header-view'; import FacetsView from './facets-view'; import FiltersView from './filters-view'; +import './partials'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + this.layout = new Layout({ el: options.el }); this.layout.render(); $('#footer').addClass('search-navigator-footer'); @@ -92,9 +96,9 @@ var appXHR = $.get(baseUrl + '/api/rules/app').done(function (r) { }); App.on('start', function (options) { - $.when(window.requestMessages(), appXHR).done(function () { + appXHR.done(function () { init.call(App, options); }); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js index 76e193d8f33..f8dcd2570a4 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalFormView from 'components/common/modal-form'; -import './templates'; +import ModalFormView from '../../components/common/modal-form'; +import Template from './templates/coding-rules-bulk-change-modal.hbs'; export default ModalFormView.extend({ - template: Templates['coding-rules-bulk-change-modal'], + template: Template, ui: function () { return _.extend(ModalFormView.prototype.ui.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js index 6d6268f3ef6..881b84434de 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import PopupView from 'components/common/popup'; +import PopupView from '../../components/common/popup'; import BulkChangeModalView from './bulk-change-modal-view'; -import './templates'; +import Template from './templates/coding-rules-bulk-change-popup.hbs'; export default PopupView.extend({ - template: Templates['coding-rules-bulk-change-popup'], + template: Template, events: { 'click .js-bulk-change': 'doAction' diff --git a/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js b/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js new file mode 100644 index 00000000000..624f3e8b997 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js @@ -0,0 +1,43 @@ +import $ from 'jquery'; +import _ from 'underscore'; + +const DEFAULTS = { + title: 'Confirmation', + html: '', + yesLabel: 'Yes', + noLabel: 'Cancel', + yesHandler: function () { + // no op + }, + noHandler: function () { + // no op + }, + always: function () { + // no op + } +}; + +export default function (options) { + var settings = _.extend({}, DEFAULTS, options), + dialog = $('<div><div class="modal-head"><h2>' + settings.title + '</h2></div><div class="modal-body">' + + settings.html + '</div><div class="modal-foot"><button data-confirm="yes">' + settings.yesLabel + + '</button> <a data-confirm="no" class="action">' + settings.noLabel + '</a></div></div>'); + + $('[data-confirm=yes]', dialog).on('click', function () { + dialog.dialog('close'); + settings.yesHandler(); + return settings.always(); + }); + + $('[data-confirm=no]', dialog).on('click', function () { + dialog.dialog('close'); + settings.noHandler(); + return settings.always(); + }); + + return dialog.dialog({ + modal: true, + minHeight: null, + width: 540 + }); +} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/controller.js b/server/sonar-web/src/main/js/apps/coding-rules/controller.js index 2049cb8bf0c..e399ddb9acc 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/controller.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/controller.js @@ -1,6 +1,6 @@ import $ from 'jquery'; import _ from 'underscore'; -import Controller from 'components/navigator/controller'; +import Controller from '../../components/navigator/controller'; import Rule from './models/rule'; import RuleDetailsView from './rule-details-view'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js b/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js index c3da8bbe54b..22246af5046 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js @@ -1,4 +1,4 @@ -import FacetsView from 'components/navigator/facets-view'; +import FacetsView from '../../components/navigator/facets-view'; import BaseFacet from './facets/base-facet'; import QueryFacet from './facets/query-facet'; import KeyFacet from './facets/key-facet'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js index 0f0de13b0de..35ae3641ba5 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-severity-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-severity-facet'], + template: Template, severities: ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'], initialize: function (options) { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js index 3f2f6a2839f..253c636bd8f 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-available-since-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-available-since-facet'], + template: Template, events: function () { return _.extend(BaseFacet.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/base-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/base-facet.js index f02260069cb..ebdca1169e0 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/base-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/base-facet.js @@ -1,9 +1,9 @@ -import BaseFacet from 'components/navigator/facets/base-facet'; -import '../templates'; +import BaseFacet from '../../../components/navigator/facets/base-facet'; +import Template from '../templates/facets/coding-rules-base-facet.hbs'; export default BaseFacet.extend({ className: 'search-navigator-facet-box', - template: Templates['coding-rules-base-facet'] + template: Template }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/characteristic-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/characteristic-facet.js index 5463b4e13bc..9ab26b33caf 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/characteristic-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/characteristic-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-characteristic-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-characteristic-facet'], + template: Template, onRender: function () { BaseFacet.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js index c2499876610..ba35fe660ed 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-custom-values-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-custom-values-facet'], + template: Template, events: function () { return _.extend(BaseFacet.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js index e3dc2c2cafc..ecf8ba9dde9 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-inheritance-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-inheritance-facet'], + template: Template, initialize: function (options) { this.listenTo(options.app.state, 'change:query', this.onQueryChange); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js index 4117345bd4b..b2854b5028a 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js @@ -1,9 +1,9 @@ import BaseFacet from './base-facet'; import _ from 'underscore'; -import '../templates'; +import Template from '../templates/facets/coding-rules-key-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-key-facet'], + template: Template, onRender: function () { this.$el.toggleClass('hidden', !this.options.app.state.get('query').rule_key); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js index 5686d6b2cea..c04d56f93ee 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-quality-profile-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-quality-profile-facet'], + template: Template, events: function () { return _.extend(BaseFacet.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js index fe380885438..0b1216ca4bd 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-query-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-query-facet'], + template: Template, events: function () { return _.extend(BaseFacet.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js index 6ab2c4f8a4d..9c019f36b95 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-severity-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-severity-facet'], + template: Template, severities: ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'], sortValues: function (values) { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js index bf819b33b5f..13c5cd7b405 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js @@ -1,9 +1,9 @@ import $ from 'jquery'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/coding-rules-template-facet.hbs'; export default BaseFacet.extend({ - template: Templates['coding-rules-template-facet'], + template: Template, onRender: function () { BaseFacet.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/filters-view.js b/server/sonar-web/src/main/js/apps/coding-rules/filters-view.js index 37644b06ee9..ff902dec733 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/filters-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/filters-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import ManualRuleCreationView from './rule/manual-rule-creation-view'; -import './templates'; +import Template from './templates/coding-rules-filters.hbs'; export default Marionette.ItemView.extend({ - template: Templates['coding-rules-filters'], + template: Template, events: { 'click .js-create-manual-rule': 'createManualRule' diff --git a/server/sonar-web/src/main/js/apps/coding-rules/layout.js b/server/sonar-web/src/main/js/apps/coding-rules/layout.js index ee83c4d684d..ef24f8ce321 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/layout.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/layout.js @@ -1,9 +1,9 @@ import $ from 'jquery'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/coding-rules-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['coding-rules-layout'], + template: Template, regions: { filtersRegion: '.search-navigator-filters', diff --git a/server/sonar-web/src/main/js/apps/coding-rules/models/state.js b/server/sonar-web/src/main/js/apps/coding-rules/models/state.js index da1dcad586c..952bff0d252 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/models/state.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/models/state.js @@ -1,4 +1,4 @@ -import State from 'components/navigator/models/state'; +import State from '../../../components/navigator/models/state'; export default State.extend({ defaults: { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/partials.js b/server/sonar-web/src/main/js/apps/coding-rules/partials.js new file mode 100644 index 00000000000..9eb9de128e6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/coding-rules/partials.js @@ -0,0 +1,8 @@ +import Handlebars from 'hbsfy/runtime'; +import ActivationPartial from './templates/_coding-rules-workspace-list-item-activation.hbs'; +import FacetHeaderPartial from './templates/facets/_coding-rules-facet-header.hbs'; +import MarkdownTipsPartial from '../../components/common/templates/_markdown-tips.hbs'; + +Handlebars.registerPartial('_coding-rules-workspace-list-item-activation', ActivationPartial); +Handlebars.registerPartial('_coding-rules-facet-header', FacetHeaderPartial); +Handlebars.registerPartial('_markdown-tips', MarkdownTipsPartial); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js index c33ea38e401..f8dee5b02cd 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js @@ -11,11 +11,12 @@ import CustomRulesView from './rule/custom-rules-view'; import ManualRuleCreationView from './rule/manual-rule-creation-view'; import CustomRuleCreationView from './rule/custom-rule-creation-view'; import IssuesView from './rule/rule-issues-view'; -import './templates'; +import Template from './templates/coding-rules-rule-details.hbs'; +import confirmDialog from './confirm-dialog'; export default Marionette.LayoutView.extend({ className: 'coding-rule-details', - template: Templates['coding-rules-rule-details'], + template: Template, regions: { metaRegion: '.js-rule-meta', @@ -128,7 +129,7 @@ export default Marionette.LayoutView.extend({ deleteRule: function () { var that = this, ruleType = this.model.has('templateKey') ? 'custom' : 'manual'; - window.confirmDialog({ + confirmDialog({ title: t('delete'), html: tp('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')), yesHandler: function () { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js index bb9acd5ccef..b2dc3619cf9 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ActionOptionsView from 'components/common/action-options-view'; -import './templates'; +import ActionOptionsView from '../../components/common/action-options-view'; +import Template from './templates/coding-rules-rule-filter-form.hbs'; export default ActionOptionsView.extend({ - template: Templates['coding-rules-rule-filter-form'], + template: Template, selectOption: function (e) { var property = $(e.currentTarget).data('property'), diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js index dbaf9af0d64..d3e9d49ba6b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js @@ -1,10 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalFormView from 'components/common/modal-form'; -import '../templates'; +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/rule/coding-rules-custom-rule-creation.hbs'; +import {csvEscape} from '../../../helpers/csv'; +import latinize from '../../../helpers/latinize'; export default ModalFormView.extend({ - template: Templates['coding-rules-custom-rule-creation'], + template: Template, ui: function () { return _.extend(ModalFormView.prototype.ui.apply(this, arguments), { @@ -38,7 +40,7 @@ export default ModalFormView.extend({ generateKey: function () { if (!this.keyModifiedByUser && this.ui.customRuleCreationKey) { - var generatedKey = this.ui.customRuleCreationName.val().latinize().replace(/[^A-Za-z0-9]/g, '_'); + var generatedKey = latinize(this.ui.customRuleCreationName.val()).replace(/[^A-Za-z0-9]/g, '_'); this.ui.customRuleCreationKey.val(generatedKey); } }, @@ -107,7 +109,7 @@ export default ModalFormView.extend({ }; }).get(); options.params = params.map(function (param) { - return param.key + '=' + window.csvEscape(param.value); + return param.key + '=' + csvEscape(param.value); }).join(';'); this.sendRequest(action, options); }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js index a47aef607b8..43f577429a9 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js @@ -1,11 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/rule/coding-rules-custom-rule.hbs'; +import confirmDialog from '../confirm-dialog'; export default Marionette.ItemView.extend({ tagName: 'tr', - template: Templates['coding-rules-custom-rule'], + template: Template, modelEvents: { 'change': 'render' @@ -17,7 +18,7 @@ export default Marionette.ItemView.extend({ deleteRule: function () { var that = this; - window.confirmDialog({ + confirmDialog({ title: t('delete'), html: t('are_you_sure'), yesHandler: function () { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js index 7486abbb573..c550708d0aa 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js @@ -2,10 +2,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import CustomRuleView from './custom-rule-view'; import CustomRuleCreationView from './custom-rule-creation-view'; -import '../templates'; +import Template from '../templates/rule/coding-rules-custom-rules.hbs'; export default Marionette.CompositeView.extend({ - template: Templates['coding-rules-custom-rules'], + template: Template, childView: CustomRuleView, childViewContainer: '#coding-rules-detail-custom-rules', diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js index f0890a06e08..d5c5dd07fbf 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js @@ -1,10 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalFormView from 'components/common/modal-form'; -import '../templates'; +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/rule/coding-rules-manual-rule-creation.hbs'; +import latinize from '../../../helpers/latinize'; export default ModalFormView.extend({ - template: Templates['coding-rules-manual-rule-creation'], + template: Template, ui: function () { return _.extend(ModalFormView.prototype.ui.apply(this.arguments), { @@ -44,7 +45,7 @@ export default ModalFormView.extend({ generateKey: function () { if (!this.keyModifiedByUser && this.ui.manualRuleCreationKey) { - var generatedKey = this.ui.manualRuleCreationName.val().latinize().replace(/[^A-Za-z0-9]/g, '_'); + var generatedKey = latinize(this.ui.manualRuleCreationName.val()).replace(/[^A-Za-z0-9]/g, '_'); this.ui.manualRuleCreationKey.val(generatedKey); } }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js index 8ea8ce0496d..e20be1987e7 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js @@ -1,11 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; -import ModalForm from 'components/common/modal-form'; -import '../templates'; +import ModalForm from '../../../components/common/modal-form'; +import Template from '../templates/rule/coding-rules-profile-activation.hbs'; +import {csvEscape} from '../../../helpers/csv'; export default ModalForm.extend({ - template: Templates['coding-rules-profile-activation'], + template: Template, ui: function () { return _.extend(this._super(), { @@ -62,7 +63,7 @@ export default ModalForm.extend({ }; }).get(), paramsHash = (params.map(function (param) { - return param.key + '=' + window.csvEscape(param.value); + return param.key + '=' + csvEscape(param.value); })).join(';'); if (this.model) { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js index e49e2bb2a75..f169121e376 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js @@ -1,10 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/rule/coding-rules-rule-description.hbs'; +import confirmDialog from '../confirm-dialog'; export default Marionette.ItemView.extend({ - template: Templates['coding-rules-rule-description'], + template: Template, modelEvents: { 'change': 'render' @@ -62,7 +63,7 @@ export default Marionette.ItemView.extend({ removeExtendedDescription: function () { var that = this; - window.confirmDialog({ + confirmDialog({ html: t('coding_rules.remove_extended_description.confirm'), yesHandler: function () { that.ui.extendDescriptionText.val(''); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js index 0bd9da9bdac..fa4e771efd3 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/rule/coding-rules-rule-issues.hbs'; export default Marionette.ItemView.extend({ - template: Templates['coding-rules-rule-issues'], + template: Template, initialize: function () { var that = this; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js index f2b947343dd..73540c26b77 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js @@ -2,10 +2,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; import RuleFilterMixin from './rule-filter-mixin'; -import '../templates'; +import Template from '../templates/rule/coding-rules-rule-meta.hbs'; export default Marionette.ItemView.extend(RuleFilterMixin).extend({ - template: Templates['coding-rules-rule-meta'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js index fc34437c23c..54f85d7eaa1 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/rule/coding-rules-rule-parameters.hbs'; export default Marionette.ItemView.extend({ - template: Templates['coding-rules-rule-parameters'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js index 40e09aed4a4..1c74fc9dd63 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js @@ -3,11 +3,12 @@ import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import ProfileActivationView from './profile-activation-view'; -import '../templates'; +import Template from '../templates/rule/coding-rules-rule-profile.hbs'; +import confirmDialog from '../confirm-dialog'; export default Marionette.ItemView.extend({ tagName: 'tr', - template: Templates['coding-rules-rule-profile'], + template: Template, modelEvents: { 'change': 'render' @@ -48,7 +49,7 @@ export default Marionette.ItemView.extend({ revert: function () { var that = this, ruleKey = this.options.rule.get('key'); - window.confirmDialog({ + confirmDialog({ title: t('coding_rules.revert_to_parent_definition'), html: tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name), yesHandler: function () { @@ -70,7 +71,7 @@ export default Marionette.ItemView.extend({ deactivate: function () { var that = this, ruleKey = this.options.rule.get('key'); - window.confirmDialog({ + confirmDialog({ title: t('coding_rules.deactivate'), html: tp('coding_rules.deactivate.confirm'), yesHandler: function () { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js index f449d944473..5f9f497acba 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js @@ -2,10 +2,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import ProfileView from './rule-profile-view'; import ProfileActivationView from './profile-activation-view'; -import '../templates'; +import Template from '../templates/rule/coding-rules-rule-profiles.hbs'; export default Marionette.CompositeView.extend({ - template: Templates['coding-rules-rule-profiles'], + template: Template, childView: ProfileView, childViewContainer: '#coding-rules-detail-quality-profiles', diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js index 74b1a14dc50..01028a952f6 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import WorkspaceHeaderView from 'components/navigator/workspace-header-view'; +import WorkspaceHeaderView from '../../components/navigator/workspace-header-view'; import BulkChangePopup from './bulk-change-popup-view'; -import './templates'; +import Template from './templates/coding-rules-workspace-header.hbs'; export default WorkspaceHeaderView.extend({ - template: Templates['coding-rules-workspace-header'], + template: Template, events: function () { return _.extend(WorkspaceHeaderView.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js index 4fda1255c8c..e4e70351b97 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js @@ -1,14 +1,15 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; -import WorkspaceListItemView from 'components/navigator/workspace-list-item-view'; +import WorkspaceListItemView from '../../components/navigator/workspace-list-item-view'; import ProfileActivationView from './rule/profile-activation-view'; import RuleFilterMixin from './rule/rule-filter-mixin'; -import './templates'; +import Template from './templates/coding-rules-workspace-list-item.hbs'; +import confirmDialog from './confirm-dialog'; export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ className: 'coding-rule', - template: Templates['coding-rules-workspace-list-item'], + template: Template, modelEvents: { 'change': 'render' @@ -60,7 +61,7 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ var that = this, ruleKey = this.model.get('key'), activation = this.model.get('activation'); - window.confirmDialog({ + confirmDialog({ title: t('coding_rules.deactivate'), html: tp('coding_rules.deactivate.confirm'), yesHandler: function () { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js index 252d5a093ce..1d7036b593e 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js @@ -1,10 +1,10 @@ -import WorkspaceListView from 'components/navigator/workspace-list-view'; +import WorkspaceListView from '../../components/navigator/workspace-list-view'; import WorkspaceListItemView from './workspace-list-item-view'; import WorkspaceListEmptyView from './workspace-list-empty-view'; -import './templates'; +import Template from './templates/coding-rules-workspace-list.hbs'; export default WorkspaceListView.extend({ - template: Templates['coding-rules-workspace-list'], + template: Template, childView: WorkspaceListItemView, childViewContainer: '.js-list', emptyView: WorkspaceListEmptyView, diff --git a/server/sonar-web/src/main/js/apps/issues/app-context.js b/server/sonar-web/src/main/js/apps/component-issues/app.js index 8d28597d056..8cf2fddb3eb 100644 --- a/server/sonar-web/src/main/js/apps/issues/app-context.js +++ b/server/sonar-web/src/main/js/apps/component-issues/app.js @@ -2,20 +2,24 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; -import State from './models/state'; -import Layout from './layout'; -import Issues from './models/issues'; -import Facets from 'components/navigator/models/facets'; -import Filters from './models/filters'; -import Controller from './controller'; -import Router from './router'; -import WorkspaceListView from './workspace-list-view'; -import WorkspaceHeaderView from './workspace-header-view'; -import FacetsView from './facets-view'; -import './helpers/format-facet-value'; +import State from '../issues/models/state'; +import Layout from '../issues/layout'; +import Issues from '../issues/models/issues'; +import Facets from '../../components/navigator/models/facets'; +import Filters from '../issues/models/filters'; +import Controller from '../issues/controller'; +import Router from '../issues/router'; +import WorkspaceListView from '../issues/workspace-list-view'; +import WorkspaceHeaderView from '../issues/workspace-header-view'; +import FacetsView from './../issues/facets-view'; +import './../issues/helpers/format-facet-value'; +import '../issues/partials'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + this.config = options.config; this.state = new State({ isContext: true, @@ -87,11 +91,7 @@ App.updateContextFacets = function () { }; App.on('start', function (options) { - $.when(window.requestMessages()).done(function () { - init.call(App, options); - }); + init.call(App, options); }); -export default App; - - +window.sonarqube.appStarted.then(options => App.start(options));
\ No newline at end of file diff --git a/server/sonar-web/src/main/js/apps/custom-measures/app.js b/server/sonar-web/src/main/js/apps/custom-measures/app.js index 5d6c1c2b16c..81d58f58d84 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/app.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/app.js @@ -4,6 +4,7 @@ import CustomMeasures from './custom-measures'; import HeaderView from './header-view'; import ListView from './list-view'; import ListFooterView from './list-footer-view'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), init = function (options) { @@ -15,13 +16,13 @@ var App = new Marionette.Application(), // Collection this.customMeasures = new CustomMeasures({ - projectId: options.projectId + projectId: options.component.id }); // Header View this.headerView = new HeaderView({ collection: this.customMeasures, - projectId: options.projectId + projectId: options.component.id }); this.layout.headerRegion.show(this.headerView); @@ -42,10 +43,8 @@ var App = new Marionette.Application(), }; App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); + init.call(App, options); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js b/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js index 6798c1259a3..74fbd979adc 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/custom-measures-delete.hbs'; export default ModalForm.extend({ - template: Templates['custom-measures-delete'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/custom-measures/form-view.js b/server/sonar-web/src/main/js/apps/custom-measures/form-view.js index d86e0176b30..f7af5500cd0 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/form-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/form-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; -import ModalForm from 'components/common/modal-form'; -import Metrics from 'apps/metrics/metrics'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Metrics from '../metrics/metrics'; +import Template from './templates/custom-measures-form.hbs'; export default ModalForm.extend({ - template: Templates['custom-measures-form'], + template: Template, initialize: function () { this.metrics = new Metrics(); diff --git a/server/sonar-web/src/main/js/apps/custom-measures/header-view.js b/server/sonar-web/src/main/js/apps/custom-measures/header-view.js index 02ee2a795c3..adf99c5e384 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/header-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/header-view.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import CreateView from './create-view'; -import './templates'; +import Template from './templates/custom-measures-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['custom-measures-header'], + template: Template, events: { 'click #custom-measures-create': 'onCreateClick' diff --git a/server/sonar-web/src/main/js/apps/custom-measures/layout.js b/server/sonar-web/src/main/js/apps/custom-measures/layout.js index 92ac6de28b1..a2c22f9477e 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/layout.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/layout.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/custom-measures-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['custom-measures-layout'], + template: Template, regions: { headerRegion: '#custom-measures-header', diff --git a/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js b/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js index e917ddb294a..24906a35318 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/custom-measures-list-footer.hbs'; export default Marionette.ItemView.extend({ - template: Templates['custom-measures-list-footer'], + template: Template, collectionEvents: { 'all': 'render' diff --git a/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js b/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js index 7b7cb5aa6e1..7ae08cfe87b 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js @@ -1,11 +1,11 @@ import Marionette from 'backbone.marionette'; import UpdateView from './update-view'; import DeleteView from './delete-view'; -import './templates'; +import Template from './templates/custom-measures-list-item.hbs'; export default Marionette.ItemView.extend({ tagName: 'tr', - template: Templates['custom-measures-list-item'], + template: Template, events: { 'click .js-custom-measure-update': 'onUpdateClick', diff --git a/server/sonar-web/src/main/js/apps/custom-measures/list-view.js b/server/sonar-web/src/main/js/apps/custom-measures/list-view.js index 2d38eae4d1d..7b45f899947 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/list-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/list-view.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import ListItemView from './list-item-view'; -import './templates'; +import Template from './templates/custom-measures-list.hbs'; export default Marionette.CompositeView.extend({ - template: Templates['custom-measures-list'], + template: Template, childView: ListItemView, childViewContainer: 'tbody' }); diff --git a/server/sonar-web/src/main/js/apps/dashboard/app.js b/server/sonar-web/src/main/js/apps/dashboard/app.js new file mode 100644 index 00000000000..aa5e99b4486 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/dashboard/app.js @@ -0,0 +1,152 @@ +import $ from 'jquery'; + +window.Portal = function (options) { + this.initialize(options); +}; + +window.Portal.prototype = { + + initialize: function (options) { + this.options = options; + if (!this.options.editorEnabled) { + return; + } + this.createAllSortables(); + this.lastSaveString = ''; + this.saveDashboardsState(); + }, + + + createAllSortables: function () { + var that = this, + blocks = $('.' + this.options.block), + columnHandle = $('.' + this.options.columnHandle), + draggable, + + onDragLeave = function (e) { + $(e.currentTarget).removeClass(that.options.hoverClass); + }, + + onDrop = function (e) { + e.preventDefault(); + draggable.detach().insertBefore($(e.currentTarget)); + onDragLeave(e); + that.saveDashboardsState(); + }; + + blocks + .prop('draggable', true) + .on('selectstart', function () { + this.dragDrop(); + return false; + }) + .on('dragstart', function (e) { + e.originalEvent.dataTransfer.setData('Text', 'drag'); + draggable = $(this); + columnHandle.show(); + }) + .on('dragover', function (e) { + if (draggable.prop('id') !== $(this).prop('id')) { + e.preventDefault(); + $(e.currentTarget).addClass(that.options.hoverClass); + } + }) + .on('drop', onDrop) + .on('dragleave', onDragLeave); + + columnHandle + .on('dragover', function (e) { + e.preventDefault(); + $(e.currentTarget).addClass(that.options.hoverClass); + }) + .on('drop', onDrop) + .on('dragleave', onDragLeave); + }, + + + highlightWidget: function (widgetId) { + var block = $('#block_' + widgetId), + options = this.options; + block.css('background-color', options.highlightStartColor); + setTimeout(function () { + block.css('background-color', options.highlightEndColor); + }, this.options.highlightDuration); + }, + + + saveDashboardsState: function () { + var options = this.options, + result = $('.' + this.options.column).map(function () { + var blocks = $(this).find('.' + options.block); + $(this).find('.' + options.columnHandle).toggle(blocks.length === 0); + + return blocks.map(function () { + return $(this).prop('id').substring(options.block.length + 1); + }).get().join(','); + }).get().join(';'); + + if (result === this.lastSaveString) { + return; + } + + var firstTime = this.lastSaveString === ''; + this.lastSaveString = result; + + if (firstTime) { + return; + } + + if (this.options.saveUrl) { + var postBody = this.options.dashboardState + '=' + encodeURIComponent(result); + + $.ajax({ + url: this.options.saveUrl, + type: 'POST', + data: postBody + }); + } + }, + + + editWidget: function (widgetId) { + $('#widget_title_' + widgetId).hide(); + $('#widget_' + widgetId).hide(); + $('#widget_props_' + widgetId).show(); + $($('#block_' + widgetId + ' a.link-action')[0]).hide(); + }, + + + cancelEditWidget: function (widgetId) { + $('widget_title_' + widgetId).show(); + $('#widget_' + widgetId).show(); + $('#widget_props_' + widgetId).hide(); + $($('#block_' + widgetId + ' a.link-action')[0]).show(); + }, + + + deleteWidget: function (element) { + $(element).closest('.' + this.options.block).remove(); + this.saveDashboardsState(); + } +}; + + +window.autoResize = function (everyMs, callback) { + var debounce = _.debounce(callback, everyMs); + $(window).on('resize', debounce); +}; + + +$(function () { + var $sidebar = jQuery('#sidebar'); + if ($sidebar.length > 0) { + var $window = jQuery(window), + topOffset = $sidebar.offset().top; + $window.on('scroll', function () { + var scrollTop = $window.scrollTop(), + scrollLeft = $window.scrollLeft(); + $sidebar.toggleClass('sticky', scrollTop > topOffset); + $sidebar.css('left', -scrollLeft + 10); + }); + } +}); diff --git a/server/sonar-web/src/main/js/apps/drilldown/app.js b/server/sonar-web/src/main/js/apps/drilldown/app.js index f860933924f..c0dfdde6e73 100644 --- a/server/sonar-web/src/main/js/apps/drilldown/app.js +++ b/server/sonar-web/src/main/js/apps/drilldown/app.js @@ -1,9 +1,11 @@ import $ from 'jquery'; import Marionette from 'backbone.marionette'; import SourceViewer from '../../components/source-viewer/main'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; App.addRegions({ viewerRegion: options.el }); $('.js-drilldown-link').on('click', function (e) { e.preventDefault(); @@ -22,9 +24,7 @@ var App = new Marionette.Application(), }; App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); + init.call(App, options); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/global-permissions/app.js b/server/sonar-web/src/main/js/apps/global-permissions/app.js new file mode 100644 index 00000000000..f010e11b6e0 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/global-permissions/app.js @@ -0,0 +1,8 @@ +import React from 'react'; +import Main from './main'; +import '../../helpers/handlebars-helpers'; + +window.sonarqube.appStarted.then(options => { + var el = document.querySelector(options.el); + React.render(<Main/>, el); +}); diff --git a/server/sonar-web/src/main/js/apps/global-permissions/app.jsx b/server/sonar-web/src/main/js/apps/global-permissions/app.jsx deleted file mode 100644 index f35eeceda98..00000000000 --- a/server/sonar-web/src/main/js/apps/global-permissions/app.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import Main from './main'; - -export default { - start(options) { - window.requestMessages().done(() => { - var el = document.querySelector(options.el); - React.render(<Main/>, el); - }); - } -}; diff --git a/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js b/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js index f6369ea191a..9e8393dbd1f 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js +++ b/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js @@ -1,6 +1,6 @@ -import Modal from 'components/common/modals'; -import 'components/common/select-list'; -import './templates'; +import Modal from '../../components/common/modals'; +import Template from './templates/global-permissions-groups.hbs'; +import '../../components/common/select-list'; function getSearchUrl (permission, project) { var url = baseUrl + '/api/permissions/groups?ps=100&permission=' + permission; @@ -19,7 +19,7 @@ function getExtra (permission, project) { } export default Modal.extend({ - template: Templates['global-permissions-groups'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/global-permissions/main.jsx b/server/sonar-web/src/main/js/apps/global-permissions/main.js index 11f6b032ebf..11f6b032ebf 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/main.jsx +++ b/server/sonar-web/src/main/js/apps/global-permissions/main.js diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.js index 7a38d84c0a6..7a38d84c0a6 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx +++ b/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.js diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.js index 91da5b747bb..91da5b747bb 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.jsx +++ b/server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.js diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission-users.js index aaed2ab0014..aaed2ab0014 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx +++ b/server/sonar-web/src/main/js/apps/global-permissions/permission-users.js diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission.js index 1a5f993a90e..1a5f993a90e 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/permission.jsx +++ b/server/sonar-web/src/main/js/apps/global-permissions/permission.js diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.js index e019fbcbfec..e019fbcbfec 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx +++ b/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.js diff --git a/server/sonar-web/src/main/js/apps/global-permissions/users-view.js b/server/sonar-web/src/main/js/apps/global-permissions/users-view.js index 61ad9371166..cb01982c291 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/users-view.js +++ b/server/sonar-web/src/main/js/apps/global-permissions/users-view.js @@ -1,6 +1,6 @@ -import Modal from 'components/common/modals'; -import 'components/common/select-list'; -import './templates'; +import Modal from '../../components/common/modals'; +import Template from './templates/global-permissions-users.hbs'; +import '../../components/common/select-list'; function getSearchUrl (permission, project) { var url = baseUrl + '/api/permissions/users?ps=100&permission=' + permission; @@ -19,7 +19,7 @@ function getExtra (permission, project) { } export default Modal.extend({ - template: Templates['global-permissions-users'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/groups/app.js b/server/sonar-web/src/main/js/apps/groups/app.js index 8965f3ecea7..6f9bfd0c44f 100644 --- a/server/sonar-web/src/main/js/apps/groups/app.js +++ b/server/sonar-web/src/main/js/apps/groups/app.js @@ -5,9 +5,12 @@ import HeaderView from './header-view'; import SearchView from './search-view'; import ListView from './list-view'; import ListFooterView from './list-footer-view'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + // Layout this.layout = new Layout({ el: options.el }); this.layout.render(); @@ -35,12 +38,10 @@ var App = new Marionette.Application(), this.groups.fetch(); }; -App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); +App.on('start', function () { + init.call(App); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/groups/delete-view.js b/server/sonar-web/src/main/js/apps/groups/delete-view.js index 272a0a85bbc..6192a4dd153 100644 --- a/server/sonar-web/src/main/js/apps/groups/delete-view.js +++ b/server/sonar-web/src/main/js/apps/groups/delete-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/groups-delete.hbs'; export default ModalForm.extend({ - template: Templates['groups-delete'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/groups/form-view.js b/server/sonar-web/src/main/js/apps/groups/form-view.js index 5b541f1ae12..abd64842d3c 100644 --- a/server/sonar-web/src/main/js/apps/groups/form-view.js +++ b/server/sonar-web/src/main/js/apps/groups/form-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/groups-form.hbs'; export default ModalForm.extend({ - template: Templates['groups-form'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/groups/header-view.js b/server/sonar-web/src/main/js/apps/groups/header-view.js index bd7226176b2..e4a118f2822 100644 --- a/server/sonar-web/src/main/js/apps/groups/header-view.js +++ b/server/sonar-web/src/main/js/apps/groups/header-view.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import CreateView from './create-view'; -import './templates'; +import Template from './templates/groups-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['groups-header'], + template: Template, events: { 'click #groups-create': 'onCreateClick' diff --git a/server/sonar-web/src/main/js/apps/groups/layout.js b/server/sonar-web/src/main/js/apps/groups/layout.js index ba1f58e81fc..52e9e96901d 100644 --- a/server/sonar-web/src/main/js/apps/groups/layout.js +++ b/server/sonar-web/src/main/js/apps/groups/layout.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/groups-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['groups-layout'], + template: Template, regions: { headerRegion: '#groups-header', diff --git a/server/sonar-web/src/main/js/apps/groups/list-footer-view.js b/server/sonar-web/src/main/js/apps/groups/list-footer-view.js index 53dc3e7acaa..74953a7a601 100644 --- a/server/sonar-web/src/main/js/apps/groups/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/groups/list-footer-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/groups-list-footer.hbs'; export default Marionette.ItemView.extend({ - template: Templates['groups-list-footer'], + template: Template, collectionEvents: { 'all': 'render' diff --git a/server/sonar-web/src/main/js/apps/groups/list-item-view.js b/server/sonar-web/src/main/js/apps/groups/list-item-view.js index 43278c2ac6e..968218d1c4c 100644 --- a/server/sonar-web/src/main/js/apps/groups/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/groups/list-item-view.js @@ -3,12 +3,12 @@ import Marionette from 'backbone.marionette'; import UpdateView from './update-view'; import DeleteView from './delete-view'; import UsersView from './users-view'; -import './templates'; +import Template from './templates/groups-list-item.hbs'; export default Marionette.ItemView.extend({ tagName: 'li', className: 'panel panel-vertical', - template: Templates['groups-list-item'], + template: Template, events: { 'click .js-group-update': 'onUpdateClick', diff --git a/server/sonar-web/src/main/js/apps/groups/list-view.js b/server/sonar-web/src/main/js/apps/groups/list-view.js index 695bf2ac034..699e9c76a85 100644 --- a/server/sonar-web/src/main/js/apps/groups/list-view.js +++ b/server/sonar-web/src/main/js/apps/groups/list-view.js @@ -1,6 +1,5 @@ import Marionette from 'backbone.marionette'; import ListItemView from './list-item-view'; -import './templates'; export default Marionette.CollectionView.extend({ tagName: 'ul', diff --git a/server/sonar-web/src/main/js/apps/groups/search-view.js b/server/sonar-web/src/main/js/apps/groups/search-view.js index db3d4d8bb18..442c5533904 100644 --- a/server/sonar-web/src/main/js/apps/groups/search-view.js +++ b/server/sonar-web/src/main/js/apps/groups/search-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/groups-search.hbs'; export default Marionette.ItemView.extend({ - template: Templates['groups-search'], + template: Template, events: { 'submit #groups-search-form': 'onFormSubmit', diff --git a/server/sonar-web/src/main/js/apps/groups/users-view.js b/server/sonar-web/src/main/js/apps/groups/users-view.js index fa8e632ef07..4c6643a8cc8 100644 --- a/server/sonar-web/src/main/js/apps/groups/users-view.js +++ b/server/sonar-web/src/main/js/apps/groups/users-view.js @@ -1,9 +1,9 @@ -import Modal from 'components/common/modals'; -import 'components/common/select-list'; -import './templates'; +import Modal from '../../components/common/modals'; +import '../../components/common/select-list'; +import Template from './templates/groups-users.hbs'; export default Modal.extend({ - template: Templates['groups-users'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/issues/app.js b/server/sonar-web/src/main/js/apps/issues/app.js index fe9188b27f8..6ab3502f2b8 100644 --- a/server/sonar-web/src/main/js/apps/issues/app.js +++ b/server/sonar-web/src/main/js/apps/issues/app.js @@ -4,7 +4,7 @@ import Marionette from 'backbone.marionette'; import State from './models/state'; import Layout from './layout'; import Issues from './models/issues'; -import Facets from 'components/navigator/models/facets'; +import Facets from '../../components/navigator/models/facets'; import Filters from './models/filters'; import Controller from './controller'; import Router from './router'; @@ -13,9 +13,13 @@ import WorkspaceHeaderView from './workspace-header-view'; import FacetsView from './facets-view'; import FiltersView from './filters-view'; import './helpers/format-facet-value'; +import './partials'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + this.state = new State(); this.list = new Issues(); this.facets = new Facets(); @@ -59,12 +63,10 @@ var App = new Marionette.Application(), }); }; -App.on('start', function (options) { - $.when(window.requestMessages()).done(function () { - init.call(App, options); - }); +App.on('start', function () { + init.call(App); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js b/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js index 2397bf06cb0..3877b2707fe 100644 --- a/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js +++ b/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js @@ -1,8 +1,7 @@ import $ from 'jquery'; import _ from 'underscore'; -import SourceViewer from 'components/source-viewer/main'; +import SourceViewer from '../../../components/source-viewer/main'; import IssueView from './issue-view'; -import '../templates'; export default SourceViewer.extend({ events: function () { diff --git a/server/sonar-web/src/main/js/apps/issues/controller.js b/server/sonar-web/src/main/js/apps/issues/controller.js index 54e74f39980..db002a48944 100644 --- a/server/sonar-web/src/main/js/apps/issues/controller.js +++ b/server/sonar-web/src/main/js/apps/issues/controller.js @@ -1,7 +1,7 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; -import Controller from 'components/navigator/controller'; +import Controller from '../../components/navigator/controller'; import ComponentViewer from './component-viewer/main'; import HomeView from './workspace-home-view'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets-view.js b/server/sonar-web/src/main/js/apps/issues/facets-view.js index 82fd76fe714..3d99d8c7082 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets-view.js +++ b/server/sonar-web/src/main/js/apps/issues/facets-view.js @@ -1,4 +1,4 @@ -import FacetsView from 'components/navigator/facets-view'; +import FacetsView from '../../components/navigator/facets-view'; import BaseFacet from './facets/base-facet'; import SeverityFacet from './facets/severity-facet'; import StatusFacet from './facets/status-facet'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/action-plan-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/action-plan-facet.js index fa415f981ff..46c8139467b 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/action-plan-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/action-plan-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-action-plan-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-action-plan-facet'], + template: Template, onRender: function () { BaseFacet.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js index edebc4adf52..672ca67726a 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import CustomValuesFacet from './custom-values-facet'; -import '../templates'; +import Template from '../templates/facets/issues-assignee-facet.hbs'; export default CustomValuesFacet.extend({ - template: Templates['issues-assignee-facet'], + template: Template, getUrl: function () { return baseUrl + '/api/users/search'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js index d781c602fbd..59ac379e704 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; -import BaseFacet from 'components/navigator/facets/base-facet'; -import '../templates'; +import BaseFacet from '../../../components/navigator/facets/base-facet'; +import Template from '../templates/facets/issues-base-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-base-facet'], + template: Template, onRender: function () { BaseFacet.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js index 4f49aebc6ea..a043235164d 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-context-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-context-facet'], + template: Template, serializeData: function () { return _.extend(BaseFacet.prototype.serializeData.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js index 34edcbf706d..49bb2cd7cde 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-creation-date-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-creation-date-facet'], + template: Template, events: function () { return _.extend(BaseFacet.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js index 04faae8470b..bf86b4970fb 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-custom-values-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-custom-values-facet'], + template: Template, events: function () { return _.extend(BaseFacet.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js index 0c904feeec5..af18cbcbb18 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-file-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-file-facet'], + template: Template, onRender: function () { BaseFacet.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js index b7e8cfd136a..f10e6dab2b9 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-issue-key-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-issue-key-facet'], + template: Template, onRender: function () { return this.$el.toggleClass('hidden', !this.options.app.state.get('query').issues); diff --git a/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js index d826c379940..bbe12185686 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-mode-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-mode-facet'], + template: Template, events: { 'change [name="issues-page-mode"]': 'onModeChange' diff --git a/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js index a15cf51aed7..62dee4d48de 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-resolution-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-resolution-facet'], + template: Template, onRender: function () { BaseFacet.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js index e1dc9abe396..45ec1c16a53 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-severity-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-severity-facet'], + template: Template, sortValues: function (values) { var order = ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR']; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js index 9293d393cf7..c87a36aa209 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; -import '../templates'; +import Template from '../templates/facets/issues-status-facet.hbs'; export default BaseFacet.extend({ - template: Templates['issues-status-facet'], + template: Template, sortValues: function (values) { var order = ['OPEN', 'RESOLVED', 'REOPENED', 'CLOSED', 'CONFIRMED']; diff --git a/server/sonar-web/src/main/js/apps/issues/filters-view.js b/server/sonar-web/src/main/js/apps/issues/filters-view.js index 18a46bfd096..50fdae86217 100644 --- a/server/sonar-web/src/main/js/apps/issues/filters-view.js +++ b/server/sonar-web/src/main/js/apps/issues/filters-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/issues-filters.hbs'; export default Marionette.ItemView.extend({ - template: Templates['issues-filters'], + template: Template, events: { 'click .js-toggle-filters': 'toggleFilters', diff --git a/server/sonar-web/src/main/js/apps/issues/helpers/format-facet-value.js b/server/sonar-web/src/main/js/apps/issues/helpers/format-facet-value.js index 5cef0500ded..94ddec317a4 100644 --- a/server/sonar-web/src/main/js/apps/issues/helpers/format-facet-value.js +++ b/server/sonar-web/src/main/js/apps/issues/helpers/format-facet-value.js @@ -1,3 +1,5 @@ +import Handlebars from 'hbsfy/runtime'; + Handlebars.registerHelper('formatFacetValue', function (value, facetMode) { var formatter = facetMode === 'debt' ? 'SHORT_WORK_DUR' : 'SHORT_INT'; return window.formatMeasure(value, formatter); diff --git a/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js b/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js index 980a0eceded..fa39dce2f5e 100644 --- a/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js +++ b/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ActionOptionsView from 'components/common/action-options-view'; -import './templates'; +import ActionOptionsView from '../../components/common/action-options-view'; +import Template from './templates/issues-issue-filter-form.hbs'; export default ActionOptionsView.extend({ - template: Templates['issues-issue-filter-form'], + template: Template, selectOption: function (e) { var property = $(e.currentTarget).data('property'), diff --git a/server/sonar-web/src/main/js/apps/issues/layout.js b/server/sonar-web/src/main/js/apps/issues/layout.js index 7b6c7b8366e..cfed80f3356 100644 --- a/server/sonar-web/src/main/js/apps/issues/layout.js +++ b/server/sonar-web/src/main/js/apps/issues/layout.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/issues-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['issues-layout'], + template: Template, regions: { filtersRegion: '.search-navigator-filters', diff --git a/server/sonar-web/src/main/js/apps/issues/models/issue.js b/server/sonar-web/src/main/js/apps/issues/models/issue.js index f466243ad63..52779091ed7 100644 --- a/server/sonar-web/src/main/js/apps/issues/models/issue.js +++ b/server/sonar-web/src/main/js/apps/issues/models/issue.js @@ -1,4 +1,4 @@ -import Issue from 'components/issue/models/issue'; +import Issue from '../../../components/issue/models/issue'; export default Issue.extend({ reset: function (attrs, options) { diff --git a/server/sonar-web/src/main/js/apps/issues/models/state.js b/server/sonar-web/src/main/js/apps/issues/models/state.js index f49d2566dfc..533c41f7842 100644 --- a/server/sonar-web/src/main/js/apps/issues/models/state.js +++ b/server/sonar-web/src/main/js/apps/issues/models/state.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import State from 'components/navigator/models/state'; +import State from '../../../components/navigator/models/state'; export default State.extend({ defaults: { diff --git a/server/sonar-web/src/main/js/apps/issues/partials.js b/server/sonar-web/src/main/js/apps/issues/partials.js new file mode 100644 index 00000000000..ba4cab9716f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/issues/partials.js @@ -0,0 +1,8 @@ +import Handlebars from 'hbsfy/runtime'; +import FilterNamePartial from './templates/_issues-filter-name.hbs'; +import FacetHeaderPartial from './templates/facets/_issues-facet-header.hbs'; +import MarkdownTipsPartial from '../../components/common/templates/_markdown-tips.hbs'; + +Handlebars.registerPartial('_issues-filter-name', FilterNamePartial); +Handlebars.registerPartial('_issues-facet-header', FacetHeaderPartial); +Handlebars.registerPartial('_markdown-tips', MarkdownTipsPartial); diff --git a/server/sonar-web/src/main/js/apps/issues/router.js b/server/sonar-web/src/main/js/apps/issues/router.js index 6cb6622da6e..f3b560c14c5 100644 --- a/server/sonar-web/src/main/js/apps/issues/router.js +++ b/server/sonar-web/src/main/js/apps/issues/router.js @@ -1,4 +1,4 @@ -import Router from 'components/navigator/router'; +import Router from '../../components/navigator/router'; export default Router.extend({ routes: { diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js index dba0e384c5a..867fcfcaccd 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import WorkspaceHeaderView from 'components/navigator/workspace-header-view'; -import './templates'; +import WorkspaceHeaderView from '../../components/navigator/workspace-header-view'; +import Template from './templates/issues-workspace-header.hbs'; export default WorkspaceHeaderView.extend({ - template: Templates['issues-workspace-header'], + template: Template, events: function () { return _.extend(WorkspaceHeaderView.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-home-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-home-view.js index 44efc574890..31607238594 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-home-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-home-view.js @@ -1,12 +1,13 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Handlebars from 'hbsfy/runtime'; +import Template from './templates/issues-workspace-home.hbs'; Handlebars.registerHelper('issueFilterHomeLink', function (id) { return baseUrl + '/issues/search#id=' + id; }); export default Marionette.ItemView.extend({ - template: Templates['issues-workspace-home'] + template: Template }); diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js index 585beb1afce..568fc546723 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js @@ -1,8 +1,9 @@ import $ from 'jquery'; import _ from 'underscore'; -import IssueView from 'components/issue/issue-view'; +import IssueView from '../../components/issue/issue-view'; import IssueFilterView from './issue-filter-view'; -import './templates'; +import CheckboxTemplate from './templates/issues-issue-checkbox.hbs'; +import FilterTemplate from './templates/issues-issue-filter.hbs'; var SHOULD_NULL = { any: ['issues'], @@ -15,8 +16,8 @@ var SHOULD_NULL = { }; export default IssueView.extend({ - checkboxTemplate: Templates['issues-issue-checkbox'], - filterTemplate: Templates['issues-issue-filter'], + checkboxTemplate: CheckboxTemplate, + filterTemplate: FilterTemplate, events: function () { return _.extend(IssueView.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js index 3fcccd1546f..45efbf8dc0d 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js @@ -1,15 +1,16 @@ import $ from 'jquery'; -import WorkspaceListView from 'components/navigator/workspace-list-view'; +import WorkspaceListView from '../../components/navigator/workspace-list-view'; import IssueView from './workspace-list-item-view'; import EmptyView from './workspace-list-empty-view'; -import './templates'; +import Template from './templates/issues-workspace-list.hbs'; +import ComponentTemplate from './templates/issues-workspace-list-component.hbs'; var COMPONENT_HEIGHT = 29, BOTTOM_OFFSET = 60; export default WorkspaceListView.extend({ - template: Templates['issues-workspace-list'], - componentTemplate: Templates['issues-workspace-list-component'], + template: Template, + componentTemplate: ComponentTemplate, childView: IssueView, childViewContainer: '.js-list', emptyView: EmptyView, diff --git a/server/sonar-web/src/main/js/apps/maintenance/app.js b/server/sonar-web/src/main/js/apps/maintenance/app.js index b089a9cb574..dd2a626399d 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/app.js +++ b/server/sonar-web/src/main/js/apps/maintenance/app.js @@ -2,10 +2,14 @@ import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import MainView from './main-view'; +import './partials'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(); -App.on('start', function (options) { +App.on('start', function () { + let options = window.sonarqube; + var viewOptions = _.extend(options, { model: new Backbone.Model() }); @@ -13,6 +17,6 @@ App.on('start', function (options) { mainView.render().refresh(); }); -export default App; +App.start(); diff --git a/server/sonar-web/src/main/js/apps/maintenance/main-view.js b/server/sonar-web/src/main/js/apps/maintenance/main-view.js index 3e9825adfa0..ece2ee8c1c2 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/main-view.js +++ b/server/sonar-web/src/main/js/apps/maintenance/main-view.js @@ -2,10 +2,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/maintenance-main.hbs'; export default Marionette.ItemView.extend({ - template: Templates['maintenance-main'], + template: Template, events: { 'click #start-migration': 'startMigration' diff --git a/server/sonar-web/src/main/js/apps/maintenance/partials.js b/server/sonar-web/src/main/js/apps/maintenance/partials.js new file mode 100644 index 00000000000..9fdc6d07f22 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/maintenance/partials.js @@ -0,0 +1,23 @@ +import Handlebars from 'hbsfy/runtime'; + +import StateMigrationFailedPartial from './templates/_maintenance-state-migration-failed.hbs'; +import StateMigrationNotSupportedPartial from './templates/_maintenance-state-migration-not-supported.hbs'; +import StateMigrationRequiredPartial from './templates/_maintenance-state-migration-required.hbs'; +import StateMigrationRunningPartial from './templates/_maintenance-state-migration-running.hbs'; +import StateMigrationSucceededPartial from './templates/_maintenance-state-migration-succeeded.hbs'; +import StateNoMigrationPartial from './templates/_maintenance-state-no-migration.hbs'; + +import StatusDownPartial from './templates/_maintenance-status-down.hbs'; +import StatusMigrationPartial from './templates/_maintenance-status-migration.hbs'; +import StatusUpPartial from './templates/_maintenance-status-up.hbs'; + +Handlebars.registerPartial('_maintenance-state-migration-failed', StateMigrationFailedPartial); +Handlebars.registerPartial('_maintenance-state-migration-not-supported', StateMigrationNotSupportedPartial); +Handlebars.registerPartial('_maintenance-state-migration-required', StateMigrationRequiredPartial); +Handlebars.registerPartial('_maintenance-state-migration-running', StateMigrationRunningPartial); +Handlebars.registerPartial('_maintenance-state-migration-succeeded', StateMigrationSucceededPartial); +Handlebars.registerPartial('_maintenance-state-no-migration', StateNoMigrationPartial); + +Handlebars.registerPartial('_maintenance-status-down', StatusDownPartial); +Handlebars.registerPartial('_maintenance-status-migration', StatusMigrationPartial); +Handlebars.registerPartial('_maintenance-status-up', StatusUpPartial); diff --git a/server/sonar-web/src/main/js/apps/markdown/app.js b/server/sonar-web/src/main/js/apps/markdown/app.js index 86ed29e5207..b2a79a646c5 100644 --- a/server/sonar-web/src/main/js/apps/markdown/app.js +++ b/server/sonar-web/src/main/js/apps/markdown/app.js @@ -3,10 +3,11 @@ import MarkdownView from './markdown-help-view'; var App = new Marionette.Application(); -App.on('start', function (options) { +App.on('start', function () { + let options = window.sonarqube; new MarkdownView({ el: options.el }).render(); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/markdown/markdown-help-view.js b/server/sonar-web/src/main/js/apps/markdown/markdown-help-view.js index c7db13a5b09..65a603c5653 100644 --- a/server/sonar-web/src/main/js/apps/markdown/markdown-help-view.js +++ b/server/sonar-web/src/main/js/apps/markdown/markdown-help-view.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/markdown-help.hbs'; export default Marionette.ItemView.extend({ - template: Templates['markdown-help'] + template: Template }); diff --git a/server/sonar-web/src/main/js/apps/measures/app.js b/server/sonar-web/src/main/js/apps/measures/app.js index a3b533d0958..7a1826cd669 100644 --- a/server/sonar-web/src/main/js/apps/measures/app.js +++ b/server/sonar-web/src/main/js/apps/measures/app.js @@ -1,14 +1,15 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import FilterBar from './measures-filter-bar'; -import BaseFilters from 'components/navigator/filters/base-filters'; -import CheckboxFilterView from 'components/navigator/filters/checkbox-filters'; -import ChoiceFilters from 'components/navigator/filters/choice-filters'; -import AjaxSelectFilters from 'components/navigator/filters/ajax-select-filters'; -import FavoriteFilters from 'components/navigator/filters/favorite-filters'; -import RangeFilters from 'components/navigator/filters/range-filters'; -import StringFilterView from 'components/navigator/filters/string-filters'; -import MetricFilterView from 'components/navigator/filters/metric-filters'; +import BaseFilters from '../../components/navigator/filters/base-filters'; +import CheckboxFilterView from '../../components/navigator/filters/checkbox-filters'; +import ChoiceFilters from '../../components/navigator/filters/choice-filters'; +import AjaxSelectFilters from '../../components/navigator/filters/ajax-select-filters'; +import FavoriteFilters from '../../components/navigator/filters/favorite-filters'; +import RangeFilters from '../../components/navigator/filters/range-filters'; +import StringFilterView from '../../components/navigator/filters/string-filters'; +import MetricFilterView from '../../components/navigator/filters/metric-filters'; +import '../../helpers/handlebars-helpers'; var NavigatorApp = new Marionette.Application(), init = function () { @@ -161,4 +162,4 @@ NavigatorApp.on('start', function () { init.call(NavigatorApp); }); -export default NavigatorApp; +window.sonarqube.appStarted.then(options => NavigatorApp.start(options)); diff --git a/server/sonar-web/src/main/js/apps/measures/measures-filter-bar.js b/server/sonar-web/src/main/js/apps/measures/measures-filter-bar.js index acd0c0dea3a..9e61faf2b2c 100644 --- a/server/sonar-web/src/main/js/apps/measures/measures-filter-bar.js +++ b/server/sonar-web/src/main/js/apps/measures/measures-filter-bar.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import FilterBarView from 'components/navigator/filters/filter-bar'; +import FilterBarView from '../../components/navigator/filters/filter-bar'; export default FilterBarView.extend({ template: function () { diff --git a/server/sonar-web/src/main/js/apps/metrics/app.js b/server/sonar-web/src/main/js/apps/metrics/app.js index 42eecceff9a..15a2aacb1a5 100644 --- a/server/sonar-web/src/main/js/apps/metrics/app.js +++ b/server/sonar-web/src/main/js/apps/metrics/app.js @@ -5,9 +5,12 @@ import Metrics from './metrics'; import HeaderView from './header-view'; import ListView from './list-view'; import ListFooterView from './list-footer-view'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + // Layout this.layout = new Layout({ el: options.el }); this.layout.render(); @@ -52,12 +55,12 @@ App.requestTypes = function () { }); }; -App.on('start', function (options) { - $.when(window.requestMessages(), App.requestDomains(), App.requestTypes()).done(function () { - init.call(App, options); +App.on('start', function () { + $.when(App.requestDomains(), App.requestTypes()).done(function () { + init.call(App); }); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/metrics/delete-view.js b/server/sonar-web/src/main/js/apps/metrics/delete-view.js index cef043b54b8..0210d0c2e35 100644 --- a/server/sonar-web/src/main/js/apps/metrics/delete-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/delete-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/metrics-delete.hbs'; export default ModalForm.extend({ - template: Templates['metrics-delete'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/metrics/form-view.js b/server/sonar-web/src/main/js/apps/metrics/form-view.js index 7396e4da8ff..91aeda83a7c 100644 --- a/server/sonar-web/src/main/js/apps/metrics/form-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/form-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/metrics-form.hbs'; export default ModalForm.extend({ - template: Templates['metrics-form'], + template: Template, onRender: function () { var that = this; diff --git a/server/sonar-web/src/main/js/apps/metrics/header-view.js b/server/sonar-web/src/main/js/apps/metrics/header-view.js index 37cdc7dc8b4..9278318d73a 100644 --- a/server/sonar-web/src/main/js/apps/metrics/header-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/header-view.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import CreateView from './create-view'; -import './templates'; +import Template from './templates/metrics-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['metrics-header'], + template: Template, events: { 'click #metrics-create': 'onCreateClick' diff --git a/server/sonar-web/src/main/js/apps/metrics/layout.js b/server/sonar-web/src/main/js/apps/metrics/layout.js index 6d1a560cf89..14917cdff33 100644 --- a/server/sonar-web/src/main/js/apps/metrics/layout.js +++ b/server/sonar-web/src/main/js/apps/metrics/layout.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/metrics-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['metrics-layout'], + template: Template, regions: { headerRegion: '#metrics-header', diff --git a/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js b/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js index a48c0a11e7a..9a2aaa64000 100644 --- a/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/metrics-list-footer.hbs'; export default Marionette.ItemView.extend({ - template: Templates['metrics-list-footer'], + template: Template, collectionEvents: { 'all': 'render' diff --git a/server/sonar-web/src/main/js/apps/metrics/list-item-view.js b/server/sonar-web/src/main/js/apps/metrics/list-item-view.js index 3a56e9c9650..e5ab41fd532 100644 --- a/server/sonar-web/src/main/js/apps/metrics/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/list-item-view.js @@ -1,12 +1,12 @@ import Marionette from 'backbone.marionette'; import UpdateView from './update-view'; import DeleteView from './delete-view'; -import './templates'; +import Template from './templates/metrics-list-item.hbs'; export default Marionette.ItemView.extend({ tagName: 'li', className: 'panel panel-vertical', - template: Templates['metrics-list-item'], + template: Template, events: { 'click .js-metric-update': 'onUpdateClick', diff --git a/server/sonar-web/src/main/js/apps/metrics/list-view.js b/server/sonar-web/src/main/js/apps/metrics/list-view.js index e5a0f9f1e96..496b7240df1 100644 --- a/server/sonar-web/src/main/js/apps/metrics/list-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/list-view.js @@ -1,6 +1,5 @@ import Marionette from 'backbone.marionette'; import ListItemView from './list-item-view'; -import './templates'; export default Marionette.CollectionView.extend({ tagName: 'ul', diff --git a/server/sonar-web/src/main/js/apps/nav/app.jsx b/server/sonar-web/src/main/js/apps/nav/app.jsx deleted file mode 100644 index 509a438d0ae..00000000000 --- a/server/sonar-web/src/main/js/apps/nav/app.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import GlobalNav from './global/global-nav'; -import ComponentNav from './component/component-nav'; -import SettingsNav from './settings/settings-nav'; -import '../../components/workspace/main'; - -export default { - start(options) { - window.requestMessages().done(() => { - this.renderGlobalNav(options); - options.space === 'component' && this.renderComponentNav(options); - options.space === 'settings' && this.renderSettingsNav(options); - }); - }, - - renderGlobalNav(options) { - const el = document.getElementById('global-navigation'); - if (el) { - React.render(<GlobalNav {...options}/>, el); - } - }, - - renderComponentNav(options) { - const el = document.getElementById('context-navigation'); - if (el) { - React.render(<ComponentNav {...options}/>, el); - } - }, - - renderSettingsNav(options) { - const el = document.getElementById('context-navigation'); - if (el) { - React.render(<SettingsNav {...options}/>, el); - } - } -}; diff --git a/server/sonar-web/src/main/js/apps/nav/global/shortcuts-help-view.js b/server/sonar-web/src/main/js/apps/nav/global/shortcuts-help-view.js deleted file mode 100644 index 02807d5951f..00000000000 --- a/server/sonar-web/src/main/js/apps/nav/global/shortcuts-help-view.js +++ /dev/null @@ -1,9 +0,0 @@ -import ModalView from 'components/common/modals'; -import '../templates'; - -export default ModalView.extend({ - className: 'modal modal-large', - template: Templates['nav-shortcuts-help'] -}); - - diff --git a/server/sonar-web/src/main/js/apps/permission-templates/app.js b/server/sonar-web/src/main/js/apps/permission-templates/app.js new file mode 100644 index 00000000000..aec705a28d6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/app.js @@ -0,0 +1,8 @@ +import React from 'react'; +import Main from './main'; +import '../../helpers/handlebars-helpers'; + +window.sonarqube.appStarted.then(options => { + var el = document.querySelector(options.el); + React.render(<Main topQualifiers={options.rootQualifiers}/>, el); +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/app.jsx b/server/sonar-web/src/main/js/apps/permission-templates/app.jsx deleted file mode 100644 index 44ff6954266..00000000000 --- a/server/sonar-web/src/main/js/apps/permission-templates/app.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import $ from 'jquery'; -import React from 'react'; -import Main from './main'; - -let topQualifiers = []; - -export default { - start(options) { - $.when( - window.requestMessages(), - this.requestTopQualifiers() - ).then(() => { - var el = document.querySelector(options.el); - React.render(<Main topQualifiers={topQualifiers}/>, el); - }); - }, - - requestTopQualifiers() { - return $.get(baseUrl + '/api/navigation/global').done(r => { - topQualifiers = r.qualifiers; - }); - } -}; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/create-view.jsx b/server/sonar-web/src/main/js/apps/permission-templates/create-view.js index 733e970069f..733e970069f 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/create-view.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/create-view.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/delete-view.jsx b/server/sonar-web/src/main/js/apps/permission-templates/delete-view.js index 60b81fb701c..8f86bb0759d 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/delete-view.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/delete-view.js @@ -1,9 +1,9 @@ import ModalForm from '../../components/common/modal-form'; import {deletePermissionTemplate} from '../../api/permissions'; -import './templates'; +import Template from './templates/permission-templates-delete.hbs'; export default ModalForm.extend({ - template: Templates['permission-templates-delete'], + template: Template, onFormSubmit: function () { ModalForm.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/form-view.js b/server/sonar-web/src/main/js/apps/permission-templates/form-view.js index 71d0802a790..f2cbf834af9 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/form-view.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/form-view.js @@ -1,8 +1,8 @@ import ModalForm from '../../components/common/modal-form'; -import './templates'; +import Template from './templates/permission-templates-form.hbs'; export default ModalForm.extend({ - template: Templates['permission-templates-form'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/groups-view.js b/server/sonar-web/src/main/js/apps/permission-templates/groups-view.js index c13d978d9d3..fc43c68c24c 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/groups-view.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/groups-view.js @@ -1,7 +1,7 @@ import _ from 'underscore'; import Modal from '../../components/common/modals'; import '../../components/common/select-list'; -import './templates'; +import Template from './templates/permission-templates-groups.hbs'; function getSearchUrl (permission, permissionTemplate) { return baseUrl + '/api/permissions/template_groups?ps=100&permission=' + permission.key + @@ -9,7 +9,7 @@ function getSearchUrl (permission, permissionTemplate) { } export default Modal.extend({ - template: Templates['permission-templates-groups'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/header.jsx b/server/sonar-web/src/main/js/apps/permission-templates/header.js index 0325d4bf6cb..0325d4bf6cb 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/header.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/header.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/main.jsx b/server/sonar-web/src/main/js/apps/permission-templates/main.js index 1a0abfc8ead..1a0abfc8ead 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/main.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/main.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.js index 39b9ec52021..39b9ec52021 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.js index 87a75de168b..87a75de168b 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-template.js index ced79afd895..ced79afd895 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permission-template.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.js index a86379e256d..a86379e256d 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.js index 7768f9ec414..7768f9ec414 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/update-view.jsx b/server/sonar-web/src/main/js/apps/permission-templates/update-view.js index 38e546b820d..38e546b820d 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/update-view.jsx +++ b/server/sonar-web/src/main/js/apps/permission-templates/update-view.js diff --git a/server/sonar-web/src/main/js/apps/permission-templates/users-view.js b/server/sonar-web/src/main/js/apps/permission-templates/users-view.js index 6c6fa5f90e4..83b474ddb70 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/users-view.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/users-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Modal from '../../components/common/modals'; import '../../components/common/select-list'; -import './templates'; +import Template from './templates/permission-templates-users.hbs'; export default Modal.extend({ - template: Templates['permission-templates-users'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/app.js b/server/sonar-web/src/main/js/apps/project-permissions/app.js new file mode 100644 index 00000000000..1c6f5645fc6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/app.js @@ -0,0 +1,15 @@ +import $ from 'jquery'; +import React from 'react'; +import Main from './main'; +import '../../helpers/handlebars-helpers'; + +function requestPermissionTemplates () { + return $.get(baseUrl + '/api/permissions/search_templates'); +} + +window.sonarqube.appStarted.then(options => { + requestPermissionTemplates().done(r => { + var el = document.querySelector(options.el); + React.render(<Main permissionTemplates={r.permissionTemplates} componentId={options.componentId}/>, el); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/app.jsx b/server/sonar-web/src/main/js/apps/project-permissions/app.jsx deleted file mode 100644 index 25abfb8629d..00000000000 --- a/server/sonar-web/src/main/js/apps/project-permissions/app.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import $ from 'jquery'; -import React from 'react'; -import Main from './main'; - -let permissionTemplates = []; - -export default { - start(options) { - $.when( - window.requestMessages(), - this.requestPermissionTemplates() - ).then(() => { - var el = document.querySelector(options.el); - React.render(<Main permissionTemplates={permissionTemplates} componentId={options.componentId}/>, el); - }); - }, - - requestPermissionTemplates() { - return $.get(baseUrl + '/api/permissions/search_templates').done(r => { - permissionTemplates = r.permissionTemplates; - }); - } -}; diff --git a/server/sonar-web/src/main/js/apps/project-permissions/apply-template-view.jsx b/server/sonar-web/src/main/js/apps/project-permissions/apply-template-view.js index dbf1c26520f..73dc0ec1b95 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/apply-template-view.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/apply-template-view.js @@ -2,10 +2,10 @@ import $ from 'jquery'; import _ from 'underscore'; import ModalForm from '../../components/common/modal-form'; import {applyTemplateToProject} from '../../api/permissions'; -import './templates'; +import Template from './templates/project-permissions-apply-template.hbs'; export default ModalForm.extend({ - template: Templates['project-permissions-apply-template'], + template: Template, onRender: function () { ModalForm.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js b/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js index ed88709054a..0f63aac99b9 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js +++ b/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js @@ -1,14 +1,14 @@ import _ from 'underscore'; -import Modal from 'components/common/modals'; -import 'components/common/select-list'; -import './templates'; +import Modal from '../../components/common/modals'; +import '../../components/common/select-list'; +import Template from './templates/project-permissions-groups.hbs'; function getSearchUrl (permission, project) { return baseUrl + '/api/permissions/groups?ps=100&permission=' + permission + '&projectId=' + project; } export default Modal.extend({ - template: Templates['project-permissions-groups'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/main.jsx b/server/sonar-web/src/main/js/apps/project-permissions/main.js index 2c248f81344..2c248f81344 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/main.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/main.js diff --git a/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.jsx b/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.js index cab1354e3ff..cab1354e3ff 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.js diff --git a/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.jsx b/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.js index 7768f9ec414..7768f9ec414 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.js diff --git a/server/sonar-web/src/main/js/apps/project-permissions/permissions.jsx b/server/sonar-web/src/main/js/apps/project-permissions/permissions.js index 26da7da40d6..26da7da40d6 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/permissions.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/permissions.js diff --git a/server/sonar-web/src/main/js/apps/project-permissions/project.jsx b/server/sonar-web/src/main/js/apps/project-permissions/project.js index 57b87b71cbd..57b87b71cbd 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/project.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/project.js diff --git a/server/sonar-web/src/main/js/apps/project-permissions/search.jsx b/server/sonar-web/src/main/js/apps/project-permissions/search.js index dfc243f8636..dfc243f8636 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/search.jsx +++ b/server/sonar-web/src/main/js/apps/project-permissions/search.js diff --git a/server/sonar-web/src/main/js/apps/project-permissions/users-view.js b/server/sonar-web/src/main/js/apps/project-permissions/users-view.js index 31cbc91c653..62ab87e8143 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/users-view.js +++ b/server/sonar-web/src/main/js/apps/project-permissions/users-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; -import Modal from 'components/common/modals'; -import 'components/common/select-list'; -import './templates'; +import Modal from '../../components/common/modals'; +import '../../components/common/select-list'; +import Template from './templates/project-permissions-users.hbs'; export default Modal.extend({ - template: Templates['project-permissions-users'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/projects/app.js b/server/sonar-web/src/main/js/apps/projects/app.js index 8e98bb1686b..917d7342adc 100644 --- a/server/sonar-web/src/main/js/apps/projects/app.js +++ b/server/sonar-web/src/main/js/apps/projects/app.js @@ -1,21 +1,14 @@ -import $ from 'jquery'; import React from 'react'; import Main from './main'; import {getCurrentUser} from '../../api/users'; -import {getGlobalNavigation} from '../../api/nav'; +import '../../helpers/handlebars-helpers'; -export default { - start(options) { - $.when( - getCurrentUser(), - getGlobalNavigation(), - window.requestMessages() - ).then((user, nav) => { - let el = document.querySelector(options.el), - hasProvisionPermission = user[0].permissions.global.indexOf('provisioning') !== -1, - topLevelQualifiers = nav[0].qualifiers; - React.render(<Main hasProvisionPermission={hasProvisionPermission} - topLevelQualifiers={topLevelQualifiers}/>, el); - }); - } -}; +window.sonarqube.appStarted.then(options => { + getCurrentUser().done(user => { + let el = document.querySelector(options.el), + hasProvisionPermission = user.permissions.global.indexOf('provisioning') !== -1, + topLevelQualifiers = options.rootQualifiers; + React.render(<Main hasProvisionPermission={hasProvisionPermission} + topLevelQualifiers={topLevelQualifiers}/>, el); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/projects/create-view.js b/server/sonar-web/src/main/js/apps/projects/create-view.js index 6307b708614..89425a212f8 100644 --- a/server/sonar-web/src/main/js/apps/projects/create-view.js +++ b/server/sonar-web/src/main/js/apps/projects/create-view.js @@ -1,9 +1,9 @@ -import ModalForm from 'components/common/modal-form'; +import ModalForm from '../../components/common/modal-form'; import {createProject} from '../../api/components'; -import './templates'; +import Template from './templates/projects-create-form.hbs'; export default ModalForm.extend({ - template: Templates['projects-create-form'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/projects/delete-view.js b/server/sonar-web/src/main/js/apps/projects/delete-view.js index 56d5f1587b8..2a677ee1355 100644 --- a/server/sonar-web/src/main/js/apps/projects/delete-view.js +++ b/server/sonar-web/src/main/js/apps/projects/delete-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/projects-delete.hbs'; export default ModalForm.extend({ - template: Templates['projects-delete'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/actions-view.js b/server/sonar-web/src/main/js/apps/quality-gates/actions-view.js index 62d27477f50..66c200cdb77 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/actions-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/actions-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import CreateView from './create-view'; -import './templates'; +import Template from './templates/quality-gate-actions.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-gate-actions'], + template: Template, events: { 'click #quality-gate-add': 'add' diff --git a/server/sonar-web/src/main/js/apps/quality-gates/app.js b/server/sonar-web/src/main/js/apps/quality-gates/app.js index 3dc3eece7f6..bf8fb14aa7b 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/app.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/app.js @@ -7,10 +7,12 @@ import ActionsView from './actions-view'; import Router from './router'; import Layout from './layout'; import Controller from './controller'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(); -var init = function (options) { +var init = function () { + let options = window.sonarqube; // Layout this.layout = new Layout({ el: options.el }); this.layout.render(); @@ -52,11 +54,11 @@ var appXHR = $.get(baseUrl + '/api/qualitygates/app') }); App.on('start', function (options) { - $.when(window.requestMessages(), appXHR).done(function () { + appXHR.done(function () { init.call(App, options); }); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/delete-view.js b/server/sonar-web/src/main/js/apps/quality-gates/delete-view.js index ca25708f342..4cef8ac5363 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/delete-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/delete-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/quality-gates-delete.hbs'; export default ModalForm.extend({ - template: Templates['quality-gates-delete'], + template: Template, onFormSubmit: function () { ModalForm.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/details-view.js b/server/sonar-web/src/main/js/apps/quality-gates/details-view.js index 6f7429cc5f6..5e7f9782b43 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/details-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/details-view.js @@ -2,10 +2,10 @@ import Marionette from 'backbone.marionette'; import Conditions from './conditions'; import DetailConditionsView from './gate-conditions-view'; import ProjectsView from './gate-projects-view'; -import './templates'; +import Template from './templates/quality-gate-detail.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['quality-gate-detail'], + template: Template, regions: { conditionsRegion: '#quality-gate-conditions', diff --git a/server/sonar-web/src/main/js/apps/quality-gates/form-view.js b/server/sonar-web/src/main/js/apps/quality-gates/form-view.js index f3f4d55d869..6d0b022334c 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/form-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/form-view.js @@ -1,11 +1,11 @@ import _ from 'underscore'; import Backbone from 'backbone'; -import ModalForm from 'components/common/modal-form'; +import ModalForm from '../../components/common/modal-form'; import Gate from './gate'; -import './templates'; +import Template from './templates/quality-gate-form.hbs'; export default ModalForm.extend({ - template: Templates['quality-gate-form'], + template: Template, onFormSubmit: function () { ModalForm.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js index 7678405c622..9ab319a78e7 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js @@ -1,11 +1,11 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import DeleteConditionView from './gate-conditions-delete-view'; -import './templates'; +import Template from './templates/quality-gate-detail-condition.hbs'; export default Marionette.ItemView.extend({ tagName: 'tr', - template: Templates['quality-gate-detail-condition'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-delete-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-delete-view.js index 9922a0bc5b1..b617e603358 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-delete-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-delete-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/quality-gates-condition-delete.hbs'; export default ModalForm.extend({ - template: Templates['quality-gates-condition-delete'], + template: Template, onFormSubmit: function () { ModalForm.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-empty-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-empty-view.js index 5be03d5a0c6..a23861c00c1 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-empty-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-empty-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-gate-detail-conditions-empty.hbs'; export default Marionette.ItemView.extend({ tagName: 'tr', - template: Templates['quality-gate-detail-conditions-empty'], + template: Template, serializeData: function () { return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js index d02f8f93603..4994a9da37b 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js @@ -3,10 +3,10 @@ import Marionette from 'backbone.marionette'; import Condition from './condition'; import ConditionView from './gate-condition-view'; import ConditionsEmptyView from './gate-conditions-empty-view'; -import './templates'; +import Template from './templates/quality-gate-detail-conditions.hbs'; export default Marionette.CompositeView.extend({ - template: Templates['quality-gate-detail-conditions'], + template: Template, childView: ConditionView, emptyView: ConditionsEmptyView, childViewContainer: '.js-conditions', diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js index 732074be79d..ff7816bd659 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import 'components/common/select-list'; -import './templates'; +import Template from './templates/quality-gate-detail-projects.hbs'; +import '../../components/common/select-list'; export default Marionette.ItemView.extend({ - template: Templates['quality-gate-detail-projects'], + template: Template, onRender: function () { if (!this.model.isDefault()) { diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-view.js index 13b3e582b96..937b2e013d6 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-view.js @@ -1,10 +1,10 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-gates-gate.hbs'; export default Marionette.ItemView.extend({ tagName: 'a', className: 'list-group-item', - template: Templates['quality-gates-gate'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gates-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gates-view.js index 956cc21826a..6864665239e 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gates-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gates-view.js @@ -1,10 +1,10 @@ import Marionette from 'backbone.marionette'; import ItemView from './gate-view'; -import './templates'; +import Template from './templates/quality-gates-gates.hbs'; export default Marionette.CompositeView.extend({ className: 'list-group', - template: Templates['quality-gates-gates'], + template: Template, childView: ItemView, childViewContainer: '.js-list', diff --git a/server/sonar-web/src/main/js/apps/quality-gates/header-view.js b/server/sonar-web/src/main/js/apps/quality-gates/header-view.js index 7a002258513..4a51fd42696 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/header-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/header-view.js @@ -3,10 +3,10 @@ import Marionette from 'backbone.marionette'; import RenameView from './rename-view'; import CopyView from './copy-view'; import DeleteView from './delete-view'; -import './templates'; +import Template from './templates/quality-gate-detail-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-gate-detail-header'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/quality-gates/intro-view.js b/server/sonar-web/src/main/js/apps/quality-gates/intro-view.js index 6128211275c..53c95caa621 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/intro-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/intro-view.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-gates-intro.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-gates-intro'] + template: Template }); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/layout.js b/server/sonar-web/src/main/js/apps/quality-gates/layout.js index 5d0a65ae47b..2eeece27cd0 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/layout.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/layout.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import IntroView from './intro-view'; -import './templates'; +import Template from './templates/quality-gates-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['quality-gates-layout'], + template: Template, regions: { headerRegion: '.search-navigator-workspace-header', diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js index a2fe43cbe18..021343f4878 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js @@ -4,10 +4,10 @@ import Marionette from 'backbone.marionette'; import CreateProfileView from './create-profile-view'; import RestoreProfileView from './restore-profile-view'; import RestoreBuiltInProfilesView from './restore-built-in-profiles-view'; -import './templates'; +import Template from './templates/quality-profiles-actions.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-profiles-actions'], + template: Template, events: { 'click #quality-profiles-create': 'onCreateClick', diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/app.js b/server/sonar-web/src/main/js/apps/quality-profiles/app.js index 1a81ee6598b..9e95e793ad3 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/app.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/app.js @@ -7,6 +7,7 @@ import Layout from './layout'; import Profiles from './profiles'; import ActionsView from './actions-view'; import ProfilesView from './profiles-view'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), requestUser = $.get(baseUrl + '/api/users/current').done(function (r) { @@ -15,7 +16,9 @@ var App = new Marionette.Application(), requestExporters = $.get(baseUrl + '/api/qualityprofiles/exporters').done(function (r) { App.exporters = r.exporters; }), - init = function (options) { + init = function () { + let options = window.sonarqube; + // Layout this.layout = new Layout({ el: options.el }); this.layout.render(); @@ -51,12 +54,12 @@ var App = new Marionette.Application(), }); }; -App.on('start', function (options) { - $.when(window.requestMessages(), requestUser, requestExporters).done(function () { - init.call(App, options); +App.on('start', function () { + $.when(requestUser, requestExporters).done(function () { + init.call(App); }); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js index a3d5ec6b7ad..e4ebc87eb29 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import ModalFormView from 'components/common/modal-form'; -import './templates'; +import ModalFormView from '../../components/common/modal-form'; +import Template from './templates/quality-profiles-change-profile-parent.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-change-profile-parent'], + template: Template, onRender: function () { ModalFormView.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/copy-profile-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/copy-profile-view.js index 9c7d29d0dbc..c1060e9ea27 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/copy-profile-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/copy-profile-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; -import ModalFormView from 'components/common/modal-form'; +import ModalFormView from '../../components/common/modal-form'; import Profile from './profile'; -import './templates'; +import Template from './templates/quality-profiles-copy-profile.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-copy-profile'], + template: Template, onFormSubmit: function () { ModalFormView.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/create-profile-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/create-profile-view.js index a6258bff571..8a788d23b67 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/create-profile-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/create-profile-view.js @@ -1,12 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalFormView from 'components/common/modal-form'; -import uploader from 'components/common/file-upload'; +import ModalFormView from '../../components/common/modal-form'; +import uploader from '../../components/common/file-upload'; import Profile from './profile'; -import './templates'; +import Template from './templates/quality-profiles-create-profile.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-create-profile'], + template: Template, events: function () { return _.extend(ModalFormView.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/delete-profile-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/delete-profile-view.js index ed2ee8ac7da..49cd86ef4af 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/delete-profile-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/delete-profile-view.js @@ -1,9 +1,9 @@ import $ from 'jquery'; -import ModalFormView from 'components/common/modal-form'; -import './templates'; +import ModalFormView from '../../components/common/modal-form'; +import Template from './templates/quality-profiles-delete-profile.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-delete-profile'], + template: Template, modelEvents: { 'destroy': 'destroy' diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js b/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js index efb8e83253d..7e060b9599b 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js @@ -1,3 +1,5 @@ +import Handlebars from 'hbsfy/runtime'; + Handlebars.registerHelper('profileUrl', function (key) { return baseUrl + '/profiles/show?key=' + encodeURIComponent(key); }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/intro-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/intro-view.js index c250e4c7569..ac19cf7e72b 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/intro-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/intro-view.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-profiles-intro.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-profiles-intro'] + template: Template }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/layout.js b/server/sonar-web/src/main/js/apps/quality-profiles/layout.js index 6f7a0af9057..3fc1d0543ff 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/layout.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/layout.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import IntroView from './intro-view'; -import './templates'; +import Template from './templates/quality-profiles-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['quality-profiles-layout'], + template: Template, regions: { headerRegion: '.search-navigator-workspace-header', diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-changelog-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-changelog-view.js index 4d9e18ad660..b18d730d768 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-changelog-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-changelog-view.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-profile-changelog.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-profile-changelog'], + template: Template, events: { 'submit #quality-profile-changelog-form': 'onFormSubmit', diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-comparison-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-comparison-view.js index aab7018aac6..17217c5921a 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-comparison-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-comparison-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-profile-comparison.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-profile-comparison'], + template: Template, events: { 'submit #quality-profile-comparison-form': 'onFormSubmit' diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js index 03ea016e555..7ea7ef2dc96 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js @@ -4,12 +4,12 @@ import Marionette from 'backbone.marionette'; import ChangeProfileParentView from './change-profile-parent-view'; import ProfileChangelogView from './profile-changelog-view'; import ProfileComparisonView from './profile-comparison-view'; -import 'components/common/select-list'; +import '../../components/common/select-list'; import './helpers'; -import './templates'; +import Template from './templates/quality-profiles-profile-details.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['quality-profiles-profile-details'], + template: Template, regions: { changelogRegion: '#quality-profile-changelog', diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-header-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-header-view.js index 4c75884fff8..9a209d04530 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-header-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-header-view.js @@ -4,10 +4,10 @@ import Marionette from 'backbone.marionette'; import ProfileCopyView from './copy-profile-view'; import ProfileRenameView from './rename-profile-view'; import ProfileDeleteView from './delete-profile-view'; -import './templates'; +import Template from './templates/quality-profiles-profile-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['quality-profiles-profile-header'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-view.js index 541482a5569..862c86f2d6c 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-view.js @@ -1,11 +1,11 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-profiles-profile.hbs'; export default Marionette.ItemView.extend({ tagName: 'a', className: 'list-group-item', - template: Templates['quality-profiles-profile'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profiles-empty-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profiles-empty-view.js index 49a0a803749..5e5a0b1adb1 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profiles-empty-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profiles-empty-view.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/quality-profiles-empty.hbs'; export default Marionette.ItemView.extend({ className: 'list-group-item', - template: Templates['quality-profiles-empty'] + template: Template }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profiles-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profiles-view.js index 82d8c26f297..713487a5dd5 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profiles-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profiles-view.js @@ -1,12 +1,13 @@ import Marionette from 'backbone.marionette'; import ProfileView from './profile-view'; import ProfilesEmptyView from './profiles-empty-view'; -import './templates'; +import Template from './templates/quality-profiles-profiles.hbs'; +import LanguageTemplate from './templates/quality-profiles-profiles-language.hbs'; export default Marionette.CompositeView.extend({ className: 'list-group', - template: Templates['quality-profiles-profiles'], - languageTemplate: Templates['quality-profiles-profiles-language'], + template: Template, + languageTemplate: LanguageTemplate, childView: ProfileView, childViewContainer: '.js-list', emptyView: ProfilesEmptyView, diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/rename-profile-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/rename-profile-view.js index 9e4aef76403..5ab77f11dc3 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/rename-profile-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/rename-profile-view.js @@ -1,9 +1,9 @@ import $ from 'jquery'; -import ModalFormView from 'components/common/modal-form'; -import './templates'; +import ModalFormView from '../../components/common/modal-form'; +import Template from './templates/quality-profiles-rename-profile.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-rename-profile'], + template: Template, onFormSubmit: function () { ModalFormView.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/restore-built-in-profiles-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/restore-built-in-profiles-view.js index 76ca3851738..e23638f8f5b 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/restore-built-in-profiles-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/restore-built-in-profiles-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalFormView from 'components/common/modal-form'; -import './templates'; +import ModalFormView from '../../components/common/modal-form'; +import Template from './templates/quality-profiles-restore-built-in-profiles.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-restore-built-in-profiles'], + template: Template, onFormSubmit: function () { ModalFormView.prototype.onFormSubmit.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/restore-profile-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/restore-profile-view.js index 57540d9b4a4..2d280acafa9 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/restore-profile-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/restore-profile-view.js @@ -1,12 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalFormView from 'components/common/modal-form'; -import uploader from 'components/common/file-upload'; +import ModalFormView from '../../components/common/modal-form'; +import uploader from '../../components/common/file-upload'; import Profile from './profile'; -import './templates'; +import Template from './templates/quality-profiles-restore-profile.hbs'; export default ModalFormView.extend({ - template: Templates['quality-profiles-restore-profile'], + template: Template, onFormSubmit: function (e) { var that = this; diff --git a/server/sonar-web/src/main/js/apps/source-viewer/app.js b/server/sonar-web/src/main/js/apps/source-viewer/app.js index 3c013e406de..8d7ecb575f7 100644 --- a/server/sonar-web/src/main/js/apps/source-viewer/app.js +++ b/server/sonar-web/src/main/js/apps/source-viewer/app.js @@ -1,8 +1,11 @@ import Marionette from 'backbone.marionette'; -import SourceViewer from 'components/source-viewer/main'; +import SourceViewer from '../../components/source-viewer/main'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + this.addRegions({ mainRegion: options.el }); var viewer = new SourceViewer(); @@ -17,12 +20,10 @@ var App = new Marionette.Application(), } }; -App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); +App.on('start', function () { + init.call(App); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/system/app.js b/server/sonar-web/src/main/js/apps/system/app.js index 6f01aa94453..223337df883 100644 --- a/server/sonar-web/src/main/js/apps/system/app.js +++ b/server/sonar-web/src/main/js/apps/system/app.js @@ -3,7 +3,7 @@ import {setLogLevel} from '../../api/system'; const LOG_LEVELS = ['INFO', 'DEBUG', 'TRACE']; -window.requestMessages().done(() => { +window.sonarqube.appStarted.then(() => { let cell = $('#sonarqube-logs-level').find('td:last-child'); if (cell.length) { let currentValue = cell.text().trim(); @@ -53,3 +53,5 @@ window.requestMessages().done(() => { }); } }); + + diff --git a/server/sonar-web/src/main/js/apps/update-center/app.js b/server/sonar-web/src/main/js/apps/update-center/app.js index b667f6736b8..01d4c554cc6 100644 --- a/server/sonar-web/src/main/js/apps/update-center/app.js +++ b/server/sonar-web/src/main/js/apps/update-center/app.js @@ -8,9 +8,13 @@ import FooterView from './footer-view'; import Controller from './controller'; import Router from './router'; import Plugins from './plugins'; +import './partials'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + // State this.state = new Backbone.Model({ updateCenterActive: window.SS.updateCenterActive @@ -53,12 +57,10 @@ var App = new Marionette.Application(), }); }; -App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); +App.on('start', function () { + init.call(App); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/update-center/footer-view.js b/server/sonar-web/src/main/js/apps/update-center/footer-view.js index 085dacf43c2..07f8e622124 100644 --- a/server/sonar-web/src/main/js/apps/update-center/footer-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/footer-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/update-center-footer.hbs'; export default Marionette.ItemView.extend({ - template: Templates['update-center-footer'], + template: Template, collectionEvents: { 'all': 'render' diff --git a/server/sonar-web/src/main/js/apps/update-center/header-view.js b/server/sonar-web/src/main/js/apps/update-center/header-view.js index 1a78ad8533b..c22354b1233 100644 --- a/server/sonar-web/src/main/js/apps/update-center/header-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/header-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/update-center-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['update-center-header'], + template: Template, collectionEvents: { all: 'render' diff --git a/server/sonar-web/src/main/js/apps/update-center/layout.js b/server/sonar-web/src/main/js/apps/update-center/layout.js index 2a8c5d7b4e8..16aad883f3a 100644 --- a/server/sonar-web/src/main/js/apps/update-center/layout.js +++ b/server/sonar-web/src/main/js/apps/update-center/layout.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/update-center-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['update-center-layout'], + template: Template, regions: { headerRegion: '#update-center-header', diff --git a/server/sonar-web/src/main/js/apps/update-center/list-item-view.js b/server/sonar-web/src/main/js/apps/update-center/list-item-view.js index 163d3c61fa0..695994f9e18 100644 --- a/server/sonar-web/src/main/js/apps/update-center/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/list-item-view.js @@ -2,13 +2,14 @@ import $ from 'jquery'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import PluginChangelogView from './plugin-changelog-view'; -import './templates'; +import Template from './templates/update-center-plugin.hbs'; +import SystemTemplate from './templates/update-center-system-update.hbs'; export default Marionette.ItemView.extend({ tagName: 'li', className: 'panel panel-vertical', - template: Templates['update-center-plugin'], - systemTemplate: Templates['update-center-system-update'], + template: Template, + systemTemplate: SystemTemplate, modelEvents: { 'change:_hidden': 'toggleDisplay', diff --git a/server/sonar-web/src/main/js/apps/update-center/partials.js b/server/sonar-web/src/main/js/apps/update-center/partials.js new file mode 100644 index 00000000000..88483429742 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/update-center/partials.js @@ -0,0 +1,6 @@ +import Handlebars from 'hbsfy/runtime'; +import ChangeEntryPartial from './templates/_update-center-plugin-changelog-entry.hbs'; +import ActionsPartial from './templates/_update-center-plugin-actions.hbs'; + +Handlebars.registerPartial('_update-center-plugin-changelog-entry', ChangeEntryPartial); +Handlebars.registerPartial('_update-center-plugin-actions', ActionsPartial); diff --git a/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js b/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js index 56ce094b922..c07b2d3c7ac 100644 --- a/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; -import Popup from 'components/common/popup'; -import './templates'; +import Popup from '../../components/common/popup'; +import Template from './templates/update-center-plugin-changelog.hbs'; export default Popup.extend({ - template: Templates['update-center-plugin-changelog'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/update-center/search-view.js b/server/sonar-web/src/main/js/apps/update-center/search-view.js index 739f11a2c96..c711e8a56af 100644 --- a/server/sonar-web/src/main/js/apps/update-center/search-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/search-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/update-center-search.hbs'; export default Marionette.ItemView.extend({ - template: Templates['update-center-search'], + template: Template, events: { 'change [name="update-center-filter"]': 'onFilterChange', diff --git a/server/sonar-web/src/main/js/apps/users/app.js b/server/sonar-web/src/main/js/apps/users/app.js index cf64028a2e7..5e51c04d989 100644 --- a/server/sonar-web/src/main/js/apps/users/app.js +++ b/server/sonar-web/src/main/js/apps/users/app.js @@ -5,9 +5,12 @@ import HeaderView from './header-view'; import SearchView from './search-view'; import ListView from './list-view'; import ListFooterView from './list-footer-view'; +import '../../helpers/handlebars-helpers'; var App = new Marionette.Application(), - init = function (options) { + init = function () { + let options = window.sonarqube; + // Layout this.layout = new Layout({ el: options.el }); this.layout.render(); @@ -35,12 +38,10 @@ var App = new Marionette.Application(), this.users.fetch(); }; -App.on('start', function (options) { - window.requestMessages().done(function () { - init.call(App, options); - }); +App.on('start', function () { + init.call(App); }); -export default App; +window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/users/change-password-view.js b/server/sonar-web/src/main/js/apps/users/change-password-view.js index f8b9f95eb60..f9912b607ad 100644 --- a/server/sonar-web/src/main/js/apps/users/change-password-view.js +++ b/server/sonar-web/src/main/js/apps/users/change-password-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/users-change-password.hbs'; export default ModalForm.extend({ - template: Templates['users-change-password'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/users/deactivate-view.js b/server/sonar-web/src/main/js/apps/users/deactivate-view.js index bf7cbe80489..780e140f39a 100644 --- a/server/sonar-web/src/main/js/apps/users/deactivate-view.js +++ b/server/sonar-web/src/main/js/apps/users/deactivate-view.js @@ -1,8 +1,8 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/users-deactivate.hbs'; export default ModalForm.extend({ - template: Templates['users-deactivate'], + template: Template, onFormSubmit: function (e) { this._super(e); diff --git a/server/sonar-web/src/main/js/apps/users/form-view.js b/server/sonar-web/src/main/js/apps/users/form-view.js index 71bd7716038..85d8affe3bb 100644 --- a/server/sonar-web/src/main/js/apps/users/form-view.js +++ b/server/sonar-web/src/main/js/apps/users/form-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; +import Template from './templates/users-form.hbs'; export default ModalForm.extend({ - template: Templates['users-form'], + template: Template, events: function () { return _.extend(this._super(), { diff --git a/server/sonar-web/src/main/js/apps/users/groups-view.js b/server/sonar-web/src/main/js/apps/users/groups-view.js index 6e4a9048854..498ab93df92 100644 --- a/server/sonar-web/src/main/js/apps/users/groups-view.js +++ b/server/sonar-web/src/main/js/apps/users/groups-view.js @@ -1,10 +1,9 @@ -import Modal from 'components/common/modals'; -import 'components/common/select-list'; -import './templates'; +import Modal from '../../components/common/modals'; +import '../../components/common/select-list'; +import Template from './templates/users-groups.hbs'; export default Modal.extend({ - template: Templates['users-groups'], - itemTemplate: Templates['users-group'], + template: Template, onRender: function () { this._super(); diff --git a/server/sonar-web/src/main/js/apps/users/header-view.js b/server/sonar-web/src/main/js/apps/users/header-view.js index ae9bae8e422..66e5df75b1a 100644 --- a/server/sonar-web/src/main/js/apps/users/header-view.js +++ b/server/sonar-web/src/main/js/apps/users/header-view.js @@ -1,9 +1,9 @@ import Marionette from 'backbone.marionette'; import CreateView from './create-view'; -import './templates'; +import Template from './templates/users-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['users-header'], + template: Template, events: { 'click #users-create': 'onCreateClick' diff --git a/server/sonar-web/src/main/js/apps/users/layout.js b/server/sonar-web/src/main/js/apps/users/layout.js index 90866f6f6e1..f72e5f2caa3 100644 --- a/server/sonar-web/src/main/js/apps/users/layout.js +++ b/server/sonar-web/src/main/js/apps/users/layout.js @@ -1,8 +1,8 @@ import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/users-layout.hbs'; export default Marionette.LayoutView.extend({ - template: Templates['users-layout'], + template: Template, regions: { headerRegion: '#users-header', diff --git a/server/sonar-web/src/main/js/apps/users/list-footer-view.js b/server/sonar-web/src/main/js/apps/users/list-footer-view.js index 7c4d2482efa..6a4dd06a2b1 100644 --- a/server/sonar-web/src/main/js/apps/users/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-footer-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/users-list-footer.hbs'; export default Marionette.ItemView.extend({ - template: Templates['users-list-footer'], + template: Template, collectionEvents: { 'all': 'render' diff --git a/server/sonar-web/src/main/js/apps/users/list-item-view.js b/server/sonar-web/src/main/js/apps/users/list-item-view.js index 50e864992fa..316d0428576 100644 --- a/server/sonar-web/src/main/js/apps/users/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-item-view.js @@ -4,12 +4,12 @@ import UpdateView from './update-view'; import ChangePasswordView from './change-password-view'; import DeactivateView from './deactivate-view'; import GroupsView from './groups-view'; -import './templates'; +import Template from './templates/users-list-item.hbs'; export default Marionette.ItemView.extend({ tagName: 'li', className: 'panel panel-vertical', - template: Templates['users-list-item'], + template: Template, events: { 'click .js-user-more-scm': 'onMoreScmClick', diff --git a/server/sonar-web/src/main/js/apps/users/list-view.js b/server/sonar-web/src/main/js/apps/users/list-view.js index 695bf2ac034..699e9c76a85 100644 --- a/server/sonar-web/src/main/js/apps/users/list-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-view.js @@ -1,6 +1,5 @@ import Marionette from 'backbone.marionette'; import ListItemView from './list-item-view'; -import './templates'; export default Marionette.CollectionView.extend({ tagName: 'ul', diff --git a/server/sonar-web/src/main/js/apps/users/search-view.js b/server/sonar-web/src/main/js/apps/users/search-view.js index 114f0971e71..beae12b40ad 100644 --- a/server/sonar-web/src/main/js/apps/users/search-view.js +++ b/server/sonar-web/src/main/js/apps/users/search-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import './templates'; +import Template from './templates/users-search.hbs'; export default Marionette.ItemView.extend({ - template: Templates['users-search'], + template: Template, events: { 'submit #users-search-form': 'onFormSubmit', diff --git a/server/sonar-web/src/main/js/components/common/action-options-view.js b/server/sonar-web/src/main/js/components/common/action-options-view.js index 061d3dffd7f..19e13e7e4e5 100644 --- a/server/sonar-web/src/main/js/components/common/action-options-view.js +++ b/server/sonar-web/src/main/js/components/common/action-options-view.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import PopupView from 'components/common/popup'; +import PopupView from './popup'; export default PopupView.extend({ className: 'bubble-popup bubble-popup-menu', diff --git a/server/sonar-web/src/main/js/components/common/modal-form.js b/server/sonar-web/src/main/js/components/common/modal-form.js index 86ae8b89387..418083b0d61 100644 --- a/server/sonar-web/src/main/js/components/common/modal-form.js +++ b/server/sonar-web/src/main/js/components/common/modal-form.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import ModalView from 'components/common/modals'; +import ModalView from './modals'; export default ModalView.extend({ diff --git a/server/sonar-web/src/main/js/components/issue/issue-view.js b/server/sonar-web/src/main/js/components/issue/issue-view.js index 12ff93c00ba..5b974d80ba4 100644 --- a/server/sonar-web/src/main/js/components/issue/issue-view.js +++ b/server/sonar-web/src/main/js/components/issue/issue-view.js @@ -12,12 +12,12 @@ import PlanFormView from './views/plan-form-view'; import SetSeverityFormView from './views/set-severity-form-view'; import MoreActionsView from './views/more-actions-view'; import TagsFormView from './views/tags-form-view'; -import Workspace from 'components/workspace/main'; -import './templates'; +import Workspace from '../workspace/main'; +import Template from './templates/issue.hbs'; export default Marionette.ItemView.extend({ className: 'issue', - template: Templates.issue, + template: Template, modelEvents: { 'change': 'render', @@ -206,8 +206,7 @@ export default Marionette.ItemView.extend({ showRule: function () { var ruleKey = this.model.get('rule'); - var RealWorkspace = Workspace.openComponent ? Workspace : require('components/workspace/main'); - RealWorkspace.openRule({ key: ruleKey }); + Workspace.openRule({ key: ruleKey }); }, showMoreActions: function (e) { diff --git a/server/sonar-web/src/main/js/components/issue/manual-issue-view.js b/server/sonar-web/src/main/js/components/issue/manual-issue-view.js index 31b318a4ac8..cf198aebd4e 100644 --- a/server/sonar-web/src/main/js/components/issue/manual-issue-view.js +++ b/server/sonar-web/src/main/js/components/issue/manual-issue-view.js @@ -2,10 +2,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; import Issue from './models/issue'; -import './templates'; +import Template from './templates/manual-issue.hbs'; export default Marionette.ItemView.extend({ - template: Templates['manual-issue'], + template: Template, events: { 'submit .js-manual-issue-form': 'formSubmit', diff --git a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js index b99d8ab8e90..e732493b89a 100644 --- a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js @@ -1,11 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; -import ActionOptionsView from 'components/common/action-options-view'; -import '../templates'; +import ActionOptionsView from '../../common/action-options-view'; +import Template from '../templates/issue-assign-form.hbs'; +import OptionTemplate from '../templates/issue-assign-form-option.hbs'; export default ActionOptionsView.extend({ - template: Templates['issue-assign-form'], - optionTemplate: Templates['issue-assign-form-option'], + template: Template, + optionTemplate: OptionTemplate, events: function () { return _.extend(ActionOptionsView.prototype.events.apply(this, arguments), { diff --git a/server/sonar-web/src/main/js/components/issue/views/changelog-view.js b/server/sonar-web/src/main/js/components/issue/views/changelog-view.js index f7c51f88a7f..ca431561a98 100644 --- a/server/sonar-web/src/main/js/components/issue/views/changelog-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/changelog-view.js @@ -1,9 +1,9 @@ import _ from 'underscore'; -import PopupView from 'components/common/popup'; -import '../templates'; +import PopupView from '../../common/popup'; +import Template from '../templates/issue-changelog.hbs'; export default PopupView.extend({ - template: Templates['issue-changelog'], + template: Template, collectionEvents: { 'sync': 'render' diff --git a/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js b/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js index ee2f1c91e87..c1dc3cfd172 100644 --- a/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import PopupView from 'components/common/popup'; -import '../templates'; +import PopupView from '../../common/popup'; +import Template from '../templates/comment-form.hbs'; export default PopupView.extend({ className: 'bubble-popup issue-comment-bubble-popup', - template: Templates['comment-form'], + template: Template, ui: { textarea: '.issue-comment-form-text textarea', diff --git a/server/sonar-web/src/main/js/components/issue/views/issue-popup.js b/server/sonar-web/src/main/js/components/issue/views/issue-popup.js index e8160c8ef66..8c03550ee5c 100644 --- a/server/sonar-web/src/main/js/components/issue/views/issue-popup.js +++ b/server/sonar-web/src/main/js/components/issue/views/issue-popup.js @@ -1,4 +1,4 @@ -import PopupView from 'components/common/popup'; +import PopupView from '../../common/popup'; export default PopupView.extend({ className: 'bubble-popup issue-bubble-popup', diff --git a/server/sonar-web/src/main/js/components/issue/views/more-actions-view.js b/server/sonar-web/src/main/js/components/issue/views/more-actions-view.js index 70db7c1b2e4..e3f62b08e10 100644 --- a/server/sonar-web/src/main/js/components/issue/views/more-actions-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/more-actions-view.js @@ -1,9 +1,9 @@ import $ from 'jquery'; -import ActionOptionsView from 'components/common/action-options-view'; -import '../templates'; +import ActionOptionsView from '../../../components/common/action-options-view'; +import Template from '../templates/issue-more-actions.hbs'; export default ActionOptionsView.extend({ - template: Templates['issue-more-actions'], + template: Template, selectOption: function (e) { var action = $(e.currentTarget).data('action'); diff --git a/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js b/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js index a0459ed7765..244d65e6a79 100644 --- a/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ActionOptionsView from 'components/common/action-options-view'; -import '../templates'; +import ActionOptionsView from '../../common/action-options-view'; +import Template from '../templates/issue-plan-form.hbs'; export default ActionOptionsView.extend({ - template: Templates['issue-plan-form'], + template: Template, getActionPlan: function () { return this.model.get('actionPlan') || ''; diff --git a/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js b/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js index 50fd125f0d2..10ff68f86ef 100644 --- a/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; -import ActionOptionsView from 'components/common/action-options-view'; -import '../templates'; +import ActionOptionsView from '../../common/action-options-view'; +import Template from '../templates/issue-set-severity-form.hbs'; export default ActionOptionsView.extend({ - template: Templates['issue-set-severity-form'], + template: Template, getTransition: function () { return this.model.get('severity'); diff --git a/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js b/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js index 9a3716841e0..9a688d9997a 100644 --- a/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js @@ -1,11 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; -import ActionOptionsView from 'components/common/action-options-view'; -import '../templates'; +import ActionOptionsView from '../../common/action-options-view'; +import Template from '../templates/issue-tags-form.hbs'; +import OptionTemplate from '../templates/issue-tags-form-option.hbs'; export default ActionOptionsView.extend({ - template: Templates['issue-tags-form'], - optionTemplate: Templates['issue-tags-form-option'], + template: Template, + optionTemplate: OptionTemplate, modelEvents: { 'change:tags': 'renderTags' diff --git a/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js b/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js index 80da2defc34..7af966c4149 100644 --- a/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js @@ -1,9 +1,9 @@ import $ from 'jquery'; -import ActionOptionsView from 'components/common/action-options-view'; -import '../templates'; +import ActionOptionsView from '../../common/action-options-view'; +import Template from '../templates/issue-transitions-form.hbs'; export default ActionOptionsView.extend({ - template: Templates['issue-transitions-form'], + template: Template, selectInitialOption: function () { this.makeActive(this.getOptions().first()); diff --git a/server/sonar-web/src/main/js/components/navigator/facets-view.js b/server/sonar-web/src/main/js/components/navigator/facets-view.js index 4471ca7de8b..15e8867a88d 100644 --- a/server/sonar-web/src/main/js/components/navigator/facets-view.js +++ b/server/sonar-web/src/main/js/components/navigator/facets-view.js @@ -1,5 +1,5 @@ import Marionette from 'backbone.marionette'; -import BaseFacet from 'components/navigator/facets/base-facet'; +import BaseFacet from './facets/base-facet'; export default Marionette.CollectionView.extend({ className: 'search-navigator-facets-list', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/ajax-select-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/ajax-select-filters.js index c97990b940f..0d2103ed7d7 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/ajax-select-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/ajax-select-filters.js @@ -3,7 +3,8 @@ import _ from 'underscore'; import Backbone from 'backbone'; import BaseFilters from './base-filters'; import ChoiceFilters from './choice-filters'; -import '../templates'; +import Template from '../templates/ajax-select-filter.hbs'; +import ListTemplate from '../templates/choice-filter-item.hbs'; var PAGE_SIZE = 100; @@ -98,8 +99,8 @@ var ComponentSuggestions = Suggestions.extend({ var AjaxSelectDetailsFilterView = ChoiceFilters.DetailsChoiceFilterView.extend({ - template: Templates['ajax-select-filter'], - listTemplate: Templates['choice-filter-template'], + template: Template, + listTemplate: ListTemplate, searchKey: 's', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/base-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/base-filters.js index a0d96287987..0315e847257 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/base-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/base-filters.js @@ -2,7 +2,8 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/base-filter.hbs'; +import DetailsTemplate from '../templates/base-details-filter.hbs'; var Filter = Backbone.Model.extend({ @@ -22,7 +23,7 @@ var Filters = Backbone.Collection.extend({ var DetailsFilterView = Marionette.ItemView.extend({ - template: Templates['base-details-filter'], + template: DetailsTemplate, className: 'navigator-filter-details', @@ -42,7 +43,7 @@ var DetailsFilterView = Marionette.ItemView.extend({ var BaseFilterView = Marionette.ItemView.extend({ - template: Templates['base-filter'], + template: Template, className: 'navigator-filter', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/checkbox-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/checkbox-filters.js index 08152fd9388..f13fa417d45 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/checkbox-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/checkbox-filters.js @@ -1,9 +1,9 @@ import $ from 'jquery'; import BaseFilters from './base-filters'; -import '../templates'; +import Template from '../templates/checkbox-filter.hbs'; export default BaseFilters.BaseFilterView.extend({ - template: Templates['checkbox-filter'], + template: Template, className: 'navigator-filter navigator-filter-inline', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js index e3451731d72..153cae4fc9e 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js @@ -2,11 +2,12 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; import BaseFilters from './base-filters'; -import '../templates'; +import Template from '../templates/choice-filter.hbs'; +import ItemTemplate from '../templates/choice-filter-item.hbs'; var DetailsChoiceFilterView = BaseFilters.DetailsFilterView.extend({ - template: Templates['choice-filter'], - itemTemplate: Templates['choice-filter-item'], + template: Template, + itemTemplate: ItemTemplate, events: function () { diff --git a/server/sonar-web/src/main/js/components/navigator/filters/favorite-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/favorite-filters.js index fcf16bb0f0b..99933f83da3 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/favorite-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/favorite-filters.js @@ -2,10 +2,11 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFilters from './base-filters'; import ChoiceFilters from './choice-filters'; -import '../templates'; +import Template from '../templates/favorite-filter.hbs'; +import DetailsTemplate from '../templates/favorite-details-filter.hbs'; var DetailsFavoriteFilterView = BaseFilters.DetailsFilterView.extend({ - template: Templates['favorite-details-filter'], + template: DetailsTemplate, events: { @@ -43,7 +44,7 @@ var DetailsFavoriteFilterView = BaseFilters.DetailsFilterView.extend({ var FavoriteFilterView = ChoiceFilters.ChoiceFilterView.extend({ - template: Templates['favorite-filter'], + template: Template, className: 'navigator-filter navigator-filter-favorite', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/filter-bar.js b/server/sonar-web/src/main/js/components/navigator/filters/filter-bar.js index 17419cf5042..bc01032a430 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/filter-bar.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/filter-bar.js @@ -3,7 +3,6 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import BaseFilters from './base-filters'; import MoreCriteriaFilters from './more-criteria-filters'; -import './favorite-filters'; export default Marionette.CompositeView.extend({ childViewContainer: '.navigator-filters-list', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/metric-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/metric-filters.js index 0125f3abf50..6344ab06182 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/metric-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/metric-filters.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFilters from './base-filters'; -import '../templates'; +import Template from '../templates/metric-filter.hbs'; var DetailsMetricFilterView = BaseFilters.DetailsFilterView.extend({ - template: Templates['metric-filter'], + template: Template, events: { diff --git a/server/sonar-web/src/main/js/components/navigator/filters/more-criteria-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/more-criteria-filters.js index cab8a35d67a..b83382ce979 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/more-criteria-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/more-criteria-filters.js @@ -1,10 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; import ChoiceFilters from './choice-filters'; -import '../templates'; +import Template from '../templates/more-criteria-filter.hbs'; +import DetailsTemplate from '../templates/more-criteria-details-filter.hbs'; var DetailsMoreCriteriaFilterView = ChoiceFilters.DetailsChoiceFilterView.extend({ - template: Templates['more-criteria-details-filter'], + template: DetailsTemplate, events: { @@ -56,7 +57,7 @@ var DetailsMoreCriteriaFilterView = ChoiceFilters.DetailsChoiceFilterView.extend var MoreCriteriaFilterView = ChoiceFilters.ChoiceFilterView.extend({ - template: Templates['more-criteria-filter'], + template: Template, className: 'navigator-filter navigator-filter-more-criteria', diff --git a/server/sonar-web/src/main/js/components/navigator/filters/range-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/range-filters.js index 6f5d9b7d8d0..5a24295f4fe 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/range-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/range-filters.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFilters from './base-filters'; -import '../templates'; +import Template from '../templates/range-filter.hbs'; var DetailsRangeFilterView = BaseFilters.DetailsFilterView.extend({ - template: Templates['range-filter'], + template: Template, events: { diff --git a/server/sonar-web/src/main/js/components/navigator/filters/string-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/string-filters.js index f1145c3732e..852b0cdeff5 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/string-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/string-filters.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFilters from './base-filters'; -import '../templates'; +import Template from '../templates/string-filter.hbs'; var DetailsStringFilterView = BaseFilters.DetailsFilterView.extend({ - template: Templates['string-filter'], + template: Template, events: { diff --git a/server/sonar-web/src/main/js/components/navigator/models/facets.js b/server/sonar-web/src/main/js/components/navigator/models/facets.js index 482783957b5..c9feae8422b 100644 --- a/server/sonar-web/src/main/js/components/navigator/models/facets.js +++ b/server/sonar-web/src/main/js/components/navigator/models/facets.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import Facet from 'components/navigator/models/facet'; +import Facet from './facet'; export default Backbone.Collection.extend({ model: Facet diff --git a/server/sonar-web/src/main/js/components/shared/avatar.jsx b/server/sonar-web/src/main/js/components/shared/avatar.js index 2f596bf3a0d..5060e088a00 100644 --- a/server/sonar-web/src/main/js/components/shared/avatar.jsx +++ b/server/sonar-web/src/main/js/components/shared/avatar.js @@ -1,4 +1,5 @@ import React from 'react'; +import md5 from 'blueimp-md5'; export default React.createClass({ propTypes: { @@ -11,7 +12,7 @@ export default React.createClass({ if (!shouldShowAvatar) { return null; } - const emailHash = window.md5(this.props.email || '').trim(); + const emailHash = md5.md5(this.props.email || '').trim(); const url = ('' + window.SS.lf.gravatarServerUrl) .replace('{EMAIL_MD5}', emailHash) .replace('{SIZE}', this.props.size * 2); diff --git a/server/sonar-web/src/main/js/components/shared/checkbox.jsx b/server/sonar-web/src/main/js/components/shared/checkbox.js index 633c23c8354..633c23c8354 100644 --- a/server/sonar-web/src/main/js/components/shared/checkbox.jsx +++ b/server/sonar-web/src/main/js/components/shared/checkbox.js diff --git a/server/sonar-web/src/main/js/components/shared/favorite.jsx b/server/sonar-web/src/main/js/components/shared/favorite.js index f75d03b4cb4..f75d03b4cb4 100644 --- a/server/sonar-web/src/main/js/components/shared/favorite.jsx +++ b/server/sonar-web/src/main/js/components/shared/favorite.js diff --git a/server/sonar-web/src/main/js/components/shared/list-footer.jsx b/server/sonar-web/src/main/js/components/shared/list-footer.js index 31ba9e1f0d6..31ba9e1f0d6 100644 --- a/server/sonar-web/src/main/js/components/shared/list-footer.jsx +++ b/server/sonar-web/src/main/js/components/shared/list-footer.js diff --git a/server/sonar-web/src/main/js/components/shared/pending-icon.jsx b/server/sonar-web/src/main/js/components/shared/pending-icon.js index 6749e973287..6749e973287 100644 --- a/server/sonar-web/src/main/js/components/shared/pending-icon.jsx +++ b/server/sonar-web/src/main/js/components/shared/pending-icon.js diff --git a/server/sonar-web/src/main/js/components/shared/qualifier-icon.jsx b/server/sonar-web/src/main/js/components/shared/qualifier-icon.js index e0f6e5a342d..e0f6e5a342d 100644 --- a/server/sonar-web/src/main/js/components/shared/qualifier-icon.jsx +++ b/server/sonar-web/src/main/js/components/shared/qualifier-icon.js diff --git a/server/sonar-web/src/main/js/components/shared/radio-toggle.jsx b/server/sonar-web/src/main/js/components/shared/radio-toggle.js index eca4026c69f..eca4026c69f 100644 --- a/server/sonar-web/src/main/js/components/shared/radio-toggle.jsx +++ b/server/sonar-web/src/main/js/components/shared/radio-toggle.js diff --git a/server/sonar-web/src/main/js/components/shared/severity-helper.jsx b/server/sonar-web/src/main/js/components/shared/severity-helper.js index a0e931aca2f..a0e931aca2f 100644 --- a/server/sonar-web/src/main/js/components/shared/severity-helper.jsx +++ b/server/sonar-web/src/main/js/components/shared/severity-helper.js diff --git a/server/sonar-web/src/main/js/components/shared/severity-icon.jsx b/server/sonar-web/src/main/js/components/shared/severity-icon.js index 87aec17ea7b..87aec17ea7b 100644 --- a/server/sonar-web/src/main/js/components/shared/severity-icon.jsx +++ b/server/sonar-web/src/main/js/components/shared/severity-icon.js diff --git a/server/sonar-web/src/main/js/components/shared/status-helper.jsx b/server/sonar-web/src/main/js/components/shared/status-helper.js index 033fd3ff786..033fd3ff786 100644 --- a/server/sonar-web/src/main/js/components/shared/status-helper.jsx +++ b/server/sonar-web/src/main/js/components/shared/status-helper.js diff --git a/server/sonar-web/src/main/js/components/shared/status-icon.jsx b/server/sonar-web/src/main/js/components/shared/status-icon.js index 5acd210745e..5acd210745e 100644 --- a/server/sonar-web/src/main/js/components/shared/status-icon.jsx +++ b/server/sonar-web/src/main/js/components/shared/status-icon.js diff --git a/server/sonar-web/src/main/js/components/source-viewer/header.js b/server/sonar-web/src/main/js/components/source-viewer/header.js index 5f72fb686f2..160577b115c 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/header.js +++ b/server/sonar-web/src/main/js/components/source-viewer/header.js @@ -3,12 +3,12 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import MoreActionsView from './more-actions'; import MeasuresOverlay from './measures-overlay'; -import './templates'; +import Template from './templates/source-viewer-header.hbs'; var API_FAVORITE = baseUrl + '/api/favourites'; export default Marionette.ItemView.extend({ - template: Templates['source-viewer-header'], + template: Template, events: function () { return { diff --git a/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js b/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js index 0a1537002fd..417f98663a5 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js +++ b/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js @@ -1,4 +1,5 @@ import _ from 'underscore'; +import Handlebars from 'hbsfy/runtime'; /** * Intersect two ranges @@ -113,14 +114,13 @@ function doTheStuff (code, issueLocations, optionalClassName) { } -if (typeof Handlebars !== 'undefined') { - /** - * Handlebars helper to highlight issue locations in the source code - */ - Handlebars.registerHelper('codeWithIssueLocations', function (code, issueLocations) { - return doTheStuff(code, issueLocations); - }); -} +/** + * Handlebars helper to highlight issue locations in the source code + */ +Handlebars.registerHelper('codeWithIssueLocations', function (code, issueLocations) { + return doTheStuff(code, issueLocations); +}); + export default doTheStuff; diff --git a/server/sonar-web/src/main/js/components/source-viewer/main.js b/server/sonar-web/src/main/js/components/source-viewer/main.js index 05a94e07e53..c9f553d7bd3 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/main.js +++ b/server/sonar-web/src/main/js/components/source-viewer/main.js @@ -3,22 +3,23 @@ import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import Source from './source'; -import Issues from 'components/issue/collections/issues'; -import IssueView from 'components/issue/issue-view'; +import Issues from '../issue/collections/issues'; +import IssueView from '../issue/issue-view'; import HeaderView from './header'; import SCMPopupView from './popups/scm-popup'; import CoveragePopupView from './popups/coverage-popup'; import DuplicationPopupView from './popups/duplication-popup'; import LineActionsPopupView from './popups/line-actions-popup'; import highlightLocations from './helpers/code-with-issue-locations-helper'; -import './templates'; +import Template from './templates/source-viewer.hbs'; +import IssueLocationTemplate from './templates/source-viewer-issue-location.hbs'; var HIGHLIGHTED_ROW_CLASS = 'source-line-highlighted'; export default Marionette.LayoutView.extend({ className: 'source-viewer', - template: Templates['source-viewer'], - issueLocationTemplate: Templates['source-viewer-issue-location'], + template: Template, + issueLocationTemplate: IssueLocationTemplate, ISSUES_LIMIT: 3000, LINES_LIMIT: 1000, diff --git a/server/sonar-web/src/main/js/components/source-viewer/measures-overlay.js b/server/sonar-web/src/main/js/components/source-viewer/measures-overlay.js index 7283eaa2a2e..9b071f6e1f9 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/measures-overlay.js +++ b/server/sonar-web/src/main/js/components/source-viewer/measures-overlay.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import ModalView from 'components/common/modals'; -import './templates'; +import ModalView from '../common/modals'; +import Template from './templates/source-viewer-measures.hbs'; export default ModalView.extend({ - template: Templates['source-viewer-measures'], + template: Template, testsOrder: ['ERROR', 'FAILURE', 'OK', 'SKIPPED'], initialize: function () { diff --git a/server/sonar-web/src/main/js/components/source-viewer/more-actions.js b/server/sonar-web/src/main/js/components/source-viewer/more-actions.js index 93704f062a7..0c633afcfdb 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/more-actions.js +++ b/server/sonar-web/src/main/js/components/source-viewer/more-actions.js @@ -1,12 +1,12 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import Workspace from 'components/workspace/main'; -import './templates'; +import Workspace from '../workspace/main'; +import Template from './templates/source-viewer-more-actions.hbs'; export default Marionette.ItemView.extend({ className: 'source-viewer-header-more-actions', - template: Templates['source-viewer-more-actions'], + template: Template, events: { 'click .js-measures': 'showMeasures', @@ -33,8 +33,7 @@ export default Marionette.ItemView.extend({ openInWorkspace: function () { var uuid = this.options.parent.model.id; - var RealWorkspace = Workspace.openComponent ? Workspace : require('components/workspace/main'); - RealWorkspace.openComponent({ uuid: uuid }); + Workspace.openComponent({ uuid: uuid }); }, showRawSource: function () { diff --git a/server/sonar-web/src/main/js/components/source-viewer/popups/coverage-popup.js b/server/sonar-web/src/main/js/components/source-viewer/popups/coverage-popup.js index 9e3e0993ec4..1f712bdf4be 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/popups/coverage-popup.js +++ b/server/sonar-web/src/main/js/components/source-viewer/popups/coverage-popup.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import Popup from 'components/common/popup'; -import Workspace from 'components/workspace/main'; -import '../templates'; +import Popup from '../../common/popup'; +import Workspace from '../../workspace/main'; +import Template from '../templates/source-viewer-coverage-popup.hbs'; export default Popup.extend({ - template: Templates['source-viewer-coverage-popup'], + template: Template, events: { 'click a[data-uuid]': 'goToFile' @@ -19,8 +19,7 @@ export default Popup.extend({ goToFile: function (e) { e.stopPropagation(); var uuid = $(e.currentTarget).data('uuid'); - var RealWorkspace = Workspace.openComponent ? Workspace : require('components/workspace/main'); - RealWorkspace.openComponent({ uuid: uuid }); + Workspace.openComponent({ uuid: uuid }); }, serializeData: function () { diff --git a/server/sonar-web/src/main/js/components/source-viewer/popups/duplication-popup.js b/server/sonar-web/src/main/js/components/source-viewer/popups/duplication-popup.js index 4d62ee40eb0..1220e736b96 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/popups/duplication-popup.js +++ b/server/sonar-web/src/main/js/components/source-viewer/popups/duplication-popup.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import _ from 'underscore'; -import Popup from 'components/common/popup'; -import Workspace from 'components/workspace/main'; -import '../templates'; +import Popup from '../../common/popup'; +import Workspace from '../../workspace/main'; +import Template from '../templates/source-viewer-duplication-popup.hbs'; export default Popup.extend({ - template: Templates['source-viewer-duplication-popup'], + template: Template, events: { 'click a[data-uuid]': 'goToFile' @@ -15,8 +15,7 @@ export default Popup.extend({ e.stopPropagation(); var uuid = $(e.currentTarget).data('uuid'), line = $(e.currentTarget).data('line'); - var RealWorkspace = Workspace.openComponent ? Workspace : require('components/workspace/main'); - RealWorkspace.openComponent({ uuid: uuid, line: line }); + Workspace.openComponent({ uuid: uuid, line: line }); }, serializeData: function () { diff --git a/server/sonar-web/src/main/js/components/source-viewer/popups/line-actions-popup.js b/server/sonar-web/src/main/js/components/source-viewer/popups/line-actions-popup.js index dc9be5637e0..961faebcbf0 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/popups/line-actions-popup.js +++ b/server/sonar-web/src/main/js/components/source-viewer/popups/line-actions-popup.js @@ -1,9 +1,9 @@ -import Popup from 'components/common/popup'; -import ManualIssueView from 'components/issue/manual-issue-view'; -import '../templates'; +import Popup from '../../common/popup'; +import ManualIssueView from '../../issue/manual-issue-view'; +import Template from '../templates/source-viewer-line-options-popup.hbs'; export default Popup.extend({ - template: Templates['source-viewer-line-options-popup'], + template: Template, events: { 'click .js-get-permalink': 'getPermalink', diff --git a/server/sonar-web/src/main/js/components/source-viewer/popups/scm-popup.js b/server/sonar-web/src/main/js/components/source-viewer/popups/scm-popup.js index d229f2e9d57..95e45483c2a 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/popups/scm-popup.js +++ b/server/sonar-web/src/main/js/components/source-viewer/popups/scm-popup.js @@ -1,8 +1,8 @@ -import Popup from 'components/common/popup'; -import '../templates'; +import Popup from '../../common/popup'; +import Template from '../templates/source-viewer-scm-popup.hbs'; export default Popup.extend({ - template: Templates['source-viewer-scm-popup'], + template: Template, events: { 'click': 'onClick' diff --git a/server/sonar-web/src/main/js/components/workspace/views/item-view.js b/server/sonar-web/src/main/js/components/workspace/views/item-view.js index c307e69916d..a72c1a847ab 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/item-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/item-view.js @@ -1,10 +1,10 @@ import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/workspace-item.hbs'; export default Marionette.ItemView.extend({ tagName: 'li', className: 'workspace-nav-item', - template: Templates['workspace-item'], + template: Template, modelEvents: { 'change': 'render', diff --git a/server/sonar-web/src/main/js/components/workspace/views/items-view.js b/server/sonar-web/src/main/js/components/workspace/views/items-view.js index c244ff9c450..d156a765c77 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/items-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/items-view.js @@ -1,10 +1,10 @@ import Marionette from 'backbone.marionette'; import ItemView from './item-view'; -import '../templates'; +import Template from '../templates/workspace-items.hbs'; export default Marionette.CompositeView.extend({ className: 'workspace-nav', - template: Templates['workspace-items'], + template: Template, childViewContainer: '.workspace-nav-list', childView: ItemView, diff --git a/server/sonar-web/src/main/js/components/workspace/views/rule-view.js b/server/sonar-web/src/main/js/components/workspace/views/rule-view.js index 6b3fd957638..a13165db550 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/rule-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/rule-view.js @@ -1,10 +1,10 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import BaseView from './base-viewer-view'; -import '../templates'; +import Template from '../templates/workspace-rule.hbs'; export default BaseView.extend({ - template: Templates['workspace-rule'], + template: Template, onRender: function () { BaseView.prototype.onRender.apply(this, arguments); diff --git a/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js b/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js index b0c03b77edd..9ed91fb6a13 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js @@ -1,10 +1,10 @@ import $ from 'jquery'; import _ from 'underscore'; import Marionette from 'backbone.marionette'; -import '../templates'; +import Template from '../templates/workspace-viewer-header.hbs'; export default Marionette.ItemView.extend({ - template: Templates['workspace-viewer-header'], + template: Template, modelEvents: { 'change': 'render' diff --git a/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js b/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js index c335411693e..6e7699d68fd 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js @@ -1,9 +1,9 @@ import BaseView from './base-viewer-view'; -import SourceViewer from 'components/source-viewer/main'; -import '../templates'; +import SourceViewer from '../../source-viewer/main'; +import Template from '../templates/workspace-viewer.hbs'; export default BaseView.extend({ - template: Templates['workspace-viewer'], + template: Template, onRender: function () { BaseView.prototype.onRender.apply(this, arguments); @@ -11,9 +11,8 @@ export default BaseView.extend({ }, showViewer: function () { - var RealSourceViewer = SourceViewer.on ? SourceViewer : require('components/source-viewer/main'); var that = this, - viewer = new RealSourceViewer(), + viewer = new SourceViewer(), options = this.model.toJSON(); viewer.open(this.model.get('uuid'), { workspace: true }); viewer.on('loaded', function () { diff --git a/server/sonar-web/src/main/js/helpers/Url.jsx b/server/sonar-web/src/main/js/helpers/Url.js index 7fa21b44f0f..7fa21b44f0f 100644 --- a/server/sonar-web/src/main/js/helpers/Url.jsx +++ b/server/sonar-web/src/main/js/helpers/Url.js diff --git a/server/sonar-web/src/main/js/helpers/csv.js b/server/sonar-web/src/main/js/helpers/csv.js new file mode 100644 index 00000000000..f92c08443f6 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/csv.js @@ -0,0 +1,4 @@ +export function csvEscape (value) { + var escaped = value.replace(/"/g, '\\"'); + return '"' + escaped + '"'; +} diff --git a/server/sonar-web/src/main/js/helpers/handlebars-helpers.js b/server/sonar-web/src/main/js/helpers/handlebars-helpers.js new file mode 100644 index 00000000000..08058a70e03 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/handlebars-helpers.js @@ -0,0 +1,593 @@ +import _ from 'underscore'; +import Handlebars from 'hbsfy/runtime'; +import md5 from 'blueimp-md5'; + +var defaultActions = ['comment', 'assign', 'assign_to_me', 'plan', 'set_severity', 'set_tags']; + +Handlebars.registerHelper('log', function () { + /* eslint no-console: 0 */ + var args = Array.prototype.slice.call(arguments, 0, -1); + console.log.apply(console, args); +}); + +Handlebars.registerHelper('link', function () { + var url = Array.prototype.slice.call(arguments, 0, -1).join(''); + return baseUrl + url; +}); + +Handlebars.registerHelper('componentPermalink', function (componentKey) { + return baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey); +}); + +Handlebars.registerHelper('componentDashboardPermalink', function (componentKey, dashboardKey) { + var params = [ + { key: 'id', value: componentKey }, + { key: 'did', value: dashboardKey } + ]; + + var matchPeriod = window.location.search.match(/period=(\d+)/); + if (matchPeriod) { + // If we have a match for period, check that it is not project-specific + var period = parseInt(matchPeriod[1], 10); + if (period <= 3) { + params.push({ key: 'period', value: period }); + } + } + + var query = params.map(function (p) { + return p.key + '=' + encodeURIComponent(p.value); + }).join('&'); + return baseUrl + '/dashboard/index?' + query; +}); + +Handlebars.registerHelper('componentBrowsePermalink', function (componentKey) { + return baseUrl + '/components/index?id=' + encodeURIComponent(componentKey); +}); + +Handlebars.registerHelper('componentIssuesPermalink', function (componentKey) { + return baseUrl + '/component_issues/index?id=' + encodeURIComponent(componentKey); +}); + +Handlebars.registerHelper('rulePermalink', function (ruleKey) { + return baseUrl + '/coding_rules#rule_key=' + encodeURIComponent(ruleKey); +}); + +Handlebars.registerHelper('isActiveLink', function () { + var args = Array.prototype.slice.call(arguments, 0, -1), + options = arguments[arguments.length - 1], + prefix = args.join(''), + path = window.location.pathname, + match = path.indexOf(baseUrl + prefix) === 0; + return match ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('capitalize', function (string) { + return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); +}); + +Handlebars.registerHelper('severityIcon', function (severity) { + return new Handlebars.SafeString( + '<i class="icon-severity-' + severity.toLowerCase() + '"></i>' + ); +}); + +Handlebars.registerHelper('severityHelper', function (severity) { + return new Handlebars.SafeString( + '<i class="icon-severity-' + severity.toLowerCase() + '"></i> ' + t('severity', severity) + ); +}); + +Handlebars.registerHelper('statusIcon', function (status) { + return new Handlebars.SafeString( + '<i class="icon-status-' + status.toLowerCase() + '"></i>' + ); +}); + +Handlebars.registerHelper('statusHelper', function (status, resolution) { + var s = '<i class="icon-status-' + status.toLowerCase() + '"></i> ' + t('issue.status', status); + if (resolution != null) { + s = s + ' (' + t('issue.resolution', resolution) + ')'; + } + return new Handlebars.SafeString(s); +}); + +Handlebars.registerHelper('testStatusIcon', function (status) { + return new Handlebars.SafeString( + '<i class="icon-test-status-' + status.toLowerCase() + '"></i>' + ); +}); + +Handlebars.registerHelper('testStatusIconClass', function (status) { + return new Handlebars.SafeString('' + + 'icon-test-status-' + status.toLowerCase() + ); +}); + +Handlebars.registerHelper('alertIconClass', function (alert) { + return new Handlebars.SafeString( + 'icon-alert-' + alert.toLowerCase() + ); +}); + +Handlebars.registerHelper('qualifierIcon', function (qualifier) { + return new Handlebars.SafeString( + qualifier ? '<i class="icon-qualifier-' + qualifier.toLowerCase() + '"></i>' : '' + ); +}); + +Handlebars.registerHelper('default', function () { + var args = Array.prototype.slice.call(arguments, 0, -1); + return args.reduce(function (prev, current) { + return prev != null ? prev : current; + }, null); +}); + +Handlebars.registerHelper('show', function () { + var args = Array.prototype.slice.call(arguments), + ret = null; + args.forEach(function (arg) { + if (typeof arg === 'string' && ret == null) { + ret = arg; + } + }); + return ret || ''; +}); + +Handlebars.registerHelper('percent', function (value, total) { + if (total > 0) { + return '' + ((value || 0) / total * 100) + '%'; + } else { + return '0%'; + } +}); + +Handlebars.registerHelper('eachIndex', function (context, options) { + var ret = ''; + context.forEach(function (d, i) { + var c = _.extend({ index: i }, d); + ret += options.fn(c); + }); + return ret; +}); + +Handlebars.registerHelper('eachChanged', function (context, property, options) { + var ret = ''; + context.forEach(function (d, i) { + var changed = i > 0 ? d[property] !== context[i - 1][property] : true, + c = _.extend({ changed: changed }, d); + ret += options.fn(c); + }); + return ret; +}); + +Handlebars.registerHelper('eachEven', function (context, options) { + var ret = ''; + context.forEach(function (d, i) { + if (i % 2 === 0) { + ret += options.fn(d); + } + }); + return ret; +}); + +Handlebars.registerHelper('eachOdd', function (context, options) { + var ret = ''; + context.forEach(function (d, i) { + if (i % 2 === 1) { + ret += options.fn(d); + } + }); + return ret; +}); + +Handlebars.registerHelper('eq', function (v1, v2, options) { + /* eslint eqeqeq: 0 */ + return v1 == v2 ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('notEq', function (v1, v2, options) { + /* eslint eqeqeq: 0 */ + return v1 != v2 ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('gt', function (v1, v2, options) { + return v1 > v2 ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('lt', function (v1, v2, options) { + return v1 < v2 ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('notNull', function (value, options) { + return value != null ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('isNull', function (value, options) { + return value == null ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('notEmpty', function (array, options) { + var cond = _.isArray(array) && array.length > 0; + return cond ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('empty', function (array, options) { + var cond = _.isArray(array) && array.length > 0; + return cond ? options.inverse(this) : options.fn(this); +}); + +Handlebars.registerHelper('all', function () { + var args = Array.prototype.slice.call(arguments, 0, -1), + options = arguments[arguments.length - 1], + all = args.reduce(function (prev, current) { + return prev && current; + }, true); + return all ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('any', function () { + var args = Array.prototype.slice.call(arguments, 0, -1), + options = arguments[arguments.length - 1], + any = args.reduce(function (prev, current) { + return prev || current; + }, false); + return any ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('inArray', function (array, element, options) { + if (_.isArray(array)) { + if (array.indexOf(element) !== -1) { + return options.fn(this); + } else { + return options.inverse(this); + } + } +}); + +Handlebars.registerHelper('ifNotEmpty', function () { + var args = Array.prototype.slice.call(arguments, 0, -1), + options = arguments[arguments.length - 1], + notEmpty = args.reduce(function (prev, current) { + return prev || (current && current.length > 0); + }, false); + return notEmpty ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('join', function (array, separator) { + return array.join(separator); +}); + +Handlebars.registerHelper('ifLength', function (array, len, options) { + var cond = _.isArray(array) && array.length === +len; + return cond ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('unlessLength', function (array, len, options) { + var cond = _.isArray(array) && array.length === +len; + return cond ? options.inverse(this) : options.fn(this); +}); + +Handlebars.registerHelper('eachReverse', function (array, options) { + var ret = ''; + + if (array && array.length > 0) { + for (var i = array.length - 1; i >= 0; i--) { + ret += options.fn(array[i]); + } + } else { + ret = options.inverse(this); + } + + return ret; +}); + +Handlebars.registerHelper('joinEach', function (array, separator, options) { + var ret = ''; + + if (array && array.length > 0) { + for (var i = 0, n = array.length; i < n; i++) { + ret += options.fn(array[i]); + if (i < n - 1) { + ret += separator; + } + } + } else { + ret = options.inverse(this); + } + + return ret; +}); + +Handlebars.registerHelper('sum', function () { + var args = Array.prototype.slice.call(arguments, 0, -1); + return args.reduce(function (p, c) { + return p + +c; + }, 0); +}); + +Handlebars.registerHelper('dashboardUrl', function (componentKey, componentQualifier) { + var url = baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey); + if (componentQualifier === 'FIL' || componentQualifier === 'CLA') { + url += '&metric=sqale_index'; + } + return url; +}); + +Handlebars.registerHelper('translate', function () { + var args = Array.prototype.slice.call(arguments, 0, -1); + return window.translate.apply(this, args); +}); + +Handlebars.registerHelper('t', function () { + var args = Array.prototype.slice.call(arguments, 0, -1); + return window.t.apply(this, args); +}); + +Handlebars.registerHelper('tp', function () { + var args = Array.prototype.slice.call(arguments, 0, -1); + return window.tp.apply(this, args); +}); + +Handlebars.registerHelper('d', function (date) { + return moment(date).format('LL'); +}); + +Handlebars.registerHelper('dt', function (date) { + return moment(date).format('LLL'); +}); + +Handlebars.registerHelper('ds', function (date) { + return moment(date).format('YYYY-MM-DD'); +}); + +Handlebars.registerHelper('fromNow', function (date) { + return moment(date).fromNow(); +}); + +Handlebars.registerHelper('durationFromNow', function (date, units) { + return moment(new Date()).diff(date, units); +}); + +Handlebars.registerHelper('numberShort', function (number) { + var format = '0,0'; + if (number >= 10000) { + format = '0.[0]a'; + } + if (number >= 100000) { + format = '0a'; + } + return numeral(number).format(format); +}); + +Handlebars.registerHelper('pluginActions', function (actions, options) { + var pluginActions = _.difference(actions, defaultActions); + return pluginActions.reduce(function (prev, current) { + return prev + options.fn(current); + }, ''); +}); + +Handlebars.registerHelper('ifHasExtraActions', function (actions, options) { + var actionsLeft = _.difference(actions, defaultActions); + if (actionsLeft.length > 0) { + return options.fn(this); + } else { + return options.inverse(this); + } +}); + +Handlebars.registerHelper('withFirst', function (list, options) { + if (list && list.length > 0) { + return options.fn(list[0]); + } else { + return ''; + } +}); + +Handlebars.registerHelper('withLast', function (list, options) { + if (list && list.length > 0) { + return options.fn(list[list.length - 1]); + } else { + return ''; + } +}); + +Handlebars.registerHelper('withoutFirst', function (list, options) { + if (list && list.length > 1) { + return list.slice(1).reduce(function (prev, current) { + return prev + options.fn(current); + }, ''); + } else { + return ''; + } +}); + +var audaciousFn; +Handlebars.registerHelper('recursive', function (children, options) { + var out = ''; + + if (options.fn !== undefined) { + audaciousFn = options.fn; + } + + children.forEach(function (child) { + out = out + audaciousFn(child); + }); + + return out; +}); + +Handlebars.registerHelper('sources', function (source, scm, options) { + if (options == null) { + options = scm; + scm = null; + } + + var sources = _.map(source, function (code, line) { + return { + lineNumber: line, + code: code, + scm: (scm && scm[line]) ? { author: scm[line][0], date: scm[line][1] } : undefined + }; + }); + + return sources.reduce(function (prev, current, index) { + return prev + options.fn(_.extend({ first: index === 0 }, current)); + }, ''); +}); + +Handlebars.registerHelper('operators', function (options) { + var ops = ['LT', 'GT', 'EQ', 'NE']; + + return ops.reduce(function (prev, current) { + return prev + options.fn(current); + }, ''); +}); + +Handlebars.registerHelper('changelog', function (diff) { + var message = ''; + if (diff.newValue != null) { + message = tp('issue.changelog.changed_to', t('issue.changelog.field', diff.key), diff.newValue); + } else { + message = tp('issue.changelog.removed', t('issue.changelog.field', diff.key)); + } + if (diff.oldValue != null) { + message += ' ('; + message += tp('issue.changelog.was', diff.oldValue); + message += ')'; + } + return message; +}); + +Handlebars.registerHelper('ifMeasureShouldBeShown', function (measure, period, options) { + if (measure != null || period != null) { + return options.fn(this); + } else { + return options.inverse(this); + } +}); + +Handlebars.registerHelper('ifSCMChanged', function (source, line, options) { + var currentLine = _.findWhere(source, { lineNumber: line }), + prevLine = _.findWhere(source, { lineNumber: line - 1 }), + changed = true; + if (currentLine && prevLine && currentLine.scm && prevLine.scm) { + changed = (currentLine.scm.author !== prevLine.scm.author) || + (currentLine.scm.date !== prevLine.scm.date) || (!prevLine.show); + } + return changed ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('ifSCMChanged2', function (source, line, options) { + var currentLine = _.findWhere(source, { line: line }), + prevLine = _.findWhere(source, { line: line - 1 }), + changed = true; + if (currentLine && prevLine && currentLine.scmAuthor && prevLine.scmAuthor) { + changed = (currentLine.scmAuthor !== prevLine.scmAuthor) || (currentLine.scmDate !== prevLine.scmDate); + } + return changed ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('ifTestData', function (test, options) { + if ((test.status !== 'OK') || ((test.status === 'OK') && test.coveredLines)) { + return options.fn(this); + } else { + return options.inverse(this); + } +}); + +Handlebars.registerHelper('eqComponents', function (a, b, options) { + var notEq = a && b && ((a.project !== b.project) || (a.subProject !== b.subProject)); + return notEq ? options.inverse(this) : options.fn(this); +}); + +Handlebars.registerHelper('notEqComponents', function (a, b, options) { + var notEq = a && b && ((a.project !== b.project) || (a.subProject !== b.subProject)); + return notEq ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('projectFullName', function (component) { + return component.projectName + (component.subProjectName ? (' / ' + component.subProjectName) : ''); +}); + +Handlebars.registerHelper('dirFromPath', function (path) { + if (typeof path === 'string') { + var tokens = path.split('/'); + return tokens.length > 1 ? _.initial(tokens).join('/') + '/' : ''; + } else { + return null; + } +}); + +Handlebars.registerHelper('collapsedDirFromPath', function (path) { + return window.collapsedDirFromPath(path); +}); + +Handlebars.registerHelper('fileFromPath', function (path) { + return window.fileFromPath(path); +}); + +Handlebars.registerHelper('repeat', function (number, options) { + var ret = ''; + for (var i = 0; i < number; i++) { + ret += options.fn(this); + } + return ret; +}); + +Handlebars.registerHelper('limitString', function (str) { + if (typeof str === 'string') { + var LIMIT = 30; + return str.length > LIMIT ? str.substr(0, LIMIT) + '...' : str; + } +}); + +Handlebars.registerHelper('withSign', function (number) { + return number >= 0 ? '+' + number : '' + number; +}); + +Handlebars.registerHelper('formatMeasure', function (measure, type) { + return window.formatMeasure(measure, type); +}); + +Handlebars.registerHelper('formatMeasureVariation', function (measure, type) { + return window.formatMeasureVariation(measure, type); +}); + +Handlebars.registerHelper('dashboardL10n', function (dashboardName) { + var l10nKey = 'dashboard.' + dashboardName + '.name'; + var l10nLabel = window.t(l10nKey); + if (l10nLabel !== l10nKey) { + return l10nLabel; + } else { + return dashboardName; + } +}); + +Handlebars.registerHelper('ifShowAvatars', function (options) { + var cond = window.SS && window.SS.lf && window.SS.lf.enableGravatar; + return cond ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('avatarHelper', function (email, size) { + // double the size for high pixel density screens + var emailHash = md5.md5((email || '').trim()), + url = ('' + window.SS.lf.gravatarServerUrl) + .replace('{EMAIL_MD5}', emailHash) + .replace('{SIZE}', size * 2); + return new Handlebars.SafeString( + '<img class="rounded" src="' + url + '" width="' + size + '" height="' + size + '" alt="' + email + '">' + ); +}); + +Handlebars.registerHelper('ifCanUseFilter', function (query, options) { + var cond = window.SS.user || query.indexOf('__me__') === -1; + return cond ? options.fn(this) : options.inverse(this); +}); + +Handlebars.registerHelper('length', function (array) { + return _.size(array); +}); + +Handlebars.registerHelper('ifLengthGT', function (array, len, options) { + return _.size(array) > len ? options.fn(this) : options.inverse(this); +}); diff --git a/server/sonar-web/src/main/js/helpers/latinize.js b/server/sonar-web/src/main/js/helpers/latinize.js new file mode 100644 index 00000000000..48ddda4b309 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/latinize.js @@ -0,0 +1,367 @@ +/* + * Latinize string by removing all diacritics + * From http://stackoverflow.com/questions/990904/javascript-remove-accents-in-strings + */ +var defaultDiacriticsRemovalap = [ + { + 'base': 'A', + 'letters': '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F' + }, + { + 'base': 'AA', + 'letters': '\uA732' + }, + { + 'base': 'AE', + 'letters': '\u00C6\u01FC\u01E2' + }, + { + 'base': 'AO', + 'letters': '\uA734' + }, + { + 'base': 'AU', + 'letters': '\uA736' + }, + { + 'base': 'AV', + 'letters': '\uA738\uA73A' + }, + { + 'base': 'AY', + 'letters': '\uA73C' + }, + { + 'base': 'B', + 'letters': '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' + }, + { + 'base': 'C', + 'letters': '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' + }, + { + 'base': 'D', + 'letters': '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' + }, + { + 'base': 'DZ', + 'letters': '\u01F1\u01C4' + }, + { + 'base': 'Dz', + 'letters': '\u01F2\u01C5' + }, + { + 'base': 'E', + 'letters': '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E' + }, + { + 'base': 'F', + 'letters': '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' + }, + { + 'base': 'G', + 'letters': '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' + }, + { + 'base': 'H', + 'letters': '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' + }, + { + 'base': 'I', + 'letters': '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' + }, + { + 'base': 'J', + 'letters': '\u004A\u24BF\uFF2A\u0134\u0248' + }, + { + 'base': 'K', + 'letters': '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' + }, + { + 'base': 'L', + 'letters': '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' + }, + { + 'base': 'LJ', + 'letters': '\u01C7' + }, + { + 'base': 'Lj', + 'letters': '\u01C8' + }, + { + 'base': 'M', + 'letters': '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' + }, + { + 'base': 'N', + 'letters': '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' + }, + { + 'base': 'NJ', + 'letters': '\u01CA' + }, + { + 'base': 'Nj', + 'letters': '\u01CB' + }, + { + 'base': 'O', + 'letters': '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C' + }, + { + 'base': 'OI', + 'letters': '\u01A2' + }, + { + 'base': 'OO', + 'letters': '\uA74E' + }, + { + 'base': 'OU', + 'letters': '\u0222' + }, + { + 'base': 'OE', + 'letters': '\u008C\u0152' + }, + { + 'base': 'oe', + 'letters': '\u009C\u0153' + }, + { + 'base': 'P', + 'letters': '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' + }, + { + 'base': 'Q', + 'letters': '\u0051\u24C6\uFF31\uA756\uA758\u024A' + }, + { + 'base': 'R', + 'letters': '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' + }, + { + 'base': 'S', + 'letters': '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' + }, + { + 'base': 'T', + 'letters': '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' + }, + { + 'base': 'TZ', + 'letters': '\uA728' + }, + { + 'base': 'U', + 'letters': '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244' + }, + { + 'base': 'V', + 'letters': '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' + }, + { + 'base': 'VY', + 'letters': '\uA760' + }, + { + 'base': 'W', + 'letters': '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' + }, + { + 'base': 'X', + 'letters': '\u0058\u24CD\uFF38\u1E8A\u1E8C' + }, + { + 'base': 'Y', + 'letters': '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' + }, + { + 'base': 'Z', + 'letters': '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' + }, + { + 'base': 'a', + 'letters': '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250' + }, + { + 'base': 'aa', + 'letters': '\uA733' + }, + { + 'base': 'ae', + 'letters': '\u00E6\u01FD\u01E3' + }, + { + 'base': 'ao', + 'letters': '\uA735' + }, + { + 'base': 'au', + 'letters': '\uA737' + }, + { + 'base': 'av', + 'letters': '\uA739\uA73B' + }, + { + 'base': 'ay', + 'letters': '\uA73D' + }, + { + 'base': 'b', + 'letters': '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' + }, + { + 'base': 'c', + 'letters': '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' + }, + { + 'base': 'd', + 'letters': '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' + }, + { + 'base': 'dz', + 'letters': '\u01F3\u01C6' + }, + { + 'base': 'e', + 'letters': '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD' + }, + { + 'base': 'f', + 'letters': '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' + }, + { + 'base': 'g', + 'letters': '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' + }, + { + 'base': 'h', + 'letters': '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' + }, + { + 'base': 'hv', + 'letters': '\u0195' + }, + { + 'base': 'i', + 'letters': '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' + }, + { + 'base': 'j', + 'letters': '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' + }, + { + 'base': 'k', + 'letters': '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' + }, + { + 'base': 'l', + 'letters': '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' + }, + { + 'base': 'lj', + 'letters': '\u01C9' + }, + { + 'base': 'm', + 'letters': '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' + }, + { + 'base': 'n', + 'letters': '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' + }, + { + 'base': 'nj', + 'letters': '\u01CC' + }, + { + 'base': 'o', + 'letters': '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275' + }, + { + 'base': 'oi', + 'letters': '\u01A3' + }, + { + 'base': 'ou', + 'letters': '\u0223' + }, + { + 'base': 'oo', + 'letters': '\uA74F' + }, + { + 'base': 'p', + 'letters': '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' + }, + { + 'base': 'q', + 'letters': '\u0071\u24E0\uFF51\u024B\uA757\uA759' + }, + { + 'base': 'r', + 'letters': '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' + }, + { + 'base': 's', + 'letters': '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' + }, + { + 'base': 't', + 'letters': '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' + }, + { + 'base': 'tz', + 'letters': '\uA729' + }, + { + 'base': 'u', + 'letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289' + }, + { + 'base': 'v', + 'letters': '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' + }, + { + 'base': 'vy', + 'letters': '\uA761' + }, + { + 'base': 'w', + 'letters': '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' + }, + { + 'base': 'x', + 'letters': '\u0078\u24E7\uFF58\u1E8B\u1E8D' + }, + { + 'base': 'y', + 'letters': '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' + }, + { + 'base': 'z', + 'letters': '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' + } +]; + +var diacriticsMap = {}; +for (var i = 0; i < defaultDiacriticsRemovalap.length; i++) { + var letters = defaultDiacriticsRemovalap[i].letters.split(''); + for (var j = 0; j < letters.length; j++) { + diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base; + } +} + +// "what?" version ... http://jsperf.com/diacritics/12 +function removeDiacritics (str) { + return str.replace(/[^\u0000-\u007E]/g, function (a) { + return diacriticsMap[a] || a; + }); +} + +export default removeDiacritics; diff --git a/server/sonar-web/src/main/js/helpers/request.js b/server/sonar-web/src/main/js/helpers/request.js new file mode 100644 index 00000000000..74a5eaaf3bc --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/request.js @@ -0,0 +1,115 @@ +import _ from 'underscore'; + +/** + * Default options for any request + * @type {{credentials: string}} + */ +const OPTIONS = { + type: 'GET', + credentials: 'same-origin' +}; + + +/** + * Default request headers + * @type {{Accept: string}} + */ +const HEADERS = { + 'Accept': 'application/json' +}; + + +/** + * Create a query string from an object + * @param {object} parameters + * @returns {string} + */ +function queryString (parameters) { + return Object.keys(parameters) + .map(key => { + return `${encodeURIComponent(key)}=${encodeURIComponent(parameters[key])}`; + }) + .join('&'); +} + + +/** + * Request + */ +class Request { + constructor (url) { + this.url = url; + this.options = {}; + this.headers = {}; + } + + submit () { + let url = this.url; + let options = _.defaults(this.options, OPTIONS); + let headers = _.defaults(this.headers, HEADERS); + options.headers = headers; + if (this.data) { + if (options.type === 'GET') { + url += '?' + queryString(this.data); + } else { + options.body = queryString(this.data); + } + } + return window.fetch(url, options); + } + + setData (data) { + this.data = data; + return this; + } +} + + +/** + * Make a request + * @param {string} url + * @returns {Request} + */ +export function request (url) { + return new Request(url); +} + + +/** + * Check that response status is ok + * @param response + * @returns {*} + */ +export function checkStatus (response) { + if (response.status >= 200 && response.status < 300) { + return response; + } else { + var error = new Error(response.status); + error.response = response; + throw error; + } +} + + +/** + * Parse response as JSON + * @param response + * @returns {object} + */ +export function parseJSON (response) { + return response.json(); +} + + +/** + * Shortcut to do a GET request and return response json + * @param url + * @param data + */ +export function getJSON (url, data) { + return request(url) + .setData(data) + .submit() + .then(checkStatus) + .then(parseJSON); +}
\ No newline at end of file diff --git a/server/sonar-web/src/main/js/libs/application.js b/server/sonar-web/src/main/js/libs/application.js index 7982910f9ad..255af4f496c 100644 --- a/server/sonar-web/src/main/js/libs/application.js +++ b/server/sonar-web/src/main/js/libs/application.js @@ -631,20 +631,6 @@ function closeModalWindow () { return params; }; - - /** - * Return an md5 hash of a string - * @param s - * @returns {*} - */ - window.getMD5Hash = function (s) { - if (typeof s === 'string') { - return window.md5(s.trim()); - } else { - return null; - } - }; - })(); (function () { diff --git a/server/sonar-web/src/main/js/libs/csv.js b/server/sonar-web/src/main/js/libs/csv.js deleted file mode 100644 index fcca34e796b..00000000000 --- a/server/sonar-web/src/main/js/libs/csv.js +++ /dev/null @@ -1,8 +0,0 @@ -(function() { - - window.csvEscape = function(value) { - var escaped = value.replace(/"/g, '\\"'); - return '"' + escaped + '"'; - }; - -})(); diff --git a/server/sonar-web/src/main/js/libs/dashboard.js b/server/sonar-web/src/main/js/libs/dashboard.js deleted file mode 100644 index 231c5f4239e..00000000000 --- a/server/sonar-web/src/main/js/libs/dashboard.js +++ /dev/null @@ -1,156 +0,0 @@ -(function($) { - - window.Portal = function(options) { - this.initialize(options); - }; - - window.Portal.prototype = { - - initialize: function(options) { - this.options = options; - if (!this.options.editorEnabled) { - return; - } - this.createAllSortables(); - this.lastSaveString = ''; - this.saveDashboardsState(); - }, - - - createAllSortables: function() { - var that = this, - blocks = $('.' + this.options.block), - columnHandle = $('.' + this.options.columnHandle), - draggable, - - onDragLeave = function(e) { - $(e.currentTarget).removeClass(that.options.hoverClass); - }, - - onDrop = function(e) { - e.preventDefault(); - draggable.detach().insertBefore($(e.currentTarget)); - onDragLeave(e); - that.saveDashboardsState(); - }; - - blocks - .prop('draggable', true) - .on('selectstart', function() { - this.dragDrop(); - return false; - }) - .on('dragstart', function(e) { - e.originalEvent.dataTransfer.setData('Text', 'drag'); - draggable = $(this); - columnHandle.show(); - }) - .on('dragover', function(e) { - if (draggable.prop('id') !== $(this).prop('id')) { - e.preventDefault(); - $(e.currentTarget).addClass(that.options.hoverClass); - } - }) - .on('drop', onDrop) - .on('dragleave', onDragLeave); - - columnHandle - .on('dragover', function(e) { - e.preventDefault(); - $(e.currentTarget).addClass(that.options.hoverClass); - }) - .on('drop', onDrop) - .on('dragleave', onDragLeave); - }, - - - highlightWidget: function(widgetId) { - var block = $('#block_' + widgetId), - options = this.options; - block.css('background-color', options.highlightStartColor); - setTimeout(function() { - block.css('background-color', options.highlightEndColor); - }, this.options.highlightDuration); - }, - - - saveDashboardsState: function() { - var options = this.options, - result = $('.' + this.options.column).map(function () { - var blocks = $(this).find('.' + options.block); - $(this).find('.' + options.columnHandle).toggle(blocks.length === 0); - - return blocks.map(function () { - return $(this).prop('id').substring(options.block.length + 1); - }).get().join(','); - }).get().join(';'); - - if (result === this.lastSaveString) { - return; - } - - var firstTime = this.lastSaveString === ''; - this.lastSaveString = result; - - if (firstTime) { - return; - } - - if (this.options.saveUrl) { - var postBody = this.options.dashboardState + '=' + encodeURIComponent(result); - - $.ajax({ - url: this.options.saveUrl, - type: 'POST', - data: postBody - }); - } - }, - - - editWidget: function(widgetId) { - $('#widget_title_' + widgetId).hide(); - $('#widget_' + widgetId).hide(); - $('#widget_props_' + widgetId).show(); - $($('#block_' + widgetId + ' a.link-action')[0]).hide(); - }, - - - cancelEditWidget: function(widgetId) { - $('widget_title_' + widgetId).show(); - $('#widget_' + widgetId).show(); - $('#widget_props_' + widgetId).hide(); - $($('#block_' + widgetId + ' a.link-action')[0]).show(); - }, - - - deleteWidget: function(element) { - $(element).closest('.' + this.options.block).remove(); - this.saveDashboardsState(); - } - }; - - - - window.autoResize = function(everyMs, callback) { - var debounce = _.debounce(callback, everyMs); - $(window).on('resize', debounce); - }; - - - - $(function () { - var $sidebar = jQuery('#sidebar'); - if ($sidebar.length > 0) { - var $window = jQuery(window), - topOffset = $sidebar.offset().top; - $window.on('scroll', function () { - var scrollTop = $window.scrollTop(), - scrollLeft = $window.scrollLeft(); - $sidebar.toggleClass('sticky', scrollTop > topOffset); - $sidebar.css('left', -scrollLeft + 10); - }); - } - }); - -})(jQuery); diff --git a/server/sonar-web/src/main/js/libs/dialogs.js b/server/sonar-web/src/main/js/libs/dialogs.js deleted file mode 100644 index 46f8b68354c..00000000000 --- a/server/sonar-web/src/main/js/libs/dialogs.js +++ /dev/null @@ -1,44 +0,0 @@ -(function ($) { - - window.confirmDialog = function (options) { - var settings = _.extend(window.confirmDialog.defaults, options), - dialog = $('<div><div class="modal-head"><h2>' + settings.title + '</h2></div><div class="modal-body">' + - settings.html + '</div><div class="modal-foot"><button data-confirm="yes">' + settings.yesLabel + - '</button> <a data-confirm="no" class="action">' + settings.noLabel + '</a></div></div>'); - - $('[data-confirm=yes]', dialog).on('click', function () { - dialog.dialog('close'); - settings.yesHandler(); - return settings.always(); - }); - - $('[data-confirm=no]', dialog).on('click', function () { - dialog.dialog('close'); - settings.noHandler(); - return settings.always(); - }); - - return dialog.dialog({ - modal: true, - minHeight: null, - width: 540 - }); - }; - - window.confirmDialog.defaults = { - title: 'Confirmation', - html: '', - yesLabel: 'Yes', - noLabel: 'Cancel', - yesHandler: function () { - // no op - }, - noHandler: function () { - // no op - }, - always: function () { - // no op - } - }; - -})(window.jQuery); diff --git a/server/sonar-web/src/main/js/libs/handlebars-extensions.js b/server/sonar-web/src/main/js/libs/handlebars-extensions.js deleted file mode 100644 index adac1db2b0a..00000000000 --- a/server/sonar-web/src/main/js/libs/handlebars-extensions.js +++ /dev/null @@ -1,592 +0,0 @@ -(function () { - var defaultActions = ['comment', 'assign', 'assign_to_me', 'plan', 'set_severity', 'set_tags']; - - Handlebars.registerHelper('log', function () { - /* eslint no-console: 0 */ - var args = Array.prototype.slice.call(arguments, 0, -1); - console.log.apply(console, args); - }); - - Handlebars.registerHelper('link', function () { - var url = Array.prototype.slice.call(arguments, 0, -1).join(''); - return baseUrl + url; - }); - - Handlebars.registerHelper('componentPermalink', function (componentKey) { - return baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey); - }); - - Handlebars.registerHelper('componentDashboardPermalink', function (componentKey, dashboardKey) { - var params = [ - { key: 'id', value: componentKey }, - { key: 'did', value: dashboardKey } - ]; - - var matchPeriod = window.location.search.match(/period=(\d+)/); - if (matchPeriod) { - // If we have a match for period, check that it is not project-specific - var period = parseInt(matchPeriod[1], 10); - if (period <= 3) { - params.push({ key: 'period', value: period }); - } - } - - var query = params.map(function (p) { - return p.key + '=' + encodeURIComponent(p.value); - }).join('&'); - return baseUrl + '/dashboard/index?' + query; - }); - - Handlebars.registerHelper('componentBrowsePermalink', function (componentKey) { - return baseUrl + '/components/index?id=' + encodeURIComponent(componentKey); - }); - - Handlebars.registerHelper('componentIssuesPermalink', function (componentKey) { - return baseUrl + '/component_issues/index?id=' + encodeURIComponent(componentKey); - }); - - Handlebars.registerHelper('rulePermalink', function (ruleKey) { - return baseUrl + '/coding_rules#rule_key=' + encodeURIComponent(ruleKey); - }); - - Handlebars.registerHelper('isActiveLink', function () { - var args = Array.prototype.slice.call(arguments, 0, -1), - options = arguments[arguments.length - 1], - prefix = args.join(''), - path = window.location.pathname, - match = path.indexOf(baseUrl + prefix) === 0; - return match ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('capitalize', function (string) { - return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - }); - - Handlebars.registerHelper('severityIcon', function (severity) { - return new Handlebars.SafeString( - '<i class="icon-severity-' + severity.toLowerCase() + '"></i>' - ); - }); - - Handlebars.registerHelper('severityHelper', function (severity) { - return new Handlebars.SafeString( - '<i class="icon-severity-' + severity.toLowerCase() + '"></i> ' + t('severity', severity) - ); - }); - - Handlebars.registerHelper('statusIcon', function (status) { - return new Handlebars.SafeString( - '<i class="icon-status-' + status.toLowerCase() + '"></i>' - ); - }); - - Handlebars.registerHelper('statusHelper', function (status, resolution) { - var s = '<i class="icon-status-' + status.toLowerCase() + '"></i> ' + t('issue.status', status); - if (resolution != null) { - s = s + ' (' + t('issue.resolution', resolution) + ')'; - } - return new Handlebars.SafeString(s); - }); - - Handlebars.registerHelper('testStatusIcon', function (status) { - return new Handlebars.SafeString( - '<i class="icon-test-status-' + status.toLowerCase() + '"></i>' - ); - }); - - Handlebars.registerHelper('testStatusIconClass', function (status) { - return new Handlebars.SafeString('' + - 'icon-test-status-' + status.toLowerCase() - ); - }); - - Handlebars.registerHelper('alertIconClass', function (alert) { - return new Handlebars.SafeString( - 'icon-alert-' + alert.toLowerCase() - ); - }); - - Handlebars.registerHelper('qualifierIcon', function (qualifier) { - return new Handlebars.SafeString( - qualifier ? '<i class="icon-qualifier-' + qualifier.toLowerCase() + '"></i>' : '' - ); - }); - - Handlebars.registerHelper('default', function () { - var args = Array.prototype.slice.call(arguments, 0, -1); - return args.reduce(function (prev, current) { - return prev != null ? prev : current; - }, null); - }); - - Handlebars.registerHelper('show', function () { - var args = Array.prototype.slice.call(arguments), - ret = null; - args.forEach(function (arg) { - if (typeof arg === 'string' && ret == null) { - ret = arg; - } - }); - return ret || ''; - }); - - Handlebars.registerHelper('percent', function (value, total) { - if (total > 0) { - return '' + ((value || 0) / total * 100) + '%'; - } else { - return '0%'; - } - }); - - Handlebars.registerHelper('eachIndex', function (context, options) { - var ret = ''; - context.forEach(function (d, i) { - var c = _.extend({ index: i }, d); - ret += options.fn(c); - }); - return ret; - }); - - Handlebars.registerHelper('eachChanged', function (context, property, options) { - var ret = ''; - context.forEach(function (d, i) { - var changed = i > 0 ? d[property] !== context[i - 1][property] : true, - c = _.extend({ changed: changed }, d); - ret += options.fn(c); - }); - return ret; - }); - - Handlebars.registerHelper('eachEven', function (context, options) { - var ret = ''; - context.forEach(function (d, i) { - if (i % 2 === 0) { - ret += options.fn(d); - } - }); - return ret; - }); - - Handlebars.registerHelper('eachOdd', function (context, options) { - var ret = ''; - context.forEach(function (d, i) { - if (i % 2 === 1) { - ret += options.fn(d); - } - }); - return ret; - }); - - Handlebars.registerHelper('eq', function (v1, v2, options) { - /* eslint eqeqeq: 0 */ - return v1 == v2 ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('notEq', function (v1, v2, options) { - /* eslint eqeqeq: 0 */ - return v1 != v2 ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('gt', function (v1, v2, options) { - return v1 > v2 ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('lt', function (v1, v2, options) { - return v1 < v2 ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('notNull', function (value, options) { - return value != null ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('isNull', function (value, options) { - return value == null ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('notEmpty', function (array, options) { - var cond = _.isArray(array) && array.length > 0; - return cond ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('empty', function (array, options) { - var cond = _.isArray(array) && array.length > 0; - return cond ? options.inverse(this) : options.fn(this); - }); - - Handlebars.registerHelper('all', function () { - var args = Array.prototype.slice.call(arguments, 0, -1), - options = arguments[arguments.length - 1], - all = args.reduce(function (prev, current) { - return prev && current; - }, true); - return all ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('any', function () { - var args = Array.prototype.slice.call(arguments, 0, -1), - options = arguments[arguments.length - 1], - any = args.reduce(function (prev, current) { - return prev || current; - }, false); - return any ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('inArray', function (array, element, options) { - if (_.isArray(array)) { - if (array.indexOf(element) !== -1) { - return options.fn(this); - } else { - return options.inverse(this); - } - } - }); - - Handlebars.registerHelper('ifNotEmpty', function () { - var args = Array.prototype.slice.call(arguments, 0, -1), - options = arguments[arguments.length - 1], - notEmpty = args.reduce(function (prev, current) { - return prev || (current && current.length > 0); - }, false); - return notEmpty ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('join', function (array, separator) { - return array.join(separator); - }); - - Handlebars.registerHelper('ifLength', function (array, len, options) { - var cond = _.isArray(array) && array.length === +len; - return cond ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('unlessLength', function (array, len, options) { - var cond = _.isArray(array) && array.length === +len; - return cond ? options.inverse(this) : options.fn(this); - }); - - Handlebars.registerHelper('eachReverse', function (array, options) { - var ret = ''; - - if (array && array.length > 0) { - for (var i = array.length - 1; i >= 0; i--) { - ret += options.fn(array[i]); - } - } else { - ret = options.inverse(this); - } - - return ret; - }); - - Handlebars.registerHelper('joinEach', function (array, separator, options) { - var ret = ''; - - if (array && array.length > 0) { - for (var i = 0, n = array.length; i < n; i++) { - ret += options.fn(array[i]); - if (i < n - 1) { - ret += separator; - } - } - } else { - ret = options.inverse(this); - } - - return ret; - }); - - Handlebars.registerHelper('sum', function () { - var args = Array.prototype.slice.call(arguments, 0, -1); - return args.reduce(function (p, c) { - return p + +c; - }, 0); - }); - - Handlebars.registerHelper('dashboardUrl', function (componentKey, componentQualifier) { - var url = baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey); - if (componentQualifier === 'FIL' || componentQualifier === 'CLA') { - url += '&metric=sqale_index'; - } - return url; - }); - - Handlebars.registerHelper('translate', function () { - var args = Array.prototype.slice.call(arguments, 0, -1); - return window.translate.apply(this, args); - }); - - Handlebars.registerHelper('t', function () { - var args = Array.prototype.slice.call(arguments, 0, -1); - return window.t.apply(this, args); - }); - - Handlebars.registerHelper('tp', function () { - var args = Array.prototype.slice.call(arguments, 0, -1); - return window.tp.apply(this, args); - }); - - Handlebars.registerHelper('d', function (date) { - return moment(date).format('LL'); - }); - - Handlebars.registerHelper('dt', function (date) { - return moment(date).format('LLL'); - }); - - Handlebars.registerHelper('ds', function (date) { - return moment(date).format('YYYY-MM-DD'); - }); - - Handlebars.registerHelper('fromNow', function (date) { - return moment(date).fromNow(); - }); - - Handlebars.registerHelper('durationFromNow', function (date, units) { - return moment(new Date()).diff(date, units); - }); - - Handlebars.registerHelper('numberShort', function (number) { - var format = '0,0'; - if (number >= 10000) { - format = '0.[0]a'; - } - if (number >= 100000) { - format = '0a'; - } - return numeral(number).format(format); - }); - - Handlebars.registerHelper('pluginActions', function (actions, options) { - var pluginActions = _.difference(actions, defaultActions); - return pluginActions.reduce(function (prev, current) { - return prev + options.fn(current); - }, ''); - }); - - Handlebars.registerHelper('ifHasExtraActions', function (actions, options) { - var actionsLeft = _.difference(actions, defaultActions); - if (actionsLeft.length > 0) { - return options.fn(this); - } else { - return options.inverse(this); - } - }); - - Handlebars.registerHelper('withFirst', function (list, options) { - if (list && list.length > 0) { - return options.fn(list[0]); - } else { - return ''; - } - }); - - Handlebars.registerHelper('withLast', function (list, options) { - if (list && list.length > 0) { - return options.fn(list[list.length - 1]); - } else { - return ''; - } - }); - - Handlebars.registerHelper('withoutFirst', function (list, options) { - if (list && list.length > 1) { - return list.slice(1).reduce(function (prev, current) { - return prev + options.fn(current); - }, ''); - } else { - return ''; - } - }); - - var audaciousFn; - Handlebars.registerHelper('recursive', function (children, options) { - var out = ''; - - if (options.fn !== undefined) { - audaciousFn = options.fn; - } - - children.forEach(function (child) { - out = out + audaciousFn(child); - }); - - return out; - }); - - Handlebars.registerHelper('sources', function (source, scm, options) { - if (options == null) { - options = scm; - scm = null; - } - - var sources = _.map(source, function (code, line) { - return { - lineNumber: line, - code: code, - scm: (scm && scm[line]) ? { author: scm[line][0], date: scm[line][1] } : undefined - }; - }); - - return sources.reduce(function (prev, current, index) { - return prev + options.fn(_.extend({ first: index === 0 }, current)); - }, ''); - }); - - Handlebars.registerHelper('operators', function (options) { - var ops = ['LT', 'GT', 'EQ', 'NE']; - - return ops.reduce(function (prev, current) { - return prev + options.fn(current); - }, ''); - }); - - Handlebars.registerHelper('changelog', function (diff) { - var message = ''; - if (diff.newValue != null) { - message = tp('issue.changelog.changed_to', t('issue.changelog.field', diff.key), diff.newValue); - } else { - message = tp('issue.changelog.removed', t('issue.changelog.field', diff.key)); - } - if (diff.oldValue != null) { - message += ' ('; - message += tp('issue.changelog.was', diff.oldValue); - message += ')'; - } - return message; - }); - - Handlebars.registerHelper('ifMeasureShouldBeShown', function (measure, period, options) { - if (measure != null || period != null) { - return options.fn(this); - } else { - return options.inverse(this); - } - }); - - Handlebars.registerHelper('ifSCMChanged', function (source, line, options) { - var currentLine = _.findWhere(source, { lineNumber: line }), - prevLine = _.findWhere(source, { lineNumber: line - 1 }), - changed = true; - if (currentLine && prevLine && currentLine.scm && prevLine.scm) { - changed = (currentLine.scm.author !== prevLine.scm.author) || - (currentLine.scm.date !== prevLine.scm.date) || (!prevLine.show); - } - return changed ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('ifSCMChanged2', function (source, line, options) { - var currentLine = _.findWhere(source, { line: line }), - prevLine = _.findWhere(source, { line: line - 1 }), - changed = true; - if (currentLine && prevLine && currentLine.scmAuthor && prevLine.scmAuthor) { - changed = (currentLine.scmAuthor !== prevLine.scmAuthor) || (currentLine.scmDate !== prevLine.scmDate); - } - return changed ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('ifTestData', function (test, options) { - if ((test.status !== 'OK') || ((test.status === 'OK') && test.coveredLines)) { - return options.fn(this); - } else { - return options.inverse(this); - } - }); - - Handlebars.registerHelper('eqComponents', function (a, b, options) { - var notEq = a && b && ((a.project !== b.project) || (a.subProject !== b.subProject)); - return notEq ? options.inverse(this) : options.fn(this); - }); - - Handlebars.registerHelper('notEqComponents', function (a, b, options) { - var notEq = a && b && ((a.project !== b.project) || (a.subProject !== b.subProject)); - return notEq ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('projectFullName', function (component) { - return component.projectName + (component.subProjectName ? (' / ' + component.subProjectName) : ''); - }); - - Handlebars.registerHelper('dirFromPath', function (path) { - if (typeof path === 'string') { - var tokens = path.split('/'); - return tokens.length > 1 ? _.initial(tokens).join('/') + '/' : ''; - } else { - return null; - } - }); - - Handlebars.registerHelper('collapsedDirFromPath', function (path) { - return window.collapsedDirFromPath(path); - }); - - Handlebars.registerHelper('fileFromPath', function (path) { - return window.fileFromPath(path); - }); - - Handlebars.registerHelper('repeat', function (number, options) { - var ret = ''; - for (var i = 0; i < number; i++) { - ret += options.fn(this); - } - return ret; - }); - - Handlebars.registerHelper('limitString', function (str) { - if (typeof str === 'string') { - var LIMIT = 30; - return str.length > LIMIT ? str.substr(0, LIMIT) + '...' : str; - } - }); - - Handlebars.registerHelper('withSign', function (number) { - return number >= 0 ? '+' + number : '' + number; - }); - - Handlebars.registerHelper('formatMeasure', function (measure, type) { - return window.formatMeasure(measure, type); - }); - - Handlebars.registerHelper('formatMeasureVariation', function (measure, type) { - return window.formatMeasureVariation(measure, type); - }); - - Handlebars.registerHelper('dashboardL10n', function (dashboardName) { - var l10nKey = 'dashboard.' + dashboardName + '.name'; - var l10nLabel = window.t(l10nKey); - if (l10nLabel !== l10nKey) { - return l10nLabel; - } else { - return dashboardName; - } - }); - - Handlebars.registerHelper('ifShowAvatars', function (options) { - var cond = window.SS && window.SS.lf && window.SS.lf.enableGravatar; - return cond ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('avatarHelper', function (email, size) { - // double the size for high pixel density screens - var emailHash = window.md5((email || '').trim()), - url = ('' + window.SS.lf.gravatarServerUrl) - .replace('{EMAIL_MD5}', emailHash) - .replace('{SIZE}', size * 2); - return new Handlebars.SafeString( - '<img class="rounded" src="' + url + '" width="' + size + '" height="' + size + '" alt="' + email + '">' - ); - }); - - Handlebars.registerHelper('ifCanUseFilter', function (query, options) { - var cond = window.SS.user || query.indexOf('__me__') === -1; - return cond ? options.fn(this) : options.inverse(this); - }); - - Handlebars.registerHelper('length', function (array) { - return _.size(array); - }); - - Handlebars.registerHelper('ifLengthGT', function (array, len, options) { - return _.size(array) > len ? options.fn(this) : options.inverse(this); - }); - -})(); diff --git a/server/sonar-web/src/main/js/libs/processes.js b/server/sonar-web/src/main/js/libs/processes.js deleted file mode 100644 index bb361e88b68..00000000000 --- a/server/sonar-web/src/main/js/libs/processes.js +++ /dev/null @@ -1,169 +0,0 @@ -(function ($) { - - var defaults = { - queue: {}, - timeout: 300, - fadeTimeout: 100 - }; - - var Process = Backbone.Model.extend({ - defaults: { - state: 'ok' - }, - - timeout: function () { - this.set({ - state: 'timeout', - message: 'Still Working...' - }); - }, - - finish: function (options) { - options = _.defaults(options || {}, { force: false }); - if (this.get('state') !== 'failed' || !!options.force) { - this.trigger('destroy', this, this.collection, options); - } - }, - - fail: function (message) { - var that = this, - msg = message || t('process.fail'); - if (msg === 'process.fail') { - // no translation - msg = 'An error happened, some parts of the page might not render correctly. ' + - 'Please contact the administrator if you keep on experiencing this error.'; - } - clearInterval(this.get('timer')); - this.set({ - state: 'failed', - message: msg - }); - this.set('state', 'failed'); - setTimeout(function () { - that.finish({ force: true }); - }, 5000); - } - }), - - Processes = Backbone.Collection.extend({ - model: Process - }), - - ProcessesView = Marionette.ItemView.extend({ - tagName: 'ul', - className: 'processes-container', - - collectionEvents: { - 'all': 'render' - }, - - render: function () { - var failed = this.collection.findWhere({ state: 'failed' }), - timeout = this.collection.findWhere({ state: 'timeout' }), - el; - this.$el.empty(); - if (failed != null) { - el = $('<li></li>') - .html(failed.get('message')) - .addClass('process-spinner process-spinner-failed shown'); - var close = $('<button></button>').html('<i class="icon-close"></i>').addClass('process-spinner-close'); - close.appendTo(el); - close.on('click', function () { - failed.finish({ force: true }); - }); - el.appendTo(this.$el); - } else if (timeout != null) { - el = $('<li></li>') - .html(timeout.get('message')) - .addClass('process-spinner shown'); - el.appendTo(this.$el); - } - return this; - } - }); - - - var processes = new Processes(), - processesView = new ProcessesView({ - collection: processes - }); - - /** - * Add background process - * @returns {number} - */ - function addBackgroundProcess () { - var uid = _.uniqueId('process'), - process = new Process({ - id: uid, - timer: setTimeout(function () { - process.timeout(); - }, defaults.timeout) - }); - processes.add(process); - return uid; - } - - /** - * Finish background process - * @param {number} uid - */ - function finishBackgroundProcess (uid) { - var process = processes.get(uid); - if (process != null) { - process.finish(); - } - } - - /** - * Fail background process - * @param {number} uid - * @param {string} message - */ - function failBackgroundProcess (uid, message) { - var process = processes.get(uid); - if (process != null) { - process.fail(message); - } - } - - /** - * Handle ajax error - * @param jqXHR - */ - function handleAjaxError (jqXHR) { - if (jqXHR.processId != null) { - var message = null; - if (jqXHR != null && jqXHR.responseJSON != null && jqXHR.responseJSON.errors != null) { - message = _.pluck(jqXHR.responseJSON.errors, 'msg').join('. '); - } - failBackgroundProcess(jqXHR.processId, message); - } - } - - - $.ajaxSetup({ - beforeSend: function (jqXHR) { - jqXHR.processId = addBackgroundProcess(); - }, - complete: function (jqXHR) { - if (jqXHR.processId != null) { - finishBackgroundProcess(jqXHR.processId); - } - }, - statusCode: { - 400: handleAjaxError, - 401: handleAjaxError, - 403: handleAjaxError, - 500: handleAjaxError - } - }); - - - $(function () { - - processesView.render().$el.insertBefore('#footer'); - - }); - -})(window.jQuery); diff --git a/server/sonar-web/src/main/js/libs/recent-history.js b/server/sonar-web/src/main/js/libs/recent-history.js deleted file mode 100644 index b9e54a7ccb6..00000000000 --- a/server/sonar-web/src/main/js/libs/recent-history.js +++ /dev/null @@ -1,57 +0,0 @@ -window.Sonar = {}; - -window.Sonar.RecentHistory = function () { -}; - -window.Sonar.RecentHistory.prototype.getRecentHistory = function () { - var sonarHistory = localStorage.getItem('sonar_recent_history'); - if (sonarHistory == null) { - sonarHistory = []; - } else { - sonarHistory = JSON.parse(sonarHistory); - } - return sonarHistory; -}; - -window.Sonar.RecentHistory.prototype.clear = function () { - localStorage.removeItem('sonar_recent_history'); -}; - -window.Sonar.RecentHistory.prototype.add = function (resourceKey, resourceName, icon) { - var sonarHistory = this.getRecentHistory(); - - if (resourceKey !== '') { - var newEntry = {'key': resourceKey, 'name': resourceName, 'icon': icon}; - // removes the element of the array if it exists - for (var i = 0; i < sonarHistory.length; i++) { - var item = sonarHistory[i]; - if (item.key === resourceKey) { - sonarHistory.splice(i, 1); - break; - } - } - // then add it to the beginning of the array - sonarHistory.unshift(newEntry); - // and finally slice the array to keep only 10 elements - sonarHistory = sonarHistory.slice(0, 10); - - localStorage.setItem('sonar_recent_history', JSON.stringify(sonarHistory)); - } -}; - -window.Sonar.RecentHistory.prototype.populateRecentHistoryPanel = function () { - var historyLinksList = jQuery('#recent-history-list'); - historyLinksList.empty(); - - var recentHistory = this.getRecentHistory(); - if (recentHistory.length === 0) { - jQuery('#recent-history').hide(); - } else { - recentHistory.forEach(function (resource) { - historyLinksList.append('<li><i class="icon-qualifier-' + resource.icon + '"></i><a href="' + - baseUrl + '/dashboard/index/' + resource.key + window.dashboardParameters() + '"> ' + - resource.name + '</a></li>'); - }); - jQuery('#recent-history').show(); - } -}; diff --git a/server/sonar-web/src/main/js/libs/third-party/backbone.js b/server/sonar-web/src/main/js/libs/third-party/backbone.js deleted file mode 100644 index 24a550a0adc..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/backbone.js +++ /dev/null @@ -1,1608 +0,0 @@ -// Backbone.js 1.1.2 - -// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org - -(function(root, factory) { - - // Set up Backbone appropriately for the environment. Start with AMD. - if (typeof define === 'function' && define.amd) { - define(['underscore', 'jquery', 'exports'], function(_, $, exports) { - // Export global even in AMD case in case this script is loaded with - // others that may still expect a global Backbone. - root.Backbone = factory(root, exports, _, $); - }); - - // Next for Node.js or CommonJS. jQuery may not be needed as a module. - } else if (typeof exports !== 'undefined') { - var _ = require('underscore'); - factory(root, exports, _); - - // Finally, as a browser global. - } else { - root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$)); - } - -}(this, function(root, Backbone, _, $) { - - // Initial Setup - // ------------- - - // Save the previous value of the `Backbone` variable, so that it can be - // restored later on, if `noConflict` is used. - var previousBackbone = root.Backbone; - - // Create local references to array methods we'll want to use later. - var array = []; - var push = array.push; - var slice = array.slice; - var splice = array.splice; - - // Current version of the library. Keep in sync with `package.json`. - Backbone.VERSION = '1.1.2'; - - // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns - // the `$` variable. - Backbone.$ = $; - - // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable - // to its previous owner. Returns a reference to this Backbone object. - Backbone.noConflict = function() { - root.Backbone = previousBackbone; - return this; - }; - - // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option - // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and - // set a `X-Http-Method-Override` header. - Backbone.emulateHTTP = false; - - // Turn on `emulateJSON` to support legacy servers that can't deal with direct - // `application/json` requests ... will encode the body as - // `application/x-www-form-urlencoded` instead and will send the model in a - // form param named `model`. - Backbone.emulateJSON = false; - - // Backbone.Events - // --------------- - - // A module that can be mixed in to *any object* in order to provide it with - // custom events. You may bind with `on` or remove with `off` callback - // functions to an event; `trigger`-ing an event fires all callbacks in - // succession. - // - // var object = {}; - // _.extend(object, Backbone.Events); - // object.on('expand', function(){ alert('expanded'); }); - // object.trigger('expand'); - // - var Events = Backbone.Events = { - - // Bind an event to a `callback` function. Passing `"all"` will bind - // the callback to all events fired. - on: function(name, callback, context) { - if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this; - this._events || (this._events = {}); - var events = this._events[name] || (this._events[name] = []); - events.push({callback: callback, context: context, ctx: context || this}); - return this; - }, - - // Bind an event to only be triggered a single time. After the first time - // the callback is invoked, it will be removed. - once: function(name, callback, context) { - if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this; - var self = this; - var once = _.once(function() { - self.off(name, once); - callback.apply(this, arguments); - }); - once._callback = callback; - return this.on(name, once, context); - }, - - // Remove one or many callbacks. If `context` is null, removes all - // callbacks with that function. If `callback` is null, removes all - // callbacks for the event. If `name` is null, removes all bound - // callbacks for all events. - off: function(name, callback, context) { - var retain, ev, events, names, i, l, j, k; - if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; - if (!name && !callback && !context) { - this._events = void 0; - return this; - } - names = name ? [name] : _.keys(this._events); - for (i = 0, l = names.length; i < l; i++) { - name = names[i]; - if (events = this._events[name]) { - this._events[name] = retain = []; - if (callback || context) { - for (j = 0, k = events.length; j < k; j++) { - ev = events[j]; - if ((callback && callback !== ev.callback && callback !== ev.callback._callback) || - (context && context !== ev.context)) { - retain.push(ev); - } - } - } - if (!retain.length) delete this._events[name]; - } - } - - return this; - }, - - // Trigger one or many events, firing all bound callbacks. Callbacks are - // passed the same arguments as `trigger` is, apart from the event name - // (unless you're listening on `"all"`, which will cause your callback to - // receive the true name of the event as the first argument). - trigger: function(name) { - if (!this._events) return this; - var args = slice.call(arguments, 1); - if (!eventsApi(this, 'trigger', name, args)) return this; - var events = this._events[name]; - var allEvents = this._events.all; - if (events) triggerEvents(events, args); - if (allEvents) triggerEvents(allEvents, arguments); - return this; - }, - - // Tell this object to stop listening to either specific events ... or - // to every object it's currently listening to. - stopListening: function(obj, name, callback) { - var listeningTo = this._listeningTo; - if (!listeningTo) return this; - var remove = !name && !callback; - if (!callback && typeof name === 'object') callback = this; - if (obj) (listeningTo = {})[obj._listenId] = obj; - for (var id in listeningTo) { - obj = listeningTo[id]; - obj.off(name, callback, this); - if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id]; - } - return this; - } - - }; - - // Regular expression used to split event strings. - var eventSplitter = /\s+/; - - // Implement fancy features of the Events API such as multiple event - // names `"change blur"` and jQuery-style event maps `{change: action}` - // in terms of the existing API. - var eventsApi = function(obj, action, name, rest) { - if (!name) return true; - - // Handle event maps. - if (typeof name === 'object') { - for (var key in name) { - obj[action].apply(obj, [key, name[key]].concat(rest)); - } - return false; - } - - // Handle space separated event names. - if (eventSplitter.test(name)) { - var names = name.split(eventSplitter); - for (var i = 0, l = names.length; i < l; i++) { - obj[action].apply(obj, [names[i]].concat(rest)); - } - return false; - } - - return true; - }; - - // A difficult-to-believe, but optimized internal dispatch function for - // triggering events. Tries to keep the usual cases speedy (most internal - // Backbone events have 3 arguments). - var triggerEvents = function(events, args) { - var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; - switch (args.length) { - case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; - case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; - case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; - case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; - default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; - } - }; - - var listenMethods = {listenTo: 'on', listenToOnce: 'once'}; - - // Inversion-of-control versions of `on` and `once`. Tell *this* object to - // listen to an event in another object ... keeping track of what it's - // listening to. - _.each(listenMethods, function(implementation, method) { - Events[method] = function(obj, name, callback) { - var listeningTo = this._listeningTo || (this._listeningTo = {}); - var id = obj._listenId || (obj._listenId = _.uniqueId('l')); - listeningTo[id] = obj; - if (!callback && typeof name === 'object') callback = this; - obj[implementation](name, callback, this); - return this; - }; - }); - - // Aliases for backwards compatibility. - Events.bind = Events.on; - Events.unbind = Events.off; - - // Allow the `Backbone` object to serve as a global event bus, for folks who - // want global "pubsub" in a convenient place. - _.extend(Backbone, Events); - - // Backbone.Model - // -------------- - - // Backbone **Models** are the basic data object in the framework -- - // frequently representing a row in a table in a database on your server. - // A discrete chunk of data and a bunch of useful, related methods for - // performing computations and transformations on that data. - - // Create a new model with the specified attributes. A client id (`cid`) - // is automatically generated and assigned for you. - var Model = Backbone.Model = function(attributes, options) { - var attrs = attributes || {}; - options || (options = {}); - this.cid = _.uniqueId('c'); - this.attributes = {}; - if (options.collection) this.collection = options.collection; - if (options.parse) attrs = this.parse(attrs, options) || {}; - attrs = _.defaults({}, attrs, _.result(this, 'defaults')); - this.set(attrs, options); - this.changed = {}; - this.initialize.apply(this, arguments); - }; - - // Attach all inheritable methods to the Model prototype. - _.extend(Model.prototype, Events, { - - // A hash of attributes whose current and previous value differ. - changed: null, - - // The value returned during the last failed validation. - validationError: null, - - // The default name for the JSON `id` attribute is `"id"`. MongoDB and - // CouchDB users may want to set this to `"_id"`. - idAttribute: 'id', - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // Return a copy of the model's `attributes` object. - toJSON: function(options) { - return _.clone(this.attributes); - }, - - // Proxy `Backbone.sync` by default -- but override this if you need - // custom syncing semantics for *this* particular model. - sync: function() { - return Backbone.sync.apply(this, arguments); - }, - - // Get the value of an attribute. - get: function(attr) { - return this.attributes[attr]; - }, - - // Get the HTML-escaped value of an attribute. - escape: function(attr) { - return _.escape(this.get(attr)); - }, - - // Returns `true` if the attribute contains a value that is not null - // or undefined. - has: function(attr) { - return this.get(attr) != null; - }, - - // Set a hash of model attributes on the object, firing `"change"`. This is - // the core primitive operation of a model, updating the data and notifying - // anyone who needs to know about the change in state. The heart of the beast. - set: function(key, val, options) { - var attr, attrs, unset, changes, silent, changing, prev, current; - if (key == null) return this; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - options || (options = {}); - - // Run validation. - if (!this._validate(attrs, options)) return false; - - // Extract attributes and options. - unset = options.unset; - silent = options.silent; - changes = []; - changing = this._changing; - this._changing = true; - - if (!changing) { - this._previousAttributes = _.clone(this.attributes); - this.changed = {}; - } - current = this.attributes, prev = this._previousAttributes; - - // Check for changes of `id`. - if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; - - // For each `set` attribute, update or delete the current value. - for (attr in attrs) { - val = attrs[attr]; - if (!_.isEqual(current[attr], val)) changes.push(attr); - if (!_.isEqual(prev[attr], val)) { - this.changed[attr] = val; - } else { - delete this.changed[attr]; - } - unset ? delete current[attr] : current[attr] = val; - } - - // Trigger all relevant attribute changes. - if (!silent) { - if (changes.length) this._pending = options; - for (var i = 0, l = changes.length; i < l; i++) { - this.trigger('change:' + changes[i], this, current[changes[i]], options); - } - } - - // You might be wondering why there's a `while` loop here. Changes can - // be recursively nested within `"change"` events. - if (changing) return this; - if (!silent) { - while (this._pending) { - options = this._pending; - this._pending = false; - this.trigger('change', this, options); - } - } - this._pending = false; - this._changing = false; - return this; - }, - - // Remove an attribute from the model, firing `"change"`. `unset` is a noop - // if the attribute doesn't exist. - unset: function(attr, options) { - return this.set(attr, void 0, _.extend({}, options, {unset: true})); - }, - - // Clear all attributes on the model, firing `"change"`. - clear: function(options) { - var attrs = {}; - for (var key in this.attributes) attrs[key] = void 0; - return this.set(attrs, _.extend({}, options, {unset: true})); - }, - - // Determine if the model has changed since the last `"change"` event. - // If you specify an attribute name, determine if that attribute has changed. - hasChanged: function(attr) { - if (attr == null) return !_.isEmpty(this.changed); - return _.has(this.changed, attr); - }, - - // Return an object containing all the attributes that have changed, or - // false if there are no changed attributes. Useful for determining what - // parts of a view need to be updated and/or what attributes need to be - // persisted to the server. Unset attributes will be set to undefined. - // You can also pass an attributes object to diff against the model, - // determining if there *would be* a change. - changedAttributes: function(diff) { - if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; - var val, changed = false; - var old = this._changing ? this._previousAttributes : this.attributes; - for (var attr in diff) { - if (_.isEqual(old[attr], (val = diff[attr]))) continue; - (changed || (changed = {}))[attr] = val; - } - return changed; - }, - - // Get the previous value of an attribute, recorded at the time the last - // `"change"` event was fired. - previous: function(attr) { - if (attr == null || !this._previousAttributes) return null; - return this._previousAttributes[attr]; - }, - - // Get all of the attributes of the model at the time of the previous - // `"change"` event. - previousAttributes: function() { - return _.clone(this._previousAttributes); - }, - - // Fetch the model from the server. If the server's representation of the - // model differs from its current attributes, they will be overridden, - // triggering a `"change"` event. - fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; - var model = this; - var success = options.success; - options.success = function(resp) { - if (!model.set(model.parse(resp, options), options)) return false; - if (success) success(model, resp, options); - model.trigger('sync', model, resp, options); - }; - wrapError(this, options); - return this.sync('read', this, options); - }, - - // Set a hash of model attributes, and sync the model to the server. - // If the server returns an attributes hash that differs, the model's - // state will be `set` again. - save: function(key, val, options) { - var attrs, method, xhr, attributes = this.attributes; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (key == null || typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - options = _.extend({validate: true}, options); - - // If we're not waiting and attributes exist, save acts as - // `set(attr).save(null, opts)` with validation. Otherwise, check if - // the model will be valid when the attributes, if any, are set. - if (attrs && !options.wait) { - if (!this.set(attrs, options)) return false; - } else { - if (!this._validate(attrs, options)) return false; - } - - // Set temporary attributes if `{wait: true}`. - if (attrs && options.wait) { - this.attributes = _.extend({}, attributes, attrs); - } - - // After a successful server-side save, the client is (optionally) - // updated with the server-side state. - if (options.parse === void 0) options.parse = true; - var model = this; - var success = options.success; - options.success = function(resp) { - // Ensure attributes are restored during synchronous saves. - model.attributes = attributes; - var serverAttrs = model.parse(resp, options); - if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); - if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { - return false; - } - if (success) success(model, resp, options); - model.trigger('sync', model, resp, options); - }; - wrapError(this, options); - - method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); - if (method === 'patch') options.attrs = attrs; - xhr = this.sync(method, this, options); - - // Restore attributes. - if (attrs && options.wait) this.attributes = attributes; - - return xhr; - }, - - // Destroy this model on the server if it was already persisted. - // Optimistically removes the model from its collection, if it has one. - // If `wait: true` is passed, waits for the server to respond before removal. - destroy: function(options) { - options = options ? _.clone(options) : {}; - var model = this; - var success = options.success; - - var destroy = function() { - model.trigger('destroy', model, model.collection, options); - }; - - options.success = function(resp) { - if (options.wait || model.isNew()) destroy(); - if (success) success(model, resp, options); - if (!model.isNew()) model.trigger('sync', model, resp, options); - }; - - if (this.isNew()) { - options.success(); - return false; - } - wrapError(this, options); - - var xhr = this.sync('delete', this, options); - if (!options.wait) destroy(); - return xhr; - }, - - // Default URL for the model's representation on the server -- if you're - // using Backbone's restful methods, override this to change the endpoint - // that will be called. - url: function() { - var base = - _.result(this, 'urlRoot') || - _.result(this.collection, 'url') || - urlError(); - if (this.isNew()) return base; - return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id); - }, - - // **parse** converts a response into the hash of attributes to be `set` on - // the model. The default implementation is just to pass the response along. - parse: function(resp, options) { - return resp; - }, - - // Create a new model with identical attributes to this one. - clone: function() { - return new this.constructor(this.attributes); - }, - - // A model is new if it has never been saved to the server, and lacks an id. - isNew: function() { - return !this.has(this.idAttribute); - }, - - // Check if the model is currently in a valid state. - isValid: function(options) { - return this._validate({}, _.extend(options || {}, { validate: true })); - }, - - // Run validation against the next complete set of model attributes, - // returning `true` if all is well. Otherwise, fire an `"invalid"` event. - _validate: function(attrs, options) { - if (!options.validate || !this.validate) return true; - attrs = _.extend({}, this.attributes, attrs); - var error = this.validationError = this.validate(attrs, options) || null; - if (!error) return true; - this.trigger('invalid', this, error, _.extend(options, {validationError: error})); - return false; - } - - }); - - // Underscore methods that we want to implement on the Model. - var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit']; - - // Mix in each Underscore method as a proxy to `Model#attributes`. - _.each(modelMethods, function(method) { - Model.prototype[method] = function() { - var args = slice.call(arguments); - args.unshift(this.attributes); - return _[method].apply(_, args); - }; - }); - - // Backbone.Collection - // ------------------- - - // If models tend to represent a single row of data, a Backbone Collection is - // more analagous to a table full of data ... or a small slice or page of that - // table, or a collection of rows that belong together for a particular reason - // -- all of the messages in this particular folder, all of the documents - // belonging to this particular author, and so on. Collections maintain - // indexes of their models, both in order, and for lookup by `id`. - - // Create a new **Collection**, perhaps to contain a specific type of `model`. - // If a `comparator` is specified, the Collection will maintain - // its models in sort order, as they're added and removed. - var Collection = Backbone.Collection = function(models, options) { - options || (options = {}); - if (options.model) this.model = options.model; - if (options.comparator !== void 0) this.comparator = options.comparator; - this._reset(); - this.initialize.apply(this, arguments); - if (models) this.reset(models, _.extend({silent: true}, options)); - }; - - // Default options for `Collection#set`. - var setOptions = {add: true, remove: true, merge: true}; - var addOptions = {add: true, remove: false}; - - // Define the Collection's inheritable methods. - _.extend(Collection.prototype, Events, { - - // The default model for a collection is just a **Backbone.Model**. - // This should be overridden in most cases. - model: Model, - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // The JSON representation of a Collection is an array of the - // models' attributes. - toJSON: function(options) { - return this.map(function(model){ return model.toJSON(options); }); - }, - - // Proxy `Backbone.sync` by default. - sync: function() { - return Backbone.sync.apply(this, arguments); - }, - - // Add a model, or list of models to the set. - add: function(models, options) { - return this.set(models, _.extend({merge: false}, options, addOptions)); - }, - - // Remove a model, or a list of models from the set. - remove: function(models, options) { - var singular = !_.isArray(models); - models = singular ? [models] : _.clone(models); - options || (options = {}); - var i, l, index, model; - for (i = 0, l = models.length; i < l; i++) { - model = models[i] = this.get(models[i]); - if (!model) continue; - delete this._byId[model.id]; - delete this._byId[model.cid]; - index = this.indexOf(model); - this.models.splice(index, 1); - this.length--; - if (!options.silent) { - options.index = index; - model.trigger('remove', model, this, options); - } - this._removeReference(model, options); - } - return singular ? models[0] : models; - }, - - // Update a collection by `set`-ing a new list of models, adding new ones, - // removing models that are no longer present, and merging models that - // already exist in the collection, as necessary. Similar to **Model#set**, - // the core operation for updating the data contained by the collection. - set: function(models, options) { - options = _.defaults({}, options, setOptions); - if (options.parse) models = this.parse(models, options); - var singular = !_.isArray(models); - models = singular ? (models ? [models] : []) : _.clone(models); - var i, l, id, model, attrs, existing, sort; - var at = options.at; - var targetModel = this.model; - var sortable = this.comparator && (at == null) && options.sort !== false; - var sortAttr = _.isString(this.comparator) ? this.comparator : null; - var toAdd = [], toRemove = [], modelMap = {}; - var add = options.add, merge = options.merge, remove = options.remove; - var order = !sortable && add && remove ? [] : false; - - // Turn bare objects into model references, and prevent invalid models - // from being added. - for (i = 0, l = models.length; i < l; i++) { - attrs = models[i] || {}; - if (attrs instanceof Model) { - id = model = attrs; - } else { - id = attrs[targetModel.prototype.idAttribute || 'id']; - } - - // If a duplicate is found, prevent it from being added and - // optionally merge it into the existing model. - if (existing = this.get(id)) { - if (remove) modelMap[existing.cid] = true; - if (merge) { - attrs = attrs === model ? model.attributes : attrs; - if (options.parse) attrs = existing.parse(attrs, options); - existing.set(attrs, options); - if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true; - } - models[i] = existing; - - // If this is a new, valid model, push it to the `toAdd` list. - } else if (add) { - model = models[i] = this._prepareModel(attrs, options); - if (!model) continue; - toAdd.push(model); - this._addReference(model, options); - } - - // Do not add multiple models with the same `id`. - model = existing || model; - if (order && (model.isNew() || !modelMap[model.id])) order.push(model); - modelMap[model.id] = true; - } - - // Remove nonexistent models if appropriate. - if (remove) { - for (i = 0, l = this.length; i < l; ++i) { - if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model); - } - if (toRemove.length) this.remove(toRemove, options); - } - - // See if sorting is needed, update `length` and splice in new models. - if (toAdd.length || (order && order.length)) { - if (sortable) sort = true; - this.length += toAdd.length; - if (at != null) { - for (i = 0, l = toAdd.length; i < l; i++) { - this.models.splice(at + i, 0, toAdd[i]); - } - } else { - if (order) this.models.length = 0; - var orderedModels = order || toAdd; - for (i = 0, l = orderedModels.length; i < l; i++) { - this.models.push(orderedModels[i]); - } - } - } - - // Silently sort the collection if appropriate. - if (sort) this.sort({silent: true}); - - // Unless silenced, it's time to fire all appropriate add/sort events. - if (!options.silent) { - for (i = 0, l = toAdd.length; i < l; i++) { - (model = toAdd[i]).trigger('add', model, this, options); - } - if (sort || (order && order.length)) this.trigger('sort', this, options); - } - - // Return the added (or merged) model (or models). - return singular ? models[0] : models; - }, - - // When you have more items than you want to add or remove individually, - // you can reset the entire set with a new list of models, without firing - // any granular `add` or `remove` events. Fires `reset` when finished. - // Useful for bulk operations and optimizations. - reset: function(models, options) { - options || (options = {}); - for (var i = 0, l = this.models.length; i < l; i++) { - this._removeReference(this.models[i], options); - } - options.previousModels = this.models; - this._reset(); - models = this.add(models, _.extend({silent: true}, options)); - if (!options.silent) this.trigger('reset', this, options); - return models; - }, - - // Add a model to the end of the collection. - push: function(model, options) { - return this.add(model, _.extend({at: this.length}, options)); - }, - - // Remove a model from the end of the collection. - pop: function(options) { - var model = this.at(this.length - 1); - this.remove(model, options); - return model; - }, - - // Add a model to the beginning of the collection. - unshift: function(model, options) { - return this.add(model, _.extend({at: 0}, options)); - }, - - // Remove a model from the beginning of the collection. - shift: function(options) { - var model = this.at(0); - this.remove(model, options); - return model; - }, - - // Slice out a sub-array of models from the collection. - slice: function() { - return slice.apply(this.models, arguments); - }, - - // Get a model from the set by id. - get: function(obj) { - if (obj == null) return void 0; - return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid]; - }, - - // Get the model at the given index. - at: function(index) { - return this.models[index]; - }, - - // Return models with matching attributes. Useful for simple cases of - // `filter`. - where: function(attrs, first) { - if (_.isEmpty(attrs)) return first ? void 0 : []; - return this[first ? 'find' : 'filter'](function(model) { - for (var key in attrs) { - if (attrs[key] !== model.get(key)) return false; - } - return true; - }); - }, - - // Return the first model with matching attributes. Useful for simple cases - // of `find`. - findWhere: function(attrs) { - return this.where(attrs, true); - }, - - // Force the collection to re-sort itself. You don't need to call this under - // normal circumstances, as the set will maintain sort order as each item - // is added. - sort: function(options) { - if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); - options || (options = {}); - - // Run sort based on type of `comparator`. - if (_.isString(this.comparator) || this.comparator.length === 1) { - this.models = this.sortBy(this.comparator, this); - } else { - this.models.sort(_.bind(this.comparator, this)); - } - - if (!options.silent) this.trigger('sort', this, options); - return this; - }, - - // Pluck an attribute from each model in the collection. - pluck: function(attr) { - return _.invoke(this.models, 'get', attr); - }, - - // Fetch the default set of models for this collection, resetting the - // collection when they arrive. If `reset: true` is passed, the response - // data will be passed through the `reset` method instead of `set`. - fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; - var success = options.success; - var collection = this; - options.success = function(resp) { - var method = options.reset ? 'reset' : 'set'; - collection[method](resp, options); - if (success) success(collection, resp, options); - collection.trigger('sync', collection, resp, options); - }; - wrapError(this, options); - return this.sync('read', this, options); - }, - - // Create a new instance of a model in this collection. Add the model to the - // collection immediately, unless `wait: true` is passed, in which case we - // wait for the server to agree. - create: function(model, options) { - options = options ? _.clone(options) : {}; - if (!(model = this._prepareModel(model, options))) return false; - if (!options.wait) this.add(model, options); - var collection = this; - var success = options.success; - options.success = function(model, resp) { - if (options.wait) collection.add(model, options); - if (success) success(model, resp, options); - }; - model.save(null, options); - return model; - }, - - // **parse** converts a response into a list of models to be added to the - // collection. The default implementation is just to pass it through. - parse: function(resp, options) { - return resp; - }, - - // Create a new collection with an identical list of models as this one. - clone: function() { - return new this.constructor(this.models); - }, - - // Private method to reset all internal state. Called when the collection - // is first initialized or reset. - _reset: function() { - this.length = 0; - this.models = []; - this._byId = {}; - }, - - // Prepare a hash of attributes (or other model) to be added to this - // collection. - _prepareModel: function(attrs, options) { - if (attrs instanceof Model) return attrs; - options = options ? _.clone(options) : {}; - options.collection = this; - var model = new this.model(attrs, options); - if (!model.validationError) return model; - this.trigger('invalid', this, model.validationError, options); - return false; - }, - - // Internal method to create a model's ties to a collection. - _addReference: function(model, options) { - this._byId[model.cid] = model; - if (model.id != null) this._byId[model.id] = model; - if (!model.collection) model.collection = this; - model.on('all', this._onModelEvent, this); - }, - - // Internal method to sever a model's ties to a collection. - _removeReference: function(model, options) { - if (this === model.collection) delete model.collection; - model.off('all', this._onModelEvent, this); - }, - - // Internal method called every time a model in the set fires an event. - // Sets need to update their indexes when models change ids. All other - // events simply proxy through. "add" and "remove" events that originate - // in other collections are ignored. - _onModelEvent: function(event, model, collection, options) { - if ((event === 'add' || event === 'remove') && collection !== this) return; - if (event === 'destroy') this.remove(model, options); - if (model && event === 'change:' + model.idAttribute) { - delete this._byId[model.previous(model.idAttribute)]; - if (model.id != null) this._byId[model.id] = model; - } - this.trigger.apply(this, arguments); - } - - }); - - // Underscore methods that we want to implement on the Collection. - // 90% of the core usefulness of Backbone Collections is actually implemented - // right here: - var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', - 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', - 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', - 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest', - 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle', - 'lastIndexOf', 'isEmpty', 'chain', 'sample']; - - // Mix in each Underscore method as a proxy to `Collection#models`. - _.each(methods, function(method) { - Collection.prototype[method] = function() { - var args = slice.call(arguments); - args.unshift(this.models); - return _[method].apply(_, args); - }; - }); - - // Underscore methods that take a property name as an argument. - var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy']; - - // Use attributes instead of properties. - _.each(attributeMethods, function(method) { - Collection.prototype[method] = function(value, context) { - var iterator = _.isFunction(value) ? value : function(model) { - return model.get(value); - }; - return _[method](this.models, iterator, context); - }; - }); - - // Backbone.View - // ------------- - - // Backbone Views are almost more convention than they are actual code. A View - // is simply a JavaScript object that represents a logical chunk of UI in the - // DOM. This might be a single item, an entire list, a sidebar or panel, or - // even the surrounding frame which wraps your whole app. Defining a chunk of - // UI as a **View** allows you to define your DOM events declaratively, without - // having to worry about render order ... and makes it easy for the view to - // react to specific changes in the state of your models. - - // Creating a Backbone.View creates its initial element outside of the DOM, - // if an existing element is not provided... - var View = Backbone.View = function(options) { - this.cid = _.uniqueId('view'); - options || (options = {}); - _.extend(this, _.pick(options, viewOptions)); - this._ensureElement(); - this.initialize.apply(this, arguments); - this.delegateEvents(); - }; - - // Cached regex to split keys for `delegate`. - var delegateEventSplitter = /^(\S+)\s*(.*)$/; - - // List of view options to be merged as properties. - var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; - - // Set up all inheritable **Backbone.View** properties and methods. - _.extend(View.prototype, Events, { - - // The default `tagName` of a View's element is `"div"`. - tagName: 'div', - - // jQuery delegate for element lookup, scoped to DOM elements within the - // current view. This should be preferred to global lookups where possible. - $: function(selector) { - return this.$el.find(selector); - }, - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // **render** is the core function that your view should override, in order - // to populate its element (`this.el`), with the appropriate HTML. The - // convention is for **render** to always return `this`. - render: function() { - return this; - }, - - // Remove this view by taking the element out of the DOM, and removing any - // applicable Backbone.Events listeners. - remove: function() { - this.$el.remove(); - this.stopListening(); - return this; - }, - - // Change the view's element (`this.el` property), including event - // re-delegation. - setElement: function(element, delegate) { - if (this.$el) this.undelegateEvents(); - this.$el = element instanceof Backbone.$ ? element : Backbone.$(element); - this.el = this.$el[0]; - if (delegate !== false) this.delegateEvents(); - return this; - }, - - // Set callbacks, where `this.events` is a hash of - // - // *{"event selector": "callback"}* - // - // { - // 'mousedown .title': 'edit', - // 'click .button': 'save', - // 'click .open': function(e) { ... } - // } - // - // pairs. Callbacks will be bound to the view, with `this` set properly. - // Uses event delegation for efficiency. - // Omitting the selector binds the event to `this.el`. - // This only works for delegate-able events: not `focus`, `blur`, and - // not `change`, `submit`, and `reset` in Internet Explorer. - delegateEvents: function(events) { - if (!(events || (events = _.result(this, 'events')))) return this; - this.undelegateEvents(); - for (var key in events) { - var method = events[key]; - if (!_.isFunction(method)) method = this[events[key]]; - if (!method) continue; - - var match = key.match(delegateEventSplitter); - var eventName = match[1], selector = match[2]; - method = _.bind(method, this); - eventName += '.delegateEvents' + this.cid; - if (selector === '') { - this.$el.on(eventName, method); - } else { - this.$el.on(eventName, selector, method); - } - } - return this; - }, - - // Clears all callbacks previously bound to the view with `delegateEvents`. - // You usually don't need to use this, but may wish to if you have multiple - // Backbone views attached to the same DOM element. - undelegateEvents: function() { - this.$el.off('.delegateEvents' + this.cid); - return this; - }, - - // Ensure that the View has a DOM element to render into. - // If `this.el` is a string, pass it through `$()`, take the first - // matching element, and re-assign it to `el`. Otherwise, create - // an element from the `id`, `className` and `tagName` properties. - _ensureElement: function() { - if (!this.el) { - var attrs = _.extend({}, _.result(this, 'attributes')); - if (this.id) attrs.id = _.result(this, 'id'); - if (this.className) attrs['class'] = _.result(this, 'className'); - var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs); - this.setElement($el, false); - } else { - this.setElement(_.result(this, 'el'), false); - } - } - - }); - - // Backbone.sync - // ------------- - - // Override this function to change the manner in which Backbone persists - // models to the server. You will be passed the type of request, and the - // model in question. By default, makes a RESTful Ajax request - // to the model's `url()`. Some possible customizations could be: - // - // * Use `setTimeout` to batch rapid-fire updates into a single request. - // * Send up the models as XML instead of JSON. - // * Persist models via WebSockets instead of Ajax. - // - // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests - // as `POST`, with a `_method` parameter containing the true HTTP method, - // as well as all requests with the body as `application/x-www-form-urlencoded` - // instead of `application/json` with the model in a param named `model`. - // Useful when interfacing with server-side languages like **PHP** that make - // it difficult to read the body of `PUT` requests. - Backbone.sync = function(method, model, options) { - var type = methodMap[method]; - - // Default options, unless specified. - _.defaults(options || (options = {}), { - emulateHTTP: Backbone.emulateHTTP, - emulateJSON: Backbone.emulateJSON - }); - - // Default JSON-request options. - var params = {type: type, dataType: 'json'}; - - // Ensure that we have a URL. - if (!options.url) { - params.url = _.result(model, 'url') || urlError(); - } - - // Ensure that we have the appropriate request data. - if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { - params.contentType = 'application/json'; - params.data = JSON.stringify(options.attrs || model.toJSON(options)); - } - - // For older servers, emulate JSON by encoding the request into an HTML-form. - if (options.emulateJSON) { - params.contentType = 'application/x-www-form-urlencoded'; - params.data = params.data ? {model: params.data} : {}; - } - - // For older servers, emulate HTTP by mimicking the HTTP method with `_method` - // And an `X-HTTP-Method-Override` header. - if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) { - params.type = 'POST'; - if (options.emulateJSON) params.data._method = type; - var beforeSend = options.beforeSend; - options.beforeSend = function(xhr) { - xhr.setRequestHeader('X-HTTP-Method-Override', type); - if (beforeSend) return beforeSend.apply(this, arguments); - }; - } - - // Don't process data on a non-GET request. - if (params.type !== 'GET' && !options.emulateJSON) { - params.processData = false; - } - - // If we're sending a `PATCH` request, and we're in an old Internet Explorer - // that still has ActiveX enabled by default, override jQuery to use that - // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8. - if (params.type === 'PATCH' && noXhrPatch) { - params.xhr = function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }; - } - - // Make the request, allowing the user to override any Ajax options. - var xhr = options.xhr = Backbone.ajax(_.extend(params, options)); - model.trigger('request', model, xhr, options); - return xhr; - }; - - var noXhrPatch = - typeof window !== 'undefined' && !!window.ActiveXObject && - !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent); - - // Map from CRUD to HTTP for our default `Backbone.sync` implementation. - var methodMap = { - 'create': 'POST', - 'update': 'PUT', - 'patch': 'PATCH', - 'delete': 'DELETE', - 'read': 'GET' - }; - - // Set the default implementation of `Backbone.ajax` to proxy through to `$`. - // Override this if you'd like to use a different library. - Backbone.ajax = function() { - return Backbone.$.ajax.apply(Backbone.$, arguments); - }; - - // Backbone.Router - // --------------- - - // Routers map faux-URLs to actions, and fire events when routes are - // matched. Creating a new one sets its `routes` hash, if not set statically. - var Router = Backbone.Router = function(options) { - options || (options = {}); - if (options.routes) this.routes = options.routes; - this._bindRoutes(); - this.initialize.apply(this, arguments); - }; - - // Cached regular expressions for matching named param parts and splatted - // parts of route strings. - var optionalParam = /\((.*?)\)/g; - var namedParam = /(\(\?)?:\w+/g; - var splatParam = /\*\w+/g; - var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; - - // Set up all inheritable **Backbone.Router** properties and methods. - _.extend(Router.prototype, Events, { - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // Manually bind a single named route to a callback. For example: - // - // this.route('search/:query/p:num', 'search', function(query, num) { - // ... - // }); - // - route: function(route, name, callback) { - if (!_.isRegExp(route)) route = this._routeToRegExp(route); - if (_.isFunction(name)) { - callback = name; - name = ''; - } - if (!callback) callback = this[name]; - var router = this; - Backbone.history.route(route, function(fragment) { - var args = router._extractParameters(route, fragment); - router.execute(callback, args); - router.trigger.apply(router, ['route:' + name].concat(args)); - router.trigger('route', name, args); - Backbone.history.trigger('route', router, name, args); - }); - return this; - }, - - // Execute a route handler with the provided parameters. This is an - // excellent place to do pre-route setup or post-route cleanup. - execute: function(callback, args) { - if (callback) callback.apply(this, args); - }, - - // Simple proxy to `Backbone.history` to save a fragment into the history. - navigate: function(fragment, options) { - Backbone.history.navigate(fragment, options); - return this; - }, - - // Bind all defined routes to `Backbone.history`. We have to reverse the - // order of the routes here to support behavior where the most general - // routes can be defined at the bottom of the route map. - _bindRoutes: function() { - if (!this.routes) return; - this.routes = _.result(this, 'routes'); - var route, routes = _.keys(this.routes); - while ((route = routes.pop()) != null) { - this.route(route, this.routes[route]); - } - }, - - // Convert a route string into a regular expression, suitable for matching - // against the current location hash. - _routeToRegExp: function(route) { - route = route.replace(escapeRegExp, '\\$&') - .replace(optionalParam, '(?:$1)?') - .replace(namedParam, function(match, optional) { - return optional ? match : '([^/?]+)'; - }) - .replace(splatParam, '([^?]*?)'); - return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$'); - }, - - // Given a route, and a URL fragment that it matches, return the array of - // extracted decoded parameters. Empty or unmatched parameters will be - // treated as `null` to normalize cross-browser behavior. - _extractParameters: function(route, fragment) { - var params = route.exec(fragment).slice(1); - return _.map(params, function(param, i) { - // Don't decode the search params. - if (i === params.length - 1) return param || null; - return param ? decodeURIComponent(param) : null; - }); - } - - }); - - // Backbone.History - // ---------------- - - // Handles cross-browser history management, based on either - // [pushState](http://diveintohtml5.info/history.html) and real URLs, or - // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) - // and URL fragments. If the browser supports neither (old IE, natch), - // falls back to polling. - var History = Backbone.History = function() { - this.handlers = []; - _.bindAll(this, 'checkUrl'); - - // Ensure that `History` can be used outside of the browser. - if (typeof window !== 'undefined') { - this.location = window.location; - this.history = window.history; - } - }; - - // Cached regex for stripping a leading hash/slash and trailing space. - var routeStripper = /^[#\/]|\s+$/g; - - // Cached regex for stripping leading and trailing slashes. - var rootStripper = /^\/+|\/+$/g; - - // Cached regex for detecting MSIE. - var isExplorer = /msie [\w.]+/; - - // Cached regex for removing a trailing slash. - var trailingSlash = /\/$/; - - // Cached regex for stripping urls of hash. - var pathStripper = /#.*$/; - - // Has the history handling already been started? - History.started = false; - - // Set up all inheritable **Backbone.History** properties and methods. - _.extend(History.prototype, Events, { - - // The default interval to poll for hash changes, if necessary, is - // twenty times a second. - interval: 50, - - // Are we at the app root? - atRoot: function() { - return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root; - }, - - // Gets the true hash value. Cannot use location.hash directly due to bug - // in Firefox where location.hash will always be decoded. - getHash: function(window) { - var match = (window || this).location.href.match(/#(.*)$/); - return match ? match[1] : ''; - }, - - // Get the cross-browser normalized URL fragment, either from the URL, - // the hash, or the override. - getFragment: function(fragment, forcePushState) { - if (fragment == null) { - if (this._hasPushState || !this._wantsHashChange || forcePushState) { - fragment = decodeURI(this.location.pathname + this.location.search); - var root = this.root.replace(trailingSlash, ''); - if (!fragment.indexOf(root)) fragment = fragment.slice(root.length); - } else { - fragment = this.getHash(); - } - } - return fragment.replace(routeStripper, ''); - }, - - // Start the hash change handling, returning `true` if the current URL matches - // an existing route, and `false` otherwise. - start: function(options) { - if (History.started) throw new Error("Backbone.history has already been started"); - History.started = true; - - // Figure out the initial configuration. Do we need an iframe? - // Is pushState desired ... is it available? - this.options = _.extend({root: '/'}, this.options, options); - this.root = this.options.root; - this._wantsHashChange = this.options.hashChange !== false; - this._wantsPushState = !!this.options.pushState; - this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); - var fragment = this.getFragment(); - var docMode = document.documentMode; - var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); - - // Normalize root to always include a leading and trailing slash. - this.root = ('/' + this.root + '/').replace(rootStripper, '/'); - - if (oldIE && this._wantsHashChange) { - var frame = Backbone.$('<iframe src="javascript:0" tabindex="-1">'); - this.iframe = frame.hide().appendTo('body')[0].contentWindow; - this.navigate(fragment); - } - - // Depending on whether we're using pushState or hashes, and whether - // 'onhashchange' is supported, determine how we check the URL state. - if (this._hasPushState) { - Backbone.$(window).on('popstate', this.checkUrl); - } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) { - Backbone.$(window).on('hashchange', this.checkUrl); - } else if (this._wantsHashChange) { - this._checkUrlInterval = setInterval(this.checkUrl, this.interval); - } - - // Determine if we need to change the base url, for a pushState link - // opened by a non-pushState browser. - this.fragment = fragment; - var loc = this.location; - - // Transition from hashChange to pushState or vice versa if both are - // requested. - if (this._wantsHashChange && this._wantsPushState) { - - // If we've started off with a route from a `pushState`-enabled - // browser, but we're currently in a browser that doesn't support it... - if (!this._hasPushState && !this.atRoot()) { - this.fragment = this.getFragment(null, true); - this.location.replace(this.root + '#' + this.fragment); - // Return immediately as browser will do redirect to new url - return true; - - // Or if we've started out with a hash-based route, but we're currently - // in a browser where it could be `pushState`-based instead... - } else if (this._hasPushState && this.atRoot() && loc.hash) { - this.fragment = this.getHash().replace(routeStripper, ''); - this.history.replaceState({}, document.title, this.root + this.fragment); - } - - } - - if (!this.options.silent) return this.loadUrl(); - }, - - // Disable Backbone.history, perhaps temporarily. Not useful in a real app, - // but possibly useful for unit testing Routers. - stop: function() { - Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl); - if (this._checkUrlInterval) clearInterval(this._checkUrlInterval); - History.started = false; - }, - - // Add a route to be tested when the fragment changes. Routes added later - // may override previous routes. - route: function(route, callback) { - this.handlers.unshift({route: route, callback: callback}); - }, - - // Checks the current URL to see if it has changed, and if it has, - // calls `loadUrl`, normalizing across the hidden iframe. - checkUrl: function(e) { - var current = this.getFragment(); - if (current === this.fragment && this.iframe) { - current = this.getFragment(this.getHash(this.iframe)); - } - if (current === this.fragment) return false; - if (this.iframe) this.navigate(current); - this.loadUrl(); - }, - - // Attempt to load the current URL fragment. If a route succeeds with a - // match, returns `true`. If no defined routes matches the fragment, - // returns `false`. - loadUrl: function(fragment) { - fragment = this.fragment = this.getFragment(fragment); - return _.any(this.handlers, function(handler) { - if (handler.route.test(fragment)) { - handler.callback(fragment); - return true; - } - }); - }, - - // Save a fragment into the hash history, or replace the URL state if the - // 'replace' option is passed. You are responsible for properly URL-encoding - // the fragment in advance. - // - // The options object can contain `trigger: true` if you wish to have the - // route callback be fired (not usually desirable), or `replace: true`, if - // you wish to modify the current URL without adding an entry to the history. - navigate: function(fragment, options) { - if (!History.started) return false; - if (!options || options === true) options = {trigger: !!options}; - - var url = this.root + (fragment = this.getFragment(fragment || '')); - - // Strip the hash for matching. - fragment = fragment.replace(pathStripper, ''); - - if (this.fragment === fragment) return; - this.fragment = fragment; - - // Don't include a trailing slash on the root. - if (fragment === '' && url !== '/') url = url.slice(0, -1); - - // If pushState is available, we use it to set the fragment as a real URL. - if (this._hasPushState) { - this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url); - - // If hash changes haven't been explicitly disabled, update the hash - // fragment to store history. - } else if (this._wantsHashChange) { - this._updateHash(this.location, fragment, options.replace); - if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) { - // Opening and closing the iframe tricks IE7 and earlier to push a - // history entry on hash-tag change. When replace is true, we don't - // want this. - if(!options.replace) this.iframe.document.open().close(); - this._updateHash(this.iframe.location, fragment, options.replace); - } - - // If you've told us that you explicitly don't want fallback hashchange- - // based history, then `navigate` becomes a page refresh. - } else { - return this.location.assign(url); - } - if (options.trigger) return this.loadUrl(fragment); - }, - - // Update the hash location, either replacing the current entry, or adding - // a new one to the browser history. - _updateHash: function(location, fragment, replace) { - if (replace) { - var href = location.href.replace(/(javascript:|#).*$/, ''); - location.replace(href + '#' + fragment); - } else { - // Some browsers require that `hash` contains a leading #. - location.hash = '#' + fragment; - } - } - - }); - - // Create the default Backbone.history. - Backbone.history = new History; - - // Helpers - // ------- - - // Helper function to correctly set up the prototype chain, for subclasses. - // Similar to `goog.inherits`, but uses a hash of prototype properties and - // class properties to be extended. - var extend = function(protoProps, staticProps) { - var parent = this; - var child; - - // The constructor function for the new subclass is either defined by you - // (the "constructor" property in your `extend` definition), or defaulted - // by us to simply call the parent's constructor. - if (protoProps && _.has(protoProps, 'constructor')) { - child = protoProps.constructor; - } else { - child = function(){ return parent.apply(this, arguments); }; - } - - // Add static properties to the constructor function, if supplied. - _.extend(child, parent, staticProps); - - // Set the prototype chain to inherit from `parent`, without calling - // `parent`'s constructor function. - var Surrogate = function(){ this.constructor = child; }; - Surrogate.prototype = parent.prototype; - child.prototype = new Surrogate; - - // Add prototype properties (instance properties) to the subclass, - // if supplied. - if (protoProps) _.extend(child.prototype, protoProps); - - // Set a convenience property in case the parent's prototype is needed - // later. - child.__super__ = parent.prototype; - - return child; - }; - - // Set up inheritance for the model, collection, router, view and history. - Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend; - - // Throw an error when a URL is needed, and none is supplied. - var urlError = function() { - throw new Error('A "url" property or function must be specified'); - }; - - // Wrap an optional error callback with a fallback error event. - var wrapError = function(model, options) { - var error = options.error; - options.error = function(resp) { - if (error) error(model, resp, options); - model.trigger('error', model, resp, options); - }; - }; - - return Backbone; - -})); diff --git a/server/sonar-web/src/main/js/libs/third-party/backbone.marionette.js b/server/sonar-web/src/main/js/libs/third-party/backbone.marionette.js deleted file mode 100644 index d0e801ddcfa..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/backbone.marionette.js +++ /dev/null @@ -1,3819 +0,0 @@ -// MarionetteJS (Backbone.Marionette) -// ---------------------------------- -// v2.4.1 -// -// Copyright (c)2015 Derick Bailey, Muted Solutions, LLC. -// Distributed under MIT license -// -// http://marionettejs.com - - -/*! - * Includes BabySitter - * https://github.com/marionettejs/backbone.babysitter/ - * - * Includes Wreqr - * https://github.com/marionettejs/backbone.wreqr/ - */ - - -(function(root, factory) { - - /* istanbul ignore next */ - if (typeof define === 'function' && define.amd) { - define(['backbone', 'underscore'], function(Backbone, _) { - return (root.Marionette = root.Mn = factory(root, Backbone, _)); - }); - } else if (typeof exports !== 'undefined') { - var Backbone = require('backbone'); - var _ = require('underscore'); - module.exports = factory(root, Backbone, _); - } else { - root.Marionette = root.Mn = factory(root, root.Backbone, root._); - } - -}(this, function(root, Backbone, _) { - 'use strict'; - - /* istanbul ignore next */ - // Backbone.BabySitter - // ------------------- - // v0.1.6 - // - // Copyright (c)2015 Derick Bailey, Muted Solutions, LLC. - // Distributed under MIT license - // - // http://github.com/marionettejs/backbone.babysitter - (function(Backbone, _) { - "use strict"; - var previousChildViewContainer = Backbone.ChildViewContainer; - // BabySitter.ChildViewContainer - // ----------------------------- - // - // Provide a container to store, retrieve and - // shut down child views. - Backbone.ChildViewContainer = function(Backbone, _) { - // Container Constructor - // --------------------- - var Container = function(views) { - this._views = {}; - this._indexByModel = {}; - this._indexByCustom = {}; - this._updateLength(); - _.each(views, this.add, this); - }; - // Container Methods - // ----------------- - _.extend(Container.prototype, { - // Add a view to this container. Stores the view - // by `cid` and makes it searchable by the model - // cid (and model itself). Optionally specify - // a custom key to store an retrieve the view. - add: function(view, customIndex) { - var viewCid = view.cid; - // store the view - this._views[viewCid] = view; - // index it by model - if (view.model) { - this._indexByModel[view.model.cid] = viewCid; - } - // index by custom - if (customIndex) { - this._indexByCustom[customIndex] = viewCid; - } - this._updateLength(); - return this; - }, - // Find a view by the model that was attached to - // it. Uses the model's `cid` to find it. - findByModel: function(model) { - return this.findByModelCid(model.cid); - }, - // Find a view by the `cid` of the model that was attached to - // it. Uses the model's `cid` to find the view `cid` and - // retrieve the view using it. - findByModelCid: function(modelCid) { - var viewCid = this._indexByModel[modelCid]; - return this.findByCid(viewCid); - }, - // Find a view by a custom indexer. - findByCustom: function(index) { - var viewCid = this._indexByCustom[index]; - return this.findByCid(viewCid); - }, - // Find by index. This is not guaranteed to be a - // stable index. - findByIndex: function(index) { - return _.values(this._views)[index]; - }, - // retrieve a view by its `cid` directly - findByCid: function(cid) { - return this._views[cid]; - }, - // Remove a view - remove: function(view) { - var viewCid = view.cid; - // delete model index - if (view.model) { - delete this._indexByModel[view.model.cid]; - } - // delete custom index - _.any(this._indexByCustom, function(cid, key) { - if (cid === viewCid) { - delete this._indexByCustom[key]; - return true; - } - }, this); - // remove the view from the container - delete this._views[viewCid]; - // update the length - this._updateLength(); - return this; - }, - // Call a method on every view in the container, - // passing parameters to the call method one at a - // time, like `function.call`. - call: function(method) { - this.apply(method, _.tail(arguments)); - }, - // Apply a method on every view in the container, - // passing parameters to the call method one at a - // time, like `function.apply`. - apply: function(method, args) { - _.each(this._views, function(view) { - if (_.isFunction(view[method])) { - view[method].apply(view, args || []); - } - }); - }, - // Update the `.length` attribute on this container - _updateLength: function() { - this.length = _.size(this._views); - } - }); - // Borrowing this code from Backbone.Collection: - // http://backbonejs.org/docs/backbone.html#section-106 - // - // Mix in methods from Underscore, for iteration, and other - // collection related features. - var methods = [ "forEach", "each", "map", "find", "detect", "filter", "select", "reject", "every", "all", "some", "any", "include", "contains", "invoke", "toArray", "first", "initial", "rest", "last", "without", "isEmpty", "pluck", "reduce" ]; - _.each(methods, function(method) { - Container.prototype[method] = function() { - var views = _.values(this._views); - var args = [ views ].concat(_.toArray(arguments)); - return _[method].apply(_, args); - }; - }); - // return the public API - return Container; - }(Backbone, _); - Backbone.ChildViewContainer.VERSION = "0.1.6"; - Backbone.ChildViewContainer.noConflict = function() { - Backbone.ChildViewContainer = previousChildViewContainer; - return this; - }; - return Backbone.ChildViewContainer; - })(Backbone, _); - - /* istanbul ignore next */ - // Backbone.Wreqr (Backbone.Marionette) - // ---------------------------------- - // v1.3.1 - // - // Copyright (c)2014 Derick Bailey, Muted Solutions, LLC. - // Distributed under MIT license - // - // http://github.com/marionettejs/backbone.wreqr - (function(Backbone, _) { - "use strict"; - var previousWreqr = Backbone.Wreqr; - var Wreqr = Backbone.Wreqr = {}; - Backbone.Wreqr.VERSION = "1.3.1"; - Backbone.Wreqr.noConflict = function() { - Backbone.Wreqr = previousWreqr; - return this; - }; - // Handlers - // -------- - // A registry of functions to call, given a name - Wreqr.Handlers = function(Backbone, _) { - "use strict"; - // Constructor - // ----------- - var Handlers = function(options) { - this.options = options; - this._wreqrHandlers = {}; - if (_.isFunction(this.initialize)) { - this.initialize(options); - } - }; - Handlers.extend = Backbone.Model.extend; - // Instance Members - // ---------------- - _.extend(Handlers.prototype, Backbone.Events, { - // Add multiple handlers using an object literal configuration - setHandlers: function(handlers) { - _.each(handlers, function(handler, name) { - var context = null; - if (_.isObject(handler) && !_.isFunction(handler)) { - context = handler.context; - handler = handler.callback; - } - this.setHandler(name, handler, context); - }, this); - }, - // Add a handler for the given name, with an - // optional context to run the handler within - setHandler: function(name, handler, context) { - var config = { - callback: handler, - context: context - }; - this._wreqrHandlers[name] = config; - this.trigger("handler:add", name, handler, context); - }, - // Determine whether or not a handler is registered - hasHandler: function(name) { - return !!this._wreqrHandlers[name]; - }, - // Get the currently registered handler for - // the specified name. Throws an exception if - // no handler is found. - getHandler: function(name) { - var config = this._wreqrHandlers[name]; - if (!config) { - return; - } - return function() { - var args = Array.prototype.slice.apply(arguments); - return config.callback.apply(config.context, args); - }; - }, - // Remove a handler for the specified name - removeHandler: function(name) { - delete this._wreqrHandlers[name]; - }, - // Remove all handlers from this registry - removeAllHandlers: function() { - this._wreqrHandlers = {}; - } - }); - return Handlers; - }(Backbone, _); - // Wreqr.CommandStorage - // -------------------- - // - // Store and retrieve commands for execution. - Wreqr.CommandStorage = function() { - "use strict"; - // Constructor function - var CommandStorage = function(options) { - this.options = options; - this._commands = {}; - if (_.isFunction(this.initialize)) { - this.initialize(options); - } - }; - // Instance methods - _.extend(CommandStorage.prototype, Backbone.Events, { - // Get an object literal by command name, that contains - // the `commandName` and the `instances` of all commands - // represented as an array of arguments to process - getCommands: function(commandName) { - var commands = this._commands[commandName]; - // we don't have it, so add it - if (!commands) { - // build the configuration - commands = { - command: commandName, - instances: [] - }; - // store it - this._commands[commandName] = commands; - } - return commands; - }, - // Add a command by name, to the storage and store the - // args for the command - addCommand: function(commandName, args) { - var command = this.getCommands(commandName); - command.instances.push(args); - }, - // Clear all commands for the given `commandName` - clearCommands: function(commandName) { - var command = this.getCommands(commandName); - command.instances = []; - } - }); - return CommandStorage; - }(); - // Wreqr.Commands - // -------------- - // - // A simple command pattern implementation. Register a command - // handler and execute it. - Wreqr.Commands = function(Wreqr) { - "use strict"; - return Wreqr.Handlers.extend({ - // default storage type - storageType: Wreqr.CommandStorage, - constructor: function(options) { - this.options = options || {}; - this._initializeStorage(this.options); - this.on("handler:add", this._executeCommands, this); - var args = Array.prototype.slice.call(arguments); - Wreqr.Handlers.prototype.constructor.apply(this, args); - }, - // Execute a named command with the supplied args - execute: function(name, args) { - name = arguments[0]; - args = Array.prototype.slice.call(arguments, 1); - if (this.hasHandler(name)) { - this.getHandler(name).apply(this, args); - } else { - this.storage.addCommand(name, args); - } - }, - // Internal method to handle bulk execution of stored commands - _executeCommands: function(name, handler, context) { - var command = this.storage.getCommands(name); - // loop through and execute all the stored command instances - _.each(command.instances, function(args) { - handler.apply(context, args); - }); - this.storage.clearCommands(name); - }, - // Internal method to initialize storage either from the type's - // `storageType` or the instance `options.storageType`. - _initializeStorage: function(options) { - var storage; - var StorageType = options.storageType || this.storageType; - if (_.isFunction(StorageType)) { - storage = new StorageType(); - } else { - storage = StorageType; - } - this.storage = storage; - } - }); - }(Wreqr); - // Wreqr.RequestResponse - // --------------------- - // - // A simple request/response implementation. Register a - // request handler, and return a response from it - Wreqr.RequestResponse = function(Wreqr) { - "use strict"; - return Wreqr.Handlers.extend({ - request: function() { - var name = arguments[0]; - var args = Array.prototype.slice.call(arguments, 1); - if (this.hasHandler(name)) { - return this.getHandler(name).apply(this, args); - } - } - }); - }(Wreqr); - // Event Aggregator - // ---------------- - // A pub-sub object that can be used to decouple various parts - // of an application through event-driven architecture. - Wreqr.EventAggregator = function(Backbone, _) { - "use strict"; - var EA = function() {}; - // Copy the `extend` function used by Backbone's classes - EA.extend = Backbone.Model.extend; - // Copy the basic Backbone.Events on to the event aggregator - _.extend(EA.prototype, Backbone.Events); - return EA; - }(Backbone, _); - // Wreqr.Channel - // -------------- - // - // An object that wraps the three messaging systems: - // EventAggregator, RequestResponse, Commands - Wreqr.Channel = function(Wreqr) { - "use strict"; - var Channel = function(channelName) { - this.vent = new Backbone.Wreqr.EventAggregator(); - this.reqres = new Backbone.Wreqr.RequestResponse(); - this.commands = new Backbone.Wreqr.Commands(); - this.channelName = channelName; - }; - _.extend(Channel.prototype, { - // Remove all handlers from the messaging systems of this channel - reset: function() { - this.vent.off(); - this.vent.stopListening(); - this.reqres.removeAllHandlers(); - this.commands.removeAllHandlers(); - return this; - }, - // Connect a hash of events; one for each messaging system - connectEvents: function(hash, context) { - this._connect("vent", hash, context); - return this; - }, - connectCommands: function(hash, context) { - this._connect("commands", hash, context); - return this; - }, - connectRequests: function(hash, context) { - this._connect("reqres", hash, context); - return this; - }, - // Attach the handlers to a given message system `type` - _connect: function(type, hash, context) { - if (!hash) { - return; - } - context = context || this; - var method = type === "vent" ? "on" : "setHandler"; - _.each(hash, function(fn, eventName) { - this[type][method](eventName, _.bind(fn, context)); - }, this); - } - }); - return Channel; - }(Wreqr); - // Wreqr.Radio - // -------------- - // - // An object that lets you communicate with many channels. - Wreqr.radio = function(Wreqr) { - "use strict"; - var Radio = function() { - this._channels = {}; - this.vent = {}; - this.commands = {}; - this.reqres = {}; - this._proxyMethods(); - }; - _.extend(Radio.prototype, { - channel: function(channelName) { - if (!channelName) { - throw new Error("Channel must receive a name"); - } - return this._getChannel(channelName); - }, - _getChannel: function(channelName) { - var channel = this._channels[channelName]; - if (!channel) { - channel = new Wreqr.Channel(channelName); - this._channels[channelName] = channel; - } - return channel; - }, - _proxyMethods: function() { - _.each([ "vent", "commands", "reqres" ], function(system) { - _.each(messageSystems[system], function(method) { - this[system][method] = proxyMethod(this, system, method); - }, this); - }, this); - } - }); - var messageSystems = { - vent: [ "on", "off", "trigger", "once", "stopListening", "listenTo", "listenToOnce" ], - commands: [ "execute", "setHandler", "setHandlers", "removeHandler", "removeAllHandlers" ], - reqres: [ "request", "setHandler", "setHandlers", "removeHandler", "removeAllHandlers" ] - }; - var proxyMethod = function(radio, system, method) { - return function(channelName) { - var messageSystem = radio._getChannel(channelName)[system]; - var args = Array.prototype.slice.call(arguments, 1); - return messageSystem[method].apply(messageSystem, args); - }; - }; - return new Radio(); - }(Wreqr); - return Backbone.Wreqr; - })(Backbone, _); - - var previousMarionette = root.Marionette; - var previousMn = root.Mn; - - var Marionette = Backbone.Marionette = {}; - - Marionette.VERSION = '2.4.1'; - - Marionette.noConflict = function() { - root.Marionette = previousMarionette; - root.Mn = previousMn; - return this; - }; - - Backbone.Marionette = Marionette; - - // Get the Deferred creator for later use - Marionette.Deferred = Backbone.$.Deferred; - - /* jshint unused: false *//* global console */ - - // Helpers - // ------- - - // Marionette.extend - // ----------------- - - // Borrow the Backbone `extend` method so we can use it as needed - Marionette.extend = Backbone.Model.extend; - - // Marionette.isNodeAttached - // ------------------------- - - // Determine if `el` is a child of the document - Marionette.isNodeAttached = function(el) { - return Backbone.$.contains(document.documentElement, el); - }; - - // Merge `keys` from `options` onto `this` - Marionette.mergeOptions = function(options, keys) { - if (!options) { return; } - _.extend(this, _.pick(options, keys)); - }; - - // Marionette.getOption - // -------------------- - - // Retrieve an object, function or other value from a target - // object or its `options`, with `options` taking precedence. - Marionette.getOption = function(target, optionName) { - if (!target || !optionName) { return; } - if (target.options && (target.options[optionName] !== undefined)) { - return target.options[optionName]; - } else { - return target[optionName]; - } - }; - - // Proxy `Marionette.getOption` - Marionette.proxyGetOption = function(optionName) { - return Marionette.getOption(this, optionName); - }; - - // Similar to `_.result`, this is a simple helper - // If a function is provided we call it with context - // otherwise just return the value. If the value is - // undefined return a default value - Marionette._getValue = function(value, context, params) { - if (_.isFunction(value)) { - value = params ? value.apply(context, params) : value.call(context); - } - return value; - }; - - // Marionette.normalizeMethods - // ---------------------- - - // Pass in a mapping of events => functions or function names - // and return a mapping of events => functions - Marionette.normalizeMethods = function(hash) { - return _.reduce(hash, function(normalizedHash, method, name) { - if (!_.isFunction(method)) { - method = this[method]; - } - if (method) { - normalizedHash[name] = method; - } - return normalizedHash; - }, {}, this); - }; - - // utility method for parsing @ui. syntax strings - // into associated selector - Marionette.normalizeUIString = function(uiString, ui) { - return uiString.replace(/@ui\.[a-zA-Z_$0-9]*/g, function(r) { - return ui[r.slice(4)]; - }); - }; - - // allows for the use of the @ui. syntax within - // a given key for triggers and events - // swaps the @ui with the associated selector. - // Returns a new, non-mutated, parsed events hash. - Marionette.normalizeUIKeys = function(hash, ui) { - return _.reduce(hash, function(memo, val, key) { - var normalizedKey = Marionette.normalizeUIString(key, ui); - memo[normalizedKey] = val; - return memo; - }, {}); - }; - - // allows for the use of the @ui. syntax within - // a given value for regions - // swaps the @ui with the associated selector - Marionette.normalizeUIValues = function(hash, ui, properties) { - _.each(hash, function(val, key) { - if (_.isString(val)) { - hash[key] = Marionette.normalizeUIString(val, ui); - } else if (_.isObject(val) && _.isArray(properties)) { - _.extend(val, Marionette.normalizeUIValues(_.pick(val, properties), ui)); - /* Value is an object, and we got an array of embedded property names to normalize. */ - _.each(properties, function(property) { - var propertyVal = val[property]; - if (_.isString(propertyVal)) { - val[property] = Marionette.normalizeUIString(propertyVal, ui); - } - }); - } - }); - return hash; - }; - - // Mix in methods from Underscore, for iteration, and other - // collection related features. - // Borrowing this code from Backbone.Collection: - // http://backbonejs.org/docs/backbone.html#section-121 - Marionette.actAsCollection = function(object, listProperty) { - var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter', - 'select', 'reject', 'every', 'all', 'some', 'any', 'include', - 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest', - 'last', 'without', 'isEmpty', 'pluck']; - - _.each(methods, function(method) { - object[method] = function() { - var list = _.values(_.result(this, listProperty)); - var args = [list].concat(_.toArray(arguments)); - return _[method].apply(_, args); - }; - }); - }; - - var deprecate = Marionette.deprecate = function(message, test) { - if (_.isObject(message)) { - message = ( - message.prev + ' is going to be removed in the future. ' + - 'Please use ' + message.next + ' instead.' + - (message.url ? ' See: ' + message.url : '') - ); - } - - if ((test === undefined || !test) && !deprecate._cache[message]) { - deprecate._warn('Deprecation warning: ' + message); - deprecate._cache[message] = true; - } - }; - - deprecate._warn = typeof console !== 'undefined' && (console.warn || console.log) || function() {}; - deprecate._cache = {}; - - /* jshint maxstatements: 14, maxcomplexity: 7 */ - - // Trigger Method - // -------------- - - Marionette._triggerMethod = (function() { - // split the event name on the ":" - var splitter = /(^|:)(\w)/gi; - - // take the event section ("section1:section2:section3") - // and turn it in to uppercase name - function getEventName(match, prefix, eventName) { - return eventName.toUpperCase(); - } - - return function(context, event, args) { - var noEventArg = arguments.length < 3; - if (noEventArg) { - args = event; - event = args[0]; - } - - // get the method name from the event name - var methodName = 'on' + event.replace(splitter, getEventName); - var method = context[methodName]; - var result; - - // call the onMethodName if it exists - if (_.isFunction(method)) { - // pass all args, except the event name - result = method.apply(context, noEventArg ? _.rest(args) : args); - } - - // trigger the event, if a trigger method exists - if (_.isFunction(context.trigger)) { - if (noEventArg + args.length > 1) { - context.trigger.apply(context, noEventArg ? args : [event].concat(_.drop(args, 0))); - } else { - context.trigger(event); - } - } - - return result; - }; - })(); - - // Trigger an event and/or a corresponding method name. Examples: - // - // `this.triggerMethod("foo")` will trigger the "foo" event and - // call the "onFoo" method. - // - // `this.triggerMethod("foo:bar")` will trigger the "foo:bar" event and - // call the "onFooBar" method. - Marionette.triggerMethod = function(event) { - return Marionette._triggerMethod(this, arguments); - }; - - // triggerMethodOn invokes triggerMethod on a specific context - // - // e.g. `Marionette.triggerMethodOn(view, 'show')` - // will trigger a "show" event or invoke onShow the view. - Marionette.triggerMethodOn = function(context) { - var fnc = _.isFunction(context.triggerMethod) ? - context.triggerMethod : - Marionette.triggerMethod; - - return fnc.apply(context, _.rest(arguments)); - }; - - // DOM Refresh - // ----------- - - // Monitor a view's state, and after it has been rendered and shown - // in the DOM, trigger a "dom:refresh" event every time it is - // re-rendered. - - Marionette.MonitorDOMRefresh = function(view) { - - // track when the view has been shown in the DOM, - // using a Marionette.Region (or by other means of triggering "show") - function handleShow() { - view._isShown = true; - triggerDOMRefresh(); - } - - // track when the view has been rendered - function handleRender() { - view._isRendered = true; - triggerDOMRefresh(); - } - - // Trigger the "dom:refresh" event and corresponding "onDomRefresh" method - function triggerDOMRefresh() { - if (view._isShown && view._isRendered && Marionette.isNodeAttached(view.el)) { - if (_.isFunction(view.triggerMethod)) { - view.triggerMethod('dom:refresh'); - } - } - } - - view.on({ - show: handleShow, - render: handleRender - }); - }; - - /* jshint maxparams: 5 */ - - // Bind Entity Events & Unbind Entity Events - // ----------------------------------------- - // - // These methods are used to bind/unbind a backbone "entity" (e.g. collection/model) - // to methods on a target object. - // - // The first parameter, `target`, must have the Backbone.Events module mixed in. - // - // The second parameter is the `entity` (Backbone.Model, Backbone.Collection or - // any object that has Backbone.Events mixed in) to bind the events from. - // - // The third parameter is a hash of { "event:name": "eventHandler" } - // configuration. Multiple handlers can be separated by a space. A - // function can be supplied instead of a string handler name. - - (function(Marionette) { - 'use strict'; - - // Bind the event to handlers specified as a string of - // handler names on the target object - function bindFromStrings(target, entity, evt, methods) { - var methodNames = methods.split(/\s+/); - - _.each(methodNames, function(methodName) { - - var method = target[methodName]; - if (!method) { - throw new Marionette.Error('Method "' + methodName + - '" was configured as an event handler, but does not exist.'); - } - - target.listenTo(entity, evt, method); - }); - } - - // Bind the event to a supplied callback function - function bindToFunction(target, entity, evt, method) { - target.listenTo(entity, evt, method); - } - - // Bind the event to handlers specified as a string of - // handler names on the target object - function unbindFromStrings(target, entity, evt, methods) { - var methodNames = methods.split(/\s+/); - - _.each(methodNames, function(methodName) { - var method = target[methodName]; - target.stopListening(entity, evt, method); - }); - } - - // Bind the event to a supplied callback function - function unbindToFunction(target, entity, evt, method) { - target.stopListening(entity, evt, method); - } - - // generic looping function - function iterateEvents(target, entity, bindings, functionCallback, stringCallback) { - if (!entity || !bindings) { return; } - - // type-check bindings - if (!_.isObject(bindings)) { - throw new Marionette.Error({ - message: 'Bindings must be an object or function.', - url: 'marionette.functions.html#marionettebindentityevents' - }); - } - - // allow the bindings to be a function - bindings = Marionette._getValue(bindings, target); - - // iterate the bindings and bind them - _.each(bindings, function(methods, evt) { - - // allow for a function as the handler, - // or a list of event names as a string - if (_.isFunction(methods)) { - functionCallback(target, entity, evt, methods); - } else { - stringCallback(target, entity, evt, methods); - } - - }); - } - - // Export Public API - Marionette.bindEntityEvents = function(target, entity, bindings) { - iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings); - }; - - Marionette.unbindEntityEvents = function(target, entity, bindings) { - iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings); - }; - - // Proxy `bindEntityEvents` - Marionette.proxyBindEntityEvents = function(entity, bindings) { - return Marionette.bindEntityEvents(this, entity, bindings); - }; - - // Proxy `unbindEntityEvents` - Marionette.proxyUnbindEntityEvents = function(entity, bindings) { - return Marionette.unbindEntityEvents(this, entity, bindings); - }; - })(Marionette); - - - // Error - // ----- - - var errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number']; - - Marionette.Error = Marionette.extend.call(Error, { - urlRoot: 'http://marionettejs.com/docs/v' + Marionette.VERSION + '/', - - constructor: function(message, options) { - if (_.isObject(message)) { - options = message; - message = options.message; - } else if (!options) { - options = {}; - } - - var error = Error.call(this, message); - _.extend(this, _.pick(error, errorProps), _.pick(options, errorProps)); - - this.captureStackTrace(); - - if (options.url) { - this.url = this.urlRoot + options.url; - } - }, - - captureStackTrace: function() { - if (Error.captureStackTrace) { - Error.captureStackTrace(this, Marionette.Error); - } - }, - - toString: function() { - return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : ''); - } - }); - - Marionette.Error.extend = Marionette.extend; - - // Callbacks - // --------- - - // A simple way of managing a collection of callbacks - // and executing them at a later point in time, using jQuery's - // `Deferred` object. - Marionette.Callbacks = function() { - this._deferred = Marionette.Deferred(); - this._callbacks = []; - }; - - _.extend(Marionette.Callbacks.prototype, { - - // Add a callback to be executed. Callbacks added here are - // guaranteed to execute, even if they are added after the - // `run` method is called. - add: function(callback, contextOverride) { - var promise = _.result(this._deferred, 'promise'); - - this._callbacks.push({cb: callback, ctx: contextOverride}); - - promise.then(function(args) { - if (contextOverride) { args.context = contextOverride; } - callback.call(args.context, args.options); - }); - }, - - // Run all registered callbacks with the context specified. - // Additional callbacks can be added after this has been run - // and they will still be executed. - run: function(options, context) { - this._deferred.resolve({ - options: options, - context: context - }); - }, - - // Resets the list of callbacks to be run, allowing the same list - // to be run multiple times - whenever the `run` method is called. - reset: function() { - var callbacks = this._callbacks; - this._deferred = Marionette.Deferred(); - this._callbacks = []; - - _.each(callbacks, function(cb) { - this.add(cb.cb, cb.ctx); - }, this); - } - }); - - // Controller - // ---------- - - // A multi-purpose object to use as a controller for - // modules and routers, and as a mediator for workflow - // and coordination of other objects, views, and more. - Marionette.Controller = function(options) { - this.options = options || {}; - - if (_.isFunction(this.initialize)) { - this.initialize(this.options); - } - }; - - Marionette.Controller.extend = Marionette.extend; - - // Controller Methods - // -------------- - - // Ensure it can trigger events with Backbone.Events - _.extend(Marionette.Controller.prototype, Backbone.Events, { - destroy: function() { - Marionette._triggerMethod(this, 'before:destroy', arguments); - Marionette._triggerMethod(this, 'destroy', arguments); - - this.stopListening(); - this.off(); - return this; - }, - - // import the `triggerMethod` to trigger events with corresponding - // methods if the method exists - triggerMethod: Marionette.triggerMethod, - - // A handy way to merge options onto the instance - mergeOptions: Marionette.mergeOptions, - - // Proxy `getOption` to enable getting options from this or this.options by name. - getOption: Marionette.proxyGetOption - - }); - - // Object - // ------ - - // A Base Class that other Classes should descend from. - // Object borrows many conventions and utilities from Backbone. - Marionette.Object = function(options) { - this.options = _.extend({}, _.result(this, 'options'), options); - - this.initialize.apply(this, arguments); - }; - - Marionette.Object.extend = Marionette.extend; - - // Object Methods - // -------------- - - // Ensure it can trigger events with Backbone.Events - _.extend(Marionette.Object.prototype, Backbone.Events, { - - //this is a noop method intended to be overridden by classes that extend from this base - initialize: function() {}, - - destroy: function() { - this.triggerMethod('before:destroy'); - this.triggerMethod('destroy'); - this.stopListening(); - - return this; - }, - - // Import the `triggerMethod` to trigger events with corresponding - // methods if the method exists - triggerMethod: Marionette.triggerMethod, - - // A handy way to merge options onto the instance - mergeOptions: Marionette.mergeOptions, - - // Proxy `getOption` to enable getting options from this or this.options by name. - getOption: Marionette.proxyGetOption, - - // Proxy `bindEntityEvents` to enable binding view's events from another entity. - bindEntityEvents: Marionette.proxyBindEntityEvents, - - // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity. - unbindEntityEvents: Marionette.proxyUnbindEntityEvents - }); - - /* jshint maxcomplexity: 16, maxstatements: 45, maxlen: 120 */ - - // Region - // ------ - - // Manage the visual regions of your composite application. See - // http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/ - - Marionette.Region = Marionette.Object.extend({ - constructor: function(options) { - - // set options temporarily so that we can get `el`. - // options will be overriden by Object.constructor - this.options = options || {}; - this.el = this.getOption('el'); - - // Handle when this.el is passed in as a $ wrapped element. - this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el; - - if (!this.el) { - throw new Marionette.Error({ - name: 'NoElError', - message: 'An "el" must be specified for a region.' - }); - } - - this.$el = this.getEl(this.el); - Marionette.Object.call(this, options); - }, - - // Displays a backbone view instance inside of the region. - // Handles calling the `render` method for you. Reads content - // directly from the `el` attribute. Also calls an optional - // `onShow` and `onDestroy` method on your view, just after showing - // or just before destroying the view, respectively. - // The `preventDestroy` option can be used to prevent a view from - // the old view being destroyed on show. - // The `forceShow` option can be used to force a view to be - // re-rendered if it's already shown in the region. - show: function(view, options) { - if (!this._ensureElement()) { - return; - } - - this._ensureViewIsIntact(view); - - var showOptions = options || {}; - var isDifferentView = view !== this.currentView; - var preventDestroy = !!showOptions.preventDestroy; - var forceShow = !!showOptions.forceShow; - - // We are only changing the view if there is a current view to change to begin with - var isChangingView = !!this.currentView; - - // Only destroy the current view if we don't want to `preventDestroy` and if - // the view given in the first argument is different than `currentView` - var _shouldDestroyView = isDifferentView && !preventDestroy; - - // Only show the view given in the first argument if it is different than - // the current view or if we want to re-show the view. Note that if - // `_shouldDestroyView` is true, then `_shouldShowView` is also necessarily true. - var _shouldShowView = isDifferentView || forceShow; - - if (isChangingView) { - this.triggerMethod('before:swapOut', this.currentView, this, options); - } - - if (this.currentView) { - delete this.currentView._parent; - } - - if (_shouldDestroyView) { - this.empty(); - - // A `destroy` event is attached to the clean up manually removed views. - // We need to detach this event when a new view is going to be shown as it - // is no longer relevant. - } else if (isChangingView && _shouldShowView) { - this.currentView.off('destroy', this.empty, this); - } - - if (_shouldShowView) { - - // We need to listen for if a view is destroyed - // in a way other than through the region. - // If this happens we need to remove the reference - // to the currentView since once a view has been destroyed - // we can not reuse it. - view.once('destroy', this.empty, this); - view.render(); - - view._parent = this; - - if (isChangingView) { - this.triggerMethod('before:swap', view, this, options); - } - - this.triggerMethod('before:show', view, this, options); - Marionette.triggerMethodOn(view, 'before:show', view, this, options); - - if (isChangingView) { - this.triggerMethod('swapOut', this.currentView, this, options); - } - - // An array of views that we're about to display - var attachedRegion = Marionette.isNodeAttached(this.el); - - // The views that we're about to attach to the document - // It's important that we prevent _getNestedViews from being executed unnecessarily - // as it's a potentially-slow method - var displayedViews = []; - - var triggerBeforeAttach = showOptions.triggerBeforeAttach || this.triggerBeforeAttach; - var triggerAttach = showOptions.triggerAttach || this.triggerAttach; - - if (attachedRegion && triggerBeforeAttach) { - displayedViews = this._displayedViews(view); - this._triggerAttach(displayedViews, 'before:'); - } - - this.attachHtml(view); - this.currentView = view; - - if (attachedRegion && triggerAttach) { - displayedViews = this._displayedViews(view); - this._triggerAttach(displayedViews); - } - - if (isChangingView) { - this.triggerMethod('swap', view, this, options); - } - - this.triggerMethod('show', view, this, options); - Marionette.triggerMethodOn(view, 'show', view, this, options); - - return this; - } - - return this; - }, - - triggerBeforeAttach: true, - triggerAttach: true, - - _triggerAttach: function(views, prefix) { - var eventName = (prefix || '') + 'attach'; - _.each(views, function(view) { - Marionette.triggerMethodOn(view, eventName, view, this); - }, this); - }, - - _displayedViews: function(view) { - return _.union([view], _.result(view, '_getNestedViews') || []); - }, - - _ensureElement: function() { - if (!_.isObject(this.el)) { - this.$el = this.getEl(this.el); - this.el = this.$el[0]; - } - - if (!this.$el || this.$el.length === 0) { - if (this.getOption('allowMissingEl')) { - return false; - } else { - throw new Marionette.Error('An "el" ' + this.$el.selector + ' must exist in DOM'); - } - } - return true; - }, - - _ensureViewIsIntact: function(view) { - if (!view) { - throw new Marionette.Error({ - name: 'ViewNotValid', - message: 'The view passed is undefined and therefore invalid. You must pass a view instance to show.' - }); - } - - if (view.isDestroyed) { - throw new Marionette.Error({ - name: 'ViewDestroyedError', - message: 'View (cid: "' + view.cid + '") has already been destroyed and cannot be used.' - }); - } - }, - - // Override this method to change how the region finds the DOM - // element that it manages. Return a jQuery selector object scoped - // to a provided parent el or the document if none exists. - getEl: function(el) { - return Backbone.$(el, Marionette._getValue(this.options.parentEl, this)); - }, - - // Override this method to change how the new view is - // appended to the `$el` that the region is managing - attachHtml: function(view) { - this.$el.contents().detach(); - - this.el.appendChild(view.el); - }, - - // Destroy the current view, if there is one. If there is no - // current view, it does nothing and returns immediately. - empty: function(options) { - var view = this.currentView; - - var preventDestroy = Marionette._getValue(options, 'preventDestroy', this); - // If there is no view in the region - // we should not remove anything - if (!view) { return; } - - view.off('destroy', this.empty, this); - this.triggerMethod('before:empty', view); - if (!preventDestroy) { - this._destroyView(); - } - this.triggerMethod('empty', view); - - // Remove region pointer to the currentView - delete this.currentView; - - if (preventDestroy) { - this.$el.contents().detach(); - } - - return this; - }, - - // call 'destroy' or 'remove', depending on which is found - // on the view (if showing a raw Backbone view or a Marionette View) - _destroyView: function() { - var view = this.currentView; - - if (view.destroy && !view.isDestroyed) { - view.destroy(); - } else if (view.remove) { - view.remove(); - - // appending isDestroyed to raw Backbone View allows regions - // to throw a ViewDestroyedError for this view - view.isDestroyed = true; - } - }, - - // Attach an existing view to the region. This - // will not call `render` or `onShow` for the new view, - // and will not replace the current HTML for the `el` - // of the region. - attachView: function(view) { - this.currentView = view; - return this; - }, - - // Checks whether a view is currently present within - // the region. Returns `true` if there is and `false` if - // no view is present. - hasView: function() { - return !!this.currentView; - }, - - // Reset the region by destroying any existing view and - // clearing out the cached `$el`. The next time a view - // is shown via this region, the region will re-query the - // DOM for the region's `el`. - reset: function() { - this.empty(); - - if (this.$el) { - this.el = this.$el.selector; - } - - delete this.$el; - return this; - } - - }, - - // Static Methods - { - - // Build an instance of a region by passing in a configuration object - // and a default region class to use if none is specified in the config. - // - // The config object should either be a string as a jQuery DOM selector, - // a Region class directly, or an object literal that specifies a selector, - // a custom regionClass, and any options to be supplied to the region: - // - // ```js - // { - // selector: "#foo", - // regionClass: MyCustomRegion, - // allowMissingEl: false - // } - // ``` - // - buildRegion: function(regionConfig, DefaultRegionClass) { - if (_.isString(regionConfig)) { - return this._buildRegionFromSelector(regionConfig, DefaultRegionClass); - } - - if (regionConfig.selector || regionConfig.el || regionConfig.regionClass) { - return this._buildRegionFromObject(regionConfig, DefaultRegionClass); - } - - if (_.isFunction(regionConfig)) { - return this._buildRegionFromRegionClass(regionConfig); - } - - throw new Marionette.Error({ - message: 'Improper region configuration type.', - url: 'marionette.region.html#region-configuration-types' - }); - }, - - // Build the region from a string selector like '#foo-region' - _buildRegionFromSelector: function(selector, DefaultRegionClass) { - return new DefaultRegionClass({el: selector}); - }, - - // Build the region from a configuration object - // ```js - // { selector: '#foo', regionClass: FooRegion, allowMissingEl: false } - // ``` - _buildRegionFromObject: function(regionConfig, DefaultRegionClass) { - var RegionClass = regionConfig.regionClass || DefaultRegionClass; - var options = _.omit(regionConfig, 'selector', 'regionClass'); - - if (regionConfig.selector && !options.el) { - options.el = regionConfig.selector; - } - - return new RegionClass(options); - }, - - // Build the region directly from a given `RegionClass` - _buildRegionFromRegionClass: function(RegionClass) { - return new RegionClass(); - } - }); - - // Region Manager - // -------------- - - // Manage one or more related `Marionette.Region` objects. - Marionette.RegionManager = Marionette.Controller.extend({ - constructor: function(options) { - this._regions = {}; - this.length = 0; - - Marionette.Controller.call(this, options); - - this.addRegions(this.getOption('regions')); - }, - - // Add multiple regions using an object literal or a - // function that returns an object literal, where - // each key becomes the region name, and each value is - // the region definition. - addRegions: function(regionDefinitions, defaults) { - regionDefinitions = Marionette._getValue(regionDefinitions, this, arguments); - - return _.reduce(regionDefinitions, function(regions, definition, name) { - if (_.isString(definition)) { - definition = {selector: definition}; - } - if (definition.selector) { - definition = _.defaults({}, definition, defaults); - } - - regions[name] = this.addRegion(name, definition); - return regions; - }, {}, this); - }, - - // Add an individual region to the region manager, - // and return the region instance - addRegion: function(name, definition) { - var region; - - if (definition instanceof Marionette.Region) { - region = definition; - } else { - region = Marionette.Region.buildRegion(definition, Marionette.Region); - } - - this.triggerMethod('before:add:region', name, region); - - region._parent = this; - this._store(name, region); - - this.triggerMethod('add:region', name, region); - return region; - }, - - // Get a region by name - get: function(name) { - return this._regions[name]; - }, - - // Gets all the regions contained within - // the `regionManager` instance. - getRegions: function() { - return _.clone(this._regions); - }, - - // Remove a region by name - removeRegion: function(name) { - var region = this._regions[name]; - this._remove(name, region); - - return region; - }, - - // Empty all regions in the region manager, and - // remove them - removeRegions: function() { - var regions = this.getRegions(); - _.each(this._regions, function(region, name) { - this._remove(name, region); - }, this); - - return regions; - }, - - // Empty all regions in the region manager, but - // leave them attached - emptyRegions: function() { - var regions = this.getRegions(); - _.invoke(regions, 'empty'); - return regions; - }, - - // Destroy all regions and shut down the region - // manager entirely - destroy: function() { - this.removeRegions(); - return Marionette.Controller.prototype.destroy.apply(this, arguments); - }, - - // internal method to store regions - _store: function(name, region) { - if (!this._regions[name]) { - this.length++; - } - - this._regions[name] = region; - }, - - // internal method to remove a region - _remove: function(name, region) { - this.triggerMethod('before:remove:region', name, region); - region.empty(); - region.stopListening(); - - delete region._parent; - delete this._regions[name]; - this.length--; - this.triggerMethod('remove:region', name, region); - } - }); - - Marionette.actAsCollection(Marionette.RegionManager.prototype, '_regions'); - - - // Template Cache - // -------------- - - // Manage templates stored in `<script>` blocks, - // caching them for faster access. - Marionette.TemplateCache = function(templateId) { - this.templateId = templateId; - }; - - // TemplateCache object-level methods. Manage the template - // caches from these method calls instead of creating - // your own TemplateCache instances - _.extend(Marionette.TemplateCache, { - templateCaches: {}, - - // Get the specified template by id. Either - // retrieves the cached version, or loads it - // from the DOM. - get: function(templateId, options) { - var cachedTemplate = this.templateCaches[templateId]; - - if (!cachedTemplate) { - cachedTemplate = new Marionette.TemplateCache(templateId); - this.templateCaches[templateId] = cachedTemplate; - } - - return cachedTemplate.load(options); - }, - - // Clear templates from the cache. If no arguments - // are specified, clears all templates: - // `clear()` - // - // If arguments are specified, clears each of the - // specified templates from the cache: - // `clear("#t1", "#t2", "...")` - clear: function() { - var i; - var args = _.toArray(arguments); - var length = args.length; - - if (length > 0) { - for (i = 0; i < length; i++) { - delete this.templateCaches[args[i]]; - } - } else { - this.templateCaches = {}; - } - } - }); - - // TemplateCache instance methods, allowing each - // template cache object to manage its own state - // and know whether or not it has been loaded - _.extend(Marionette.TemplateCache.prototype, { - - // Internal method to load the template - load: function(options) { - // Guard clause to prevent loading this template more than once - if (this.compiledTemplate) { - return this.compiledTemplate; - } - - // Load the template and compile it - var template = this.loadTemplate(this.templateId, options); - this.compiledTemplate = this.compileTemplate(template, options); - - return this.compiledTemplate; - }, - - // Load a template from the DOM, by default. Override - // this method to provide your own template retrieval - // For asynchronous loading with AMD/RequireJS, consider - // using a template-loader plugin as described here: - // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs - loadTemplate: function(templateId, options) { - var template = Backbone.$(templateId).html(); - - if (!template || template.length === 0) { - throw new Marionette.Error({ - name: 'NoTemplateError', - message: 'Could not find template: "' + templateId + '"' - }); - } - - return template; - }, - - // Pre-compile the template before caching it. Override - // this method if you do not need to pre-compile a template - // (JST / RequireJS for example) or if you want to change - // the template engine used (Handebars, etc). - compileTemplate: function(rawTemplate, options) { - return _.template(rawTemplate, options); - } - }); - - // Renderer - // -------- - - // Render a template with data by passing in the template - // selector and the data to render. - Marionette.Renderer = { - - // Render a template with data. The `template` parameter is - // passed to the `TemplateCache` object to retrieve the - // template function. Override this method to provide your own - // custom rendering and template handling for all of Marionette. - render: function(template, data) { - if (!template) { - throw new Marionette.Error({ - name: 'TemplateNotFoundError', - message: 'Cannot render the template since its false, null or undefined.' - }); - } - - var templateFunc = _.isFunction(template) ? template : Marionette.TemplateCache.get(template); - - return templateFunc(data); - } - }; - - - /* jshint maxlen: 114, nonew: false */ - // View - // ---- - - // The core view class that other Marionette views extend from. - Marionette.View = Backbone.View.extend({ - isDestroyed: false, - - constructor: function(options) { - _.bindAll(this, 'render'); - - options = Marionette._getValue(options, this); - - // this exposes view options to the view initializer - // this is a backfill since backbone removed the assignment - // of this.options - // at some point however this may be removed - this.options = _.extend({}, _.result(this, 'options'), options); - - this._behaviors = Marionette.Behaviors(this); - - Backbone.View.call(this, this.options); - - Marionette.MonitorDOMRefresh(this); - }, - - // Get the template for this view - // instance. You can set a `template` attribute in the view - // definition or pass a `template: "whatever"` parameter in - // to the constructor options. - getTemplate: function() { - return this.getOption('template'); - }, - - // Serialize a model by returning its attributes. Clones - // the attributes to allow modification. - serializeModel: function(model) { - return model.toJSON.apply(model, _.rest(arguments)); - }, - - // Mix in template helper methods. Looks for a - // `templateHelpers` attribute, which can either be an - // object literal, or a function that returns an object - // literal. All methods and attributes from this object - // are copies to the object passed in. - mixinTemplateHelpers: function(target) { - target = target || {}; - var templateHelpers = this.getOption('templateHelpers'); - templateHelpers = Marionette._getValue(templateHelpers, this); - return _.extend(target, templateHelpers); - }, - - // normalize the keys of passed hash with the views `ui` selectors. - // `{"@ui.foo": "bar"}` - normalizeUIKeys: function(hash) { - var uiBindings = _.result(this, '_uiBindings'); - return Marionette.normalizeUIKeys(hash, uiBindings || _.result(this, 'ui')); - }, - - // normalize the values of passed hash with the views `ui` selectors. - // `{foo: "@ui.bar"}` - normalizeUIValues: function(hash, properties) { - var ui = _.result(this, 'ui'); - var uiBindings = _.result(this, '_uiBindings'); - return Marionette.normalizeUIValues(hash, uiBindings || ui, properties); - }, - - // Configure `triggers` to forward DOM events to view - // events. `triggers: {"click .foo": "do:foo"}` - configureTriggers: function() { - if (!this.triggers) { return; } - - // Allow `triggers` to be configured as a function - var triggers = this.normalizeUIKeys(_.result(this, 'triggers')); - - // Configure the triggers, prevent default - // action and stop propagation of DOM events - return _.reduce(triggers, function(events, value, key) { - events[key] = this._buildViewTrigger(value); - return events; - }, {}, this); - }, - - // Overriding Backbone.View's delegateEvents to handle - // the `triggers`, `modelEvents`, and `collectionEvents` configuration - delegateEvents: function(events) { - this._delegateDOMEvents(events); - this.bindEntityEvents(this.model, this.getOption('modelEvents')); - this.bindEntityEvents(this.collection, this.getOption('collectionEvents')); - - _.each(this._behaviors, function(behavior) { - behavior.bindEntityEvents(this.model, behavior.getOption('modelEvents')); - behavior.bindEntityEvents(this.collection, behavior.getOption('collectionEvents')); - }, this); - - return this; - }, - - // internal method to delegate DOM events and triggers - _delegateDOMEvents: function(eventsArg) { - var events = Marionette._getValue(eventsArg || this.events, this); - - // normalize ui keys - events = this.normalizeUIKeys(events); - if (_.isUndefined(eventsArg)) {this.events = events;} - - var combinedEvents = {}; - - // look up if this view has behavior events - var behaviorEvents = _.result(this, 'behaviorEvents') || {}; - var triggers = this.configureTriggers(); - var behaviorTriggers = _.result(this, 'behaviorTriggers') || {}; - - // behavior events will be overriden by view events and or triggers - _.extend(combinedEvents, behaviorEvents, events, triggers, behaviorTriggers); - - Backbone.View.prototype.delegateEvents.call(this, combinedEvents); - }, - - // Overriding Backbone.View's undelegateEvents to handle unbinding - // the `triggers`, `modelEvents`, and `collectionEvents` config - undelegateEvents: function() { - Backbone.View.prototype.undelegateEvents.apply(this, arguments); - - this.unbindEntityEvents(this.model, this.getOption('modelEvents')); - this.unbindEntityEvents(this.collection, this.getOption('collectionEvents')); - - _.each(this._behaviors, function(behavior) { - behavior.unbindEntityEvents(this.model, behavior.getOption('modelEvents')); - behavior.unbindEntityEvents(this.collection, behavior.getOption('collectionEvents')); - }, this); - - return this; - }, - - // Internal helper method to verify whether the view hasn't been destroyed - _ensureViewIsIntact: function() { - if (this.isDestroyed) { - throw new Marionette.Error({ - name: 'ViewDestroyedError', - message: 'View (cid: "' + this.cid + '") has already been destroyed and cannot be used.' - }); - } - }, - - // Default `destroy` implementation, for removing a view from the - // DOM and unbinding it. Regions will call this method - // for you. You can specify an `onDestroy` method in your view to - // add custom code that is called after the view is destroyed. - destroy: function() { - if (this.isDestroyed) { return this; } - - var args = _.toArray(arguments); - - this.triggerMethod.apply(this, ['before:destroy'].concat(args)); - - // mark as destroyed before doing the actual destroy, to - // prevent infinite loops within "destroy" event handlers - // that are trying to destroy other views - this.isDestroyed = true; - this.triggerMethod.apply(this, ['destroy'].concat(args)); - - // unbind UI elements - this.unbindUIElements(); - - this.isRendered = false; - - // remove the view from the DOM - this.remove(); - - // Call destroy on each behavior after - // destroying the view. - // This unbinds event listeners - // that behaviors have registered for. - _.invoke(this._behaviors, 'destroy', args); - - return this; - }, - - bindUIElements: function() { - this._bindUIElements(); - _.invoke(this._behaviors, this._bindUIElements); - }, - - // This method binds the elements specified in the "ui" hash inside the view's code with - // the associated jQuery selectors. - _bindUIElements: function() { - if (!this.ui) { return; } - - // store the ui hash in _uiBindings so they can be reset later - // and so re-rendering the view will be able to find the bindings - if (!this._uiBindings) { - this._uiBindings = this.ui; - } - - // get the bindings result, as a function or otherwise - var bindings = _.result(this, '_uiBindings'); - - // empty the ui so we don't have anything to start with - this.ui = {}; - - // bind each of the selectors - _.each(bindings, function(selector, key) { - this.ui[key] = this.$(selector); - }, this); - }, - - // This method unbinds the elements specified in the "ui" hash - unbindUIElements: function() { - this._unbindUIElements(); - _.invoke(this._behaviors, this._unbindUIElements); - }, - - _unbindUIElements: function() { - if (!this.ui || !this._uiBindings) { return; } - - // delete all of the existing ui bindings - _.each(this.ui, function($el, name) { - delete this.ui[name]; - }, this); - - // reset the ui element to the original bindings configuration - this.ui = this._uiBindings; - delete this._uiBindings; - }, - - // Internal method to create an event handler for a given `triggerDef` like - // 'click:foo' - _buildViewTrigger: function(triggerDef) { - var hasOptions = _.isObject(triggerDef); - - var options = _.defaults({}, (hasOptions ? triggerDef : {}), { - preventDefault: true, - stopPropagation: true - }); - - var eventName = hasOptions ? options.event : triggerDef; - - return function(e) { - if (e) { - if (e.preventDefault && options.preventDefault) { - e.preventDefault(); - } - - if (e.stopPropagation && options.stopPropagation) { - e.stopPropagation(); - } - } - - var args = { - view: this, - model: this.model, - collection: this.collection - }; - - this.triggerMethod(eventName, args); - }; - }, - - setElement: function() { - var ret = Backbone.View.prototype.setElement.apply(this, arguments); - - // proxy behavior $el to the view's $el. - // This is needed because a view's $el proxy - // is not set until after setElement is called. - _.invoke(this._behaviors, 'proxyViewProperties', this); - - return ret; - }, - - // import the `triggerMethod` to trigger events with corresponding - // methods if the method exists - triggerMethod: function() { - var ret = Marionette._triggerMethod(this, arguments); - - this._triggerEventOnBehaviors(arguments); - this._triggerEventOnParentLayout(arguments[0], _.rest(arguments)); - - return ret; - }, - - _triggerEventOnBehaviors: function(args) { - var triggerMethod = Marionette._triggerMethod; - var behaviors = this._behaviors; - // Use good ol' for as this is a very hot function - for (var i = 0, length = behaviors && behaviors.length; i < length; i++) { - triggerMethod(behaviors[i], args); - } - }, - - _triggerEventOnParentLayout: function(eventName, args) { - var layoutView = this._parentLayoutView(); - if (!layoutView) { - return; - } - - // invoke triggerMethod on parent view - var eventPrefix = Marionette.getOption(layoutView, 'childViewEventPrefix'); - var prefixedEventName = eventPrefix + ':' + eventName; - - Marionette._triggerMethod(layoutView, [prefixedEventName, this].concat(args)); - - // call the parent view's childEvents handler - var childEvents = Marionette.getOption(layoutView, 'childEvents'); - var normalizedChildEvents = layoutView.normalizeMethods(childEvents); - - if (!!normalizedChildEvents && _.isFunction(normalizedChildEvents[eventName])) { - normalizedChildEvents[eventName].apply(layoutView, [this].concat(args)); - } - }, - - // This method returns any views that are immediate - // children of this view - _getImmediateChildren: function() { - return []; - }, - - // Returns an array of every nested view within this view - _getNestedViews: function() { - var children = this._getImmediateChildren(); - - if (!children.length) { return children; } - - return _.reduce(children, function(memo, view) { - if (!view._getNestedViews) { return memo; } - return memo.concat(view._getNestedViews()); - }, children); - }, - - // Internal utility for building an ancestor - // view tree list. - _getAncestors: function() { - var ancestors = []; - var parent = this._parent; - - while (parent) { - ancestors.push(parent); - parent = parent._parent; - } - - return ancestors; - }, - - // Returns the containing parent view. - _parentLayoutView: function() { - var ancestors = this._getAncestors(); - return _.find(ancestors, function(parent) { - return parent instanceof Marionette.LayoutView; - }); - }, - - // Imports the "normalizeMethods" to transform hashes of - // events=>function references/names to a hash of events=>function references - normalizeMethods: Marionette.normalizeMethods, - - // A handy way to merge passed-in options onto the instance - mergeOptions: Marionette.mergeOptions, - - // Proxy `getOption` to enable getting options from this or this.options by name. - getOption: Marionette.proxyGetOption, - - // Proxy `bindEntityEvents` to enable binding view's events from another entity. - bindEntityEvents: Marionette.proxyBindEntityEvents, - - // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity. - unbindEntityEvents: Marionette.proxyUnbindEntityEvents - }); - - // Item View - // --------- - - // A single item view implementation that contains code for rendering - // with underscore.js templates, serializing the view's model or collection, - // and calling several methods on extended views, such as `onRender`. - Marionette.ItemView = Marionette.View.extend({ - - // Setting up the inheritance chain which allows changes to - // Marionette.View.prototype.constructor which allows overriding - constructor: function() { - Marionette.View.apply(this, arguments); - }, - - // Serialize the model or collection for the view. If a model is - // found, the view's `serializeModel` is called. If a collection is found, - // each model in the collection is serialized by calling - // the view's `serializeCollection` and put into an `items` array in - // the resulting data. If both are found, defaults to the model. - // You can override the `serializeData` method in your own view definition, - // to provide custom serialization for your view's data. - serializeData: function() { - if (!this.model && !this.collection) { - return {}; - } - - var args = [this.model || this.collection]; - if (arguments.length) { - args.push.apply(args, arguments); - } - - if (this.model) { - return this.serializeModel.apply(this, args); - } else { - return { - items: this.serializeCollection.apply(this, args) - }; - } - }, - - // Serialize a collection by serializing each of its models. - serializeCollection: function(collection) { - return collection.toJSON.apply(collection, _.rest(arguments)); - }, - - // Render the view, defaulting to underscore.js templates. - // You can override this in your view definition to provide - // a very specific rendering for your view. In general, though, - // you should override the `Marionette.Renderer` object to - // change how Marionette renders views. - render: function() { - this._ensureViewIsIntact(); - - this.triggerMethod('before:render', this); - - this._renderTemplate(); - this.isRendered = true; - this.bindUIElements(); - - this.triggerMethod('render', this); - - return this; - }, - - // Internal method to render the template with the serialized data - // and template helpers via the `Marionette.Renderer` object. - // Throws an `UndefinedTemplateError` error if the template is - // any falsely value but literal `false`. - _renderTemplate: function() { - var template = this.getTemplate(); - - // Allow template-less item views - if (template === false) { - return; - } - - if (!template) { - throw new Marionette.Error({ - name: 'UndefinedTemplateError', - message: 'Cannot render the template since it is null or undefined.' - }); - } - - // Add in entity data and template helpers - var data = this.mixinTemplateHelpers(this.serializeData()); - - // Render and add to el - var html = Marionette.Renderer.render(template, data, this); - this.attachElContent(html); - - return this; - }, - - // Attaches the content of a given view. - // This method can be overridden to optimize rendering, - // or to render in a non standard way. - // - // For example, using `innerHTML` instead of `$el.html` - // - // ```js - // attachElContent: function(html) { - // this.el.innerHTML = html; - // return this; - // } - // ``` - attachElContent: function(html) { - this.$el.html(html); - - return this; - } - }); - - /* jshint maxstatements: 14 */ - - // Collection View - // --------------- - - // A view that iterates over a Backbone.Collection - // and renders an individual child view for each model. - Marionette.CollectionView = Marionette.View.extend({ - - // used as the prefix for child view events - // that are forwarded through the collectionview - childViewEventPrefix: 'childview', - - // flag for maintaining the sorted order of the collection - sort: true, - - // constructor - // option to pass `{sort: false}` to prevent the `CollectionView` from - // maintaining the sorted order of the collection. - // This will fallback onto appending childView's to the end. - // - // option to pass `{comparator: compFunction()}` to allow the `CollectionView` - // to use a custom sort order for the collection. - constructor: function(options) { - - this.once('render', this._initialEvents); - this._initChildViewStorage(); - - Marionette.View.apply(this, arguments); - - this.on('show', this._onShowCalled); - - this.initRenderBuffer(); - }, - - // Instead of inserting elements one by one into the page, - // it's much more performant to insert elements into a document - // fragment and then insert that document fragment into the page - initRenderBuffer: function() { - this._bufferedChildren = []; - }, - - startBuffering: function() { - this.initRenderBuffer(); - this.isBuffering = true; - }, - - endBuffering: function() { - this.isBuffering = false; - this._triggerBeforeShowBufferedChildren(); - - this.attachBuffer(this); - - this._triggerShowBufferedChildren(); - this.initRenderBuffer(); - }, - - _triggerBeforeShowBufferedChildren: function() { - if (this._isShown) { - _.each(this._bufferedChildren, _.partial(this._triggerMethodOnChild, 'before:show')); - } - }, - - _triggerShowBufferedChildren: function() { - if (this._isShown) { - _.each(this._bufferedChildren, _.partial(this._triggerMethodOnChild, 'show')); - - this._bufferedChildren = []; - } - }, - - // Internal method for _.each loops to call `Marionette.triggerMethodOn` on - // a child view - _triggerMethodOnChild: function(event, childView) { - Marionette.triggerMethodOn(childView, event); - }, - - // Configured the initial events that the collection view - // binds to. - _initialEvents: function() { - if (this.collection) { - this.listenTo(this.collection, 'add', this._onCollectionAdd); - this.listenTo(this.collection, 'remove', this._onCollectionRemove); - this.listenTo(this.collection, 'reset', this.render); - - if (this.getOption('sort')) { - this.listenTo(this.collection, 'sort', this._sortViews); - } - } - }, - - // Handle a child added to the collection - _onCollectionAdd: function(child, collection, opts) { - var index; - if (opts.at !== undefined) { - index = opts.at; - } else { - index = _.indexOf(this._filteredSortedModels(), child); - } - - if (this._shouldAddChild(child, index)) { - this.destroyEmptyView(); - var ChildView = this.getChildView(child); - this.addChild(child, ChildView, index); - } - }, - - // get the child view by model it holds, and remove it - _onCollectionRemove: function(model) { - var view = this.children.findByModel(model); - this.removeChildView(view); - this.checkEmpty(); - }, - - _onShowCalled: function() { - this.children.each(_.partial(this._triggerMethodOnChild, 'show')); - }, - - // Render children views. Override this method to - // provide your own implementation of a render function for - // the collection view. - render: function() { - this._ensureViewIsIntact(); - this.triggerMethod('before:render', this); - this._renderChildren(); - this.isRendered = true; - this.triggerMethod('render', this); - return this; - }, - - // Reorder DOM after sorting. When your element's rendering - // do not use their index, you can pass reorderOnSort: true - // to only reorder the DOM after a sort instead of rendering - // all the collectionView - reorder: function() { - var children = this.children; - var models = this._filteredSortedModels(); - var modelsChanged = _.find(models, function(model) { - return !children.findByModel(model); - }); - - // If the models we're displaying have changed due to filtering - // We need to add and/or remove child views - // So render as normal - if (modelsChanged) { - this.render(); - } else { - // get the DOM nodes in the same order as the models - var els = _.map(models, function(model) { - return children.findByModel(model).el; - }); - - // since append moves elements that are already in the DOM, - // appending the elements will effectively reorder them - this.triggerMethod('before:reorder'); - this._appendReorderedChildren(els); - this.triggerMethod('reorder'); - } - }, - - // Render view after sorting. Override this method to - // change how the view renders after a `sort` on the collection. - // An example of this would be to only `renderChildren` in a `CompositeView` - // rather than the full view. - resortView: function() { - if (Marionette.getOption(this, 'reorderOnSort')) { - this.reorder(); - } else { - this.render(); - } - }, - - // Internal method. This checks for any changes in the order of the collection. - // If the index of any view doesn't match, it will render. - _sortViews: function() { - var models = this._filteredSortedModels(); - - // check for any changes in sort order of views - var orderChanged = _.find(models, function(item, index) { - var view = this.children.findByModel(item); - return !view || view._index !== index; - }, this); - - if (orderChanged) { - this.resortView(); - } - }, - - // Internal reference to what index a `emptyView` is. - _emptyViewIndex: -1, - - // Internal method. Separated so that CompositeView can append to the childViewContainer - // if necessary - _appendReorderedChildren: function(children) { - this.$el.append(children); - }, - - // Internal method. Separated so that CompositeView can have - // more control over events being triggered, around the rendering - // process - _renderChildren: function() { - this.destroyEmptyView(); - this.destroyChildren(); - - if (this.isEmpty(this.collection)) { - this.showEmptyView(); - } else { - this.triggerMethod('before:render:collection', this); - this.startBuffering(); - this.showCollection(); - this.endBuffering(); - this.triggerMethod('render:collection', this); - - // If we have shown children and none have passed the filter, show the empty view - if (this.children.isEmpty()) { - this.showEmptyView(); - } - } - }, - - // Internal method to loop through collection and show each child view. - showCollection: function() { - var ChildView; - - var models = this._filteredSortedModels(); - - _.each(models, function(child, index) { - ChildView = this.getChildView(child); - this.addChild(child, ChildView, index); - }, this); - }, - - // Allow the collection to be sorted by a custom view comparator - _filteredSortedModels: function() { - var models; - var viewComparator = this.getViewComparator(); - - if (viewComparator) { - if (_.isString(viewComparator) || viewComparator.length === 1) { - models = this.collection.sortBy(viewComparator, this); - } else { - models = _.clone(this.collection.models).sort(_.bind(viewComparator, this)); - } - } else { - models = this.collection.models; - } - - // Filter after sorting in case the filter uses the index - if (this.getOption('filter')) { - models = _.filter(models, function(model, index) { - return this._shouldAddChild(model, index); - }, this); - } - - return models; - }, - - // Internal method to show an empty view in place of - // a collection of child views, when the collection is empty - showEmptyView: function() { - var EmptyView = this.getEmptyView(); - - if (EmptyView && !this._showingEmptyView) { - this.triggerMethod('before:render:empty'); - - this._showingEmptyView = true; - var model = new Backbone.Model(); - this.addEmptyView(model, EmptyView); - - this.triggerMethod('render:empty'); - } - }, - - // Internal method to destroy an existing emptyView instance - // if one exists. Called when a collection view has been - // rendered empty, and then a child is added to the collection. - destroyEmptyView: function() { - if (this._showingEmptyView) { - this.triggerMethod('before:remove:empty'); - - this.destroyChildren(); - delete this._showingEmptyView; - - this.triggerMethod('remove:empty'); - } - }, - - // Retrieve the empty view class - getEmptyView: function() { - return this.getOption('emptyView'); - }, - - // Render and show the emptyView. Similar to addChild method - // but "add:child" events are not fired, and the event from - // emptyView are not forwarded - addEmptyView: function(child, EmptyView) { - - // get the emptyViewOptions, falling back to childViewOptions - var emptyViewOptions = this.getOption('emptyViewOptions') || - this.getOption('childViewOptions'); - - if (_.isFunction(emptyViewOptions)) { - emptyViewOptions = emptyViewOptions.call(this, child, this._emptyViewIndex); - } - - // build the empty view - var view = this.buildChildView(child, EmptyView, emptyViewOptions); - - view._parent = this; - - // Proxy emptyView events - this.proxyChildEvents(view); - - // trigger the 'before:show' event on `view` if the collection view - // has already been shown - if (this._isShown) { - Marionette.triggerMethodOn(view, 'before:show'); - } - - // Store the `emptyView` like a `childView` so we can properly - // remove and/or close it later - this.children.add(view); - - // Render it and show it - this.renderChildView(view, this._emptyViewIndex); - - // call the 'show' method if the collection view - // has already been shown - if (this._isShown) { - Marionette.triggerMethodOn(view, 'show'); - } - }, - - // Retrieve the `childView` class, either from `this.options.childView` - // or from the `childView` in the object definition. The "options" - // takes precedence. - // This method receives the model that will be passed to the instance - // created from this `childView`. Overriding methods may use the child - // to determine what `childView` class to return. - getChildView: function(child) { - var childView = this.getOption('childView'); - - if (!childView) { - throw new Marionette.Error({ - name: 'NoChildViewError', - message: 'A "childView" must be specified' - }); - } - - return childView; - }, - - // Render the child's view and add it to the - // HTML for the collection view at a given index. - // This will also update the indices of later views in the collection - // in order to keep the children in sync with the collection. - addChild: function(child, ChildView, index) { - var childViewOptions = this.getOption('childViewOptions'); - childViewOptions = Marionette._getValue(childViewOptions, this, [child, index]); - - var view = this.buildChildView(child, ChildView, childViewOptions); - - // increment indices of views after this one - this._updateIndices(view, true, index); - - this._addChildView(view, index); - - view._parent = this; - - return view; - }, - - // Internal method. This decrements or increments the indices of views after the - // added/removed view to keep in sync with the collection. - _updateIndices: function(view, increment, index) { - if (!this.getOption('sort')) { - return; - } - - if (increment) { - // assign the index to the view - view._index = index; - } - - // update the indexes of views after this one - this.children.each(function(laterView) { - if (laterView._index >= view._index) { - laterView._index += increment ? 1 : -1; - } - }); - }, - - // Internal Method. Add the view to children and render it at - // the given index. - _addChildView: function(view, index) { - // set up the child view event forwarding - this.proxyChildEvents(view); - - this.triggerMethod('before:add:child', view); - - // trigger the 'before:show' event on `view` if the collection view - // has already been shown - if (this._isShown && !this.isBuffering) { - Marionette.triggerMethodOn(view, 'before:show'); - } - - // Store the child view itself so we can properly - // remove and/or destroy it later - this.children.add(view); - this.renderChildView(view, index); - - if (this._isShown && !this.isBuffering) { - Marionette.triggerMethodOn(view, 'show'); - } - - this.triggerMethod('add:child', view); - }, - - // render the child view - renderChildView: function(view, index) { - view.render(); - this.attachHtml(this, view, index); - return view; - }, - - // Build a `childView` for a model in the collection. - buildChildView: function(child, ChildViewClass, childViewOptions) { - var options = _.extend({model: child}, childViewOptions); - return new ChildViewClass(options); - }, - - // Remove the child view and destroy it. - // This function also updates the indices of - // later views in the collection in order to keep - // the children in sync with the collection. - removeChildView: function(view) { - - if (view) { - this.triggerMethod('before:remove:child', view); - - // call 'destroy' or 'remove', depending on which is found - if (view.destroy) { - view.destroy(); - } else if (view.remove) { - view.remove(); - } - - delete view._parent; - this.stopListening(view); - this.children.remove(view); - this.triggerMethod('remove:child', view); - - // decrement the index of views after this one - this._updateIndices(view, false); - } - - return view; - }, - - // check if the collection is empty - isEmpty: function() { - return !this.collection || this.collection.length === 0; - }, - - // If empty, show the empty view - checkEmpty: function() { - if (this.isEmpty(this.collection)) { - this.showEmptyView(); - } - }, - - // You might need to override this if you've overridden attachHtml - attachBuffer: function(collectionView) { - collectionView.$el.append(this._createBuffer(collectionView)); - }, - - // Create a fragment buffer from the currently buffered children - _createBuffer: function(collectionView) { - var elBuffer = document.createDocumentFragment(); - _.each(collectionView._bufferedChildren, function(b) { - elBuffer.appendChild(b.el); - }); - return elBuffer; - }, - - // Append the HTML to the collection's `el`. - // Override this method to do something other - // than `.append`. - attachHtml: function(collectionView, childView, index) { - if (collectionView.isBuffering) { - // buffering happens on reset events and initial renders - // in order to reduce the number of inserts into the - // document, which are expensive. - collectionView._bufferedChildren.splice(index, 0, childView); - } else { - // If we've already rendered the main collection, append - // the new child into the correct order if we need to. Otherwise - // append to the end. - if (!collectionView._insertBefore(childView, index)) { - collectionView._insertAfter(childView); - } - } - }, - - // Internal method. Check whether we need to insert the view into - // the correct position. - _insertBefore: function(childView, index) { - var currentView; - var findPosition = this.getOption('sort') && (index < this.children.length - 1); - if (findPosition) { - // Find the view after this one - currentView = this.children.find(function(view) { - return view._index === index + 1; - }); - } - - if (currentView) { - currentView.$el.before(childView.el); - return true; - } - - return false; - }, - - // Internal method. Append a view to the end of the $el - _insertAfter: function(childView) { - this.$el.append(childView.el); - }, - - // Internal method to set up the `children` object for - // storing all of the child views - _initChildViewStorage: function() { - this.children = new Backbone.ChildViewContainer(); - }, - - // Handle cleanup and other destroying needs for the collection of views - destroy: function() { - if (this.isDestroyed) { return this; } - - this.triggerMethod('before:destroy:collection'); - this.destroyChildren(); - this.triggerMethod('destroy:collection'); - - return Marionette.View.prototype.destroy.apply(this, arguments); - }, - - // Destroy the child views that this collection view - // is holding on to, if any - destroyChildren: function() { - var childViews = this.children.map(_.identity); - this.children.each(this.removeChildView, this); - this.checkEmpty(); - return childViews; - }, - - // Return true if the given child should be shown - // Return false otherwise - // The filter will be passed (child, index, collection) - // Where - // 'child' is the given model - // 'index' is the index of that model in the collection - // 'collection' is the collection referenced by this CollectionView - _shouldAddChild: function(child, index) { - var filter = this.getOption('filter'); - return !_.isFunction(filter) || filter.call(this, child, index, this.collection); - }, - - // Set up the child view event forwarding. Uses a "childview:" - // prefix in front of all forwarded events. - proxyChildEvents: function(view) { - var prefix = this.getOption('childViewEventPrefix'); - - // Forward all child view events through the parent, - // prepending "childview:" to the event name - this.listenTo(view, 'all', function() { - var args = _.toArray(arguments); - var rootEvent = args[0]; - var childEvents = this.normalizeMethods(_.result(this, 'childEvents')); - - args[0] = prefix + ':' + rootEvent; - args.splice(1, 0, view); - - // call collectionView childEvent if defined - if (typeof childEvents !== 'undefined' && _.isFunction(childEvents[rootEvent])) { - childEvents[rootEvent].apply(this, args.slice(1)); - } - - this.triggerMethod.apply(this, args); - }); - }, - - _getImmediateChildren: function() { - return _.values(this.children._views); - }, - - getViewComparator: function() { - return this.getOption('viewComparator'); - } - }); - - /* jshint maxstatements: 17, maxlen: 117 */ - - // Composite View - // -------------- - - // Used for rendering a branch-leaf, hierarchical structure. - // Extends directly from CollectionView and also renders an - // a child view as `modelView`, for the top leaf - Marionette.CompositeView = Marionette.CollectionView.extend({ - - // Setting up the inheritance chain which allows changes to - // Marionette.CollectionView.prototype.constructor which allows overriding - // option to pass '{sort: false}' to prevent the CompositeView from - // maintaining the sorted order of the collection. - // This will fallback onto appending childView's to the end. - constructor: function() { - Marionette.CollectionView.apply(this, arguments); - }, - - // Configured the initial events that the composite view - // binds to. Override this method to prevent the initial - // events, or to add your own initial events. - _initialEvents: function() { - - // Bind only after composite view is rendered to avoid adding child views - // to nonexistent childViewContainer - - if (this.collection) { - this.listenTo(this.collection, 'add', this._onCollectionAdd); - this.listenTo(this.collection, 'remove', this._onCollectionRemove); - this.listenTo(this.collection, 'reset', this._renderChildren); - - if (this.getOption('sort')) { - this.listenTo(this.collection, 'sort', this._sortViews); - } - } - }, - - // Retrieve the `childView` to be used when rendering each of - // the items in the collection. The default is to return - // `this.childView` or Marionette.CompositeView if no `childView` - // has been defined - getChildView: function(child) { - var childView = this.getOption('childView') || this.constructor; - - return childView; - }, - - // Serialize the model for the view. - // You can override the `serializeData` method in your own view - // definition, to provide custom serialization for your view's data. - serializeData: function() { - var data = {}; - - if (this.model) { - data = _.partial(this.serializeModel, this.model).apply(this, arguments); - } - - return data; - }, - - // Renders the model and the collection. - render: function() { - this._ensureViewIsIntact(); - this._isRendering = true; - this.resetChildViewContainer(); - - this.triggerMethod('before:render', this); - - this._renderTemplate(); - this._renderChildren(); - - this._isRendering = false; - this.isRendered = true; - this.triggerMethod('render', this); - return this; - }, - - _renderChildren: function() { - if (this.isRendered || this._isRendering) { - Marionette.CollectionView.prototype._renderChildren.call(this); - } - }, - - // Render the root template that the children - // views are appended to - _renderTemplate: function() { - var data = {}; - data = this.serializeData(); - data = this.mixinTemplateHelpers(data); - - this.triggerMethod('before:render:template'); - - var template = this.getTemplate(); - var html = Marionette.Renderer.render(template, data, this); - this.attachElContent(html); - - // the ui bindings is done here and not at the end of render since they - // will not be available until after the model is rendered, but should be - // available before the collection is rendered. - this.bindUIElements(); - this.triggerMethod('render:template'); - }, - - // Attaches the content of the root. - // This method can be overridden to optimize rendering, - // or to render in a non standard way. - // - // For example, using `innerHTML` instead of `$el.html` - // - // ```js - // attachElContent: function(html) { - // this.el.innerHTML = html; - // return this; - // } - // ``` - attachElContent: function(html) { - this.$el.html(html); - - return this; - }, - - // You might need to override this if you've overridden attachHtml - attachBuffer: function(compositeView) { - var $container = this.getChildViewContainer(compositeView); - $container.append(this._createBuffer(compositeView)); - }, - - // Internal method. Append a view to the end of the $el. - // Overidden from CollectionView to ensure view is appended to - // childViewContainer - _insertAfter: function(childView) { - var $container = this.getChildViewContainer(this, childView); - $container.append(childView.el); - }, - - // Internal method. Append reordered childView'. - // Overidden from CollectionView to ensure reordered views - // are appended to childViewContainer - _appendReorderedChildren: function(children) { - var $container = this.getChildViewContainer(this); - $container.append(children); - }, - - // Internal method to ensure an `$childViewContainer` exists, for the - // `attachHtml` method to use. - getChildViewContainer: function(containerView, childView) { - if ('$childViewContainer' in containerView) { - return containerView.$childViewContainer; - } - - var container; - var childViewContainer = Marionette.getOption(containerView, 'childViewContainer'); - if (childViewContainer) { - - var selector = Marionette._getValue(childViewContainer, containerView); - - if (selector.charAt(0) === '@' && containerView.ui) { - container = containerView.ui[selector.substr(4)]; - } else { - container = containerView.$(selector); - } - - if (container.length <= 0) { - throw new Marionette.Error({ - name: 'ChildViewContainerMissingError', - message: 'The specified "childViewContainer" was not found: ' + containerView.childViewContainer - }); - } - - } else { - container = containerView.$el; - } - - containerView.$childViewContainer = container; - return container; - }, - - // Internal method to reset the `$childViewContainer` on render - resetChildViewContainer: function() { - if (this.$childViewContainer) { - delete this.$childViewContainer; - } - } - }); - - // Layout View - // ----------- - - // Used for managing application layoutViews, nested layoutViews and - // multiple regions within an application or sub-application. - // - // A specialized view class that renders an area of HTML and then - // attaches `Region` instances to the specified `regions`. - // Used for composite view management and sub-application areas. - Marionette.LayoutView = Marionette.ItemView.extend({ - regionClass: Marionette.Region, - - options: { - destroyImmediate: false - }, - - // used as the prefix for child view events - // that are forwarded through the layoutview - childViewEventPrefix: 'childview', - - // Ensure the regions are available when the `initialize` method - // is called. - constructor: function(options) { - options = options || {}; - - this._firstRender = true; - this._initializeRegions(options); - - Marionette.ItemView.call(this, options); - }, - - // LayoutView's render will use the existing region objects the - // first time it is called. Subsequent calls will destroy the - // views that the regions are showing and then reset the `el` - // for the regions to the newly rendered DOM elements. - render: function() { - this._ensureViewIsIntact(); - - if (this._firstRender) { - // if this is the first render, don't do anything to - // reset the regions - this._firstRender = false; - } else { - // If this is not the first render call, then we need to - // re-initialize the `el` for each region - this._reInitializeRegions(); - } - - return Marionette.ItemView.prototype.render.apply(this, arguments); - }, - - // Handle destroying regions, and then destroy the view itself. - destroy: function() { - if (this.isDestroyed) { return this; } - // #2134: remove parent element before destroying the child views, so - // removing the child views doesn't retrigger repaints - if (this.getOption('destroyImmediate') === true) { - this.$el.remove(); - } - this.regionManager.destroy(); - return Marionette.ItemView.prototype.destroy.apply(this, arguments); - }, - - showChildView: function(regionName, view) { - return this.getRegion(regionName).show(view); - }, - - getChildView: function(regionName) { - return this.getRegion(regionName).currentView; - }, - - // Add a single region, by name, to the layoutView - addRegion: function(name, definition) { - var regions = {}; - regions[name] = definition; - return this._buildRegions(regions)[name]; - }, - - // Add multiple regions as a {name: definition, name2: def2} object literal - addRegions: function(regions) { - this.regions = _.extend({}, this.regions, regions); - return this._buildRegions(regions); - }, - - // Remove a single region from the LayoutView, by name - removeRegion: function(name) { - delete this.regions[name]; - return this.regionManager.removeRegion(name); - }, - - // Provides alternative access to regions - // Accepts the region name - // getRegion('main') - getRegion: function(region) { - return this.regionManager.get(region); - }, - - // Get all regions - getRegions: function() { - return this.regionManager.getRegions(); - }, - - // internal method to build regions - _buildRegions: function(regions) { - var defaults = { - regionClass: this.getOption('regionClass'), - parentEl: _.partial(_.result, this, 'el') - }; - - return this.regionManager.addRegions(regions, defaults); - }, - - // Internal method to initialize the regions that have been defined in a - // `regions` attribute on this layoutView. - _initializeRegions: function(options) { - var regions; - this._initRegionManager(); - - regions = Marionette._getValue(this.regions, this, [options]) || {}; - - // Enable users to define `regions` as instance options. - var regionOptions = this.getOption.call(options, 'regions'); - - // enable region options to be a function - regionOptions = Marionette._getValue(regionOptions, this, [options]); - - _.extend(regions, regionOptions); - - // Normalize region selectors hash to allow - // a user to use the @ui. syntax. - regions = this.normalizeUIValues(regions, ['selector', 'el']); - - this.addRegions(regions); - }, - - // Internal method to re-initialize all of the regions by updating the `el` that - // they point to - _reInitializeRegions: function() { - this.regionManager.invoke('reset'); - }, - - // Enable easy overriding of the default `RegionManager` - // for customized region interactions and business specific - // view logic for better control over single regions. - getRegionManager: function() { - return new Marionette.RegionManager(); - }, - - // Internal method to initialize the region manager - // and all regions in it - _initRegionManager: function() { - this.regionManager = this.getRegionManager(); - this.regionManager._parent = this; - - this.listenTo(this.regionManager, 'before:add:region', function(name) { - this.triggerMethod('before:add:region', name); - }); - - this.listenTo(this.regionManager, 'add:region', function(name, region) { - this[name] = region; - this.triggerMethod('add:region', name, region); - }); - - this.listenTo(this.regionManager, 'before:remove:region', function(name) { - this.triggerMethod('before:remove:region', name); - }); - - this.listenTo(this.regionManager, 'remove:region', function(name, region) { - delete this[name]; - this.triggerMethod('remove:region', name, region); - }); - }, - - _getImmediateChildren: function() { - return _.chain(this.regionManager.getRegions()) - .pluck('currentView') - .compact() - .value(); - } - }); - - - // Behavior - // -------- - - // A Behavior is an isolated set of DOM / - // user interactions that can be mixed into any View. - // Behaviors allow you to blackbox View specific interactions - // into portable logical chunks, keeping your views simple and your code DRY. - - Marionette.Behavior = Marionette.Object.extend({ - constructor: function(options, view) { - // Setup reference to the view. - // this comes in handle when a behavior - // wants to directly talk up the chain - // to the view. - this.view = view; - this.defaults = _.result(this, 'defaults') || {}; - this.options = _.extend({}, this.defaults, options); - // Construct an internal UI hash using - // the views UI hash and then the behaviors UI hash. - // This allows the user to use UI hash elements - // defined in the parent view as well as those - // defined in the given behavior. - this.ui = _.extend({}, _.result(view, 'ui'), _.result(this, 'ui')); - - Marionette.Object.apply(this, arguments); - }, - - // proxy behavior $ method to the view - // this is useful for doing jquery DOM lookups - // scoped to behaviors view. - $: function() { - return this.view.$.apply(this.view, arguments); - }, - - // Stops the behavior from listening to events. - // Overrides Object#destroy to prevent additional events from being triggered. - destroy: function() { - this.stopListening(); - - return this; - }, - - proxyViewProperties: function(view) { - this.$el = view.$el; - this.el = view.el; - } - }); - - /* jshint maxlen: 143 */ - // Behaviors - // --------- - - // Behaviors is a utility class that takes care of - // gluing your behavior instances to their given View. - // The most important part of this class is that you - // **MUST** override the class level behaviorsLookup - // method for things to work properly. - - Marionette.Behaviors = (function(Marionette, _) { - // Borrow event splitter from Backbone - var delegateEventSplitter = /^(\S+)\s*(.*)$/; - - function Behaviors(view, behaviors) { - - if (!_.isObject(view.behaviors)) { - return {}; - } - - // Behaviors defined on a view can be a flat object literal - // or it can be a function that returns an object. - behaviors = Behaviors.parseBehaviors(view, behaviors || _.result(view, 'behaviors')); - - // Wraps several of the view's methods - // calling the methods first on each behavior - // and then eventually calling the method on the view. - Behaviors.wrap(view, behaviors, _.keys(methods)); - return behaviors; - } - - var methods = { - behaviorTriggers: function(behaviorTriggers, behaviors) { - var triggerBuilder = new BehaviorTriggersBuilder(this, behaviors); - return triggerBuilder.buildBehaviorTriggers(); - }, - - behaviorEvents: function(behaviorEvents, behaviors) { - var _behaviorsEvents = {}; - - _.each(behaviors, function(b, i) { - var _events = {}; - var behaviorEvents = _.clone(_.result(b, 'events')) || {}; - - // Normalize behavior events hash to allow - // a user to use the @ui. syntax. - behaviorEvents = Marionette.normalizeUIKeys(behaviorEvents, getBehaviorsUI(b)); - - var j = 0; - _.each(behaviorEvents, function(behaviour, key) { - var match = key.match(delegateEventSplitter); - - // Set event name to be namespaced using the view cid, - // the behavior index, and the behavior event index - // to generate a non colliding event namespace - // http://api.jquery.com/event.namespace/ - var eventName = match[1] + '.' + [this.cid, i, j++, ' '].join(''); - var selector = match[2]; - - var eventKey = eventName + selector; - var handler = _.isFunction(behaviour) ? behaviour : b[behaviour]; - - _events[eventKey] = _.bind(handler, b); - }, this); - - _behaviorsEvents = _.extend(_behaviorsEvents, _events); - }, this); - - return _behaviorsEvents; - } - }; - - _.extend(Behaviors, { - - // Placeholder method to be extended by the user. - // The method should define the object that stores the behaviors. - // i.e. - // - // ```js - // Marionette.Behaviors.behaviorsLookup: function() { - // return App.Behaviors - // } - // ``` - behaviorsLookup: function() { - throw new Marionette.Error({ - message: 'You must define where your behaviors are stored.', - url: 'marionette.behaviors.html#behaviorslookup' - }); - }, - - // Takes care of getting the behavior class - // given options and a key. - // If a user passes in options.behaviorClass - // default to using that. Otherwise delegate - // the lookup to the users `behaviorsLookup` implementation. - getBehaviorClass: function(options, key) { - if (options.behaviorClass) { - return options.behaviorClass; - } - - // Get behavior class can be either a flat object or a method - return Marionette._getValue(Behaviors.behaviorsLookup, this, [options, key])[key]; - }, - - // Iterate over the behaviors object, for each behavior - // instantiate it and get its grouped behaviors. - parseBehaviors: function(view, behaviors) { - return _.chain(behaviors).map(function(options, key) { - var BehaviorClass = Behaviors.getBehaviorClass(options, key); - - var behavior = new BehaviorClass(options, view); - var nestedBehaviors = Behaviors.parseBehaviors(view, _.result(behavior, 'behaviors')); - - return [behavior].concat(nestedBehaviors); - }).flatten().value(); - }, - - // Wrap view internal methods so that they delegate to behaviors. For example, - // `onDestroy` should trigger destroy on all of the behaviors and then destroy itself. - // i.e. - // - // `view.delegateEvents = _.partial(methods.delegateEvents, view.delegateEvents, behaviors);` - wrap: function(view, behaviors, methodNames) { - _.each(methodNames, function(methodName) { - view[methodName] = _.partial(methods[methodName], view[methodName], behaviors); - }); - } - }); - - // Class to build handlers for `triggers` on behaviors - // for views - function BehaviorTriggersBuilder(view, behaviors) { - this._view = view; - this._behaviors = behaviors; - this._triggers = {}; - } - - _.extend(BehaviorTriggersBuilder.prototype, { - // Main method to build the triggers hash with event keys and handlers - buildBehaviorTriggers: function() { - _.each(this._behaviors, this._buildTriggerHandlersForBehavior, this); - return this._triggers; - }, - - // Internal method to build all trigger handlers for a given behavior - _buildTriggerHandlersForBehavior: function(behavior, i) { - var triggersHash = _.clone(_.result(behavior, 'triggers')) || {}; - - triggersHash = Marionette.normalizeUIKeys(triggersHash, getBehaviorsUI(behavior)); - - _.each(triggersHash, _.bind(this._setHandlerForBehavior, this, behavior, i)); - }, - - // Internal method to create and assign the trigger handler for a given - // behavior - _setHandlerForBehavior: function(behavior, i, eventName, trigger) { - // Unique identifier for the `this._triggers` hash - var triggerKey = trigger.replace(/^\S+/, function(triggerName) { - return triggerName + '.' + 'behaviortriggers' + i; - }); - - this._triggers[triggerKey] = this._view._buildViewTrigger(eventName); - } - }); - - function getBehaviorsUI(behavior) { - return behavior._uiBindings || behavior.ui; - } - - return Behaviors; - - })(Marionette, _); - - - // App Router - // ---------- - - // Reduce the boilerplate code of handling route events - // and then calling a single method on another object. - // Have your routers configured to call the method on - // your object, directly. - // - // Configure an AppRouter with `appRoutes`. - // - // App routers can only take one `controller` object. - // It is recommended that you divide your controller - // objects in to smaller pieces of related functionality - // and have multiple routers / controllers, instead of - // just one giant router and controller. - // - // You can also add standard routes to an AppRouter. - - Marionette.AppRouter = Backbone.Router.extend({ - - constructor: function(options) { - this.options = options || {}; - - Backbone.Router.apply(this, arguments); - - var appRoutes = this.getOption('appRoutes'); - var controller = this._getController(); - this.processAppRoutes(controller, appRoutes); - this.on('route', this._processOnRoute, this); - }, - - // Similar to route method on a Backbone Router but - // method is called on the controller - appRoute: function(route, methodName) { - var controller = this._getController(); - this._addAppRoute(controller, route, methodName); - }, - - // process the route event and trigger the onRoute - // method call, if it exists - _processOnRoute: function(routeName, routeArgs) { - // make sure an onRoute before trying to call it - if (_.isFunction(this.onRoute)) { - // find the path that matches the current route - var routePath = _.invert(this.getOption('appRoutes'))[routeName]; - this.onRoute(routeName, routePath, routeArgs); - } - }, - - // Internal method to process the `appRoutes` for the - // router, and turn them in to routes that trigger the - // specified method on the specified `controller`. - processAppRoutes: function(controller, appRoutes) { - if (!appRoutes) { return; } - - var routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes - - _.each(routeNames, function(route) { - this._addAppRoute(controller, route, appRoutes[route]); - }, this); - }, - - _getController: function() { - return this.getOption('controller'); - }, - - _addAppRoute: function(controller, route, methodName) { - var method = controller[methodName]; - - if (!method) { - throw new Marionette.Error('Method "' + methodName + '" was not found on the controller'); - } - - this.route(route, methodName, _.bind(method, controller)); - }, - - mergeOptions: Marionette.mergeOptions, - - // Proxy `getOption` to enable getting options from this or this.options by name. - getOption: Marionette.proxyGetOption, - - triggerMethod: Marionette.triggerMethod, - - bindEntityEvents: Marionette.proxyBindEntityEvents, - - unbindEntityEvents: Marionette.proxyUnbindEntityEvents - }); - - // Application - // ----------- - - // Contain and manage the composite application as a whole. - // Stores and starts up `Region` objects, includes an - // event aggregator as `app.vent` - Marionette.Application = Marionette.Object.extend({ - constructor: function(options) { - this._initializeRegions(options); - this._initCallbacks = new Marionette.Callbacks(); - this.submodules = {}; - _.extend(this, options); - this._initChannel(); - Marionette.Object.call(this, options); - }, - - // Command execution, facilitated by Backbone.Wreqr.Commands - execute: function() { - this.commands.execute.apply(this.commands, arguments); - }, - - // Request/response, facilitated by Backbone.Wreqr.RequestResponse - request: function() { - return this.reqres.request.apply(this.reqres, arguments); - }, - - // Add an initializer that is either run at when the `start` - // method is called, or run immediately if added after `start` - // has already been called. - addInitializer: function(initializer) { - this._initCallbacks.add(initializer); - }, - - // kick off all of the application's processes. - // initializes all of the regions that have been added - // to the app, and runs all of the initializer functions - start: function(options) { - this.triggerMethod('before:start', options); - this._initCallbacks.run(options, this); - this.triggerMethod('start', options); - }, - - // Add regions to your app. - // Accepts a hash of named strings or Region objects - // addRegions({something: "#someRegion"}) - // addRegions({something: Region.extend({el: "#someRegion"}) }); - addRegions: function(regions) { - return this._regionManager.addRegions(regions); - }, - - // Empty all regions in the app, without removing them - emptyRegions: function() { - return this._regionManager.emptyRegions(); - }, - - // Removes a region from your app, by name - // Accepts the regions name - // removeRegion('myRegion') - removeRegion: function(region) { - return this._regionManager.removeRegion(region); - }, - - // Provides alternative access to regions - // Accepts the region name - // getRegion('main') - getRegion: function(region) { - return this._regionManager.get(region); - }, - - // Get all the regions from the region manager - getRegions: function() { - return this._regionManager.getRegions(); - }, - - // Create a module, attached to the application - module: function(moduleNames, moduleDefinition) { - - // Overwrite the module class if the user specifies one - var ModuleClass = Marionette.Module.getClass(moduleDefinition); - - var args = _.toArray(arguments); - args.unshift(this); - - // see the Marionette.Module object for more information - return ModuleClass.create.apply(ModuleClass, args); - }, - - // Enable easy overriding of the default `RegionManager` - // for customized region interactions and business-specific - // view logic for better control over single regions. - getRegionManager: function() { - return new Marionette.RegionManager(); - }, - - // Internal method to initialize the regions that have been defined in a - // `regions` attribute on the application instance - _initializeRegions: function(options) { - var regions = _.isFunction(this.regions) ? this.regions(options) : this.regions || {}; - - this._initRegionManager(); - - // Enable users to define `regions` in instance options. - var optionRegions = Marionette.getOption(options, 'regions'); - - // Enable region options to be a function - if (_.isFunction(optionRegions)) { - optionRegions = optionRegions.call(this, options); - } - - // Overwrite current regions with those passed in options - _.extend(regions, optionRegions); - - this.addRegions(regions); - - return this; - }, - - // Internal method to set up the region manager - _initRegionManager: function() { - this._regionManager = this.getRegionManager(); - this._regionManager._parent = this; - - this.listenTo(this._regionManager, 'before:add:region', function() { - Marionette._triggerMethod(this, 'before:add:region', arguments); - }); - - this.listenTo(this._regionManager, 'add:region', function(name, region) { - this[name] = region; - Marionette._triggerMethod(this, 'add:region', arguments); - }); - - this.listenTo(this._regionManager, 'before:remove:region', function() { - Marionette._triggerMethod(this, 'before:remove:region', arguments); - }); - - this.listenTo(this._regionManager, 'remove:region', function(name) { - delete this[name]; - Marionette._triggerMethod(this, 'remove:region', arguments); - }); - }, - - // Internal method to setup the Wreqr.radio channel - _initChannel: function() { - this.channelName = _.result(this, 'channelName') || 'global'; - this.channel = _.result(this, 'channel') || Backbone.Wreqr.radio.channel(this.channelName); - this.vent = _.result(this, 'vent') || this.channel.vent; - this.commands = _.result(this, 'commands') || this.channel.commands; - this.reqres = _.result(this, 'reqres') || this.channel.reqres; - } - }); - - /* jshint maxparams: 9 */ - - // Module - // ------ - - // A simple module system, used to create privacy and encapsulation in - // Marionette applications - Marionette.Module = function(moduleName, app, options) { - this.moduleName = moduleName; - this.options = _.extend({}, this.options, options); - // Allow for a user to overide the initialize - // for a given module instance. - this.initialize = options.initialize || this.initialize; - - // Set up an internal store for sub-modules. - this.submodules = {}; - - this._setupInitializersAndFinalizers(); - - // Set an internal reference to the app - // within a module. - this.app = app; - - if (_.isFunction(this.initialize)) { - this.initialize(moduleName, app, this.options); - } - }; - - Marionette.Module.extend = Marionette.extend; - - // Extend the Module prototype with events / listenTo, so that the module - // can be used as an event aggregator or pub/sub. - _.extend(Marionette.Module.prototype, Backbone.Events, { - - // By default modules start with their parents. - startWithParent: true, - - // Initialize is an empty function by default. Override it with your own - // initialization logic when extending Marionette.Module. - initialize: function() {}, - - // Initializer for a specific module. Initializers are run when the - // module's `start` method is called. - addInitializer: function(callback) { - this._initializerCallbacks.add(callback); - }, - - // Finalizers are run when a module is stopped. They are used to teardown - // and finalize any variables, references, events and other code that the - // module had set up. - addFinalizer: function(callback) { - this._finalizerCallbacks.add(callback); - }, - - // Start the module, and run all of its initializers - start: function(options) { - // Prevent re-starting a module that is already started - if (this._isInitialized) { return; } - - // start the sub-modules (depth-first hierarchy) - _.each(this.submodules, function(mod) { - // check to see if we should start the sub-module with this parent - if (mod.startWithParent) { - mod.start(options); - } - }); - - // run the callbacks to "start" the current module - this.triggerMethod('before:start', options); - - this._initializerCallbacks.run(options, this); - this._isInitialized = true; - - this.triggerMethod('start', options); - }, - - // Stop this module by running its finalizers and then stop all of - // the sub-modules for this module - stop: function() { - // if we are not initialized, don't bother finalizing - if (!this._isInitialized) { return; } - this._isInitialized = false; - - this.triggerMethod('before:stop'); - - // stop the sub-modules; depth-first, to make sure the - // sub-modules are stopped / finalized before parents - _.invoke(this.submodules, 'stop'); - - // run the finalizers - this._finalizerCallbacks.run(undefined, this); - - // reset the initializers and finalizers - this._initializerCallbacks.reset(); - this._finalizerCallbacks.reset(); - - this.triggerMethod('stop'); - }, - - // Configure the module with a definition function and any custom args - // that are to be passed in to the definition function - addDefinition: function(moduleDefinition, customArgs) { - this._runModuleDefinition(moduleDefinition, customArgs); - }, - - // Internal method: run the module definition function with the correct - // arguments - _runModuleDefinition: function(definition, customArgs) { - // If there is no definition short circut the method. - if (!definition) { return; } - - // build the correct list of arguments for the module definition - var args = _.flatten([ - this, - this.app, - Backbone, - Marionette, - Backbone.$, _, - customArgs - ]); - - definition.apply(this, args); - }, - - // Internal method: set up new copies of initializers and finalizers. - // Calling this method will wipe out all existing initializers and - // finalizers. - _setupInitializersAndFinalizers: function() { - this._initializerCallbacks = new Marionette.Callbacks(); - this._finalizerCallbacks = new Marionette.Callbacks(); - }, - - // import the `triggerMethod` to trigger events with corresponding - // methods if the method exists - triggerMethod: Marionette.triggerMethod - }); - - // Class methods to create modules - _.extend(Marionette.Module, { - - // Create a module, hanging off the app parameter as the parent object. - create: function(app, moduleNames, moduleDefinition) { - var module = app; - - // get the custom args passed in after the module definition and - // get rid of the module name and definition function - var customArgs = _.drop(arguments, 3); - - // Split the module names and get the number of submodules. - // i.e. an example module name of `Doge.Wow.Amaze` would - // then have the potential for 3 module definitions. - moduleNames = moduleNames.split('.'); - var length = moduleNames.length; - - // store the module definition for the last module in the chain - var moduleDefinitions = []; - moduleDefinitions[length - 1] = moduleDefinition; - - // Loop through all the parts of the module definition - _.each(moduleNames, function(moduleName, i) { - var parentModule = module; - module = this._getModule(parentModule, moduleName, app, moduleDefinition); - this._addModuleDefinition(parentModule, module, moduleDefinitions[i], customArgs); - }, this); - - // Return the last module in the definition chain - return module; - }, - - _getModule: function(parentModule, moduleName, app, def, args) { - var options = _.extend({}, def); - var ModuleClass = this.getClass(def); - - // Get an existing module of this name if we have one - var module = parentModule[moduleName]; - - if (!module) { - // Create a new module if we don't have one - module = new ModuleClass(moduleName, app, options); - parentModule[moduleName] = module; - // store the module on the parent - parentModule.submodules[moduleName] = module; - } - - return module; - }, - - // ## Module Classes - // - // Module classes can be used as an alternative to the define pattern. - // The extend function of a Module is identical to the extend functions - // on other Backbone and Marionette classes. - // This allows module lifecyle events like `onStart` and `onStop` to be called directly. - getClass: function(moduleDefinition) { - var ModuleClass = Marionette.Module; - - if (!moduleDefinition) { - return ModuleClass; - } - - // If all of the module's functionality is defined inside its class, - // then the class can be passed in directly. `MyApp.module("Foo", FooModule)`. - if (moduleDefinition.prototype instanceof ModuleClass) { - return moduleDefinition; - } - - return moduleDefinition.moduleClass || ModuleClass; - }, - - // Add the module definition and add a startWithParent initializer function. - // This is complicated because module definitions are heavily overloaded - // and support an anonymous function, module class, or options object - _addModuleDefinition: function(parentModule, module, def, args) { - var fn = this._getDefine(def); - var startWithParent = this._getStartWithParent(def, module); - - if (fn) { - module.addDefinition(fn, args); - } - - this._addStartWithParent(parentModule, module, startWithParent); - }, - - _getStartWithParent: function(def, module) { - var swp; - - if (_.isFunction(def) && (def.prototype instanceof Marionette.Module)) { - swp = module.constructor.prototype.startWithParent; - return _.isUndefined(swp) ? true : swp; - } - - if (_.isObject(def)) { - swp = def.startWithParent; - return _.isUndefined(swp) ? true : swp; - } - - return true; - }, - - _getDefine: function(def) { - if (_.isFunction(def) && !(def.prototype instanceof Marionette.Module)) { - return def; - } - - if (_.isObject(def)) { - return def.define; - } - - return null; - }, - - _addStartWithParent: function(parentModule, module, startWithParent) { - module.startWithParent = module.startWithParent && startWithParent; - - if (!module.startWithParent || !!module.startWithParentIsConfigured) { - return; - } - - module.startWithParentIsConfigured = true; - - parentModule.addInitializer(function(options) { - if (module.startWithParent) { - module.start(options); - } - }); - } - }); - - - return Marionette; -})); diff --git a/server/sonar-web/src/main/js/libs/third-party/classNames.js b/server/sonar-web/src/main/js/libs/third-party/classNames.js deleted file mode 100644 index afb8eed33a7..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/classNames.js +++ /dev/null @@ -1,49 +0,0 @@ -/*! - Copyright (c) 2015 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames -*/ - -(function () { - 'use strict'; - - function classNames () { - - var classes = ''; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - if (!arg) continue; - - var argType = typeof arg; - - if ('string' === argType || 'number' === argType) { - classes += ' ' + arg; - - } else if (Array.isArray(arg)) { - classes += ' ' + classNames.apply(null, arg); - - } else if ('object' === argType) { - for (var key in arg) { - if (arg.hasOwnProperty(key) && arg[key]) { - classes += ' ' + key; - } - } - } - } - - return classes.substr(1); - } - - if (typeof module !== 'undefined' && module.exports) { - module.exports = classNames; - } else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd){ - // AMD. Register as an anonymous module. - define(function () { - return classNames; - }); - } else { - window.classNames = classNames; - } - -}()); diff --git a/server/sonar-web/src/main/js/libs/third-party/handlebars.js b/server/sonar-web/src/main/js/libs/third-party/handlebars.js deleted file mode 100644 index 8ae0445c57b..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/handlebars.js +++ /dev/null @@ -1,660 +0,0 @@ -/*! - - handlebars v2.0.0 - - Copyright (C) 2011-2014 by Yehuda Katz - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - @license - */ -/* exported Handlebars */ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define([], factory); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.Handlebars = root.Handlebars || factory(); - } -}(this, function () { -// handlebars/safe-string.js - var __module3__ = (function() { - "use strict"; - var __exports__; - // Build out our basic SafeString type - function SafeString(string) { - this.string = string; - } - - SafeString.prototype.toString = function() { - return "" + this.string; - }; - - __exports__ = SafeString; - return __exports__; - })(); - -// handlebars/utils.js - var __module2__ = (function(__dependency1__) { - "use strict"; - var __exports__ = {}; - /*jshint -W004 */ - var SafeString = __dependency1__; - - var escape = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - }; - - var badChars = /[&<>"'`]/g; - var possible = /[&<>"'`]/; - - function escapeChar(chr) { - return escape[chr]; - } - - function extend(obj /* , ...source */) { - for (var i = 1; i < arguments.length; i++) { - for (var key in arguments[i]) { - if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { - obj[key] = arguments[i][key]; - } - } - } - - return obj; - } - - __exports__.extend = extend;var toString = Object.prototype.toString; - __exports__.toString = toString; - // Sourced from lodash - // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt - var isFunction = function(value) { - return typeof value === 'function'; - }; - // fallback for older versions of Chrome and Safari - /* istanbul ignore next */ - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value === 'function' && toString.call(value) === '[object Function]'; - }; - } - var isFunction; - __exports__.isFunction = isFunction; - /* istanbul ignore next */ - var isArray = Array.isArray || function(value) { - return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false; - }; - __exports__.isArray = isArray; - - function escapeExpression(string) { - // don't escape SafeStrings, since they're already safe - if (string instanceof SafeString) { - return string.toString(); - } else if (string == null) { - return ""; - } else if (!string) { - return string + ''; - } - - // Force a string conversion as this will be done by the append regardless and - // the regex test will do this transparently behind the scenes, causing issues if - // an object's to string has escaped characters in it. - string = "" + string; - - if(!possible.test(string)) { return string; } - return string.replace(badChars, escapeChar); - } - - __exports__.escapeExpression = escapeExpression;function isEmpty(value) { - if (!value && value !== 0) { - return true; - } else if (isArray(value) && value.length === 0) { - return true; - } else { - return false; - } - } - - __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) { - return (contextPath ? contextPath + '.' : '') + id; - } - - __exports__.appendContextPath = appendContextPath; - return __exports__; - })(__module3__); - -// handlebars/exception.js - var __module4__ = (function() { - "use strict"; - var __exports__; - - var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; - - function Exception(message, node) { - var line; - if (node && node.firstLine) { - line = node.firstLine; - - message += ' - ' + line + ':' + node.firstColumn; - } - - var tmp = Error.prototype.constructor.call(this, message); - - // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. - for (var idx = 0; idx < errorProps.length; idx++) { - this[errorProps[idx]] = tmp[errorProps[idx]]; - } - - if (line) { - this.lineNumber = line; - this.column = node.firstColumn; - } - } - - Exception.prototype = new Error(); - - __exports__ = Exception; - return __exports__; - })(); - -// handlebars/base.js - var __module1__ = (function(__dependency1__, __dependency2__) { - "use strict"; - var __exports__ = {}; - var Utils = __dependency1__; - var Exception = __dependency2__; - - var VERSION = "2.0.0"; - __exports__.VERSION = VERSION;var COMPILER_REVISION = 6; - __exports__.COMPILER_REVISION = COMPILER_REVISION; - var REVISION_CHANGES = { - 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it - 2: '== 1.0.0-rc.3', - 3: '== 1.0.0-rc.4', - 4: '== 1.x.x', - 5: '== 2.0.0-alpha.x', - 6: '>= 2.0.0-beta.1' - }; - __exports__.REVISION_CHANGES = REVISION_CHANGES; - var isArray = Utils.isArray, - isFunction = Utils.isFunction, - toString = Utils.toString, - objectType = '[object Object]'; - - function HandlebarsEnvironment(helpers, partials) { - this.helpers = helpers || {}; - this.partials = partials || {}; - - registerDefaultHelpers(this); - } - - __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = { - constructor: HandlebarsEnvironment, - - logger: logger, - log: log, - - registerHelper: function(name, fn) { - if (toString.call(name) === objectType) { - if (fn) { throw new Exception('Arg not supported with multiple helpers'); } - Utils.extend(this.helpers, name); - } else { - this.helpers[name] = fn; - } - }, - unregisterHelper: function(name) { - delete this.helpers[name]; - }, - - registerPartial: function(name, partial) { - if (toString.call(name) === objectType) { - Utils.extend(this.partials, name); - } else { - this.partials[name] = partial; - } - }, - unregisterPartial: function(name) { - delete this.partials[name]; - } - }; - - function registerDefaultHelpers(instance) { - instance.registerHelper('helperMissing', function(/* [args, ]options */) { - if(arguments.length === 1) { - // A missing field in a {{foo}} constuct. - return undefined; - } else { - // Someone is actually trying to call something, blow up. - throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'"); - } - }); - - instance.registerHelper('blockHelperMissing', function(context, options) { - var inverse = options.inverse, - fn = options.fn; - - if(context === true) { - return fn(this); - } else if(context === false || context == null) { - return inverse(this); - } else if (isArray(context)) { - if(context.length > 0) { - if (options.ids) { - options.ids = [options.name]; - } - - return instance.helpers.each(context, options); - } else { - return inverse(this); - } - } else { - if (options.data && options.ids) { - var data = createFrame(options.data); - data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name); - options = {data: data}; - } - - return fn(context, options); - } - }); - - instance.registerHelper('each', function(context, options) { - if (!options) { - throw new Exception('Must pass iterator to #each'); - } - - var fn = options.fn, inverse = options.inverse; - var i = 0, ret = "", data; - - var contextPath; - if (options.data && options.ids) { - contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; - } - - if (isFunction(context)) { context = context.call(this); } - - if (options.data) { - data = createFrame(options.data); - } - - if(context && typeof context === 'object') { - if (isArray(context)) { - for(var j = context.length; i<j; i++) { - if (data) { - data.index = i; - data.first = (i === 0); - data.last = (i === (context.length-1)); - - if (contextPath) { - data.contextPath = contextPath + i; - } - } - ret = ret + fn(context[i], { data: data }); - } - } else { - for(var key in context) { - if(context.hasOwnProperty(key)) { - if(data) { - data.key = key; - data.index = i; - data.first = (i === 0); - - if (contextPath) { - data.contextPath = contextPath + key; - } - } - ret = ret + fn(context[key], {data: data}); - i++; - } - } - } - } - - if(i === 0){ - ret = inverse(this); - } - - return ret; - }); - - instance.registerHelper('if', function(conditional, options) { - if (isFunction(conditional)) { conditional = conditional.call(this); } - - // Default behavior is to render the positive path if the value is truthy and not empty. - // The `includeZero` option may be set to treat the condtional as purely not empty based on the - // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. - if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) { - return options.inverse(this); - } else { - return options.fn(this); - } - }); - - instance.registerHelper('unless', function(conditional, options) { - return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash}); - }); - - instance.registerHelper('with', function(context, options) { - if (isFunction(context)) { context = context.call(this); } - - var fn = options.fn; - - if (!Utils.isEmpty(context)) { - if (options.data && options.ids) { - var data = createFrame(options.data); - data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]); - options = {data:data}; - } - - return fn(context, options); - } else { - return options.inverse(this); - } - }); - - instance.registerHelper('log', function(message, options) { - var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1; - instance.log(level, message); - }); - - instance.registerHelper('lookup', function(obj, field) { - return obj && obj[field]; - }); - } - - var logger = { - methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' }, - - // State enum - DEBUG: 0, - INFO: 1, - WARN: 2, - ERROR: 3, - level: 3, - - // can be overridden in the host environment - log: function(level, message) { - if (logger.level <= level) { - var method = logger.methodMap[level]; - if (typeof console !== 'undefined' && console[method]) { - console[method].call(console, message); - } - } - } - }; - __exports__.logger = logger; - var log = logger.log; - __exports__.log = log; - var createFrame = function(object) { - var frame = Utils.extend({}, object); - frame._parent = object; - return frame; - }; - __exports__.createFrame = createFrame; - return __exports__; - })(__module2__, __module4__); - -// handlebars/runtime.js - var __module5__ = (function(__dependency1__, __dependency2__, __dependency3__) { - "use strict"; - var __exports__ = {}; - var Utils = __dependency1__; - var Exception = __dependency2__; - var COMPILER_REVISION = __dependency3__.COMPILER_REVISION; - var REVISION_CHANGES = __dependency3__.REVISION_CHANGES; - var createFrame = __dependency3__.createFrame; - - function checkRevision(compilerInfo) { - var compilerRevision = compilerInfo && compilerInfo[0] || 1, - currentRevision = COMPILER_REVISION; - - if (compilerRevision !== currentRevision) { - if (compilerRevision < currentRevision) { - var runtimeVersions = REVISION_CHANGES[currentRevision], - compilerVersions = REVISION_CHANGES[compilerRevision]; - throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+ - "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+")."); - } else { - // Use the embedded version info since the runtime doesn't know about this revision yet - throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+ - "Please update your runtime to a newer version ("+compilerInfo[1]+")."); - } - } - } - - __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial - - function template(templateSpec, env) { - /* istanbul ignore next */ - if (!env) { - throw new Exception("No environment passed to template"); - } - if (!templateSpec || !templateSpec.main) { - throw new Exception('Unknown template object: ' + typeof templateSpec); - } - - // Note: Using env.VM references rather than local var references throughout this section to allow - // for external users to override these as psuedo-supported APIs. - env.VM.checkRevision(templateSpec.compiler); - - var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) { - if (hash) { - context = Utils.extend({}, context, hash); - } - - var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths); - - if (result == null && env.compile) { - var options = { helpers: helpers, partials: partials, data: data, depths: depths }; - partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env); - result = partials[name](context, options); - } - if (result != null) { - if (indent) { - var lines = result.split('\n'); - for (var i = 0, l = lines.length; i < l; i++) { - if (!lines[i] && i + 1 === l) { - break; - } - - lines[i] = indent + lines[i]; - } - result = lines.join('\n'); - } - return result; - } else { - throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode"); - } - }; - - // Just add water - var container = { - lookup: function(depths, name) { - var len = depths.length; - for (var i = 0; i < len; i++) { - if (depths[i] && depths[i][name] != null) { - return depths[i][name]; - } - } - }, - lambda: function(current, context) { - return typeof current === 'function' ? current.call(context) : current; - }, - - escapeExpression: Utils.escapeExpression, - invokePartial: invokePartialWrapper, - - fn: function(i) { - return templateSpec[i]; - }, - - programs: [], - program: function(i, data, depths) { - var programWrapper = this.programs[i], - fn = this.fn(i); - if (data || depths) { - programWrapper = program(this, i, fn, data, depths); - } else if (!programWrapper) { - programWrapper = this.programs[i] = program(this, i, fn); - } - return programWrapper; - }, - - data: function(data, depth) { - while (data && depth--) { - data = data._parent; - } - return data; - }, - merge: function(param, common) { - var ret = param || common; - - if (param && common && (param !== common)) { - ret = Utils.extend({}, common, param); - } - - return ret; - }, - - noop: env.VM.noop, - compilerInfo: templateSpec.compiler - }; - - var ret = function(context, options) { - options = options || {}; - var data = options.data; - - ret._setup(options); - if (!options.partial && templateSpec.useData) { - data = initData(context, data); - } - var depths; - if (templateSpec.useDepths) { - depths = options.depths ? [context].concat(options.depths) : [context]; - } - - return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths); - }; - ret.isTop = true; - - ret._setup = function(options) { - if (!options.partial) { - container.helpers = container.merge(options.helpers, env.helpers); - - if (templateSpec.usePartial) { - container.partials = container.merge(options.partials, env.partials); - } - } else { - container.helpers = options.helpers; - container.partials = options.partials; - } - }; - - ret._child = function(i, data, depths) { - if (templateSpec.useDepths && !depths) { - throw new Exception('must pass parent depths'); - } - - return program(container, i, templateSpec[i], data, depths); - }; - return ret; - } - - __exports__.template = template;function program(container, i, fn, data, depths) { - var prog = function(context, options) { - options = options || {}; - - return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths)); - }; - prog.program = i; - prog.depth = depths ? depths.length : 0; - return prog; - } - - __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data, depths) { - var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths }; - - if(partial === undefined) { - throw new Exception("The partial " + name + " could not be found"); - } else if(partial instanceof Function) { - return partial(context, options); - } - } - - __exports__.invokePartial = invokePartial;function noop() { return ""; } - - __exports__.noop = noop;function initData(context, data) { - if (!data || !('root' in data)) { - data = data ? createFrame(data) : {}; - data.root = context; - } - return data; - } - return __exports__; - })(__module2__, __module4__, __module1__); - -// handlebars.runtime.js - var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) { - "use strict"; - var __exports__; - /*globals Handlebars: true */ - var base = __dependency1__; - - // Each of these augment the Handlebars object. No need to setup here. - // (This is done to easily share code between commonjs and browse envs) - var SafeString = __dependency2__; - var Exception = __dependency3__; - var Utils = __dependency4__; - var runtime = __dependency5__; - - // For compatibility and usage outside of module systems, make the Handlebars object a namespace - var create = function() { - var hb = new base.HandlebarsEnvironment(); - - Utils.extend(hb, base); - hb.SafeString = SafeString; - hb.Exception = Exception; - hb.Utils = Utils; - hb.escapeExpression = Utils.escapeExpression; - - hb.VM = runtime; - hb.template = function(spec) { - return runtime.template(spec, hb); - }; - - return hb; - }; - - var Handlebars = create(); - Handlebars.create = create; - - Handlebars['default'] = Handlebars; - - __exports__ = Handlebars; - return __exports__; - })(__module1__, __module3__, __module4__, __module2__, __module5__); - - return __module0__; -})); diff --git a/server/sonar-web/src/main/js/libs/third-party/latinize.js b/server/sonar-web/src/main/js/libs/third-party/latinize.js deleted file mode 100644 index 6d302eec0a3..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/latinize.js +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Latinize string by removing all diacritics - * From http://stackoverflow.com/questions/990904/javascript-remove-accents-in-strings - */ -(function() { - var defaultDiacriticsRemovalap = [ - {'base':'A', 'letters':'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'}, - {'base':'AA','letters':'\uA732'}, - {'base':'AE','letters':'\u00C6\u01FC\u01E2'}, - {'base':'AO','letters':'\uA734'}, - {'base':'AU','letters':'\uA736'}, - {'base':'AV','letters':'\uA738\uA73A'}, - {'base':'AY','letters':'\uA73C'}, - {'base':'B', 'letters':'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'}, - {'base':'C', 'letters':'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'}, - {'base':'D', 'letters':'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'}, - {'base':'DZ','letters':'\u01F1\u01C4'}, - {'base':'Dz','letters':'\u01F2\u01C5'}, - {'base':'E', 'letters':'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'}, - {'base':'F', 'letters':'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'}, - {'base':'G', 'letters':'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'}, - {'base':'H', 'letters':'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'}, - {'base':'I', 'letters':'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'}, - {'base':'J', 'letters':'\u004A\u24BF\uFF2A\u0134\u0248'}, - {'base':'K', 'letters':'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'}, - {'base':'L', 'letters':'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'}, - {'base':'LJ','letters':'\u01C7'}, - {'base':'Lj','letters':'\u01C8'}, - {'base':'M', 'letters':'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'}, - {'base':'N', 'letters':'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'}, - {'base':'NJ','letters':'\u01CA'}, - {'base':'Nj','letters':'\u01CB'}, - {'base':'O', 'letters':'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'}, - {'base':'OI','letters':'\u01A2'}, - {'base':'OO','letters':'\uA74E'}, - {'base':'OU','letters':'\u0222'}, - {'base':'OE','letters':'\u008C\u0152'}, - {'base':'oe','letters':'\u009C\u0153'}, - {'base':'P', 'letters':'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'}, - {'base':'Q', 'letters':'\u0051\u24C6\uFF31\uA756\uA758\u024A'}, - {'base':'R', 'letters':'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'}, - {'base':'S', 'letters':'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'}, - {'base':'T', 'letters':'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'}, - {'base':'TZ','letters':'\uA728'}, - {'base':'U', 'letters':'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'}, - {'base':'V', 'letters':'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'}, - {'base':'VY','letters':'\uA760'}, - {'base':'W', 'letters':'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'}, - {'base':'X', 'letters':'\u0058\u24CD\uFF38\u1E8A\u1E8C'}, - {'base':'Y', 'letters':'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'}, - {'base':'Z', 'letters':'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'}, - {'base':'a', 'letters':'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'}, - {'base':'aa','letters':'\uA733'}, - {'base':'ae','letters':'\u00E6\u01FD\u01E3'}, - {'base':'ao','letters':'\uA735'}, - {'base':'au','letters':'\uA737'}, - {'base':'av','letters':'\uA739\uA73B'}, - {'base':'ay','letters':'\uA73D'}, - {'base':'b', 'letters':'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'}, - {'base':'c', 'letters':'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'}, - {'base':'d', 'letters':'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'}, - {'base':'dz','letters':'\u01F3\u01C6'}, - {'base':'e', 'letters':'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'}, - {'base':'f', 'letters':'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'}, - {'base':'g', 'letters':'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'}, - {'base':'h', 'letters':'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'}, - {'base':'hv','letters':'\u0195'}, - {'base':'i', 'letters':'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'}, - {'base':'j', 'letters':'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'}, - {'base':'k', 'letters':'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'}, - {'base':'l', 'letters':'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'}, - {'base':'lj','letters':'\u01C9'}, - {'base':'m', 'letters':'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'}, - {'base':'n', 'letters':'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'}, - {'base':'nj','letters':'\u01CC'}, - {'base':'o', 'letters':'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'}, - {'base':'oi','letters':'\u01A3'}, - {'base':'ou','letters':'\u0223'}, - {'base':'oo','letters':'\uA74F'}, - {'base':'p','letters':'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'}, - {'base':'q','letters':'\u0071\u24E0\uFF51\u024B\uA757\uA759'}, - {'base':'r','letters':'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'}, - {'base':'s','letters':'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'}, - {'base':'t','letters':'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'}, - {'base':'tz','letters':'\uA729'}, - {'base':'u','letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'}, - {'base':'v','letters':'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'}, - {'base':'vy','letters':'\uA761'}, - {'base':'w','letters':'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'}, - {'base':'x','letters':'\u0078\u24E7\uFF58\u1E8B\u1E8D'}, - {'base':'y','letters':'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'}, - {'base':'z','letters':'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'} - ]; - - var diacriticsMap = {}; - for (var i=0; i < defaultDiacriticsRemovalap.length; i++){ - var letters = defaultDiacriticsRemovalap[i].letters.split(""); - for (var j=0; j < letters.length ; j++){ - diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base; - } - } - - // "what?" version ... http://jsperf.com/diacritics/12 - function removeDiacritics (str) { - return str.replace(/[^\u0000-\u007E]/g, function(a){ - return diacriticsMap[a] || a; - }); - } - - String.prototype.latinize = function() { - return removeDiacritics(this); - }; -})(); diff --git a/server/sonar-web/src/main/js/libs/third-party/md5.js b/server/sonar-web/src/main/js/libs/third-party/md5.js deleted file mode 100644 index f92ba37a4de..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/md5.js +++ /dev/null @@ -1,274 +0,0 @@ -/* - * JavaScript MD5 1.0.1 - * https://github.com/blueimp/JavaScript-MD5 - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - * - * Based on - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * Digest Algorithm, as defined in RFC 1321. - * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for more info. - */ - -/*jslint bitwise: true */ -/*global unescape, define */ - -(function ($) { - 'use strict'; - - /* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ - function safe_add(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), - msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); - } - - /* - * Bitwise rotate a 32-bit number to the left. - */ - function bit_rol(num, cnt) { - return (num << cnt) | (num >>> (32 - cnt)); - } - - /* - * These functions implement the four basic operations the algorithm uses. - */ - function md5_cmn(q, a, b, x, s, t) { - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); - } - function md5_ff(a, b, c, d, x, s, t) { - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); - } - function md5_gg(a, b, c, d, x, s, t) { - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); - } - function md5_hh(a, b, c, d, x, s, t) { - return md5_cmn(b ^ c ^ d, a, b, x, s, t); - } - function md5_ii(a, b, c, d, x, s, t) { - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); - } - - /* - * Calculate the MD5 of an array of little-endian words, and a bit length. - */ - function binl_md5(x, len) { - /* append padding */ - x[len >> 5] |= 0x80 << (len % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; - - var i, olda, oldb, oldc, oldd, - a = 1732584193, - b = -271733879, - c = -1732584194, - d = 271733878; - - for (i = 0; i < x.length; i += 16) { - olda = a; - oldb = b; - oldc = c; - oldd = d; - - a = md5_ff(a, b, c, d, x[i], 7, -680876936); - d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); - d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); - d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); - b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); - d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); - - a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); - d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); - c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i], 20, -373897302); - a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); - d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); - c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); - d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); - c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); - d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); - c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); - - a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); - d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); - d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); - d = md5_hh(d, a, b, c, x[i], 11, -358537222); - c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); - d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); - - a = md5_ii(a, b, c, d, x[i], 6, -198630844); - d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); - d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); - d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); - d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return [a, b, c, d]; - } - - /* - * Convert an array of little-endian words to a string - */ - function binl2rstr(input) { - var i, - output = ''; - for (i = 0; i < input.length * 32; i += 8) { - output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); - } - return output; - } - - /* - * Convert a raw string to an array of little-endian words - * Characters >255 have their high-byte silently ignored. - */ - function rstr2binl(input) { - var i, - output = []; - output[(input.length >> 2) - 1] = undefined; - for (i = 0; i < output.length; i += 1) { - output[i] = 0; - } - for (i = 0; i < input.length * 8; i += 8) { - output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); - } - return output; - } - - /* - * Calculate the MD5 of a raw string - */ - function rstr_md5(s) { - return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); - } - - /* - * Calculate the HMAC-MD5, of a key and some data (raw strings) - */ - function rstr_hmac_md5(key, data) { - var i, - bkey = rstr2binl(key), - ipad = [], - opad = [], - hash; - ipad[15] = opad[15] = undefined; - if (bkey.length > 16) { - bkey = binl_md5(bkey, key.length * 8); - } - for (i = 0; i < 16; i += 1) { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } - hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); - return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); - } - - /* - * Convert a raw string to a hex string - */ - function rstr2hex(input) { - var hex_tab = '0123456789abcdef', - output = '', - x, - i; - for (i = 0; i < input.length; i += 1) { - x = input.charCodeAt(i); - output += hex_tab.charAt((x >>> 4) & 0x0F) + - hex_tab.charAt(x & 0x0F); - } - return output; - } - - /* - * Encode a string as utf-8 - */ - function str2rstr_utf8(input) { - return unescape(encodeURIComponent(input)); - } - - /* - * Take string arguments and return either raw or hex encoded strings - */ - function raw_md5(s) { - return rstr_md5(str2rstr_utf8(s)); - } - function hex_md5(s) { - return rstr2hex(raw_md5(s)); - } - function raw_hmac_md5(k, d) { - return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)); - } - function hex_hmac_md5(k, d) { - return rstr2hex(raw_hmac_md5(k, d)); - } - - function md5(string, key, raw) { - if (!key) { - if (!raw) { - return hex_md5(string); - } - return raw_md5(string); - } - if (!raw) { - return hex_hmac_md5(key, string); - } - return raw_hmac_md5(key, string); - } - - if (typeof define === 'function' && define.amd) { - define(function () { - return md5; - }); - } else { - $.md5 = md5; - } -}(this)); diff --git a/server/sonar-web/src/main/js/libs/third-party/react-with-addons.js b/server/sonar-web/src/main/js/libs/third-party/react-with-addons.js deleted file mode 100644 index c1578b776e4..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/react-with-addons.js +++ /dev/null @@ -1,21642 +0,0 @@ -/** - * React (with addons) v0.13.3 - */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.React = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactWithAddons - */ - -/** - * This module exists purely in the open source project, and is meant as a way - * to create a separate standalone build of React. This build has "addons", or - * functionality we've built and think might be useful but doesn't have a good - * place to live inside React core. - */ - -'use strict'; - -var LinkedStateMixin = _dereq_(25); -var React = _dereq_(31); -var ReactComponentWithPureRenderMixin = - _dereq_(42); -var ReactCSSTransitionGroup = _dereq_(34); -var ReactFragment = _dereq_(69); -var ReactTransitionGroup = _dereq_(98); -var ReactUpdates = _dereq_(100); - -var cx = _dereq_(127); -var cloneWithProps = _dereq_(122); -var update = _dereq_(170); - -React.addons = { - CSSTransitionGroup: ReactCSSTransitionGroup, - LinkedStateMixin: LinkedStateMixin, - PureRenderMixin: ReactComponentWithPureRenderMixin, - TransitionGroup: ReactTransitionGroup, - - batchedUpdates: ReactUpdates.batchedUpdates, - classSet: cx, - cloneWithProps: cloneWithProps, - createFragment: ReactFragment.create, - update: update -}; - -if ("production" !== "development") { - React.addons.Perf = _dereq_(61); - React.addons.TestUtils = _dereq_(95); -} - -module.exports = React; - -},{"100":100,"122":122,"127":127,"170":170,"25":25,"31":31,"34":34,"42":42,"61":61,"69":69,"95":95,"98":98}],2:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule AutoFocusMixin - * @typechecks static-only - */ - -'use strict'; - -var focusNode = _dereq_(134); - -var AutoFocusMixin = { - componentDidMount: function() { - if (this.props.autoFocus) { - focusNode(this.getDOMNode()); - } - } -}; - -module.exports = AutoFocusMixin; - -},{"134":134}],3:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015 Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule BeforeInputEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPropagators = _dereq_(21); -var ExecutionEnvironment = _dereq_(22); -var FallbackCompositionState = _dereq_(23); -var SyntheticCompositionEvent = _dereq_(106); -var SyntheticInputEvent = _dereq_(110); - -var keyOf = _dereq_(157); - -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; - -var canUseCompositionEvent = ( - ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window -); - -var documentMode = null; -if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { - documentMode = document.documentMode; -} - -// Webkit offers a very useful `textInput` event that can be used to -// directly represent `beforeInput`. The IE `textinput` event is not as -// useful, so we don't use it. -var canUseTextInputEvent = ( - ExecutionEnvironment.canUseDOM && - 'TextEvent' in window && - !documentMode && - !isPresto() -); - -// In IE9+, we have access to composition events, but the data supplied -// by the native compositionend event may be incorrect. Japanese ideographic -// spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ( - ExecutionEnvironment.canUseDOM && - ( - (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11) - ) -); - -/** - * Opera <= 12 includes TextEvent in window, but does not fire - * text input events. Rely on keypress instead. - */ -function isPresto() { - var opera = window.opera; - return ( - typeof opera === 'object' && - typeof opera.version === 'function' && - parseInt(opera.version(), 10) <= 12 - ); -} - -var SPACEBAR_CODE = 32; -var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); - -var topLevelTypes = EventConstants.topLevelTypes; - -// Events and their corresponding property names. -var eventTypes = { - beforeInput: { - phasedRegistrationNames: { - bubbled: keyOf({onBeforeInput: null}), - captured: keyOf({onBeforeInputCapture: null}) - }, - dependencies: [ - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyPress, - topLevelTypes.topTextInput, - topLevelTypes.topPaste - ] - }, - compositionEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionStart, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionUpdate, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - } -}; - -// Track whether we've ever handled a keypress on the space key. -var hasSpaceKeypress = false; - -/** - * Return whether a native keypress event is assumed to be a command. - * This is required because Firefox fires `keypress` events for key commands - * (cut, copy, select-all, etc.) even though no character is inserted. - */ -function isKeypressCommand(nativeEvent) { - return ( - (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey) - ); -} - - -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case topLevelTypes.topCompositionStart: - return eventTypes.compositionStart; - case topLevelTypes.topCompositionEnd: - return eventTypes.compositionEnd; - case topLevelTypes.topCompositionUpdate: - return eventTypes.compositionUpdate; - } -} - -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); -} - -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topKeyUp: - // Command keys insert or clear IME input. - return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); - case topLevelTypes.topKeyDown: - // Expect IME keyCode on each keydown. If we get any other - // code we must have exited earlier. - return (nativeEvent.keyCode !== START_KEYCODE); - case topLevelTypes.topKeyPress: - case topLevelTypes.topMouseDown: - case topLevelTypes.topBlur: - // Events are not possible without cancelling IME. - return true; - default: - return false; - } -} - -/** - * Google Input Tools provides composition data via a CustomEvent, - * with the `data` property populated in the `detail` object. If this - * is available on the event object, use it. If not, this is a plain - * composition event and we have nothing special to extract. - * - * @param {object} nativeEvent - * @return {?string} - */ -function getDataFromCustomEvent(nativeEvent) { - var detail = nativeEvent.detail; - if (typeof detail === 'object' && 'data' in detail) { - return detail.data; - } - return null; -} - -// Track the current IME composition fallback object, if any. -var currentComposition = null; - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {?object} A SyntheticCompositionEvent. - */ -function extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { - var eventType; - var fallbackData; - - if (canUseCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackCompositionStart(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionStart; - } - } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - } - - if (!eventType) { - return null; - } - - if (useFallbackCompositionData) { - // The current composition is stored statically and must not be - // overwritten while composition continues. - if (!currentComposition && eventType === eventTypes.compositionStart) { - currentComposition = FallbackCompositionState.getPooled(topLevelTarget); - } else if (eventType === eventTypes.compositionEnd) { - if (currentComposition) { - fallbackData = currentComposition.getData(); - } - } - } - - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent - ); - - if (fallbackData) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = fallbackData; - } else { - var customData = getDataFromCustomEvent(nativeEvent); - if (customData !== null) { - event.data = customData; - } - } - - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The string corresponding to this `beforeInput` event. - */ -function getNativeBeforeInputChars(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topCompositionEnd: - return getDataFromCustomEvent(nativeEvent); - case topLevelTypes.topKeyPress: - /** - * If native `textInput` events are available, our goal is to make - * use of them. However, there is a special case: the spacebar key. - * In Webkit, preventing default on a spacebar `textInput` event - * cancels character insertion, but it *also* causes the browser - * to fall back to its default spacebar behavior of scrolling the - * page. - * - * Tracking at: - * https://code.google.com/p/chromium/issues/detail?id=355103 - * - * To avoid this issue, use the keypress event as if no `textInput` - * event is available. - */ - var which = nativeEvent.which; - if (which !== SPACEBAR_CODE) { - return null; - } - - hasSpaceKeypress = true; - return SPACEBAR_CHAR; - - case topLevelTypes.topTextInput: - // Record the characters to be added to the DOM. - var chars = nativeEvent.data; - - // If it's a spacebar character, assume that we have already handled - // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. - if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { - return null; - } - - return chars; - - default: - // For other native event types, do nothing. - return null; - } -} - -/** - * For browsers that do not provide the `textInput` event, extract the - * appropriate string to use for SyntheticInputEvent. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The fallback string for this `beforeInput` event. - */ -function getFallbackBeforeInputChars(topLevelType, nativeEvent) { - // If we are currently composing (IME) and using a fallback to do so, - // try to extract the composed characters from the fallback object. - if (currentComposition) { - if ( - topLevelType === topLevelTypes.topCompositionEnd || - isFallbackCompositionEnd(topLevelType, nativeEvent) - ) { - var chars = currentComposition.getData(); - FallbackCompositionState.release(currentComposition); - currentComposition = null; - return chars; - } - return null; - } - - switch (topLevelType) { - case topLevelTypes.topPaste: - // If a paste event occurs after a keypress, throw out the input - // chars. Paste events should not lead to BeforeInput events. - return null; - case topLevelTypes.topKeyPress: - /** - * As of v27, Firefox may fire keypress events even when no character - * will be inserted. A few possibilities: - * - * - `which` is `0`. Arrow keys, Esc key, etc. - * - * - `which` is the pressed key code, but no char is available. - * Ex: 'AltGr + d` in Polish. There is no modified character for - * this key combination and no character is inserted into the - * document, but FF fires the keypress for char code `100` anyway. - * No `input` event will occur. - * - * - `which` is the pressed key code, but a command combination is - * being used. Ex: `Cmd+C`. No character is inserted, and no - * `input` event will occur. - */ - if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { - return String.fromCharCode(nativeEvent.which); - } - return null; - case topLevelTypes.topCompositionEnd: - return useFallbackCompositionData ? null : nativeEvent.data; - default: - return null; - } -} - -/** - * Extract a SyntheticInputEvent for `beforeInput`, based on either native - * `textInput` or fallback behavior. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {?object} A SyntheticInputEvent. - */ -function extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { - var chars; - - if (canUseTextInputEvent) { - chars = getNativeBeforeInputChars(topLevelType, nativeEvent); - } else { - chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); - } - - // If no characters are being inserted, no BeforeInput event should - // be fired. - if (!chars) { - return null; - } - - var event = SyntheticInputEvent.getPooled( - eventTypes.beforeInput, - topLevelTargetID, - nativeEvent - ); - - event.data = chars; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. - * - * This event plugin is based on the native `textInput` event - * available in Chrome, Safari, Opera, and IE. This event fires after - * `onKeyPress` and `onCompositionEnd`, but before `onInput`. - * - * `beforeInput` is spec'd but not implemented in any browsers, and - * the `input` event does not provide any useful information about what has - * actually been added, contrary to the spec. Thus, `textInput` is the best - * available event to identify the characters that have actually been inserted - * into the target node. - * - * This plugin is also responsible for emitting `composition` events, thus - * allowing us to share composition fallback code for both `beforeInput` and - * `composition` event types. - */ -var BeforeInputEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) { - return [ - extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ), - extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) - ]; - } -}; - -module.exports = BeforeInputEventPlugin; - -},{"106":106,"110":110,"157":157,"16":16,"21":21,"22":22,"23":23}],4:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSCore - * @typechecks - */ - -var invariant = _dereq_(150); - -/** - * The CSSCore module specifies the API (and implements most of the methods) - * that should be used when dealing with the display of elements (via their - * CSS classes and visibility on screen. It is an API focused on mutating the - * display and not reading it as no logical state should be encoded in the - * display of elements. - */ - -var CSSCore = { - - /** - * Adds the class passed in to the element if it doesn't already have it. - * - * @param {DOMElement} element the element to set the class on - * @param {string} className the CSS className - * @return {DOMElement} the element passed in - */ - addClass: function(element, className) { - ("production" !== "development" ? invariant( - !/\s/.test(className), - 'CSSCore.addClass takes only a single class name. "%s" contains ' + - 'multiple classes.', className - ) : invariant(!/\s/.test(className))); - - if (className) { - if (element.classList) { - element.classList.add(className); - } else if (!CSSCore.hasClass(element, className)) { - element.className = element.className + ' ' + className; - } - } - return element; - }, - - /** - * Removes the class passed in from the element - * - * @param {DOMElement} element the element to set the class on - * @param {string} className the CSS className - * @return {DOMElement} the element passed in - */ - removeClass: function(element, className) { - ("production" !== "development" ? invariant( - !/\s/.test(className), - 'CSSCore.removeClass takes only a single class name. "%s" contains ' + - 'multiple classes.', className - ) : invariant(!/\s/.test(className))); - - if (className) { - if (element.classList) { - element.classList.remove(className); - } else if (CSSCore.hasClass(element, className)) { - element.className = element.className - .replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1') - .replace(/\s+/g, ' ') // multiple spaces to one - .replace(/^\s*|\s*$/g, ''); // trim the ends - } - } - return element; - }, - - /** - * Helper to add or remove a class from an element based on a condition. - * - * @param {DOMElement} element the element to set the class on - * @param {string} className the CSS className - * @param {*} bool condition to whether to add or remove the class - * @return {DOMElement} the element passed in - */ - conditionClass: function(element, className, bool) { - return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className); - }, - - /** - * Tests whether the element has the class specified. - * - * @param {DOMNode|DOMWindow} element the element to set the class on - * @param {string} className the CSS className - * @return {boolean} true if the element has the class, false if not - */ - hasClass: function(element, className) { - ("production" !== "development" ? invariant( - !/\s/.test(className), - 'CSS.hasClass takes only a single class name.' - ) : invariant(!/\s/.test(className))); - if (element.classList) { - return !!className && element.classList.contains(className); - } - return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; - } - -}; - -module.exports = CSSCore; - -},{"150":150}],5:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSProperty - */ - -'use strict'; - -/** - * CSS properties which accept numbers but are not in units of "px". - */ -var isUnitlessNumber = { - boxFlex: true, - boxFlexGroup: true, - columnCount: true, - flex: true, - flexGrow: true, - flexPositive: true, - flexShrink: true, - flexNegative: true, - fontWeight: true, - lineClamp: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related properties - fillOpacity: true, - strokeDashoffset: true, - strokeOpacity: true, - strokeWidth: true -}; - -/** - * @param {string} prefix vendor-specific prefix, eg: Webkit - * @param {string} key style name, eg: transitionDuration - * @return {string} style name prefixed with `prefix`, properly camelCased, eg: - * WebkitTransitionDuration - */ -function prefixKey(prefix, key) { - return prefix + key.charAt(0).toUpperCase() + key.substring(1); -} - -/** - * Support style names that may come passed in prefixed by adding permutations - * of vendor prefixes. - */ -var prefixes = ['Webkit', 'ms', 'Moz', 'O']; - -// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an -// infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function(prop) { - prefixes.forEach(function(prefix) { - isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; - }); -}); - -/** - * Most style properties can be unset by doing .style[prop] = '' but IE8 - * doesn't like doing that with shorthand properties so for the properties that - * IE8 breaks on, which are listed here, we instead unset each of the - * individual properties. See http://bugs.jquery.com/ticket/12385. - * The 4-value 'clock' properties like margin, padding, border-width seem to - * behave without any problems. Curiously, list-style works too without any - * special prodding. - */ -var shorthandPropertyExpansions = { - background: { - backgroundImage: true, - backgroundPosition: true, - backgroundRepeat: true, - backgroundColor: true - }, - border: { - borderWidth: true, - borderStyle: true, - borderColor: true - }, - borderBottom: { - borderBottomWidth: true, - borderBottomStyle: true, - borderBottomColor: true - }, - borderLeft: { - borderLeftWidth: true, - borderLeftStyle: true, - borderLeftColor: true - }, - borderRight: { - borderRightWidth: true, - borderRightStyle: true, - borderRightColor: true - }, - borderTop: { - borderTopWidth: true, - borderTopStyle: true, - borderTopColor: true - }, - font: { - fontStyle: true, - fontVariant: true, - fontWeight: true, - fontSize: true, - lineHeight: true, - fontFamily: true - } -}; - -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions -}; - -module.exports = CSSProperty; - -},{}],6:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var CSSProperty = _dereq_(5); -var ExecutionEnvironment = _dereq_(22); - -var camelizeStyleName = _dereq_(121); -var dangerousStyleValue = _dereq_(128); -var hyphenateStyleName = _dereq_(148); -var memoizeStringOnly = _dereq_(159); -var warning = _dereq_(171); - -var processStyleName = memoizeStringOnly(function(styleName) { - return hyphenateStyleName(styleName); -}); - -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; - } -} - -if ("production" !== "development") { - // 'msTransform' is correct, but the other prefixes should be capitalized - var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; - - // style values shouldn't contain a semicolon - var badStyleValueWithSemicolonPattern = /;\s*$/; - - var warnedStyleNames = {}; - var warnedStyleValues = {}; - - var warnHyphenatedStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - ("production" !== "development" ? warning( - false, - 'Unsupported style property %s. Did you mean %s?', - name, - camelizeStyleName(name) - ) : null); - }; - - var warnBadVendoredStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - ("production" !== "development" ? warning( - false, - 'Unsupported vendor-prefixed style property %s. Did you mean %s?', - name, - name.charAt(0).toUpperCase() + name.slice(1) - ) : null); - }; - - var warnStyleValueWithSemicolon = function(name, value) { - if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { - return; - } - - warnedStyleValues[value] = true; - ("production" !== "development" ? warning( - false, - 'Style property values shouldn\'t contain a semicolon. ' + - 'Try "%s: %s" instead.', - name, - value.replace(badStyleValueWithSemicolonPattern, '') - ) : null); - }; - - /** - * @param {string} name - * @param {*} value - */ - var warnValidStyle = function(name, value) { - if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name); - } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name); - } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value); - } - }; -} - -/** - * Operations for dealing with CSS properties. - */ -var CSSPropertyOperations = { - - /** - * Serializes a mapping of style properties for use as inline styles: - * - * > createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * The result should be HTML-escaped before insertion into the DOM. - * - * @param {object} styles - * @return {?string} - */ - createMarkupForStyles: function(styles) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = styles[styleName]; - if ("production" !== "development") { - warnValidStyle(styleName, styleValue); - } - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; - } - } - return serialized || null; - }, - - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - */ - setValueForStyles: function(node, styles) { - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if ("production" !== "development") { - warnValidStyle(styleName, styles[styleName]); - } - var styleValue = dangerousStyleValue(styleName, styles[styleName]); - if (styleName === 'float') { - styleName = styleFloatAccessor; - } - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } - } - -}; - -module.exports = CSSPropertyOperations; - -},{"121":121,"128":128,"148":148,"159":159,"171":171,"22":22,"5":5}],7:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CallbackQueue - */ - -'use strict'; - -var PooledClass = _dereq_(30); - -var assign = _dereq_(29); -var invariant = _dereq_(150); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ -function CallbackQueue() { - this._callbacks = null; - this._contexts = null; -} - -assign(CallbackQueue.prototype, { - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - enqueue: function(callback, context) { - this._callbacks = this._callbacks || []; - this._contexts = this._contexts || []; - this._callbacks.push(callback); - this._contexts.push(context); - }, - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - notifyAll: function() { - var callbacks = this._callbacks; - var contexts = this._contexts; - if (callbacks) { - ("production" !== "development" ? invariant( - callbacks.length === contexts.length, - 'Mismatched list of contexts in callback queue' - ) : invariant(callbacks.length === contexts.length)); - this._callbacks = null; - this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { - callbacks[i].call(contexts[i]); - } - callbacks.length = 0; - contexts.length = 0; - } - }, - - /** - * Resets the internal queue. - * - * @internal - */ - reset: function() { - this._callbacks = null; - this._contexts = null; - }, - - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); - } - -}); - -PooledClass.addPoolingTo(CallbackQueue); - -module.exports = CallbackQueue; - -},{"150":150,"29":29,"30":30}],8:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ChangeEventPlugin - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPluginHub = _dereq_(18); -var EventPropagators = _dereq_(21); -var ExecutionEnvironment = _dereq_(22); -var ReactUpdates = _dereq_(100); -var SyntheticEvent = _dereq_(108); - -var isEventSupported = _dereq_(151); -var isTextInputElement = _dereq_(153); -var keyOf = _dereq_(157); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topChange, - topLevelTypes.topClick, - topLevelTypes.topFocus, - topLevelTypes.topInput, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyUp, - topLevelTypes.topSelectionChange - ] - } -}; - -/** - * For IE shims - */ -var activeElement = null; -var activeElementID = null; -var activeElementValue = null; -var activeElementValueProp = null; - -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); -} - -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - (!('documentMode' in document) || document.documentMode > 8) - ); -} - -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - - // If change and propertychange bubbled, we'd just bind to it like all the - // other events and have it go through ReactBrowserEventEmitter. Since it - // doesn't, we manually listen for the events and so we have to enqueue and - // process the abstract event manually. - // - // Batching is necessary here in order to ensure that all event handlers run - // before the next rerender (including event handlers attached to ancestor - // elements instead of directly on the input). Without this, controlled - // components don't work properly in conjunction with event bubbling because - // the component is rerendered and the value reverted before all the event - // handlers can run. See https://github.com/facebook/react/issues/708. - ReactUpdates.batchedUpdates(runEventInBatch, event); -} - -function runEventInBatch(event) { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); -} - -function startWatchingForChangeEventIE8(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} - -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementID = null; -} - -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topChange) { - return topLevelTargetID; - } -} -function handleEventsForChangeEventIE8( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForChangeEventIE8(); - } -} - - -/** - * SECTION: handle `input` event - */ -var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { - // IE9 claims to support the input event but fails to trigger it when - // deleting text, so we ignore its input events - isInputEventSupported = isEventSupported('input') && ( - (!('documentMode' in document) || document.documentMode > 9) - ); -} - -/** - * (For old IE.) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function() { - return activeElementValueProp.get.call(this); - }, - set: function(val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; - -/** - * (For old IE.) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); - - Object.defineProperty(activeElement, 'value', newValueProp); - activeElement.attachEvent('onpropertychange', handlePropertyChange); -} - -/** - * (For old IE.) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - - // delete restores the original property definition - delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); - - activeElement = null; - activeElementID = null; - activeElementValue = null; - activeElementValueProp = null; -} - -/** - * (For old IE.) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; - - manualDispatchChangeEvent(nativeEvent); -} - -/** - * If a `change` event should be fired, returns the target's ID. - */ -function getTargetIDForInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topInput) { - // In modern browsers (i.e., not IE8 or IE9), the input event is exactly - // what we want so fall through here and trigger an abstract event - return topLevelTargetID; - } -} - -// For IE8 and IE9. -function handleEventsForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // In IE8, we can capture almost all .value changes by adding a - // propertychange handler and looking for events with propertyName - // equal to 'value' - // In IE9, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForValueChange(); - } -} - -// For IE8 and IE9. -function getTargetIDForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topSelectionChange || - topLevelType === topLevelTypes.topKeyUp || - topLevelType === topLevelTypes.topKeyDown) { - // On the selectionchange event, the target is just document which isn't - // helpful for us so just check activeElement instead. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementID; - } - } -} - - -/** - * SECTION: handle `click` event - */ -function shouldUseClickEvent(elem) { - // Use the `click` event to detect changes to checkbox and radio inputs. - // This approach works across all browsers, whereas `change` does not fire - // until `blur` in IE8. - return ( - elem.nodeName === 'INPUT' && - (elem.type === 'checkbox' || elem.type === 'radio') - ); -} - -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; - } -} - -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - var getTargetIDFunc, handleEventFunc; - if (shouldUseChangeEvent(topLevelTarget)) { - if (doesChangeEventBubble) { - getTargetIDFunc = getTargetIDForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(topLevelTarget)) { - if (isInputEventSupported) { - getTargetIDFunc = getTargetIDForInputEvent; - } else { - getTargetIDFunc = getTargetIDForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(topLevelTarget)) { - getTargetIDFunc = getTargetIDForClickEvent; - } - - if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } - - if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - } - } - -}; - -module.exports = ChangeEventPlugin; - -},{"100":100,"108":108,"151":151,"153":153,"157":157,"16":16,"18":18,"21":21,"22":22}],9:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ClientReactRootIndex - * @typechecks - */ - -'use strict'; - -var nextReactRootIndex = 0; - -var ClientReactRootIndex = { - createReactRootIndex: function() { - return nextReactRootIndex++; - } -}; - -module.exports = ClientReactRootIndex; - -},{}],10:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMChildrenOperations - * @typechecks static-only - */ - -'use strict'; - -var Danger = _dereq_(13); -var ReactMultiChildUpdateTypes = _dereq_(79); - -var setTextContent = _dereq_(165); -var invariant = _dereq_(150); - -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -function insertChildAt(parentNode, childNode, index) { - // By exploiting arrays returning `undefined` for an undefined index, we can - // rely exclusively on `insertBefore(node, null)` instead of also using - // `appendChild(node)`. However, using `undefined` is not allowed by all - // browsers so we must replace it with `null`. - parentNode.insertBefore( - childNode, - parentNode.childNodes[index] || null - ); -} - -/** - * Operations for updating with DOM children. - */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, - - updateTextContent: setTextContent, - - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array<object>} updates List of update configurations. - * @param {array<string>} markupList List of markup strings. - * @internal - */ - processUpdates: function(updates, markupList) { - var update; - // Mapping from parent IDs to initial child orderings. - var initialChildren = null; - // List of children that will be moved or removed. - var updatedChildren = null; - - for (var i = 0; i < updates.length; i++) { - update = updates[i]; - if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || - update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { - var updatedIndex = update.fromIndex; - var updatedChild = update.parentNode.childNodes[updatedIndex]; - var parentID = update.parentID; - - ("production" !== "development" ? invariant( - updatedChild, - 'processUpdates(): Unable to find child %s of element. This ' + - 'probably means the DOM was unexpectedly mutated (e.g., by the ' + - 'browser), usually due to forgetting a <tbody> when using tables, ' + - 'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' + - 'in an <svg> parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); - - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; - - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } - - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); - - // Remove updated children first so that `toIndex` is consistent. - if (updatedChildren) { - for (var j = 0; j < updatedChildren.length; j++) { - updatedChildren[j].parentNode.removeChild(updatedChildren[j]); - } - } - - for (var k = 0; k < updates.length; k++) { - update = updates[k]; - switch (update.type) { - case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent( - update.parentNode, - update.textContent - ); - break; - case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; - -},{"13":13,"150":150,"165":165,"79":79}],11:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMProperty - * @typechecks static-only - */ - -/*jslint bitwise: true */ - -'use strict'; - -var invariant = _dereq_(150); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } - - for (var propName in Properties) { - ("production" !== "development" ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - - DOMProperty.isStandardName[propName] = true; - - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; - } - - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; - - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } - - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - ("production" !== "development" ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== "development" ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== "development" ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); - } - } -}; -var defaultValueCache = {}; - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails `<propName> in <element>`.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. - * @type {Object} - */ - hasOverloadedBooleanValue: {}, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * TODO: Is it better to grab all the possible properties when creating an - * element to avoid having to create the same element twice? - */ - getDefaultValueForProperty: function(nodeName, prop) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; - } - return nodeDefaults[prop]; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; - -},{"150":150}],12:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = _dereq_(11); - -var quoteAttributeValueForBrowser = _dereq_(163); -var warning = _dereq_(171); - -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); -} - -if ("production" !== "development") { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true - }; - var warnedProperties = {}; - - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return; - } - - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); - - // For now, only warn when we have a suggested correction. This prevents - // logging too much when using transferPropsTo. - ("production" !== "development" ? warning( - standardName == null, - 'Unknown DOM property %s. Did you mean %s?', - name, - standardName - ) : null); - - }; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); - }, - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { - return ''; - } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return attributeName; - } - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("production" !== "development") { - warnUnknownProperty(name); - } - return null; - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { - this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); - } else { - var propName = DOMProperty.getPropertyName[name]; - // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the - // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propName] = value; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== "development") { - warnUnknownProperty(name); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { - node[propName] = defaultValue; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } else if ("production" !== "development") { - warnUnknownProperty(name); - } - } - -}; - -module.exports = DOMPropertyOperations; - -},{"11":11,"163":163,"171":171}],13:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Danger - * @typechecks static-only - */ - -/*jslint evil: true, sub: true */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); - -var createNodesFromMarkup = _dereq_(126); -var emptyFunction = _dereq_(129); -var getMarkupWrap = _dereq_(142); -var invariant = _dereq_(150); - -var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; -var RESULT_INDEX_ATTR = 'data-danger-index'; - -/** - * Extracts the `nodeName` from a string of markup. - * - * NOTE: Extracting the `nodeName` does not require a regular expression match - * because we make assumptions about React-generated markup (i.e. there are no - * spaces surrounding the opening tag and there is at least one attribute). - * - * @param {string} markup String of markup. - * @return {string} Node name of the supplied markup. - * @see http://jsperf.com/extract-nodename - */ -function getNodeName(markup) { - return markup.substring(1, markup.indexOf(' ')); -} - -var Danger = { - - /** - * Renders markup into an array of nodes. The markup is expected to render - * into a list of root nodes. Also, the length of `resultList` and - * `markupList` should be the same. - * - * @param {array<string>} markupList List of markup strings to render. - * @return {array<DOMElement>} List of rendered nodes. - * @internal - */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== "development" ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - var nodeName; - var markupByNodeName = {}; - // Group markup by `nodeName` if a wrap is necessary, else by '*'. - for (var i = 0; i < markupList.length; i++) { - ("production" !== "development" ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); - nodeName = getNodeName(markupList[i]); - nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; - markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; - markupByNodeName[nodeName][i] = markupList[i]; - } - var resultList = []; - var resultListAssignmentCount = 0; - for (nodeName in markupByNodeName) { - if (!markupByNodeName.hasOwnProperty(nodeName)) { - continue; - } - var markupListByNodeName = markupByNodeName[nodeName]; - - // This for-in loop skips the holes of the sparse array. The order of - // iteration should follow the order of assignment, which happens to match - // numerical index order, but we don't rely on that. - var resultIndex; - for (resultIndex in markupListByNodeName) { - if (markupListByNodeName.hasOwnProperty(resultIndex)) { - var markup = markupListByNodeName[resultIndex]; - - // Push the requested markup with an additional RESULT_INDEX_ATTR - // attribute. If the markup does not start with a < character, it - // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); - } - } - - // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with <script> tags. - ); - - for (var j = 0; j < renderNodes.length; ++j) { - var renderNode = renderNodes[j]; - if (renderNode.hasAttribute && - renderNode.hasAttribute(RESULT_INDEX_ATTR)) { - - resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR); - renderNode.removeAttribute(RESULT_INDEX_ATTR); - - ("production" !== "development" ? invariant( - !resultList.hasOwnProperty(resultIndex), - 'Danger: Assigning to an already-occupied result index.' - ) : invariant(!resultList.hasOwnProperty(resultIndex))); - - resultList[resultIndex] = renderNode; - - // This should match resultList.length and markupList.length when - // we're done. - resultListAssignmentCount += 1; - - } else if ("production" !== "development") { - console.error( - 'Danger: Discarding unexpected node:', - renderNode - ); - } - } - } - - // Although resultList was populated out of order, it should now be a dense - // array. - ("production" !== "development" ? invariant( - resultListAssignmentCount === resultList.length, - 'Danger: Did not assign to every index of resultList.' - ) : invariant(resultListAssignmentCount === resultList.length)); - - ("production" !== "development" ? invariant( - resultList.length === markupList.length, - 'Danger: Expected markup to render %s nodes, but rendered %s.', - markupList.length, - resultList.length - ) : invariant(resultList.length === markupList.length)); - - return resultList; - }, - - /** - * Replaces a node with a string of markup at its current position within its - * parent. The markup must render into a single root node. - * - * @param {DOMElement} oldChild Child node to replace. - * @param {string} markup Markup to render in place of the child node. - * @internal - */ - dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) { - ("production" !== "development" ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + - 'worker thread. Make sure `window` and `document` are available ' + - 'globally before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - ("production" !== "development" ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup)); - ("production" !== "development" ? invariant( - oldChild.tagName.toLowerCase() !== 'html', - 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + - '<html> node. This is because browser quirks make this unreliable ' + - 'and/or slow. If you want to render to the root you must use ' + - 'server rendering. See React.renderToString().' - ) : invariant(oldChild.tagName.toLowerCase() !== 'html')); - - var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; - oldChild.parentNode.replaceChild(newChild, oldChild); - } - -}; - -module.exports = Danger; - -},{"126":126,"129":129,"142":142,"150":150,"22":22}],14:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DefaultEventPluginOrder - */ - -'use strict'; - -var keyOf = _dereq_(157); - -/** - * Module that is injectable into `EventPluginHub`, that specifies a - * deterministic ordering of `EventPlugin`s. A convenient way to reason about - * plugins, without having to package every one of them. This is better than - * having plugins be ordered in the same order that they are injected because - * that ordering would be influenced by the packaging order. - * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that - * preventing default on events is convenient in `SimpleEventPlugin` handlers. - */ -var DefaultEventPluginOrder = [ - keyOf({ResponderEventPlugin: null}), - keyOf({SimpleEventPlugin: null}), - keyOf({TapEventPlugin: null}), - keyOf({EnterLeaveEventPlugin: null}), - keyOf({ChangeEventPlugin: null}), - keyOf({SelectEventPlugin: null}), - keyOf({BeforeInputEventPlugin: null}), - keyOf({AnalyticsEventPlugin: null}), - keyOf({MobileSafariClickEventPlugin: null}) -]; - -module.exports = DefaultEventPluginOrder; - -},{"157":157}],15:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EnterLeaveEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPropagators = _dereq_(21); -var SyntheticMouseEvent = _dereq_(112); - -var ReactMount = _dereq_(77); -var keyOf = _dereq_(157); - -var topLevelTypes = EventConstants.topLevelTypes; -var getFirstReactDOM = ReactMount.getFirstReactDOM; - -var eventTypes = { - mouseEnter: { - registrationName: keyOf({onMouseEnter: null}), - dependencies: [ - topLevelTypes.topMouseOut, - topLevelTypes.topMouseOver - ] - }, - mouseLeave: { - registrationName: keyOf({onMouseLeave: null}), - dependencies: [ - topLevelTypes.topMouseOut, - topLevelTypes.topMouseOver - ] - } -}; - -var extractedEvents = [null, null]; - -var EnterLeaveEventPlugin = { - - eventTypes: eventTypes, - - /** - * For almost every interaction we care about, there will be both a top-level - * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that - * we do not extract duplicate events. However, moving the mouse into the - * browser from outside will not fire a `mouseout` event. In this case, we use - * the `mouseover` top-level event. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - if (topLevelType === topLevelTypes.topMouseOver && - (nativeEvent.relatedTarget || nativeEvent.fromElement)) { - return null; - } - if (topLevelType !== topLevelTypes.topMouseOut && - topLevelType !== topLevelTypes.topMouseOver) { - // Must not be a mouse in or mouse out - ignoring. - return null; - } - - var win; - if (topLevelTarget.window === topLevelTarget) { - // `topLevelTarget` is probably a window object. - win = topLevelTarget; - } else { - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - var doc = topLevelTarget.ownerDocument; - if (doc) { - win = doc.defaultView || doc.parentWindow; - } else { - win = window; - } - } - - var from, to; - if (topLevelType === topLevelTypes.topMouseOut) { - from = topLevelTarget; - to = - getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) || - win; - } else { - from = win; - to = topLevelTarget; - } - - if (from === to) { - // Nothing pertains to our managed components. - return null; - } - - var fromID = from ? ReactMount.getID(from) : ''; - var toID = to ? ReactMount.getID(to) : ''; - - var leave = SyntheticMouseEvent.getPooled( - eventTypes.mouseLeave, - fromID, - nativeEvent - ); - leave.type = 'mouseleave'; - leave.target = from; - leave.relatedTarget = to; - - var enter = SyntheticMouseEvent.getPooled( - eventTypes.mouseEnter, - toID, - nativeEvent - ); - enter.type = 'mouseenter'; - enter.target = to; - enter.relatedTarget = from; - - EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID); - - extractedEvents[0] = leave; - extractedEvents[1] = enter; - - return extractedEvents; - } - -}; - -module.exports = EnterLeaveEventPlugin; - -},{"112":112,"157":157,"16":16,"21":21,"77":77}],16:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventConstants - */ - -'use strict'; - -var keyMirror = _dereq_(156); - -var PropagationPhases = keyMirror({bubbled: null, captured: null}); - -/** - * Types of raw signals from the browser caught at the top level. - */ -var topLevelTypes = keyMirror({ - topBlur: null, - topChange: null, - topClick: null, - topCompositionEnd: null, - topCompositionStart: null, - topCompositionUpdate: null, - topContextMenu: null, - topCopy: null, - topCut: null, - topDoubleClick: null, - topDrag: null, - topDragEnd: null, - topDragEnter: null, - topDragExit: null, - topDragLeave: null, - topDragOver: null, - topDragStart: null, - topDrop: null, - topError: null, - topFocus: null, - topInput: null, - topKeyDown: null, - topKeyPress: null, - topKeyUp: null, - topLoad: null, - topMouseDown: null, - topMouseMove: null, - topMouseOut: null, - topMouseOver: null, - topMouseUp: null, - topPaste: null, - topReset: null, - topScroll: null, - topSelectionChange: null, - topSubmit: null, - topTextInput: null, - topTouchCancel: null, - topTouchEnd: null, - topTouchMove: null, - topTouchStart: null, - topWheel: null -}); - -var EventConstants = { - topLevelTypes: topLevelTypes, - PropagationPhases: PropagationPhases -}; - -module.exports = EventConstants; - -},{"156":156}],17:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @providesModule EventListener - * @typechecks - */ - -var emptyFunction = _dereq_(129); - -/** - * Upstream version of event listener. Does not take into account specific - * nature of platform. - */ -var EventListener = { - /** - * Listen to DOM events during the bubble phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - listen: function(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function() { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent('on' + eventType, callback); - return { - remove: function() { - target.detachEvent('on' + eventType, callback); - } - }; - } - }, - - /** - * Listen to DOM events during the capture phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - capture: function(target, eventType, callback) { - if (!target.addEventListener) { - if ("production" !== "development") { - console.error( - 'Attempted to listen to events during the capture phase on a ' + - 'browser that does not support the capture phase. Your application ' + - 'will not receive some events.' - ); - } - return { - remove: emptyFunction - }; - } else { - target.addEventListener(eventType, callback, true); - return { - remove: function() { - target.removeEventListener(eventType, callback, true); - } - }; - } - }, - - registerDefault: function() {} -}; - -module.exports = EventListener; - -},{"129":129}],18:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPluginHub - */ - -'use strict'; - -var EventPluginRegistry = _dereq_(19); -var EventPluginUtils = _dereq_(20); - -var accumulateInto = _dereq_(118); -var forEachAccumulated = _dereq_(135); -var invariant = _dereq_(150); - -/** - * Internal store for event listeners - */ -var listenerBank = {}; - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ -var eventQueue = null; - -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private - */ -var executeDispatchesAndRelease = function(event) { - if (event) { - var executeDispatch = EventPluginUtils.executeDispatch; - // Plugins can provide custom behavior when dispatching events. - var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event); - if (PluginModule && PluginModule.executeDispatch) { - executeDispatch = PluginModule.executeDispatch; - } - EventPluginUtils.executeDispatchesInOrder(event, executeDispatch); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; - -/** - * - `InstanceHandle`: [required] Module that performs logical traversals of DOM - * hierarchy given ids of the logical DOM elements involved. - */ -var InstanceHandle = null; - -function validateInstanceHandle() { - var valid = - InstanceHandle && - InstanceHandle.traverseTwoPhase && - InstanceHandle.traverseEnterLeave; - ("production" !== "development" ? invariant( - valid, - 'InstanceHandle not injected before use!' - ) : invariant(valid)); -} - -/** - * This is a unified interface for event plugins to be installed and configured. - * - * Event plugins can implement the following properties: - * - * `extractEvents` {function(string, DOMEventTarget, string, object): *} - * Required. When a top-level event is fired, this method is expected to - * extract synthetic events that will in turn be queued and dispatched. - * - * `eventTypes` {object} - * Optional, plugins that fire events must publish a mapping of registration - * names that are used to register listeners. Values of this mapping must - * be objects that contain `registrationName` or `phasedRegistrationNames`. - * - * `executeDispatch` {function(object, function, string)} - * Optional, allows plugins to override how an event gets dispatched. By - * default, the listener is simply invoked. - * - * Each plugin that is injected into `EventsPluginHub` is immediately operable. - * - * @public - */ -var EventPluginHub = { - - /** - * Methods for injecting dependencies. - */ - injection: { - - /** - * @param {object} InjectedMount - * @public - */ - injectMount: EventPluginUtils.injection.injectMount, - - /** - * @param {object} InjectedInstanceHandle - * @public - */ - injectInstanceHandle: function(InjectedInstanceHandle) { - InstanceHandle = InjectedInstanceHandle; - if ("production" !== "development") { - validateInstanceHandle(); - } - }, - - getInstanceHandle: function() { - if ("production" !== "development") { - validateInstanceHandle(); - } - return InstanceHandle; - }, - - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, - - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName - - }, - - eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, - - registrationNameModules: EventPluginRegistry.registrationNameModules, - - /** - * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {?function} listener The callback to store. - */ - putListener: function(id, registrationName, listener) { - ("production" !== "development" ? invariant( - !listener || typeof listener === 'function', - 'Expected %s listener to be a function, instead got type %s', - registrationName, typeof listener - ) : invariant(!listener || typeof listener === 'function')); - - var bankForRegistrationName = - listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[id] = listener; - }, - - /** - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - getListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - return bankForRegistrationName && bankForRegistrationName[id]; - }, - - /** - * Deletes a listener from the registration bank. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - */ - deleteListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - if (bankForRegistrationName) { - delete bankForRegistrationName[id]; - } - }, - - /** - * Deletes all listeners for the DOM element with the supplied ID. - * - * @param {string} id ID of the DOM element. - */ - deleteAllListeners: function(id) { - for (var registrationName in listenerBank) { - delete listenerBank[registrationName][id]; - } - }, - - /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @internal - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var events; - var plugins = EventPluginRegistry.plugins; - for (var i = 0, l = plugins.length; i < l; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ); - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } - } - } - return events; - }, - - /** - * Enqueues a synthetic event that should be dispatched when - * `processEventQueue` is invoked. - * - * @param {*} events An accumulation of synthetic events. - * @internal - */ - enqueueEvents: function(events) { - if (events) { - eventQueue = accumulateInto(eventQueue, events); - } - }, - - /** - * Dispatches all synthetic events on the event queue. - * - * @internal - */ - processEventQueue: function() { - // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - var processingEventQueue = eventQueue; - eventQueue = null; - forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); - ("production" !== "development" ? invariant( - !eventQueue, - 'processEventQueue(): Additional events were enqueued while processing ' + - 'an event queue. Support for this has not yet been implemented.' - ) : invariant(!eventQueue)); - }, - - /** - * These are needed for tests only. Do not use! - */ - __purge: function() { - listenerBank = {}; - }, - - __getListenerBank: function() { - return listenerBank; - } - -}; - -module.exports = EventPluginHub; - -},{"118":118,"135":135,"150":150,"19":19,"20":20}],19:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPluginRegistry - * @typechecks static-only - */ - -'use strict'; - -var invariant = _dereq_(150); - -/** - * Injectable ordering of event plugins. - */ -var EventPluginOrder = null; - -/** - * Injectable mapping from names to event plugin modules. - */ -var namesToPlugins = {}; - -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ -function recomputePluginOrdering() { - if (!EventPluginOrder) { - // Wait until an `EventPluginOrder` is injected. - return; - } - for (var pluginName in namesToPlugins) { - var PluginModule = namesToPlugins[pluginName]; - var pluginIndex = EventPluginOrder.indexOf(pluginName); - ("production" !== "development" ? invariant( - pluginIndex > -1, - 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + - 'the plugin ordering, `%s`.', - pluginName - ) : invariant(pluginIndex > -1)); - if (EventPluginRegistry.plugins[pluginIndex]) { - continue; - } - ("production" !== "development" ? invariant( - PluginModule.extractEvents, - 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + - 'method, but `%s` does not.', - pluginName - ) : invariant(PluginModule.extractEvents)); - EventPluginRegistry.plugins[pluginIndex] = PluginModule; - var publishedEvents = PluginModule.eventTypes; - for (var eventName in publishedEvents) { - ("production" !== "development" ? invariant( - publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ), - 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', - eventName, - pluginName - ) : invariant(publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ))); - } - } -} - -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { - ("production" !== "development" ? invariant( - !EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName), - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'event name, `%s`.', - eventName - ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName))); - EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; - - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - PluginModule, - eventName - ); - } - } - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - PluginModule, - eventName - ); - return true; - } - return false; -} - -/** - * Publishes a registration name that is used to identify dispatched events and - * can be used with `EventPluginHub.putListener` to register listeners. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ -function publishRegistrationName(registrationName, PluginModule, eventName) { - ("production" !== "development" ? invariant( - !EventPluginRegistry.registrationNameModules[registrationName], - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'registration name, `%s`.', - registrationName - ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); - EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; - EventPluginRegistry.registrationNameDependencies[registrationName] = - PluginModule.eventTypes[eventName].dependencies; -} - -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ -var EventPluginRegistry = { - - /** - * Ordered list of injected plugins. - */ - plugins: [], - - /** - * Mapping from event name to dispatch config - */ - eventNameDispatchConfigs: {}, - - /** - * Mapping from registration name to plugin module - */ - registrationNameModules: {}, - - /** - * Mapping from registration name to event name - */ - registrationNameDependencies: {}, - - /** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - * @see {EventPluginHub.injection.injectEventPluginOrder} - */ - injectEventPluginOrder: function(InjectedEventPluginOrder) { - ("production" !== "development" ? invariant( - !EventPluginOrder, - 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + - 'once. You are likely trying to load more than one copy of React.' - ) : invariant(!EventPluginOrder)); - // Clone the ordering so it cannot be dynamically mutated. - EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); - recomputePluginOrdering(); - }, - - /** - * Injects plugins to be used by `EventPluginHub`. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - * @see {EventPluginHub.injection.injectEventPluginsByName} - */ - injectEventPluginsByName: function(injectedNamesToPlugins) { - var isOrderingDirty = false; - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - var PluginModule = injectedNamesToPlugins[pluginName]; - if (!namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== PluginModule) { - ("production" !== "development" ? invariant( - !namesToPlugins[pluginName], - 'EventPluginRegistry: Cannot inject two different event plugins ' + - 'using the same name, `%s`.', - pluginName - ) : invariant(!namesToPlugins[pluginName])); - namesToPlugins[pluginName] = PluginModule; - isOrderingDirty = true; - } - } - if (isOrderingDirty) { - recomputePluginOrdering(); - } - }, - - /** - * Looks up the plugin for the supplied event. - * - * @param {object} event A synthetic event. - * @return {?object} The plugin that created the supplied event. - * @internal - */ - getPluginModuleForEvent: function(event) { - var dispatchConfig = event.dispatchConfig; - if (dispatchConfig.registrationName) { - return EventPluginRegistry.registrationNameModules[ - dispatchConfig.registrationName - ] || null; - } - for (var phase in dispatchConfig.phasedRegistrationNames) { - if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { - continue; - } - var PluginModule = EventPluginRegistry.registrationNameModules[ - dispatchConfig.phasedRegistrationNames[phase] - ]; - if (PluginModule) { - return PluginModule; - } - } - return null; - }, - - /** - * Exposed for unit testing. - * @private - */ - _resetEventPlugins: function() { - EventPluginOrder = null; - for (var pluginName in namesToPlugins) { - if (namesToPlugins.hasOwnProperty(pluginName)) { - delete namesToPlugins[pluginName]; - } - } - EventPluginRegistry.plugins.length = 0; - - var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; - for (var eventName in eventNameDispatchConfigs) { - if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { - delete eventNameDispatchConfigs[eventName]; - } - } - - var registrationNameModules = EventPluginRegistry.registrationNameModules; - for (var registrationName in registrationNameModules) { - if (registrationNameModules.hasOwnProperty(registrationName)) { - delete registrationNameModules[registrationName]; - } - } - } - -}; - -module.exports = EventPluginRegistry; - -},{"150":150}],20:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPluginUtils - */ - -'use strict'; - -var EventConstants = _dereq_(16); - -var invariant = _dereq_(150); - -/** - * Injected dependencies: - */ - -/** - * - `Mount`: [required] Module that can convert between React dom IDs and - * actual node references. - */ -var injection = { - Mount: null, - injectMount: function(InjectedMount) { - injection.Mount = InjectedMount; - if ("production" !== "development") { - ("production" !== "development" ? invariant( - InjectedMount && InjectedMount.getNode, - 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + - 'is missing getNode.' - ) : invariant(InjectedMount && InjectedMount.getNode)); - } - } -}; - -var topLevelTypes = EventConstants.topLevelTypes; - -function isEndish(topLevelType) { - return topLevelType === topLevelTypes.topMouseUp || - topLevelType === topLevelTypes.topTouchEnd || - topLevelType === topLevelTypes.topTouchCancel; -} - -function isMoveish(topLevelType) { - return topLevelType === topLevelTypes.topMouseMove || - topLevelType === topLevelTypes.topTouchMove; -} -function isStartish(topLevelType) { - return topLevelType === topLevelTypes.topMouseDown || - topLevelType === topLevelTypes.topTouchStart; -} - - -var validateEventDispatches; -if ("production" !== "development") { - validateEventDispatches = function(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - - var listenersIsArr = Array.isArray(dispatchListeners); - var idsIsArr = Array.isArray(dispatchIDs); - var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; - var listenersLen = listenersIsArr ? - dispatchListeners.length : - dispatchListeners ? 1 : 0; - - ("production" !== "development" ? invariant( - idsIsArr === listenersIsArr && IDsLen === listenersLen, - 'EventPluginUtils: Invalid `event`.' - ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); - }; -} - -/** - * Invokes `cb(event, listener, id)`. Avoids using call if no scope is - * provided. The `(listener,id)` pair effectively forms the "dispatch" but are - * kept separate to conserve memory. - */ -function forEachEventDispatch(event, cb) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - if ("production" !== "development") { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and IDs are two parallel arrays that are always in sync. - cb(event, dispatchListeners[i], dispatchIDs[i]); - } - } else if (dispatchListeners) { - cb(event, dispatchListeners, dispatchIDs); - } -} - -/** - * Default implementation of PluginModule.executeDispatch(). - * @param {SyntheticEvent} SyntheticEvent to handle - * @param {function} Application-level callback - * @param {string} domID DOM id to pass to the callback. - */ -function executeDispatch(event, listener, domID) { - event.currentTarget = injection.Mount.getNode(domID); - var returnValue = listener(event, domID); - event.currentTarget = null; - return returnValue; -} - -/** - * Standard/simple iteration through an event's collected dispatches. - */ -function executeDispatchesInOrder(event, cb) { - forEachEventDispatch(event, cb); - event._dispatchListeners = null; - event._dispatchIDs = null; -} - -/** - * Standard/simple iteration through an event's collected dispatches, but stops - * at the first dispatch execution returning true, and returns that id. - * - * @return id of the first dispatch execution who's listener returns true, or - * null if no listener returned true. - */ -function executeDispatchesInOrderStopAtTrueImpl(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - if ("production" !== "development") { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and IDs are two parallel arrays that are always in sync. - if (dispatchListeners[i](event, dispatchIDs[i])) { - return dispatchIDs[i]; - } - } - } else if (dispatchListeners) { - if (dispatchListeners(event, dispatchIDs)) { - return dispatchIDs; - } - } - return null; -} - -/** - * @see executeDispatchesInOrderStopAtTrueImpl - */ -function executeDispatchesInOrderStopAtTrue(event) { - var ret = executeDispatchesInOrderStopAtTrueImpl(event); - event._dispatchIDs = null; - event._dispatchListeners = null; - return ret; -} - -/** - * Execution of a "direct" dispatch - there must be at most one dispatch - * accumulated on the event or it is considered an error. It doesn't really make - * sense for an event with multiple dispatches (bubbled) to keep track of the - * return values at each dispatch execution, but it does tend to make sense when - * dealing with "direct" dispatches. - * - * @return The return value of executing the single dispatch. - */ -function executeDirectDispatch(event) { - if ("production" !== "development") { - validateEventDispatches(event); - } - var dispatchListener = event._dispatchListeners; - var dispatchID = event._dispatchIDs; - ("production" !== "development" ? invariant( - !Array.isArray(dispatchListener), - 'executeDirectDispatch(...): Invalid `event`.' - ) : invariant(!Array.isArray(dispatchListener))); - var res = dispatchListener ? - dispatchListener(event, dispatchID) : - null; - event._dispatchListeners = null; - event._dispatchIDs = null; - return res; -} - -/** - * @param {SyntheticEvent} event - * @return {bool} True iff number of dispatches accumulated is greater than 0. - */ -function hasDispatches(event) { - return !!event._dispatchListeners; -} - -/** - * General utilities that are useful in creating custom Event Plugins. - */ -var EventPluginUtils = { - isEndish: isEndish, - isMoveish: isMoveish, - isStartish: isStartish, - - executeDirectDispatch: executeDirectDispatch, - executeDispatch: executeDispatch, - executeDispatchesInOrder: executeDispatchesInOrder, - executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, - hasDispatches: hasDispatches, - injection: injection, - useTouchEvents: false -}; - -module.exports = EventPluginUtils; - -},{"150":150,"16":16}],21:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPropagators - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPluginHub = _dereq_(18); - -var accumulateInto = _dereq_(118); -var forEachAccumulated = _dereq_(135); - -var PropagationPhases = EventConstants.PropagationPhases; -var getListener = EventPluginHub.getListener; - -/** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(id, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(id, registrationName); -} - -/** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. - */ -function accumulateDirectionalDispatches(domID, upwards, event) { - if ("production" !== "development") { - if (!domID) { - throw new Error('Dispatching id must not be null'); - } - } - var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; - var listener = listenerAtPhase(domID, event, phase); - if (listener) { - event._dispatchListeners = - accumulateInto(event._dispatchListeners, listener); - event._dispatchIDs = accumulateInto(event._dispatchIDs, domID); - } -} - -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We can not perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - EventPluginHub.injection.getInstanceHandle().traverseTwoPhase( - event.dispatchMarker, - accumulateDirectionalDispatches, - event - ); - } -} - - -/** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. - */ -function accumulateDispatches(id, ignoredDirection, event) { - if (event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(id, registrationName); - if (listener) { - event._dispatchListeners = - accumulateInto(event._dispatchListeners, listener); - event._dispatchIDs = accumulateInto(event._dispatchIDs, id); - } - } -} - -/** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event - */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event.dispatchMarker, null, event); - } -} - -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} - -function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) { - EventPluginHub.injection.getInstanceHandle().traverseEnterLeave( - fromID, - toID, - accumulateDispatches, - leave, - enter - ); -} - - -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} - - - -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing event a - * single one. - * - * @constructor EventPropagators - */ -var EventPropagators = { - accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, - accumulateDirectDispatches: accumulateDirectDispatches, - accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches -}; - -module.exports = EventPropagators; - -},{"118":118,"135":135,"16":16,"18":18}],22:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ExecutionEnvironment - */ - -/*jslint evil: true */ - -"use strict"; - -var canUseDOM = !!( - (typeof window !== 'undefined' && - window.document && window.document.createElement) -); - -/** - * Simple, lightweight module assisting with the detection and context of - * Worker. Helps avoid circular dependencies and allows code to reason about - * whether or not they are in a Worker, even if they never include the main - * `ReactWorker` dependency. - */ -var ExecutionEnvironment = { - - canUseDOM: canUseDOM, - - canUseWorkers: typeof Worker !== 'undefined', - - canUseEventListeners: - canUseDOM && !!(window.addEventListener || window.attachEvent), - - canUseViewport: canUseDOM && !!window.screen, - - isInWorker: !canUseDOM // For now, this is true - might change in the future. - -}; - -module.exports = ExecutionEnvironment; - -},{}],23:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule FallbackCompositionState - * @typechecks static-only - */ - -'use strict'; - -var PooledClass = _dereq_(30); - -var assign = _dereq_(29); -var getTextContentAccessor = _dereq_(145); - -/** - * This helper class stores information about text content of a target node, - * allowing comparison of content before and after a given event. - * - * Identify the node where selection currently begins, then observe - * both its text content and its current position in the DOM. Since the - * browser may natively replace the target node during composition, we can - * use its position to find its replacement. - * - * @param {DOMEventTarget} root - */ -function FallbackCompositionState(root) { - this._root = root; - this._startText = this.getText(); - this._fallbackText = null; -} - -assign(FallbackCompositionState.prototype, { - /** - * Get current text of input. - * - * @return {string} - */ - getText: function() { - if ('value' in this._root) { - return this._root.value; - } - return this._root[getTextContentAccessor()]; - }, - - /** - * Determine the differing substring between the initially stored - * text content and the current content. - * - * @return {string} - */ - getData: function() { - if (this._fallbackText) { - return this._fallbackText; - } - - var start; - var startValue = this._startText; - var startLength = startValue.length; - var end; - var endValue = this.getText(); - var endLength = endValue.length; - - for (start = 0; start < startLength; start++) { - if (startValue[start] !== endValue[start]) { - break; - } - } - - var minEnd = startLength - start; - for (end = 1; end <= minEnd; end++) { - if (startValue[startLength - end] !== endValue[endLength - end]) { - break; - } - } - - var sliceTail = end > 1 ? 1 - end : undefined; - this._fallbackText = endValue.slice(start, sliceTail); - return this._fallbackText; - } -}); - -PooledClass.addPoolingTo(FallbackCompositionState); - -module.exports = FallbackCompositionState; - -},{"145":145,"29":29,"30":30}],24:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule HTMLDOMPropertyConfig - */ - -/*jslint bitwise: true*/ - -'use strict'; - -var DOMProperty = _dereq_(11); -var ExecutionEnvironment = _dereq_(22); - -var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; -var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; -var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; -var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS; -var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; -var HAS_POSITIVE_NUMERIC_VALUE = - DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; -var HAS_OVERLOADED_BOOLEAN_VALUE = - DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; - -var hasSVG; -if (ExecutionEnvironment.canUseDOM) { - var implementation = document.implementation; - hasSVG = ( - implementation && - implementation.hasFeature && - implementation.hasFeature( - 'http://www.w3.org/TR/SVG11/feature#BasicStructure', - '1.1' - ) - ); -} - - -var HTMLDOMPropertyConfig = { - isCustomAttribute: RegExp.prototype.test.bind( - /^(data|aria)-[a-z_][a-z\d_.\-]*$/ - ), - Properties: { - /** - * Standard Properties - */ - accept: null, - acceptCharset: null, - accessKey: null, - action: null, - allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - allowTransparency: MUST_USE_ATTRIBUTE, - alt: null, - async: HAS_BOOLEAN_VALUE, - autoComplete: null, - // autoFocus is polyfilled/normalized by AutoFocusMixin - // autoFocus: HAS_BOOLEAN_VALUE, - autoPlay: HAS_BOOLEAN_VALUE, - cellPadding: null, - cellSpacing: null, - charSet: MUST_USE_ATTRIBUTE, - checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - classID: MUST_USE_ATTRIBUTE, - // To set className on SVG elements, it's necessary to use .setAttribute; - // this works on HTML elements too in all browsers except IE8. Conveniently, - // IE8 doesn't support SVG and so we can simply use the attribute in - // browsers that support SVG and the property in browsers that don't, - // regardless of whether the element is HTML or SVG. - className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY, - cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - colSpan: null, - content: null, - contentEditable: null, - contextMenu: MUST_USE_ATTRIBUTE, - controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - coords: null, - crossOrigin: null, - data: null, // For `<object />` acts as `src`. - dateTime: MUST_USE_ATTRIBUTE, - defer: HAS_BOOLEAN_VALUE, - dir: null, - disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - download: HAS_OVERLOADED_BOOLEAN_VALUE, - draggable: null, - encType: null, - form: MUST_USE_ATTRIBUTE, - formAction: MUST_USE_ATTRIBUTE, - formEncType: MUST_USE_ATTRIBUTE, - formMethod: MUST_USE_ATTRIBUTE, - formNoValidate: HAS_BOOLEAN_VALUE, - formTarget: MUST_USE_ATTRIBUTE, - frameBorder: MUST_USE_ATTRIBUTE, - headers: null, - height: MUST_USE_ATTRIBUTE, - hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - high: null, - href: null, - hrefLang: null, - htmlFor: null, - httpEquiv: null, - icon: null, - id: MUST_USE_PROPERTY, - label: null, - lang: null, - list: MUST_USE_ATTRIBUTE, - loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - low: null, - manifest: MUST_USE_ATTRIBUTE, - marginHeight: null, - marginWidth: null, - max: null, - maxLength: MUST_USE_ATTRIBUTE, - media: MUST_USE_ATTRIBUTE, - mediaGroup: null, - method: null, - min: null, - multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - name: null, - noValidate: HAS_BOOLEAN_VALUE, - open: HAS_BOOLEAN_VALUE, - optimum: null, - pattern: null, - placeholder: null, - poster: null, - preload: null, - radioGroup: null, - readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - rel: null, - required: HAS_BOOLEAN_VALUE, - role: MUST_USE_ATTRIBUTE, - rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - rowSpan: null, - sandbox: null, - scope: null, - scoped: HAS_BOOLEAN_VALUE, - scrolling: null, - seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - shape: null, - size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - sizes: MUST_USE_ATTRIBUTE, - span: HAS_POSITIVE_NUMERIC_VALUE, - spellCheck: null, - src: null, - srcDoc: MUST_USE_PROPERTY, - srcSet: MUST_USE_ATTRIBUTE, - start: HAS_NUMERIC_VALUE, - step: null, - style: null, - tabIndex: null, - target: null, - title: null, - type: null, - useMap: null, - value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS, - width: MUST_USE_ATTRIBUTE, - wmode: MUST_USE_ATTRIBUTE, - - /** - * Non-standard Properties - */ - // autoCapitalize and autoCorrect are supported in Mobile Safari for - // keyboard hints. - autoCapitalize: null, - autoCorrect: null, - // itemProp, itemScope, itemType are for - // Microdata support. See http://schema.org/docs/gs.html - itemProp: MUST_USE_ATTRIBUTE, - itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - itemType: MUST_USE_ATTRIBUTE, - // itemID and itemRef are for Microdata support as well but - // only specified in the the WHATWG spec document. See - // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api - itemID: MUST_USE_ATTRIBUTE, - itemRef: MUST_USE_ATTRIBUTE, - // property is supported for OpenGraph in meta tags. - property: null, - // IE-only attribute that controls focus behavior - unselectable: MUST_USE_ATTRIBUTE - }, - DOMAttributeNames: { - acceptCharset: 'accept-charset', - className: 'class', - htmlFor: 'for', - httpEquiv: 'http-equiv' - }, - DOMPropertyNames: { - autoCapitalize: 'autocapitalize', - autoComplete: 'autocomplete', - autoCorrect: 'autocorrect', - autoFocus: 'autofocus', - autoPlay: 'autoplay', - // `encoding` is equivalent to `enctype`, IE8 lacks an `enctype` setter. - // http://www.w3.org/TR/html5/forms.html#dom-fs-encoding - encType: 'encoding', - hrefLang: 'hreflang', - radioGroup: 'radiogroup', - spellCheck: 'spellcheck', - srcDoc: 'srcdoc', - srcSet: 'srcset' - } -}; - -module.exports = HTMLDOMPropertyConfig; - -},{"11":11,"22":22}],25:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule LinkedStateMixin - * @typechecks static-only - */ - -'use strict'; - -var ReactLink = _dereq_(75); -var ReactStateSetters = _dereq_(94); - -/** - * A simple mixin around ReactLink.forState(). - */ -var LinkedStateMixin = { - /** - * Create a ReactLink that's linked to part of this component's state. The - * ReactLink will have the current value of this.state[key] and will call - * setState() when a change is requested. - * - * @param {string} key state key to update. Note: you may want to use keyOf() - * if you're using Google Closure Compiler advanced mode. - * @return {ReactLink} ReactLink instance linking to the state. - */ - linkState: function(key) { - return new ReactLink( - this.state[key], - ReactStateSetters.createStateKeySetter(this, key) - ); - } -}; - -module.exports = LinkedStateMixin; - -},{"75":75,"94":94}],26:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule LinkedValueUtils - * @typechecks static-only - */ - -'use strict'; - -var ReactPropTypes = _dereq_(86); - -var invariant = _dereq_(150); - -var hasReadOnlyValue = { - 'button': true, - 'checkbox': true, - 'image': true, - 'hidden': true, - 'radio': true, - 'reset': true, - 'submit': true -}; - -function _assertSingleLink(input) { - ("production" !== "development" ? invariant( - input.props.checkedLink == null || input.props.valueLink == null, - 'Cannot provide a checkedLink and a valueLink. If you want to use ' + - 'checkedLink, you probably don\'t want to use valueLink and vice versa.' - ) : invariant(input.props.checkedLink == null || input.props.valueLink == null)); -} -function _assertValueLink(input) { - _assertSingleLink(input); - ("production" !== "development" ? invariant( - input.props.value == null && input.props.onChange == null, - 'Cannot provide a valueLink and a value or onChange event. If you want ' + - 'to use value or onChange, you probably don\'t want to use valueLink.' - ) : invariant(input.props.value == null && input.props.onChange == null)); -} - -function _assertCheckedLink(input) { - _assertSingleLink(input); - ("production" !== "development" ? invariant( - input.props.checked == null && input.props.onChange == null, - 'Cannot provide a checkedLink and a checked property or onChange event. ' + - 'If you want to use checked or onChange, you probably don\'t want to ' + - 'use checkedLink' - ) : invariant(input.props.checked == null && input.props.onChange == null)); -} - -/** - * @param {SyntheticEvent} e change event to handle - */ -function _handleLinkedValueChange(e) { - /*jshint validthis:true */ - this.props.valueLink.requestChange(e.target.value); -} - -/** - * @param {SyntheticEvent} e change event to handle - */ -function _handleLinkedCheckChange(e) { - /*jshint validthis:true */ - this.props.checkedLink.requestChange(e.target.checked); -} - -/** - * Provide a linked `value` attribute for controlled forms. You should not use - * this outside of the ReactDOM controlled form components. - */ -var LinkedValueUtils = { - Mixin: { - propTypes: { - value: function(props, propName, componentName) { - if (!props[propName] || - hasReadOnlyValue[props.type] || - props.onChange || - props.readOnly || - props.disabled) { - return null; - } - return new Error( - 'You provided a `value` prop to a form field without an ' + - '`onChange` handler. This will render a read-only field. If ' + - 'the field should be mutable use `defaultValue`. Otherwise, ' + - 'set either `onChange` or `readOnly`.' - ); - }, - checked: function(props, propName, componentName) { - if (!props[propName] || - props.onChange || - props.readOnly || - props.disabled) { - return null; - } - return new Error( - 'You provided a `checked` prop to a form field without an ' + - '`onChange` handler. This will render a read-only field. If ' + - 'the field should be mutable use `defaultChecked`. Otherwise, ' + - 'set either `onChange` or `readOnly`.' - ); - }, - onChange: ReactPropTypes.func - } - }, - - /** - * @param {ReactComponent} input Form component - * @return {*} current value of the input either from value prop or link. - */ - getValue: function(input) { - if (input.props.valueLink) { - _assertValueLink(input); - return input.props.valueLink.value; - } - return input.props.value; - }, - - /** - * @param {ReactComponent} input Form component - * @return {*} current checked status of the input either from checked prop - * or link. - */ - getChecked: function(input) { - if (input.props.checkedLink) { - _assertCheckedLink(input); - return input.props.checkedLink.value; - } - return input.props.checked; - }, - - /** - * @param {ReactComponent} input Form component - * @return {function} change callback either from onChange prop or link. - */ - getOnChange: function(input) { - if (input.props.valueLink) { - _assertValueLink(input); - return _handleLinkedValueChange; - } else if (input.props.checkedLink) { - _assertCheckedLink(input); - return _handleLinkedCheckChange; - } - return input.props.onChange; - } -}; - -module.exports = LinkedValueUtils; - -},{"150":150,"86":86}],27:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule LocalEventTrapMixin - */ - -'use strict'; - -var ReactBrowserEventEmitter = _dereq_(33); - -var accumulateInto = _dereq_(118); -var forEachAccumulated = _dereq_(135); -var invariant = _dereq_(150); - -function remove(event) { - event.remove(); -} - -var LocalEventTrapMixin = { - trapBubbledEvent:function(topLevelType, handlerBaseName) { - ("production" !== "development" ? invariant(this.isMounted(), 'Must be mounted to trap events') : invariant(this.isMounted())); - // If a component renders to null or if another component fatals and causes - // the state of the tree to be corrupted, `node` here can be null. - var node = this.getDOMNode(); - ("production" !== "development" ? invariant( - node, - 'LocalEventTrapMixin.trapBubbledEvent(...): Requires node to be rendered.' - ) : invariant(node)); - var listener = ReactBrowserEventEmitter.trapBubbledEvent( - topLevelType, - handlerBaseName, - node - ); - this._localEventListeners = - accumulateInto(this._localEventListeners, listener); - }, - - // trapCapturedEvent would look nearly identical. We don't implement that - // method because it isn't currently needed. - - componentWillUnmount:function() { - if (this._localEventListeners) { - forEachAccumulated(this._localEventListeners, remove); - } - } -}; - -module.exports = LocalEventTrapMixin; - -},{"118":118,"135":135,"150":150,"33":33}],28:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule MobileSafariClickEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(16); - -var emptyFunction = _dereq_(129); - -var topLevelTypes = EventConstants.topLevelTypes; - -/** - * Mobile Safari does not fire properly bubble click events on non-interactive - * elements, which means delegated click listeners do not fire. The workaround - * for this bug involves attaching an empty click listener on the target node. - * - * This particular plugin works around the bug by attaching an empty click - * listener on `touchstart` (which does fire on every element). - */ -var MobileSafariClickEventPlugin = { - - eventTypes: null, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - if (topLevelType === topLevelTypes.topTouchStart) { - var target = nativeEvent.target; - if (target && !target.onclick) { - target.onclick = emptyFunction; - } - } - } - -}; - -module.exports = MobileSafariClickEventPlugin; - -},{"129":129,"16":16}],29:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Object.assign - */ - -// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign - -'use strict'; - -function assign(target, sources) { - if (target == null) { - throw new TypeError('Object.assign target cannot be null or undefined'); - } - - var to = Object(target); - var hasOwnProperty = Object.prototype.hasOwnProperty; - - for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { - var nextSource = arguments[nextIndex]; - if (nextSource == null) { - continue; - } - - var from = Object(nextSource); - - // We don't currently support accessors nor proxies. Therefore this - // copy cannot throw. If we ever supported this then we must handle - // exceptions and side-effects. We don't support symbols so they won't - // be transferred. - - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - } - - return to; -} - -module.exports = assign; - -},{}],30:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule PooledClass - */ - -'use strict'; - -var invariant = _dereq_(150); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function(copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function(a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function(a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4, a5); - return instance; - } else { - return new Klass(a1, a2, a3, a4, a5); - } -}; - -var standardReleaser = function(instance) { - var Klass = this; - ("production" !== "development" ? invariant( - instance instanceof Klass, - 'Trying to release an instance into a pool of a different type.' - ) : invariant(instance instanceof Klass)); - if (instance.destructor) { - instance.destructor(); - } - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances (optional). - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function(CopyConstructor, pooler) { - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fiveArgumentPooler: fiveArgumentPooler -}; - -module.exports = PooledClass; - -},{"150":150}],31:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule React - */ - -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ - -'use strict'; - -var EventPluginUtils = _dereq_(20); -var ReactChildren = _dereq_(37); -var ReactComponent = _dereq_(39); -var ReactClass = _dereq_(38); -var ReactContext = _dereq_(44); -var ReactCurrentOwner = _dereq_(45); -var ReactElement = _dereq_(63); -var ReactElementValidator = _dereq_(64); -var ReactDOM = _dereq_(46); -var ReactDOMTextComponent = _dereq_(57); -var ReactDefaultInjection = _dereq_(60); -var ReactInstanceHandles = _dereq_(72); -var ReactMount = _dereq_(77); -var ReactPerf = _dereq_(82); -var ReactPropTypes = _dereq_(86); -var ReactReconciler = _dereq_(89); -var ReactServerRendering = _dereq_(92); - -var assign = _dereq_(29); -var findDOMNode = _dereq_(132); -var onlyChild = _dereq_(160); - -ReactDefaultInjection.inject(); - -var createElement = ReactElement.createElement; -var createFactory = ReactElement.createFactory; -var cloneElement = ReactElement.cloneElement; - -if ("production" !== "development") { - createElement = ReactElementValidator.createElement; - createFactory = ReactElementValidator.createFactory; - cloneElement = ReactElementValidator.cloneElement; -} - -var render = ReactPerf.measure('React', 'render', ReactMount.render); - -var React = { - Children: { - map: ReactChildren.map, - forEach: ReactChildren.forEach, - count: ReactChildren.count, - only: onlyChild - }, - Component: ReactComponent, - DOM: ReactDOM, - PropTypes: ReactPropTypes, - initializeTouchEvents: function(shouldUseTouch) { - EventPluginUtils.useTouchEvents = shouldUseTouch; - }, - createClass: ReactClass.createClass, - createElement: createElement, - cloneElement: cloneElement, - createFactory: createFactory, - createMixin: function(mixin) { - // Currently a noop. Will be used to validate and trace mixins. - return mixin; - }, - constructAndRenderComponent: ReactMount.constructAndRenderComponent, - constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID, - findDOMNode: findDOMNode, - render: render, - renderToString: ReactServerRendering.renderToString, - renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup, - unmountComponentAtNode: ReactMount.unmountComponentAtNode, - isValidElement: ReactElement.isValidElement, - withContext: ReactContext.withContext, - - // Hook for JSX spread, don't use this for anything else. - __spread: assign -}; - -// Inject the runtime into a devtools global hook regardless of browser. -// Allows for debugging when the hook is injected on the page. -if ( - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ - CurrentOwner: ReactCurrentOwner, - InstanceHandles: ReactInstanceHandles, - Mount: ReactMount, - Reconciler: ReactReconciler, - TextComponent: ReactDOMTextComponent - }); -} - -if ("production" !== "development") { - var ExecutionEnvironment = _dereq_(22); - if (ExecutionEnvironment.canUseDOM && window.top === window.self) { - - // If we're in Chrome, look for the devtools marker and provide a download - // link if not installed. - if (navigator.userAgent.indexOf('Chrome') > -1) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { - console.debug( - 'Download the React DevTools for a better development experience: ' + - 'https://fb.me/react-devtools' - ); - } - } - - var expectedFeatures = [ - // shims - Array.isArray, - Array.prototype.every, - Array.prototype.forEach, - Array.prototype.indexOf, - Array.prototype.map, - Date.now, - Function.prototype.bind, - Object.keys, - String.prototype.split, - String.prototype.trim, - - // shams - Object.create, - Object.freeze - ]; - - for (var i = 0; i < expectedFeatures.length; i++) { - if (!expectedFeatures[i]) { - console.error( - 'One or more ES5 shim/shams expected by React are not available: ' + - 'https://fb.me/react-warning-polyfills' - ); - break; - } - } - } -} - -React.version = '0.13.3'; - -module.exports = React; - -},{"132":132,"160":160,"20":20,"22":22,"29":29,"37":37,"38":38,"39":39,"44":44,"45":45,"46":46,"57":57,"60":60,"63":63,"64":64,"72":72,"77":77,"82":82,"86":86,"89":89,"92":92}],32:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactBrowserComponentMixin - */ - -'use strict'; - -var findDOMNode = _dereq_(132); - -var ReactBrowserComponentMixin = { - /** - * Returns the DOM node rendered by this component. - * - * @return {DOMElement} The root node of this component. - * @final - * @protected - */ - getDOMNode: function() { - return findDOMNode(this); - } -}; - -module.exports = ReactBrowserComponentMixin; - -},{"132":132}],33:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactBrowserEventEmitter - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPluginHub = _dereq_(18); -var EventPluginRegistry = _dereq_(19); -var ReactEventEmitterMixin = _dereq_(67); -var ViewportMetrics = _dereq_(117); - -var assign = _dereq_(29); -var isEventSupported = _dereq_(151); - -/** - * Summary of `ReactBrowserEventEmitter` event handling: - * - * - Top-level delegation is used to trap most native browser events. This - * may only occur in the main thread and is the responsibility of - * ReactEventListener, which is injected and can therefore support pluggable - * event sources. This is the only work that occurs in the main thread. - * - * - We normalize and de-duplicate events to account for browser quirks. This - * may be done in the worker thread. - * - * - Forward these native events (with the associated top-level type used to - * trap it) to `EventPluginHub`, which in turn will ask plugins if they want - * to extract any synthetic events. - * - * - The `EventPluginHub` will then process each event by annotating them with - * "dispatches", a sequence of listeners and IDs that care about that event. - * - * - The `EventPluginHub` then dispatches the events. - * - * Overview of React and the event system: - * - * +------------+ . - * | DOM | . - * +------------+ . - * | . - * v . - * +------------+ . - * | ReactEvent | . - * | Listener | . - * +------------+ . +-----------+ - * | . +--------+|SimpleEvent| - * | . | |Plugin | - * +-----|------+ . v +-----------+ - * | | | . +--------------+ +------------+ - * | +-----------.--->|EventPluginHub| | Event | - * | | . | | +-----------+ | Propagators| - * | ReactEvent | . | | |TapEvent | |------------| - * | Emitter | . | |<---+|Plugin | |other plugin| - * | | . | | +-----------+ | utilities | - * | +-----------.--->| | +------------+ - * | | | . +--------------+ - * +-----|------+ . ^ +-----------+ - * | . | |Enter/Leave| - * + . +-------+|Plugin | - * +-------------+ . +-----------+ - * | application | . - * |-------------| . - * | | . - * | | . - * +-------------+ . - * . - * React Core . General Purpose Event Plugin System - */ - -var alreadyListeningTo = {}; -var isMonitoringScrollValue = false; -var reactTopListenersCounter = 0; - -// For events like 'submit' which don't consistently bubble (which we trap at a -// lower node than `document`), binding at `document` would cause duplicate -// events so we don't include them here -var topEventMapping = { - topBlur: 'blur', - topChange: 'change', - topClick: 'click', - topCompositionEnd: 'compositionend', - topCompositionStart: 'compositionstart', - topCompositionUpdate: 'compositionupdate', - topContextMenu: 'contextmenu', - topCopy: 'copy', - topCut: 'cut', - topDoubleClick: 'dblclick', - topDrag: 'drag', - topDragEnd: 'dragend', - topDragEnter: 'dragenter', - topDragExit: 'dragexit', - topDragLeave: 'dragleave', - topDragOver: 'dragover', - topDragStart: 'dragstart', - topDrop: 'drop', - topFocus: 'focus', - topInput: 'input', - topKeyDown: 'keydown', - topKeyPress: 'keypress', - topKeyUp: 'keyup', - topMouseDown: 'mousedown', - topMouseMove: 'mousemove', - topMouseOut: 'mouseout', - topMouseOver: 'mouseover', - topMouseUp: 'mouseup', - topPaste: 'paste', - topScroll: 'scroll', - topSelectionChange: 'selectionchange', - topTextInput: 'textInput', - topTouchCancel: 'touchcancel', - topTouchEnd: 'touchend', - topTouchMove: 'touchmove', - topTouchStart: 'touchstart', - topWheel: 'wheel' -}; - -/** - * To ensure no conflicts with other potential React instances on the page - */ -var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; - } - return alreadyListeningTo[mountAt[topListenersIDKey]]; -} - -/** - * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For - * example: - * - * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction); - * - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. - * - * @internal - */ -var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { - - /** - * Injectable event backend - */ - ReactEventListener: null, - - injection: { - /** - * @param {object} ReactEventListener - */ - injectReactEventListener: function(ReactEventListener) { - ReactEventListener.setHandleTopLevel( - ReactBrowserEventEmitter.handleTopLevel - ); - ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; - } - }, - - /** - * Sets whether or not any created callbacks should be enabled. - * - * @param {boolean} enabled True if callbacks should be enabled. - */ - setEnabled: function(enabled) { - if (ReactBrowserEventEmitter.ReactEventListener) { - ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); - } - }, - - /** - * @return {boolean} True if callbacks are enabled. - */ - isEnabled: function() { - return !!( - (ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()) - ); - }, - - /** - * We listen for bubbled touch events on the document object. - * - * Firefox v8.01 (and possibly others) exhibited strange behavior when - * mounting `onmousemove` events at some node that was not the document - * element. The symptoms were that if your mouse is not moving over something - * contained within that mount point (for example on the background) the - * top-level listeners for `onmousemove` won't be called. However, if you - * register the `mousemove` on the document object, then it will of course - * catch all `mousemove`s. This along with iOS quirks, justifies restricting - * top-level listeners to the document object only, at least for these - * movement types of events and possibly all events. - * - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - * - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but - * they bubble to document. - * - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {object} contentDocumentHandle Document which owns the container - */ - listenTo: function(registrationName, contentDocumentHandle) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry. - registrationNameDependencies[registrationName]; - - var topLevelTypes = EventConstants.topLevelTypes; - for (var i = 0, l = dependencies.length; i < l; i++) { - var dependency = dependencies[i]; - if (!( - (isListening.hasOwnProperty(dependency) && isListening[dependency]) - )) { - if (dependency === topLevelTypes.topWheel) { - if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'wheel', - mountAt - ); - } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'mousewheel', - mountAt - ); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'DOMMouseScroll', - mountAt - ); - } - } else if (dependency === topLevelTypes.topScroll) { - - if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topScroll, - 'scroll', - mountAt - ); - } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topScroll, - 'scroll', - ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE - ); - } - } else if (dependency === topLevelTypes.topFocus || - dependency === topLevelTypes.topBlur) { - - if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topFocus, - 'focus', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topBlur, - 'blur', - mountAt - ); - } else if (isEventSupported('focusin')) { - // IE has `focusin` and `focusout` events which bubble. - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topFocus, - 'focusin', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topBlur, - 'focusout', - mountAt - ); - } - - // to make sure blur and focus event listeners are only attached once - isListening[topLevelTypes.topBlur] = true; - isListening[topLevelTypes.topFocus] = true; - } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - dependency, - topEventMapping[dependency], - mountAt - ); - } - - isListening[dependency] = true; - } - } - }, - - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelType, - handlerBaseName, - handle - ); - }, - - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelType, - handlerBaseName, - handle - ); - }, - - /** - * Listens to window scroll and resize events. We cache scroll values so that - * application code can access them without triggering reflows. - * - * NOTE: Scroll events do not bubble. - * - * @see http://www.quirksmode.org/dom/events/scroll.html - */ - ensureScrollValueMonitoring: function() { - if (!isMonitoringScrollValue) { - var refresh = ViewportMetrics.refreshScrollValues; - ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); - isMonitoringScrollValue = true; - } - }, - - eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, - - registrationNameModules: EventPluginHub.registrationNameModules, - - putListener: EventPluginHub.putListener, - - getListener: EventPluginHub.getListener, - - deleteListener: EventPluginHub.deleteListener, - - deleteAllListeners: EventPluginHub.deleteAllListeners - -}); - -module.exports = ReactBrowserEventEmitter; - -},{"117":117,"151":151,"16":16,"18":18,"19":19,"29":29,"67":67}],34:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - * @providesModule ReactCSSTransitionGroup - */ - -'use strict'; - -var React = _dereq_(31); - -var assign = _dereq_(29); - -var ReactTransitionGroup = React.createFactory( - _dereq_(98) -); -var ReactCSSTransitionGroupChild = React.createFactory( - _dereq_(35) -); - -var ReactCSSTransitionGroup = React.createClass({ - displayName: 'ReactCSSTransitionGroup', - - propTypes: { - transitionName: React.PropTypes.string.isRequired, - transitionAppear: React.PropTypes.bool, - transitionEnter: React.PropTypes.bool, - transitionLeave: React.PropTypes.bool - }, - - getDefaultProps: function() { - return { - transitionAppear: false, - transitionEnter: true, - transitionLeave: true - }; - }, - - _wrapChild: function(child) { - // We need to provide this childFactory so that - // ReactCSSTransitionGroupChild can receive updates to name, enter, and - // leave while it is leaving. - return ReactCSSTransitionGroupChild( - { - name: this.props.transitionName, - appear: this.props.transitionAppear, - enter: this.props.transitionEnter, - leave: this.props.transitionLeave - }, - child - ); - }, - - render: function() { - return ( - ReactTransitionGroup( - assign({}, this.props, {childFactory: this._wrapChild}) - ) - ); - } -}); - -module.exports = ReactCSSTransitionGroup; - -},{"29":29,"31":31,"35":35,"98":98}],35:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - * @providesModule ReactCSSTransitionGroupChild - */ - -'use strict'; - -var React = _dereq_(31); - -var CSSCore = _dereq_(4); -var ReactTransitionEvents = _dereq_(97); - -var onlyChild = _dereq_(160); -var warning = _dereq_(171); - -// We don't remove the element from the DOM until we receive an animationend or -// transitionend event. If the user screws up and forgets to add an animation -// their node will be stuck in the DOM forever, so we detect if an animation -// does not start and if it doesn't, we just call the end listener immediately. -var TICK = 17; -var NO_EVENT_TIMEOUT = 5000; - -var noEventListener = null; - - -if ("production" !== "development") { - noEventListener = function() { - ("production" !== "development" ? warning( - false, - 'transition(): tried to perform an animation without ' + - 'an animationend or transitionend event after timeout (' + - '%sms). You should either disable this ' + - 'transition in JS or add a CSS animation/transition.', - NO_EVENT_TIMEOUT - ) : null); - }; -} - -var ReactCSSTransitionGroupChild = React.createClass({ - displayName: 'ReactCSSTransitionGroupChild', - - transition: function(animationType, finishCallback) { - var node = this.getDOMNode(); - var className = this.props.name + '-' + animationType; - var activeClassName = className + '-active'; - var noEventTimeout = null; - - var endListener = function(e) { - if (e && e.target !== node) { - return; - } - if ("production" !== "development") { - clearTimeout(noEventTimeout); - } - - CSSCore.removeClass(node, className); - CSSCore.removeClass(node, activeClassName); - - ReactTransitionEvents.removeEndEventListener(node, endListener); - - // Usually this optional callback is used for informing an owner of - // a leave animation and telling it to remove the child. - if (finishCallback) { - finishCallback(); - } - }; - - ReactTransitionEvents.addEndEventListener(node, endListener); - - CSSCore.addClass(node, className); - - // Need to do this to actually trigger a transition. - this.queueClass(activeClassName); - - if ("production" !== "development") { - noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT); - } - }, - - queueClass: function(className) { - this.classNameQueue.push(className); - - if (!this.timeout) { - this.timeout = setTimeout(this.flushClassNameQueue, TICK); - } - }, - - flushClassNameQueue: function() { - if (this.isMounted()) { - this.classNameQueue.forEach( - CSSCore.addClass.bind(CSSCore, this.getDOMNode()) - ); - } - this.classNameQueue.length = 0; - this.timeout = null; - }, - - componentWillMount: function() { - this.classNameQueue = []; - }, - - componentWillUnmount: function() { - if (this.timeout) { - clearTimeout(this.timeout); - } - }, - - componentWillAppear: function(done) { - if (this.props.appear) { - this.transition('appear', done); - } else { - done(); - } - }, - - componentWillEnter: function(done) { - if (this.props.enter) { - this.transition('enter', done); - } else { - done(); - } - }, - - componentWillLeave: function(done) { - if (this.props.leave) { - this.transition('leave', done); - } else { - done(); - } - }, - - render: function() { - return onlyChild(this.props.children); - } -}); - -module.exports = ReactCSSTransitionGroupChild; - -},{"160":160,"171":171,"31":31,"4":4,"97":97}],36:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactChildReconciler - * @typechecks static-only - */ - -'use strict'; - -var ReactReconciler = _dereq_(89); - -var flattenChildren = _dereq_(133); -var instantiateReactComponent = _dereq_(149); -var shouldUpdateReactComponent = _dereq_(167); - -/** - * ReactChildReconciler provides helpers for initializing or updating a set of - * children. Its output is suitable for passing it onto ReactMultiChild which - * does diffed reordering and insertion. - */ -var ReactChildReconciler = { - - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildNodes Nested child maps. - * @return {?object} A set of child instances. - * @internal - */ - instantiateChildren: function(nestedChildNodes, transaction, context) { - var children = flattenChildren(nestedChildNodes); - for (var name in children) { - if (children.hasOwnProperty(name)) { - var child = children[name]; - // The rendered children must be turned into instances as they're - // mounted. - var childInstance = instantiateReactComponent(child, null); - children[name] = childInstance; - } - } - return children; - }, - - /** - * Updates the rendered children and returns a new set of children. - * - * @param {?object} prevChildren Previously initialized set of children. - * @param {?object} nextNestedChildNodes Nested child maps. - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @return {?object} A new set of child instances. - * @internal - */ - updateChildren: function( - prevChildren, - nextNestedChildNodes, - transaction, - context) { - // We currently don't have a way to track moves here but if we use iterators - // instead of for..in we can zip the iterators and check if an item has - // moved. - // TODO: If nothing has changed, return the prevChildren object so that we - // can quickly bailout if nothing has changed. - var nextChildren = flattenChildren(nextNestedChildNodes); - if (!nextChildren && !prevChildren) { - return null; - } - var name; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - var prevChild = prevChildren && prevChildren[name]; - var prevElement = prevChild && prevChild._currentElement; - var nextElement = nextChildren[name]; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - ReactReconciler.receiveComponent( - prevChild, nextElement, transaction, context - ); - nextChildren[name] = prevChild; - } else { - if (prevChild) { - ReactReconciler.unmountComponent(prevChild, name); - } - // The child must be instantiated before it's mounted. - var nextChildInstance = instantiateReactComponent( - nextElement, - null - ); - nextChildren[name] = nextChildInstance; - } - } - // Unmount children that are no longer present. - for (name in prevChildren) { - if (prevChildren.hasOwnProperty(name) && - !(nextChildren && nextChildren.hasOwnProperty(name))) { - ReactReconciler.unmountComponent(prevChildren[name]); - } - } - return nextChildren; - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. - * - * @param {?object} renderedChildren Previously initialized set of children. - * @internal - */ - unmountChildren: function(renderedChildren) { - for (var name in renderedChildren) { - var renderedChild = renderedChildren[name]; - ReactReconciler.unmountComponent(renderedChild); - } - } - -}; - -module.exports = ReactChildReconciler; - -},{"133":133,"149":149,"167":167,"89":89}],37:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactChildren - */ - -'use strict'; - -var PooledClass = _dereq_(30); -var ReactFragment = _dereq_(69); - -var traverseAllChildren = _dereq_(169); -var warning = _dereq_(171); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; -var threeArgumentPooler = PooledClass.threeArgumentPooler; - -/** - * PooledClass representing the bookkeeping associated with performing a child - * traversal. Allows avoiding binding callbacks. - * - * @constructor ForEachBookKeeping - * @param {!function} forEachFunction Function to perform traversal with. - * @param {?*} forEachContext Context to perform context with. - */ -function ForEachBookKeeping(forEachFunction, forEachContext) { - this.forEachFunction = forEachFunction; - this.forEachContext = forEachContext; -} -PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); - -function forEachSingleChild(traverseContext, child, name, i) { - var forEachBookKeeping = traverseContext; - forEachBookKeeping.forEachFunction.call( - forEachBookKeeping.forEachContext, child, i); -} - -/** - * Iterates through children that are typically specified as `props.children`. - * - * The provided forEachFunc(child, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc. - * @param {*} forEachContext Context for forEachContext. - */ -function forEachChildren(children, forEachFunc, forEachContext) { - if (children == null) { - return children; - } - - var traverseContext = - ForEachBookKeeping.getPooled(forEachFunc, forEachContext); - traverseAllChildren(children, forEachSingleChild, traverseContext); - ForEachBookKeeping.release(traverseContext); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * mapping. Allows avoiding binding callbacks. - * - * @constructor MapBookKeeping - * @param {!*} mapResult Object containing the ordered map of results. - * @param {!function} mapFunction Function to perform mapping with. - * @param {?*} mapContext Context to perform mapping with. - */ -function MapBookKeeping(mapResult, mapFunction, mapContext) { - this.mapResult = mapResult; - this.mapFunction = mapFunction; - this.mapContext = mapContext; -} -PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); - -function mapSingleChildIntoContext(traverseContext, child, name, i) { - var mapBookKeeping = traverseContext; - var mapResult = mapBookKeeping.mapResult; - - var keyUnique = !mapResult.hasOwnProperty(name); - if ("production" !== "development") { - ("production" !== "development" ? warning( - keyUnique, - 'ReactChildren.map(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ) : null); - } - - if (keyUnique) { - var mappedChild = - mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); - mapResult[name] = mappedChild; - } -} - -/** - * Maps children that are typically specified as `props.children`. - * - * The provided mapFunction(child, key, index) will be called for each - * leaf child. - * - * TODO: This may likely break any calls to `ReactChildren.map` that were - * previously relying on the fact that we guarded against null children. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} mapFunction. - * @param {*} mapContext Context for mapFunction. - * @return {object} Object containing the ordered map of results. - */ -function mapChildren(children, func, context) { - if (children == null) { - return children; - } - - var mapResult = {}; - var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); - traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); - MapBookKeeping.release(traverseContext); - return ReactFragment.create(mapResult); -} - -function forEachSingleChildDummy(traverseContext, child, name, i) { - return null; -} - -/** - * Count the number of children that are typically specified as - * `props.children`. - * - * @param {?*} children Children tree container. - * @return {number} The number of children. - */ -function countChildren(children, context) { - return traverseAllChildren(children, forEachSingleChildDummy, null); -} - -var ReactChildren = { - forEach: forEachChildren, - map: mapChildren, - count: countChildren -}; - -module.exports = ReactChildren; - -},{"169":169,"171":171,"30":30,"69":69}],38:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactClass - */ - -'use strict'; - -var ReactComponent = _dereq_(39); -var ReactCurrentOwner = _dereq_(45); -var ReactElement = _dereq_(63); -var ReactErrorUtils = _dereq_(66); -var ReactInstanceMap = _dereq_(73); -var ReactLifeCycle = _dereq_(74); -var ReactPropTypeLocations = _dereq_(85); -var ReactPropTypeLocationNames = _dereq_(84); -var ReactUpdateQueue = _dereq_(99); - -var assign = _dereq_(29); -var invariant = _dereq_(150); -var keyMirror = _dereq_(156); -var keyOf = _dereq_(157); -var warning = _dereq_(171); - -var MIXINS_KEY = keyOf({mixins: null}); - -/** - * Policies that describe methods in `ReactClassInterface`. - */ -var SpecPolicy = keyMirror({ - /** - * These methods may be defined only once by the class specification or mixin. - */ - DEFINE_ONCE: null, - /** - * These methods may be defined by both the class specification and mixins. - * Subsequent definitions will be chained. These methods must return void. - */ - DEFINE_MANY: null, - /** - * These methods are overriding the base class. - */ - OVERRIDE_BASE: null, - /** - * These methods are similar to DEFINE_MANY, except we assume they return - * objects. We try to merge the keys of the return values of all the mixed in - * functions. If there is a key conflict we throw. - */ - DEFINE_MANY_MERGED: null -}); - - -var injectedMixins = []; - -/** - * Composite components are higher-level components that compose other composite - * or native components. - * - * To create a new type of `ReactClass`, pass a specification of - * your new class to `React.createClass`. The only requirement of your class - * specification is that you implement a `render` method. - * - * var MyComponent = React.createClass({ - * render: function() { - * return <div>Hello World</div>; - * } - * }); - * - * The class specification supports a specific protocol of methods that have - * special meaning (e.g. `render`). See `ReactClassInterface` for - * more the comprehensive protocol. Any other properties and methods in the - * class specification will available on the prototype. - * - * @interface ReactClassInterface - * @internal - */ -var ReactClassInterface = { - - /** - * An array of Mixin objects to include when defining your component. - * - * @type {array} - * @optional - */ - mixins: SpecPolicy.DEFINE_MANY, - - /** - * An object containing properties and methods that should be defined on - * the component's constructor instead of its prototype (static methods). - * - * @type {object} - * @optional - */ - statics: SpecPolicy.DEFINE_MANY, - - /** - * Definition of prop types for this component. - * - * @type {object} - * @optional - */ - propTypes: SpecPolicy.DEFINE_MANY, - - /** - * Definition of context types for this component. - * - * @type {object} - * @optional - */ - contextTypes: SpecPolicy.DEFINE_MANY, - - /** - * Definition of context types this component sets for its children. - * - * @type {object} - * @optional - */ - childContextTypes: SpecPolicy.DEFINE_MANY, - - // ==== Definition methods ==== - - /** - * Invoked when the component is mounted. Values in the mapping will be set on - * `this.props` if that prop is not specified (i.e. using an `in` check). - * - * This method is invoked before `getInitialState` and therefore cannot rely - * on `this.state` or use `this.setState`. - * - * @return {object} - * @optional - */ - getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * Invoked once before the component is mounted. The return value will be used - * as the initial value of `this.state`. - * - * getInitialState: function() { - * return { - * isOn: false, - * fooBaz: new BazFoo() - * } - * } - * - * @return {object} - * @optional - */ - getInitialState: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * @return {object} - * @optional - */ - getChildContext: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * Uses props from `this.props` and state from `this.state` to render the - * structure of the component. - * - * No guarantees are made about when or how often this method is invoked, so - * it must not have side effects. - * - * render: function() { - * var name = this.props.name; - * return <div>Hello, {name}!</div>; - * } - * - * @return {ReactComponent} - * @nosideeffects - * @required - */ - render: SpecPolicy.DEFINE_ONCE, - - - - // ==== Delegate methods ==== - - /** - * Invoked when the component is initially created and about to be mounted. - * This may have side effects, but any external subscriptions or data created - * by this method must be cleaned up in `componentWillUnmount`. - * - * @optional - */ - componentWillMount: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component has been mounted and has a DOM representation. - * However, there is no guarantee that the DOM node is in the document. - * - * Use this as an opportunity to operate on the DOM when the component has - * been mounted (initialized and rendered) for the first time. - * - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidMount: SpecPolicy.DEFINE_MANY, - - /** - * Invoked before the component receives new props. - * - * Use this as an opportunity to react to a prop transition by updating the - * state using `this.setState`. Current props are accessed via `this.props`. - * - * componentWillReceiveProps: function(nextProps, nextContext) { - * this.setState({ - * likesIncreasing: nextProps.likeCount > this.props.likeCount - * }); - * } - * - * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop - * transition may cause a state change, but the opposite is not true. If you - * need it, you are probably looking for `componentWillUpdate`. - * - * @param {object} nextProps - * @optional - */ - componentWillReceiveProps: SpecPolicy.DEFINE_MANY, - - /** - * Invoked while deciding if the component should be updated as a result of - * receiving new props, state and/or context. - * - * Use this as an opportunity to `return false` when you're certain that the - * transition to the new props/state/context will not require a component - * update. - * - * shouldComponentUpdate: function(nextProps, nextState, nextContext) { - * return !equal(nextProps, this.props) || - * !equal(nextState, this.state) || - * !equal(nextContext, this.context); - * } - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @return {boolean} True if the component should update. - * @optional - */ - shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, - - /** - * Invoked when the component is about to update due to a transition from - * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` - * and `nextContext`. - * - * Use this as an opportunity to perform preparation before an update occurs. - * - * NOTE: You **cannot** use `this.setState()` in this method. - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @param {ReactReconcileTransaction} transaction - * @optional - */ - componentWillUpdate: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component's DOM representation has been updated. - * - * Use this as an opportunity to operate on the DOM when the component has - * been updated. - * - * @param {object} prevProps - * @param {?object} prevState - * @param {?object} prevContext - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidUpdate: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component is about to be removed from its parent and have - * its DOM representation destroyed. - * - * Use this as an opportunity to deallocate any external resources. - * - * NOTE: There is no `componentDidUnmount` since your component will have been - * destroyed by that point. - * - * @optional - */ - componentWillUnmount: SpecPolicy.DEFINE_MANY, - - - - // ==== Advanced methods ==== - - /** - * Updates the component's currently mounted DOM representation. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @internal - * @overridable - */ - updateComponent: SpecPolicy.OVERRIDE_BASE - -}; - -/** - * Mapping from class specification keys to special processing functions. - * - * Although these are declared like instance properties in the specification - * when defining classes using `React.createClass`, they are actually static - * and are accessible on the constructor instead of the prototype. Despite - * being static, they must be defined outside of the "statics" key under - * which all other static methods are defined. - */ -var RESERVED_SPEC_KEYS = { - displayName: function(Constructor, displayName) { - Constructor.displayName = displayName; - }, - mixins: function(Constructor, mixins) { - if (mixins) { - for (var i = 0; i < mixins.length; i++) { - mixSpecIntoComponent(Constructor, mixins[i]); - } - } - }, - childContextTypes: function(Constructor, childContextTypes) { - if ("production" !== "development") { - validateTypeDef( - Constructor, - childContextTypes, - ReactPropTypeLocations.childContext - ); - } - Constructor.childContextTypes = assign( - {}, - Constructor.childContextTypes, - childContextTypes - ); - }, - contextTypes: function(Constructor, contextTypes) { - if ("production" !== "development") { - validateTypeDef( - Constructor, - contextTypes, - ReactPropTypeLocations.context - ); - } - Constructor.contextTypes = assign( - {}, - Constructor.contextTypes, - contextTypes - ); - }, - /** - * Special case getDefaultProps which should move into statics but requires - * automatic merging. - */ - getDefaultProps: function(Constructor, getDefaultProps) { - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps = createMergedResultFunction( - Constructor.getDefaultProps, - getDefaultProps - ); - } else { - Constructor.getDefaultProps = getDefaultProps; - } - }, - propTypes: function(Constructor, propTypes) { - if ("production" !== "development") { - validateTypeDef( - Constructor, - propTypes, - ReactPropTypeLocations.prop - ); - } - Constructor.propTypes = assign( - {}, - Constructor.propTypes, - propTypes - ); - }, - statics: function(Constructor, statics) { - mixStaticSpecIntoComponent(Constructor, statics); - } -}; - -function validateTypeDef(Constructor, typeDef, location) { - for (var propName in typeDef) { - if (typeDef.hasOwnProperty(propName)) { - // use a warning instead of an invariant so components - // don't show up in prod but not in __DEV__ - ("production" !== "development" ? warning( - typeof typeDef[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - Constructor.displayName || 'ReactClass', - ReactPropTypeLocationNames[location], - propName - ) : null); - } - } -} - -function validateMethodOverride(proto, name) { - var specPolicy = ReactClassInterface.hasOwnProperty(name) ? - ReactClassInterface[name] : - null; - - // Disallow overriding of base class methods unless explicitly allowed. - if (ReactClassMixin.hasOwnProperty(name)) { - ("production" !== "development" ? invariant( - specPolicy === SpecPolicy.OVERRIDE_BASE, - 'ReactClassInterface: You are attempting to override ' + - '`%s` from your class specification. Ensure that your method names ' + - 'do not overlap with React methods.', - name - ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); - } - - // Disallow defining methods more than once unless explicitly allowed. - if (proto.hasOwnProperty(name)) { - ("production" !== "development" ? invariant( - specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED, - 'ReactClassInterface: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be due ' + - 'to a mixin.', - name - ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); - } -} - -/** - * Mixin helper which handles policy validation and reserved - * specification keys when building React classses. - */ -function mixSpecIntoComponent(Constructor, spec) { - if (!spec) { - return; - } - - ("production" !== "development" ? invariant( - typeof spec !== 'function', - 'ReactClass: You\'re attempting to ' + - 'use a component class as a mixin. Instead, just use a regular object.' - ) : invariant(typeof spec !== 'function')); - ("production" !== "development" ? invariant( - !ReactElement.isValidElement(spec), - 'ReactClass: You\'re attempting to ' + - 'use a component as a mixin. Instead, just use a regular object.' - ) : invariant(!ReactElement.isValidElement(spec))); - - var proto = Constructor.prototype; - - // By handling mixins before any other properties, we ensure the same - // chaining order is applied to methods with DEFINE_MANY policy, whether - // mixins are listed before or after these methods in the spec. - if (spec.hasOwnProperty(MIXINS_KEY)) { - RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); - } - - for (var name in spec) { - if (!spec.hasOwnProperty(name)) { - continue; - } - - if (name === MIXINS_KEY) { - // We have already handled mixins in a special case above - continue; - } - - var property = spec[name]; - validateMethodOverride(proto, name); - - if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { - RESERVED_SPEC_KEYS[name](Constructor, property); - } else { - // Setup methods on prototype: - // The following member methods should not be automatically bound: - // 1. Expected ReactClass methods (in the "interface"). - // 2. Overridden methods (that were mixed in). - var isReactClassMethod = - ReactClassInterface.hasOwnProperty(name); - var isAlreadyDefined = proto.hasOwnProperty(name); - var markedDontBind = property && property.__reactDontBind; - var isFunction = typeof property === 'function'; - var shouldAutoBind = - isFunction && - !isReactClassMethod && - !isAlreadyDefined && - !markedDontBind; - - if (shouldAutoBind) { - if (!proto.__reactAutoBindMap) { - proto.__reactAutoBindMap = {}; - } - proto.__reactAutoBindMap[name] = property; - proto[name] = property; - } else { - if (isAlreadyDefined) { - var specPolicy = ReactClassInterface[name]; - - // These cases should already be caught by validateMethodOverride - ("production" !== "development" ? invariant( - isReactClassMethod && ( - (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) - ), - 'ReactClass: Unexpected spec policy %s for key %s ' + - 'when mixing in component specs.', - specPolicy, - name - ) : invariant(isReactClassMethod && ( - (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) - ))); - - // For methods which are defined more than once, call the existing - // methods before calling the new property, merging if appropriate. - if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { - proto[name] = createMergedResultFunction(proto[name], property); - } else if (specPolicy === SpecPolicy.DEFINE_MANY) { - proto[name] = createChainedFunction(proto[name], property); - } - } else { - proto[name] = property; - if ("production" !== "development") { - // Add verbose displayName to the function, which helps when looking - // at profiling tools. - if (typeof property === 'function' && spec.displayName) { - proto[name].displayName = spec.displayName + '_' + name; - } - } - } - } - } - } -} - -function mixStaticSpecIntoComponent(Constructor, statics) { - if (!statics) { - return; - } - for (var name in statics) { - var property = statics[name]; - if (!statics.hasOwnProperty(name)) { - continue; - } - - var isReserved = name in RESERVED_SPEC_KEYS; - ("production" !== "development" ? invariant( - !isReserved, - 'ReactClass: You are attempting to define a reserved ' + - 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + - 'as an instance property instead; it will still be accessible on the ' + - 'constructor.', - name - ) : invariant(!isReserved)); - - var isInherited = name in Constructor; - ("production" !== "development" ? invariant( - !isInherited, - 'ReactClass: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be ' + - 'due to a mixin.', - name - ) : invariant(!isInherited)); - Constructor[name] = property; - } -} - -/** - * Merge two objects, but throw if both contain the same key. - * - * @param {object} one The first object, which is mutated. - * @param {object} two The second object - * @return {object} one after it has been mutated to contain everything in two. - */ -function mergeIntoWithNoDuplicateKeys(one, two) { - ("production" !== "development" ? invariant( - one && two && typeof one === 'object' && typeof two === 'object', - 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' - ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); - - for (var key in two) { - if (two.hasOwnProperty(key)) { - ("production" !== "development" ? invariant( - one[key] === undefined, - 'mergeIntoWithNoDuplicateKeys(): ' + - 'Tried to merge two objects with the same key: `%s`. This conflict ' + - 'may be due to a mixin; in particular, this may be caused by two ' + - 'getInitialState() or getDefaultProps() methods returning objects ' + - 'with clashing keys.', - key - ) : invariant(one[key] === undefined)); - one[key] = two[key]; - } - } - return one; -} - -/** - * Creates a function that invokes two functions and merges their return values. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createMergedResultFunction(one, two) { - return function mergedResult() { - var a = one.apply(this, arguments); - var b = two.apply(this, arguments); - if (a == null) { - return b; - } else if (b == null) { - return a; - } - var c = {}; - mergeIntoWithNoDuplicateKeys(c, a); - mergeIntoWithNoDuplicateKeys(c, b); - return c; - }; -} - -/** - * Creates a function that invokes two functions and ignores their return vales. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createChainedFunction(one, two) { - return function chainedFunction() { - one.apply(this, arguments); - two.apply(this, arguments); - }; -} - -/** - * Binds a method to the component. - * - * @param {object} component Component whose method is going to be bound. - * @param {function} method Method to be bound. - * @return {function} The bound method. - */ -function bindAutoBindMethod(component, method) { - var boundMethod = method.bind(component); - if ("production" !== "development") { - boundMethod.__reactBoundContext = component; - boundMethod.__reactBoundMethod = method; - boundMethod.__reactBoundArguments = null; - var componentName = component.constructor.displayName; - var _bind = boundMethod.bind; - /* eslint-disable block-scoped-var, no-undef */ - boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - // User is trying to bind() an autobound method; we effectively will - // ignore the value of "this" that the user is trying to use, so - // let's warn. - if (newThis !== component && newThis !== null) { - ("production" !== "development" ? warning( - false, - 'bind(): React component methods may only be bound to the ' + - 'component instance. See %s', - componentName - ) : null); - } else if (!args.length) { - ("production" !== "development" ? warning( - false, - 'bind(): You are binding a component method to the component. ' + - 'React does this for you automatically in a high-performance ' + - 'way, so you can safely remove this call. See %s', - componentName - ) : null); - return boundMethod; - } - var reboundMethod = _bind.apply(boundMethod, arguments); - reboundMethod.__reactBoundContext = component; - reboundMethod.__reactBoundMethod = method; - reboundMethod.__reactBoundArguments = args; - return reboundMethod; - /* eslint-enable */ - }; - } - return boundMethod; -} - -/** - * Binds all auto-bound methods in a component. - * - * @param {object} component Component whose method is going to be bound. - */ -function bindAutoBindMethods(component) { - for (var autoBindKey in component.__reactAutoBindMap) { - if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { - var method = component.__reactAutoBindMap[autoBindKey]; - component[autoBindKey] = bindAutoBindMethod( - component, - ReactErrorUtils.guard( - method, - component.constructor.displayName + '.' + autoBindKey - ) - ); - } - } -} - -var typeDeprecationDescriptor = { - enumerable: false, - get: function() { - var displayName = this.displayName || this.name || 'Component'; - ("production" !== "development" ? warning( - false, - '%s.type is deprecated. Use %s directly to access the class.', - displayName, - displayName - ) : null); - Object.defineProperty(this, 'type', { - value: this - }); - return this; - } -}; - -/** - * Add more to the ReactClass base class. These are all legacy features and - * therefore not already part of the modern ReactComponent. - */ -var ReactClassMixin = { - - /** - * TODO: This will be deprecated because state should always keep a consistent - * type signature and the only use case for this, is to avoid that. - */ - replaceState: function(newState, callback) { - ReactUpdateQueue.enqueueReplaceState(this, newState); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - }, - - /** - * Checks whether or not this composite component is mounted. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function() { - if ("production" !== "development") { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - ("production" !== "development" ? warning( - owner._warnedAboutRefsInRender, - '%s is accessing isMounted inside its render() function. ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ) : null); - owner._warnedAboutRefsInRender = true; - } - } - var internalInstance = ReactInstanceMap.get(this); - return ( - internalInstance && - internalInstance !== ReactLifeCycle.currentlyMountingInstance - ); - }, - - /** - * Sets a subset of the props. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - * @deprecated - */ - setProps: function(partialProps, callback) { - ReactUpdateQueue.enqueueSetProps(this, partialProps); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - }, - - /** - * Replace all the props. - * - * @param {object} newProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - * @deprecated - */ - replaceProps: function(newProps, callback) { - ReactUpdateQueue.enqueueReplaceProps(this, newProps); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - } -}; - -var ReactClassComponent = function() {}; -assign( - ReactClassComponent.prototype, - ReactComponent.prototype, - ReactClassMixin -); - -/** - * Module for creating composite components. - * - * @class ReactClass - */ -var ReactClass = { - - /** - * Creates a composite component class given a class specification. - * - * @param {object} spec Class specification (which must define `render`). - * @return {function} Component constructor function. - * @public - */ - createClass: function(spec) { - var Constructor = function(props, context) { - // This constructor is overridden by mocks. The argument is used - // by mocks to assert on what gets mounted. - - if ("production" !== "development") { - ("production" !== "development" ? warning( - this instanceof Constructor, - 'Something is calling a React component directly. Use a factory or ' + - 'JSX instead. See: https://fb.me/react-legacyfactory' - ) : null); - } - - // Wire up auto-binding - if (this.__reactAutoBindMap) { - bindAutoBindMethods(this); - } - - this.props = props; - this.context = context; - this.state = null; - - // ReactClasses doesn't have constructors. Instead, they use the - // getInitialState and componentWillMount methods for initialization. - - var initialState = this.getInitialState ? this.getInitialState() : null; - if ("production" !== "development") { - // We allow auto-mocks to proceed as if they're returning null. - if (typeof initialState === 'undefined' && - this.getInitialState._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - initialState = null; - } - } - ("production" !== "development" ? invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.getInitialState(): must return an object or null', - Constructor.displayName || 'ReactCompositeComponent' - ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); - - this.state = initialState; - }; - Constructor.prototype = new ReactClassComponent(); - Constructor.prototype.constructor = Constructor; - - injectedMixins.forEach( - mixSpecIntoComponent.bind(null, Constructor) - ); - - mixSpecIntoComponent(Constructor, spec); - - // Initialize the defaultProps property after all mixins have been merged - if (Constructor.getDefaultProps) { - Constructor.defaultProps = Constructor.getDefaultProps(); - } - - if ("production" !== "development") { - // This is a tag to indicate that the use of these method names is ok, - // since it's used with createClass. If it's not, then it's likely a - // mistake so we'll warn you to use the static property, property - // initializer or constructor respectively. - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps.isReactClassApproved = {}; - } - if (Constructor.prototype.getInitialState) { - Constructor.prototype.getInitialState.isReactClassApproved = {}; - } - } - - ("production" !== "development" ? invariant( - Constructor.prototype.render, - 'createClass(...): Class specification must implement a `render` method.' - ) : invariant(Constructor.prototype.render)); - - if ("production" !== "development") { - ("production" !== "development" ? warning( - !Constructor.prototype.componentShouldUpdate, - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - spec.displayName || 'A component' - ) : null); - } - - // Reduce time spent doing lookups by setting these on the prototype. - for (var methodName in ReactClassInterface) { - if (!Constructor.prototype[methodName]) { - Constructor.prototype[methodName] = null; - } - } - - // Legacy hook - Constructor.type = Constructor; - if ("production" !== "development") { - try { - Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - - return Constructor; - }, - - injection: { - injectMixin: function(mixin) { - injectedMixins.push(mixin); - } - } - -}; - -module.exports = ReactClass; - -},{"150":150,"156":156,"157":157,"171":171,"29":29,"39":39,"45":45,"63":63,"66":66,"73":73,"74":74,"84":84,"85":85,"99":99}],39:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactComponent - */ - -'use strict'; - -var ReactUpdateQueue = _dereq_(99); - -var invariant = _dereq_(150); -var warning = _dereq_(171); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactComponent(props, context) { - this.props = props; - this.context = context; -} - -/** - * Sets a subset of the state. Always use this to mutate - * state. You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * There is no guarantee that calls to `setState` will run synchronously, - * as they may eventually be batched together. You can provide an optional - * callback that will be executed when the call to setState is actually - * completed. - * - * When a function is provided to setState, it will be called at some point in - * the future (not synchronously). It will be called with the up to date - * component arguments (state, props, context). These values can be different - * from this.* because your function may be called after receiveProps but before - * shouldComponentUpdate, and this new state, props, and context will not yet be - * assigned to this. - * - * @param {object|function} partialState Next partial state or function to - * produce next partial state to be merged with current state. - * @param {?function} callback Called after state is updated. - * @final - * @protected - */ -ReactComponent.prototype.setState = function(partialState, callback) { - ("production" !== "development" ? invariant( - typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null, - 'setState(...): takes an object of state variables to update or a ' + - 'function which returns an object of state variables.' - ) : invariant(typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null)); - if ("production" !== "development") { - ("production" !== "development" ? warning( - partialState != null, - 'setState(...): You passed an undefined or null state object; ' + - 'instead, use forceUpdate().' - ) : null); - } - ReactUpdateQueue.enqueueSetState(this, partialState); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } -}; - -/** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {?function} callback Called after update is complete. - * @final - * @protected - */ -ReactComponent.prototype.forceUpdate = function(callback) { - ReactUpdateQueue.enqueueForceUpdate(this); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } -}; - -/** - * Deprecated APIs. These APIs used to exist on classic React classes but since - * we would like to deprecate them, we're not going to move them over to this - * modern base class. Instead, we define a getter that warns if it's accessed. - */ -if ("production" !== "development") { - var deprecatedAPIs = { - getDOMNode: [ - 'getDOMNode', - 'Use React.findDOMNode(component) instead.' - ], - isMounted: [ - 'isMounted', - 'Instead, make sure to clean up subscriptions and pending requests in ' + - 'componentWillUnmount to prevent memory leaks.' - ], - replaceProps: [ - 'replaceProps', - 'Instead call React.render again at the top level.' - ], - replaceState: [ - 'replaceState', - 'Refactor your code to use setState instead (see ' + - 'https://github.com/facebook/react/issues/3236).' - ], - setProps: [ - 'setProps', - 'Instead call React.render again at the top level.' - ] - }; - var defineDeprecationWarning = function(methodName, info) { - try { - Object.defineProperty(ReactComponent.prototype, methodName, { - get: function() { - ("production" !== "development" ? warning( - false, - '%s(...) is deprecated in plain JavaScript React classes. %s', - info[0], - info[1] - ) : null); - return undefined; - } - }); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - }; - for (var fnName in deprecatedAPIs) { - if (deprecatedAPIs.hasOwnProperty(fnName)) { - defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); - } - } -} - -module.exports = ReactComponent; - -},{"150":150,"171":171,"99":99}],40:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactComponentBrowserEnvironment - */ - -/*jslint evil: true */ - -'use strict'; - -var ReactDOMIDOperations = _dereq_(50); -var ReactMount = _dereq_(77); - -/** - * Abstracts away all functionality of the reconciler that requires knowledge of - * the browser context. TODO: These callers should be refactored to avoid the - * need for this injection. - */ -var ReactComponentBrowserEnvironment = { - - processChildrenUpdates: - ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, - - replaceNodeWithMarkupByID: - ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID, - - /** - * If a particular environment requires that some resources be cleaned up, - * specify this in the injected Mixin. In the DOM, we would likely want to - * purge any cached node ID lookups. - * - * @private - */ - unmountIDFromEnvironment: function(rootNodeID) { - ReactMount.purgeID(rootNodeID); - } - -}; - -module.exports = ReactComponentBrowserEnvironment; - -},{"50":50,"77":77}],41:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactComponentEnvironment - */ - -'use strict'; - -var invariant = _dereq_(150); - -var injected = false; - -var ReactComponentEnvironment = { - - /** - * Optionally injectable environment dependent cleanup hook. (server vs. - * browser etc). Example: A browser system caches DOM nodes based on component - * ID and must remove that cache entry when this instance is unmounted. - */ - unmountIDFromEnvironment: null, - - /** - * Optionally injectable hook for swapping out mount images in the middle of - * the tree. - */ - replaceNodeWithMarkupByID: null, - - /** - * Optionally injectable hook for processing a queue of child updates. Will - * later move into MultiChildComponents. - */ - processChildrenUpdates: null, - - injection: { - injectEnvironment: function(environment) { - ("production" !== "development" ? invariant( - !injected, - 'ReactCompositeComponent: injectEnvironment() can only be called once.' - ) : invariant(!injected)); - ReactComponentEnvironment.unmountIDFromEnvironment = - environment.unmountIDFromEnvironment; - ReactComponentEnvironment.replaceNodeWithMarkupByID = - environment.replaceNodeWithMarkupByID; - ReactComponentEnvironment.processChildrenUpdates = - environment.processChildrenUpdates; - injected = true; - } - } - -}; - -module.exports = ReactComponentEnvironment; - -},{"150":150}],42:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * -* @providesModule ReactComponentWithPureRenderMixin -*/ - -'use strict'; - -var shallowEqual = _dereq_(166); - -/** - * If your React component's render function is "pure", e.g. it will render the - * same result given the same props and state, provide this Mixin for a - * considerable performance boost. - * - * Most React components have pure render functions. - * - * Example: - * - * var ReactComponentWithPureRenderMixin = - * require('ReactComponentWithPureRenderMixin'); - * React.createClass({ - * mixins: [ReactComponentWithPureRenderMixin], - * - * render: function() { - * return <div className={this.props.className}>foo</div>; - * } - * }); - * - * Note: This only checks shallow equality for props and state. If these contain - * complex data structures this mixin may have false-negatives for deeper - * differences. Only mixin to components which have simple props and state, or - * use `forceUpdate()` when you know deep data structures have changed. - */ -var ReactComponentWithPureRenderMixin = { - shouldComponentUpdate: function(nextProps, nextState) { - return !shallowEqual(this.props, nextProps) || - !shallowEqual(this.state, nextState); - } -}; - -module.exports = ReactComponentWithPureRenderMixin; - -},{"166":166}],43:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactCompositeComponent - */ - -'use strict'; - -var ReactComponentEnvironment = _dereq_(41); -var ReactContext = _dereq_(44); -var ReactCurrentOwner = _dereq_(45); -var ReactElement = _dereq_(63); -var ReactElementValidator = _dereq_(64); -var ReactInstanceMap = _dereq_(73); -var ReactLifeCycle = _dereq_(74); -var ReactNativeComponent = _dereq_(80); -var ReactPerf = _dereq_(82); -var ReactPropTypeLocations = _dereq_(85); -var ReactPropTypeLocationNames = _dereq_(84); -var ReactReconciler = _dereq_(89); -var ReactUpdates = _dereq_(100); - -var assign = _dereq_(29); -var emptyObject = _dereq_(130); -var invariant = _dereq_(150); -var shouldUpdateReactComponent = _dereq_(167); -var warning = _dereq_(171); - -function getDeclarationErrorAddendum(component) { - var owner = component._currentElement._owner || null; - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * ------------------ The Life-Cycle of a Composite Component ------------------ - * - * - constructor: Initialization of state. The instance is now retained. - * - componentWillMount - * - render - * - [children's constructors] - * - [children's componentWillMount and render] - * - [children's componentDidMount] - * - componentDidMount - * - * Update Phases: - * - componentWillReceiveProps (only called if parent updated) - * - shouldComponentUpdate - * - componentWillUpdate - * - render - * - [children's constructors or receive props phases] - * - componentDidUpdate - * - * - componentWillUnmount - * - [children's componentWillUnmount] - * - [children destroyed] - * - (destroyed): The instance is now blank, released by React and ready for GC. - * - * ----------------------------------------------------------------------------- - */ - -/** - * An incrementing ID assigned to each component when it is mounted. This is - * used to enforce the order in which `ReactUpdates` updates dirty components. - * - * @private - */ -var nextMountID = 1; - -/** - * @lends {ReactCompositeComponent.prototype} - */ -var ReactCompositeComponentMixin = { - - /** - * Base constructor for all composite component. - * - * @param {ReactElement} element - * @final - * @internal - */ - construct: function(element) { - this._currentElement = element; - this._rootNodeID = null; - this._instance = null; - - // See ReactUpdateQueue - this._pendingElement = null; - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - this._renderedComponent = null; - - this._context = null; - this._mountOrder = 0; - this._isTopLevel = false; - - // See ReactUpdates and ReactUpdateQueue. - this._pendingCallbacks = null; - }, - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function(rootID, transaction, context) { - this._context = context; - this._mountOrder = nextMountID++; - this._rootNodeID = rootID; - - var publicProps = this._processProps(this._currentElement.props); - var publicContext = this._processContext(this._currentElement._context); - - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); - - // Initialize the public class - var inst = new Component(publicProps, publicContext); - - if ("production" !== "development") { - // This will throw later in _renderValidatedComponent, but add an early - // warning now to help debugging - ("production" !== "development" ? warning( - inst.render != null, - '%s(...): No `render` method found on the returned component ' + - 'instance: you may have forgotten to define `render` in your ' + - 'component or you may have accidentally tried to render an element ' + - 'whose type is a function that isn\'t a React component.', - Component.displayName || Component.name || 'Component' - ) : null); - } - - // These should be set up in the constructor, but as a convenience for - // simpler class abstractions, we set them up after the fact. - inst.props = publicProps; - inst.context = publicContext; - inst.refs = emptyObject; - - this._instance = inst; - - // Store a reference from the instance back to the internal representation - ReactInstanceMap.set(inst, this); - - if ("production" !== "development") { - this._warnIfContextsDiffer(this._currentElement._context, context); - } - - if ("production" !== "development") { - // Since plain JS classes are defined without any special initialization - // logic, we can not catch common errors early. Therefore, we have to - // catch them here, at initialization time, instead. - ("production" !== "development" ? warning( - !inst.getInitialState || - inst.getInitialState.isReactClassApproved, - 'getInitialState was defined on %s, a plain JavaScript class. ' + - 'This is only supported for classes created using React.createClass. ' + - 'Did you mean to define a state property instead?', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - !inst.getDefaultProps || - inst.getDefaultProps.isReactClassApproved, - 'getDefaultProps was defined on %s, a plain JavaScript class. ' + - 'This is only supported for classes created using React.createClass. ' + - 'Use a static property to define defaultProps instead.', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - !inst.propTypes, - 'propTypes was defined as an instance property on %s. Use a static ' + - 'property to define propTypes instead.', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - !inst.contextTypes, - 'contextTypes was defined as an instance property on %s. Use a ' + - 'static property to define contextTypes instead.', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - typeof inst.componentShouldUpdate !== 'function', - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - (this.getName() || 'A component') - ) : null); - } - - var initialState = inst.state; - if (initialState === undefined) { - inst.state = initialState = null; - } - ("production" !== "development" ? invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.state: must be set to an object or null', - this.getName() || 'ReactCompositeComponent' - ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); - - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - var childContext; - var renderedElement; - - var previouslyMounting = ReactLifeCycle.currentlyMountingInstance; - ReactLifeCycle.currentlyMountingInstance = this; - try { - if (inst.componentWillMount) { - inst.componentWillMount(); - // When mounting, calls to `setState` by `componentWillMount` will set - // `this._pendingStateQueue` without triggering a re-render. - if (this._pendingStateQueue) { - inst.state = this._processPendingState(inst.props, inst.context); - } - } - - childContext = this._getValidatedChildContext(context); - renderedElement = this._renderValidatedComponent(childContext); - } finally { - ReactLifeCycle.currentlyMountingInstance = previouslyMounting; - } - - this._renderedComponent = this._instantiateReactComponent( - renderedElement, - this._currentElement.type // The wrapping type - ); - - var markup = ReactReconciler.mountComponent( - this._renderedComponent, - rootID, - transaction, - this._mergeChildContext(context, childContext) - ); - if (inst.componentDidMount) { - transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); - } - - return markup; - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function() { - var inst = this._instance; - - if (inst.componentWillUnmount) { - var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance; - ReactLifeCycle.currentlyUnmountingInstance = this; - try { - inst.componentWillUnmount(); - } finally { - ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting; - } - } - - ReactReconciler.unmountComponent(this._renderedComponent); - this._renderedComponent = null; - - // Reset pending fields - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - this._pendingCallbacks = null; - this._pendingElement = null; - - // These fields do not really need to be reset since this object is no - // longer accessible. - this._context = null; - this._rootNodeID = null; - - // Delete the reference from the instance to this internal representation - // which allow the internals to be properly cleaned up even if the user - // leaks a reference to the public instance. - ReactInstanceMap.remove(inst); - - // Some existing components rely on inst.props even after they've been - // destroyed (in event handlers). - // TODO: inst.props = null; - // TODO: inst.state = null; - // TODO: inst.context = null; - }, - - /** - * Schedule a partial update to the props. Only used for internal testing. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @internal - */ - _setPropsInternal: function(partialProps, callback) { - // This is a deoptimized path. We optimize for always having an element. - // This creates an extra internal element. - var element = this._pendingElement || this._currentElement; - this._pendingElement = ReactElement.cloneAndReplaceProps( - element, - assign({}, element.props, partialProps) - ); - ReactUpdates.enqueueUpdate(this, callback); - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes` - * - * @param {object} context - * @return {?object} - * @private - */ - _maskContext: function(context) { - var maskedContext = null; - // This really should be getting the component class for the element, - // but we know that we're not going to need it for built-ins. - if (typeof this._currentElement.type === 'string') { - return emptyObject; - } - var contextTypes = this._currentElement.type.contextTypes; - if (!contextTypes) { - return emptyObject; - } - maskedContext = {}; - for (var contextName in contextTypes) { - maskedContext[contextName] = context[contextName]; - } - return maskedContext; - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes`, and asserts that they are valid. - * - * @param {object} context - * @return {?object} - * @private - */ - _processContext: function(context) { - var maskedContext = this._maskContext(context); - if ("production" !== "development") { - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); - if (Component.contextTypes) { - this._checkPropTypes( - Component.contextTypes, - maskedContext, - ReactPropTypeLocations.context - ); - } - } - return maskedContext; - }, - - /** - * @param {object} currentContext - * @return {object} - * @private - */ - _getValidatedChildContext: function(currentContext) { - var inst = this._instance; - var childContext = inst.getChildContext && inst.getChildContext(); - if (childContext) { - ("production" !== "development" ? invariant( - typeof inst.constructor.childContextTypes === 'object', - '%s.getChildContext(): childContextTypes must be defined in order to ' + - 'use getChildContext().', - this.getName() || 'ReactCompositeComponent' - ) : invariant(typeof inst.constructor.childContextTypes === 'object')); - if ("production" !== "development") { - this._checkPropTypes( - inst.constructor.childContextTypes, - childContext, - ReactPropTypeLocations.childContext - ); - } - for (var name in childContext) { - ("production" !== "development" ? invariant( - name in inst.constructor.childContextTypes, - '%s.getChildContext(): key "%s" is not defined in childContextTypes.', - this.getName() || 'ReactCompositeComponent', - name - ) : invariant(name in inst.constructor.childContextTypes)); - } - return childContext; - } - return null; - }, - - _mergeChildContext: function(currentContext, childContext) { - if (childContext) { - return assign({}, currentContext, childContext); - } - return currentContext; - }, - - /** - * Processes props by setting default values for unspecified props and - * asserting that the props are valid. Does not mutate its argument; returns - * a new props object with defaults merged in. - * - * @param {object} newProps - * @return {object} - * @private - */ - _processProps: function(newProps) { - if ("production" !== "development") { - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); - if (Component.propTypes) { - this._checkPropTypes( - Component.propTypes, - newProps, - ReactPropTypeLocations.prop - ); - } - } - return newProps; - }, - - /** - * Assert that the props are valid - * - * @param {object} propTypes Map of prop name to a ReactPropType - * @param {object} props - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ - _checkPropTypes: function(propTypes, props, location) { - // TODO: Stop validating prop types here and only use the element - // validation. - var componentName = this.getName(); - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error; - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - ("production" !== "development" ? invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually ' + - 'from React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ) : invariant(typeof propTypes[propName] === 'function')); - error = propTypes[propName](props, propName, componentName, location); - } catch (ex) { - error = ex; - } - if (error instanceof Error) { - // We may want to extend this logic for similar errors in - // React.render calls, so I'm abstracting it away into - // a function to minimize refactoring in the future - var addendum = getDeclarationErrorAddendum(this); - - if (location === ReactPropTypeLocations.prop) { - // Preface gives us something to blacklist in warning module - ("production" !== "development" ? warning( - false, - 'Failed Composite propType: %s%s', - error.message, - addendum - ) : null); - } else { - ("production" !== "development" ? warning( - false, - 'Failed Context Types: %s%s', - error.message, - addendum - ) : null); - } - } - } - } - }, - - receiveComponent: function(nextElement, transaction, nextContext) { - var prevElement = this._currentElement; - var prevContext = this._context; - - this._pendingElement = null; - - this.updateComponent( - transaction, - prevElement, - nextElement, - prevContext, - nextContext - ); - }, - - /** - * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` - * is set, update the component. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function(transaction) { - if (this._pendingElement != null) { - ReactReconciler.receiveComponent( - this, - this._pendingElement || this._currentElement, - transaction, - this._context - ); - } - - if (this._pendingStateQueue !== null || this._pendingForceUpdate) { - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps( - this._currentElement - ); - } - - this.updateComponent( - transaction, - this._currentElement, - this._currentElement, - this._context, - this._context - ); - } - }, - - /** - * Compare two contexts, warning if they are different - * TODO: Remove this check when owner-context is removed - */ - _warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) { - ownerBasedContext = this._maskContext(ownerBasedContext); - parentBasedContext = this._maskContext(parentBasedContext); - var parentKeys = Object.keys(parentBasedContext).sort(); - var displayName = this.getName() || 'ReactCompositeComponent'; - for (var i = 0; i < parentKeys.length; i++) { - var key = parentKeys[i]; - ("production" !== "development" ? warning( - ownerBasedContext[key] === parentBasedContext[key], - 'owner-based and parent-based contexts differ ' + - '(values: `%s` vs `%s`) for key (%s) while mounting %s ' + - '(see: http://fb.me/react-context-by-parent)', - ownerBasedContext[key], - parentBasedContext[key], - key, - displayName - ) : null); - } - }, - - /** - * Perform an update to a mounted component. The componentWillReceiveProps and - * shouldComponentUpdate methods are called, then (assuming the update isn't - * skipped) the remaining update lifecycle methods are called and the DOM - * representation is updated. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevParentElement - * @param {ReactElement} nextParentElement - * @internal - * @overridable - */ - updateComponent: function( - transaction, - prevParentElement, - nextParentElement, - prevUnmaskedContext, - nextUnmaskedContext - ) { - var inst = this._instance; - - var nextContext = inst.context; - var nextProps = inst.props; - - // Distinguish between a props update versus a simple state update - if (prevParentElement !== nextParentElement) { - nextContext = this._processContext(nextParentElement._context); - nextProps = this._processProps(nextParentElement.props); - - if ("production" !== "development") { - if (nextUnmaskedContext != null) { - this._warnIfContextsDiffer( - nextParentElement._context, - nextUnmaskedContext - ); - } - } - - // An update here will schedule an update but immediately set - // _pendingStateQueue which will ensure that any state updates gets - // immediately reconciled instead of waiting for the next batch. - - if (inst.componentWillReceiveProps) { - inst.componentWillReceiveProps(nextProps, nextContext); - } - } - - var nextState = this._processPendingState(nextProps, nextContext); - - var shouldUpdate = - this._pendingForceUpdate || - !inst.shouldComponentUpdate || - inst.shouldComponentUpdate(nextProps, nextState, nextContext); - - if ("production" !== "development") { - ("production" !== "development" ? warning( - typeof shouldUpdate !== 'undefined', - '%s.shouldComponentUpdate(): Returned undefined instead of a ' + - 'boolean value. Make sure to return true or false.', - this.getName() || 'ReactCompositeComponent' - ) : null); - } - - if (shouldUpdate) { - this._pendingForceUpdate = false; - // Will set `this.props`, `this.state` and `this.context`. - this._performComponentUpdate( - nextParentElement, - nextProps, - nextState, - nextContext, - transaction, - nextUnmaskedContext - ); - } else { - // If it's determined that a component should not update, we still want - // to set props and state but we shortcut the rest of the update. - this._currentElement = nextParentElement; - this._context = nextUnmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - } - }, - - _processPendingState: function(props, context) { - var inst = this._instance; - var queue = this._pendingStateQueue; - var replace = this._pendingReplaceState; - this._pendingReplaceState = false; - this._pendingStateQueue = null; - - if (!queue) { - return inst.state; - } - - if (replace && queue.length === 1) { - return queue[0]; - } - - var nextState = assign({}, replace ? queue[0] : inst.state); - for (var i = replace ? 1 : 0; i < queue.length; i++) { - var partial = queue[i]; - assign( - nextState, - typeof partial === 'function' ? - partial.call(inst, nextState, props, context) : - partial - ); - } - - return nextState; - }, - - /** - * Merges new props and state, notifies delegate methods of update and - * performs update. - * - * @param {ReactElement} nextElement Next element - * @param {object} nextProps Next public object to set as properties. - * @param {?object} nextState Next object to set as state. - * @param {?object} nextContext Next public object to set as context. - * @param {ReactReconcileTransaction} transaction - * @param {?object} unmaskedContext - * @private - */ - _performComponentUpdate: function( - nextElement, - nextProps, - nextState, - nextContext, - transaction, - unmaskedContext - ) { - var inst = this._instance; - - var prevProps = inst.props; - var prevState = inst.state; - var prevContext = inst.context; - - if (inst.componentWillUpdate) { - inst.componentWillUpdate(nextProps, nextState, nextContext); - } - - this._currentElement = nextElement; - this._context = unmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - - this._updateRenderedComponent(transaction, unmaskedContext); - - if (inst.componentDidUpdate) { - transaction.getReactMountReady().enqueue( - inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), - inst - ); - } - }, - - /** - * Call the component's `render` method and update the DOM accordingly. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - _updateRenderedComponent: function(transaction, context) { - var prevComponentInstance = this._renderedComponent; - var prevRenderedElement = prevComponentInstance._currentElement; - var childContext = this._getValidatedChildContext(); - var nextRenderedElement = this._renderValidatedComponent(childContext); - if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { - ReactReconciler.receiveComponent( - prevComponentInstance, - nextRenderedElement, - transaction, - this._mergeChildContext(context, childContext) - ); - } else { - // These two IDs are actually the same! But nothing should rely on that. - var thisID = this._rootNodeID; - var prevComponentID = prevComponentInstance._rootNodeID; - ReactReconciler.unmountComponent(prevComponentInstance); - - this._renderedComponent = this._instantiateReactComponent( - nextRenderedElement, - this._currentElement.type - ); - var nextMarkup = ReactReconciler.mountComponent( - this._renderedComponent, - thisID, - transaction, - this._mergeChildContext(context, childContext) - ); - this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup); - } - }, - - /** - * @protected - */ - _replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) { - ReactComponentEnvironment.replaceNodeWithMarkupByID( - prevComponentID, - nextMarkup - ); - }, - - /** - * @protected - */ - _renderValidatedComponentWithoutOwnerOrContext: function() { - var inst = this._instance; - var renderedComponent = inst.render(); - if ("production" !== "development") { - // We allow auto-mocks to proceed as if they're returning null. - if (typeof renderedComponent === 'undefined' && - inst.render._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - renderedComponent = null; - } - } - - return renderedComponent; - }, - - /** - * @private - */ - _renderValidatedComponent: function(childContext) { - var renderedComponent; - var previousContext = ReactContext.current; - ReactContext.current = this._mergeChildContext( - this._currentElement._context, - childContext - ); - ReactCurrentOwner.current = this; - try { - renderedComponent = - this._renderValidatedComponentWithoutOwnerOrContext(); - } finally { - ReactContext.current = previousContext; - ReactCurrentOwner.current = null; - } - ("production" !== "development" ? invariant( - // TODO: An `isValidNode` function would probably be more appropriate - renderedComponent === null || renderedComponent === false || - ReactElement.isValidElement(renderedComponent), - '%s.render(): A valid ReactComponent must be returned. You may have ' + - 'returned undefined, an array or some other invalid object.', - this.getName() || 'ReactCompositeComponent' - ) : invariant(// TODO: An `isValidNode` function would probably be more appropriate - renderedComponent === null || renderedComponent === false || - ReactElement.isValidElement(renderedComponent))); - return renderedComponent; - }, - - /** - * Lazily allocates the refs object and stores `component` as `ref`. - * - * @param {string} ref Reference name. - * @param {component} component Component to store as `ref`. - * @final - * @private - */ - attachRef: function(ref, component) { - var inst = this.getPublicInstance(); - var refs = inst.refs === emptyObject ? (inst.refs = {}) : inst.refs; - refs[ref] = component.getPublicInstance(); - }, - - /** - * Detaches a reference name. - * - * @param {string} ref Name to dereference. - * @final - * @private - */ - detachRef: function(ref) { - var refs = this.getPublicInstance().refs; - delete refs[ref]; - }, - - /** - * Get a text description of the component that can be used to identify it - * in error messages. - * @return {string} The name or null. - * @internal - */ - getName: function() { - var type = this._currentElement.type; - var constructor = this._instance && this._instance.constructor; - return ( - type.displayName || (constructor && constructor.displayName) || - type.name || (constructor && constructor.name) || - null - ); - }, - - /** - * Get the publicly accessible representation of this component - i.e. what - * is exposed by refs and returned by React.render. Can be null for stateless - * components. - * - * @return {ReactComponent} the public component instance. - * @internal - */ - getPublicInstance: function() { - return this._instance; - }, - - // Stub - _instantiateReactComponent: null - -}; - -ReactPerf.measureMethods( - ReactCompositeComponentMixin, - 'ReactCompositeComponent', - { - mountComponent: 'mountComponent', - updateComponent: 'updateComponent', - _renderValidatedComponent: '_renderValidatedComponent' - } -); - -var ReactCompositeComponent = { - - Mixin: ReactCompositeComponentMixin - -}; - -module.exports = ReactCompositeComponent; - -},{"100":100,"130":130,"150":150,"167":167,"171":171,"29":29,"41":41,"44":44,"45":45,"63":63,"64":64,"73":73,"74":74,"80":80,"82":82,"84":84,"85":85,"89":89}],44:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactContext - */ - -'use strict'; - -var assign = _dereq_(29); -var emptyObject = _dereq_(130); -var warning = _dereq_(171); - -var didWarn = false; - -/** - * Keeps track of the current context. - * - * The context is automatically passed down the component ownership hierarchy - * and is accessible via `this.context` on ReactCompositeComponents. - */ -var ReactContext = { - - /** - * @internal - * @type {object} - */ - current: emptyObject, - - /** - * Temporarily extends the current context while executing scopedCallback. - * - * A typical use case might look like - * - * render: function() { - * var children = ReactContext.withContext({foo: 'foo'}, () => ( - * - * )); - * return <div>{children}</div>; - * } - * - * @param {object} newContext New context to merge into the existing context - * @param {function} scopedCallback Callback to run with the new context - * @return {ReactComponent|array<ReactComponent>} - */ - withContext: function(newContext, scopedCallback) { - if ("production" !== "development") { - ("production" !== "development" ? warning( - didWarn, - 'withContext is deprecated and will be removed in a future version. ' + - 'Use a wrapper component with getChildContext instead.' - ) : null); - - didWarn = true; - } - - var result; - var previousContext = ReactContext.current; - ReactContext.current = assign({}, previousContext, newContext); - try { - result = scopedCallback(); - } finally { - ReactContext.current = previousContext; - } - return result; - } - -}; - -module.exports = ReactContext; - -},{"130":130,"171":171,"29":29}],45:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactCurrentOwner - */ - -'use strict'; - -/** - * Keeps track of the current owner. - * - * The current owner is the component who should own any components that are - * currently being constructed. - * - * The depth indicate how many composite components are above this render level. - */ -var ReactCurrentOwner = { - - /** - * @internal - * @type {ReactComponent} - */ - current: null - -}; - -module.exports = ReactCurrentOwner; - -},{}],46:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOM - * @typechecks static-only - */ - -'use strict'; - -var ReactElement = _dereq_(63); -var ReactElementValidator = _dereq_(64); - -var mapObject = _dereq_(158); - -/** - * Create a factory that creates HTML tag elements. - * - * @param {string} tag Tag name (e.g. `div`). - * @private - */ -function createDOMFactory(tag) { - if ("production" !== "development") { - return ReactElementValidator.createFactory(tag); - } - return ReactElement.createFactory(tag); -} - -/** - * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. - * This is also accessible via `React.DOM`. - * - * @public - */ -var ReactDOM = mapObject({ - a: 'a', - abbr: 'abbr', - address: 'address', - area: 'area', - article: 'article', - aside: 'aside', - audio: 'audio', - b: 'b', - base: 'base', - bdi: 'bdi', - bdo: 'bdo', - big: 'big', - blockquote: 'blockquote', - body: 'body', - br: 'br', - button: 'button', - canvas: 'canvas', - caption: 'caption', - cite: 'cite', - code: 'code', - col: 'col', - colgroup: 'colgroup', - data: 'data', - datalist: 'datalist', - dd: 'dd', - del: 'del', - details: 'details', - dfn: 'dfn', - dialog: 'dialog', - div: 'div', - dl: 'dl', - dt: 'dt', - em: 'em', - embed: 'embed', - fieldset: 'fieldset', - figcaption: 'figcaption', - figure: 'figure', - footer: 'footer', - form: 'form', - h1: 'h1', - h2: 'h2', - h3: 'h3', - h4: 'h4', - h5: 'h5', - h6: 'h6', - head: 'head', - header: 'header', - hr: 'hr', - html: 'html', - i: 'i', - iframe: 'iframe', - img: 'img', - input: 'input', - ins: 'ins', - kbd: 'kbd', - keygen: 'keygen', - label: 'label', - legend: 'legend', - li: 'li', - link: 'link', - main: 'main', - map: 'map', - mark: 'mark', - menu: 'menu', - menuitem: 'menuitem', - meta: 'meta', - meter: 'meter', - nav: 'nav', - noscript: 'noscript', - object: 'object', - ol: 'ol', - optgroup: 'optgroup', - option: 'option', - output: 'output', - p: 'p', - param: 'param', - picture: 'picture', - pre: 'pre', - progress: 'progress', - q: 'q', - rp: 'rp', - rt: 'rt', - ruby: 'ruby', - s: 's', - samp: 'samp', - script: 'script', - section: 'section', - select: 'select', - small: 'small', - source: 'source', - span: 'span', - strong: 'strong', - style: 'style', - sub: 'sub', - summary: 'summary', - sup: 'sup', - table: 'table', - tbody: 'tbody', - td: 'td', - textarea: 'textarea', - tfoot: 'tfoot', - th: 'th', - thead: 'thead', - time: 'time', - title: 'title', - tr: 'tr', - track: 'track', - u: 'u', - ul: 'ul', - 'var': 'var', - video: 'video', - wbr: 'wbr', - - // SVG - circle: 'circle', - clipPath: 'clipPath', - defs: 'defs', - ellipse: 'ellipse', - g: 'g', - line: 'line', - linearGradient: 'linearGradient', - mask: 'mask', - path: 'path', - pattern: 'pattern', - polygon: 'polygon', - polyline: 'polyline', - radialGradient: 'radialGradient', - rect: 'rect', - stop: 'stop', - svg: 'svg', - text: 'text', - tspan: 'tspan' - -}, createDOMFactory); - -module.exports = ReactDOM; - -},{"158":158,"63":63,"64":64}],47:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMButton - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); - -var keyMirror = _dereq_(156); - -var button = ReactElement.createFactory('button'); - -var mouseListenerNames = keyMirror({ - onClick: true, - onDoubleClick: true, - onMouseDown: true, - onMouseMove: true, - onMouseUp: true, - onClickCapture: true, - onDoubleClickCapture: true, - onMouseDownCapture: true, - onMouseMoveCapture: true, - onMouseUpCapture: true -}); - -/** - * Implements a <button> native component that does not receive mouse events - * when `disabled` is set. - */ -var ReactDOMButton = ReactClass.createClass({ - displayName: 'ReactDOMButton', - tagName: 'BUTTON', - - mixins: [AutoFocusMixin, ReactBrowserComponentMixin], - - render: function() { - var props = {}; - - // Copy the props; except the mouse listeners if we're disabled - for (var key in this.props) { - if (this.props.hasOwnProperty(key) && - (!this.props.disabled || !mouseListenerNames[key])) { - props[key] = this.props[key]; - } - } - - return button(props, this.props.children); - } - -}); - -module.exports = ReactDOMButton; - -},{"156":156,"2":2,"32":32,"38":38,"63":63}],48:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMComponent - * @typechecks static-only - */ - -/* global hasOwnProperty:true */ - -'use strict'; - -var CSSPropertyOperations = _dereq_(6); -var DOMProperty = _dereq_(11); -var DOMPropertyOperations = _dereq_(12); -var ReactBrowserEventEmitter = _dereq_(33); -var ReactComponentBrowserEnvironment = - _dereq_(40); -var ReactMount = _dereq_(77); -var ReactMultiChild = _dereq_(78); -var ReactPerf = _dereq_(82); - -var assign = _dereq_(29); -var escapeTextContentForBrowser = _dereq_(131); -var invariant = _dereq_(150); -var isEventSupported = _dereq_(151); -var keyOf = _dereq_(157); -var warning = _dereq_(171); - -var deleteListener = ReactBrowserEventEmitter.deleteListener; -var listenTo = ReactBrowserEventEmitter.listenTo; -var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules; - -// For quickly matching children type, to test if can be treated as content. -var CONTENT_TYPES = {'string': true, 'number': true}; - -var STYLE = keyOf({style: null}); - -var ELEMENT_NODE_TYPE = 1; - -/** - * Optionally injectable operations for mutating the DOM - */ -var BackendIDOperations = null; - -/** - * @param {?object} props - */ -function assertValidProps(props) { - if (!props) { - return; - } - // Note the use of `==` which checks for null or undefined. - if (props.dangerouslySetInnerHTML != null) { - ("production" !== "development" ? invariant( - props.children == null, - 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' - ) : invariant(props.children == null)); - ("production" !== "development" ? invariant( - typeof props.dangerouslySetInnerHTML === 'object' && - '__html' in props.dangerouslySetInnerHTML, - '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + - 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + - 'for more information.' - ) : invariant(typeof props.dangerouslySetInnerHTML === 'object' && - '__html' in props.dangerouslySetInnerHTML)); - } - if ("production" !== "development") { - ("production" !== "development" ? warning( - props.innerHTML == null, - 'Directly setting property `innerHTML` is not permitted. ' + - 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' - ) : null); - ("production" !== "development" ? warning( - !props.contentEditable || props.children == null, - 'A component is `contentEditable` and contains `children` managed by ' + - 'React. It is now your responsibility to guarantee that none of ' + - 'those nodes are unexpectedly modified or duplicated. This is ' + - 'probably not intentional.' - ) : null); - } - ("production" !== "development" ? invariant( - props.style == null || typeof props.style === 'object', - 'The `style` prop expects a mapping from style properties to values, ' + - 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + - 'using JSX.' - ) : invariant(props.style == null || typeof props.style === 'object')); -} - -function putListener(id, registrationName, listener, transaction) { - if ("production" !== "development") { - // IE8 has no API for event capturing and the `onScroll` event doesn't - // bubble. - ("production" !== "development" ? warning( - registrationName !== 'onScroll' || isEventSupported('scroll', true), - 'This browser doesn\'t support the `onScroll` event' - ) : null); - } - var container = ReactMount.findReactContainerForID(id); - if (container) { - var doc = container.nodeType === ELEMENT_NODE_TYPE ? - container.ownerDocument : - container; - listenTo(registrationName, doc); - } - transaction.getPutListenerQueue().enqueuePutListener( - id, - registrationName, - listener - ); -} - -// For HTML, certain tags should omit their close tag. We keep a whitelist for -// those special cased tags. - -var omittedCloseTags = { - 'area': true, - 'base': true, - 'br': true, - 'col': true, - 'embed': true, - 'hr': true, - 'img': true, - 'input': true, - 'keygen': true, - 'link': true, - 'meta': true, - 'param': true, - 'source': true, - 'track': true, - 'wbr': true - // NOTE: menuitem's close tag should be omitted, but that causes problems. -}; - -// We accept any tag to be rendered but since this gets injected into abitrary -// HTML, we want to make sure that it's a safe tag. -// http://www.w3.org/TR/REC-xml/#NT-Name - -var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset -var validatedTagCache = {}; -var hasOwnProperty = {}.hasOwnProperty; - -function validateDangerousTag(tag) { - if (!hasOwnProperty.call(validatedTagCache, tag)) { - ("production" !== "development" ? invariant(VALID_TAG_REGEX.test(tag), 'Invalid tag: %s', tag) : invariant(VALID_TAG_REGEX.test(tag))); - validatedTagCache[tag] = true; - } -} - -/** - * Creates a new React class that is idempotent and capable of containing other - * React components. It accepts event listeners and DOM properties that are - * valid according to `DOMProperty`. - * - * - Event listeners: `onClick`, `onMouseDown`, etc. - * - DOM properties: `className`, `name`, `title`, etc. - * - * The `style` property functions differently from the DOM API. It accepts an - * object mapping of style properties to values. - * - * @constructor ReactDOMComponent - * @extends ReactMultiChild - */ -function ReactDOMComponent(tag) { - validateDangerousTag(tag); - this._tag = tag; - this._renderedChildren = null; - this._previousStyleCopy = null; - this._rootNodeID = null; -} - -ReactDOMComponent.displayName = 'ReactDOMComponent'; - -ReactDOMComponent.Mixin = { - - construct: function(element) { - this._currentElement = element; - }, - - /** - * Generates root tag markup then recurses. This method has side effects and - * is not idempotent. - * - * @internal - * @param {string} rootID The root DOM ID for this node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} The computed markup. - */ - mountComponent: function(rootID, transaction, context) { - this._rootNodeID = rootID; - assertValidProps(this._currentElement.props); - var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>'; - return ( - this._createOpenTagMarkupAndPutListeners(transaction) + - this._createContentMarkup(transaction, context) + - closeTag - ); - }, - - /** - * Creates markup for the open tag and all attributes. - * - * This method has side effects because events get registered. - * - * Iterating over object properties is faster than iterating over arrays. - * @see http://jsperf.com/obj-vs-arr-iteration - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} Markup of opening tag. - */ - _createOpenTagMarkupAndPutListeners: function(transaction) { - var props = this._currentElement.props; - var ret = '<' + this._tag; - - for (var propKey in props) { - if (!props.hasOwnProperty(propKey)) { - continue; - } - var propValue = props[propKey]; - if (propValue == null) { - continue; - } - if (registrationNameModules.hasOwnProperty(propKey)) { - putListener(this._rootNodeID, propKey, propValue, transaction); - } else { - if (propKey === STYLE) { - if (propValue) { - propValue = this._previousStyleCopy = assign({}, props.style); - } - propValue = CSSPropertyOperations.createMarkupForStyles(propValue); - } - var markup = - DOMPropertyOperations.createMarkupForProperty(propKey, propValue); - if (markup) { - ret += ' ' + markup; - } - } - } - - // For static pages, no need to put React ID and checksum. Saves lots of - // bytes. - if (transaction.renderToStaticMarkup) { - return ret + '>'; - } - - var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); - return ret + ' ' + markupForID + '>'; - }, - - /** - * Creates markup for the content between the tags. - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} context - * @return {string} Content markup. - */ - _createContentMarkup: function(transaction, context) { - var prefix = ''; - if (this._tag === 'listing' || - this._tag === 'pre' || - this._tag === 'textarea') { - // Add an initial newline because browsers ignore the first newline in - // a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody. - prefix = '\n'; - } - - var props = this._currentElement.props; - - // Intentional use of != to avoid catching zero/false. - var innerHTML = props.dangerouslySetInnerHTML; - if (innerHTML != null) { - if (innerHTML.__html != null) { - return prefix + innerHTML.__html; - } - } else { - var contentToUse = - CONTENT_TYPES[typeof props.children] ? props.children : null; - var childrenToUse = contentToUse != null ? null : props.children; - if (contentToUse != null) { - return prefix + escapeTextContentForBrowser(contentToUse); - } else if (childrenToUse != null) { - var mountImages = this.mountChildren( - childrenToUse, - transaction, - context - ); - return prefix + mountImages.join(''); - } - } - return prefix; - }, - - receiveComponent: function(nextElement, transaction, context) { - var prevElement = this._currentElement; - this._currentElement = nextElement; - this.updateComponent(transaction, prevElement, nextElement, context); - }, - - /** - * Updates a native DOM component after it has already been allocated and - * attached to the DOM. Reconciles the root DOM node, then recurses. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevElement - * @param {ReactElement} nextElement - * @internal - * @overridable - */ - updateComponent: function(transaction, prevElement, nextElement, context) { - assertValidProps(this._currentElement.props); - this._updateDOMProperties(prevElement.props, transaction); - this._updateDOMChildren(prevElement.props, transaction, context); - }, - - /** - * Reconciles the properties by detecting differences in property values and - * updating the DOM as necessary. This function is probably the single most - * critical path for performance optimization. - * - * TODO: Benchmark whether checking for changed values in memory actually - * improves performance (especially statically positioned elements). - * TODO: Benchmark the effects of putting this at the top since 99% of props - * do not change for a given reconciliation. - * TODO: Benchmark areas that can be improved with caching. - * - * @private - * @param {object} lastProps - * @param {ReactReconcileTransaction} transaction - */ - _updateDOMProperties: function(lastProps, transaction) { - var nextProps = this._currentElement.props; - var propKey; - var styleName; - var styleUpdates; - for (propKey in lastProps) { - if (nextProps.hasOwnProperty(propKey) || - !lastProps.hasOwnProperty(propKey)) { - continue; - } - if (propKey === STYLE) { - var lastStyle = this._previousStyleCopy; - for (styleName in lastStyle) { - if (lastStyle.hasOwnProperty(styleName)) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - this._previousStyleCopy = null; - } else if (registrationNameModules.hasOwnProperty(propKey)) { - deleteListener(this._rootNodeID, propKey); - } else if ( - DOMProperty.isStandardName[propKey] || - DOMProperty.isCustomAttribute(propKey)) { - BackendIDOperations.deletePropertyByID( - this._rootNodeID, - propKey - ); - } - } - for (propKey in nextProps) { - var nextProp = nextProps[propKey]; - var lastProp = propKey === STYLE ? - this._previousStyleCopy : - lastProps[propKey]; - if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) { - continue; - } - if (propKey === STYLE) { - if (nextProp) { - nextProp = this._previousStyleCopy = assign({}, nextProp); - } else { - this._previousStyleCopy = null; - } - if (lastProp) { - // Unset styles on `lastProp` but not on `nextProp`. - for (styleName in lastProp) { - if (lastProp.hasOwnProperty(styleName) && - (!nextProp || !nextProp.hasOwnProperty(styleName))) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - // Update styles that changed since `lastProp`. - for (styleName in nextProp) { - if (nextProp.hasOwnProperty(styleName) && - lastProp[styleName] !== nextProp[styleName]) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = nextProp[styleName]; - } - } - } else { - // Relies on `updateStylesByID` not mutating `styleUpdates`. - styleUpdates = nextProp; - } - } else if (registrationNameModules.hasOwnProperty(propKey)) { - putListener(this._rootNodeID, propKey, nextProp, transaction); - } else if ( - DOMProperty.isStandardName[propKey] || - DOMProperty.isCustomAttribute(propKey)) { - BackendIDOperations.updatePropertyByID( - this._rootNodeID, - propKey, - nextProp - ); - } - } - if (styleUpdates) { - BackendIDOperations.updateStylesByID( - this._rootNodeID, - styleUpdates - ); - } - }, - - /** - * Reconciles the children with the various properties that affect the - * children content. - * - * @param {object} lastProps - * @param {ReactReconcileTransaction} transaction - */ - _updateDOMChildren: function(lastProps, transaction, context) { - var nextProps = this._currentElement.props; - - var lastContent = - CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; - var nextContent = - CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; - - var lastHtml = - lastProps.dangerouslySetInnerHTML && - lastProps.dangerouslySetInnerHTML.__html; - var nextHtml = - nextProps.dangerouslySetInnerHTML && - nextProps.dangerouslySetInnerHTML.__html; - - // Note the use of `!=` which checks for null or undefined. - var lastChildren = lastContent != null ? null : lastProps.children; - var nextChildren = nextContent != null ? null : nextProps.children; - - // If we're switching from children to content/html or vice versa, remove - // the old content - var lastHasContentOrHtml = lastContent != null || lastHtml != null; - var nextHasContentOrHtml = nextContent != null || nextHtml != null; - if (lastChildren != null && nextChildren == null) { - this.updateChildren(null, transaction, context); - } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { - this.updateTextContent(''); - } - - if (nextContent != null) { - if (lastContent !== nextContent) { - this.updateTextContent('' + nextContent); - } - } else if (nextHtml != null) { - if (lastHtml !== nextHtml) { - BackendIDOperations.updateInnerHTMLByID( - this._rootNodeID, - nextHtml - ); - } - } else if (nextChildren != null) { - this.updateChildren(nextChildren, transaction, context); - } - }, - - /** - * Destroys all event registrations for this instance. Does not remove from - * the DOM. That must be done by the parent. - * - * @internal - */ - unmountComponent: function() { - this.unmountChildren(); - ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID); - ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); - this._rootNodeID = null; - } - -}; - -ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', { - mountComponent: 'mountComponent', - updateComponent: 'updateComponent' -}); - -assign( - ReactDOMComponent.prototype, - ReactDOMComponent.Mixin, - ReactMultiChild.Mixin -); - -ReactDOMComponent.injection = { - injectIDOperations: function(IDOperations) { - ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations; - } -}; - -module.exports = ReactDOMComponent; - -},{"11":11,"12":12,"131":131,"150":150,"151":151,"157":157,"171":171,"29":29,"33":33,"40":40,"6":6,"77":77,"78":78,"82":82}],49:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMForm - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var LocalEventTrapMixin = _dereq_(27); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); - -var form = ReactElement.createFactory('form'); - -/** - * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need - * to capture it on the <form> element itself. There are lots of hacks we could - * do to accomplish this, but the most reliable is to make <form> a - * composite component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMForm = ReactClass.createClass({ - displayName: 'ReactDOMForm', - tagName: 'FORM', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - // TODO: Instead of using `ReactDOM` directly, we should use JSX. However, - // `jshint` fails to parse JSX so in order for linting to work in the open - // source repo, we need to just use `ReactDOM.form`. - return form(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset'); - this.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit'); - } -}); - -module.exports = ReactDOMForm; - -},{"16":16,"27":27,"32":32,"38":38,"63":63}],50:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMIDOperations - * @typechecks static-only - */ - -/*jslint evil: true */ - -'use strict'; - -var CSSPropertyOperations = _dereq_(6); -var DOMChildrenOperations = _dereq_(10); -var DOMPropertyOperations = _dereq_(12); -var ReactMount = _dereq_(77); -var ReactPerf = _dereq_(82); - -var invariant = _dereq_(150); -var setInnerHTML = _dereq_(164); - -/** - * Errors for properties that should not be updated with `updatePropertyById()`. - * - * @type {object} - * @private - */ -var INVALID_PROPERTY_ERRORS = { - dangerouslySetInnerHTML: - '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', - style: '`style` must be set using `updateStylesByID()`.' -}; - -/** - * Operations used to process updates to DOM nodes. This is made injectable via - * `ReactDOMComponent.BackendIDOperations`. - */ -var ReactDOMIDOperations = { - - /** - * Updates a DOM node with new property values. This should only be used to - * update DOM properties in `DOMProperty`. - * - * @param {string} id ID of the node to update. - * @param {string} name A valid property name, see `DOMProperty`. - * @param {*} value New value of the property. - * @internal - */ - updatePropertyByID: function(id, name, value) { - var node = ReactMount.getNode(id); - ("production" !== "development" ? invariant( - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), - 'updatePropertyByID(...): %s', - INVALID_PROPERTY_ERRORS[name] - ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); - - // If we're updating to null or undefined, we should remove the property - // from the DOM node instead of inadvertantly setting to a string. This - // brings us in line with the same behavior we have on initial render. - if (value != null) { - DOMPropertyOperations.setValueForProperty(node, name, value); - } else { - DOMPropertyOperations.deleteValueForProperty(node, name); - } - }, - - /** - * Updates a DOM node to remove a property. This should only be used to remove - * DOM properties in `DOMProperty`. - * - * @param {string} id ID of the node to update. - * @param {string} name A property name to remove, see `DOMProperty`. - * @internal - */ - deletePropertyByID: function(id, name, value) { - var node = ReactMount.getNode(id); - ("production" !== "development" ? invariant( - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), - 'updatePropertyByID(...): %s', - INVALID_PROPERTY_ERRORS[name] - ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); - DOMPropertyOperations.deleteValueForProperty(node, name, value); - }, - - /** - * Updates a DOM node with new style values. If a value is specified as '', - * the corresponding style property will be unset. - * - * @param {string} id ID of the node to update. - * @param {object} styles Mapping from styles to values. - * @internal - */ - updateStylesByID: function(id, styles) { - var node = ReactMount.getNode(id); - CSSPropertyOperations.setValueForStyles(node, styles); - }, - - /** - * Updates a DOM node's innerHTML. - * - * @param {string} id ID of the node to update. - * @param {string} html An HTML string. - * @internal - */ - updateInnerHTMLByID: function(id, html) { - var node = ReactMount.getNode(id); - setInnerHTML(node, html); - }, - - /** - * Updates a DOM node's text content set by `props.content`. - * - * @param {string} id ID of the node to update. - * @param {string} content Text content. - * @internal - */ - updateTextContentByID: function(id, content) { - var node = ReactMount.getNode(id); - DOMChildrenOperations.updateTextContent(node, content); - }, - - /** - * Replaces a DOM node that exists in the document with markup. - * - * @param {string} id ID of child to be replaced. - * @param {string} markup Dangerous markup to inject in place of child. - * @internal - * @see {Danger.dangerouslyReplaceNodeWithMarkup} - */ - dangerouslyReplaceNodeWithMarkupByID: function(id, markup) { - var node = ReactMount.getNode(id); - DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); - }, - - /** - * Updates a component's children by processing a series of updates. - * - * @param {array<object>} updates List of update configurations. - * @param {array<string>} markup List of markup strings. - * @internal - */ - dangerouslyProcessChildrenUpdates: function(updates, markup) { - for (var i = 0; i < updates.length; i++) { - updates[i].parentNode = ReactMount.getNode(updates[i].parentID); - } - DOMChildrenOperations.processUpdates(updates, markup); - } -}; - -ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', { - updatePropertyByID: 'updatePropertyByID', - deletePropertyByID: 'deletePropertyByID', - updateStylesByID: 'updateStylesByID', - updateInnerHTMLByID: 'updateInnerHTMLByID', - updateTextContentByID: 'updateTextContentByID', - dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID', - dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates' -}); - -module.exports = ReactDOMIDOperations; - -},{"10":10,"12":12,"150":150,"164":164,"6":6,"77":77,"82":82}],51:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMIframe - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var LocalEventTrapMixin = _dereq_(27); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); - -var iframe = ReactElement.createFactory('iframe'); - -/** - * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to - * capture it on the <iframe> element itself. There are lots of hacks we could - * do to accomplish this, but the most reliable is to make <iframe> a composite - * component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMIframe = ReactClass.createClass({ - displayName: 'ReactDOMIframe', - tagName: 'IFRAME', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - return iframe(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load'); - } -}); - -module.exports = ReactDOMIframe; - -},{"16":16,"27":27,"32":32,"38":38,"63":63}],52:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMImg - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var LocalEventTrapMixin = _dereq_(27); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); - -var img = ReactElement.createFactory('img'); - -/** - * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to - * capture it on the <img> element itself. There are lots of hacks we could do - * to accomplish this, but the most reliable is to make <img> a composite - * component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMImg = ReactClass.createClass({ - displayName: 'ReactDOMImg', - tagName: 'IMG', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - return img(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load'); - this.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error'); - } -}); - -module.exports = ReactDOMImg; - -},{"16":16,"27":27,"32":32,"38":38,"63":63}],53:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMInput - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var DOMPropertyOperations = _dereq_(12); -var LinkedValueUtils = _dereq_(26); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); -var ReactMount = _dereq_(77); -var ReactUpdates = _dereq_(100); - -var assign = _dereq_(29); -var invariant = _dereq_(150); - -var input = ReactElement.createFactory('input'); - -var instancesByReactID = {}; - -function forceUpdateIfMounted() { - /*jshint validthis:true */ - if (this.isMounted()) { - this.forceUpdate(); - } -} - -/** - * Implements an <input> native component that allows setting these optional - * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. - * - * If `checked` or `value` are not supplied (or null/undefined), user actions - * that affect the checked state or value will trigger updates to the element. - * - * If they are supplied (and not null/undefined), the rendered element will not - * trigger updates to the element. Instead, the props must change in order for - * the rendered element to be updated. - * - * The rendered element will be initialized as unchecked (or `defaultChecked`) - * with an empty value (or `defaultValue`). - * - * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html - */ -var ReactDOMInput = ReactClass.createClass({ - displayName: 'ReactDOMInput', - tagName: 'INPUT', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], - - getInitialState: function() { - var defaultValue = this.props.defaultValue; - return { - initialChecked: this.props.defaultChecked || false, - initialValue: defaultValue != null ? defaultValue : null - }; - }, - - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - props.defaultChecked = null; - props.defaultValue = null; - - var value = LinkedValueUtils.getValue(this); - props.value = value != null ? value : this.state.initialValue; - - var checked = LinkedValueUtils.getChecked(this); - props.checked = checked != null ? checked : this.state.initialChecked; - - props.onChange = this._handleChange; - - return input(props, this.props.children); - }, - - componentDidMount: function() { - var id = ReactMount.getID(this.getDOMNode()); - instancesByReactID[id] = this; - }, - - componentWillUnmount: function() { - var rootNode = this.getDOMNode(); - var id = ReactMount.getID(rootNode); - delete instancesByReactID[id]; - }, - - componentDidUpdate: function(prevProps, prevState, prevContext) { - var rootNode = this.getDOMNode(); - if (this.props.checked != null) { - DOMPropertyOperations.setValueForProperty( - rootNode, - 'checked', - this.props.checked || false - ); - } - - var value = LinkedValueUtils.getValue(this); - if (value != null) { - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - // Here we use asap to wait until all updates have propagated, which - // is important when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - ReactUpdates.asap(forceUpdateIfMounted, this); - - var name = this.props.name; - if (this.props.type === 'radio' && name != null) { - var rootNode = this.getDOMNode(); - var queryRoot = rootNode; - - while (queryRoot.parentNode) { - queryRoot = queryRoot.parentNode; - } - - // If `rootNode.form` was non-null, then we could try `form.elements`, - // but that sometimes behaves strangely in IE8. We could also try using - // `form.getElementsByName`, but that will only return direct children - // and won't include inputs that use the HTML5 `form=` attribute. Since - // the input might not even be in a form, let's just use the global - // `querySelectorAll` to ensure we don't miss anything. - var group = queryRoot.querySelectorAll( - 'input[name=' + JSON.stringify('' + name) + '][type="radio"]'); - - for (var i = 0, groupLen = group.length; i < groupLen; i++) { - var otherNode = group[i]; - if (otherNode === rootNode || - otherNode.form !== rootNode.form) { - continue; - } - var otherID = ReactMount.getID(otherNode); - ("production" !== "development" ? invariant( - otherID, - 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + - 'same `name` is not supported.' - ) : invariant(otherID)); - var otherInstance = instancesByReactID[otherID]; - ("production" !== "development" ? invariant( - otherInstance, - 'ReactDOMInput: Unknown radio button ID %s.', - otherID - ) : invariant(otherInstance)); - // If this is a controlled radio button group, forcing the input that - // was previously checked to update will cause it to be come re-checked - // as appropriate. - ReactUpdates.asap(forceUpdateIfMounted, otherInstance); - } - } - - return returnValue; - } - -}); - -module.exports = ReactDOMInput; - -},{"100":100,"12":12,"150":150,"2":2,"26":26,"29":29,"32":32,"38":38,"63":63,"77":77}],54:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMOption - */ - -'use strict'; - -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); - -var warning = _dereq_(171); - -var option = ReactElement.createFactory('option'); - -/** - * Implements an <option> native component that warns when `selected` is set. - */ -var ReactDOMOption = ReactClass.createClass({ - displayName: 'ReactDOMOption', - tagName: 'OPTION', - - mixins: [ReactBrowserComponentMixin], - - componentWillMount: function() { - // TODO (yungsters): Remove support for `selected` in <option>. - if ("production" !== "development") { - ("production" !== "development" ? warning( - this.props.selected == null, - 'Use the `defaultValue` or `value` props on <select> instead of ' + - 'setting `selected` on <option>.' - ) : null); - } - }, - - render: function() { - return option(this.props, this.props.children); - } - -}); - -module.exports = ReactDOMOption; - -},{"171":171,"32":32,"38":38,"63":63}],55:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMSelect - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var LinkedValueUtils = _dereq_(26); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); -var ReactUpdates = _dereq_(100); - -var assign = _dereq_(29); - -var select = ReactElement.createFactory('select'); - -function updateOptionsIfPendingUpdateAndMounted() { - /*jshint validthis:true */ - if (this._pendingUpdate) { - this._pendingUpdate = false; - var value = LinkedValueUtils.getValue(this); - if (value != null && this.isMounted()) { - updateOptions(this, value); - } - } -} - -/** - * Validation function for `value` and `defaultValue`. - * @private - */ -function selectValueType(props, propName, componentName) { - if (props[propName] == null) { - return null; - } - if (props.multiple) { - if (!Array.isArray(props[propName])) { - return new Error( - ("The `" + propName + "` prop supplied to <select> must be an array if ") + - ("`multiple` is true.") - ); - } - } else { - if (Array.isArray(props[propName])) { - return new Error( - ("The `" + propName + "` prop supplied to <select> must be a scalar ") + - ("value if `multiple` is false.") - ); - } - } -} - -/** - * @param {ReactComponent} component Instance of ReactDOMSelect - * @param {*} propValue A stringable (with `multiple`, a list of stringables). - * @private - */ -function updateOptions(component, propValue) { - var selectedValue, i, l; - var options = component.getDOMNode().options; - - if (component.props.multiple) { - selectedValue = {}; - for (i = 0, l = propValue.length; i < l; i++) { - selectedValue['' + propValue[i]] = true; - } - for (i = 0, l = options.length; i < l; i++) { - var selected = selectedValue.hasOwnProperty(options[i].value); - if (options[i].selected !== selected) { - options[i].selected = selected; - } - } - } else { - // Do not set `select.value` as exact behavior isn't consistent across all - // browsers for all cases. - selectedValue = '' + propValue; - for (i = 0, l = options.length; i < l; i++) { - if (options[i].value === selectedValue) { - options[i].selected = true; - return; - } - } - if (options.length) { - options[0].selected = true; - } - } -} - -/** - * Implements a <select> native component that allows optionally setting the - * props `value` and `defaultValue`. If `multiple` is false, the prop must be a - * stringable. If `multiple` is true, the prop must be an array of stringables. - * - * If `value` is not supplied (or null/undefined), user actions that change the - * selected option will trigger updates to the rendered options. - * - * If it is supplied (and not null/undefined), the rendered options will not - * update in response to user actions. Instead, the `value` prop must change in - * order for the rendered options to update. - * - * If `defaultValue` is provided, any options with the supplied values will be - * selected. - */ -var ReactDOMSelect = ReactClass.createClass({ - displayName: 'ReactDOMSelect', - tagName: 'SELECT', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], - - propTypes: { - defaultValue: selectValueType, - value: selectValueType - }, - - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - props.onChange = this._handleChange; - props.value = null; - - return select(props, this.props.children); - }, - - componentWillMount: function() { - this._pendingUpdate = false; - }, - - componentDidMount: function() { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - updateOptions(this, value); - } else if (this.props.defaultValue != null) { - updateOptions(this, this.props.defaultValue); - } - }, - - componentDidUpdate: function(prevProps) { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - this._pendingUpdate = false; - updateOptions(this, value); - } else if (!prevProps.multiple !== !this.props.multiple) { - // For simplicity, reapply `defaultValue` if `multiple` is toggled. - if (this.props.defaultValue != null) { - updateOptions(this, this.props.defaultValue); - } else { - // Revert the select back to its default unselected state. - updateOptions(this, this.props.multiple ? [] : ''); - } - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - - this._pendingUpdate = true; - ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); - return returnValue; - } - -}); - -module.exports = ReactDOMSelect; - -},{"100":100,"2":2,"26":26,"29":29,"32":32,"38":38,"63":63}],56:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMSelection - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); - -var getNodeForCharacterOffset = _dereq_(143); -var getTextContentAccessor = _dereq_(145); - -/** - * While `isCollapsed` is available on the Selection object and `collapsed` - * is available on the Range object, IE11 sometimes gets them wrong. - * If the anchor/focus nodes and offsets are the same, the range is collapsed. - */ -function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) { - return anchorNode === focusNode && anchorOffset === focusOffset; -} - -/** - * Get the appropriate anchor and focus node/offset pairs for IE. - * - * The catch here is that IE's selection API doesn't provide information - * about whether the selection is forward or backward, so we have to - * behave as though it's always forward. - * - * IE text differs from modern selection in that it behaves as though - * block elements end with a new line. This means character offsets will - * differ between the two APIs. - * - * @param {DOMElement} node - * @return {object} - */ -function getIEOffsets(node) { - var selection = document.selection; - var selectedRange = selection.createRange(); - var selectedLength = selectedRange.text.length; - - // Duplicate selection so we can move range without breaking user selection. - var fromStart = selectedRange.duplicate(); - fromStart.moveToElementText(node); - fromStart.setEndPoint('EndToStart', selectedRange); - - var startOffset = fromStart.text.length; - var endOffset = startOffset + selectedLength; - - return { - start: startOffset, - end: endOffset - }; -} - -/** - * @param {DOMElement} node - * @return {?object} - */ -function getModernOffsets(node) { - var selection = window.getSelection && window.getSelection(); - - if (!selection || selection.rangeCount === 0) { - return null; - } - - var anchorNode = selection.anchorNode; - var anchorOffset = selection.anchorOffset; - var focusNode = selection.focusNode; - var focusOffset = selection.focusOffset; - - var currentRange = selection.getRangeAt(0); - - // If the node and offset values are the same, the selection is collapsed. - // `Selection.isCollapsed` is available natively, but IE sometimes gets - // this value wrong. - var isSelectionCollapsed = isCollapsed( - selection.anchorNode, - selection.anchorOffset, - selection.focusNode, - selection.focusOffset - ); - - var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; - - var tempRange = currentRange.cloneRange(); - tempRange.selectNodeContents(node); - tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); - - var isTempRangeCollapsed = isCollapsed( - tempRange.startContainer, - tempRange.startOffset, - tempRange.endContainer, - tempRange.endOffset - ); - - var start = isTempRangeCollapsed ? 0 : tempRange.toString().length; - var end = start + rangeLength; - - // Detect whether the selection is backward. - var detectionRange = document.createRange(); - detectionRange.setStart(anchorNode, anchorOffset); - detectionRange.setEnd(focusNode, focusOffset); - var isBackward = detectionRange.collapsed; - - return { - start: isBackward ? end : start, - end: isBackward ? start : end - }; -} - -/** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setIEOffsets(node, offsets) { - var range = document.selection.createRange().duplicate(); - var start, end; - - if (typeof offsets.end === 'undefined') { - start = offsets.start; - end = start; - } else if (offsets.start > offsets.end) { - start = offsets.end; - end = offsets.start; - } else { - start = offsets.start; - end = offsets.end; - } - - range.moveToElementText(node); - range.moveStart('character', start); - range.setEndPoint('EndToStart', range); - range.moveEnd('character', end - start); - range.select(); -} - -/** - * In modern non-IE browsers, we can support both forward and backward - * selections. - * - * Note: IE10+ supports the Selection object, but it does not support - * the `extend` method, which means that even in modern IE, it's not possible - * to programatically create a backward selection. Thus, for all IE - * versions, we use the old IE API to create our selections. - * - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setModernOffsets(node, offsets) { - if (!window.getSelection) { - return; - } - - var selection = window.getSelection(); - var length = node[getTextContentAccessor()].length; - var start = Math.min(offsets.start, length); - var end = typeof offsets.end === 'undefined' ? - start : Math.min(offsets.end, length); - - // IE 11 uses modern selection, but doesn't support the extend method. - // Flip backward selections, so we can set with a single range. - if (!selection.extend && start > end) { - var temp = end; - end = start; - start = temp; - } - - var startMarker = getNodeForCharacterOffset(node, start); - var endMarker = getNodeForCharacterOffset(node, end); - - if (startMarker && endMarker) { - var range = document.createRange(); - range.setStart(startMarker.node, startMarker.offset); - selection.removeAllRanges(); - - if (start > end) { - selection.addRange(range); - selection.extend(endMarker.node, endMarker.offset); - } else { - range.setEnd(endMarker.node, endMarker.offset); - selection.addRange(range); - } - } -} - -var useIEOffsets = ( - ExecutionEnvironment.canUseDOM && - 'selection' in document && - !('getSelection' in window) -); - -var ReactDOMSelection = { - /** - * @param {DOMElement} node - */ - getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets, - - /** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ - setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets -}; - -module.exports = ReactDOMSelection; - -},{"143":143,"145":145,"22":22}],57:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMTextComponent - * @typechecks static-only - */ - -'use strict'; - -var DOMPropertyOperations = _dereq_(12); -var ReactComponentBrowserEnvironment = - _dereq_(40); -var ReactDOMComponent = _dereq_(48); - -var assign = _dereq_(29); -var escapeTextContentForBrowser = _dereq_(131); - -/** - * Text nodes violate a couple assumptions that React makes about components: - * - * - When mounting text into the DOM, adjacent text nodes are merged. - * - Text nodes cannot be assigned a React root ID. - * - * This component is used to wrap strings in elements so that they can undergo - * the same reconciliation that is applied to elements. - * - * TODO: Investigate representing React components in the DOM with text nodes. - * - * @class ReactDOMTextComponent - * @extends ReactComponent - * @internal - */ -var ReactDOMTextComponent = function(props) { - // This constructor and its argument is currently used by mocks. -}; - -assign(ReactDOMTextComponent.prototype, { - - /** - * @param {ReactText} text - * @internal - */ - construct: function(text) { - // TODO: This is really a ReactText (ReactNode), not a ReactElement - this._currentElement = text; - this._stringText = '' + text; - - // Properties - this._rootNodeID = null; - this._mountIndex = 0; - }, - - /** - * Creates the markup for this text node. This node is not intended to have - * any features besides containing text content. - * - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} Markup for this text node. - * @internal - */ - mountComponent: function(rootID, transaction, context) { - this._rootNodeID = rootID; - var escapedText = escapeTextContentForBrowser(this._stringText); - - if (transaction.renderToStaticMarkup) { - // Normally we'd wrap this in a `span` for the reasons stated above, but - // since this is a situation where React won't take over (static pages), - // we can simply return the text as it is. - return escapedText; - } - - return ( - '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + - escapedText + - '</span>' - ); - }, - - /** - * Updates this component by updating the text content. - * - * @param {ReactText} nextText The next text content - * @param {ReactReconcileTransaction} transaction - * @internal - */ - receiveComponent: function(nextText, transaction) { - if (nextText !== this._currentElement) { - this._currentElement = nextText; - var nextStringText = '' + nextText; - if (nextStringText !== this._stringText) { - // TODO: Save this as pending props and use performUpdateIfNecessary - // and/or updateComponent to do the actual update for consistency with - // other component types? - this._stringText = nextStringText; - ReactDOMComponent.BackendIDOperations.updateTextContentByID( - this._rootNodeID, - nextStringText - ); - } - } - }, - - unmountComponent: function() { - ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); - } - -}); - -module.exports = ReactDOMTextComponent; - -},{"12":12,"131":131,"29":29,"40":40,"48":48}],58:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMTextarea - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var DOMPropertyOperations = _dereq_(12); -var LinkedValueUtils = _dereq_(26); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); -var ReactUpdates = _dereq_(100); - -var assign = _dereq_(29); -var invariant = _dereq_(150); - -var warning = _dereq_(171); - -var textarea = ReactElement.createFactory('textarea'); - -function forceUpdateIfMounted() { - /*jshint validthis:true */ - if (this.isMounted()) { - this.forceUpdate(); - } -} - -/** - * Implements a <textarea> native component that allows setting `value`, and - * `defaultValue`. This differs from the traditional DOM API because value is - * usually set as PCDATA children. - * - * If `value` is not supplied (or null/undefined), user actions that affect the - * value will trigger updates to the element. - * - * If `value` is supplied (and not null/undefined), the rendered element will - * not trigger updates to the element. Instead, the `value` prop must change in - * order for the rendered element to be updated. - * - * The rendered element will be initialized with an empty value, the prop - * `defaultValue` if specified, or the children content (deprecated). - */ -var ReactDOMTextarea = ReactClass.createClass({ - displayName: 'ReactDOMTextarea', - tagName: 'TEXTAREA', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], - - getInitialState: function() { - var defaultValue = this.props.defaultValue; - // TODO (yungsters): Remove support for children content in <textarea>. - var children = this.props.children; - if (children != null) { - if ("production" !== "development") { - ("production" !== "development" ? warning( - false, - 'Use the `defaultValue` or `value` props instead of setting ' + - 'children on <textarea>.' - ) : null); - } - ("production" !== "development" ? invariant( - defaultValue == null, - 'If you supply `defaultValue` on a <textarea>, do not pass children.' - ) : invariant(defaultValue == null)); - if (Array.isArray(children)) { - ("production" !== "development" ? invariant( - children.length <= 1, - '<textarea> can only have at most one child.' - ) : invariant(children.length <= 1)); - children = children[0]; - } - - defaultValue = '' + children; - } - if (defaultValue == null) { - defaultValue = ''; - } - var value = LinkedValueUtils.getValue(this); - return { - // We save the initial value so that `ReactDOMComponent` doesn't update - // `textContent` (unnecessary since we update value). - // The initial value can be a boolean or object so that's why it's - // forced to be a string. - initialValue: '' + (value != null ? value : defaultValue) - }; - }, - - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - ("production" !== "development" ? invariant( - props.dangerouslySetInnerHTML == null, - '`dangerouslySetInnerHTML` does not make sense on <textarea>.' - ) : invariant(props.dangerouslySetInnerHTML == null)); - - props.defaultValue = null; - props.value = null; - props.onChange = this._handleChange; - - // Always set children to the same thing. In IE9, the selection range will - // get reset if `textContent` is mutated. - return textarea(props, this.state.initialValue); - }, - - componentDidUpdate: function(prevProps, prevState, prevContext) { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - var rootNode = this.getDOMNode(); - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - ReactUpdates.asap(forceUpdateIfMounted, this); - return returnValue; - } - -}); - -module.exports = ReactDOMTextarea; - -},{"100":100,"12":12,"150":150,"171":171,"2":2,"26":26,"29":29,"32":32,"38":38,"63":63}],59:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultBatchingStrategy - */ - -'use strict'; - -var ReactUpdates = _dereq_(100); -var Transaction = _dereq_(116); - -var assign = _dereq_(29); -var emptyFunction = _dereq_(129); - -var RESET_BATCHED_UPDATES = { - initialize: emptyFunction, - close: function() { - ReactDefaultBatchingStrategy.isBatchingUpdates = false; - } -}; - -var FLUSH_BATCHED_UPDATES = { - initialize: emptyFunction, - close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates) -}; - -var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES]; - -function ReactDefaultBatchingStrategyTransaction() { - this.reinitializeTransaction(); -} - -assign( - ReactDefaultBatchingStrategyTransaction.prototype, - Transaction.Mixin, - { - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - } - } -); - -var transaction = new ReactDefaultBatchingStrategyTransaction(); - -var ReactDefaultBatchingStrategy = { - isBatchingUpdates: false, - - /** - * Call the provided function in a context within which calls to `setState` - * and friends are batched such that components aren't updated unnecessarily. - */ - batchedUpdates: function(callback, a, b, c, d) { - var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; - - ReactDefaultBatchingStrategy.isBatchingUpdates = true; - - // The code is written this way to avoid extra allocations - if (alreadyBatchingUpdates) { - callback(a, b, c, d); - } else { - transaction.perform(callback, null, a, b, c, d); - } - } -}; - -module.exports = ReactDefaultBatchingStrategy; - -},{"100":100,"116":116,"129":129,"29":29}],60:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultInjection - */ - -'use strict'; - -var BeforeInputEventPlugin = _dereq_(3); -var ChangeEventPlugin = _dereq_(8); -var ClientReactRootIndex = _dereq_(9); -var DefaultEventPluginOrder = _dereq_(14); -var EnterLeaveEventPlugin = _dereq_(15); -var ExecutionEnvironment = _dereq_(22); -var HTMLDOMPropertyConfig = _dereq_(24); -var MobileSafariClickEventPlugin = _dereq_(28); -var ReactBrowserComponentMixin = _dereq_(32); -var ReactClass = _dereq_(38); -var ReactComponentBrowserEnvironment = - _dereq_(40); -var ReactDefaultBatchingStrategy = _dereq_(59); -var ReactDOMComponent = _dereq_(48); -var ReactDOMButton = _dereq_(47); -var ReactDOMForm = _dereq_(49); -var ReactDOMImg = _dereq_(52); -var ReactDOMIDOperations = _dereq_(50); -var ReactDOMIframe = _dereq_(51); -var ReactDOMInput = _dereq_(53); -var ReactDOMOption = _dereq_(54); -var ReactDOMSelect = _dereq_(55); -var ReactDOMTextarea = _dereq_(58); -var ReactDOMTextComponent = _dereq_(57); -var ReactElement = _dereq_(63); -var ReactEventListener = _dereq_(68); -var ReactInjection = _dereq_(70); -var ReactInstanceHandles = _dereq_(72); -var ReactMount = _dereq_(77); -var ReactReconcileTransaction = _dereq_(88); -var SelectEventPlugin = _dereq_(102); -var ServerReactRootIndex = _dereq_(103); -var SimpleEventPlugin = _dereq_(104); -var SVGDOMPropertyConfig = _dereq_(101); - -var createFullPageComponent = _dereq_(125); - -function autoGenerateWrapperClass(type) { - return ReactClass.createClass({ - tagName: type.toUpperCase(), - render: function() { - return new ReactElement( - type, - null, - null, - null, - null, - this.props - ); - } - }); -} - -function inject() { - ReactInjection.EventEmitter.injectReactEventListener( - ReactEventListener - ); - - /** - * Inject modules for resolving DOM hierarchy and plugin ordering. - */ - ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); - ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles); - ReactInjection.EventPluginHub.injectMount(ReactMount); - - /** - * Some important event plugins included by default (without having to require - * them). - */ - ReactInjection.EventPluginHub.injectEventPluginsByName({ - SimpleEventPlugin: SimpleEventPlugin, - EnterLeaveEventPlugin: EnterLeaveEventPlugin, - ChangeEventPlugin: ChangeEventPlugin, - MobileSafariClickEventPlugin: MobileSafariClickEventPlugin, - SelectEventPlugin: SelectEventPlugin, - BeforeInputEventPlugin: BeforeInputEventPlugin - }); - - ReactInjection.NativeComponent.injectGenericComponentClass( - ReactDOMComponent - ); - - ReactInjection.NativeComponent.injectTextComponentClass( - ReactDOMTextComponent - ); - - ReactInjection.NativeComponent.injectAutoWrapper( - autoGenerateWrapperClass - ); - - // This needs to happen before createFullPageComponent() otherwise the mixin - // won't be included. - ReactInjection.Class.injectMixin(ReactBrowserComponentMixin); - - ReactInjection.NativeComponent.injectComponentClasses({ - 'button': ReactDOMButton, - 'form': ReactDOMForm, - 'iframe': ReactDOMIframe, - 'img': ReactDOMImg, - 'input': ReactDOMInput, - 'option': ReactDOMOption, - 'select': ReactDOMSelect, - 'textarea': ReactDOMTextarea, - - 'html': createFullPageComponent('html'), - 'head': createFullPageComponent('head'), - 'body': createFullPageComponent('body') - }); - - ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); - ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); - - ReactInjection.EmptyComponent.injectEmptyComponent('noscript'); - - ReactInjection.Updates.injectReconcileTransaction( - ReactReconcileTransaction - ); - ReactInjection.Updates.injectBatchingStrategy( - ReactDefaultBatchingStrategy - ); - - ReactInjection.RootIndex.injectCreateReactRootIndex( - ExecutionEnvironment.canUseDOM ? - ClientReactRootIndex.createReactRootIndex : - ServerReactRootIndex.createReactRootIndex - ); - - ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); - ReactInjection.DOMComponent.injectIDOperations(ReactDOMIDOperations); - - if ("production" !== "development") { - var url = (ExecutionEnvironment.canUseDOM && window.location.href) || ''; - if ((/[?&]react_perf\b/).test(url)) { - var ReactDefaultPerf = _dereq_(61); - ReactDefaultPerf.start(); - } - } -} - -module.exports = { - inject: inject -}; - -},{"101":101,"102":102,"103":103,"104":104,"125":125,"14":14,"15":15,"22":22,"24":24,"28":28,"3":3,"32":32,"38":38,"40":40,"47":47,"48":48,"49":49,"50":50,"51":51,"52":52,"53":53,"54":54,"55":55,"57":57,"58":58,"59":59,"61":61,"63":63,"68":68,"70":70,"72":72,"77":77,"8":8,"88":88,"9":9}],61:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultPerf - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = _dereq_(11); -var ReactDefaultPerfAnalysis = _dereq_(62); -var ReactMount = _dereq_(77); -var ReactPerf = _dereq_(82); - -var performanceNow = _dereq_(162); - -function roundFloat(val) { - return Math.floor(val * 100) / 100; -} - -function addValue(obj, key, val) { - obj[key] = (obj[key] || 0) + val; -} - -var ReactDefaultPerf = { - _allMeasurements: [], // last item in the list is the current one - _mountStack: [0], - _injected: false, - - start: function() { - if (!ReactDefaultPerf._injected) { - ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); - } - - ReactDefaultPerf._allMeasurements.length = 0; - ReactPerf.enableMeasure = true; - }, - - stop: function() { - ReactPerf.enableMeasure = false; - }, - - getLastMeasurements: function() { - return ReactDefaultPerf._allMeasurements; - }, - - printExclusive: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); - console.table(summary.map(function(item) { - return { - 'Component class name': item.componentName, - 'Total inclusive time (ms)': roundFloat(item.inclusive), - 'Exclusive mount time (ms)': roundFloat(item.exclusive), - 'Exclusive render time (ms)': roundFloat(item.render), - 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count), - 'Render time per instance (ms)': roundFloat(item.render / item.count), - 'Instances': item.count - }; - })); - // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct - // number. - }, - - printInclusive: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); - console.table(summary.map(function(item) { - return { - 'Owner > component': item.componentName, - 'Inclusive time (ms)': roundFloat(item.time), - 'Instances': item.count - }; - })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - getMeasurementsSummaryMap: function(measurements) { - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( - measurements, - true - ); - return summary.map(function(item) { - return { - 'Owner > component': item.componentName, - 'Wasted time (ms)': item.time, - 'Instances': item.count - }; - }); - }, - - printWasted: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements)); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - printDOM: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); - console.table(summary.map(function(item) { - var result = {}; - result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; - result['type'] = item.type; - result['args'] = JSON.stringify(item.args); - return result; - })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - _recordWrite: function(id, fnName, totalTime, args) { - // TODO: totalTime isn't that useful since it doesn't count paints/reflows - var writes = - ReactDefaultPerf - ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] - .writes; - writes[id] = writes[id] || []; - writes[id].push({ - type: fnName, - time: totalTime, - args: args - }); - }, - - measure: function(moduleName, fnName, func) { - return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - var totalTime; - var rv; - var start; - - if (fnName === '_renderNewRootComponent' || - fnName === 'flushBatchedUpdates') { - // A "measurement" is a set of metrics recorded for each flush. We want - // to group the metrics for a given flush together so we can look at the - // components that rendered and the DOM operations that actually - // happened to determine the amount of "wasted work" performed. - ReactDefaultPerf._allMeasurements.push({ - exclusive: {}, - inclusive: {}, - render: {}, - counts: {}, - writes: {}, - displayNames: {}, - totalTime: 0 - }); - start = performanceNow(); - rv = func.apply(this, args); - ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ].totalTime = performanceNow() - start; - return rv; - } else if (fnName === '_mountImageIntoNode' || - moduleName === 'ReactDOMIDOperations') { - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (fnName === '_mountImageIntoNode') { - var mountID = ReactMount.getID(args[1]); - ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); - } else if (fnName === 'dangerouslyProcessChildrenUpdates') { - // special format - args[0].forEach(function(update) { - var writeArgs = {}; - if (update.fromIndex !== null) { - writeArgs.fromIndex = update.fromIndex; - } - if (update.toIndex !== null) { - writeArgs.toIndex = update.toIndex; - } - if (update.textContent !== null) { - writeArgs.textContent = update.textContent; - } - if (update.markupIndex !== null) { - writeArgs.markup = args[1][update.markupIndex]; - } - ReactDefaultPerf._recordWrite( - update.parentID, - update.type, - totalTime, - writeArgs - ); - }); - } else { - // basic format - ReactDefaultPerf._recordWrite( - args[0], - fnName, - totalTime, - Array.prototype.slice.call(args, 1) - ); - } - return rv; - } else if (moduleName === 'ReactCompositeComponent' && ( - (// TODO: receiveComponent()? - (fnName === 'mountComponent' || - fnName === 'updateComponent' || fnName === '_renderValidatedComponent')))) { - - if (typeof this._currentElement.type === 'string') { - return func.apply(this, args); - } - - var rootNodeID = fnName === 'mountComponent' ? - args[0] : - this._rootNodeID; - var isRender = fnName === '_renderValidatedComponent'; - var isMount = fnName === 'mountComponent'; - - var mountStack = ReactDefaultPerf._mountStack; - var entry = ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ]; - - if (isRender) { - addValue(entry.counts, rootNodeID, 1); - } else if (isMount) { - mountStack.push(0); - } - - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (isRender) { - addValue(entry.render, rootNodeID, totalTime); - } else if (isMount) { - var subMountTime = mountStack.pop(); - mountStack[mountStack.length - 1] += totalTime; - addValue(entry.exclusive, rootNodeID, totalTime - subMountTime); - addValue(entry.inclusive, rootNodeID, totalTime); - } else { - addValue(entry.inclusive, rootNodeID, totalTime); - } - - entry.displayNames[rootNodeID] = { - current: this.getName(), - owner: this._currentElement._owner ? - this._currentElement._owner.getName() : - '<root>' - }; - - return rv; - } else { - return func.apply(this, args); - } - }; - } -}; - -module.exports = ReactDefaultPerf; - -},{"11":11,"162":162,"62":62,"77":77,"82":82}],62:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultPerfAnalysis - */ - -var assign = _dereq_(29); - -// Don't try to save users less than 1.2ms (a number I made up) -var DONT_CARE_THRESHOLD = 1.2; -var DOM_OPERATION_TYPES = { - '_mountImageIntoNode': 'set innerHTML', - INSERT_MARKUP: 'set innerHTML', - MOVE_EXISTING: 'move', - REMOVE_NODE: 'remove', - TEXT_CONTENT: 'set textContent', - 'updatePropertyByID': 'update attribute', - 'deletePropertyByID': 'delete attribute', - 'updateStylesByID': 'update styles', - 'updateInnerHTMLByID': 'set innerHTML', - 'dangerouslyReplaceNodeWithMarkupByID': 'replace' -}; - -function getTotalTime(measurements) { - // TODO: return number of DOM ops? could be misleading. - // TODO: measure dropped frames after reconcile? - // TODO: log total time of each reconcile and the top-level component - // class that triggered it. - var totalTime = 0; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - totalTime += measurement.totalTime; - } - return totalTime; -} - -function getDOMSummary(measurements) { - var items = []; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var id; - - for (id in measurement.writes) { - measurement.writes[id].forEach(function(write) { - items.push({ - id: id, - type: DOM_OPERATION_TYPES[write.type] || write.type, - args: write.args - }); - }); - } - } - return items; -} - -function getExclusiveSummary(measurements) { - var candidates = {}; - var displayName; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); - - for (var id in allIDs) { - displayName = measurement.displayNames[id].current; - - candidates[displayName] = candidates[displayName] || { - componentName: displayName, - inclusive: 0, - exclusive: 0, - render: 0, - count: 0 - }; - if (measurement.render[id]) { - candidates[displayName].render += measurement.render[id]; - } - if (measurement.exclusive[id]) { - candidates[displayName].exclusive += measurement.exclusive[id]; - } - if (measurement.inclusive[id]) { - candidates[displayName].inclusive += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[displayName].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (displayName in candidates) { - if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { - arr.push(candidates[displayName]); - } - } - - arr.sort(function(a, b) { - return b.exclusive - a.exclusive; - }); - - return arr; -} - -function getInclusiveSummary(measurements, onlyClean) { - var candidates = {}; - var inclusiveKey; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); - var cleanComponents; - - if (onlyClean) { - cleanComponents = getUnchangedComponents(measurement); - } - - for (var id in allIDs) { - if (onlyClean && !cleanComponents[id]) { - continue; - } - - var displayName = measurement.displayNames[id]; - - // Inclusive time is not useful for many components without knowing where - // they are instantiated. So we aggregate inclusive time with both the - // owner and current displayName as the key. - inclusiveKey = displayName.owner + ' > ' + displayName.current; - - candidates[inclusiveKey] = candidates[inclusiveKey] || { - componentName: inclusiveKey, - time: 0, - count: 0 - }; - - if (measurement.inclusive[id]) { - candidates[inclusiveKey].time += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[inclusiveKey].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (inclusiveKey in candidates) { - if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { - arr.push(candidates[inclusiveKey]); - } - } - - arr.sort(function(a, b) { - return b.time - a.time; - }); - - return arr; -} - -function getUnchangedComponents(measurement) { - // For a given reconcile, look at which components did not actually - // render anything to the DOM and return a mapping of their ID to - // the amount of time it took to render the entire subtree. - var cleanComponents = {}; - var dirtyLeafIDs = Object.keys(measurement.writes); - var allIDs = assign({}, measurement.exclusive, measurement.inclusive); - - for (var id in allIDs) { - var isDirty = false; - // For each component that rendered, see if a component that triggered - // a DOM op is in its subtree. - for (var i = 0; i < dirtyLeafIDs.length; i++) { - if (dirtyLeafIDs[i].indexOf(id) === 0) { - isDirty = true; - break; - } - } - if (!isDirty && measurement.counts[id] > 0) { - cleanComponents[id] = true; - } - } - return cleanComponents; -} - -var ReactDefaultPerfAnalysis = { - getExclusiveSummary: getExclusiveSummary, - getInclusiveSummary: getInclusiveSummary, - getDOMSummary: getDOMSummary, - getTotalTime: getTotalTime -}; - -module.exports = ReactDefaultPerfAnalysis; - -},{"29":29}],63:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactElement - */ - -'use strict'; - -var ReactContext = _dereq_(44); -var ReactCurrentOwner = _dereq_(45); - -var assign = _dereq_(29); -var warning = _dereq_(171); - -var RESERVED_PROPS = { - key: true, - ref: true -}; - -/** - * Warn for mutations. - * - * @internal - * @param {object} object - * @param {string} key - */ -function defineWarningProperty(object, key) { - Object.defineProperty(object, key, { - - configurable: false, - enumerable: true, - - get: function() { - if (!this._store) { - return null; - } - return this._store[key]; - }, - - set: function(value) { - ("production" !== "development" ? warning( - false, - 'Don\'t set the %s property of the React element. Instead, ' + - 'specify the correct value when initially creating the element.', - key - ) : null); - this._store[key] = value; - } - - }); -} - -/** - * This is updated to true if the membrane is successfully created. - */ -var useMutationMembrane = false; - -/** - * Warn for mutations. - * - * @internal - * @param {object} element - */ -function defineMutationMembrane(prototype) { - try { - var pseudoFrozenProperties = { - props: true - }; - for (var key in pseudoFrozenProperties) { - defineWarningProperty(prototype, key); - } - useMutationMembrane = true; - } catch (x) { - // IE will fail on defineProperty - } -} - -/** - * Base constructor for all React elements. This is only used to make this - * work with a dynamic instanceof check. Nothing should live on this prototype. - * - * @param {*} type - * @param {string|object} ref - * @param {*} key - * @param {*} props - * @internal - */ -var ReactElement = function(type, key, ref, owner, context, props) { - // Built-in properties that belong on the element - this.type = type; - this.key = key; - this.ref = ref; - - // Record the component responsible for creating this element. - this._owner = owner; - - // TODO: Deprecate withContext, and then the context becomes accessible - // through the owner. - this._context = context; - - if ("production" !== "development") { - // The validation flag and props are currently mutative. We put them on - // an external backing store so that we can freeze the whole object. - // This can be replaced with a WeakMap once they are implemented in - // commonly used development environments. - this._store = {props: props, originalProps: assign({}, props)}; - - // To make comparing ReactElements easier for testing purposes, we make - // the validation flag non-enumerable (where possible, which should - // include every environment we run tests in), so the test framework - // ignores it. - try { - Object.defineProperty(this._store, 'validated', { - configurable: false, - enumerable: false, - writable: true - }); - } catch (x) { - } - this._store.validated = false; - - // We're not allowed to set props directly on the object so we early - // return and rely on the prototype membrane to forward to the backing - // store. - if (useMutationMembrane) { - Object.freeze(this); - return; - } - } - - this.props = props; -}; - -// We intentionally don't expose the function on the constructor property. -// ReactElement should be indistinguishable from a plain object. -ReactElement.prototype = { - _isReactElement: true -}; - -if ("production" !== "development") { - defineMutationMembrane(ReactElement.prototype); -} - -ReactElement.createElement = function(type, config, children) { - var propName; - - // Reserved names are extracted - var props = {}; - - var key = null; - var ref = null; - - if (config != null) { - ref = config.ref === undefined ? null : config.ref; - key = config.key === undefined ? null : '' + config.key; - // Remaining properties are added to a new props object - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - // Resolve default props - if (type && type.defaultProps) { - var defaultProps = type.defaultProps; - for (propName in defaultProps) { - if (typeof props[propName] === 'undefined') { - props[propName] = defaultProps[propName]; - } - } - } - - return new ReactElement( - type, - key, - ref, - ReactCurrentOwner.current, - ReactContext.current, - props - ); -}; - -ReactElement.createFactory = function(type) { - var factory = ReactElement.createElement.bind(null, type); - // Expose the type on the factory and the prototype so that it can be - // easily accessed on elements. E.g. <Foo />.type === Foo.type. - // This should not be named `constructor` since this may not be the function - // that created the element, and it may not even be a constructor. - // Legacy hook TODO: Warn if this is accessed - factory.type = type; - return factory; -}; - -ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { - var newElement = new ReactElement( - oldElement.type, - oldElement.key, - oldElement.ref, - oldElement._owner, - oldElement._context, - newProps - ); - - if ("production" !== "development") { - // If the key on the original is valid, then the clone is valid - newElement._store.validated = oldElement._store.validated; - } - return newElement; -}; - -ReactElement.cloneElement = function(element, config, children) { - var propName; - - // Original props are copied - var props = assign({}, element.props); - - // Reserved names are extracted - var key = element.key; - var ref = element.ref; - - // Owner will be preserved, unless ref is overridden - var owner = element._owner; - - if (config != null) { - if (config.ref !== undefined) { - // Silently steal the ref from the parent. - ref = config.ref; - owner = ReactCurrentOwner.current; - } - if (config.key !== undefined) { - key = '' + config.key; - } - // Remaining properties override existing props - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - return new ReactElement( - element.type, - key, - ref, - owner, - element._context, - props - ); -}; - -/** - * @param {?object} object - * @return {boolean} True if `object` is a valid component. - * @final - */ -ReactElement.isValidElement = function(object) { - // ReactTestUtils is often used outside of beforeEach where as React is - // within it. This leads to two different instances of React on the same - // page. To identify a element from a different React instance we use - // a flag instead of an instanceof check. - var isElement = !!(object && object._isReactElement); - // if (isElement && !(object instanceof ReactElement)) { - // This is an indicator that you're using multiple versions of React at the - // same time. This will screw with ownership and stuff. Fix it, please. - // TODO: We could possibly warn here. - // } - return isElement; -}; - -module.exports = ReactElement; - -},{"171":171,"29":29,"44":44,"45":45}],64:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactElementValidator - */ - -/** - * ReactElementValidator provides a wrapper around a element factory - * which validates the props passed to the element. This is intended to be - * used only in DEV and could be replaced by a static type checker for languages - * that support it. - */ - -'use strict'; - -var ReactElement = _dereq_(63); -var ReactFragment = _dereq_(69); -var ReactPropTypeLocations = _dereq_(85); -var ReactPropTypeLocationNames = _dereq_(84); -var ReactCurrentOwner = _dereq_(45); -var ReactNativeComponent = _dereq_(80); - -var getIteratorFn = _dereq_(141); -var invariant = _dereq_(150); -var warning = _dereq_(171); - -function getDeclarationErrorAddendum() { - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Warn if there's no key explicitly set on dynamic arrays of children or - * object keys are not valid. This allows us to keep track of children between - * updates. - */ -var ownerHasKeyUseWarning = {}; - -var loggedTypeFailures = {}; - -var NUMERIC_PROPERTY_REGEX = /^\d+$/; - -/** - * Gets the instance's name for use in warnings. - * - * @internal - * @return {?string} Display name or undefined - */ -function getName(instance) { - var publicInstance = instance && instance.getPublicInstance(); - if (!publicInstance) { - return undefined; - } - var constructor = publicInstance.constructor; - if (!constructor) { - return undefined; - } - return constructor.displayName || constructor.name || undefined; -} - -/** - * Gets the current owner's displayName for use in warnings. - * - * @internal - * @return {?string} Display name or undefined - */ -function getCurrentOwnerDisplayName() { - var current = ReactCurrentOwner.current; - return ( - current && getName(current) || undefined - ); -} - -/** - * Warn if the element doesn't have an explicit key assigned to it. - * This element is in an array. The array could grow and shrink or be - * reordered. All children that haven't already been validated are required to - * have a "key" property assigned to it. - * - * @internal - * @param {ReactElement} element Element that requires a key. - * @param {*} parentType element's parent's type. - */ -function validateExplicitKey(element, parentType) { - if (element._store.validated || element.key != null) { - return; - } - element._store.validated = true; - - warnAndMonitorForKeyUse( - 'Each child in an array or iterator should have a unique "key" prop.', - element, - parentType - ); -} - -/** - * Warn if the key is being defined as an object property but has an incorrect - * value. - * - * @internal - * @param {string} name Property name of the key. - * @param {ReactElement} element Component that requires a key. - * @param {*} parentType element's parent's type. - */ -function validatePropertyKey(name, element, parentType) { - if (!NUMERIC_PROPERTY_REGEX.test(name)) { - return; - } - warnAndMonitorForKeyUse( - 'Child objects should have non-numeric keys so ordering is preserved.', - element, - parentType - ); -} - -/** - * Shared warning and monitoring code for the key warnings. - * - * @internal - * @param {string} message The base warning that gets output. - * @param {ReactElement} element Component that requires a key. - * @param {*} parentType element's parent's type. - */ -function warnAndMonitorForKeyUse(message, element, parentType) { - var ownerName = getCurrentOwnerDisplayName(); - var parentName = typeof parentType === 'string' ? - parentType : parentType.displayName || parentType.name; - - var useName = ownerName || parentName; - var memoizer = ownerHasKeyUseWarning[message] || ( - (ownerHasKeyUseWarning[message] = {}) - ); - if (memoizer.hasOwnProperty(useName)) { - return; - } - memoizer[useName] = true; - - var parentOrOwnerAddendum = - ownerName ? (" Check the render method of " + ownerName + ".") : - parentName ? (" Check the React.render call using <" + parentName + ">.") : - ''; - - // Usually the current owner is the offender, but if it accepts children as a - // property, it may be the creator of the child that's responsible for - // assigning it a key. - var childOwnerAddendum = ''; - if (element && - element._owner && - element._owner !== ReactCurrentOwner.current) { - // Name of the component that originally created this child. - var childOwnerName = getName(element._owner); - - childOwnerAddendum = (" It was passed a child from " + childOwnerName + "."); - } - - ("production" !== "development" ? warning( - false, - message + '%s%s See https://fb.me/react-warning-keys for more information.', - parentOrOwnerAddendum, - childOwnerAddendum - ) : null); -} - -/** - * Ensure that every element either is passed in a static location, in an - * array with an explicit keys property defined, or in an object literal - * with valid key property. - * - * @internal - * @param {ReactNode} node Statically passed child of any type. - * @param {*} parentType node's parent's type. - */ -function validateChildKeys(node, parentType) { - if (Array.isArray(node)) { - for (var i = 0; i < node.length; i++) { - var child = node[i]; - if (ReactElement.isValidElement(child)) { - validateExplicitKey(child, parentType); - } - } - } else if (ReactElement.isValidElement(node)) { - // This element was passed in a valid location. - node._store.validated = true; - } else if (node) { - var iteratorFn = getIteratorFn(node); - // Entry iterators provide implicit keys. - if (iteratorFn) { - if (iteratorFn !== node.entries) { - var iterator = iteratorFn.call(node); - var step; - while (!(step = iterator.next()).done) { - if (ReactElement.isValidElement(step.value)) { - validateExplicitKey(step.value, parentType); - } - } - } - } else if (typeof node === 'object') { - var fragment = ReactFragment.extractIfFragment(node); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - validatePropertyKey(key, fragment[key], parentType); - } - } - } - } -} - -/** - * Assert that the props are valid - * - * @param {string} componentName Name of the component for error messages. - * @param {object} propTypes Map of prop name to a ReactPropType - * @param {object} props - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ -function checkPropTypes(componentName, propTypes, props, location) { - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - ("production" !== "development" ? invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ) : invariant(typeof propTypes[propName] === 'function')); - error = propTypes[propName](props, propName, componentName, location); - } catch (ex) { - error = ex; - } - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var addendum = getDeclarationErrorAddendum(this); - ("production" !== "development" ? warning(false, 'Failed propType: %s%s', error.message, addendum) : null); - } - } - } -} - -var warnedPropsMutations = {}; - -/** - * Warn about mutating props when setting `propName` on `element`. - * - * @param {string} propName The string key within props that was set - * @param {ReactElement} element - */ -function warnForPropsMutation(propName, element) { - var type = element.type; - var elementName = typeof type === 'string' ? type : type.displayName; - var ownerName = element._owner ? - element._owner.getPublicInstance().constructor.displayName : null; - - var warningKey = propName + '|' + elementName + '|' + ownerName; - if (warnedPropsMutations.hasOwnProperty(warningKey)) { - return; - } - warnedPropsMutations[warningKey] = true; - - var elementInfo = ''; - if (elementName) { - elementInfo = ' <' + elementName + ' />'; - } - var ownerInfo = ''; - if (ownerName) { - ownerInfo = ' The element was created by ' + ownerName + '.'; - } - - ("production" !== "development" ? warning( - false, - 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + - 'correct value when initially creating the element or use ' + - 'React.cloneElement to make a new element with updated props.%s', - propName, - elementInfo, - ownerInfo - ) : null); -} - -// Inline Object.is polyfill -function is(a, b) { - if (a !== a) { - // NaN - return b !== b; - } - if (a === 0 && b === 0) { - // +-0 - return 1 / a === 1 / b; - } - return a === b; -} - -/** - * Given an element, check if its props have been mutated since element - * creation (or the last call to this function). In particular, check if any - * new props have been added, which we can't directly catch by defining warning - * properties on the props object. - * - * @param {ReactElement} element - */ -function checkAndWarnForMutatedProps(element) { - if (!element._store) { - // Element was created using `new ReactElement` directly or with - // `ReactElement.createElement`; skip mutation checking - return; - } - - var originalProps = element._store.originalProps; - var props = element.props; - - for (var propName in props) { - if (props.hasOwnProperty(propName)) { - if (!originalProps.hasOwnProperty(propName) || - !is(originalProps[propName], props[propName])) { - warnForPropsMutation(propName, element); - - // Copy over the new value so that the two props objects match again - originalProps[propName] = props[propName]; - } - } - } -} - -/** - * Given an element, validate that its props follow the propTypes definition, - * provided by the type. - * - * @param {ReactElement} element - */ -function validatePropTypes(element) { - if (element.type == null) { - // This has already warned. Don't throw. - return; - } - // Extract the component class from the element. Converts string types - // to a composite class which may have propTypes. - // TODO: Validating a string's propTypes is not decoupled from the - // rendering target which is problematic. - var componentClass = ReactNativeComponent.getComponentClassForElement( - element - ); - var name = componentClass.displayName || componentClass.name; - if (componentClass.propTypes) { - checkPropTypes( - name, - componentClass.propTypes, - element.props, - ReactPropTypeLocations.prop - ); - } - if (typeof componentClass.getDefaultProps === 'function') { - ("production" !== "development" ? warning( - componentClass.getDefaultProps.isReactClassApproved, - 'getDefaultProps is only used on classic React.createClass ' + - 'definitions. Use a static property named `defaultProps` instead.' - ) : null); - } -} - -var ReactElementValidator = { - - checkAndWarnForMutatedProps: checkAndWarnForMutatedProps, - - createElement: function(type, props, children) { - // We warn in this case but don't throw. We expect the element creation to - // succeed and there will likely be errors in render. - ("production" !== "development" ? warning( - type != null, - 'React.createElement: type should not be null or undefined. It should ' + - 'be a string (for DOM elements) or a ReactClass (for composite ' + - 'components).' - ) : null); - - var element = ReactElement.createElement.apply(this, arguments); - - // The result can be nullish if a mock or a custom function is used. - // TODO: Drop this when these are no longer allowed as the type argument. - if (element == null) { - return element; - } - - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], type); - } - - validatePropTypes(element); - - return element; - }, - - createFactory: function(type) { - var validatedFactory = ReactElementValidator.createElement.bind( - null, - type - ); - // Legacy hook TODO: Warn if this is accessed - validatedFactory.type = type; - - if ("production" !== "development") { - try { - Object.defineProperty( - validatedFactory, - 'type', - { - enumerable: false, - get: function() { - ("production" !== "development" ? warning( - false, - 'Factory.type is deprecated. Access the class directly ' + - 'before passing it to createFactory.' - ) : null); - Object.defineProperty(this, 'type', { - value: type - }); - return type; - } - } - ); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - - - return validatedFactory; - }, - - cloneElement: function(element, props, children) { - var newElement = ReactElement.cloneElement.apply(this, arguments); - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], newElement.type); - } - validatePropTypes(newElement); - return newElement; - } - -}; - -module.exports = ReactElementValidator; - -},{"141":141,"150":150,"171":171,"45":45,"63":63,"69":69,"80":80,"84":84,"85":85}],65:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactEmptyComponent - */ - -'use strict'; - -var ReactElement = _dereq_(63); -var ReactInstanceMap = _dereq_(73); - -var invariant = _dereq_(150); - -var component; -// This registry keeps track of the React IDs of the components that rendered to -// `null` (in reality a placeholder such as `noscript`) -var nullComponentIDsRegistry = {}; - -var ReactEmptyComponentInjection = { - injectEmptyComponent: function(emptyComponent) { - component = ReactElement.createFactory(emptyComponent); - } -}; - -var ReactEmptyComponentType = function() {}; -ReactEmptyComponentType.prototype.componentDidMount = function() { - var internalInstance = ReactInstanceMap.get(this); - // TODO: Make sure we run these methods in the correct order, we shouldn't - // need this check. We're going to assume if we're here it means we ran - // componentWillUnmount already so there is no internal instance (it gets - // removed as part of the unmounting process). - if (!internalInstance) { - return; - } - registerNullComponentID(internalInstance._rootNodeID); -}; -ReactEmptyComponentType.prototype.componentWillUnmount = function() { - var internalInstance = ReactInstanceMap.get(this); - // TODO: Get rid of this check. See TODO in componentDidMount. - if (!internalInstance) { - return; - } - deregisterNullComponentID(internalInstance._rootNodeID); -}; -ReactEmptyComponentType.prototype.render = function() { - ("production" !== "development" ? invariant( - component, - 'Trying to return null from a render, but no null placeholder component ' + - 'was injected.' - ) : invariant(component)); - return component(); -}; - -var emptyElement = ReactElement.createElement(ReactEmptyComponentType); - -/** - * Mark the component as having rendered to null. - * @param {string} id Component's `_rootNodeID`. - */ -function registerNullComponentID(id) { - nullComponentIDsRegistry[id] = true; -} - -/** - * Unmark the component as having rendered to null: it renders to something now. - * @param {string} id Component's `_rootNodeID`. - */ -function deregisterNullComponentID(id) { - delete nullComponentIDsRegistry[id]; -} - -/** - * @param {string} id Component's `_rootNodeID`. - * @return {boolean} True if the component is rendered to null. - */ -function isNullComponentID(id) { - return !!nullComponentIDsRegistry[id]; -} - -var ReactEmptyComponent = { - emptyElement: emptyElement, - injection: ReactEmptyComponentInjection, - isNullComponentID: isNullComponentID -}; - -module.exports = ReactEmptyComponent; - -},{"150":150,"63":63,"73":73}],66:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactErrorUtils - * @typechecks - */ - -"use strict"; - -var ReactErrorUtils = { - /** - * Creates a guarded version of a function. This is supposed to make debugging - * of event handlers easier. To aid debugging with the browser's debugger, - * this currently simply returns the original function. - * - * @param {function} func Function to be executed - * @param {string} name The name of the guard - * @return {function} - */ - guard: function(func, name) { - return func; - } -}; - -module.exports = ReactErrorUtils; - -},{}],67:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactEventEmitterMixin - */ - -'use strict'; - -var EventPluginHub = _dereq_(18); - -function runEventQueueInBatch(events) { - EventPluginHub.enqueueEvents(events); - EventPluginHub.processEventQueue(); -} - -var ReactEventEmitterMixin = { - - /** - * Streams a fired top-level event to `EventPluginHub` where plugins have the - * opportunity to create `ReactEvent`s to be dispatched. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native environment event. - */ - handleTopLevel: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var events = EventPluginHub.extractEvents( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ); - - runEventQueueInBatch(events); - } -}; - -module.exports = ReactEventEmitterMixin; - -},{"18":18}],68:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactEventListener - * @typechecks static-only - */ - -'use strict'; - -var EventListener = _dereq_(17); -var ExecutionEnvironment = _dereq_(22); -var PooledClass = _dereq_(30); -var ReactInstanceHandles = _dereq_(72); -var ReactMount = _dereq_(77); -var ReactUpdates = _dereq_(100); - -var assign = _dereq_(29); -var getEventTarget = _dereq_(140); -var getUnboundedScrollPosition = _dereq_(146); - -/** - * Finds the parent React component of `node`. - * - * @param {*} node - * @return {?DOMEventTarget} Parent container, or `null` if the specified node - * is not nested. - */ -function findParent(node) { - // TODO: It may be a good idea to cache this to prevent unnecessary DOM - // traversal, but caching is difficult to do correctly without using a - // mutation observer to listen for all DOM changes. - var nodeID = ReactMount.getID(node); - var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID); - var container = ReactMount.findReactContainerForID(rootID); - var parent = ReactMount.getFirstReactDOM(container); - return parent; -} - -// Used to store ancestor hierarchy in top level callback -function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) { - this.topLevelType = topLevelType; - this.nativeEvent = nativeEvent; - this.ancestors = []; -} -assign(TopLevelCallbackBookKeeping.prototype, { - destructor: function() { - this.topLevelType = null; - this.nativeEvent = null; - this.ancestors.length = 0; - } -}); -PooledClass.addPoolingTo( - TopLevelCallbackBookKeeping, - PooledClass.twoArgumentPooler -); - -function handleTopLevelImpl(bookKeeping) { - var topLevelTarget = ReactMount.getFirstReactDOM( - getEventTarget(bookKeeping.nativeEvent) - ) || window; - - // Loop through the hierarchy, in case there's any nested components. - // It's important that we build the array of ancestors before calling any - // event handlers, because event handlers can modify the DOM, leading to - // inconsistencies with ReactMount's node cache. See #1105. - var ancestor = topLevelTarget; - while (ancestor) { - bookKeeping.ancestors.push(ancestor); - ancestor = findParent(ancestor); - } - - for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) { - topLevelTarget = bookKeeping.ancestors[i]; - var topLevelTargetID = ReactMount.getID(topLevelTarget) || ''; - ReactEventListener._handleTopLevel( - bookKeeping.topLevelType, - topLevelTarget, - topLevelTargetID, - bookKeeping.nativeEvent - ); - } -} - -function scrollValueMonitor(cb) { - var scrollPosition = getUnboundedScrollPosition(window); - cb(scrollPosition); -} - -var ReactEventListener = { - _enabled: true, - _handleTopLevel: null, - - WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null, - - setHandleTopLevel: function(handleTopLevel) { - ReactEventListener._handleTopLevel = handleTopLevel; - }, - - setEnabled: function(enabled) { - ReactEventListener._enabled = !!enabled; - }, - - isEnabled: function() { - return ReactEventListener._enabled; - }, - - - /** - * Traps top-level events by using event bubbling. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} handle Element on which to attach listener. - * @return {object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - var element = handle; - if (!element) { - return null; - } - return EventListener.listen( - element, - handlerBaseName, - ReactEventListener.dispatchEvent.bind(null, topLevelType) - ); - }, - - /** - * Traps a top-level event by using event capturing. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} handle Element on which to attach listener. - * @return {object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - var element = handle; - if (!element) { - return null; - } - return EventListener.capture( - element, - handlerBaseName, - ReactEventListener.dispatchEvent.bind(null, topLevelType) - ); - }, - - monitorScrollValue: function(refresh) { - var callback = scrollValueMonitor.bind(null, refresh); - EventListener.listen(window, 'scroll', callback); - }, - - dispatchEvent: function(topLevelType, nativeEvent) { - if (!ReactEventListener._enabled) { - return; - } - - var bookKeeping = TopLevelCallbackBookKeeping.getPooled( - topLevelType, - nativeEvent - ); - try { - // Event queue being processed in the same cycle allows - // `preventDefault`. - ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping); - } finally { - TopLevelCallbackBookKeeping.release(bookKeeping); - } - } -}; - -module.exports = ReactEventListener; - -},{"100":100,"140":140,"146":146,"17":17,"22":22,"29":29,"30":30,"72":72,"77":77}],69:[function(_dereq_,module,exports){ -/** - * Copyright 2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * -* @providesModule ReactFragment -*/ - -'use strict'; - -var ReactElement = _dereq_(63); - -var warning = _dereq_(171); - -/** - * We used to allow keyed objects to serve as a collection of ReactElements, - * or nested sets. This allowed us a way to explicitly key a set a fragment of - * components. This is now being replaced with an opaque data structure. - * The upgrade path is to call React.addons.createFragment({ key: value }) to - * create a keyed fragment. The resulting data structure is opaque, for now. - */ - -if ("production" !== "development") { - var fragmentKey = '_reactFragment'; - var didWarnKey = '_reactDidWarn'; - var canWarnForReactFragment = false; - - try { - // Feature test. Don't even try to issue this warning if we can't use - // enumerable: false. - - var dummy = function() { - return 1; - }; - - Object.defineProperty( - {}, - fragmentKey, - {enumerable: false, value: true} - ); - - Object.defineProperty( - {}, - 'key', - {enumerable: true, get: dummy} - ); - - canWarnForReactFragment = true; - } catch (x) { } - - var proxyPropertyAccessWithWarning = function(obj, key) { - Object.defineProperty(obj, key, { - enumerable: true, - get: function() { - ("production" !== "development" ? warning( - this[didWarnKey], - 'A ReactFragment is an opaque type. Accessing any of its ' + - 'properties is deprecated. Pass it to one of the React.Children ' + - 'helpers.' - ) : null); - this[didWarnKey] = true; - return this[fragmentKey][key]; - }, - set: function(value) { - ("production" !== "development" ? warning( - this[didWarnKey], - 'A ReactFragment is an immutable opaque type. Mutating its ' + - 'properties is deprecated.' - ) : null); - this[didWarnKey] = true; - this[fragmentKey][key] = value; - } - }); - }; - - var issuedWarnings = {}; - - var didWarnForFragment = function(fragment) { - // We use the keys and the type of the value as a heuristic to dedupe the - // warning to avoid spamming too much. - var fragmentCacheKey = ''; - for (var key in fragment) { - fragmentCacheKey += key + ':' + (typeof fragment[key]) + ','; - } - var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey]; - issuedWarnings[fragmentCacheKey] = true; - return alreadyWarnedOnce; - }; -} - -var ReactFragment = { - // Wrap a keyed object in an opaque proxy that warns you if you access any - // of its properties. - create: function(object) { - if ("production" !== "development") { - if (typeof object !== 'object' || !object || Array.isArray(object)) { - ("production" !== "development" ? warning( - false, - 'React.addons.createFragment only accepts a single object.', - object - ) : null); - return object; - } - if (ReactElement.isValidElement(object)) { - ("production" !== "development" ? warning( - false, - 'React.addons.createFragment does not accept a ReactElement ' + - 'without a wrapper object.' - ) : null); - return object; - } - if (canWarnForReactFragment) { - var proxy = {}; - Object.defineProperty(proxy, fragmentKey, { - enumerable: false, - value: object - }); - Object.defineProperty(proxy, didWarnKey, { - writable: true, - enumerable: false, - value: false - }); - for (var key in object) { - proxyPropertyAccessWithWarning(proxy, key); - } - Object.preventExtensions(proxy); - return proxy; - } - } - return object; - }, - // Extract the original keyed object from the fragment opaque type. Warn if - // a plain object is passed here. - extract: function(fragment) { - if ("production" !== "development") { - if (canWarnForReactFragment) { - if (!fragment[fragmentKey]) { - ("production" !== "development" ? warning( - didWarnForFragment(fragment), - 'Any use of a keyed object should be wrapped in ' + - 'React.addons.createFragment(object) before being passed as a ' + - 'child.' - ) : null); - return fragment; - } - return fragment[fragmentKey]; - } - } - return fragment; - }, - // Check if this is a fragment and if so, extract the keyed object. If it - // is a fragment-like object, warn that it should be wrapped. Ignore if we - // can't determine what kind of object this is. - extractIfFragment: function(fragment) { - if ("production" !== "development") { - if (canWarnForReactFragment) { - // If it is the opaque type, return the keyed object. - if (fragment[fragmentKey]) { - return fragment[fragmentKey]; - } - // Otherwise, check each property if it has an element, if it does - // it is probably meant as a fragment, so we can warn early. Defer, - // the warning to extract. - for (var key in fragment) { - if (fragment.hasOwnProperty(key) && - ReactElement.isValidElement(fragment[key])) { - // This looks like a fragment object, we should provide an - // early warning. - return ReactFragment.extract(fragment); - } - } - } - } - return fragment; - } -}; - -module.exports = ReactFragment; - -},{"171":171,"63":63}],70:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInjection - */ - -'use strict'; - -var DOMProperty = _dereq_(11); -var EventPluginHub = _dereq_(18); -var ReactComponentEnvironment = _dereq_(41); -var ReactClass = _dereq_(38); -var ReactEmptyComponent = _dereq_(65); -var ReactBrowserEventEmitter = _dereq_(33); -var ReactNativeComponent = _dereq_(80); -var ReactDOMComponent = _dereq_(48); -var ReactPerf = _dereq_(82); -var ReactRootIndex = _dereq_(91); -var ReactUpdates = _dereq_(100); - -var ReactInjection = { - Component: ReactComponentEnvironment.injection, - Class: ReactClass.injection, - DOMComponent: ReactDOMComponent.injection, - DOMProperty: DOMProperty.injection, - EmptyComponent: ReactEmptyComponent.injection, - EventPluginHub: EventPluginHub.injection, - EventEmitter: ReactBrowserEventEmitter.injection, - NativeComponent: ReactNativeComponent.injection, - Perf: ReactPerf.injection, - RootIndex: ReactRootIndex.injection, - Updates: ReactUpdates.injection -}; - -module.exports = ReactInjection; - -},{"100":100,"11":11,"18":18,"33":33,"38":38,"41":41,"48":48,"65":65,"80":80,"82":82,"91":91}],71:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInputSelection - */ - -'use strict'; - -var ReactDOMSelection = _dereq_(56); - -var containsNode = _dereq_(123); -var focusNode = _dereq_(134); -var getActiveElement = _dereq_(136); - -function isInDocument(node) { - return containsNode(document.documentElement, node); -} - -/** - * @ReactInputSelection: React input selection module. Based on Selection.js, - * but modified to be suitable for react and has a couple of bug fixes (doesn't - * assume buttons have range selections allowed). - * Input selection module for React. - */ -var ReactInputSelection = { - - hasSelectionCapabilities: function(elem) { - return elem && ( - ((elem.nodeName === 'INPUT' && elem.type === 'text') || - elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true') - ); - }, - - getSelectionInformation: function() { - var focusedElem = getActiveElement(); - return { - focusedElem: focusedElem, - selectionRange: - ReactInputSelection.hasSelectionCapabilities(focusedElem) ? - ReactInputSelection.getSelection(focusedElem) : - null - }; - }, - - /** - * @restoreSelection: If any selection information was potentially lost, - * restore it. This is useful when performing operations that could remove dom - * nodes and place them back in, resulting in focus being lost. - */ - restoreSelection: function(priorSelectionInformation) { - var curFocusedElem = getActiveElement(); - var priorFocusedElem = priorSelectionInformation.focusedElem; - var priorSelectionRange = priorSelectionInformation.selectionRange; - if (curFocusedElem !== priorFocusedElem && - isInDocument(priorFocusedElem)) { - if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { - ReactInputSelection.setSelection( - priorFocusedElem, - priorSelectionRange - ); - } - focusNode(priorFocusedElem); - } - }, - - /** - * @getSelection: Gets the selection bounds of a focused textarea, input or - * contentEditable node. - * -@input: Look up selection bounds of this input - * -@return {start: selectionStart, end: selectionEnd} - */ - getSelection: function(input) { - var selection; - - if ('selectionStart' in input) { - // Modern browser with input or textarea. - selection = { - start: input.selectionStart, - end: input.selectionEnd - }; - } else if (document.selection && input.nodeName === 'INPUT') { - // IE8 input. - var range = document.selection.createRange(); - // There can only be one selection per document in IE, so it must - // be in our element. - if (range.parentElement() === input) { - selection = { - start: -range.moveStart('character', -input.value.length), - end: -range.moveEnd('character', -input.value.length) - }; - } - } else { - // Content editable or old IE textarea. - selection = ReactDOMSelection.getOffsets(input); - } - - return selection || {start: 0, end: 0}; - }, - - /** - * @setSelection: Sets the selection bounds of a textarea or input and focuses - * the input. - * -@input Set selection bounds of this input or textarea - * -@offsets Object of same form that is returned from get* - */ - setSelection: function(input, offsets) { - var start = offsets.start; - var end = offsets.end; - if (typeof end === 'undefined') { - end = start; - } - - if ('selectionStart' in input) { - input.selectionStart = start; - input.selectionEnd = Math.min(end, input.value.length); - } else if (document.selection && input.nodeName === 'INPUT') { - var range = input.createTextRange(); - range.collapse(true); - range.moveStart('character', start); - range.moveEnd('character', end - start); - range.select(); - } else { - ReactDOMSelection.setOffsets(input, offsets); - } - } -}; - -module.exports = ReactInputSelection; - -},{"123":123,"134":134,"136":136,"56":56}],72:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInstanceHandles - * @typechecks static-only - */ - -'use strict'; - -var ReactRootIndex = _dereq_(91); - -var invariant = _dereq_(150); - -var SEPARATOR = '.'; -var SEPARATOR_LENGTH = SEPARATOR.length; - -/** - * Maximum depth of traversals before we consider the possibility of a bad ID. - */ -var MAX_TREE_DEPTH = 100; - -/** - * Creates a DOM ID prefix to use when mounting React components. - * - * @param {number} index A unique integer - * @return {string} React root ID. - * @internal - */ -function getReactRootIDString(index) { - return SEPARATOR + index.toString(36); -} - -/** - * Checks if a character in the supplied ID is a separator or the end. - * - * @param {string} id A React DOM ID. - * @param {number} index Index of the character to check. - * @return {boolean} True if the character is a separator or end of the ID. - * @private - */ -function isBoundary(id, index) { - return id.charAt(index) === SEPARATOR || index === id.length; -} - -/** - * Checks if the supplied string is a valid React DOM ID. - * - * @param {string} id A React DOM ID, maybe. - * @return {boolean} True if the string is a valid React DOM ID. - * @private - */ -function isValidID(id) { - return id === '' || ( - id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR - ); -} - -/** - * Checks if the first ID is an ancestor of or equal to the second ID. - * - * @param {string} ancestorID - * @param {string} descendantID - * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. - * @internal - */ -function isAncestorIDOf(ancestorID, descendantID) { - return ( - descendantID.indexOf(ancestorID) === 0 && - isBoundary(descendantID, ancestorID.length) - ); -} - -/** - * Gets the parent ID of the supplied React DOM ID, `id`. - * - * @param {string} id ID of a component. - * @return {string} ID of the parent, or an empty string. - * @private - */ -function getParentID(id) { - return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; -} - -/** - * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the - * supplied `destinationID`. If they are equal, the ID is returned. - * - * @param {string} ancestorID ID of an ancestor node of `destinationID`. - * @param {string} destinationID ID of the destination node. - * @return {string} Next ID on the path from `ancestorID` to `destinationID`. - * @private - */ -function getNextDescendantID(ancestorID, destinationID) { - ("production" !== "development" ? invariant( - isValidID(ancestorID) && isValidID(destinationID), - 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', - ancestorID, - destinationID - ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); - ("production" !== "development" ? invariant( - isAncestorIDOf(ancestorID, destinationID), - 'getNextDescendantID(...): React has made an invalid assumption about ' + - 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', - ancestorID, - destinationID - ) : invariant(isAncestorIDOf(ancestorID, destinationID))); - if (ancestorID === destinationID) { - return ancestorID; - } - // Skip over the ancestor and the immediate separator. Traverse until we hit - // another separator or we reach the end of `destinationID`. - var start = ancestorID.length + SEPARATOR_LENGTH; - var i; - for (i = start; i < destinationID.length; i++) { - if (isBoundary(destinationID, i)) { - break; - } - } - return destinationID.substr(0, i); -} - -/** - * Gets the nearest common ancestor ID of two IDs. - * - * Using this ID scheme, the nearest common ancestor ID is the longest common - * prefix of the two IDs that immediately preceded a "marker" in both strings. - * - * @param {string} oneID - * @param {string} twoID - * @return {string} Nearest common ancestor ID, or the empty string if none. - * @private - */ -function getFirstCommonAncestorID(oneID, twoID) { - var minLength = Math.min(oneID.length, twoID.length); - if (minLength === 0) { - return ''; - } - var lastCommonMarkerIndex = 0; - // Use `<=` to traverse until the "EOL" of the shorter string. - for (var i = 0; i <= minLength; i++) { - if (isBoundary(oneID, i) && isBoundary(twoID, i)) { - lastCommonMarkerIndex = i; - } else if (oneID.charAt(i) !== twoID.charAt(i)) { - break; - } - } - var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); - ("production" !== "development" ? invariant( - isValidID(longestCommonID), - 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', - oneID, - twoID, - longestCommonID - ) : invariant(isValidID(longestCommonID))); - return longestCommonID; -} - -/** - * Traverses the parent path between two IDs (either up or down). The IDs must - * not be the same, and there must exist a parent path between them. If the - * callback returns `false`, traversal is stopped. - * - * @param {?string} start ID at which to start traversal. - * @param {?string} stop ID at which to end traversal. - * @param {function} cb Callback to invoke each ID with. - * @param {?boolean} skipFirst Whether or not to skip the first node. - * @param {?boolean} skipLast Whether or not to skip the last node. - * @private - */ -function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { - start = start || ''; - stop = stop || ''; - ("production" !== "development" ? invariant( - start !== stop, - 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', - start - ) : invariant(start !== stop)); - var traverseUp = isAncestorIDOf(stop, start); - ("production" !== "development" ? invariant( - traverseUp || isAncestorIDOf(start, stop), - 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + - 'not have a parent path.', - start, - stop - ) : invariant(traverseUp || isAncestorIDOf(start, stop))); - // Traverse from `start` to `stop` one depth at a time. - var depth = 0; - var traverse = traverseUp ? getParentID : getNextDescendantID; - for (var id = start; /* until break */; id = traverse(id, stop)) { - var ret; - if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { - ret = cb(id, traverseUp, arg); - } - if (ret === false || id === stop) { - // Only break //after// visiting `stop`. - break; - } - ("production" !== "development" ? invariant( - depth++ < MAX_TREE_DEPTH, - 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + - 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', - start, stop - ) : invariant(depth++ < MAX_TREE_DEPTH)); - } -} - -/** - * Manages the IDs assigned to DOM representations of React components. This - * uses a specific scheme in order to traverse the DOM efficiently (e.g. in - * order to simulate events). - * - * @internal - */ -var ReactInstanceHandles = { - - /** - * Constructs a React root ID - * @return {string} A React root ID. - */ - createReactRootID: function() { - return getReactRootIDString(ReactRootIndex.createReactRootIndex()); - }, - - /** - * Constructs a React ID by joining a root ID with a name. - * - * @param {string} rootID Root ID of a parent component. - * @param {string} name A component's name (as flattened children). - * @return {string} A React ID. - * @internal - */ - createReactID: function(rootID, name) { - return rootID + name; - }, - - /** - * Gets the DOM ID of the React component that is the root of the tree that - * contains the React component with the supplied DOM ID. - * - * @param {string} id DOM ID of a React component. - * @return {?string} DOM ID of the React component that is the root. - * @internal - */ - getReactRootIDFromNodeID: function(id) { - if (id && id.charAt(0) === SEPARATOR && id.length > 1) { - var index = id.indexOf(SEPARATOR, 1); - return index > -1 ? id.substr(0, index) : id; - } - return null; - }, - - /** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * NOTE: Does not invoke the callback on the nearest common ancestor because - * nothing "entered" or "left" that element. - * - * @param {string} leaveID ID being left. - * @param {string} enterID ID being entered. - * @param {function} cb Callback to invoke on each entered/left ID. - * @param {*} upArg Argument to invoke the callback with on left IDs. - * @param {*} downArg Argument to invoke the callback with on entered IDs. - * @internal - */ - traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { - var ancestorID = getFirstCommonAncestorID(leaveID, enterID); - if (ancestorID !== leaveID) { - traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); - } - if (ancestorID !== enterID) { - traverseParentPath(ancestorID, enterID, cb, downArg, true, false); - } - }, - - /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseTwoPhase: function(targetID, cb, arg) { - if (targetID) { - traverseParentPath('', targetID, cb, arg, true, false); - traverseParentPath(targetID, '', cb, arg, false, true); - } - }, - - /** - * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For - * example, passing `.0.$row-0.1` would result in `cb` getting called - * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseAncestors: function(targetID, cb, arg) { - traverseParentPath('', targetID, cb, arg, true, false); - }, - - /** - * Exposed for unit testing. - * @private - */ - _getFirstCommonAncestorID: getFirstCommonAncestorID, - - /** - * Exposed for unit testing. - * @private - */ - _getNextDescendantID: getNextDescendantID, - - isAncestorIDOf: isAncestorIDOf, - - SEPARATOR: SEPARATOR - -}; - -module.exports = ReactInstanceHandles; - -},{"150":150,"91":91}],73:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInstanceMap - */ - -'use strict'; - -/** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. - */ - -// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); -var ReactInstanceMap = { - - /** - * This API should be called `delete` but we'd have to make sure to always - * transform these to strings for IE support. When this transform is fully - * supported we can rename it. - */ - remove: function(key) { - key._reactInternalInstance = undefined; - }, - - get: function(key) { - return key._reactInternalInstance; - }, - - has: function(key) { - return key._reactInternalInstance !== undefined; - }, - - set: function(key, value) { - key._reactInternalInstance = value; - } - -}; - -module.exports = ReactInstanceMap; - -},{}],74:[function(_dereq_,module,exports){ -/** - * Copyright 2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactLifeCycle - */ - -'use strict'; - -/** - * This module manages the bookkeeping when a component is in the process - * of being mounted or being unmounted. This is used as a way to enforce - * invariants (or warnings) when it is not recommended to call - * setState/forceUpdate. - * - * currentlyMountingInstance: During the construction phase, it is not possible - * to trigger an update since the instance is not fully mounted yet. However, we - * currently allow this as a convenience for mutating the initial state. - * - * currentlyUnmountingInstance: During the unmounting phase, the instance is - * still mounted and can therefore schedule an update. However, this is not - * recommended and probably an error since it's about to be unmounted. - * Therefore we still want to trigger in an error for that case. - */ - -var ReactLifeCycle = { - currentlyMountingInstance: null, - currentlyUnmountingInstance: null -}; - -module.exports = ReactLifeCycle; - -},{}],75:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactLink - * @typechecks static-only - */ - -'use strict'; - -/** - * ReactLink encapsulates a common pattern in which a component wants to modify - * a prop received from its parent. ReactLink allows the parent to pass down a - * value coupled with a callback that, when invoked, expresses an intent to - * modify that value. For example: - * - * React.createClass({ - * getInitialState: function() { - * return {value: ''}; - * }, - * render: function() { - * var valueLink = new ReactLink(this.state.value, this._handleValueChange); - * return <input valueLink={valueLink} />; - * }, - * this._handleValueChange: function(newValue) { - * this.setState({value: newValue}); - * } - * }); - * - * We have provided some sugary mixins to make the creation and - * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin. - */ - -var React = _dereq_(31); - -/** - * @param {*} value current value of the link - * @param {function} requestChange callback to request a change - */ -function ReactLink(value, requestChange) { - this.value = value; - this.requestChange = requestChange; -} - -/** - * Creates a PropType that enforces the ReactLink API and optionally checks the - * type of the value being passed inside the link. Example: - * - * MyComponent.propTypes = { - * tabIndexLink: ReactLink.PropTypes.link(React.PropTypes.number) - * } - */ -function createLinkTypeChecker(linkType) { - var shapes = { - value: typeof linkType === 'undefined' ? - React.PropTypes.any.isRequired : - linkType.isRequired, - requestChange: React.PropTypes.func.isRequired - }; - return React.PropTypes.shape(shapes); -} - -ReactLink.PropTypes = { - link: createLinkTypeChecker -}; - -module.exports = ReactLink; - -},{"31":31}],76:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMarkupChecksum - */ - -'use strict'; - -var adler32 = _dereq_(119); - -var ReactMarkupChecksum = { - CHECKSUM_ATTR_NAME: 'data-react-checksum', - - /** - * @param {string} markup Markup string - * @return {string} Markup string with checksum attribute attached - */ - addChecksumToMarkup: function(markup) { - var checksum = adler32(markup); - return markup.replace( - '>', - ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' - ); - }, - - /** - * @param {string} markup to use - * @param {DOMElement} element root React element - * @returns {boolean} whether or not the markup is the same - */ - canReuseMarkup: function(markup, element) { - var existingChecksum = element.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - existingChecksum = existingChecksum && parseInt(existingChecksum, 10); - var markupChecksum = adler32(markup); - return markupChecksum === existingChecksum; - } -}; - -module.exports = ReactMarkupChecksum; - -},{"119":119}],77:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMount - */ - -'use strict'; - -var DOMProperty = _dereq_(11); -var ReactBrowserEventEmitter = _dereq_(33); -var ReactCurrentOwner = _dereq_(45); -var ReactElement = _dereq_(63); -var ReactElementValidator = _dereq_(64); -var ReactEmptyComponent = _dereq_(65); -var ReactInstanceHandles = _dereq_(72); -var ReactInstanceMap = _dereq_(73); -var ReactMarkupChecksum = _dereq_(76); -var ReactPerf = _dereq_(82); -var ReactReconciler = _dereq_(89); -var ReactUpdateQueue = _dereq_(99); -var ReactUpdates = _dereq_(100); - -var emptyObject = _dereq_(130); -var containsNode = _dereq_(123); -var getReactRootElementInContainer = _dereq_(144); -var instantiateReactComponent = _dereq_(149); -var invariant = _dereq_(150); -var setInnerHTML = _dereq_(164); -var shouldUpdateReactComponent = _dereq_(167); -var warning = _dereq_(171); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var nodeCache = {}; - -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; - -/** Mapping from reactRootID to React component instance. */ -var instancesByReactRootID = {}; - -/** Mapping from reactRootID to `container` nodes. */ -var containersByReactRootID = {}; - -if ("production" !== "development") { - /** __DEV__-only mapping from reactRootID to root elements. */ - var rootElementsByReactRootID = {}; -} - -// Used to store breadth-first search state in findComponentRoot. -var findComponentRootReusableArray = []; - -/** - * Finds the index of the first character - * that's not common between the two given strings. - * - * @return {number} the index of the character where the strings diverge - */ -function firstDifferenceIndex(string1, string2) { - var minLen = Math.min(string1.length, string2.length); - for (var i = 0; i < minLen; i++) { - if (string1.charAt(i) !== string2.charAt(i)) { - return i; - } - } - return string1.length === string2.length ? -1 : minLen; -} - -/** - * @param {DOMElement} container DOM element that may contain a React component. - * @return {?string} A "reactRoot" ID, if a React component is rendered. - */ -function getReactRootID(container) { - var rootElement = getReactRootElementInContainer(container); - return rootElement && ReactMount.getID(rootElement); -} - -/** - * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form - * element can return its control whose name or ID equals ATTR_NAME. All - * DOM nodes support `getAttributeNode` but this can also get called on - * other objects so just return '' if we're given something other than a - * DOM node (such as window). - * - * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. - * @return {string} ID of the supplied `domNode`. - */ -function getID(node) { - var id = internalGetID(node); - if (id) { - if (nodeCache.hasOwnProperty(id)) { - var cached = nodeCache[id]; - if (cached !== node) { - ("production" !== "development" ? invariant( - !isValid(cached, id), - 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', - ATTR_NAME, id - ) : invariant(!isValid(cached, id))); - - nodeCache[id] = node; - } - } else { - nodeCache[id] = node; - } - } - - return id; -} - -function internalGetID(node) { - // If node is something like a window, document, or text node, none of - // which support attributes or a .getAttribute method, gracefully return - // the empty string, as if the attribute were missing. - return node && node.getAttribute && node.getAttribute(ATTR_NAME) || ''; -} - -/** - * Sets the React-specific ID of the given node. - * - * @param {DOMElement} node The DOM node whose ID will be set. - * @param {string} id The value of the ID attribute. - */ -function setID(node, id) { - var oldID = internalGetID(node); - if (oldID !== id) { - delete nodeCache[oldID]; - } - node.setAttribute(ATTR_NAME, id); - nodeCache[id] = node; -} - -/** - * Finds the node with the supplied React-generated DOM ID. - * - * @param {string} id A React-generated DOM ID. - * @return {DOMElement} DOM node with the suppled `id`. - * @internal - */ -function getNode(id) { - if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { - nodeCache[id] = ReactMount.findReactNodeByID(id); - } - return nodeCache[id]; -} - -/** - * Finds the node with the supplied public React instance. - * - * @param {*} instance A public React instance. - * @return {?DOMElement} DOM node with the suppled `id`. - * @internal - */ -function getNodeFromInstance(instance) { - var id = ReactInstanceMap.get(instance)._rootNodeID; - if (ReactEmptyComponent.isNullComponentID(id)) { - return null; - } - if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { - nodeCache[id] = ReactMount.findReactNodeByID(id); - } - return nodeCache[id]; -} - -/** - * A node is "valid" if it is contained by a currently mounted container. - * - * This means that the node does not have to be contained by a document in - * order to be considered valid. - * - * @param {?DOMElement} node The candidate DOM node. - * @param {string} id The expected ID of the node. - * @return {boolean} Whether the node is contained by a mounted container. - */ -function isValid(node, id) { - if (node) { - ("production" !== "development" ? invariant( - internalGetID(node) === id, - 'ReactMount: Unexpected modification of `%s`', - ATTR_NAME - ) : invariant(internalGetID(node) === id)); - - var container = ReactMount.findReactContainerForID(id); - if (container && containsNode(container, node)) { - return true; - } - } - - return false; -} - -/** - * Causes the cache to forget about one React-specific ID. - * - * @param {string} id The ID to forget. - */ -function purgeID(id) { - delete nodeCache[id]; -} - -var deepestNodeSoFar = null; -function findDeepestCachedAncestorImpl(ancestorID) { - var ancestor = nodeCache[ancestorID]; - if (ancestor && isValid(ancestor, ancestorID)) { - deepestNodeSoFar = ancestor; - } else { - // This node isn't populated in the cache, so presumably none of its - // descendants are. Break out of the loop. - return false; - } -} - -/** - * Return the deepest cached node whose ID is a prefix of `targetID`. - */ -function findDeepestCachedAncestor(targetID) { - deepestNodeSoFar = null; - ReactInstanceHandles.traverseAncestors( - targetID, - findDeepestCachedAncestorImpl - ); - - var foundNode = deepestNodeSoFar; - deepestNodeSoFar = null; - return foundNode; -} - -/** - * Mounts this component and inserts it into the DOM. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function mountComponentIntoNode( - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup) { - var markup = ReactReconciler.mountComponent( - componentInstance, rootID, transaction, emptyObject - ); - componentInstance._isTopLevel = true; - ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup); -} - -/** - * Batched mount. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function batchedMountComponentIntoNode( - componentInstance, - rootID, - container, - shouldReuseMarkup) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - transaction.perform( - mountComponentIntoNode, - null, - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup - ); - ReactUpdates.ReactReconcileTransaction.release(transaction); -} - -/** - * Mounting is the process of initializing a React component by creating its - * representative DOM elements and inserting them into a supplied `container`. - * Any prior content inside `container` is destroyed in the process. - * - * ReactMount.render( - * component, - * document.getElementById('container') - * ); - * - * <div id="container"> <-- Supplied `container`. - * <div data-reactid=".3"> <-- Rendered reactRoot of React - * // ... component. - * </div> - * </div> - * - * Inside of `container`, the first element rendered is the "reactRoot". - */ -var ReactMount = { - /** Exposed for debugging purposes **/ - _instancesByReactRootID: instancesByReactRootID, - - /** - * This is a hook provided to support rendering React components while - * ensuring that the apparent scroll position of its `container` does not - * change. - * - * @param {DOMElement} container The `container` being rendered into. - * @param {function} renderCallback This must be called once to do the render. - */ - scrollMonitor: function(container, renderCallback) { - renderCallback(); - }, - - /** - * Take a component that's already mounted into the DOM and replace its props - * @param {ReactComponent} prevComponent component instance already in the DOM - * @param {ReactElement} nextElement component instance to render - * @param {DOMElement} container container to render into - * @param {?function} callback function triggered on completion - */ - _updateRootComponent: function( - prevComponent, - nextElement, - container, - callback) { - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - ReactMount.scrollMonitor(container, function() { - ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); - } - }); - - if ("production" !== "development") { - // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[getReactRootID(container)] = - getReactRootElementInContainer(container); - } - - return prevComponent; - }, - - /** - * Register a component into the instance map and starts scroll value - * monitoring - * @param {ReactComponent} nextComponent component instance to render - * @param {DOMElement} container container to render into - * @return {string} reactRoot ID prefix - */ - _registerComponent: function(nextComponent, container) { - ("production" !== "development" ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - '_registerComponent(...): Target container is not a DOM element.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); - - ReactBrowserEventEmitter.ensureScrollValueMonitoring(); - - var reactRootID = ReactMount.registerContainer(container); - instancesByReactRootID[reactRootID] = nextComponent; - return reactRootID; - }, - - /** - * Render a new component into the DOM. - * @param {ReactElement} nextElement element to render - * @param {DOMElement} container container to render into - * @param {boolean} shouldReuseMarkup if we should skip the markup insertion - * @return {ReactComponent} nextComponent - */ - _renderNewRootComponent: function( - nextElement, - container, - shouldReuseMarkup - ) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. - ("production" !== "development" ? warning( - ReactCurrentOwner.current == null, - '_renderNewRootComponent(): Render methods should be a pure function ' + - 'of props and state; triggering nested component updates from ' + - 'render is not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - var componentInstance = instantiateReactComponent(nextElement, null); - var reactRootID = ReactMount._registerComponent( - componentInstance, - container - ); - - // The initial render is synchronous but any updates that happen during - // rendering, in componentWillMount or componentDidMount, will be batched - // according to the current batching strategy. - - ReactUpdates.batchedUpdates( - batchedMountComponentIntoNode, - componentInstance, - reactRootID, - container, - shouldReuseMarkup - ); - - if ("production" !== "development") { - // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[reactRootID] = - getReactRootElementInContainer(container); - } - - return componentInstance; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - render: function(nextElement, container, callback) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(nextElement), - 'React.render(): Invalid component element.%s', - ( - typeof nextElement === 'string' ? - ' Instead of passing an element string, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - typeof nextElement === 'function' ? - ' Instead of passing a component class, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - // Check if it quacks like an element - nextElement != null && nextElement.props !== undefined ? - ' This may be caused by unintentionally loading two independent ' + - 'copies of React.' : - '' - ) - ) : invariant(ReactElement.isValidElement(nextElement))); - - var prevComponent = instancesByReactRootID[getReactRootID(container)]; - - if (prevComponent) { - var prevElement = prevComponent._currentElement; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - return ReactMount._updateRootComponent( - prevComponent, - nextElement, - container, - callback - ).getPublicInstance(); - } else { - ReactMount.unmountComponentAtNode(container); - } - } - - var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = - reactRootElement && ReactMount.isRenderedByReact(reactRootElement); - - if ("production" !== "development") { - if (!containerHasReactMarkup || reactRootElement.nextSibling) { - var rootElementSibling = reactRootElement; - while (rootElementSibling) { - if (ReactMount.isRenderedByReact(rootElementSibling)) { - ("production" !== "development" ? warning( - false, - 'render(): Target node has markup rendered by React, but there ' + - 'are unrelated nodes as well. This is most commonly caused by ' + - 'white-space inserted around server-rendered markup.' - ) : null); - break; - } - - rootElementSibling = rootElementSibling.nextSibling; - } - } - } - - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; - - var component = ReactMount._renderNewRootComponent( - nextElement, - container, - shouldReuseMarkup - ).getPublicInstance(); - if (callback) { - callback.call(component); - } - return component; - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into the supplied `container`. - * - * @param {function} constructor React component constructor. - * @param {?object} props Initial props of the component instance. - * @param {DOMElement} container DOM element to render into. - * @return {ReactComponent} Component instance rendered in `container`. - */ - constructAndRenderComponent: function(constructor, props, container) { - var element = ReactElement.createElement(constructor, props); - return ReactMount.render(element, container); - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into a container node identified by supplied `id`. - * - * @param {function} componentConstructor React component constructor - * @param {?object} props Initial props of the component instance. - * @param {string} id ID of the DOM element to render into. - * @return {ReactComponent} Component instance rendered in the container node. - */ - constructAndRenderComponentByID: function(constructor, props, id) { - var domNode = document.getElementById(id); - ("production" !== "development" ? invariant( - domNode, - 'Tried to get element with id of "%s" but it is not present on the page.', - id - ) : invariant(domNode)); - return ReactMount.constructAndRenderComponent(constructor, props, domNode); - }, - - /** - * Registers a container node into which React components will be rendered. - * This also creates the "reactRoot" ID that will be assigned to the element - * rendered within. - * - * @param {DOMElement} container DOM element to register as a container. - * @return {string} The "reactRoot" ID of elements rendered within. - */ - registerContainer: function(container) { - var reactRootID = getReactRootID(container); - if (reactRootID) { - // If one exists, make sure it is a valid "reactRoot" ID. - reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); - } - if (!reactRootID) { - // No valid "reactRoot" ID found, create one. - reactRootID = ReactInstanceHandles.createReactRootID(); - } - containersByReactRootID[reactRootID] = container; - return reactRootID; - }, - - /** - * Unmounts and destroys the React component rendered in the `container`. - * - * @param {DOMElement} container DOM element containing a React component. - * @return {boolean} True if a component was found in and unmounted from - * `container` - */ - unmountComponentAtNode: function(container) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (Strictly speaking, unmounting won't cause a - // render but we still don't expect to be in a render call here.) - ("production" !== "development" ? warning( - ReactCurrentOwner.current == null, - 'unmountComponentAtNode(): Render methods should be a pure function of ' + - 'props and state; triggering nested component updates from render is ' + - 'not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - ("production" !== "development" ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - 'unmountComponentAtNode(...): Target container is not a DOM element.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); - - var reactRootID = getReactRootID(container); - var component = instancesByReactRootID[reactRootID]; - if (!component) { - return false; - } - ReactMount.unmountComponentFromNode(component, container); - delete instancesByReactRootID[reactRootID]; - delete containersByReactRootID[reactRootID]; - if ("production" !== "development") { - delete rootElementsByReactRootID[reactRootID]; - } - return true; - }, - - /** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ - unmountComponentFromNode: function(instance, container) { - ReactReconciler.unmountComponent(instance); - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } - }, - - /** - * Finds the container DOM element that contains React component to which the - * supplied DOM `id` belongs. - * - * @param {string} id The ID of an element rendered by a React component. - * @return {?DOMElement} DOM element that contains the `id`. - */ - findReactContainerForID: function(id) { - var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); - var container = containersByReactRootID[reactRootID]; - - if ("production" !== "development") { - var rootElement = rootElementsByReactRootID[reactRootID]; - if (rootElement && rootElement.parentNode !== container) { - ("production" !== "development" ? invariant( - // Call internalGetID here because getID calls isValid which calls - // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID, - 'ReactMount: Root element ID differed from reactRootID.' - ) : invariant(// Call internalGetID here because getID calls isValid which calls - // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID)); - - var containerChild = container.firstChild; - if (containerChild && - reactRootID === internalGetID(containerChild)) { - // If the container has a new child with the same ID as the old - // root element, then rootElementsByReactRootID[reactRootID] is - // just stale and needs to be updated. The case that deserves a - // warning is when the container is empty. - rootElementsByReactRootID[reactRootID] = containerChild; - } else { - ("production" !== "development" ? warning( - false, - 'ReactMount: Root element has been removed from its original ' + - 'container. New container:', rootElement.parentNode - ) : null); - } - } - } - - return container; - }, - - /** - * Finds an element rendered by React with the supplied ID. - * - * @param {string} id ID of a DOM node in the React component. - * @return {DOMElement} Root DOM node of the React component. - */ - findReactNodeByID: function(id) { - var reactRoot = ReactMount.findReactContainerForID(id); - return ReactMount.findComponentRoot(reactRoot, id); - }, - - /** - * True if the supplied `node` is rendered by React. - * - * @param {*} node DOM Element to check. - * @return {boolean} True if the DOM Element appears to be rendered by React. - * @internal - */ - isRenderedByReact: function(node) { - if (node.nodeType !== 1) { - // Not a DOMElement, therefore not a React component - return false; - } - var id = ReactMount.getID(node); - return id ? id.charAt(0) === SEPARATOR : false; - }, - - /** - * Traverses up the ancestors of the supplied node to find a node that is a - * DOM representation of a React component. - * - * @param {*} node - * @return {?DOMEventTarget} - * @internal - */ - getFirstReactDOM: function(node) { - var current = node; - while (current && current.parentNode !== current) { - if (ReactMount.isRenderedByReact(current)) { - return current; - } - current = current.parentNode; - } - return null; - }, - - /** - * Finds a node with the supplied `targetID` inside of the supplied - * `ancestorNode`. Exploits the ID naming scheme to perform the search - * quickly. - * - * @param {DOMEventTarget} ancestorNode Search from this root. - * @pararm {string} targetID ID of the DOM representation of the component. - * @return {DOMEventTarget} DOM node with the supplied `targetID`. - * @internal - */ - findComponentRoot: function(ancestorNode, targetID) { - var firstChildren = findComponentRootReusableArray; - var childIndex = 0; - - var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; - - firstChildren[0] = deepestAncestor.firstChild; - firstChildren.length = 1; - - while (childIndex < firstChildren.length) { - var child = firstChildren[childIndex++]; - var targetChild; - - while (child) { - var childID = ReactMount.getID(child); - if (childID) { - // Even if we find the node we're looking for, we finish looping - // through its siblings to ensure they're cached so that we don't have - // to revisit this node again. Otherwise, we make n^2 calls to getID - // when visiting the many children of a single node in order. - - if (targetID === childID) { - targetChild = child; - } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { - // If we find a child whose ID is an ancestor of the given ID, - // then we can be sure that we only want to search the subtree - // rooted at this child, so we can throw out the rest of the - // search state. - firstChildren.length = childIndex = 0; - firstChildren.push(child.firstChild); - } - - } else { - // If this child had no ID, then there's a chance that it was - // injected automatically by the browser, as when a `<table>` - // element sprouts an extra `<tbody>` child as a side effect of - // `.innerHTML` parsing. Optimistically continue down this - // branch, but not before examining the other siblings. - firstChildren.push(child.firstChild); - } - - child = child.nextSibling; - } - - if (targetChild) { - // Emptying firstChildren/findComponentRootReusableArray is - // not necessary for correctness, but it helps the GC reclaim - // any nodes that were left at the end of the search. - firstChildren.length = 0; - - return targetChild; - } - } - - firstChildren.length = 0; - - ("production" !== "development" ? invariant( - false, - 'findComponentRoot(..., %s): Unable to find element. This probably ' + - 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + - 'usually due to forgetting a <tbody> when using tables, nesting tags ' + - 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + - 'parent. ' + - 'Try inspecting the child nodes of the element with React ID `%s`.', - targetID, - ReactMount.getID(ancestorNode) - ) : invariant(false)); - }, - - _mountImageIntoNode: function(markup, container, shouldReuseMarkup) { - ("production" !== "development" ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - 'mountComponentIntoNode(...): Target container is not valid.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); - - if (shouldReuseMarkup) { - var rootElement = getReactRootElementInContainer(container); - if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { - return; - } else { - var checksum = rootElement.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - - var rootMarkup = rootElement.outerHTML; - rootElement.setAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME, - checksum - ); - - var diffIndex = firstDifferenceIndex(markup, rootMarkup); - var difference = ' (client) ' + - markup.substring(diffIndex - 20, diffIndex + 20) + - '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); - - ("production" !== "development" ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document using ' + - 'server rendering but the checksum was invalid. This usually ' + - 'means you rendered a different component type or props on ' + - 'the client from the one on the server, or your render() ' + - 'methods are impure. React cannot handle this case due to ' + - 'cross-browser quirks by rendering at the document root. You ' + - 'should look for environment dependent code in your components ' + - 'and ensure the props are the same client and server side:\n%s', - difference - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); - - if ("production" !== "development") { - ("production" !== "development" ? warning( - false, - 'React attempted to reuse markup in a container but the ' + - 'checksum was invalid. This generally means that you are ' + - 'using server rendering and the markup generated on the ' + - 'server was not what the client was expecting. React injected ' + - 'new markup to compensate which works but you have lost many ' + - 'of the benefits of server rendering. Instead, figure out ' + - 'why the markup being generated is different on the client ' + - 'or server:\n%s', - difference - ) : null); - } - } - } - - ("production" !== "development" ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document but ' + - 'you didn\'t use server rendering. We can\'t do this ' + - 'without using server rendering due to cross-browser quirks. ' + - 'See React.renderToString() for server rendering.' - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); - - setInnerHTML(container, markup); - }, - - /** - * React ID utilities. - */ - - getReactRootID: getReactRootID, - - getID: getID, - - setID: setID, - - getNode: getNode, - - getNodeFromInstance: getNodeFromInstance, - - purgeID: purgeID -}; - -ReactPerf.measureMethods(ReactMount, 'ReactMount', { - _renderNewRootComponent: '_renderNewRootComponent', - _mountImageIntoNode: '_mountImageIntoNode' -}); - -module.exports = ReactMount; - -},{"100":100,"11":11,"123":123,"130":130,"144":144,"149":149,"150":150,"164":164,"167":167,"171":171,"33":33,"45":45,"63":63,"64":64,"65":65,"72":72,"73":73,"76":76,"82":82,"89":89,"99":99}],78:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMultiChild - * @typechecks static-only - */ - -'use strict'; - -var ReactComponentEnvironment = _dereq_(41); -var ReactMultiChildUpdateTypes = _dereq_(79); - -var ReactReconciler = _dereq_(89); -var ReactChildReconciler = _dereq_(36); - -/** - * Updating children of a component may trigger recursive updates. The depth is - * used to batch recursive updates to render markup more efficiently. - * - * @type {number} - * @private - */ -var updateDepth = 0; - -/** - * Queue of update configuration objects. - * - * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`. - * - * @type {array<object>} - * @private - */ -var updateQueue = []; - -/** - * Queue of markup to be rendered. - * - * @type {array<string>} - * @private - */ -var markupQueue = []; - -/** - * Enqueues markup to be rendered and inserted at a supplied index. - * - * @param {string} parentID ID of the parent component. - * @param {string} markup Markup that renders into an element. - * @param {number} toIndex Destination index. - * @private - */ -function enqueueMarkup(parentID, markup, toIndex) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.INSERT_MARKUP, - markupIndex: markupQueue.push(markup) - 1, - textContent: null, - fromIndex: null, - toIndex: toIndex - }); -} - -/** - * Enqueues moving an existing element to another index. - * - * @param {string} parentID ID of the parent component. - * @param {number} fromIndex Source index of the existing element. - * @param {number} toIndex Destination index of the element. - * @private - */ -function enqueueMove(parentID, fromIndex, toIndex) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.MOVE_EXISTING, - markupIndex: null, - textContent: null, - fromIndex: fromIndex, - toIndex: toIndex - }); -} - -/** - * Enqueues removing an element at an index. - * - * @param {string} parentID ID of the parent component. - * @param {number} fromIndex Index of the element to remove. - * @private - */ -function enqueueRemove(parentID, fromIndex) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.REMOVE_NODE, - markupIndex: null, - textContent: null, - fromIndex: fromIndex, - toIndex: null - }); -} - -/** - * Enqueues setting the text content. - * - * @param {string} parentID ID of the parent component. - * @param {string} textContent Text content to set. - * @private - */ -function enqueueTextContent(parentID, textContent) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.TEXT_CONTENT, - markupIndex: null, - textContent: textContent, - fromIndex: null, - toIndex: null - }); -} - -/** - * Processes any enqueued updates. - * - * @private - */ -function processQueue() { - if (updateQueue.length) { - ReactComponentEnvironment.processChildrenUpdates( - updateQueue, - markupQueue - ); - clearQueue(); - } -} - -/** - * Clears any enqueued updates. - * - * @private - */ -function clearQueue() { - updateQueue.length = 0; - markupQueue.length = 0; -} - -/** - * ReactMultiChild are capable of reconciling multiple children. - * - * @class ReactMultiChild - * @internal - */ -var ReactMultiChild = { - - /** - * Provides common functionality for components that must reconcile multiple - * children. This is used by `ReactDOMComponent` to mount, update, and - * unmount child components. - * - * @lends {ReactMultiChild.prototype} - */ - Mixin: { - - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildren Nested child maps. - * @return {array} An array of mounted representations. - * @internal - */ - mountChildren: function(nestedChildren, transaction, context) { - var children = ReactChildReconciler.instantiateChildren( - nestedChildren, transaction, context - ); - this._renderedChildren = children; - var mountImages = []; - var index = 0; - for (var name in children) { - if (children.hasOwnProperty(name)) { - var child = children[name]; - // Inlined for performance, see `ReactInstanceHandles.createReactID`. - var rootID = this._rootNodeID + name; - var mountImage = ReactReconciler.mountComponent( - child, - rootID, - transaction, - context - ); - child._mountIndex = index; - mountImages.push(mountImage); - index++; - } - } - return mountImages; - }, - - /** - * Replaces any rendered children with a text content string. - * - * @param {string} nextContent String of content. - * @internal - */ - updateTextContent: function(nextContent) { - updateDepth++; - var errorThrown = true; - try { - var prevChildren = this._renderedChildren; - // Remove any rendered children. - ReactChildReconciler.unmountChildren(prevChildren); - // TODO: The setTextContent operation should be enough - for (var name in prevChildren) { - if (prevChildren.hasOwnProperty(name)) { - this._unmountChildByName(prevChildren[name], name); - } - } - // Set new text content. - this.setTextContent(nextContent); - errorThrown = false; - } finally { - updateDepth--; - if (!updateDepth) { - if (errorThrown) { - clearQueue(); - } else { - processQueue(); - } - } - } - }, - - /** - * Updates the rendered children with new children. - * - * @param {?object} nextNestedChildren Nested child maps. - * @param {ReactReconcileTransaction} transaction - * @internal - */ - updateChildren: function(nextNestedChildren, transaction, context) { - updateDepth++; - var errorThrown = true; - try { - this._updateChildren(nextNestedChildren, transaction, context); - errorThrown = false; - } finally { - updateDepth--; - if (!updateDepth) { - if (errorThrown) { - clearQueue(); - } else { - processQueue(); - } - } - - } - }, - - /** - * Improve performance by isolating this hot code path from the try/catch - * block in `updateChildren`. - * - * @param {?object} nextNestedChildren Nested child maps. - * @param {ReactReconcileTransaction} transaction - * @final - * @protected - */ - _updateChildren: function(nextNestedChildren, transaction, context) { - var prevChildren = this._renderedChildren; - var nextChildren = ReactChildReconciler.updateChildren( - prevChildren, nextNestedChildren, transaction, context - ); - this._renderedChildren = nextChildren; - if (!nextChildren && !prevChildren) { - return; - } - var name; - // `nextIndex` will increment for each child in `nextChildren`, but - // `lastIndex` will be the last index visited in `prevChildren`. - var lastIndex = 0; - var nextIndex = 0; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - var prevChild = prevChildren && prevChildren[name]; - var nextChild = nextChildren[name]; - if (prevChild === nextChild) { - this.moveChild(prevChild, nextIndex, lastIndex); - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - prevChild._mountIndex = nextIndex; - } else { - if (prevChild) { - // Update `lastIndex` before `_mountIndex` gets unset by unmounting. - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - this._unmountChildByName(prevChild, name); - } - // The child must be instantiated before it's mounted. - this._mountChildByNameAtIndex( - nextChild, name, nextIndex, transaction, context - ); - } - nextIndex++; - } - // Remove children that are no longer present. - for (name in prevChildren) { - if (prevChildren.hasOwnProperty(name) && - !(nextChildren && nextChildren.hasOwnProperty(name))) { - this._unmountChildByName(prevChildren[name], name); - } - } - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. - * - * @internal - */ - unmountChildren: function() { - var renderedChildren = this._renderedChildren; - ReactChildReconciler.unmountChildren(renderedChildren); - this._renderedChildren = null; - }, - - /** - * Moves a child component to the supplied index. - * - * @param {ReactComponent} child Component to move. - * @param {number} toIndex Destination index of the element. - * @param {number} lastIndex Last index visited of the siblings of `child`. - * @protected - */ - moveChild: function(child, toIndex, lastIndex) { - // If the index of `child` is less than `lastIndex`, then it needs to - // be moved. Otherwise, we do not need to move it because a child will be - // inserted or moved before `child`. - if (child._mountIndex < lastIndex) { - enqueueMove(this._rootNodeID, child._mountIndex, toIndex); - } - }, - - /** - * Creates a child component. - * - * @param {ReactComponent} child Component to create. - * @param {string} mountImage Markup to insert. - * @protected - */ - createChild: function(child, mountImage) { - enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex); - }, - - /** - * Removes a child component. - * - * @param {ReactComponent} child Child to remove. - * @protected - */ - removeChild: function(child) { - enqueueRemove(this._rootNodeID, child._mountIndex); - }, - - /** - * Sets this text content string. - * - * @param {string} textContent Text content to set. - * @protected - */ - setTextContent: function(textContent) { - enqueueTextContent(this._rootNodeID, textContent); - }, - - /** - * Mounts a child with the supplied name. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to mount. - * @param {string} name Name of the child. - * @param {number} index Index at which to insert the child. - * @param {ReactReconcileTransaction} transaction - * @private - */ - _mountChildByNameAtIndex: function( - child, - name, - index, - transaction, - context) { - // Inlined for performance, see `ReactInstanceHandles.createReactID`. - var rootID = this._rootNodeID + name; - var mountImage = ReactReconciler.mountComponent( - child, - rootID, - transaction, - context - ); - child._mountIndex = index; - this.createChild(child, mountImage); - }, - - /** - * Unmounts a rendered child by name. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to unmount. - * @param {string} name Name of the child in `this._renderedChildren`. - * @private - */ - _unmountChildByName: function(child, name) { - this.removeChild(child); - child._mountIndex = null; - } - - } - -}; - -module.exports = ReactMultiChild; - -},{"36":36,"41":41,"79":79,"89":89}],79:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMultiChildUpdateTypes - */ - -'use strict'; - -var keyMirror = _dereq_(156); - -/** - * When a component's children are updated, a series of update configuration - * objects are created in order to batch and serialize the required changes. - * - * Enumerates all the possible types of update configurations. - * - * @internal - */ -var ReactMultiChildUpdateTypes = keyMirror({ - INSERT_MARKUP: null, - MOVE_EXISTING: null, - REMOVE_NODE: null, - TEXT_CONTENT: null -}); - -module.exports = ReactMultiChildUpdateTypes; - -},{"156":156}],80:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactNativeComponent - */ - -'use strict'; - -var assign = _dereq_(29); -var invariant = _dereq_(150); - -var autoGenerateWrapperClass = null; -var genericComponentClass = null; -// This registry keeps track of wrapper classes around native tags -var tagToComponentClass = {}; -var textComponentClass = null; - -var ReactNativeComponentInjection = { - // This accepts a class that receives the tag string. This is a catch all - // that can render any kind of tag. - injectGenericComponentClass: function(componentClass) { - genericComponentClass = componentClass; - }, - // This accepts a text component class that takes the text string to be - // rendered as props. - injectTextComponentClass: function(componentClass) { - textComponentClass = componentClass; - }, - // This accepts a keyed object with classes as values. Each key represents a - // tag. That particular tag will use this class instead of the generic one. - injectComponentClasses: function(componentClasses) { - assign(tagToComponentClass, componentClasses); - }, - // Temporary hack since we expect DOM refs to behave like composites, - // for this release. - injectAutoWrapper: function(wrapperFactory) { - autoGenerateWrapperClass = wrapperFactory; - } -}; - -/** - * Get a composite component wrapper class for a specific tag. - * - * @param {ReactElement} element The tag for which to get the class. - * @return {function} The React class constructor function. - */ -function getComponentClassForElement(element) { - if (typeof element.type === 'function') { - return element.type; - } - var tag = element.type; - var componentClass = tagToComponentClass[tag]; - if (componentClass == null) { - tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag); - } - return componentClass; -} - -/** - * Get a native internal component class for a specific tag. - * - * @param {ReactElement} element The element to create. - * @return {function} The internal class constructor function. - */ -function createInternalComponent(element) { - ("production" !== "development" ? invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - element.type - ) : invariant(genericComponentClass)); - return new genericComponentClass(element.type, element.props); -} - -/** - * @param {ReactText} text - * @return {ReactComponent} - */ -function createInstanceForText(text) { - return new textComponentClass(text); -} - -/** - * @param {ReactComponent} component - * @return {boolean} - */ -function isTextComponent(component) { - return component instanceof textComponentClass; -} - -var ReactNativeComponent = { - getComponentClassForElement: getComponentClassForElement, - createInternalComponent: createInternalComponent, - createInstanceForText: createInstanceForText, - isTextComponent: isTextComponent, - injection: ReactNativeComponentInjection -}; - -module.exports = ReactNativeComponent; - -},{"150":150,"29":29}],81:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactOwner - */ - -'use strict'; - -var invariant = _dereq_(150); - -/** - * ReactOwners are capable of storing references to owned components. - * - * All components are capable of //being// referenced by owner components, but - * only ReactOwner components are capable of //referencing// owned components. - * The named reference is known as a "ref". - * - * Refs are available when mounted and updated during reconciliation. - * - * var MyComponent = React.createClass({ - * render: function() { - * return ( - * <div onClick={this.handleClick}> - * <CustomComponent ref="custom" /> - * </div> - * ); - * }, - * handleClick: function() { - * this.refs.custom.handleClick(); - * }, - * componentDidMount: function() { - * this.refs.custom.initialize(); - * } - * }); - * - * Refs should rarely be used. When refs are used, they should only be done to - * control data that is not handled by React's data flow. - * - * @class ReactOwner - */ -var ReactOwner = { - - /** - * @param {?object} object - * @return {boolean} True if `object` is a valid owner. - * @final - */ - isValidOwner: function(object) { - return !!( - (object && - typeof object.attachRef === 'function' && typeof object.detachRef === 'function') - ); - }, - - /** - * Adds a component by ref to an owner component. - * - * @param {ReactComponent} component Component to reference. - * @param {string} ref Name by which to refer to the component. - * @param {ReactOwner} owner Component on which to record the ref. - * @final - * @internal - */ - addComponentAsRefTo: function(component, ref, owner) { - ("production" !== "development" ? invariant( - ReactOwner.isValidOwner(owner), - 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to add a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ) : invariant(ReactOwner.isValidOwner(owner))); - owner.attachRef(ref, component); - }, - - /** - * Removes a component by ref from an owner component. - * - * @param {ReactComponent} component Component to dereference. - * @param {string} ref Name of the ref to remove. - * @param {ReactOwner} owner Component on which the ref is recorded. - * @final - * @internal - */ - removeComponentAsRefFrom: function(component, ref, owner) { - ("production" !== "development" ? invariant( - ReactOwner.isValidOwner(owner), - 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to remove a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ) : invariant(ReactOwner.isValidOwner(owner))); - // Check that `component` is still the current ref because we do not want to - // detach the ref if another component stole it. - if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) { - owner.detachRef(ref); - } - } - -}; - -module.exports = ReactOwner; - -},{"150":150}],82:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPerf - * @typechecks static-only - */ - -'use strict'; - -/** - * ReactPerf is a general AOP system designed to measure performance. This - * module only has the hooks: see ReactDefaultPerf for the analysis tool. - */ -var ReactPerf = { - /** - * Boolean to enable/disable measurement. Set to false by default to prevent - * accidental logging and perf loss. - */ - enableMeasure: false, - - /** - * Holds onto the measure function in use. By default, don't measure - * anything, but we'll override this if we inject a measure function. - */ - storedMeasure: _noMeasure, - - /** - * @param {object} object - * @param {string} objectName - * @param {object<string>} methodNames - */ - measureMethods: function(object, objectName, methodNames) { - if ("production" !== "development") { - for (var key in methodNames) { - if (!methodNames.hasOwnProperty(key)) { - continue; - } - object[key] = ReactPerf.measure( - objectName, - methodNames[key], - object[key] - ); - } - } - }, - - /** - * Use this to wrap methods you want to measure. Zero overhead in production. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ - measure: function(objName, fnName, func) { - if ("production" !== "development") { - var measuredFunc = null; - var wrapper = function() { - if (ReactPerf.enableMeasure) { - if (!measuredFunc) { - measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); - } - return measuredFunc.apply(this, arguments); - } - return func.apply(this, arguments); - }; - wrapper.displayName = objName + '_' + fnName; - return wrapper; - } - return func; - }, - - injection: { - /** - * @param {function} measure - */ - injectMeasure: function(measure) { - ReactPerf.storedMeasure = measure; - } - } -}; - -/** - * Simply passes through the measured function, without measuring it. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ -function _noMeasure(objName, fnName, func) { - return func; -} - -module.exports = ReactPerf; - -},{}],83:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTransferer - */ - -'use strict'; - -var assign = _dereq_(29); -var emptyFunction = _dereq_(129); -var joinClasses = _dereq_(155); - -/** - * Creates a transfer strategy that will merge prop values using the supplied - * `mergeStrategy`. If a prop was previously unset, this just sets it. - * - * @param {function} mergeStrategy - * @return {function} - */ -function createTransferStrategy(mergeStrategy) { - return function(props, key, value) { - if (!props.hasOwnProperty(key)) { - props[key] = value; - } else { - props[key] = mergeStrategy(props[key], value); - } - }; -} - -var transferStrategyMerge = createTransferStrategy(function(a, b) { - // `merge` overrides the first object's (`props[key]` above) keys using the - // second object's (`value`) keys. An object's style's existing `propA` would - // get overridden. Flip the order here. - return assign({}, b, a); -}); - -/** - * Transfer strategies dictate how props are transferred by `transferPropsTo`. - * NOTE: if you add any more exceptions to this list you should be sure to - * update `cloneWithProps()` accordingly. - */ -var TransferStrategies = { - /** - * Never transfer `children`. - */ - children: emptyFunction, - /** - * Transfer the `className` prop by merging them. - */ - className: createTransferStrategy(joinClasses), - /** - * Transfer the `style` prop (which is an object) by merging them. - */ - style: transferStrategyMerge -}; - -/** - * Mutates the first argument by transferring the properties from the second - * argument. - * - * @param {object} props - * @param {object} newProps - * @return {object} - */ -function transferInto(props, newProps) { - for (var thisKey in newProps) { - if (!newProps.hasOwnProperty(thisKey)) { - continue; - } - - var transferStrategy = TransferStrategies[thisKey]; - - if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { - transferStrategy(props, thisKey, newProps[thisKey]); - } else if (!props.hasOwnProperty(thisKey)) { - props[thisKey] = newProps[thisKey]; - } - } - return props; -} - -/** - * ReactPropTransferer are capable of transferring props to another component - * using a `transferPropsTo` method. - * - * @class ReactPropTransferer - */ -var ReactPropTransferer = { - - /** - * Merge two props objects using TransferStrategies. - * - * @param {object} oldProps original props (they take precedence) - * @param {object} newProps new props to merge in - * @return {object} a new object containing both sets of props merged. - */ - mergeProps: function(oldProps, newProps) { - return transferInto(assign({}, oldProps), newProps); - } - -}; - -module.exports = ReactPropTransferer; - -},{"129":129,"155":155,"29":29}],84:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypeLocationNames - */ - -'use strict'; - -var ReactPropTypeLocationNames = {}; - -if ("production" !== "development") { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; - -},{}],85:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypeLocations - */ - -'use strict'; - -var keyMirror = _dereq_(156); - -var ReactPropTypeLocations = keyMirror({ - prop: null, - context: null, - childContext: null -}); - -module.exports = ReactPropTypeLocations; - -},{"156":156}],86:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypes - */ - -'use strict'; - -var ReactElement = _dereq_(63); -var ReactFragment = _dereq_(69); -var ReactPropTypeLocationNames = _dereq_(84); - -var emptyFunction = _dereq_(129); - -/** - * Collection of methods that allow declaration and validation of props that are - * supplied to React components. Example usage: - * - * var Props = require('ReactPropTypes'); - * var MyArticle = React.createClass({ - * propTypes: { - * // An optional string prop named "description". - * description: Props.string, - * - * // A required enum prop named "category". - * category: Props.oneOf(['News','Photos']).isRequired, - * - * // A prop named "dialog" that requires an instance of Dialog. - * dialog: Props.instanceOf(Dialog).isRequired - * }, - * render: function() { ... } - * }); - * - * A more formal specification of how these methods are used: - * - * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) - * decl := ReactPropTypes.{type}(.isRequired)? - * - * Each and every declaration produces a function with the same signature. This - * allows the creation of custom validation functions. For example: - * - * var MyLink = React.createClass({ - * propTypes: { - * // An optional string or URI prop named "href". - * href: function(props, propName, componentName) { - * var propValue = props[propName]; - * if (propValue != null && typeof propValue !== 'string' && - * !(propValue instanceof URI)) { - * return new Error( - * 'Expected a string or an URI for ' + propName + ' in ' + - * componentName - * ); - * } - * } - * }, - * render: function() {...} - * }); - * - * @internal - */ - -var ANONYMOUS = '<<anonymous>>'; - -var elementTypeChecker = createElementTypeChecker(); -var nodeTypeChecker = createNodeChecker(); - -var ReactPropTypes = { - array: createPrimitiveTypeChecker('array'), - bool: createPrimitiveTypeChecker('boolean'), - func: createPrimitiveTypeChecker('function'), - number: createPrimitiveTypeChecker('number'), - object: createPrimitiveTypeChecker('object'), - string: createPrimitiveTypeChecker('string'), - - any: createAnyTypeChecker(), - arrayOf: createArrayOfTypeChecker, - element: elementTypeChecker, - instanceOf: createInstanceTypeChecker, - node: nodeTypeChecker, - objectOf: createObjectOfTypeChecker, - oneOf: createEnumTypeChecker, - oneOfType: createUnionTypeChecker, - shape: createShapeTypeChecker -}; - -function createChainableTypeChecker(validate) { - function checkType(isRequired, props, propName, componentName, location) { - componentName = componentName || ANONYMOUS; - if (props[propName] == null) { - var locationName = ReactPropTypeLocationNames[location]; - if (isRequired) { - return new Error( - ("Required " + locationName + " `" + propName + "` was not specified in ") + - ("`" + componentName + "`.") - ); - } - return null; - } else { - return validate(props, propName, componentName, location); - } - } - - var chainedCheckType = checkType.bind(null, false); - chainedCheckType.isRequired = checkType.bind(null, true); - - return chainedCheckType; -} - -function createPrimitiveTypeChecker(expectedType) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== expectedType) { - var locationName = ReactPropTypeLocationNames[location]; - // `propValue` being instance of, say, date/regexp, pass the 'object' - // check, but we can offer a more precise error message here rather than - // 'of type `object`'. - var preciseType = getPreciseType(propValue); - - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type `" + preciseType + "` ") + - ("supplied to `" + componentName + "`, expected `" + expectedType + "`.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createAnyTypeChecker() { - return createChainableTypeChecker(emptyFunction.thatReturns(null)); -} - -function createArrayOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - if (!Array.isArray(propValue)) { - var locationName = ReactPropTypeLocationNames[location]; - var propType = getPropType(propValue); - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type ") + - ("`" + propType + "` supplied to `" + componentName + "`, expected an array.") - ); - } - for (var i = 0; i < propValue.length; i++) { - var error = typeChecker(propValue, i, componentName, location); - if (error instanceof Error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createElementTypeChecker() { - function validate(props, propName, componentName, location) { - if (!ReactElement.isValidElement(props[propName])) { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected a ReactElement.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createInstanceTypeChecker(expectedClass) { - function validate(props, propName, componentName, location) { - if (!(props[propName] instanceof expectedClass)) { - var locationName = ReactPropTypeLocationNames[location]; - var expectedClassName = expectedClass.name || ANONYMOUS; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected instance of `" + expectedClassName + "`.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createEnumTypeChecker(expectedValues) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - for (var i = 0; i < expectedValues.length; i++) { - if (propValue === expectedValues[i]) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - var valuesString = JSON.stringify(expectedValues); - return new Error( - ("Invalid " + locationName + " `" + propName + "` of value `" + propValue + "` ") + - ("supplied to `" + componentName + "`, expected one of " + valuesString + ".") - ); - } - return createChainableTypeChecker(validate); -} - -function createObjectOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type ") + - ("`" + propType + "` supplied to `" + componentName + "`, expected an object.") - ); - } - for (var key in propValue) { - if (propValue.hasOwnProperty(key)) { - var error = typeChecker(propValue, key, componentName, location); - if (error instanceof Error) { - return error; - } - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createUnionTypeChecker(arrayOfTypeCheckers) { - function validate(props, propName, componentName, location) { - for (var i = 0; i < arrayOfTypeCheckers.length; i++) { - var checker = arrayOfTypeCheckers[i]; - if (checker(props, propName, componentName, location) == null) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`.") - ); - } - return createChainableTypeChecker(validate); -} - -function createNodeChecker() { - function validate(props, propName, componentName, location) { - if (!isNode(props[propName])) { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected a ReactNode.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createShapeTypeChecker(shapeTypes) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type `" + propType + "` ") + - ("supplied to `" + componentName + "`, expected `object`.") - ); - } - for (var key in shapeTypes) { - var checker = shapeTypes[key]; - if (!checker) { - continue; - } - var error = checker(propValue, key, componentName, location); - if (error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function isNode(propValue) { - switch (typeof propValue) { - case 'number': - case 'string': - case 'undefined': - return true; - case 'boolean': - return !propValue; - case 'object': - if (Array.isArray(propValue)) { - return propValue.every(isNode); - } - if (propValue === null || ReactElement.isValidElement(propValue)) { - return true; - } - propValue = ReactFragment.extractIfFragment(propValue); - for (var k in propValue) { - if (!isNode(propValue[k])) { - return false; - } - } - return true; - default: - return false; - } -} - -// Equivalent of `typeof` but with special handling for array and regexp. -function getPropType(propValue) { - var propType = typeof propValue; - if (Array.isArray(propValue)) { - return 'array'; - } - if (propValue instanceof RegExp) { - // Old webkits (at least until Android 4.0) return 'function' rather than - // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ - // passes PropTypes.object. - return 'object'; - } - return propType; -} - -// This handles more types than `getPropType`. Only used for error messages. -// See `createPrimitiveTypeChecker`. -function getPreciseType(propValue) { - var propType = getPropType(propValue); - if (propType === 'object') { - if (propValue instanceof Date) { - return 'date'; - } else if (propValue instanceof RegExp) { - return 'regexp'; - } - } - return propType; -} - -module.exports = ReactPropTypes; - -},{"129":129,"63":63,"69":69,"84":84}],87:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPutListenerQueue - */ - -'use strict'; - -var PooledClass = _dereq_(30); -var ReactBrowserEventEmitter = _dereq_(33); - -var assign = _dereq_(29); - -function ReactPutListenerQueue() { - this.listenersToPut = []; -} - -assign(ReactPutListenerQueue.prototype, { - enqueuePutListener: function(rootNodeID, propKey, propValue) { - this.listenersToPut.push({ - rootNodeID: rootNodeID, - propKey: propKey, - propValue: propValue - }); - }, - - putListeners: function() { - for (var i = 0; i < this.listenersToPut.length; i++) { - var listenerToPut = this.listenersToPut[i]; - ReactBrowserEventEmitter.putListener( - listenerToPut.rootNodeID, - listenerToPut.propKey, - listenerToPut.propValue - ); - } - }, - - reset: function() { - this.listenersToPut.length = 0; - }, - - destructor: function() { - this.reset(); - } -}); - -PooledClass.addPoolingTo(ReactPutListenerQueue); - -module.exports = ReactPutListenerQueue; - -},{"29":29,"30":30,"33":33}],88:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactReconcileTransaction - * @typechecks static-only - */ - -'use strict'; - -var CallbackQueue = _dereq_(7); -var PooledClass = _dereq_(30); -var ReactBrowserEventEmitter = _dereq_(33); -var ReactInputSelection = _dereq_(71); -var ReactPutListenerQueue = _dereq_(87); -var Transaction = _dereq_(116); - -var assign = _dereq_(29); - -/** - * Ensures that, when possible, the selection range (currently selected text - * input) is not disturbed by performing the transaction. - */ -var SELECTION_RESTORATION = { - /** - * @return {Selection} Selection information. - */ - initialize: ReactInputSelection.getSelectionInformation, - /** - * @param {Selection} sel Selection information returned from `initialize`. - */ - close: ReactInputSelection.restoreSelection -}; - -/** - * Suppresses events (blur/focus) that could be inadvertently dispatched due to - * high level DOM manipulations (like temporarily removing a text input from the - * DOM). - */ -var EVENT_SUPPRESSION = { - /** - * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before - * the reconciliation. - */ - initialize: function() { - var currentlyEnabled = ReactBrowserEventEmitter.isEnabled(); - ReactBrowserEventEmitter.setEnabled(false); - return currentlyEnabled; - }, - - /** - * @param {boolean} previouslyEnabled Enabled status of - * `ReactBrowserEventEmitter` before the reconciliation occured. `close` - * restores the previous value. - */ - close: function(previouslyEnabled) { - ReactBrowserEventEmitter.setEnabled(previouslyEnabled); - } -}; - -/** - * Provides a queue for collecting `componentDidMount` and - * `componentDidUpdate` callbacks during the the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function() { - this.reactMountReady.reset(); - }, - - /** - * After DOM is flushed, invoke all registered `onDOMReady` callbacks. - */ - close: function() { - this.reactMountReady.notifyAll(); - } -}; - -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, - - close: function() { - this.putListenerQueue.putListeners(); - } -}; - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - SELECTION_RESTORATION, - EVENT_SUPPRESSION, - ON_DOM_READY_QUEUEING -]; - -/** - * Currently: - * - The order that these are listed in the transaction is critical: - * - Suppresses events. - * - Restores selection range. - * - * Future: - * - Restore document/overflow scroll positions that were unintentionally - * modified via DOM insertions above the top viewport boundary. - * - Implement/integrate with customized constraint based layout system and keep - * track of which dimensions must be remeasured. - * - * @class ReactReconcileTransaction - */ -function ReactReconcileTransaction() { - this.reinitializeTransaction(); - // Only server-side rendering really needs this option (see - // `ReactServerRendering`), but server-side uses - // `ReactServerRenderingTransaction` instead. This option is here so that it's - // accessible and defaults to false when `ReactDOMComponent` and - // `ReactTextComponent` checks it in `mountComponent`.` - this.renderToStaticMarkup = false; - this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array<object>} List of operation wrap proceedures. - * TODO: convert to array<TransactionWrapper> - */ - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function() { - return this.reactMountReady; - }, - - getPutListenerQueue: function() { - return this.putListenerQueue; - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. - */ - destructor: function() { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; - - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; - } -}; - - -assign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin); - -PooledClass.addPoolingTo(ReactReconcileTransaction); - -module.exports = ReactReconcileTransaction; - -},{"116":116,"29":29,"30":30,"33":33,"7":7,"71":71,"87":87}],89:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactReconciler - */ - -'use strict'; - -var ReactRef = _dereq_(90); -var ReactElementValidator = _dereq_(64); - -/** - * Helper to call ReactRef.attachRefs with this composite component, split out - * to avoid allocations in the transaction mount-ready queue. - */ -function attachRefs() { - ReactRef.attachRefs(this, this._currentElement); -} - -var ReactReconciler = { - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactComponent} internalInstance - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function(internalInstance, rootID, transaction, context) { - var markup = internalInstance.mountComponent(rootID, transaction, context); - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps( - internalInstance._currentElement - ); - } - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - return markup; - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function(internalInstance) { - ReactRef.detachRefs(internalInstance, internalInstance._currentElement); - internalInstance.unmountComponent(); - }, - - /** - * Update a component using a new element. - * - * @param {ReactComponent} internalInstance - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @internal - */ - receiveComponent: function( - internalInstance, nextElement, transaction, context - ) { - var prevElement = internalInstance._currentElement; - - if (nextElement === prevElement && nextElement._owner != null) { - // Since elements are immutable after the owner is rendered, - // we can do a cheap identity compare here to determine if this is a - // superfluous reconcile. It's possible for state to be mutable but such - // change should trigger an update of the owner which would recreate - // the element. We explicitly check for the existence of an owner since - // it's possible for an element created outside a composite to be - // deeply mutated and reused. - return; - } - - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - var refsChanged = ReactRef.shouldUpdateRefs( - prevElement, - nextElement - ); - - if (refsChanged) { - ReactRef.detachRefs(internalInstance, prevElement); - } - - internalInstance.receiveComponent(nextElement, transaction, context); - - if (refsChanged) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - }, - - /** - * Flush any dirty changes in a component. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function( - internalInstance, - transaction - ) { - internalInstance.performUpdateIfNecessary(transaction); - } - -}; - -module.exports = ReactReconciler; - -},{"64":64,"90":90}],90:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactRef - */ - -'use strict'; - -var ReactOwner = _dereq_(81); - -var ReactRef = {}; - -function attachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(component.getPublicInstance()); - } else { - // Legacy ref - ReactOwner.addComponentAsRefTo(component, ref, owner); - } -} - -function detachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(null); - } else { - // Legacy ref - ReactOwner.removeComponentAsRefFrom(component, ref, owner); - } -} - -ReactRef.attachRefs = function(instance, element) { - var ref = element.ref; - if (ref != null) { - attachRef(ref, instance, element._owner); - } -}; - -ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { - // If either the owner or a `ref` has changed, make sure the newest owner - // has stored a reference to `this`, and the previous owner (if different) - // has forgotten the reference to `this`. We use the element instead - // of the public this.props because the post processing cannot determine - // a ref. The ref conceptually lives on the element. - - // TODO: Should this even be possible? The owner cannot change because - // it's forbidden by shouldUpdateReactComponent. The ref can change - // if you swap the keys of but not the refs. Reconsider where this check - // is made. It probably belongs where the key checking and - // instantiateReactComponent is done. - - return ( - nextElement._owner !== prevElement._owner || - nextElement.ref !== prevElement.ref - ); -}; - -ReactRef.detachRefs = function(instance, element) { - var ref = element.ref; - if (ref != null) { - detachRef(ref, instance, element._owner); - } -}; - -module.exports = ReactRef; - -},{"81":81}],91:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactRootIndex - * @typechecks - */ - -'use strict'; - -var ReactRootIndexInjection = { - /** - * @param {function} _createReactRootIndex - */ - injectCreateReactRootIndex: function(_createReactRootIndex) { - ReactRootIndex.createReactRootIndex = _createReactRootIndex; - } -}; - -var ReactRootIndex = { - createReactRootIndex: null, - injection: ReactRootIndexInjection -}; - -module.exports = ReactRootIndex; - -},{}],92:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks static-only - * @providesModule ReactServerRendering - */ -'use strict'; - -var ReactElement = _dereq_(63); -var ReactInstanceHandles = _dereq_(72); -var ReactMarkupChecksum = _dereq_(76); -var ReactServerRenderingTransaction = - _dereq_(93); - -var emptyObject = _dereq_(130); -var instantiateReactComponent = _dereq_(149); -var invariant = _dereq_(150); - -/** - * @param {ReactElement} element - * @return {string} the HTML markup - */ -function renderToString(element) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(element), - 'renderToString(): You must pass a valid ReactElement.' - ) : invariant(ReactElement.isValidElement(element))); - - var transaction; - try { - var id = ReactInstanceHandles.createReactRootID(); - transaction = ReactServerRenderingTransaction.getPooled(false); - - return transaction.perform(function() { - var componentInstance = instantiateReactComponent(element, null); - var markup = - componentInstance.mountComponent(id, transaction, emptyObject); - return ReactMarkupChecksum.addChecksumToMarkup(markup); - }, null); - } finally { - ReactServerRenderingTransaction.release(transaction); - } -} - -/** - * @param {ReactElement} element - * @return {string} the HTML markup, without the extra React ID and checksum - * (for generating static pages) - */ -function renderToStaticMarkup(element) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(element), - 'renderToStaticMarkup(): You must pass a valid ReactElement.' - ) : invariant(ReactElement.isValidElement(element))); - - var transaction; - try { - var id = ReactInstanceHandles.createReactRootID(); - transaction = ReactServerRenderingTransaction.getPooled(true); - - return transaction.perform(function() { - var componentInstance = instantiateReactComponent(element, null); - return componentInstance.mountComponent(id, transaction, emptyObject); - }, null); - } finally { - ReactServerRenderingTransaction.release(transaction); - } -} - -module.exports = { - renderToString: renderToString, - renderToStaticMarkup: renderToStaticMarkup -}; - -},{"130":130,"149":149,"150":150,"63":63,"72":72,"76":76,"93":93}],93:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactServerRenderingTransaction - * @typechecks - */ - -'use strict'; - -var PooledClass = _dereq_(30); -var CallbackQueue = _dereq_(7); -var ReactPutListenerQueue = _dereq_(87); -var Transaction = _dereq_(116); - -var assign = _dereq_(29); -var emptyFunction = _dereq_(129); - -/** - * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks - * during the performing of the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function() { - this.reactMountReady.reset(); - }, - - close: emptyFunction -}; - -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, - - close: emptyFunction -}; - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - ON_DOM_READY_QUEUEING -]; - -/** - * @class ReactServerRenderingTransaction - * @param {boolean} renderToStaticMarkup - */ -function ReactServerRenderingTransaction(renderToStaticMarkup) { - this.reinitializeTransaction(); - this.renderToStaticMarkup = renderToStaticMarkup; - this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array} Empty list of operation wrap proceedures. - */ - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function() { - return this.reactMountReady; - }, - - getPutListenerQueue: function() { - return this.putListenerQueue; - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. - */ - destructor: function() { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; - - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; - } -}; - - -assign( - ReactServerRenderingTransaction.prototype, - Transaction.Mixin, - Mixin -); - -PooledClass.addPoolingTo(ReactServerRenderingTransaction); - -module.exports = ReactServerRenderingTransaction; - -},{"116":116,"129":129,"29":29,"30":30,"7":7,"87":87}],94:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactStateSetters - */ - -'use strict'; - -var ReactStateSetters = { - /** - * Returns a function that calls the provided function, and uses the result - * of that to set the component's state. - * - * @param {ReactCompositeComponent} component - * @param {function} funcReturningState Returned callback uses this to - * determine how to update state. - * @return {function} callback that when invoked uses funcReturningState to - * determined the object literal to setState. - */ - createStateSetter: function(component, funcReturningState) { - return function(a, b, c, d, e, f) { - var partialState = funcReturningState.call(component, a, b, c, d, e, f); - if (partialState) { - component.setState(partialState); - } - }; - }, - - /** - * Returns a single-argument callback that can be used to update a single - * key in the component's state. - * - * Note: this is memoized function, which makes it inexpensive to call. - * - * @param {ReactCompositeComponent} component - * @param {string} key The key in the state that you should update. - * @return {function} callback of 1 argument which calls setState() with - * the provided keyName and callback argument. - */ - createStateKeySetter: function(component, key) { - // Memoize the setters. - var cache = component.__keySetters || (component.__keySetters = {}); - return cache[key] || (cache[key] = createStateKeySetter(component, key)); - } -}; - -function createStateKeySetter(component, key) { - // Partial state is allocated outside of the function closure so it can be - // reused with every call, avoiding memory allocation when this function - // is called. - var partialState = {}; - return function stateKeySetter(value) { - partialState[key] = value; - component.setState(partialState); - }; -} - -ReactStateSetters.Mixin = { - /** - * Returns a function that calls the provided function, and uses the result - * of that to set the component's state. - * - * For example, these statements are equivalent: - * - * this.setState({x: 1}); - * this.createStateSetter(function(xValue) { - * return {x: xValue}; - * })(1); - * - * @param {function} funcReturningState Returned callback uses this to - * determine how to update state. - * @return {function} callback that when invoked uses funcReturningState to - * determined the object literal to setState. - */ - createStateSetter: function(funcReturningState) { - return ReactStateSetters.createStateSetter(this, funcReturningState); - }, - - /** - * Returns a single-argument callback that can be used to update a single - * key in the component's state. - * - * For example, these statements are equivalent: - * - * this.setState({x: 1}); - * this.createStateKeySetter('x')(1); - * - * Note: this is memoized function, which makes it inexpensive to call. - * - * @param {string} key The key in the state that you should update. - * @return {function} callback of 1 argument which calls setState() with - * the provided keyName and callback argument. - */ - createStateKeySetter: function(key) { - return ReactStateSetters.createStateKeySetter(this, key); - } -}; - -module.exports = ReactStateSetters; - -},{}],95:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactTestUtils - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPluginHub = _dereq_(18); -var EventPropagators = _dereq_(21); -var React = _dereq_(31); -var ReactElement = _dereq_(63); -var ReactEmptyComponent = _dereq_(65); -var ReactBrowserEventEmitter = _dereq_(33); -var ReactCompositeComponent = _dereq_(43); -var ReactInstanceHandles = _dereq_(72); -var ReactInstanceMap = _dereq_(73); -var ReactMount = _dereq_(77); -var ReactUpdates = _dereq_(100); -var SyntheticEvent = _dereq_(108); - -var assign = _dereq_(29); -var emptyObject = _dereq_(130); - -var topLevelTypes = EventConstants.topLevelTypes; - -function Event(suffix) {} - -/** - * @class ReactTestUtils - */ - -/** - * Todo: Support the entire DOM.scry query syntax. For now, these simple - * utilities will suffice for testing purposes. - * @lends ReactTestUtils - */ -var ReactTestUtils = { - renderIntoDocument: function(instance) { - var div = document.createElement('div'); - // None of our tests actually require attaching the container to the - // DOM, and doing so creates a mess that we rely on test isolation to - // clean up, so we're going to stop honoring the name of this method - // (and probably rename it eventually) if no problems arise. - // document.documentElement.appendChild(div); - return React.render(instance, div); - }, - - isElement: function(element) { - return ReactElement.isValidElement(element); - }, - - isElementOfType: function(inst, convenienceConstructor) { - return ( - ReactElement.isValidElement(inst) && - inst.type === convenienceConstructor - ); - }, - - isDOMComponent: function(inst) { - // TODO: Fix this heuristic. It's just here because composites can currently - // pretend to be DOM components. - return !!(inst && inst.tagName && inst.getDOMNode); - }, - - isDOMComponentElement: function(inst) { - return !!(inst && - ReactElement.isValidElement(inst) && - !!inst.tagName); - }, - - isCompositeComponent: function(inst) { - return typeof inst.render === 'function' && - typeof inst.setState === 'function'; - }, - - isCompositeComponentWithType: function(inst, type) { - return !!(ReactTestUtils.isCompositeComponent(inst) && - (inst.constructor === type)); - }, - - isCompositeComponentElement: function(inst) { - if (!ReactElement.isValidElement(inst)) { - return false; - } - // We check the prototype of the type that will get mounted, not the - // instance itself. This is a future proof way of duck typing. - var prototype = inst.type.prototype; - return ( - typeof prototype.render === 'function' && - typeof prototype.setState === 'function' - ); - }, - - isCompositeComponentElementWithType: function(inst, type) { - return !!(ReactTestUtils.isCompositeComponentElement(inst) && - (inst.constructor === type)); - }, - - getRenderedChildOfCompositeComponent: function(inst) { - if (!ReactTestUtils.isCompositeComponent(inst)) { - return null; - } - var internalInstance = ReactInstanceMap.get(inst); - return internalInstance._renderedComponent.getPublicInstance(); - }, - - findAllInRenderedTree: function(inst, test) { - if (!inst) { - return []; - } - var ret = test(inst) ? [inst] : []; - if (ReactTestUtils.isDOMComponent(inst)) { - var internalInstance = ReactInstanceMap.get(inst); - var renderedChildren = internalInstance - ._renderedComponent - ._renderedChildren; - var key; - for (key in renderedChildren) { - if (!renderedChildren.hasOwnProperty(key)) { - continue; - } - if (!renderedChildren[key].getPublicInstance) { - continue; - } - ret = ret.concat( - ReactTestUtils.findAllInRenderedTree( - renderedChildren[key].getPublicInstance(), - test - ) - ); - } - } else if (ReactTestUtils.isCompositeComponent(inst)) { - ret = ret.concat( - ReactTestUtils.findAllInRenderedTree( - ReactTestUtils.getRenderedChildOfCompositeComponent(inst), - test - ) - ); - } - return ret; - }, - - /** - * Finds all instance of components in the rendered tree that are DOM - * components with the class name matching `className`. - * @return an array of all the matches. - */ - scryRenderedDOMComponentsWithClass: function(root, className) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - var instClassName = inst.props.className; - return ReactTestUtils.isDOMComponent(inst) && ( - (instClassName && (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1) - ); - }); - }, - - /** - * Like scryRenderedDOMComponentsWithClass but expects there to be one result, - * and returns that one result, or throws exception if there is any other - * number of matches besides one. - * @return {!ReactDOMComponent} The one match. - */ - findRenderedDOMComponentWithClass: function(root, className) { - var all = - ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); - if (all.length !== 1) { - throw new Error('Did not find exactly one match ' + - '(found: ' + all.length + ') for class:' + className - ); - } - return all[0]; - }, - - - /** - * Finds all instance of components in the rendered tree that are DOM - * components with the tag name matching `tagName`. - * @return an array of all the matches. - */ - scryRenderedDOMComponentsWithTag: function(root, tagName) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - return ReactTestUtils.isDOMComponent(inst) && - inst.tagName === tagName.toUpperCase(); - }); - }, - - /** - * Like scryRenderedDOMComponentsWithTag but expects there to be one result, - * and returns that one result, or throws exception if there is any other - * number of matches besides one. - * @return {!ReactDOMComponent} The one match. - */ - findRenderedDOMComponentWithTag: function(root, tagName) { - var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName); - if (all.length !== 1) { - throw new Error('Did not find exactly one match for tag:' + tagName); - } - return all[0]; - }, - - - /** - * Finds all instances of components with type equal to `componentType`. - * @return an array of all the matches. - */ - scryRenderedComponentsWithType: function(root, componentType) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - return ReactTestUtils.isCompositeComponentWithType( - inst, - componentType - ); - }); - }, - - /** - * Same as `scryRenderedComponentsWithType` but expects there to be one result - * and returns that one result, or throws exception if there is any other - * number of matches besides one. - * @return {!ReactComponent} The one match. - */ - findRenderedComponentWithType: function(root, componentType) { - var all = ReactTestUtils.scryRenderedComponentsWithType( - root, - componentType - ); - if (all.length !== 1) { - throw new Error( - 'Did not find exactly one match for componentType:' + componentType - ); - } - return all[0]; - }, - - /** - * Pass a mocked component module to this method to augment it with - * useful methods that allow it to be used as a dummy React component. - * Instead of rendering as usual, the component will become a simple - * <div> containing any provided children. - * - * @param {object} module the mock function object exported from a - * module that defines the component to be mocked - * @param {?string} mockTagName optional dummy root tag name to return - * from render method (overrides - * module.mockTagName if provided) - * @return {object} the ReactTestUtils object (for chaining) - */ - mockComponent: function(module, mockTagName) { - mockTagName = mockTagName || module.mockTagName || "div"; - - module.prototype.render.mockImplementation(function() { - return React.createElement( - mockTagName, - null, - this.props.children - ); - }); - - return this; - }, - - /** - * Simulates a top level event being dispatched from a raw event that occured - * on an `Element` node. - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes` - * @param {!Element} node The dom to simulate an event occurring on. - * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. - */ - simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) { - fakeNativeEvent.target = node; - ReactBrowserEventEmitter.ReactEventListener.dispatchEvent( - topLevelType, - fakeNativeEvent - ); - }, - - /** - * Simulates a top level event being dispatched from a raw event that occured - * on the `ReactDOMComponent` `comp`. - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`. - * @param comp {!ReactDOMComponent} - * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. - */ - simulateNativeEventOnDOMComponent: function( - topLevelType, - comp, - fakeNativeEvent) { - ReactTestUtils.simulateNativeEventOnNode( - topLevelType, - comp.getDOMNode(), - fakeNativeEvent - ); - }, - - nativeTouchData: function(x, y) { - return { - touches: [ - {pageX: x, pageY: y} - ] - }; - }, - - createRenderer: function() { - return new ReactShallowRenderer(); - }, - - Simulate: null, - SimulateNative: {} -}; - -/** - * @class ReactShallowRenderer - */ -var ReactShallowRenderer = function() { - this._instance = null; -}; - -ReactShallowRenderer.prototype.getRenderOutput = function() { - return ( - (this._instance && this._instance._renderedComponent && - this._instance._renderedComponent._renderedOutput) - || null - ); -}; - -var NoopInternalComponent = function(element) { - this._renderedOutput = element; - this._currentElement = element === null || element === false ? - ReactEmptyComponent.emptyElement : - element; -}; - -NoopInternalComponent.prototype = { - - mountComponent: function() { - }, - - receiveComponent: function(element) { - this._renderedOutput = element; - this._currentElement = element === null || element === false ? - ReactEmptyComponent.emptyElement : - element; - }, - - unmountComponent: function() { - } - -}; - -var ShallowComponentWrapper = function() { }; -assign( - ShallowComponentWrapper.prototype, - ReactCompositeComponent.Mixin, { - _instantiateReactComponent: function(element) { - return new NoopInternalComponent(element); - }, - _replaceNodeWithMarkupByID: function() {}, - _renderValidatedComponent: - ReactCompositeComponent.Mixin. - _renderValidatedComponentWithoutOwnerOrContext - } -); - -ReactShallowRenderer.prototype.render = function(element, context) { - if (!context) { - context = emptyObject; - } - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - this._render(element, transaction, context); - ReactUpdates.ReactReconcileTransaction.release(transaction); -}; - -ReactShallowRenderer.prototype.unmount = function() { - if (this._instance) { - this._instance.unmountComponent(); - } -}; - -ReactShallowRenderer.prototype._render = function(element, transaction, context) { - if (!this._instance) { - var rootID = ReactInstanceHandles.createReactRootID(); - var instance = new ShallowComponentWrapper(element.type); - instance.construct(element); - - instance.mountComponent(rootID, transaction, context); - - this._instance = instance; - } else { - this._instance.receiveComponent(element, transaction, context); - } -}; - -/** - * Exports: - * - * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)` - * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)` - * - `ReactTestUtils.Simulate.change(Element/ReactDOMComponent)` - * - ... (All keys from event plugin `eventTypes` objects) - */ -function makeSimulator(eventType) { - return function(domComponentOrNode, eventData) { - var node; - if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { - node = domComponentOrNode.getDOMNode(); - } else if (domComponentOrNode.tagName) { - node = domComponentOrNode; - } - - var fakeNativeEvent = new Event(); - fakeNativeEvent.target = node; - // We don't use SyntheticEvent.getPooled in order to not have to worry about - // properly destroying any properties assigned from `eventData` upon release - var event = new SyntheticEvent( - ReactBrowserEventEmitter.eventNameDispatchConfigs[eventType], - ReactMount.getID(node), - fakeNativeEvent - ); - assign(event, eventData); - EventPropagators.accumulateTwoPhaseDispatches(event); - - ReactUpdates.batchedUpdates(function() { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); - }); - }; -} - -function buildSimulators() { - ReactTestUtils.Simulate = {}; - - var eventType; - for (eventType in ReactBrowserEventEmitter.eventNameDispatchConfigs) { - /** - * @param {!Element || ReactDOMComponent} domComponentOrNode - * @param {?object} eventData Fake event data to use in SyntheticEvent. - */ - ReactTestUtils.Simulate[eventType] = makeSimulator(eventType); - } -} - -// Rebuild ReactTestUtils.Simulate whenever event plugins are injected -var oldInjectEventPluginOrder = EventPluginHub.injection.injectEventPluginOrder; -EventPluginHub.injection.injectEventPluginOrder = function() { - oldInjectEventPluginOrder.apply(this, arguments); - buildSimulators(); -}; -var oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName; -EventPluginHub.injection.injectEventPluginsByName = function() { - oldInjectEventPlugins.apply(this, arguments); - buildSimulators(); -}; - -buildSimulators(); - -/** - * Exports: - * - * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)` - * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)` - * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)` - * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)` - * - ... (All keys from `EventConstants.topLevelTypes`) - * - * Note: Top level event types are a subset of the entire set of handler types - * (which include a broader set of "synthetic" events). For example, onDragDone - * is a synthetic event. Except when testing an event plugin or React's event - * handling code specifically, you probably want to use ReactTestUtils.Simulate - * to dispatch synthetic events. - */ - -function makeNativeSimulator(eventType) { - return function(domComponentOrNode, nativeEventData) { - var fakeNativeEvent = new Event(eventType); - assign(fakeNativeEvent, nativeEventData); - if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { - ReactTestUtils.simulateNativeEventOnDOMComponent( - eventType, - domComponentOrNode, - fakeNativeEvent - ); - } else if (!!domComponentOrNode.tagName) { - // Will allow on actual dom nodes. - ReactTestUtils.simulateNativeEventOnNode( - eventType, - domComponentOrNode, - fakeNativeEvent - ); - } - }; -} - -var eventType; -for (eventType in topLevelTypes) { - // Event type is stored as 'topClick' - we transform that to 'click' - var convenienceName = eventType.indexOf('top') === 0 ? - eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; - /** - * @param {!Element || ReactDOMComponent} domComponentOrNode - * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent. - */ - ReactTestUtils.SimulateNative[convenienceName] = - makeNativeSimulator(eventType); -} - -module.exports = ReactTestUtils; - -},{"100":100,"108":108,"130":130,"16":16,"18":18,"21":21,"29":29,"31":31,"33":33,"43":43,"63":63,"65":65,"72":72,"73":73,"77":77}],96:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks static-only - * @providesModule ReactTransitionChildMapping - */ - -'use strict'; - -var ReactChildren = _dereq_(37); -var ReactFragment = _dereq_(69); - -var ReactTransitionChildMapping = { - /** - * Given `this.props.children`, return an object mapping key to child. Just - * simple syntactic sugar around ReactChildren.map(). - * - * @param {*} children `this.props.children` - * @return {object} Mapping of key to child - */ - getChildMapping: function(children) { - if (!children) { - return children; - } - return ReactFragment.extract(ReactChildren.map(children, function(child) { - return child; - })); - }, - - /** - * When you're adding or removing children some may be added or removed in the - * same render pass. We want to show *both* since we want to simultaneously - * animate elements in and out. This function takes a previous set of keys - * and a new set of keys and merges them with its best guess of the correct - * ordering. In the future we may expose some of the utilities in - * ReactMultiChild to make this easy, but for now React itself does not - * directly have this concept of the union of prevChildren and nextChildren - * so we implement it here. - * - * @param {object} prev prev children as returned from - * `ReactTransitionChildMapping.getChildMapping()`. - * @param {object} next next children as returned from - * `ReactTransitionChildMapping.getChildMapping()`. - * @return {object} a key set that contains all keys in `prev` and all keys - * in `next` in a reasonable order. - */ - mergeChildMappings: function(prev, next) { - prev = prev || {}; - next = next || {}; - - function getValueForKey(key) { - if (next.hasOwnProperty(key)) { - return next[key]; - } else { - return prev[key]; - } - } - - // For each key of `next`, the list of keys to insert before that key in - // the combined list - var nextKeysPending = {}; - - var pendingKeys = []; - for (var prevKey in prev) { - if (next.hasOwnProperty(prevKey)) { - if (pendingKeys.length) { - nextKeysPending[prevKey] = pendingKeys; - pendingKeys = []; - } - } else { - pendingKeys.push(prevKey); - } - } - - var i; - var childMapping = {}; - for (var nextKey in next) { - if (nextKeysPending.hasOwnProperty(nextKey)) { - for (i = 0; i < nextKeysPending[nextKey].length; i++) { - var pendingNextKey = nextKeysPending[nextKey][i]; - childMapping[nextKeysPending[nextKey][i]] = getValueForKey( - pendingNextKey - ); - } - } - childMapping[nextKey] = getValueForKey(nextKey); - } - - // Finally, add the keys which didn't appear before any key in `next` - for (i = 0; i < pendingKeys.length; i++) { - childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]); - } - - return childMapping; - } -}; - -module.exports = ReactTransitionChildMapping; - -},{"37":37,"69":69}],97:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactTransitionEvents - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); - -/** - * EVENT_NAME_MAP is used to determine which event fired when a - * transition/animation ends, based on the style property used to - * define that event. - */ -var EVENT_NAME_MAP = { - transitionend: { - 'transition': 'transitionend', - 'WebkitTransition': 'webkitTransitionEnd', - 'MozTransition': 'mozTransitionEnd', - 'OTransition': 'oTransitionEnd', - 'msTransition': 'MSTransitionEnd' - }, - - animationend: { - 'animation': 'animationend', - 'WebkitAnimation': 'webkitAnimationEnd', - 'MozAnimation': 'mozAnimationEnd', - 'OAnimation': 'oAnimationEnd', - 'msAnimation': 'MSAnimationEnd' - } -}; - -var endEvents = []; - -function detectEvents() { - var testEl = document.createElement('div'); - var style = testEl.style; - - // On some platforms, in particular some releases of Android 4.x, - // the un-prefixed "animation" and "transition" properties are defined on the - // style object but the events that fire will still be prefixed, so we need - // to check if the un-prefixed events are useable, and if not remove them - // from the map - if (!('AnimationEvent' in window)) { - delete EVENT_NAME_MAP.animationend.animation; - } - - if (!('TransitionEvent' in window)) { - delete EVENT_NAME_MAP.transitionend.transition; - } - - for (var baseEventName in EVENT_NAME_MAP) { - var baseEvents = EVENT_NAME_MAP[baseEventName]; - for (var styleName in baseEvents) { - if (styleName in style) { - endEvents.push(baseEvents[styleName]); - break; - } - } - } -} - -if (ExecutionEnvironment.canUseDOM) { - detectEvents(); -} - -// We use the raw {add|remove}EventListener() call because EventListener -// does not know how to remove event listeners and we really should -// clean up. Also, these events are not triggered in older browsers -// so we should be A-OK here. - -function addEventListener(node, eventName, eventListener) { - node.addEventListener(eventName, eventListener, false); -} - -function removeEventListener(node, eventName, eventListener) { - node.removeEventListener(eventName, eventListener, false); -} - -var ReactTransitionEvents = { - addEndEventListener: function(node, eventListener) { - if (endEvents.length === 0) { - // If CSS transitions are not supported, trigger an "end animation" - // event immediately. - window.setTimeout(eventListener, 0); - return; - } - endEvents.forEach(function(endEvent) { - addEventListener(node, endEvent, eventListener); - }); - }, - - removeEndEventListener: function(node, eventListener) { - if (endEvents.length === 0) { - return; - } - endEvents.forEach(function(endEvent) { - removeEventListener(node, endEvent, eventListener); - }); - } -}; - -module.exports = ReactTransitionEvents; - -},{"22":22}],98:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactTransitionGroup - */ - -'use strict'; - -var React = _dereq_(31); -var ReactTransitionChildMapping = _dereq_(96); - -var assign = _dereq_(29); -var cloneWithProps = _dereq_(122); -var emptyFunction = _dereq_(129); - -var ReactTransitionGroup = React.createClass({ - displayName: 'ReactTransitionGroup', - - propTypes: { - component: React.PropTypes.any, - childFactory: React.PropTypes.func - }, - - getDefaultProps: function() { - return { - component: 'span', - childFactory: emptyFunction.thatReturnsArgument - }; - }, - - getInitialState: function() { - return { - children: ReactTransitionChildMapping.getChildMapping(this.props.children) - }; - }, - - componentWillMount: function() { - this.currentlyTransitioningKeys = {}; - this.keysToEnter = []; - this.keysToLeave = []; - }, - - componentDidMount: function() { - var initialChildMapping = this.state.children; - for (var key in initialChildMapping) { - if (initialChildMapping[key]) { - this.performAppear(key); - } - } - }, - - componentWillReceiveProps: function(nextProps) { - var nextChildMapping = ReactTransitionChildMapping.getChildMapping( - nextProps.children - ); - var prevChildMapping = this.state.children; - - this.setState({ - children: ReactTransitionChildMapping.mergeChildMappings( - prevChildMapping, - nextChildMapping - ) - }); - - var key; - - for (key in nextChildMapping) { - var hasPrev = prevChildMapping && prevChildMapping.hasOwnProperty(key); - if (nextChildMapping[key] && !hasPrev && - !this.currentlyTransitioningKeys[key]) { - this.keysToEnter.push(key); - } - } - - for (key in prevChildMapping) { - var hasNext = nextChildMapping && nextChildMapping.hasOwnProperty(key); - if (prevChildMapping[key] && !hasNext && - !this.currentlyTransitioningKeys[key]) { - this.keysToLeave.push(key); - } - } - - // If we want to someday check for reordering, we could do it here. - }, - - componentDidUpdate: function() { - var keysToEnter = this.keysToEnter; - this.keysToEnter = []; - keysToEnter.forEach(this.performEnter); - - var keysToLeave = this.keysToLeave; - this.keysToLeave = []; - keysToLeave.forEach(this.performLeave); - }, - - performAppear: function(key) { - this.currentlyTransitioningKeys[key] = true; - - var component = this.refs[key]; - - if (component.componentWillAppear) { - component.componentWillAppear( - this._handleDoneAppearing.bind(this, key) - ); - } else { - this._handleDoneAppearing(key); - } - }, - - _handleDoneAppearing: function(key) { - var component = this.refs[key]; - if (component.componentDidAppear) { - component.componentDidAppear(); - } - - delete this.currentlyTransitioningKeys[key]; - - var currentChildMapping = ReactTransitionChildMapping.getChildMapping( - this.props.children - ); - - if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { - // This was removed before it had fully appeared. Remove it. - this.performLeave(key); - } - }, - - performEnter: function(key) { - this.currentlyTransitioningKeys[key] = true; - - var component = this.refs[key]; - - if (component.componentWillEnter) { - component.componentWillEnter( - this._handleDoneEntering.bind(this, key) - ); - } else { - this._handleDoneEntering(key); - } - }, - - _handleDoneEntering: function(key) { - var component = this.refs[key]; - if (component.componentDidEnter) { - component.componentDidEnter(); - } - - delete this.currentlyTransitioningKeys[key]; - - var currentChildMapping = ReactTransitionChildMapping.getChildMapping( - this.props.children - ); - - if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { - // This was removed before it had fully entered. Remove it. - this.performLeave(key); - } - }, - - performLeave: function(key) { - this.currentlyTransitioningKeys[key] = true; - - var component = this.refs[key]; - if (component.componentWillLeave) { - component.componentWillLeave(this._handleDoneLeaving.bind(this, key)); - } else { - // Note that this is somewhat dangerous b/c it calls setState() - // again, effectively mutating the component before all the work - // is done. - this._handleDoneLeaving(key); - } - }, - - _handleDoneLeaving: function(key) { - var component = this.refs[key]; - - if (component.componentDidLeave) { - component.componentDidLeave(); - } - - delete this.currentlyTransitioningKeys[key]; - - var currentChildMapping = ReactTransitionChildMapping.getChildMapping( - this.props.children - ); - - if (currentChildMapping && currentChildMapping.hasOwnProperty(key)) { - // This entered again before it fully left. Add it again. - this.performEnter(key); - } else { - var newChildren = assign({}, this.state.children); - delete newChildren[key]; - this.setState({children: newChildren}); - } - }, - - render: function() { - // TODO: we could get rid of the need for the wrapper node - // by cloning a single child - var childrenToRender = []; - for (var key in this.state.children) { - var child = this.state.children[key]; - if (child) { - // You may need to apply reactive updates to a child as it is leaving. - // The normal React way to do it won't work since the child will have - // already been removed. In case you need this behavior you can provide - // a childFactory function to wrap every child, even the ones that are - // leaving. - childrenToRender.push(cloneWithProps( - this.props.childFactory(child), - {ref: key, key: key} - )); - } - } - return React.createElement( - this.props.component, - this.props, - childrenToRender - ); - } -}); - -module.exports = ReactTransitionGroup; - -},{"122":122,"129":129,"29":29,"31":31,"96":96}],99:[function(_dereq_,module,exports){ -/** - * Copyright 2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactUpdateQueue - */ - -'use strict'; - -var ReactLifeCycle = _dereq_(74); -var ReactCurrentOwner = _dereq_(45); -var ReactElement = _dereq_(63); -var ReactInstanceMap = _dereq_(73); -var ReactUpdates = _dereq_(100); - -var assign = _dereq_(29); -var invariant = _dereq_(150); -var warning = _dereq_(171); - -function enqueueUpdate(internalInstance) { - if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) { - // If we're in a componentWillMount handler, don't enqueue a rerender - // because ReactUpdates assumes we're in a browser context (which is - // wrong for server rendering) and we're about to do a render anyway. - // See bug in #1740. - ReactUpdates.enqueueUpdate(internalInstance); - } -} - -function getInternalInstanceReadyForUpdate(publicInstance, callerName) { - ("production" !== "development" ? invariant( - ReactCurrentOwner.current == null, - '%s(...): Cannot update during an existing state transition ' + - '(such as within `render`). Render methods should be a pure function ' + - 'of props and state.', - callerName - ) : invariant(ReactCurrentOwner.current == null)); - - var internalInstance = ReactInstanceMap.get(publicInstance); - if (!internalInstance) { - if ("production" !== "development") { - // Only warn when we have a callerName. Otherwise we should be silent. - // We're probably calling from enqueueCallback. We don't want to warn - // there because we already warned for the corresponding lifecycle method. - ("production" !== "development" ? warning( - !callerName, - '%s(...): Can only update a mounted or mounting component. ' + - 'This usually means you called %s() on an unmounted ' + - 'component. This is a no-op.', - callerName, - callerName - ) : null); - } - return null; - } - - if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) { - return null; - } - - return internalInstance; -} - -/** - * ReactUpdateQueue allows for state updates to be scheduled into a later - * reconciliation step. - */ -var ReactUpdateQueue = { - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback: function(publicInstance, callback) { - ("production" !== "development" ? invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ) : invariant(typeof callback === 'function')); - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); - - // Previously we would throw an error if we didn't have an internal - // instance. Since we want to make it a no-op instead, we mirror the same - // behavior we have in other enqueue* methods. - // We also need to ignore callbacks in componentWillMount. See - // enqueueUpdates. - if (!internalInstance || - internalInstance === ReactLifeCycle.currentlyMountingInstance) { - return null; - } - - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - // TODO: The callback here is ignored when setState is called from - // componentWillMount. Either fix it or disallow doing so completely in - // favor of getInitialState. Alternatively, we can disallow - // componentWillMount during server-side rendering. - enqueueUpdate(internalInstance); - }, - - enqueueCallbackInternal: function(internalInstance, callback) { - ("production" !== "development" ? invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ) : invariant(typeof callback === 'function')); - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - enqueueUpdate(internalInstance); - }, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldUpdateComponent`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function(publicInstance) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'forceUpdate' - ); - - if (!internalInstance) { - return; - } - - internalInstance._pendingForceUpdate = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function(publicInstance, completeState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceState' - ); - - if (!internalInstance) { - return; - } - - internalInstance._pendingStateQueue = [completeState]; - internalInstance._pendingReplaceState = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function(publicInstance, partialState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setState' - ); - - if (!internalInstance) { - return; - } - - var queue = - internalInstance._pendingStateQueue || - (internalInstance._pendingStateQueue = []); - queue.push(partialState); - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the props. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialProps Subset of the next props. - * @internal - */ - enqueueSetProps: function(publicInstance, partialProps) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setProps' - ); - - if (!internalInstance) { - return; - } - - ("production" !== "development" ? invariant( - internalInstance._isTopLevel, - 'setProps(...): You called `setProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(internalInstance._isTopLevel)); - - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; - var props = assign({}, element.props, partialProps); - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the props. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} props New props. - * @internal - */ - enqueueReplaceProps: function(publicInstance, props) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceProps' - ); - - if (!internalInstance) { - return; - } - - ("production" !== "development" ? invariant( - internalInstance._isTopLevel, - 'replaceProps(...): You called `replaceProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(internalInstance._isTopLevel)); - - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); - - enqueueUpdate(internalInstance); - }, - - enqueueElementInternal: function(internalInstance, newElement) { - internalInstance._pendingElement = newElement; - enqueueUpdate(internalInstance); - } - -}; - -module.exports = ReactUpdateQueue; - -},{"100":100,"150":150,"171":171,"29":29,"45":45,"63":63,"73":73,"74":74}],100:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactUpdates - */ - -'use strict'; - -var CallbackQueue = _dereq_(7); -var PooledClass = _dereq_(30); -var ReactCurrentOwner = _dereq_(45); -var ReactPerf = _dereq_(82); -var ReactReconciler = _dereq_(89); -var Transaction = _dereq_(116); - -var assign = _dereq_(29); -var invariant = _dereq_(150); -var warning = _dereq_(171); - -var dirtyComponents = []; -var asapCallbackQueue = CallbackQueue.getPooled(); -var asapEnqueued = false; - -var batchingStrategy = null; - -function ensureInjected() { - ("production" !== "development" ? invariant( - ReactUpdates.ReactReconcileTransaction && batchingStrategy, - 'ReactUpdates: must inject a reconcile transaction class and batching ' + - 'strategy' - ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy)); -} - -var NESTED_UPDATES = { - initialize: function() { - this.dirtyComponentsLength = dirtyComponents.length; - }, - close: function() { - if (this.dirtyComponentsLength !== dirtyComponents.length) { - // Additional updates were enqueued by componentDidUpdate handlers or - // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run - // these new updates so that if A's componentDidUpdate calls setState on - // B, B will update before the callback A's updater provided when calling - // setState. - dirtyComponents.splice(0, this.dirtyComponentsLength); - flushBatchedUpdates(); - } else { - dirtyComponents.length = 0; - } - } -}; - -var UPDATE_QUEUEING = { - initialize: function() { - this.callbackQueue.reset(); - }, - close: function() { - this.callbackQueue.notifyAll(); - } -}; - -var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; - -function ReactUpdatesFlushTransaction() { - this.reinitializeTransaction(); - this.dirtyComponentsLength = null; - this.callbackQueue = CallbackQueue.getPooled(); - this.reconcileTransaction = - ReactUpdates.ReactReconcileTransaction.getPooled(); -} - -assign( - ReactUpdatesFlushTransaction.prototype, - Transaction.Mixin, { - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - destructor: function() { - this.dirtyComponentsLength = null; - CallbackQueue.release(this.callbackQueue); - this.callbackQueue = null; - ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); - this.reconcileTransaction = null; - }, - - perform: function(method, scope, a) { - // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` - // with this transaction's wrappers around it. - return Transaction.Mixin.perform.call( - this, - this.reconcileTransaction.perform, - this.reconcileTransaction, - method, - scope, - a - ); - } -}); - -PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); - -function batchedUpdates(callback, a, b, c, d) { - ensureInjected(); - batchingStrategy.batchedUpdates(callback, a, b, c, d); -} - -/** - * Array comparator for ReactComponents by mount ordering. - * - * @param {ReactComponent} c1 first component you're comparing - * @param {ReactComponent} c2 second component you're comparing - * @return {number} Return value usable by Array.prototype.sort(). - */ -function mountOrderComparator(c1, c2) { - return c1._mountOrder - c2._mountOrder; -} - -function runBatchedUpdates(transaction) { - var len = transaction.dirtyComponentsLength; - ("production" !== "development" ? invariant( - len === dirtyComponents.length, - 'Expected flush transaction\'s stored dirty-components length (%s) to ' + - 'match dirty-components array length (%s).', - len, - dirtyComponents.length - ) : invariant(len === dirtyComponents.length)); - - // Since reconciling a component higher in the owner hierarchy usually (not - // always -- see shouldComponentUpdate()) will reconcile children, reconcile - // them before their children by sorting the array. - dirtyComponents.sort(mountOrderComparator); - - for (var i = 0; i < len; i++) { - // If a component is unmounted before pending changes apply, it will still - // be here, but we assume that it has cleared its _pendingCallbacks and - // that performUpdateIfNecessary is a noop. - var component = dirtyComponents[i]; - - // If performUpdateIfNecessary happens to enqueue any new updates, we - // shouldn't execute the callbacks until the next render happens, so - // stash the callbacks first - var callbacks = component._pendingCallbacks; - component._pendingCallbacks = null; - - ReactReconciler.performUpdateIfNecessary( - component, - transaction.reconcileTransaction - ); - - if (callbacks) { - for (var j = 0; j < callbacks.length; j++) { - transaction.callbackQueue.enqueue( - callbacks[j], - component.getPublicInstance() - ); - } - } - } -} - -var flushBatchedUpdates = function() { - // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents - // array and perform any updates enqueued by mount-ready handlers (i.e., - // componentDidUpdate) but we need to check here too in order to catch - // updates enqueued by setState callbacks and asap calls. - while (dirtyComponents.length || asapEnqueued) { - if (dirtyComponents.length) { - var transaction = ReactUpdatesFlushTransaction.getPooled(); - transaction.perform(runBatchedUpdates, null, transaction); - ReactUpdatesFlushTransaction.release(transaction); - } - - if (asapEnqueued) { - asapEnqueued = false; - var queue = asapCallbackQueue; - asapCallbackQueue = CallbackQueue.getPooled(); - queue.notifyAll(); - CallbackQueue.release(queue); - } - } -}; -flushBatchedUpdates = ReactPerf.measure( - 'ReactUpdates', - 'flushBatchedUpdates', - flushBatchedUpdates -); - -/** - * Mark a component as needing a rerender, adding an optional callback to a - * list of functions which will be executed once the rerender occurs. - */ -function enqueueUpdate(component) { - ensureInjected(); - - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (This is called by each top-level update - // function, like setProps, setState, forceUpdate, etc.; creation and - // destruction of top-level components is guarded in ReactMount.) - ("production" !== "development" ? warning( - ReactCurrentOwner.current == null, - 'enqueueUpdate(): Render methods should be a pure function of props ' + - 'and state; triggering nested component updates from render is not ' + - 'allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - if (!batchingStrategy.isBatchingUpdates) { - batchingStrategy.batchedUpdates(enqueueUpdate, component); - return; - } - - dirtyComponents.push(component); -} - -/** - * Enqueue a callback to be run at the end of the current batching cycle. Throws - * if no updates are currently being performed. - */ -function asap(callback, context) { - ("production" !== "development" ? invariant( - batchingStrategy.isBatchingUpdates, - 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + - 'updates are not being batched.' - ) : invariant(batchingStrategy.isBatchingUpdates)); - asapCallbackQueue.enqueue(callback, context); - asapEnqueued = true; -} - -var ReactUpdatesInjection = { - injectReconcileTransaction: function(ReconcileTransaction) { - ("production" !== "development" ? invariant( - ReconcileTransaction, - 'ReactUpdates: must provide a reconcile transaction class' - ) : invariant(ReconcileTransaction)); - ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; - }, - - injectBatchingStrategy: function(_batchingStrategy) { - ("production" !== "development" ? invariant( - _batchingStrategy, - 'ReactUpdates: must provide a batching strategy' - ) : invariant(_batchingStrategy)); - ("production" !== "development" ? invariant( - typeof _batchingStrategy.batchedUpdates === 'function', - 'ReactUpdates: must provide a batchedUpdates() function' - ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function')); - ("production" !== "development" ? invariant( - typeof _batchingStrategy.isBatchingUpdates === 'boolean', - 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' - ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean')); - batchingStrategy = _batchingStrategy; - } -}; - -var ReactUpdates = { - /** - * React references `ReactReconcileTransaction` using this property in order - * to allow dependency injection. - * - * @internal - */ - ReactReconcileTransaction: null, - - batchedUpdates: batchedUpdates, - enqueueUpdate: enqueueUpdate, - flushBatchedUpdates: flushBatchedUpdates, - injection: ReactUpdatesInjection, - asap: asap -}; - -module.exports = ReactUpdates; - -},{"116":116,"150":150,"171":171,"29":29,"30":30,"45":45,"7":7,"82":82,"89":89}],101:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SVGDOMPropertyConfig - */ - -/*jslint bitwise: true*/ - -'use strict'; - -var DOMProperty = _dereq_(11); - -var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; - -var SVGDOMPropertyConfig = { - Properties: { - clipPath: MUST_USE_ATTRIBUTE, - cx: MUST_USE_ATTRIBUTE, - cy: MUST_USE_ATTRIBUTE, - d: MUST_USE_ATTRIBUTE, - dx: MUST_USE_ATTRIBUTE, - dy: MUST_USE_ATTRIBUTE, - fill: MUST_USE_ATTRIBUTE, - fillOpacity: MUST_USE_ATTRIBUTE, - fontFamily: MUST_USE_ATTRIBUTE, - fontSize: MUST_USE_ATTRIBUTE, - fx: MUST_USE_ATTRIBUTE, - fy: MUST_USE_ATTRIBUTE, - gradientTransform: MUST_USE_ATTRIBUTE, - gradientUnits: MUST_USE_ATTRIBUTE, - markerEnd: MUST_USE_ATTRIBUTE, - markerMid: MUST_USE_ATTRIBUTE, - markerStart: MUST_USE_ATTRIBUTE, - offset: MUST_USE_ATTRIBUTE, - opacity: MUST_USE_ATTRIBUTE, - patternContentUnits: MUST_USE_ATTRIBUTE, - patternUnits: MUST_USE_ATTRIBUTE, - points: MUST_USE_ATTRIBUTE, - preserveAspectRatio: MUST_USE_ATTRIBUTE, - r: MUST_USE_ATTRIBUTE, - rx: MUST_USE_ATTRIBUTE, - ry: MUST_USE_ATTRIBUTE, - spreadMethod: MUST_USE_ATTRIBUTE, - stopColor: MUST_USE_ATTRIBUTE, - stopOpacity: MUST_USE_ATTRIBUTE, - stroke: MUST_USE_ATTRIBUTE, - strokeDasharray: MUST_USE_ATTRIBUTE, - strokeLinecap: MUST_USE_ATTRIBUTE, - strokeOpacity: MUST_USE_ATTRIBUTE, - strokeWidth: MUST_USE_ATTRIBUTE, - textAnchor: MUST_USE_ATTRIBUTE, - transform: MUST_USE_ATTRIBUTE, - version: MUST_USE_ATTRIBUTE, - viewBox: MUST_USE_ATTRIBUTE, - x1: MUST_USE_ATTRIBUTE, - x2: MUST_USE_ATTRIBUTE, - x: MUST_USE_ATTRIBUTE, - y1: MUST_USE_ATTRIBUTE, - y2: MUST_USE_ATTRIBUTE, - y: MUST_USE_ATTRIBUTE - }, - DOMAttributeNames: { - clipPath: 'clip-path', - fillOpacity: 'fill-opacity', - fontFamily: 'font-family', - fontSize: 'font-size', - gradientTransform: 'gradientTransform', - gradientUnits: 'gradientUnits', - markerEnd: 'marker-end', - markerMid: 'marker-mid', - markerStart: 'marker-start', - patternContentUnits: 'patternContentUnits', - patternUnits: 'patternUnits', - preserveAspectRatio: 'preserveAspectRatio', - spreadMethod: 'spreadMethod', - stopColor: 'stop-color', - stopOpacity: 'stop-opacity', - strokeDasharray: 'stroke-dasharray', - strokeLinecap: 'stroke-linecap', - strokeOpacity: 'stroke-opacity', - strokeWidth: 'stroke-width', - textAnchor: 'text-anchor', - viewBox: 'viewBox' - } -}; - -module.exports = SVGDOMPropertyConfig; - -},{"11":11}],102:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SelectEventPlugin - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPropagators = _dereq_(21); -var ReactInputSelection = _dereq_(71); -var SyntheticEvent = _dereq_(108); - -var getActiveElement = _dereq_(136); -var isTextInputElement = _dereq_(153); -var keyOf = _dereq_(157); -var shallowEqual = _dereq_(166); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - select: { - phasedRegistrationNames: { - bubbled: keyOf({onSelect: null}), - captured: keyOf({onSelectCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topContextMenu, - topLevelTypes.topFocus, - topLevelTypes.topKeyDown, - topLevelTypes.topMouseDown, - topLevelTypes.topMouseUp, - topLevelTypes.topSelectionChange - ] - } -}; - -var activeElement = null; -var activeElementID = null; -var lastSelection = null; -var mouseDown = false; - -/** - * Get an object which is a unique representation of the current selection. - * - * The return value will not be consistent across nodes or browsers, but - * two identical selections on the same node will return identical objects. - * - * @param {DOMElement} node - * @param {object} - */ -function getSelection(node) { - if ('selectionStart' in node && - ReactInputSelection.hasSelectionCapabilities(node)) { - return { - start: node.selectionStart, - end: node.selectionEnd - }; - } else if (window.getSelection) { - var selection = window.getSelection(); - return { - anchorNode: selection.anchorNode, - anchorOffset: selection.anchorOffset, - focusNode: selection.focusNode, - focusOffset: selection.focusOffset - }; - } else if (document.selection) { - var range = document.selection.createRange(); - return { - parentElement: range.parentElement(), - text: range.text, - top: range.boundingTop, - left: range.boundingLeft - }; - } -} - -/** - * Poll selection to see whether it's changed. - * - * @param {object} nativeEvent - * @return {?SyntheticEvent} - */ -function constructSelectEvent(nativeEvent) { - // Ensure we have the right element, and that the user is not dragging a - // selection (this matches native `select` event behavior). In HTML5, select - // fires only on input and textarea thus if there's no focused element we - // won't dispatch. - if (mouseDown || - activeElement == null || - activeElement !== getActiveElement()) { - return null; - } - - // Only fire when selection has actually changed. - var currentSelection = getSelection(activeElement); - if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { - lastSelection = currentSelection; - - var syntheticEvent = SyntheticEvent.getPooled( - eventTypes.select, - activeElementID, - nativeEvent - ); - - syntheticEvent.type = 'select'; - syntheticEvent.target = activeElement; - - EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); - - return syntheticEvent; - } -} - -/** - * This plugin creates an `onSelect` event that normalizes select events - * across form elements. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - contentEditable - * - * This differs from native browser implementations in the following ways: - * - Fires on contentEditable fields as well as inputs. - * - Fires for collapsed selection. - * - Fires after user input. - */ -var SelectEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - switch (topLevelType) { - // Track the input node that has focus. - case topLevelTypes.topFocus: - if (isTextInputElement(topLevelTarget) || - topLevelTarget.contentEditable === 'true') { - activeElement = topLevelTarget; - activeElementID = topLevelTargetID; - lastSelection = null; - } - break; - case topLevelTypes.topBlur: - activeElement = null; - activeElementID = null; - lastSelection = null; - break; - - // Don't fire the event while the user is dragging. This matches the - // semantics of the native select event. - case topLevelTypes.topMouseDown: - mouseDown = true; - break; - case topLevelTypes.topContextMenu: - case topLevelTypes.topMouseUp: - mouseDown = false; - return constructSelectEvent(nativeEvent); - - // Chrome and IE fire non-standard event when selection is changed (and - // sometimes when it hasn't). - // Firefox doesn't support selectionchange, so check selection status - // after each key entry. The selection changes after keydown and before - // keyup, but we check on keydown as well in the case of holding down a - // key, when multiple keydown events are fired but only one keyup is. - case topLevelTypes.topSelectionChange: - case topLevelTypes.topKeyDown: - case topLevelTypes.topKeyUp: - return constructSelectEvent(nativeEvent); - } - } -}; - -module.exports = SelectEventPlugin; - -},{"108":108,"136":136,"153":153,"157":157,"16":16,"166":166,"21":21,"71":71}],103:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ServerReactRootIndex - * @typechecks - */ - -'use strict'; - -/** - * Size of the reactRoot ID space. We generate random numbers for React root - * IDs and if there's a collision the events and DOM update system will - * get confused. In the future we need a way to generate GUIDs but for - * now this will work on a smaller scale. - */ -var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53); - -var ServerReactRootIndex = { - createReactRootIndex: function() { - return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX); - } -}; - -module.exports = ServerReactRootIndex; - -},{}],104:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SimpleEventPlugin - */ - -'use strict'; - -var EventConstants = _dereq_(16); -var EventPluginUtils = _dereq_(20); -var EventPropagators = _dereq_(21); -var SyntheticClipboardEvent = _dereq_(105); -var SyntheticEvent = _dereq_(108); -var SyntheticFocusEvent = _dereq_(109); -var SyntheticKeyboardEvent = _dereq_(111); -var SyntheticMouseEvent = _dereq_(112); -var SyntheticDragEvent = _dereq_(107); -var SyntheticTouchEvent = _dereq_(113); -var SyntheticUIEvent = _dereq_(114); -var SyntheticWheelEvent = _dereq_(115); - -var getEventCharCode = _dereq_(137); - -var invariant = _dereq_(150); -var keyOf = _dereq_(157); -var warning = _dereq_(171); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - blur: { - phasedRegistrationNames: { - bubbled: keyOf({onBlur: true}), - captured: keyOf({onBlurCapture: true}) - } - }, - click: { - phasedRegistrationNames: { - bubbled: keyOf({onClick: true}), - captured: keyOf({onClickCapture: true}) - } - }, - contextMenu: { - phasedRegistrationNames: { - bubbled: keyOf({onContextMenu: true}), - captured: keyOf({onContextMenuCapture: true}) - } - }, - copy: { - phasedRegistrationNames: { - bubbled: keyOf({onCopy: true}), - captured: keyOf({onCopyCapture: true}) - } - }, - cut: { - phasedRegistrationNames: { - bubbled: keyOf({onCut: true}), - captured: keyOf({onCutCapture: true}) - } - }, - doubleClick: { - phasedRegistrationNames: { - bubbled: keyOf({onDoubleClick: true}), - captured: keyOf({onDoubleClickCapture: true}) - } - }, - drag: { - phasedRegistrationNames: { - bubbled: keyOf({onDrag: true}), - captured: keyOf({onDragCapture: true}) - } - }, - dragEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onDragEnd: true}), - captured: keyOf({onDragEndCapture: true}) - } - }, - dragEnter: { - phasedRegistrationNames: { - bubbled: keyOf({onDragEnter: true}), - captured: keyOf({onDragEnterCapture: true}) - } - }, - dragExit: { - phasedRegistrationNames: { - bubbled: keyOf({onDragExit: true}), - captured: keyOf({onDragExitCapture: true}) - } - }, - dragLeave: { - phasedRegistrationNames: { - bubbled: keyOf({onDragLeave: true}), - captured: keyOf({onDragLeaveCapture: true}) - } - }, - dragOver: { - phasedRegistrationNames: { - bubbled: keyOf({onDragOver: true}), - captured: keyOf({onDragOverCapture: true}) - } - }, - dragStart: { - phasedRegistrationNames: { - bubbled: keyOf({onDragStart: true}), - captured: keyOf({onDragStartCapture: true}) - } - }, - drop: { - phasedRegistrationNames: { - bubbled: keyOf({onDrop: true}), - captured: keyOf({onDropCapture: true}) - } - }, - focus: { - phasedRegistrationNames: { - bubbled: keyOf({onFocus: true}), - captured: keyOf({onFocusCapture: true}) - } - }, - input: { - phasedRegistrationNames: { - bubbled: keyOf({onInput: true}), - captured: keyOf({onInputCapture: true}) - } - }, - keyDown: { - phasedRegistrationNames: { - bubbled: keyOf({onKeyDown: true}), - captured: keyOf({onKeyDownCapture: true}) - } - }, - keyPress: { - phasedRegistrationNames: { - bubbled: keyOf({onKeyPress: true}), - captured: keyOf({onKeyPressCapture: true}) - } - }, - keyUp: { - phasedRegistrationNames: { - bubbled: keyOf({onKeyUp: true}), - captured: keyOf({onKeyUpCapture: true}) - } - }, - load: { - phasedRegistrationNames: { - bubbled: keyOf({onLoad: true}), - captured: keyOf({onLoadCapture: true}) - } - }, - error: { - phasedRegistrationNames: { - bubbled: keyOf({onError: true}), - captured: keyOf({onErrorCapture: true}) - } - }, - // Note: We do not allow listening to mouseOver events. Instead, use the - // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`. - mouseDown: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseDown: true}), - captured: keyOf({onMouseDownCapture: true}) - } - }, - mouseMove: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseMove: true}), - captured: keyOf({onMouseMoveCapture: true}) - } - }, - mouseOut: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseOut: true}), - captured: keyOf({onMouseOutCapture: true}) - } - }, - mouseOver: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseOver: true}), - captured: keyOf({onMouseOverCapture: true}) - } - }, - mouseUp: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseUp: true}), - captured: keyOf({onMouseUpCapture: true}) - } - }, - paste: { - phasedRegistrationNames: { - bubbled: keyOf({onPaste: true}), - captured: keyOf({onPasteCapture: true}) - } - }, - reset: { - phasedRegistrationNames: { - bubbled: keyOf({onReset: true}), - captured: keyOf({onResetCapture: true}) - } - }, - scroll: { - phasedRegistrationNames: { - bubbled: keyOf({onScroll: true}), - captured: keyOf({onScrollCapture: true}) - } - }, - submit: { - phasedRegistrationNames: { - bubbled: keyOf({onSubmit: true}), - captured: keyOf({onSubmitCapture: true}) - } - }, - touchCancel: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchCancel: true}), - captured: keyOf({onTouchCancelCapture: true}) - } - }, - touchEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchEnd: true}), - captured: keyOf({onTouchEndCapture: true}) - } - }, - touchMove: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchMove: true}), - captured: keyOf({onTouchMoveCapture: true}) - } - }, - touchStart: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchStart: true}), - captured: keyOf({onTouchStartCapture: true}) - } - }, - wheel: { - phasedRegistrationNames: { - bubbled: keyOf({onWheel: true}), - captured: keyOf({onWheelCapture: true}) - } - } -}; - -var topLevelEventsToDispatchConfig = { - topBlur: eventTypes.blur, - topClick: eventTypes.click, - topContextMenu: eventTypes.contextMenu, - topCopy: eventTypes.copy, - topCut: eventTypes.cut, - topDoubleClick: eventTypes.doubleClick, - topDrag: eventTypes.drag, - topDragEnd: eventTypes.dragEnd, - topDragEnter: eventTypes.dragEnter, - topDragExit: eventTypes.dragExit, - topDragLeave: eventTypes.dragLeave, - topDragOver: eventTypes.dragOver, - topDragStart: eventTypes.dragStart, - topDrop: eventTypes.drop, - topError: eventTypes.error, - topFocus: eventTypes.focus, - topInput: eventTypes.input, - topKeyDown: eventTypes.keyDown, - topKeyPress: eventTypes.keyPress, - topKeyUp: eventTypes.keyUp, - topLoad: eventTypes.load, - topMouseDown: eventTypes.mouseDown, - topMouseMove: eventTypes.mouseMove, - topMouseOut: eventTypes.mouseOut, - topMouseOver: eventTypes.mouseOver, - topMouseUp: eventTypes.mouseUp, - topPaste: eventTypes.paste, - topReset: eventTypes.reset, - topScroll: eventTypes.scroll, - topSubmit: eventTypes.submit, - topTouchCancel: eventTypes.touchCancel, - topTouchEnd: eventTypes.touchEnd, - topTouchMove: eventTypes.touchMove, - topTouchStart: eventTypes.touchStart, - topWheel: eventTypes.wheel -}; - -for (var type in topLevelEventsToDispatchConfig) { - topLevelEventsToDispatchConfig[type].dependencies = [type]; -} - -var SimpleEventPlugin = { - - eventTypes: eventTypes, - - /** - * Same as the default implementation, except cancels the event when return - * value is false. This behavior will be disabled in a future release. - * - * @param {object} Event to be dispatched. - * @param {function} Application-level callback. - * @param {string} domID DOM ID to pass to the callback. - */ - executeDispatch: function(event, listener, domID) { - var returnValue = EventPluginUtils.executeDispatch(event, listener, domID); - - ("production" !== "development" ? warning( - typeof returnValue !== 'boolean', - 'Returning `false` from an event handler is deprecated and will be ' + - 'ignored in a future release. Instead, manually call ' + - 'e.stopPropagation() or e.preventDefault(), as appropriate.' - ) : null); - - if (returnValue === false) { - event.stopPropagation(); - event.preventDefault(); - } - }, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; - if (!dispatchConfig) { - return null; - } - var EventConstructor; - switch (topLevelType) { - case topLevelTypes.topInput: - case topLevelTypes.topLoad: - case topLevelTypes.topError: - case topLevelTypes.topReset: - case topLevelTypes.topSubmit: - // HTML Events - // @see http://www.w3.org/TR/html5/index.html#events-0 - EventConstructor = SyntheticEvent; - break; - case topLevelTypes.topKeyPress: - // FireFox creates a keypress event for function keys too. This removes - // the unwanted keypress events. Enter is however both printable and - // non-printable. One would expect Tab to be as well (but it isn't). - if (getEventCharCode(nativeEvent) === 0) { - return null; - } - /* falls through */ - case topLevelTypes.topKeyDown: - case topLevelTypes.topKeyUp: - EventConstructor = SyntheticKeyboardEvent; - break; - case topLevelTypes.topBlur: - case topLevelTypes.topFocus: - EventConstructor = SyntheticFocusEvent; - break; - case topLevelTypes.topClick: - // Firefox creates a click event on right mouse clicks. This removes the - // unwanted click events. - if (nativeEvent.button === 2) { - return null; - } - /* falls through */ - case topLevelTypes.topContextMenu: - case topLevelTypes.topDoubleClick: - case topLevelTypes.topMouseDown: - case topLevelTypes.topMouseMove: - case topLevelTypes.topMouseOut: - case topLevelTypes.topMouseOver: - case topLevelTypes.topMouseUp: - EventConstructor = SyntheticMouseEvent; - break; - case topLevelTypes.topDrag: - case topLevelTypes.topDragEnd: - case topLevelTypes.topDragEnter: - case topLevelTypes.topDragExit: - case topLevelTypes.topDragLeave: - case topLevelTypes.topDragOver: - case topLevelTypes.topDragStart: - case topLevelTypes.topDrop: - EventConstructor = SyntheticDragEvent; - break; - case topLevelTypes.topTouchCancel: - case topLevelTypes.topTouchEnd: - case topLevelTypes.topTouchMove: - case topLevelTypes.topTouchStart: - EventConstructor = SyntheticTouchEvent; - break; - case topLevelTypes.topScroll: - EventConstructor = SyntheticUIEvent; - break; - case topLevelTypes.topWheel: - EventConstructor = SyntheticWheelEvent; - break; - case topLevelTypes.topCopy: - case topLevelTypes.topCut: - case topLevelTypes.topPaste: - EventConstructor = SyntheticClipboardEvent; - break; - } - ("production" !== "development" ? invariant( - EventConstructor, - 'SimpleEventPlugin: Unhandled event type, `%s`.', - topLevelType - ) : invariant(EventConstructor)); - var event = EventConstructor.getPooled( - dispatchConfig, - topLevelTargetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - -}; - -module.exports = SimpleEventPlugin; - -},{"105":105,"107":107,"108":108,"109":109,"111":111,"112":112,"113":113,"114":114,"115":115,"137":137,"150":150,"157":157,"16":16,"171":171,"20":20,"21":21}],105:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticClipboardEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(108); - -/** - * @interface Event - * @see http://www.w3.org/TR/clipboard-apis/ - */ -var ClipboardEventInterface = { - clipboardData: function(event) { - return ( - 'clipboardData' in event ? - event.clipboardData : - window.clipboardData - ); - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); - -module.exports = SyntheticClipboardEvent; - -},{"108":108}],106:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticCompositionEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(108); - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents - */ -var CompositionEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticCompositionEvent( - dispatchConfig, - dispatchMarker, - nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass( - SyntheticCompositionEvent, - CompositionEventInterface -); - -module.exports = SyntheticCompositionEvent; - -},{"108":108}],107:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticDragEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticMouseEvent = _dereq_(112); - -/** - * @interface DragEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var DragEventInterface = { - dataTransfer: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); - -module.exports = SyntheticDragEvent; - -},{"112":112}],108:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticEvent - * @typechecks static-only - */ - -'use strict'; - -var PooledClass = _dereq_(30); - -var assign = _dereq_(29); -var emptyFunction = _dereq_(129); -var getEventTarget = _dereq_(140); - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var EventInterface = { - type: null, - target: getEventTarget, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: emptyFunction.thatReturnsNull, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function(event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; - -/** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. - * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - */ -function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) { - this.dispatchConfig = dispatchConfig; - this.dispatchMarker = dispatchMarker; - this.nativeEvent = nativeEvent; - - var Interface = this.constructor.Interface; - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } - var normalize = Interface[propName]; - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - this[propName] = nativeEvent[propName]; - } - } - - var defaultPrevented = nativeEvent.defaultPrevented != null ? - nativeEvent.defaultPrevented : - nativeEvent.returnValue === false; - if (defaultPrevented) { - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - } else { - this.isDefaultPrevented = emptyFunction.thatReturnsFalse; - } - this.isPropagationStopped = emptyFunction.thatReturnsFalse; -} - -assign(SyntheticEvent.prototype, { - - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; - if (event.preventDefault) { - event.preventDefault(); - } else { - event.returnValue = false; - } - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - }, - - stopPropagation: function() { - var event = this.nativeEvent; - if (event.stopPropagation) { - event.stopPropagation(); - } else { - event.cancelBubble = true; - } - this.isPropagationStopped = emptyFunction.thatReturnsTrue; - }, - - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function() { - this.isPersistent = emptyFunction.thatReturnsTrue; - }, - - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: emptyFunction.thatReturnsFalse, - - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function() { - var Interface = this.constructor.Interface; - for (var propName in Interface) { - this[propName] = null; - } - this.dispatchConfig = null; - this.dispatchMarker = null; - this.nativeEvent = null; - } - -}); - -SyntheticEvent.Interface = EventInterface; - -/** - * Helper to reduce boilerplate when creating subclasses. - * - * @param {function} Class - * @param {?object} Interface - */ -SyntheticEvent.augmentClass = function(Class, Interface) { - var Super = this; - - var prototype = Object.create(Super.prototype); - assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - - Class.Interface = assign({}, Super.Interface, Interface); - Class.augmentClass = Super.augmentClass; - - PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler); -}; - -PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler); - -module.exports = SyntheticEvent; - -},{"129":129,"140":140,"29":29,"30":30}],109:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticFocusEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(114); - -/** - * @interface FocusEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var FocusEventInterface = { - relatedTarget: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); - -module.exports = SyntheticFocusEvent; - -},{"114":114}],110:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticInputEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(108); - -/** - * @interface Event - * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 - * /#events-inputevents - */ -var InputEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticInputEvent( - dispatchConfig, - dispatchMarker, - nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass( - SyntheticInputEvent, - InputEventInterface -); - -module.exports = SyntheticInputEvent; - -},{"108":108}],111:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticKeyboardEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(114); - -var getEventCharCode = _dereq_(137); -var getEventKey = _dereq_(138); -var getEventModifierState = _dereq_(139); - -/** - * @interface KeyboardEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var KeyboardEventInterface = { - key: getEventKey, - location: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - repeat: null, - locale: null, - getModifierState: getEventModifierState, - // Legacy Interface - charCode: function(event) { - // `charCode` is the result of a KeyPress event and represents the value of - // the actual printable character. - - // KeyPress is deprecated, but its replacement is not yet final and not - // implemented in any major browser. Only KeyPress has charCode. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - return 0; - }, - keyCode: function(event) { - // `keyCode` is the result of a KeyDown/Up event and represents the value of - // physical keyboard key. - - // The actual meaning of the value depends on the users' keyboard layout - // which cannot be detected. Assuming that it is a US keyboard layout - // provides a surprisingly accurate mapping for US and European users. - // Due to this, it is left to the user to implement at this time. - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - }, - which: function(event) { - // `which` is an alias for either `keyCode` or `charCode` depending on the - // type of the event. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); - -module.exports = SyntheticKeyboardEvent; - -},{"114":114,"137":137,"138":138,"139":139}],112:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticMouseEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(114); -var ViewportMetrics = _dereq_(117); - -var getEventModifierState = _dereq_(139); - -/** - * @interface MouseEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var MouseEventInterface = { - screenX: null, - screenY: null, - clientX: null, - clientY: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - getModifierState: getEventModifierState, - button: function(event) { - // Webkit, Firefox, IE9+ - // which: 1 2 3 - // button: 0 1 2 (standard) - var button = event.button; - if ('which' in event) { - return button; - } - // IE<9 - // which: undefined - // button: 0 0 0 - // button: 1 4 2 (onmouseup) - return button === 2 ? 2 : button === 4 ? 1 : 0; - }, - buttons: null, - relatedTarget: function(event) { - return event.relatedTarget || ( - ((event.fromElement === event.srcElement ? event.toElement : event.fromElement)) - ); - }, - // "Proprietary" Interface. - pageX: function(event) { - return 'pageX' in event ? - event.pageX : - event.clientX + ViewportMetrics.currentScrollLeft; - }, - pageY: function(event) { - return 'pageY' in event ? - event.pageY : - event.clientY + ViewportMetrics.currentScrollTop; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); - -module.exports = SyntheticMouseEvent; - -},{"114":114,"117":117,"139":139}],113:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticTouchEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(114); - -var getEventModifierState = _dereq_(139); - -/** - * @interface TouchEvent - * @see http://www.w3.org/TR/touch-events/ - */ -var TouchEventInterface = { - touches: null, - targetTouches: null, - changedTouches: null, - altKey: null, - metaKey: null, - ctrlKey: null, - shiftKey: null, - getModifierState: getEventModifierState -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); - -module.exports = SyntheticTouchEvent; - -},{"114":114,"139":139}],114:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticUIEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(108); - -var getEventTarget = _dereq_(140); - -/** - * @interface UIEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var UIEventInterface = { - view: function(event) { - if (event.view) { - return event.view; - } - - var target = getEventTarget(event); - if (target != null && target.window === target) { - // target is a window object - return target; - } - - var doc = target.ownerDocument; - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - if (doc) { - return doc.defaultView || doc.parentWindow; - } else { - return window; - } - }, - detail: function(event) { - return event.detail || 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); - -module.exports = SyntheticUIEvent; - -},{"108":108,"140":140}],115:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticWheelEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticMouseEvent = _dereq_(112); - -/** - * @interface WheelEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var WheelEventInterface = { - deltaX: function(event) { - return ( - 'deltaX' in event ? event.deltaX : - // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). - 'wheelDeltaX' in event ? -event.wheelDeltaX : 0 - ); - }, - deltaY: function(event) { - return ( - 'deltaY' in event ? event.deltaY : - // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). - 'wheelDeltaY' in event ? -event.wheelDeltaY : - // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). - 'wheelDelta' in event ? -event.wheelDelta : 0 - ); - }, - deltaZ: null, - - // Browsers without "deltaMode" is reporting in raw wheel delta where one - // notch on the scroll is always +/- 120, roughly equivalent to pixels. - // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or - // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. - deltaMode: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticMouseEvent} - */ -function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); - -module.exports = SyntheticWheelEvent; - -},{"112":112}],116:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Transaction - */ - -'use strict'; - -var invariant = _dereq_(150); - -/** - * `Transaction` creates a black box that is able to wrap any method such that - * certain invariants are maintained before and after the method is invoked - * (Even if an exception is thrown while invoking the wrapped method). Whoever - * instantiates a transaction can provide enforcers of the invariants at - * creation time. The `Transaction` class itself will supply one additional - * automatic invariant for you - the invariant that any transaction instance - * should not be run while it is already being run. You would typically create a - * single instance of a `Transaction` for reuse multiple times, that potentially - * is used to wrap several different methods. Wrappers are extremely simple - - * they only require implementing two methods. - * - * <pre> - * wrappers (injected at creation time) - * + + - * | | - * +-----------------|--------|--------------+ - * | v | | - * | +---------------+ | | - * | +--| wrapper1 |---|----+ | - * | | +---------------+ v | | - * | | +-------------+ | | - * | | +----| wrapper2 |--------+ | - * | | | +-------------+ | | | - * | | | | | | - * | v v v v | wrapper - * | +---+ +---+ +---------+ +---+ +---+ | invariants - * perform(anyMethod) | | | | | | | | | | | | maintained - * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|--------> - * | | | | | | | | | | | | - * | | | | | | | | | | | | - * | | | | | | | | | | | | - * | +---+ +---+ +---------+ +---+ +---+ | - * | initialize close | - * +-----------------------------------------+ - * </pre> - * - * Use cases: - * - Preserving the input selection ranges before/after reconciliation. - * Restoring selection even in the event of an unexpected error. - * - Deactivating events while rearranging the DOM, preventing blurs/focuses, - * while guaranteeing that afterwards, the event system is reactivated. - * - Flushing a queue of collected DOM mutations to the main UI thread after a - * reconciliation takes place in a worker thread. - * - Invoking any collected `componentDidUpdate` callbacks after rendering new - * content. - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue - * to preserve the `scrollTop` (an automatic scroll aware DOM). - * - (Future use case): Layout calculations before and after DOM updates. - * - * Transactional plugin API: - * - A module that has an `initialize` method that returns any precomputation. - * - and a `close` method that accepts the precomputation. `close` is invoked - * when the wrapped process is completed, or has failed. - * - * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules - * that implement `initialize` and `close`. - * @return {Transaction} Single transaction for reuse in thread. - * - * @class Transaction - */ -var Mixin = { - /** - * Sets up this instance so that it is prepared for collecting metrics. Does - * so such that this setup method may be used on an instance that is already - * initialized, in a way that does not consume additional memory upon reuse. - * That can be useful if you decide to make your subclass of this mixin a - * "PooledClass". - */ - reinitializeTransaction: function() { - this.transactionWrappers = this.getTransactionWrappers(); - if (!this.wrapperInitData) { - this.wrapperInitData = []; - } else { - this.wrapperInitData.length = 0; - } - this._isInTransaction = false; - }, - - _isInTransaction: false, - - /** - * @abstract - * @return {Array<TransactionWrapper>} Array of transaction wrappers. - */ - getTransactionWrappers: null, - - isInTransaction: function() { - return !!this._isInTransaction; - }, - - /** - * Executes the function within a safety window. Use this for the top level - * methods that result in large amounts of computation/mutations that would - * need to be safety checked. - * - * @param {function} method Member of scope to call. - * @param {Object} scope Scope to invoke from. - * @param {Object?=} args... Arguments to pass to the method (optional). - * Helps prevent need to bind in many cases. - * @return Return value from `method`. - */ - perform: function(method, scope, a, b, c, d, e, f) { - ("production" !== "development" ? invariant( - !this.isInTransaction(), - 'Transaction.perform(...): Cannot initialize a transaction when there ' + - 'is already an outstanding transaction.' - ) : invariant(!this.isInTransaction())); - var errorThrown; - var ret; - try { - this._isInTransaction = true; - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // one of these calls threw. - errorThrown = true; - this.initializeAll(0); - ret = method.call(scope, a, b, c, d, e, f); - errorThrown = false; - } finally { - try { - if (errorThrown) { - // If `method` throws, prefer to show that stack trace over any thrown - // by invoking `closeAll`. - try { - this.closeAll(0); - } catch (err) { - } - } else { - // Since `method` didn't throw, we don't want to silence the exception - // here. - this.closeAll(0); - } - } finally { - this._isInTransaction = false; - } - } - return ret; - }, - - initializeAll: function(startIndex) { - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - try { - // Catching errors makes debugging more difficult, so we start with the - // OBSERVED_ERROR state before overwriting it with the real return value - // of initialize -- if it's still set to OBSERVED_ERROR in the finally - // block, it means wrapper.initialize threw. - this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; - this.wrapperInitData[i] = wrapper.initialize ? - wrapper.initialize.call(this) : - null; - } finally { - if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { - // The initializer for wrapper i threw an error; initialize the - // remaining wrappers but silence any exceptions from them to ensure - // that the first error is the one to bubble up. - try { - this.initializeAll(i + 1); - } catch (err) { - } - } - } - } - }, - - /** - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into - * them the respective return values of `this.transactionWrappers.init[i]` - * (`close`rs that correspond to initializers that failed will not be - * invoked). - */ - closeAll: function(startIndex) { - ("production" !== "development" ? invariant( - this.isInTransaction(), - 'Transaction.closeAll(): Cannot close transaction when none are open.' - ) : invariant(this.isInTransaction())); - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - var initData = this.wrapperInitData[i]; - var errorThrown; - try { - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // wrapper.close threw. - errorThrown = true; - if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) { - wrapper.close.call(this, initData); - } - errorThrown = false; - } finally { - if (errorThrown) { - // The closer for wrapper i threw an error; close the remaining - // wrappers but silence any exceptions from them to ensure that the - // first error is the one to bubble up. - try { - this.closeAll(i + 1); - } catch (e) { - } - } - } - } - this.wrapperInitData.length = 0; - } -}; - -var Transaction = { - - Mixin: Mixin, - - /** - * Token to look for to determine if an error occured. - */ - OBSERVED_ERROR: {} - -}; - -module.exports = Transaction; - -},{"150":150}],117:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ViewportMetrics - */ - -'use strict'; - -var ViewportMetrics = { - - currentScrollLeft: 0, - - currentScrollTop: 0, - - refreshScrollValues: function(scrollPosition) { - ViewportMetrics.currentScrollLeft = scrollPosition.x; - ViewportMetrics.currentScrollTop = scrollPosition.y; - } - -}; - -module.exports = ViewportMetrics; - -},{}],118:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule accumulateInto - */ - -'use strict'; - -var invariant = _dereq_(150); - -/** - * - * Accumulates items that must not be null or undefined into the first one. This - * is used to conserve memory by avoiding array allocations, and thus sacrifices - * API cleanness. Since `current` can be null before being passed in and not - * null after this function, make sure to assign it back to `current`: - * - * `a = accumulateInto(a, b);` - * - * This API should be sparingly used. Try `accumulate` for something cleaner. - * - * @return {*|array<*>} An accumulation of items. - */ - -function accumulateInto(current, next) { - ("production" !== "development" ? invariant( - next != null, - 'accumulateInto(...): Accumulated items must not be null or undefined.' - ) : invariant(next != null)); - if (current == null) { - return next; - } - - // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - var currentIsArray = Array.isArray(current); - var nextIsArray = Array.isArray(next); - - if (currentIsArray && nextIsArray) { - current.push.apply(current, next); - return current; - } - - if (currentIsArray) { - current.push(next); - return current; - } - - if (nextIsArray) { - // A bit too dangerous to mutate `next`. - return [current].concat(next); - } - - return [current, next]; -} - -module.exports = accumulateInto; - -},{"150":150}],119:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule adler32 - */ - -/* jslint bitwise:true */ - -'use strict'; - -var MOD = 65521; - -// This is a clean-room implementation of adler32 designed for detecting -// if markup is not what we expect it to be. It does not need to be -// cryptographically strong, only reasonably good at detecting if markup -// generated on the server is different than that on the client. -function adler32(data) { - var a = 1; - var b = 0; - for (var i = 0; i < data.length; i++) { - a = (a + data.charCodeAt(i)) % MOD; - b = (b + a) % MOD; - } - return a | (b << 16); -} - -module.exports = adler32; - -},{}],120:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule camelize - * @typechecks - */ - -var _hyphenPattern = /-(.)/g; - -/** - * Camelcases a hyphenated string, for example: - * - * > camelize('background-color') - * < "backgroundColor" - * - * @param {string} string - * @return {string} - */ -function camelize(string) { - return string.replace(_hyphenPattern, function(_, character) { - return character.toUpperCase(); - }); -} - -module.exports = camelize; - -},{}],121:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule camelizeStyleName - * @typechecks - */ - -"use strict"; - -var camelize = _dereq_(120); - -var msPattern = /^-ms-/; - -/** - * Camelcases a hyphenated CSS property name, for example: - * - * > camelizeStyleName('background-color') - * < "backgroundColor" - * > camelizeStyleName('-moz-transition') - * < "MozTransition" - * > camelizeStyleName('-ms-transition') - * < "msTransition" - * - * As Andi Smith suggests - * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix - * is converted to lowercase `ms`. - * - * @param {string} string - * @return {string} - */ -function camelizeStyleName(string) { - return camelize(string.replace(msPattern, 'ms-')); -} - -module.exports = camelizeStyleName; - -},{"120":120}],122:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks static-only - * @providesModule cloneWithProps - */ - -'use strict'; - -var ReactElement = _dereq_(63); -var ReactPropTransferer = _dereq_(83); - -var keyOf = _dereq_(157); -var warning = _dereq_(171); - -var CHILDREN_PROP = keyOf({children: null}); - -/** - * Sometimes you want to change the props of a child passed to you. Usually - * this is to add a CSS class. - * - * @param {ReactElement} child child element you'd like to clone - * @param {object} props props you'd like to modify. className and style will be - * merged automatically. - * @return {ReactElement} a clone of child with props merged in. - */ -function cloneWithProps(child, props) { - if ("production" !== "development") { - ("production" !== "development" ? warning( - !child.ref, - 'You are calling cloneWithProps() on a child with a ref. This is ' + - 'dangerous because you\'re creating a new child which will not be ' + - 'added as a ref to its parent.' - ) : null); - } - - var newProps = ReactPropTransferer.mergeProps(props, child.props); - - // Use `child.props.children` if it is provided. - if (!newProps.hasOwnProperty(CHILDREN_PROP) && - child.props.hasOwnProperty(CHILDREN_PROP)) { - newProps.children = child.props.children; - } - - // The current API doesn't retain _owner and _context, which is why this - // doesn't use ReactElement.cloneAndReplaceProps. - return ReactElement.createElement(child.type, newProps); -} - -module.exports = cloneWithProps; - -},{"157":157,"171":171,"63":63,"83":83}],123:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule containsNode - * @typechecks - */ - -var isTextNode = _dereq_(154); - -/*jslint bitwise:true */ - -/** - * Checks if a given DOM node contains or is another DOM node. - * - * @param {?DOMNode} outerNode Outer DOM node. - * @param {?DOMNode} innerNode Inner DOM node. - * @return {boolean} True if `outerNode` contains or is `innerNode`. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if (outerNode.contains) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; - -},{"154":154}],124:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createArrayFromMixed - * @typechecks - */ - -var toArray = _dereq_(168); - -/** - * Perform a heuristic test to determine if an object is "array-like". - * - * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" - * Joshu replied: "Mu." - * - * This function determines if its argument has "array nature": it returns - * true if the argument is an actual array, an `arguments' object, or an - * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). - * - * It will return false for other array-like objects like Filelist. - * - * @param {*} obj - * @return {boolean} - */ -function hasArrayNature(obj) { - return ( - // not null/false - !!obj && - // arrays are objects, NodeLists are functions in Safari - (typeof obj == 'object' || typeof obj == 'function') && - // quacks like an array - ('length' in obj) && - // not window - !('setInterval' in obj) && - // no DOM node should be considered an array-like - // a 'select' element has 'length' and 'item' properties on IE8 - (typeof obj.nodeType != 'number') && - ( - // a real array - (// HTMLCollection/NodeList - (Array.isArray(obj) || - // arguments - ('callee' in obj) || 'item' in obj)) - ) - ); -} - -/** - * Ensure that the argument is an array by wrapping it in an array if it is not. - * Creates a copy of the argument if it is already an array. - * - * This is mostly useful idiomatically: - * - * var createArrayFromMixed = require('createArrayFromMixed'); - * - * function takesOneOrMoreThings(things) { - * things = createArrayFromMixed(things); - * ... - * } - * - * This allows you to treat `things' as an array, but accept scalars in the API. - * - * If you need to convert an array-like object, like `arguments`, into an array - * use toArray instead. - * - * @param {*} obj - * @return {array} - */ -function createArrayFromMixed(obj) { - if (!hasArrayNature(obj)) { - return [obj]; - } else if (Array.isArray(obj)) { - return obj.slice(); - } else { - return toArray(obj); - } -} - -module.exports = createArrayFromMixed; - -},{"168":168}],125:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createFullPageComponent - * @typechecks - */ - -'use strict'; - -// Defeat circular references by requiring this directly. -var ReactClass = _dereq_(38); -var ReactElement = _dereq_(63); - -var invariant = _dereq_(150); - -/** - * Create a component that will throw an exception when unmounted. - * - * Components like <html> <head> and <body> can't be removed or added - * easily in a cross-browser way, however it's valuable to be able to - * take advantage of React's reconciliation for styling and <title> - * management. So we just document it and throw in dangerous cases. - * - * @param {string} tag The tag to wrap - * @return {function} convenience constructor of new component - */ -function createFullPageComponent(tag) { - var elementFactory = ReactElement.createFactory(tag); - - var FullPageComponent = ReactClass.createClass({ - tagName: tag.toUpperCase(), - displayName: 'ReactFullPageComponent' + tag, - - componentWillUnmount: function() { - ("production" !== "development" ? invariant( - false, - '%s tried to unmount. Because of cross-browser quirks it is ' + - 'impossible to unmount some top-level components (eg <html>, <head>, ' + - 'and <body>) reliably and efficiently. To fix this, have a single ' + - 'top-level component that never unmounts render these elements.', - this.constructor.displayName - ) : invariant(false)); - }, - - render: function() { - return elementFactory(this.props); - } - }); - - return FullPageComponent; -} - -module.exports = createFullPageComponent; - -},{"150":150,"38":38,"63":63}],126:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createNodesFromMarkup - * @typechecks - */ - -/*jslint evil: true, sub: true */ - -var ExecutionEnvironment = _dereq_(22); - -var createArrayFromMixed = _dereq_(124); -var getMarkupWrap = _dereq_(142); -var invariant = _dereq_(150); - -/** - * Dummy container used to render all markup. - */ -var dummyNode = - ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Pattern used by `getNodeName`. - */ -var nodeNamePattern = /^\s*<(\w+)/; - -/** - * Extracts the `nodeName` of the first element in a string of markup. - * - * @param {string} markup String of markup. - * @return {?string} Node name of the supplied markup. - */ -function getNodeName(markup) { - var nodeNameMatch = markup.match(nodeNamePattern); - return nodeNameMatch && nodeNameMatch[1].toLowerCase(); -} - -/** - * Creates an array containing the nodes rendered from the supplied markup. The - * optionally supplied `handleScript` function will be invoked once for each - * <script> element that is rendered. If no `handleScript` function is supplied, - * an exception is thrown if any <script> elements are rendered. - * - * @param {string} markup A string of valid HTML markup. - * @param {?function} handleScript Invoked once for each rendered <script>. - * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. - */ -function createNodesFromMarkup(markup, handleScript) { - var node = dummyNode; - ("production" !== "development" ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode)); - var nodeName = getNodeName(markup); - - var wrap = nodeName && getMarkupWrap(nodeName); - if (wrap) { - node.innerHTML = wrap[1] + markup + wrap[2]; - - var wrapDepth = wrap[0]; - while (wrapDepth--) { - node = node.lastChild; - } - } else { - node.innerHTML = markup; - } - - var scripts = node.getElementsByTagName('script'); - if (scripts.length) { - ("production" !== "development" ? invariant( - handleScript, - 'createNodesFromMarkup(...): Unexpected <script> element rendered.' - ) : invariant(handleScript)); - createArrayFromMixed(scripts).forEach(handleScript); - } - - var nodes = createArrayFromMixed(node.childNodes); - while (node.lastChild) { - node.removeChild(node.lastChild); - } - return nodes; -} - -module.exports = createNodesFromMarkup; - -},{"124":124,"142":142,"150":150,"22":22}],127:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule cx - */ - -/** - * This function is used to mark string literals representing CSS class names - * so that they can be transformed statically. This allows for modularization - * and minification of CSS class names. - * - * In static_upstream, this function is actually implemented, but it should - * eventually be replaced with something more descriptive, and the transform - * that is used in the main stack should be ported for use elsewhere. - * - * @param string|object className to modularize, or an object of key/values. - * In the object case, the values are conditions that - * determine if the className keys should be included. - * @param [string ...] Variable list of classNames in the string case. - * @return string Renderable space-separated CSS className. - */ - -'use strict'; -var warning = _dereq_(171); - -var warned = false; - -function cx(classNames) { - if ("production" !== "development") { - ("production" !== "development" ? warning( - warned, - 'React.addons.classSet will be deprecated in a future version. See ' + - 'http://fb.me/react-addons-classset' - ) : null); - warned = true; - } - - if (typeof classNames == 'object') { - return Object.keys(classNames).filter(function(className) { - return classNames[className]; - }).join(' '); - } else { - return Array.prototype.join.call(arguments, ' '); - } -} - -module.exports = cx; - -},{"171":171}],128:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule dangerousStyleValue - * @typechecks static-only - */ - -'use strict'; - -var CSSProperty = _dereq_(5); - -var isUnitlessNumber = CSSProperty.isUnitlessNumber; - -/** - * Convert a value into the proper css writable value. The style name `name` - * should be logical (no hyphens), as specified - * in `CSSProperty.isUnitlessNumber`. - * - * @param {string} name CSS property name such as `topMargin`. - * @param {*} value CSS property value such as `10px`. - * @return {string} Normalized style value with dimensions applied. - */ -function dangerousStyleValue(name, value) { - // Note that we've removed escapeTextForBrowser() calls here since the - // whole string will be escaped when the attribute is injected into - // the markup. If you provide unsafe user data here they can inject - // arbitrary CSS which may be problematic (I couldn't repro this): - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ - // This is not an XSS hole but instead a potential CSS injection issue - // which has lead to a greater discussion about how we're going to - // trust URLs moving forward. See #2115901 - - var isEmpty = value == null || typeof value === 'boolean' || value === ''; - if (isEmpty) { - return ''; - } - - var isNonNumeric = isNaN(value); - if (isNonNumeric || value === 0 || - isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { - return '' + value; // cast to string - } - - if (typeof value === 'string') { - value = value.trim(); - } - return value + 'px'; -} - -module.exports = dangerousStyleValue; - -},{"5":5}],129:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule emptyFunction - */ - -function makeEmptyFunction(arg) { - return function() { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -function emptyFunction() {} - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function() { return this; }; -emptyFunction.thatReturnsArgument = function(arg) { return arg; }; - -module.exports = emptyFunction; - -},{}],130:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule emptyObject - */ - -"use strict"; - -var emptyObject = {}; - -if ("production" !== "development") { - Object.freeze(emptyObject); -} - -module.exports = emptyObject; - -},{}],131:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule escapeTextContentForBrowser - */ - -'use strict'; - -var ESCAPE_LOOKUP = { - '&': '&', - '>': '>', - '<': '<', - '"': '"', - '\'': ''' -}; - -var ESCAPE_REGEX = /[&><"']/g; - -function escaper(match) { - return ESCAPE_LOOKUP[match]; -} - -/** - * Escapes text to prevent scripting attacks. - * - * @param {*} text Text value to escape. - * @return {string} An escaped string. - */ -function escapeTextContentForBrowser(text) { - return ('' + text).replace(ESCAPE_REGEX, escaper); -} - -module.exports = escapeTextContentForBrowser; - -},{}],132:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule findDOMNode - * @typechecks static-only - */ - -'use strict'; - -var ReactCurrentOwner = _dereq_(45); -var ReactInstanceMap = _dereq_(73); -var ReactMount = _dereq_(77); - -var invariant = _dereq_(150); -var isNode = _dereq_(152); -var warning = _dereq_(171); - -/** - * Returns the DOM node rendered by this element. - * - * @param {ReactComponent|DOMElement} componentOrElement - * @return {DOMElement} The root node of this element. - */ -function findDOMNode(componentOrElement) { - if ("production" !== "development") { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - ("production" !== "development" ? warning( - owner._warnedAboutRefsInRender, - '%s is accessing getDOMNode or findDOMNode inside its render(). ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ) : null); - owner._warnedAboutRefsInRender = true; - } - } - if (componentOrElement == null) { - return null; - } - if (isNode(componentOrElement)) { - return componentOrElement; - } - if (ReactInstanceMap.has(componentOrElement)) { - return ReactMount.getNodeFromInstance(componentOrElement); - } - ("production" !== "development" ? invariant( - componentOrElement.render == null || - typeof componentOrElement.render !== 'function', - 'Component (with keys: %s) contains `render` method ' + - 'but is not mounted in the DOM', - Object.keys(componentOrElement) - ) : invariant(componentOrElement.render == null || - typeof componentOrElement.render !== 'function')); - ("production" !== "development" ? invariant( - false, - 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', - Object.keys(componentOrElement) - ) : invariant(false)); -} - -module.exports = findDOMNode; - -},{"150":150,"152":152,"171":171,"45":45,"73":73,"77":77}],133:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule flattenChildren - */ - -'use strict'; - -var traverseAllChildren = _dereq_(169); -var warning = _dereq_(171); - -/** - * @param {function} traverseContext Context passed through traversal. - * @param {?ReactComponent} child React child component. - * @param {!string} name String name of key path to child. - */ -function flattenSingleChildIntoContext(traverseContext, child, name) { - // We found a component instance. - var result = traverseContext; - var keyUnique = !result.hasOwnProperty(name); - if ("production" !== "development") { - ("production" !== "development" ? warning( - keyUnique, - 'flattenChildren(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ) : null); - } - if (keyUnique && child != null) { - result[name] = child; - } -} - -/** - * Flattens children that are typically specified as `props.children`. Any null - * children will not be included in the resulting object. - * @return {!object} flattened children keyed by name. - */ -function flattenChildren(children) { - if (children == null) { - return children; - } - var result = {}; - traverseAllChildren(children, flattenSingleChildIntoContext, result); - return result; -} - -module.exports = flattenChildren; - -},{"169":169,"171":171}],134:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule focusNode - */ - -"use strict"; - -/** - * @param {DOMElement} node input/textarea to focus - */ -function focusNode(node) { - // IE8 can throw "Can't move focus to the control because it is invisible, - // not enabled, or of a type that does not accept the focus." for all kinds of - // reasons that are too expensive and fragile to test. - try { - node.focus(); - } catch(e) { - } -} - -module.exports = focusNode; - -},{}],135:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule forEachAccumulated - */ - -'use strict'; - -/** - * @param {array} an "accumulation" of items which is either an Array or - * a single item. Useful when paired with the `accumulate` module. This is a - * simple utility that allows us to reason about a collection of items, but - * handling the case when there is exactly one item (and we do not need to - * allocate an array). - */ -var forEachAccumulated = function(arr, cb, scope) { - if (Array.isArray(arr)) { - arr.forEach(cb, scope); - } else if (arr) { - cb.call(scope, arr); - } -}; - -module.exports = forEachAccumulated; - -},{}],136:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getActiveElement - * @typechecks - */ - -/** - * Same as document.activeElement but wraps in a try-catch block. In IE it is - * not safe to call document.activeElement if there is nothing focused. - * - * The activeElement will be null only if the document body is not yet defined. - */ -function getActiveElement() /*?DOMElement*/ { - try { - return document.activeElement || document.body; - } catch (e) { - return document.body; - } -} - -module.exports = getActiveElement; - -},{}],137:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventCharCode - * @typechecks static-only - */ - -'use strict'; - -/** - * `charCode` represents the actual "character code" and is safe to use with - * `String.fromCharCode`. As such, only keys that correspond to printable - * characters produce a valid `charCode`, the only exception to this is Enter. - * The Tab-key is considered non-printable and does not have a `charCode`, - * presumably because it does not produce a tab-character in browsers. - * - * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `charCode` property. - */ -function getEventCharCode(nativeEvent) { - var charCode; - var keyCode = nativeEvent.keyCode; - - if ('charCode' in nativeEvent) { - charCode = nativeEvent.charCode; - - // FF does not set `charCode` for the Enter-key, check against `keyCode`. - if (charCode === 0 && keyCode === 13) { - charCode = 13; - } - } else { - // IE8 does not implement `charCode`, but `keyCode` has the correct value. - charCode = keyCode; - } - - // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. - // Must not discard the (non-)printable Enter-key. - if (charCode >= 32 || charCode === 13) { - return charCode; - } - - return 0; -} - -module.exports = getEventCharCode; - -},{}],138:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventKey - * @typechecks static-only - */ - -'use strict'; - -var getEventCharCode = _dereq_(137); - -/** - * Normalization of deprecated HTML5 `key` values - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var normalizeKey = { - 'Esc': 'Escape', - 'Spacebar': ' ', - 'Left': 'ArrowLeft', - 'Up': 'ArrowUp', - 'Right': 'ArrowRight', - 'Down': 'ArrowDown', - 'Del': 'Delete', - 'Win': 'OS', - 'Menu': 'ContextMenu', - 'Apps': 'ContextMenu', - 'Scroll': 'ScrollLock', - 'MozPrintableKey': 'Unidentified' -}; - -/** - * Translation from legacy `keyCode` to HTML5 `key` - * Only special keys supported, all others depend on keyboard layout or browser - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var translateToKey = { - 8: 'Backspace', - 9: 'Tab', - 12: 'Clear', - 13: 'Enter', - 16: 'Shift', - 17: 'Control', - 18: 'Alt', - 19: 'Pause', - 20: 'CapsLock', - 27: 'Escape', - 32: ' ', - 33: 'PageUp', - 34: 'PageDown', - 35: 'End', - 36: 'Home', - 37: 'ArrowLeft', - 38: 'ArrowUp', - 39: 'ArrowRight', - 40: 'ArrowDown', - 45: 'Insert', - 46: 'Delete', - 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', - 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', - 144: 'NumLock', - 145: 'ScrollLock', - 224: 'Meta' -}; - -/** - * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `key` property. - */ -function getEventKey(nativeEvent) { - if (nativeEvent.key) { - // Normalize inconsistent values reported by browsers due to - // implementations of a working draft specification. - - // FireFox implements `key` but returns `MozPrintableKey` for all - // printable characters (normalized to `Unidentified`), ignore it. - var key = normalizeKey[nativeEvent.key] || nativeEvent.key; - if (key !== 'Unidentified') { - return key; - } - } - - // Browser does not implement `key`, polyfill as much of it as we can. - if (nativeEvent.type === 'keypress') { - var charCode = getEventCharCode(nativeEvent); - - // The enter-key is technically both printable and non-printable and can - // thus be captured by `keypress`, no other non-printable key should. - return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); - } - if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { - // While user keyboard layout determines the actual meaning of each - // `keyCode` value, almost all function keys have a universal value. - return translateToKey[nativeEvent.keyCode] || 'Unidentified'; - } - return ''; -} - -module.exports = getEventKey; - -},{"137":137}],139:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventModifierState - * @typechecks static-only - */ - -'use strict'; - -/** - * Translation from modifier key to the associated property in the event. - * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers - */ - -var modifierKeyToProp = { - 'Alt': 'altKey', - 'Control': 'ctrlKey', - 'Meta': 'metaKey', - 'Shift': 'shiftKey' -}; - -// IE8 does not implement getModifierState so we simply map it to the only -// modifier keys exposed by the event itself, does not support Lock-keys. -// Currently, all major browsers except Chrome seems to support Lock-keys. -function modifierStateGetter(keyArg) { - /*jshint validthis:true */ - var syntheticEvent = this; - var nativeEvent = syntheticEvent.nativeEvent; - if (nativeEvent.getModifierState) { - return nativeEvent.getModifierState(keyArg); - } - var keyProp = modifierKeyToProp[keyArg]; - return keyProp ? !!nativeEvent[keyProp] : false; -} - -function getEventModifierState(nativeEvent) { - return modifierStateGetter; -} - -module.exports = getEventModifierState; - -},{}],140:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventTarget - * @typechecks static-only - */ - -'use strict'; - -/** - * Gets the target node from a native browser event by accounting for - * inconsistencies in browser DOM APIs. - * - * @param {object} nativeEvent Native browser event. - * @return {DOMEventTarget} Target node. - */ -function getEventTarget(nativeEvent) { - var target = nativeEvent.target || nativeEvent.srcElement || window; - // Safari may fire events on text nodes (Node.TEXT_NODE is 3). - // @see http://www.quirksmode.org/js/events_properties.html - return target.nodeType === 3 ? target.parentNode : target; -} - -module.exports = getEventTarget; - -},{}],141:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getIteratorFn - * @typechecks static-only - */ - -'use strict'; - -/* global Symbol */ -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && ( - (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]) - ); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; - -},{}],142:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getMarkupWrap - */ - -var ExecutionEnvironment = _dereq_(22); - -var invariant = _dereq_(150); - -/** - * Dummy container used to detect which wraps are necessary. - */ -var dummyNode = - ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Some browsers cannot use `innerHTML` to render certain elements standalone, - * so we wrap them, render the wrapped nodes, then extract the desired node. - * - * In IE8, certain elements cannot render alone, so wrap all elements ('*'). - */ -var shouldWrap = { - // Force wrapping for SVG elements because if they get created inside a <div>, - // they will be initialized in the wrong namespace (and will not display). - 'circle': true, - 'clipPath': true, - 'defs': true, - 'ellipse': true, - 'g': true, - 'line': true, - 'linearGradient': true, - 'path': true, - 'polygon': true, - 'polyline': true, - 'radialGradient': true, - 'rect': true, - 'stop': true, - 'text': true -}; - -var selectWrap = [1, '<select multiple="true">', '</select>']; -var tableWrap = [1, '<table>', '</table>']; -var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; - -var svgWrap = [1, '<svg>', '</svg>']; - -var markupWrap = { - '*': [1, '?<div>', '</div>'], - - 'area': [1, '<map>', '</map>'], - 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], - 'legend': [1, '<fieldset>', '</fieldset>'], - 'param': [1, '<object>', '</object>'], - 'tr': [2, '<table><tbody>', '</tbody></table>'], - - 'optgroup': selectWrap, - 'option': selectWrap, - - 'caption': tableWrap, - 'colgroup': tableWrap, - 'tbody': tableWrap, - 'tfoot': tableWrap, - 'thead': tableWrap, - - 'td': trWrap, - 'th': trWrap, - - 'circle': svgWrap, - 'clipPath': svgWrap, - 'defs': svgWrap, - 'ellipse': svgWrap, - 'g': svgWrap, - 'line': svgWrap, - 'linearGradient': svgWrap, - 'path': svgWrap, - 'polygon': svgWrap, - 'polyline': svgWrap, - 'radialGradient': svgWrap, - 'rect': svgWrap, - 'stop': svgWrap, - 'text': svgWrap -}; - -/** - * Gets the markup wrap configuration for the supplied `nodeName`. - * - * NOTE: This lazily detects which wraps are necessary for the current browser. - * - * @param {string} nodeName Lowercase `nodeName`. - * @return {?array} Markup wrap configuration, if applicable. - */ -function getMarkupWrap(nodeName) { - ("production" !== "development" ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode)); - if (!markupWrap.hasOwnProperty(nodeName)) { - nodeName = '*'; - } - if (!shouldWrap.hasOwnProperty(nodeName)) { - if (nodeName === '*') { - dummyNode.innerHTML = '<link />'; - } else { - dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; - } - shouldWrap[nodeName] = !dummyNode.firstChild; - } - return shouldWrap[nodeName] ? markupWrap[nodeName] : null; -} - - -module.exports = getMarkupWrap; - -},{"150":150,"22":22}],143:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getNodeForCharacterOffset - */ - -'use strict'; - -/** - * Given any node return the first leaf node without children. - * - * @param {DOMElement|DOMTextNode} node - * @return {DOMElement|DOMTextNode} - */ -function getLeafNode(node) { - while (node && node.firstChild) { - node = node.firstChild; - } - return node; -} - -/** - * Get the next sibling within a container. This will walk up the - * DOM if a node's siblings have been exhausted. - * - * @param {DOMElement|DOMTextNode} node - * @return {?DOMElement|DOMTextNode} - */ -function getSiblingNode(node) { - while (node) { - if (node.nextSibling) { - return node.nextSibling; - } - node = node.parentNode; - } -} - -/** - * Get object describing the nodes which contain characters at offset. - * - * @param {DOMElement|DOMTextNode} root - * @param {number} offset - * @return {?object} - */ -function getNodeForCharacterOffset(root, offset) { - var node = getLeafNode(root); - var nodeStart = 0; - var nodeEnd = 0; - - while (node) { - if (node.nodeType === 3) { - nodeEnd = nodeStart + node.textContent.length; - - if (nodeStart <= offset && nodeEnd >= offset) { - return { - node: node, - offset: offset - nodeStart - }; - } - - nodeStart = nodeEnd; - } - - node = getLeafNode(getSiblingNode(node)); - } -} - -module.exports = getNodeForCharacterOffset; - -},{}],144:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getReactRootElementInContainer - */ - -'use strict'; - -var DOC_NODE_TYPE = 9; - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -module.exports = getReactRootElementInContainer; - -},{}],145:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getTextContentAccessor - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); - -var contentKey = null; - -/** - * Gets the key used to access text content on a DOM node. - * - * @return {?string} Key used to access text content. - * @internal - */ -function getTextContentAccessor() { - if (!contentKey && ExecutionEnvironment.canUseDOM) { - // Prefer textContent to innerText because many browsers support both but - // SVG <text> elements don't support innerText even when <div> does. - contentKey = 'textContent' in document.documentElement ? - 'textContent' : - 'innerText'; - } - return contentKey; -} - -module.exports = getTextContentAccessor; - -},{"22":22}],146:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getUnboundedScrollPosition - * @typechecks - */ - -"use strict"; - -/** - * Gets the scroll position of the supplied element or window. - * - * The return values are unbounded, unlike `getScrollPosition`. This means they - * may be negative or exceed the element boundaries (which is possible using - * inertial scrolling). - * - * @param {DOMWindow|DOMElement} scrollable - * @return {object} Map with `x` and `y` keys. - */ -function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; - } - return { - x: scrollable.scrollLeft, - y: scrollable.scrollTop - }; -} - -module.exports = getUnboundedScrollPosition; - -},{}],147:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule hyphenate - * @typechecks - */ - -var _uppercasePattern = /([A-Z])/g; - -/** - * Hyphenates a camelcased string, for example: - * - * > hyphenate('backgroundColor') - * < "background-color" - * - * For CSS style names, use `hyphenateStyleName` instead which works properly - * with all vendor prefixes, including `ms`. - * - * @param {string} string - * @return {string} - */ -function hyphenate(string) { - return string.replace(_uppercasePattern, '-$1').toLowerCase(); -} - -module.exports = hyphenate; - -},{}],148:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule hyphenateStyleName - * @typechecks - */ - -"use strict"; - -var hyphenate = _dereq_(147); - -var msPattern = /^ms-/; - -/** - * Hyphenates a camelcased CSS property name, for example: - * - * > hyphenateStyleName('backgroundColor') - * < "background-color" - * > hyphenateStyleName('MozTransition') - * < "-moz-transition" - * > hyphenateStyleName('msTransition') - * < "-ms-transition" - * - * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix - * is converted to `-ms-`. - * - * @param {string} string - * @return {string} - */ -function hyphenateStyleName(string) { - return hyphenate(string).replace(msPattern, '-ms-'); -} - -module.exports = hyphenateStyleName; - -},{"147":147}],149:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule instantiateReactComponent - * @typechecks static-only - */ - -'use strict'; - -var ReactCompositeComponent = _dereq_(43); -var ReactEmptyComponent = _dereq_(65); -var ReactNativeComponent = _dereq_(80); - -var assign = _dereq_(29); -var invariant = _dereq_(150); -var warning = _dereq_(171); - -// To avoid a cyclic dependency, we create the final class in this module -var ReactCompositeComponentWrapper = function() { }; -assign( - ReactCompositeComponentWrapper.prototype, - ReactCompositeComponent.Mixin, - { - _instantiateReactComponent: instantiateReactComponent - } -); - -/** - * Check if the type reference is a known internal type. I.e. not a user - * provided composite type. - * - * @param {function} type - * @return {boolean} Returns true if this is a valid internal type. - */ -function isInternalComponentType(type) { - return ( - typeof type === 'function' && - typeof type.prototype !== 'undefined' && - typeof type.prototype.mountComponent === 'function' && - typeof type.prototype.receiveComponent === 'function' - ); -} - -/** - * Given a ReactNode, create an instance that will actually be mounted. - * - * @param {ReactNode} node - * @param {*} parentCompositeType The composite type that resolved this. - * @return {object} A new instance of the element's constructor. - * @protected - */ -function instantiateReactComponent(node, parentCompositeType) { - var instance; - - if (node === null || node === false) { - node = ReactEmptyComponent.emptyElement; - } - - if (typeof node === 'object') { - var element = node; - if ("production" !== "development") { - ("production" !== "development" ? warning( - element && (typeof element.type === 'function' || - typeof element.type === 'string'), - 'Only functions or strings can be mounted as React components.' - ) : null); - } - - // Special case string values - if (parentCompositeType === element.type && - typeof element.type === 'string') { - // Avoid recursion if the wrapper renders itself. - instance = ReactNativeComponent.createInternalComponent(element); - // All native components are currently wrapped in a composite so we're - // safe to assume that this is what we should instantiate. - } else if (isInternalComponentType(element.type)) { - // This is temporarily available for custom components that are not string - // represenations. I.e. ART. Once those are updated to use the string - // representation, we can drop this code path. - instance = new element.type(element); - } else { - instance = new ReactCompositeComponentWrapper(); - } - } else if (typeof node === 'string' || typeof node === 'number') { - instance = ReactNativeComponent.createInstanceForText(node); - } else { - ("production" !== "development" ? invariant( - false, - 'Encountered invalid React node of type %s', - typeof node - ) : invariant(false)); - } - - if ("production" !== "development") { - ("production" !== "development" ? warning( - typeof instance.construct === 'function' && - typeof instance.mountComponent === 'function' && - typeof instance.receiveComponent === 'function' && - typeof instance.unmountComponent === 'function', - 'Only React Components can be mounted.' - ) : null); - } - - // Sets up the instance. This can probably just move into the constructor now. - instance.construct(node); - - // These two fields are used by the DOM and ART diffing algorithms - // respectively. Instead of using expandos on components, we should be - // storing the state needed by the diffing algorithms elsewhere. - instance._mountIndex = 0; - instance._mountImage = null; - - if ("production" !== "development") { - instance._isOwnerNecessary = false; - instance._warnedAboutRefsInRender = false; - } - - // Internal instances should fully constructed at this point, so they should - // not get any new fields added to them at this point. - if ("production" !== "development") { - if (Object.preventExtensions) { - Object.preventExtensions(instance); - } - } - - return instance; -} - -module.exports = instantiateReactComponent; - -},{"150":150,"171":171,"29":29,"43":43,"65":65,"80":80}],150:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule invariant - */ - -"use strict"; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if ("production" !== "development") { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - 'Invariant Violation: ' + - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - -},{}],151:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isEventSupported - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); - -var useHasFeature; -if (ExecutionEnvironment.canUseDOM) { - useHasFeature = - document.implementation && - document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; -} - -/** - * Checks if an event is supported in the current execution environment. - * - * NOTE: This will not work correctly for non-generic events such as `change`, - * `reset`, `load`, `error`, and `select`. - * - * Borrows from Modernizr. - * - * @param {string} eventNameSuffix Event name, e.g. "click". - * @param {?boolean} capture Check if the capture phase is supported. - * @return {boolean} True if the event is supported. - * @internal - * @license Modernizr 3.0.0pre (Custom Build) | MIT - */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || - capture && !('addEventListener' in document)) { - return false; - } - - var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; - - if (!isSupported) { - var element = document.createElement('div'); - element.setAttribute(eventName, 'return;'); - isSupported = typeof element[eventName] === 'function'; - } - - if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { - // This is the only way to test support for the `wheel` event in IE9+. - isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); - } - - return isSupported; -} - -module.exports = isEventSupported; - -},{"22":22}],152:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isNode - * @typechecks - */ - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM node. - */ -function isNode(object) { - return !!(object && ( - ((typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && - typeof object.nodeType === 'number' && - typeof object.nodeName === 'string')) - )); -} - -module.exports = isNode; - -},{}],153:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isTextInputElement - */ - -'use strict'; - -/** - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary - */ -var supportedInputTypes = { - 'color': true, - 'date': true, - 'datetime': true, - 'datetime-local': true, - 'email': true, - 'month': true, - 'number': true, - 'password': true, - 'range': true, - 'search': true, - 'tel': true, - 'text': true, - 'time': true, - 'url': true, - 'week': true -}; - -function isTextInputElement(elem) { - return elem && ( - (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type] || elem.nodeName === 'TEXTAREA') - ); -} - -module.exports = isTextInputElement; - -},{}],154:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isTextNode - * @typechecks - */ - -var isNode = _dereq_(152); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; - -},{"152":152}],155:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule joinClasses - * @typechecks static-only - */ - -'use strict'; - -/** - * Combines multiple className strings into one. - * http://jsperf.com/joinclasses-args-vs-array - * - * @param {...?string} classes - * @return {string} - */ -function joinClasses(className/*, ... */) { - if (!className) { - className = ''; - } - var nextClass; - var argLength = arguments.length; - if (argLength > 1) { - for (var ii = 1; ii < argLength; ii++) { - nextClass = arguments[ii]; - if (nextClass) { - className = (className ? className + ' ' : '') + nextClass; - } - } - } - return className; -} - -module.exports = joinClasses; - -},{}],156:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule keyMirror - * @typechecks static-only - */ - -'use strict'; - -var invariant = _dereq_(150); - -/** - * Constructs an enumeration with keys equal to their value. - * - * For example: - * - * var COLORS = keyMirror({blue: null, red: null}); - * var myColor = COLORS.blue; - * var isColorValid = !!COLORS[myColor]; - * - * The last line could not be performed if the values of the generated enum were - * not equal to their keys. - * - * Input: {key1: val1, key2: val2} - * Output: {key1: key1, key2: key2} - * - * @param {object} obj - * @return {object} - */ -var keyMirror = function(obj) { - var ret = {}; - var key; - ("production" !== "development" ? invariant( - obj instanceof Object && !Array.isArray(obj), - 'keyMirror(...): Argument must be an object.' - ) : invariant(obj instanceof Object && !Array.isArray(obj))); - for (key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - ret[key] = key; - } - return ret; -}; - -module.exports = keyMirror; - -},{"150":150}],157:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule keyOf - */ - -/** - * Allows extraction of a minified key. Let's the build system minify keys - * without loosing the ability to dynamically use key strings as values - * themselves. Pass in an object with a single key/val pair and it will return - * you the string key of that single record. Suppose you want to grab the - * value for a key 'className' inside of an object. Key/val minification may - * have aliased that key to be 'xa12'. keyOf({className: null}) will return - * 'xa12' in that case. Resolve keys you want to use once at startup time, then - * reuse those resolutions. - */ -var keyOf = function(oneKeyObj) { - var key; - for (key in oneKeyObj) { - if (!oneKeyObj.hasOwnProperty(key)) { - continue; - } - return key; - } - return null; -}; - - -module.exports = keyOf; - -},{}],158:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule mapObject - */ - -'use strict'; - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Executes the provided `callback` once for each enumerable own property in the - * object and constructs a new object from the results. The `callback` is - * invoked with three arguments: - * - * - the property value - * - the property name - * - the object being traversed - * - * Properties that are added after the call to `mapObject` will not be visited - * by `callback`. If the values of existing properties are changed, the value - * passed to `callback` will be the value at the time `mapObject` visits them. - * Properties that are deleted before being visited are not visited. - * - * @grep function objectMap() - * @grep function objMap() - * - * @param {?object} object - * @param {function} callback - * @param {*} context - * @return {?object} - */ -function mapObject(object, callback, context) { - if (!object) { - return null; - } - var result = {}; - for (var name in object) { - if (hasOwnProperty.call(object, name)) { - result[name] = callback.call(context, object[name], name, object); - } - } - return result; -} - -module.exports = mapObject; - -},{}],159:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule memoizeStringOnly - * @typechecks static-only - */ - -'use strict'; - -/** - * Memoizes the return value of a function that accepts one string argument. - * - * @param {function} callback - * @return {function} - */ -function memoizeStringOnly(callback) { - var cache = {}; - return function(string) { - if (!cache.hasOwnProperty(string)) { - cache[string] = callback.call(this, string); - } - return cache[string]; - }; -} - -module.exports = memoizeStringOnly; - -},{}],160:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule onlyChild - */ -'use strict'; - -var ReactElement = _dereq_(63); - -var invariant = _dereq_(150); - -/** - * Returns the first child in a collection of children and verifies that there - * is only one child in the collection. The current implementation of this - * function assumes that a single child gets passed without a wrapper, but the - * purpose of this helper function is to abstract away the particular structure - * of children. - * - * @param {?object} children Child collection structure. - * @return {ReactComponent} The first and only `ReactComponent` contained in the - * structure. - */ -function onlyChild(children) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(children), - 'onlyChild must be passed a children with exactly one child.' - ) : invariant(ReactElement.isValidElement(children))); - return children; -} - -module.exports = onlyChild; - -},{"150":150,"63":63}],161:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule performance - * @typechecks - */ - -"use strict"; - -var ExecutionEnvironment = _dereq_(22); - -var performance; - -if (ExecutionEnvironment.canUseDOM) { - performance = - window.performance || - window.msPerformance || - window.webkitPerformance; -} - -module.exports = performance || {}; - -},{"22":22}],162:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule performanceNow - * @typechecks - */ - -var performance = _dereq_(161); - -/** - * Detect if we can use `window.performance.now()` and gracefully fallback to - * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now - * because of Facebook's testing infrastructure. - */ -if (!performance || !performance.now) { - performance = Date; -} - -var performanceNow = performance.now.bind(performance); - -module.exports = performanceNow; - -},{"161":161}],163:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule quoteAttributeValueForBrowser - */ - -'use strict'; - -var escapeTextContentForBrowser = _dereq_(131); - -/** - * Escapes attribute value to prevent scripting attacks. - * - * @param {*} value Value to escape. - * @return {string} An escaped string. - */ -function quoteAttributeValueForBrowser(value) { - return '"' + escapeTextContentForBrowser(value) + '"'; -} - -module.exports = quoteAttributeValueForBrowser; - -},{"131":131}],164:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule setInnerHTML - */ - -/* globals MSApp */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); - -var WHITESPACE_TEST = /^[ \r\n\t\f]/; -var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; - -/** - * Set the innerHTML property of a node, ensuring that whitespace is preserved - * even in IE8. - * - * @param {DOMElement} node - * @param {string} html - * @internal - */ -var setInnerHTML = function(node, html) { - node.innerHTML = html; -}; - -// Win8 apps: Allow all html to be inserted -if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { - setInnerHTML = function(node, html) { - MSApp.execUnsafeLocalFunction(function() { - node.innerHTML = html; - }); - }; -} - -if (ExecutionEnvironment.canUseDOM) { - // IE8: When updating a just created node with innerHTML only leading - // whitespace is removed. When updating an existing node with innerHTML - // whitespace in root TextNodes is also collapsed. - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html - - // Feature detection; only IE8 is known to behave improperly like this. - var testElement = document.createElement('div'); - testElement.innerHTML = ' '; - if (testElement.innerHTML === '') { - setInnerHTML = function(node, html) { - // Magic theory: IE8 supposedly differentiates between added and updated - // nodes when processing innerHTML, innerHTML on updated nodes suffers - // from worse whitespace behavior. Re-adding a node like this triggers - // the initial and more favorable whitespace behavior. - // TODO: What to do on a detached node? - if (node.parentNode) { - node.parentNode.replaceChild(node, node); - } - - // We also implement a workaround for non-visible tags disappearing into - // thin air on IE8, this only happens if there is no visible text - // in-front of the non-visible tags. Piggyback on the whitespace fix - // and simply check if any non-visible tags appear in the source. - if (WHITESPACE_TEST.test(html) || - html[0] === '<' && NONVISIBLE_TEST.test(html)) { - // Recover leading whitespace by temporarily prepending any character. - // \uFEFF has the potential advantage of being zero-width/invisible. - node.innerHTML = '\uFEFF' + html; - - // deleteData leaves an empty `TextNode` which offsets the index of all - // children. Definitely want to avoid this. - var textNode = node.firstChild; - if (textNode.data.length === 1) { - node.removeChild(textNode); - } else { - textNode.deleteData(0, 1); - } - } else { - node.innerHTML = html; - } - }; - } -} - -module.exports = setInnerHTML; - -},{"22":22}],165:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule setTextContent - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(22); -var escapeTextContentForBrowser = _dereq_(131); -var setInnerHTML = _dereq_(164); - -/** - * Set the textContent property of a node, ensuring that whitespace is preserved - * even in IE8. innerText is a poor substitute for textContent and, among many - * issues, inserts <br> instead of the literal newline chars. innerHTML behaves - * as it should. - * - * @param {DOMElement} node - * @param {string} text - * @internal - */ -var setTextContent = function(node, text) { - node.textContent = text; -}; - -if (ExecutionEnvironment.canUseDOM) { - if (!('textContent' in document.documentElement)) { - setTextContent = function(node, text) { - setInnerHTML(node, escapeTextContentForBrowser(text)); - }; - } -} - -module.exports = setTextContent; - -},{"131":131,"164":164,"22":22}],166:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule shallowEqual - */ - -'use strict'; - -/** - * Performs equality by iterating through keys on an object and returning - * false when any key has values which are not strictly equal between - * objA and objB. Returns true when the values of all keys are strictly equal. - * - * @return {boolean} - */ -function shallowEqual(objA, objB) { - if (objA === objB) { - return true; - } - var key; - // Test for A's keys different from B. - for (key in objA) { - if (objA.hasOwnProperty(key) && - (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { - return false; - } - } - // Test for B's keys missing from A. - for (key in objB) { - if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { - return false; - } - } - return true; -} - -module.exports = shallowEqual; - -},{}],167:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule shouldUpdateReactComponent - * @typechecks static-only - */ - -'use strict'; - -var warning = _dereq_(171); - -/** - * Given a `prevElement` and `nextElement`, determines if the existing - * instance should be updated as opposed to being destroyed or replaced by a new - * instance. Both arguments are elements. This ensures that this logic can - * operate on stateless trees without any backing instance. - * - * @param {?object} prevElement - * @param {?object} nextElement - * @return {boolean} True if the existing instance should be updated. - * @protected - */ -function shouldUpdateReactComponent(prevElement, nextElement) { - if (prevElement != null && nextElement != null) { - var prevType = typeof prevElement; - var nextType = typeof nextElement; - if (prevType === 'string' || prevType === 'number') { - return (nextType === 'string' || nextType === 'number'); - } else { - if (nextType === 'object' && - prevElement.type === nextElement.type && - prevElement.key === nextElement.key) { - var ownersMatch = prevElement._owner === nextElement._owner; - var prevName = null; - var nextName = null; - var nextDisplayName = null; - if ("production" !== "development") { - if (!ownersMatch) { - if (prevElement._owner != null && - prevElement._owner.getPublicInstance() != null && - prevElement._owner.getPublicInstance().constructor != null) { - prevName = - prevElement._owner.getPublicInstance().constructor.displayName; - } - if (nextElement._owner != null && - nextElement._owner.getPublicInstance() != null && - nextElement._owner.getPublicInstance().constructor != null) { - nextName = - nextElement._owner.getPublicInstance().constructor.displayName; - } - if (nextElement.type != null && - nextElement.type.displayName != null) { - nextDisplayName = nextElement.type.displayName; - } - if (nextElement.type != null && typeof nextElement.type === 'string') { - nextDisplayName = nextElement.type; - } - if (typeof nextElement.type !== 'string' || - nextElement.type === 'input' || - nextElement.type === 'textarea') { - if ((prevElement._owner != null && - prevElement._owner._isOwnerNecessary === false) || - (nextElement._owner != null && - nextElement._owner._isOwnerNecessary === false)) { - if (prevElement._owner != null) { - prevElement._owner._isOwnerNecessary = true; - } - if (nextElement._owner != null) { - nextElement._owner._isOwnerNecessary = true; - } - ("production" !== "development" ? warning( - false, - '<%s /> is being rendered by both %s and %s using the same ' + - 'key (%s) in the same place. Currently, this means that ' + - 'they don\'t preserve state. This behavior should be very ' + - 'rare so we\'re considering deprecating it. Please contact ' + - 'the React team and explain your use case so that we can ' + - 'take that into consideration.', - nextDisplayName || 'Unknown Component', - prevName || '[Unknown]', - nextName || '[Unknown]', - prevElement.key - ) : null); - } - } - } - } - return ownersMatch; - } - } - } - return false; -} - -module.exports = shouldUpdateReactComponent; - -},{"171":171}],168:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule toArray - * @typechecks - */ - -var invariant = _dereq_(150); - -/** - * Convert array-like objects to arrays. - * - * This API assumes the caller knows the contents of the data type. For less - * well defined inputs use createArrayFromMixed. - * - * @param {object|function|filelist} obj - * @return {array} - */ -function toArray(obj) { - var length = obj.length; - - // Some browse builtin objects can report typeof 'function' (e.g. NodeList in - // old versions of Safari). - ("production" !== "development" ? invariant( - !Array.isArray(obj) && - (typeof obj === 'object' || typeof obj === 'function'), - 'toArray: Array-like object expected' - ) : invariant(!Array.isArray(obj) && - (typeof obj === 'object' || typeof obj === 'function'))); - - ("production" !== "development" ? invariant( - typeof length === 'number', - 'toArray: Object needs a length property' - ) : invariant(typeof length === 'number')); - - ("production" !== "development" ? invariant( - length === 0 || - (length - 1) in obj, - 'toArray: Object should have keys for indices' - ) : invariant(length === 0 || - (length - 1) in obj)); - - // Old IE doesn't give collections access to hasOwnProperty. Assume inputs - // without method will throw during the slice call and skip straight to the - // fallback. - if (obj.hasOwnProperty) { - try { - return Array.prototype.slice.call(obj); - } catch (e) { - // IE < 9 does not support Array#slice on collections objects - } - } - - // Fall back to copying key by key. This assumes all keys have a value, - // so will not preserve sparsely populated inputs. - var ret = Array(length); - for (var ii = 0; ii < length; ii++) { - ret[ii] = obj[ii]; - } - return ret; -} - -module.exports = toArray; - -},{"150":150}],169:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule traverseAllChildren - */ - -'use strict'; - -var ReactElement = _dereq_(63); -var ReactFragment = _dereq_(69); -var ReactInstanceHandles = _dereq_(72); - -var getIteratorFn = _dereq_(141); -var invariant = _dereq_(150); -var warning = _dereq_(171); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; -var SUBSEPARATOR = ':'; - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var userProvidedKeyEscaperLookup = { - '=': '=0', - '.': '=1', - ':': '=2' -}; - -var userProvidedKeyEscapeRegex = /[=.:]/g; - -var didWarnAboutMaps = false; - -function userProvidedKeyEscaper(match) { - return userProvidedKeyEscaperLookup[match]; -} - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - if (component && component.key != null) { - // Explicit key - return wrapUserProvidedKey(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * Escape a component key so that it is safe to use in a reactid. - * - * @param {*} key Component key to be escaped. - * @return {string} An escaped string. - */ -function escapeUserProvidedKey(text) { - return ('' + text).replace( - userProvidedKeyEscapeRegex, - userProvidedKeyEscaper - ); -} - -/** - * Wrap a `key` value explicitly provided by the user to distinguish it from - * implicitly-generated keys generated by a component's index in its parent. - * - * @param {string} key Value of a user-provided `key` attribute - * @return {string} - */ -function wrapUserProvidedKey(key) { - return '$' + escapeUserProvidedKey(key); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!number} indexSoFar Number of children encountered until this point. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl( - children, - nameSoFar, - indexSoFar, - callback, - traverseContext -) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || - type === 'string' || - type === 'number' || - ReactElement.isValidElement(children)) { - callback( - traverseContext, - children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar, - indexSoFar - ); - return 1; - } - - var child, nextName, nextIndex; - var subtreeCount = 0; // Count of children found in the current subtree. - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - getComponentKey(child, i) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - getComponentKey(child, ii++) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } else { - if ("production" !== "development") { - ("production" !== "development" ? warning( - didWarnAboutMaps, - 'Using Maps as children is not yet fully supported. It is an ' + - 'experimental feature that might be removed. Convert it to a ' + - 'sequence / iterable of keyed ReactElements instead.' - ) : null); - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } - } - } else if (type === 'object') { - ("production" !== "development" ? invariant( - children.nodeType !== 1, - 'traverseAllChildren(...): Encountered an invalid child; DOM ' + - 'elements are not valid children of React components.' - ) : invariant(children.nodeType !== 1)); - var fragment = ReactFragment.extract(children); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - child = fragment[key]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(key) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', 0, callback, traverseContext); -} - -module.exports = traverseAllChildren; - -},{"141":141,"150":150,"171":171,"63":63,"69":69,"72":72}],170:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule update - */ - - /* global hasOwnProperty:true */ - -'use strict'; - -var assign = _dereq_(29); -var keyOf = _dereq_(157); -var invariant = _dereq_(150); -var hasOwnProperty = {}.hasOwnProperty; - -function shallowCopy(x) { - if (Array.isArray(x)) { - return x.concat(); - } else if (x && typeof x === 'object') { - return assign(new x.constructor(), x); - } else { - return x; - } -} - -var COMMAND_PUSH = keyOf({$push: null}); -var COMMAND_UNSHIFT = keyOf({$unshift: null}); -var COMMAND_SPLICE = keyOf({$splice: null}); -var COMMAND_SET = keyOf({$set: null}); -var COMMAND_MERGE = keyOf({$merge: null}); -var COMMAND_APPLY = keyOf({$apply: null}); - -var ALL_COMMANDS_LIST = [ - COMMAND_PUSH, - COMMAND_UNSHIFT, - COMMAND_SPLICE, - COMMAND_SET, - COMMAND_MERGE, - COMMAND_APPLY -]; - -var ALL_COMMANDS_SET = {}; - -ALL_COMMANDS_LIST.forEach(function(command) { - ALL_COMMANDS_SET[command] = true; -}); - -function invariantArrayCase(value, spec, command) { - ("production" !== "development" ? invariant( - Array.isArray(value), - 'update(): expected target of %s to be an array; got %s.', - command, - value - ) : invariant(Array.isArray(value))); - var specValue = spec[command]; - ("production" !== "development" ? invariant( - Array.isArray(specValue), - 'update(): expected spec of %s to be an array; got %s. ' + - 'Did you forget to wrap your parameter in an array?', - command, - specValue - ) : invariant(Array.isArray(specValue))); -} - -function update(value, spec) { - ("production" !== "development" ? invariant( - typeof spec === 'object', - 'update(): You provided a key path to update() that did not contain one ' + - 'of %s. Did you forget to include {%s: ...}?', - ALL_COMMANDS_LIST.join(', '), - COMMAND_SET - ) : invariant(typeof spec === 'object')); - - if (hasOwnProperty.call(spec, COMMAND_SET)) { - ("production" !== "development" ? invariant( - Object.keys(spec).length === 1, - 'Cannot have more than one key in an object with %s', - COMMAND_SET - ) : invariant(Object.keys(spec).length === 1)); - - return spec[COMMAND_SET]; - } - - var nextValue = shallowCopy(value); - - if (hasOwnProperty.call(spec, COMMAND_MERGE)) { - var mergeObj = spec[COMMAND_MERGE]; - ("production" !== "development" ? invariant( - mergeObj && typeof mergeObj === 'object', - 'update(): %s expects a spec of type \'object\'; got %s', - COMMAND_MERGE, - mergeObj - ) : invariant(mergeObj && typeof mergeObj === 'object')); - ("production" !== "development" ? invariant( - nextValue && typeof nextValue === 'object', - 'update(): %s expects a target of type \'object\'; got %s', - COMMAND_MERGE, - nextValue - ) : invariant(nextValue && typeof nextValue === 'object')); - assign(nextValue, spec[COMMAND_MERGE]); - } - - if (hasOwnProperty.call(spec, COMMAND_PUSH)) { - invariantArrayCase(value, spec, COMMAND_PUSH); - spec[COMMAND_PUSH].forEach(function(item) { - nextValue.push(item); - }); - } - - if (hasOwnProperty.call(spec, COMMAND_UNSHIFT)) { - invariantArrayCase(value, spec, COMMAND_UNSHIFT); - spec[COMMAND_UNSHIFT].forEach(function(item) { - nextValue.unshift(item); - }); - } - - if (hasOwnProperty.call(spec, COMMAND_SPLICE)) { - ("production" !== "development" ? invariant( - Array.isArray(value), - 'Expected %s target to be an array; got %s', - COMMAND_SPLICE, - value - ) : invariant(Array.isArray(value))); - ("production" !== "development" ? invariant( - Array.isArray(spec[COMMAND_SPLICE]), - 'update(): expected spec of %s to be an array of arrays; got %s. ' + - 'Did you forget to wrap your parameters in an array?', - COMMAND_SPLICE, - spec[COMMAND_SPLICE] - ) : invariant(Array.isArray(spec[COMMAND_SPLICE]))); - spec[COMMAND_SPLICE].forEach(function(args) { - ("production" !== "development" ? invariant( - Array.isArray(args), - 'update(): expected spec of %s to be an array of arrays; got %s. ' + - 'Did you forget to wrap your parameters in an array?', - COMMAND_SPLICE, - spec[COMMAND_SPLICE] - ) : invariant(Array.isArray(args))); - nextValue.splice.apply(nextValue, args); - }); - } - - if (hasOwnProperty.call(spec, COMMAND_APPLY)) { - ("production" !== "development" ? invariant( - typeof spec[COMMAND_APPLY] === 'function', - 'update(): expected spec of %s to be a function; got %s.', - COMMAND_APPLY, - spec[COMMAND_APPLY] - ) : invariant(typeof spec[COMMAND_APPLY] === 'function')); - nextValue = spec[COMMAND_APPLY](nextValue); - } - - for (var k in spec) { - if (!(ALL_COMMANDS_SET.hasOwnProperty(k) && ALL_COMMANDS_SET[k])) { - nextValue[k] = update(value[k], spec[k]); - } - } - - return nextValue; -} - -module.exports = update; - -},{"150":150,"157":157,"29":29}],171:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule warning - */ - -"use strict"; - -var emptyFunction = _dereq_(129); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if ("production" !== "development") { - warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (format.length < 10 || /^[s\W]*$/.test(format)) { - throw new Error( - 'The warning format should be able to uniquely identify this ' + - 'warning. Please, use a more descriptive format than: ' + format - ); - } - - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. - } - - if (!condition) { - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); - console.warn(message); - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch(x) {} - } - }; -} - -module.exports = warning; - -},{"129":129}]},{},[1])(1) -});
\ No newline at end of file diff --git a/server/sonar-web/src/main/js/libs/third-party/react.js b/server/sonar-web/src/main/js/libs/third-party/react.js deleted file mode 100644 index ee718d08321..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/react.js +++ /dev/null @@ -1,19602 +0,0 @@ -/** - * React v0.13.3 - */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.React = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule React - */ - -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ - -'use strict'; - -var EventPluginUtils = _dereq_(19); -var ReactChildren = _dereq_(32); -var ReactComponent = _dereq_(34); -var ReactClass = _dereq_(33); -var ReactContext = _dereq_(38); -var ReactCurrentOwner = _dereq_(39); -var ReactElement = _dereq_(57); -var ReactElementValidator = _dereq_(58); -var ReactDOM = _dereq_(40); -var ReactDOMTextComponent = _dereq_(51); -var ReactDefaultInjection = _dereq_(54); -var ReactInstanceHandles = _dereq_(66); -var ReactMount = _dereq_(70); -var ReactPerf = _dereq_(75); -var ReactPropTypes = _dereq_(78); -var ReactReconciler = _dereq_(81); -var ReactServerRendering = _dereq_(84); - -var assign = _dereq_(27); -var findDOMNode = _dereq_(117); -var onlyChild = _dereq_(144); - -ReactDefaultInjection.inject(); - -var createElement = ReactElement.createElement; -var createFactory = ReactElement.createFactory; -var cloneElement = ReactElement.cloneElement; - -if ("production" !== "development") { - createElement = ReactElementValidator.createElement; - createFactory = ReactElementValidator.createFactory; - cloneElement = ReactElementValidator.cloneElement; -} - -var render = ReactPerf.measure('React', 'render', ReactMount.render); - -var React = { - Children: { - map: ReactChildren.map, - forEach: ReactChildren.forEach, - count: ReactChildren.count, - only: onlyChild - }, - Component: ReactComponent, - DOM: ReactDOM, - PropTypes: ReactPropTypes, - initializeTouchEvents: function(shouldUseTouch) { - EventPluginUtils.useTouchEvents = shouldUseTouch; - }, - createClass: ReactClass.createClass, - createElement: createElement, - cloneElement: cloneElement, - createFactory: createFactory, - createMixin: function(mixin) { - // Currently a noop. Will be used to validate and trace mixins. - return mixin; - }, - constructAndRenderComponent: ReactMount.constructAndRenderComponent, - constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID, - findDOMNode: findDOMNode, - render: render, - renderToString: ReactServerRendering.renderToString, - renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup, - unmountComponentAtNode: ReactMount.unmountComponentAtNode, - isValidElement: ReactElement.isValidElement, - withContext: ReactContext.withContext, - - // Hook for JSX spread, don't use this for anything else. - __spread: assign -}; - -// Inject the runtime into a devtools global hook regardless of browser. -// Allows for debugging when the hook is injected on the page. -if ( - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ - CurrentOwner: ReactCurrentOwner, - InstanceHandles: ReactInstanceHandles, - Mount: ReactMount, - Reconciler: ReactReconciler, - TextComponent: ReactDOMTextComponent - }); -} - -if ("production" !== "development") { - var ExecutionEnvironment = _dereq_(21); - if (ExecutionEnvironment.canUseDOM && window.top === window.self) { - - // If we're in Chrome, look for the devtools marker and provide a download - // link if not installed. - if (navigator.userAgent.indexOf('Chrome') > -1) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { - console.debug( - 'Download the React DevTools for a better development experience: ' + - 'https://fb.me/react-devtools' - ); - } - } - - var expectedFeatures = [ - // shims - Array.isArray, - Array.prototype.every, - Array.prototype.forEach, - Array.prototype.indexOf, - Array.prototype.map, - Date.now, - Function.prototype.bind, - Object.keys, - String.prototype.split, - String.prototype.trim, - - // shams - Object.create, - Object.freeze - ]; - - for (var i = 0; i < expectedFeatures.length; i++) { - if (!expectedFeatures[i]) { - console.error( - 'One or more ES5 shim/shams expected by React are not available: ' + - 'https://fb.me/react-warning-polyfills' - ); - break; - } - } - } -} - -React.version = '0.13.3'; - -module.exports = React; - -},{"117":117,"144":144,"19":19,"21":21,"27":27,"32":32,"33":33,"34":34,"38":38,"39":39,"40":40,"51":51,"54":54,"57":57,"58":58,"66":66,"70":70,"75":75,"78":78,"81":81,"84":84}],2:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule AutoFocusMixin - * @typechecks static-only - */ - -'use strict'; - -var focusNode = _dereq_(119); - -var AutoFocusMixin = { - componentDidMount: function() { - if (this.props.autoFocus) { - focusNode(this.getDOMNode()); - } - } -}; - -module.exports = AutoFocusMixin; - -},{"119":119}],3:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015 Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule BeforeInputEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPropagators = _dereq_(20); -var ExecutionEnvironment = _dereq_(21); -var FallbackCompositionState = _dereq_(22); -var SyntheticCompositionEvent = _dereq_(93); -var SyntheticInputEvent = _dereq_(97); - -var keyOf = _dereq_(141); - -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; - -var canUseCompositionEvent = ( - ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window -); - -var documentMode = null; -if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { - documentMode = document.documentMode; -} - -// Webkit offers a very useful `textInput` event that can be used to -// directly represent `beforeInput`. The IE `textinput` event is not as -// useful, so we don't use it. -var canUseTextInputEvent = ( - ExecutionEnvironment.canUseDOM && - 'TextEvent' in window && - !documentMode && - !isPresto() -); - -// In IE9+, we have access to composition events, but the data supplied -// by the native compositionend event may be incorrect. Japanese ideographic -// spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ( - ExecutionEnvironment.canUseDOM && - ( - (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11) - ) -); - -/** - * Opera <= 12 includes TextEvent in window, but does not fire - * text input events. Rely on keypress instead. - */ -function isPresto() { - var opera = window.opera; - return ( - typeof opera === 'object' && - typeof opera.version === 'function' && - parseInt(opera.version(), 10) <= 12 - ); -} - -var SPACEBAR_CODE = 32; -var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); - -var topLevelTypes = EventConstants.topLevelTypes; - -// Events and their corresponding property names. -var eventTypes = { - beforeInput: { - phasedRegistrationNames: { - bubbled: keyOf({onBeforeInput: null}), - captured: keyOf({onBeforeInputCapture: null}) - }, - dependencies: [ - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyPress, - topLevelTypes.topTextInput, - topLevelTypes.topPaste - ] - }, - compositionEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionStart, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionUpdate, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - } -}; - -// Track whether we've ever handled a keypress on the space key. -var hasSpaceKeypress = false; - -/** - * Return whether a native keypress event is assumed to be a command. - * This is required because Firefox fires `keypress` events for key commands - * (cut, copy, select-all, etc.) even though no character is inserted. - */ -function isKeypressCommand(nativeEvent) { - return ( - (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey) - ); -} - - -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case topLevelTypes.topCompositionStart: - return eventTypes.compositionStart; - case topLevelTypes.topCompositionEnd: - return eventTypes.compositionEnd; - case topLevelTypes.topCompositionUpdate: - return eventTypes.compositionUpdate; - } -} - -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); -} - -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topKeyUp: - // Command keys insert or clear IME input. - return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); - case topLevelTypes.topKeyDown: - // Expect IME keyCode on each keydown. If we get any other - // code we must have exited earlier. - return (nativeEvent.keyCode !== START_KEYCODE); - case topLevelTypes.topKeyPress: - case topLevelTypes.topMouseDown: - case topLevelTypes.topBlur: - // Events are not possible without cancelling IME. - return true; - default: - return false; - } -} - -/** - * Google Input Tools provides composition data via a CustomEvent, - * with the `data` property populated in the `detail` object. If this - * is available on the event object, use it. If not, this is a plain - * composition event and we have nothing special to extract. - * - * @param {object} nativeEvent - * @return {?string} - */ -function getDataFromCustomEvent(nativeEvent) { - var detail = nativeEvent.detail; - if (typeof detail === 'object' && 'data' in detail) { - return detail.data; - } - return null; -} - -// Track the current IME composition fallback object, if any. -var currentComposition = null; - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {?object} A SyntheticCompositionEvent. - */ -function extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { - var eventType; - var fallbackData; - - if (canUseCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackCompositionStart(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionStart; - } - } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - } - - if (!eventType) { - return null; - } - - if (useFallbackCompositionData) { - // The current composition is stored statically and must not be - // overwritten while composition continues. - if (!currentComposition && eventType === eventTypes.compositionStart) { - currentComposition = FallbackCompositionState.getPooled(topLevelTarget); - } else if (eventType === eventTypes.compositionEnd) { - if (currentComposition) { - fallbackData = currentComposition.getData(); - } - } - } - - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent - ); - - if (fallbackData) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = fallbackData; - } else { - var customData = getDataFromCustomEvent(nativeEvent); - if (customData !== null) { - event.data = customData; - } - } - - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The string corresponding to this `beforeInput` event. - */ -function getNativeBeforeInputChars(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topCompositionEnd: - return getDataFromCustomEvent(nativeEvent); - case topLevelTypes.topKeyPress: - /** - * If native `textInput` events are available, our goal is to make - * use of them. However, there is a special case: the spacebar key. - * In Webkit, preventing default on a spacebar `textInput` event - * cancels character insertion, but it *also* causes the browser - * to fall back to its default spacebar behavior of scrolling the - * page. - * - * Tracking at: - * https://code.google.com/p/chromium/issues/detail?id=355103 - * - * To avoid this issue, use the keypress event as if no `textInput` - * event is available. - */ - var which = nativeEvent.which; - if (which !== SPACEBAR_CODE) { - return null; - } - - hasSpaceKeypress = true; - return SPACEBAR_CHAR; - - case topLevelTypes.topTextInput: - // Record the characters to be added to the DOM. - var chars = nativeEvent.data; - - // If it's a spacebar character, assume that we have already handled - // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. - if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { - return null; - } - - return chars; - - default: - // For other native event types, do nothing. - return null; - } -} - -/** - * For browsers that do not provide the `textInput` event, extract the - * appropriate string to use for SyntheticInputEvent. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The fallback string for this `beforeInput` event. - */ -function getFallbackBeforeInputChars(topLevelType, nativeEvent) { - // If we are currently composing (IME) and using a fallback to do so, - // try to extract the composed characters from the fallback object. - if (currentComposition) { - if ( - topLevelType === topLevelTypes.topCompositionEnd || - isFallbackCompositionEnd(topLevelType, nativeEvent) - ) { - var chars = currentComposition.getData(); - FallbackCompositionState.release(currentComposition); - currentComposition = null; - return chars; - } - return null; - } - - switch (topLevelType) { - case topLevelTypes.topPaste: - // If a paste event occurs after a keypress, throw out the input - // chars. Paste events should not lead to BeforeInput events. - return null; - case topLevelTypes.topKeyPress: - /** - * As of v27, Firefox may fire keypress events even when no character - * will be inserted. A few possibilities: - * - * - `which` is `0`. Arrow keys, Esc key, etc. - * - * - `which` is the pressed key code, but no char is available. - * Ex: 'AltGr + d` in Polish. There is no modified character for - * this key combination and no character is inserted into the - * document, but FF fires the keypress for char code `100` anyway. - * No `input` event will occur. - * - * - `which` is the pressed key code, but a command combination is - * being used. Ex: `Cmd+C`. No character is inserted, and no - * `input` event will occur. - */ - if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { - return String.fromCharCode(nativeEvent.which); - } - return null; - case topLevelTypes.topCompositionEnd: - return useFallbackCompositionData ? null : nativeEvent.data; - default: - return null; - } -} - -/** - * Extract a SyntheticInputEvent for `beforeInput`, based on either native - * `textInput` or fallback behavior. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {?object} A SyntheticInputEvent. - */ -function extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { - var chars; - - if (canUseTextInputEvent) { - chars = getNativeBeforeInputChars(topLevelType, nativeEvent); - } else { - chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); - } - - // If no characters are being inserted, no BeforeInput event should - // be fired. - if (!chars) { - return null; - } - - var event = SyntheticInputEvent.getPooled( - eventTypes.beforeInput, - topLevelTargetID, - nativeEvent - ); - - event.data = chars; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. - * - * This event plugin is based on the native `textInput` event - * available in Chrome, Safari, Opera, and IE. This event fires after - * `onKeyPress` and `onCompositionEnd`, but before `onInput`. - * - * `beforeInput` is spec'd but not implemented in any browsers, and - * the `input` event does not provide any useful information about what has - * actually been added, contrary to the spec. Thus, `textInput` is the best - * available event to identify the characters that have actually been inserted - * into the target node. - * - * This plugin is also responsible for emitting `composition` events, thus - * allowing us to share composition fallback code for both `beforeInput` and - * `composition` event types. - */ -var BeforeInputEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) { - return [ - extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ), - extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) - ]; - } -}; - -module.exports = BeforeInputEventPlugin; - -},{"141":141,"15":15,"20":20,"21":21,"22":22,"93":93,"97":97}],4:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSProperty - */ - -'use strict'; - -/** - * CSS properties which accept numbers but are not in units of "px". - */ -var isUnitlessNumber = { - boxFlex: true, - boxFlexGroup: true, - columnCount: true, - flex: true, - flexGrow: true, - flexPositive: true, - flexShrink: true, - flexNegative: true, - fontWeight: true, - lineClamp: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related properties - fillOpacity: true, - strokeDashoffset: true, - strokeOpacity: true, - strokeWidth: true -}; - -/** - * @param {string} prefix vendor-specific prefix, eg: Webkit - * @param {string} key style name, eg: transitionDuration - * @return {string} style name prefixed with `prefix`, properly camelCased, eg: - * WebkitTransitionDuration - */ -function prefixKey(prefix, key) { - return prefix + key.charAt(0).toUpperCase() + key.substring(1); -} - -/** - * Support style names that may come passed in prefixed by adding permutations - * of vendor prefixes. - */ -var prefixes = ['Webkit', 'ms', 'Moz', 'O']; - -// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an -// infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function(prop) { - prefixes.forEach(function(prefix) { - isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; - }); -}); - -/** - * Most style properties can be unset by doing .style[prop] = '' but IE8 - * doesn't like doing that with shorthand properties so for the properties that - * IE8 breaks on, which are listed here, we instead unset each of the - * individual properties. See http://bugs.jquery.com/ticket/12385. - * The 4-value 'clock' properties like margin, padding, border-width seem to - * behave without any problems. Curiously, list-style works too without any - * special prodding. - */ -var shorthandPropertyExpansions = { - background: { - backgroundImage: true, - backgroundPosition: true, - backgroundRepeat: true, - backgroundColor: true - }, - border: { - borderWidth: true, - borderStyle: true, - borderColor: true - }, - borderBottom: { - borderBottomWidth: true, - borderBottomStyle: true, - borderBottomColor: true - }, - borderLeft: { - borderLeftWidth: true, - borderLeftStyle: true, - borderLeftColor: true - }, - borderRight: { - borderRightWidth: true, - borderRightStyle: true, - borderRightColor: true - }, - borderTop: { - borderTopWidth: true, - borderTopStyle: true, - borderTopColor: true - }, - font: { - fontStyle: true, - fontVariant: true, - fontWeight: true, - fontSize: true, - lineHeight: true, - fontFamily: true - } -}; - -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions -}; - -module.exports = CSSProperty; - -},{}],5:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var CSSProperty = _dereq_(4); -var ExecutionEnvironment = _dereq_(21); - -var camelizeStyleName = _dereq_(108); -var dangerousStyleValue = _dereq_(113); -var hyphenateStyleName = _dereq_(133); -var memoizeStringOnly = _dereq_(143); -var warning = _dereq_(154); - -var processStyleName = memoizeStringOnly(function(styleName) { - return hyphenateStyleName(styleName); -}); - -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; - } -} - -if ("production" !== "development") { - // 'msTransform' is correct, but the other prefixes should be capitalized - var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; - - // style values shouldn't contain a semicolon - var badStyleValueWithSemicolonPattern = /;\s*$/; - - var warnedStyleNames = {}; - var warnedStyleValues = {}; - - var warnHyphenatedStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - ("production" !== "development" ? warning( - false, - 'Unsupported style property %s. Did you mean %s?', - name, - camelizeStyleName(name) - ) : null); - }; - - var warnBadVendoredStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - ("production" !== "development" ? warning( - false, - 'Unsupported vendor-prefixed style property %s. Did you mean %s?', - name, - name.charAt(0).toUpperCase() + name.slice(1) - ) : null); - }; - - var warnStyleValueWithSemicolon = function(name, value) { - if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { - return; - } - - warnedStyleValues[value] = true; - ("production" !== "development" ? warning( - false, - 'Style property values shouldn\'t contain a semicolon. ' + - 'Try "%s: %s" instead.', - name, - value.replace(badStyleValueWithSemicolonPattern, '') - ) : null); - }; - - /** - * @param {string} name - * @param {*} value - */ - var warnValidStyle = function(name, value) { - if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name); - } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name); - } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value); - } - }; -} - -/** - * Operations for dealing with CSS properties. - */ -var CSSPropertyOperations = { - - /** - * Serializes a mapping of style properties for use as inline styles: - * - * > createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * The result should be HTML-escaped before insertion into the DOM. - * - * @param {object} styles - * @return {?string} - */ - createMarkupForStyles: function(styles) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = styles[styleName]; - if ("production" !== "development") { - warnValidStyle(styleName, styleValue); - } - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; - } - } - return serialized || null; - }, - - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - */ - setValueForStyles: function(node, styles) { - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if ("production" !== "development") { - warnValidStyle(styleName, styles[styleName]); - } - var styleValue = dangerousStyleValue(styleName, styles[styleName]); - if (styleName === 'float') { - styleName = styleFloatAccessor; - } - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } - } - -}; - -module.exports = CSSPropertyOperations; - -},{"108":108,"113":113,"133":133,"143":143,"154":154,"21":21,"4":4}],6:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CallbackQueue - */ - -'use strict'; - -var PooledClass = _dereq_(28); - -var assign = _dereq_(27); -var invariant = _dereq_(135); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ -function CallbackQueue() { - this._callbacks = null; - this._contexts = null; -} - -assign(CallbackQueue.prototype, { - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - enqueue: function(callback, context) { - this._callbacks = this._callbacks || []; - this._contexts = this._contexts || []; - this._callbacks.push(callback); - this._contexts.push(context); - }, - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - notifyAll: function() { - var callbacks = this._callbacks; - var contexts = this._contexts; - if (callbacks) { - ("production" !== "development" ? invariant( - callbacks.length === contexts.length, - 'Mismatched list of contexts in callback queue' - ) : invariant(callbacks.length === contexts.length)); - this._callbacks = null; - this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { - callbacks[i].call(contexts[i]); - } - callbacks.length = 0; - contexts.length = 0; - } - }, - - /** - * Resets the internal queue. - * - * @internal - */ - reset: function() { - this._callbacks = null; - this._contexts = null; - }, - - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); - } - -}); - -PooledClass.addPoolingTo(CallbackQueue); - -module.exports = CallbackQueue; - -},{"135":135,"27":27,"28":28}],7:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ChangeEventPlugin - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPluginHub = _dereq_(17); -var EventPropagators = _dereq_(20); -var ExecutionEnvironment = _dereq_(21); -var ReactUpdates = _dereq_(87); -var SyntheticEvent = _dereq_(95); - -var isEventSupported = _dereq_(136); -var isTextInputElement = _dereq_(138); -var keyOf = _dereq_(141); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topChange, - topLevelTypes.topClick, - topLevelTypes.topFocus, - topLevelTypes.topInput, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyUp, - topLevelTypes.topSelectionChange - ] - } -}; - -/** - * For IE shims - */ -var activeElement = null; -var activeElementID = null; -var activeElementValue = null; -var activeElementValueProp = null; - -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); -} - -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - (!('documentMode' in document) || document.documentMode > 8) - ); -} - -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - - // If change and propertychange bubbled, we'd just bind to it like all the - // other events and have it go through ReactBrowserEventEmitter. Since it - // doesn't, we manually listen for the events and so we have to enqueue and - // process the abstract event manually. - // - // Batching is necessary here in order to ensure that all event handlers run - // before the next rerender (including event handlers attached to ancestor - // elements instead of directly on the input). Without this, controlled - // components don't work properly in conjunction with event bubbling because - // the component is rerendered and the value reverted before all the event - // handlers can run. See https://github.com/facebook/react/issues/708. - ReactUpdates.batchedUpdates(runEventInBatch, event); -} - -function runEventInBatch(event) { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); -} - -function startWatchingForChangeEventIE8(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} - -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementID = null; -} - -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topChange) { - return topLevelTargetID; - } -} -function handleEventsForChangeEventIE8( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForChangeEventIE8(); - } -} - - -/** - * SECTION: handle `input` event - */ -var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { - // IE9 claims to support the input event but fails to trigger it when - // deleting text, so we ignore its input events - isInputEventSupported = isEventSupported('input') && ( - (!('documentMode' in document) || document.documentMode > 9) - ); -} - -/** - * (For old IE.) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function() { - return activeElementValueProp.get.call(this); - }, - set: function(val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; - -/** - * (For old IE.) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); - - Object.defineProperty(activeElement, 'value', newValueProp); - activeElement.attachEvent('onpropertychange', handlePropertyChange); -} - -/** - * (For old IE.) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - - // delete restores the original property definition - delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); - - activeElement = null; - activeElementID = null; - activeElementValue = null; - activeElementValueProp = null; -} - -/** - * (For old IE.) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; - - manualDispatchChangeEvent(nativeEvent); -} - -/** - * If a `change` event should be fired, returns the target's ID. - */ -function getTargetIDForInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topInput) { - // In modern browsers (i.e., not IE8 or IE9), the input event is exactly - // what we want so fall through here and trigger an abstract event - return topLevelTargetID; - } -} - -// For IE8 and IE9. -function handleEventsForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // In IE8, we can capture almost all .value changes by adding a - // propertychange handler and looking for events with propertyName - // equal to 'value' - // In IE9, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForValueChange(); - } -} - -// For IE8 and IE9. -function getTargetIDForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topSelectionChange || - topLevelType === topLevelTypes.topKeyUp || - topLevelType === topLevelTypes.topKeyDown) { - // On the selectionchange event, the target is just document which isn't - // helpful for us so just check activeElement instead. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementID; - } - } -} - - -/** - * SECTION: handle `click` event - */ -function shouldUseClickEvent(elem) { - // Use the `click` event to detect changes to checkbox and radio inputs. - // This approach works across all browsers, whereas `change` does not fire - // until `blur` in IE8. - return ( - elem.nodeName === 'INPUT' && - (elem.type === 'checkbox' || elem.type === 'radio') - ); -} - -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; - } -} - -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - var getTargetIDFunc, handleEventFunc; - if (shouldUseChangeEvent(topLevelTarget)) { - if (doesChangeEventBubble) { - getTargetIDFunc = getTargetIDForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(topLevelTarget)) { - if (isInputEventSupported) { - getTargetIDFunc = getTargetIDForInputEvent; - } else { - getTargetIDFunc = getTargetIDForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(topLevelTarget)) { - getTargetIDFunc = getTargetIDForClickEvent; - } - - if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } - - if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - } - } - -}; - -module.exports = ChangeEventPlugin; - -},{"136":136,"138":138,"141":141,"15":15,"17":17,"20":20,"21":21,"87":87,"95":95}],8:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ClientReactRootIndex - * @typechecks - */ - -'use strict'; - -var nextReactRootIndex = 0; - -var ClientReactRootIndex = { - createReactRootIndex: function() { - return nextReactRootIndex++; - } -}; - -module.exports = ClientReactRootIndex; - -},{}],9:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMChildrenOperations - * @typechecks static-only - */ - -'use strict'; - -var Danger = _dereq_(12); -var ReactMultiChildUpdateTypes = _dereq_(72); - -var setTextContent = _dereq_(149); -var invariant = _dereq_(135); - -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -function insertChildAt(parentNode, childNode, index) { - // By exploiting arrays returning `undefined` for an undefined index, we can - // rely exclusively on `insertBefore(node, null)` instead of also using - // `appendChild(node)`. However, using `undefined` is not allowed by all - // browsers so we must replace it with `null`. - parentNode.insertBefore( - childNode, - parentNode.childNodes[index] || null - ); -} - -/** - * Operations for updating with DOM children. - */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, - - updateTextContent: setTextContent, - - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array<object>} updates List of update configurations. - * @param {array<string>} markupList List of markup strings. - * @internal - */ - processUpdates: function(updates, markupList) { - var update; - // Mapping from parent IDs to initial child orderings. - var initialChildren = null; - // List of children that will be moved or removed. - var updatedChildren = null; - - for (var i = 0; i < updates.length; i++) { - update = updates[i]; - if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || - update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { - var updatedIndex = update.fromIndex; - var updatedChild = update.parentNode.childNodes[updatedIndex]; - var parentID = update.parentID; - - ("production" !== "development" ? invariant( - updatedChild, - 'processUpdates(): Unable to find child %s of element. This ' + - 'probably means the DOM was unexpectedly mutated (e.g., by the ' + - 'browser), usually due to forgetting a <tbody> when using tables, ' + - 'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' + - 'in an <svg> parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); - - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; - - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } - - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); - - // Remove updated children first so that `toIndex` is consistent. - if (updatedChildren) { - for (var j = 0; j < updatedChildren.length; j++) { - updatedChildren[j].parentNode.removeChild(updatedChildren[j]); - } - } - - for (var k = 0; k < updates.length; k++) { - update = updates[k]; - switch (update.type) { - case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent( - update.parentNode, - update.textContent - ); - break; - case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; - -},{"12":12,"135":135,"149":149,"72":72}],10:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMProperty - * @typechecks static-only - */ - -/*jslint bitwise: true */ - -'use strict'; - -var invariant = _dereq_(135); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } - - for (var propName in Properties) { - ("production" !== "development" ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - - DOMProperty.isStandardName[propName] = true; - - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; - } - - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; - - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } - - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - ("production" !== "development" ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== "development" ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== "development" ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); - } - } -}; -var defaultValueCache = {}; - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails `<propName> in <element>`.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. - * @type {Object} - */ - hasOverloadedBooleanValue: {}, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * TODO: Is it better to grab all the possible properties when creating an - * element to avoid having to create the same element twice? - */ - getDefaultValueForProperty: function(nodeName, prop) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; - } - return nodeDefaults[prop]; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; - -},{"135":135}],11:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = _dereq_(10); - -var quoteAttributeValueForBrowser = _dereq_(147); -var warning = _dereq_(154); - -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); -} - -if ("production" !== "development") { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true - }; - var warnedProperties = {}; - - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return; - } - - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); - - // For now, only warn when we have a suggested correction. This prevents - // logging too much when using transferPropsTo. - ("production" !== "development" ? warning( - standardName == null, - 'Unknown DOM property %s. Did you mean %s?', - name, - standardName - ) : null); - - }; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); - }, - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { - return ''; - } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return attributeName; - } - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("production" !== "development") { - warnUnknownProperty(name); - } - return null; - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { - this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); - } else { - var propName = DOMProperty.getPropertyName[name]; - // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the - // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propName] = value; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== "development") { - warnUnknownProperty(name); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { - node[propName] = defaultValue; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } else if ("production" !== "development") { - warnUnknownProperty(name); - } - } - -}; - -module.exports = DOMPropertyOperations; - -},{"10":10,"147":147,"154":154}],12:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Danger - * @typechecks static-only - */ - -/*jslint evil: true, sub: true */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(21); - -var createNodesFromMarkup = _dereq_(112); -var emptyFunction = _dereq_(114); -var getMarkupWrap = _dereq_(127); -var invariant = _dereq_(135); - -var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; -var RESULT_INDEX_ATTR = 'data-danger-index'; - -/** - * Extracts the `nodeName` from a string of markup. - * - * NOTE: Extracting the `nodeName` does not require a regular expression match - * because we make assumptions about React-generated markup (i.e. there are no - * spaces surrounding the opening tag and there is at least one attribute). - * - * @param {string} markup String of markup. - * @return {string} Node name of the supplied markup. - * @see http://jsperf.com/extract-nodename - */ -function getNodeName(markup) { - return markup.substring(1, markup.indexOf(' ')); -} - -var Danger = { - - /** - * Renders markup into an array of nodes. The markup is expected to render - * into a list of root nodes. Also, the length of `resultList` and - * `markupList` should be the same. - * - * @param {array<string>} markupList List of markup strings to render. - * @return {array<DOMElement>} List of rendered nodes. - * @internal - */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== "development" ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - var nodeName; - var markupByNodeName = {}; - // Group markup by `nodeName` if a wrap is necessary, else by '*'. - for (var i = 0; i < markupList.length; i++) { - ("production" !== "development" ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); - nodeName = getNodeName(markupList[i]); - nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; - markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; - markupByNodeName[nodeName][i] = markupList[i]; - } - var resultList = []; - var resultListAssignmentCount = 0; - for (nodeName in markupByNodeName) { - if (!markupByNodeName.hasOwnProperty(nodeName)) { - continue; - } - var markupListByNodeName = markupByNodeName[nodeName]; - - // This for-in loop skips the holes of the sparse array. The order of - // iteration should follow the order of assignment, which happens to match - // numerical index order, but we don't rely on that. - var resultIndex; - for (resultIndex in markupListByNodeName) { - if (markupListByNodeName.hasOwnProperty(resultIndex)) { - var markup = markupListByNodeName[resultIndex]; - - // Push the requested markup with an additional RESULT_INDEX_ATTR - // attribute. If the markup does not start with a < character, it - // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); - } - } - - // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with <script> tags. - ); - - for (var j = 0; j < renderNodes.length; ++j) { - var renderNode = renderNodes[j]; - if (renderNode.hasAttribute && - renderNode.hasAttribute(RESULT_INDEX_ATTR)) { - - resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR); - renderNode.removeAttribute(RESULT_INDEX_ATTR); - - ("production" !== "development" ? invariant( - !resultList.hasOwnProperty(resultIndex), - 'Danger: Assigning to an already-occupied result index.' - ) : invariant(!resultList.hasOwnProperty(resultIndex))); - - resultList[resultIndex] = renderNode; - - // This should match resultList.length and markupList.length when - // we're done. - resultListAssignmentCount += 1; - - } else if ("production" !== "development") { - console.error( - 'Danger: Discarding unexpected node:', - renderNode - ); - } - } - } - - // Although resultList was populated out of order, it should now be a dense - // array. - ("production" !== "development" ? invariant( - resultListAssignmentCount === resultList.length, - 'Danger: Did not assign to every index of resultList.' - ) : invariant(resultListAssignmentCount === resultList.length)); - - ("production" !== "development" ? invariant( - resultList.length === markupList.length, - 'Danger: Expected markup to render %s nodes, but rendered %s.', - markupList.length, - resultList.length - ) : invariant(resultList.length === markupList.length)); - - return resultList; - }, - - /** - * Replaces a node with a string of markup at its current position within its - * parent. The markup must render into a single root node. - * - * @param {DOMElement} oldChild Child node to replace. - * @param {string} markup Markup to render in place of the child node. - * @internal - */ - dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) { - ("production" !== "development" ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + - 'worker thread. Make sure `window` and `document` are available ' + - 'globally before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - ("production" !== "development" ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup)); - ("production" !== "development" ? invariant( - oldChild.tagName.toLowerCase() !== 'html', - 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + - '<html> node. This is because browser quirks make this unreliable ' + - 'and/or slow. If you want to render to the root you must use ' + - 'server rendering. See React.renderToString().' - ) : invariant(oldChild.tagName.toLowerCase() !== 'html')); - - var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; - oldChild.parentNode.replaceChild(newChild, oldChild); - } - -}; - -module.exports = Danger; - -},{"112":112,"114":114,"127":127,"135":135,"21":21}],13:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DefaultEventPluginOrder - */ - -'use strict'; - -var keyOf = _dereq_(141); - -/** - * Module that is injectable into `EventPluginHub`, that specifies a - * deterministic ordering of `EventPlugin`s. A convenient way to reason about - * plugins, without having to package every one of them. This is better than - * having plugins be ordered in the same order that they are injected because - * that ordering would be influenced by the packaging order. - * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that - * preventing default on events is convenient in `SimpleEventPlugin` handlers. - */ -var DefaultEventPluginOrder = [ - keyOf({ResponderEventPlugin: null}), - keyOf({SimpleEventPlugin: null}), - keyOf({TapEventPlugin: null}), - keyOf({EnterLeaveEventPlugin: null}), - keyOf({ChangeEventPlugin: null}), - keyOf({SelectEventPlugin: null}), - keyOf({BeforeInputEventPlugin: null}), - keyOf({AnalyticsEventPlugin: null}), - keyOf({MobileSafariClickEventPlugin: null}) -]; - -module.exports = DefaultEventPluginOrder; - -},{"141":141}],14:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EnterLeaveEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPropagators = _dereq_(20); -var SyntheticMouseEvent = _dereq_(99); - -var ReactMount = _dereq_(70); -var keyOf = _dereq_(141); - -var topLevelTypes = EventConstants.topLevelTypes; -var getFirstReactDOM = ReactMount.getFirstReactDOM; - -var eventTypes = { - mouseEnter: { - registrationName: keyOf({onMouseEnter: null}), - dependencies: [ - topLevelTypes.topMouseOut, - topLevelTypes.topMouseOver - ] - }, - mouseLeave: { - registrationName: keyOf({onMouseLeave: null}), - dependencies: [ - topLevelTypes.topMouseOut, - topLevelTypes.topMouseOver - ] - } -}; - -var extractedEvents = [null, null]; - -var EnterLeaveEventPlugin = { - - eventTypes: eventTypes, - - /** - * For almost every interaction we care about, there will be both a top-level - * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that - * we do not extract duplicate events. However, moving the mouse into the - * browser from outside will not fire a `mouseout` event. In this case, we use - * the `mouseover` top-level event. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - if (topLevelType === topLevelTypes.topMouseOver && - (nativeEvent.relatedTarget || nativeEvent.fromElement)) { - return null; - } - if (topLevelType !== topLevelTypes.topMouseOut && - topLevelType !== topLevelTypes.topMouseOver) { - // Must not be a mouse in or mouse out - ignoring. - return null; - } - - var win; - if (topLevelTarget.window === topLevelTarget) { - // `topLevelTarget` is probably a window object. - win = topLevelTarget; - } else { - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - var doc = topLevelTarget.ownerDocument; - if (doc) { - win = doc.defaultView || doc.parentWindow; - } else { - win = window; - } - } - - var from, to; - if (topLevelType === topLevelTypes.topMouseOut) { - from = topLevelTarget; - to = - getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) || - win; - } else { - from = win; - to = topLevelTarget; - } - - if (from === to) { - // Nothing pertains to our managed components. - return null; - } - - var fromID = from ? ReactMount.getID(from) : ''; - var toID = to ? ReactMount.getID(to) : ''; - - var leave = SyntheticMouseEvent.getPooled( - eventTypes.mouseLeave, - fromID, - nativeEvent - ); - leave.type = 'mouseleave'; - leave.target = from; - leave.relatedTarget = to; - - var enter = SyntheticMouseEvent.getPooled( - eventTypes.mouseEnter, - toID, - nativeEvent - ); - enter.type = 'mouseenter'; - enter.target = to; - enter.relatedTarget = from; - - EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID); - - extractedEvents[0] = leave; - extractedEvents[1] = enter; - - return extractedEvents; - } - -}; - -module.exports = EnterLeaveEventPlugin; - -},{"141":141,"15":15,"20":20,"70":70,"99":99}],15:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventConstants - */ - -'use strict'; - -var keyMirror = _dereq_(140); - -var PropagationPhases = keyMirror({bubbled: null, captured: null}); - -/** - * Types of raw signals from the browser caught at the top level. - */ -var topLevelTypes = keyMirror({ - topBlur: null, - topChange: null, - topClick: null, - topCompositionEnd: null, - topCompositionStart: null, - topCompositionUpdate: null, - topContextMenu: null, - topCopy: null, - topCut: null, - topDoubleClick: null, - topDrag: null, - topDragEnd: null, - topDragEnter: null, - topDragExit: null, - topDragLeave: null, - topDragOver: null, - topDragStart: null, - topDrop: null, - topError: null, - topFocus: null, - topInput: null, - topKeyDown: null, - topKeyPress: null, - topKeyUp: null, - topLoad: null, - topMouseDown: null, - topMouseMove: null, - topMouseOut: null, - topMouseOver: null, - topMouseUp: null, - topPaste: null, - topReset: null, - topScroll: null, - topSelectionChange: null, - topSubmit: null, - topTextInput: null, - topTouchCancel: null, - topTouchEnd: null, - topTouchMove: null, - topTouchStart: null, - topWheel: null -}); - -var EventConstants = { - topLevelTypes: topLevelTypes, - PropagationPhases: PropagationPhases -}; - -module.exports = EventConstants; - -},{"140":140}],16:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @providesModule EventListener - * @typechecks - */ - -var emptyFunction = _dereq_(114); - -/** - * Upstream version of event listener. Does not take into account specific - * nature of platform. - */ -var EventListener = { - /** - * Listen to DOM events during the bubble phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - listen: function(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function() { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent('on' + eventType, callback); - return { - remove: function() { - target.detachEvent('on' + eventType, callback); - } - }; - } - }, - - /** - * Listen to DOM events during the capture phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - capture: function(target, eventType, callback) { - if (!target.addEventListener) { - if ("production" !== "development") { - console.error( - 'Attempted to listen to events during the capture phase on a ' + - 'browser that does not support the capture phase. Your application ' + - 'will not receive some events.' - ); - } - return { - remove: emptyFunction - }; - } else { - target.addEventListener(eventType, callback, true); - return { - remove: function() { - target.removeEventListener(eventType, callback, true); - } - }; - } - }, - - registerDefault: function() {} -}; - -module.exports = EventListener; - -},{"114":114}],17:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPluginHub - */ - -'use strict'; - -var EventPluginRegistry = _dereq_(18); -var EventPluginUtils = _dereq_(19); - -var accumulateInto = _dereq_(105); -var forEachAccumulated = _dereq_(120); -var invariant = _dereq_(135); - -/** - * Internal store for event listeners - */ -var listenerBank = {}; - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ -var eventQueue = null; - -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private - */ -var executeDispatchesAndRelease = function(event) { - if (event) { - var executeDispatch = EventPluginUtils.executeDispatch; - // Plugins can provide custom behavior when dispatching events. - var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event); - if (PluginModule && PluginModule.executeDispatch) { - executeDispatch = PluginModule.executeDispatch; - } - EventPluginUtils.executeDispatchesInOrder(event, executeDispatch); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; - -/** - * - `InstanceHandle`: [required] Module that performs logical traversals of DOM - * hierarchy given ids of the logical DOM elements involved. - */ -var InstanceHandle = null; - -function validateInstanceHandle() { - var valid = - InstanceHandle && - InstanceHandle.traverseTwoPhase && - InstanceHandle.traverseEnterLeave; - ("production" !== "development" ? invariant( - valid, - 'InstanceHandle not injected before use!' - ) : invariant(valid)); -} - -/** - * This is a unified interface for event plugins to be installed and configured. - * - * Event plugins can implement the following properties: - * - * `extractEvents` {function(string, DOMEventTarget, string, object): *} - * Required. When a top-level event is fired, this method is expected to - * extract synthetic events that will in turn be queued and dispatched. - * - * `eventTypes` {object} - * Optional, plugins that fire events must publish a mapping of registration - * names that are used to register listeners. Values of this mapping must - * be objects that contain `registrationName` or `phasedRegistrationNames`. - * - * `executeDispatch` {function(object, function, string)} - * Optional, allows plugins to override how an event gets dispatched. By - * default, the listener is simply invoked. - * - * Each plugin that is injected into `EventsPluginHub` is immediately operable. - * - * @public - */ -var EventPluginHub = { - - /** - * Methods for injecting dependencies. - */ - injection: { - - /** - * @param {object} InjectedMount - * @public - */ - injectMount: EventPluginUtils.injection.injectMount, - - /** - * @param {object} InjectedInstanceHandle - * @public - */ - injectInstanceHandle: function(InjectedInstanceHandle) { - InstanceHandle = InjectedInstanceHandle; - if ("production" !== "development") { - validateInstanceHandle(); - } - }, - - getInstanceHandle: function() { - if ("production" !== "development") { - validateInstanceHandle(); - } - return InstanceHandle; - }, - - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, - - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName - - }, - - eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, - - registrationNameModules: EventPluginRegistry.registrationNameModules, - - /** - * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {?function} listener The callback to store. - */ - putListener: function(id, registrationName, listener) { - ("production" !== "development" ? invariant( - !listener || typeof listener === 'function', - 'Expected %s listener to be a function, instead got type %s', - registrationName, typeof listener - ) : invariant(!listener || typeof listener === 'function')); - - var bankForRegistrationName = - listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[id] = listener; - }, - - /** - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - getListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - return bankForRegistrationName && bankForRegistrationName[id]; - }, - - /** - * Deletes a listener from the registration bank. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - */ - deleteListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - if (bankForRegistrationName) { - delete bankForRegistrationName[id]; - } - }, - - /** - * Deletes all listeners for the DOM element with the supplied ID. - * - * @param {string} id ID of the DOM element. - */ - deleteAllListeners: function(id) { - for (var registrationName in listenerBank) { - delete listenerBank[registrationName][id]; - } - }, - - /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @internal - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var events; - var plugins = EventPluginRegistry.plugins; - for (var i = 0, l = plugins.length; i < l; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ); - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } - } - } - return events; - }, - - /** - * Enqueues a synthetic event that should be dispatched when - * `processEventQueue` is invoked. - * - * @param {*} events An accumulation of synthetic events. - * @internal - */ - enqueueEvents: function(events) { - if (events) { - eventQueue = accumulateInto(eventQueue, events); - } - }, - - /** - * Dispatches all synthetic events on the event queue. - * - * @internal - */ - processEventQueue: function() { - // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - var processingEventQueue = eventQueue; - eventQueue = null; - forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); - ("production" !== "development" ? invariant( - !eventQueue, - 'processEventQueue(): Additional events were enqueued while processing ' + - 'an event queue. Support for this has not yet been implemented.' - ) : invariant(!eventQueue)); - }, - - /** - * These are needed for tests only. Do not use! - */ - __purge: function() { - listenerBank = {}; - }, - - __getListenerBank: function() { - return listenerBank; - } - -}; - -module.exports = EventPluginHub; - -},{"105":105,"120":120,"135":135,"18":18,"19":19}],18:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPluginRegistry - * @typechecks static-only - */ - -'use strict'; - -var invariant = _dereq_(135); - -/** - * Injectable ordering of event plugins. - */ -var EventPluginOrder = null; - -/** - * Injectable mapping from names to event plugin modules. - */ -var namesToPlugins = {}; - -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ -function recomputePluginOrdering() { - if (!EventPluginOrder) { - // Wait until an `EventPluginOrder` is injected. - return; - } - for (var pluginName in namesToPlugins) { - var PluginModule = namesToPlugins[pluginName]; - var pluginIndex = EventPluginOrder.indexOf(pluginName); - ("production" !== "development" ? invariant( - pluginIndex > -1, - 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + - 'the plugin ordering, `%s`.', - pluginName - ) : invariant(pluginIndex > -1)); - if (EventPluginRegistry.plugins[pluginIndex]) { - continue; - } - ("production" !== "development" ? invariant( - PluginModule.extractEvents, - 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + - 'method, but `%s` does not.', - pluginName - ) : invariant(PluginModule.extractEvents)); - EventPluginRegistry.plugins[pluginIndex] = PluginModule; - var publishedEvents = PluginModule.eventTypes; - for (var eventName in publishedEvents) { - ("production" !== "development" ? invariant( - publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ), - 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', - eventName, - pluginName - ) : invariant(publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ))); - } - } -} - -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { - ("production" !== "development" ? invariant( - !EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName), - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'event name, `%s`.', - eventName - ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName))); - EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; - - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - PluginModule, - eventName - ); - } - } - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - PluginModule, - eventName - ); - return true; - } - return false; -} - -/** - * Publishes a registration name that is used to identify dispatched events and - * can be used with `EventPluginHub.putListener` to register listeners. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ -function publishRegistrationName(registrationName, PluginModule, eventName) { - ("production" !== "development" ? invariant( - !EventPluginRegistry.registrationNameModules[registrationName], - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'registration name, `%s`.', - registrationName - ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); - EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; - EventPluginRegistry.registrationNameDependencies[registrationName] = - PluginModule.eventTypes[eventName].dependencies; -} - -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ -var EventPluginRegistry = { - - /** - * Ordered list of injected plugins. - */ - plugins: [], - - /** - * Mapping from event name to dispatch config - */ - eventNameDispatchConfigs: {}, - - /** - * Mapping from registration name to plugin module - */ - registrationNameModules: {}, - - /** - * Mapping from registration name to event name - */ - registrationNameDependencies: {}, - - /** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - * @see {EventPluginHub.injection.injectEventPluginOrder} - */ - injectEventPluginOrder: function(InjectedEventPluginOrder) { - ("production" !== "development" ? invariant( - !EventPluginOrder, - 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + - 'once. You are likely trying to load more than one copy of React.' - ) : invariant(!EventPluginOrder)); - // Clone the ordering so it cannot be dynamically mutated. - EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); - recomputePluginOrdering(); - }, - - /** - * Injects plugins to be used by `EventPluginHub`. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - * @see {EventPluginHub.injection.injectEventPluginsByName} - */ - injectEventPluginsByName: function(injectedNamesToPlugins) { - var isOrderingDirty = false; - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - var PluginModule = injectedNamesToPlugins[pluginName]; - if (!namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== PluginModule) { - ("production" !== "development" ? invariant( - !namesToPlugins[pluginName], - 'EventPluginRegistry: Cannot inject two different event plugins ' + - 'using the same name, `%s`.', - pluginName - ) : invariant(!namesToPlugins[pluginName])); - namesToPlugins[pluginName] = PluginModule; - isOrderingDirty = true; - } - } - if (isOrderingDirty) { - recomputePluginOrdering(); - } - }, - - /** - * Looks up the plugin for the supplied event. - * - * @param {object} event A synthetic event. - * @return {?object} The plugin that created the supplied event. - * @internal - */ - getPluginModuleForEvent: function(event) { - var dispatchConfig = event.dispatchConfig; - if (dispatchConfig.registrationName) { - return EventPluginRegistry.registrationNameModules[ - dispatchConfig.registrationName - ] || null; - } - for (var phase in dispatchConfig.phasedRegistrationNames) { - if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { - continue; - } - var PluginModule = EventPluginRegistry.registrationNameModules[ - dispatchConfig.phasedRegistrationNames[phase] - ]; - if (PluginModule) { - return PluginModule; - } - } - return null; - }, - - /** - * Exposed for unit testing. - * @private - */ - _resetEventPlugins: function() { - EventPluginOrder = null; - for (var pluginName in namesToPlugins) { - if (namesToPlugins.hasOwnProperty(pluginName)) { - delete namesToPlugins[pluginName]; - } - } - EventPluginRegistry.plugins.length = 0; - - var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; - for (var eventName in eventNameDispatchConfigs) { - if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { - delete eventNameDispatchConfigs[eventName]; - } - } - - var registrationNameModules = EventPluginRegistry.registrationNameModules; - for (var registrationName in registrationNameModules) { - if (registrationNameModules.hasOwnProperty(registrationName)) { - delete registrationNameModules[registrationName]; - } - } - } - -}; - -module.exports = EventPluginRegistry; - -},{"135":135}],19:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPluginUtils - */ - -'use strict'; - -var EventConstants = _dereq_(15); - -var invariant = _dereq_(135); - -/** - * Injected dependencies: - */ - -/** - * - `Mount`: [required] Module that can convert between React dom IDs and - * actual node references. - */ -var injection = { - Mount: null, - injectMount: function(InjectedMount) { - injection.Mount = InjectedMount; - if ("production" !== "development") { - ("production" !== "development" ? invariant( - InjectedMount && InjectedMount.getNode, - 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + - 'is missing getNode.' - ) : invariant(InjectedMount && InjectedMount.getNode)); - } - } -}; - -var topLevelTypes = EventConstants.topLevelTypes; - -function isEndish(topLevelType) { - return topLevelType === topLevelTypes.topMouseUp || - topLevelType === topLevelTypes.topTouchEnd || - topLevelType === topLevelTypes.topTouchCancel; -} - -function isMoveish(topLevelType) { - return topLevelType === topLevelTypes.topMouseMove || - topLevelType === topLevelTypes.topTouchMove; -} -function isStartish(topLevelType) { - return topLevelType === topLevelTypes.topMouseDown || - topLevelType === topLevelTypes.topTouchStart; -} - - -var validateEventDispatches; -if ("production" !== "development") { - validateEventDispatches = function(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - - var listenersIsArr = Array.isArray(dispatchListeners); - var idsIsArr = Array.isArray(dispatchIDs); - var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; - var listenersLen = listenersIsArr ? - dispatchListeners.length : - dispatchListeners ? 1 : 0; - - ("production" !== "development" ? invariant( - idsIsArr === listenersIsArr && IDsLen === listenersLen, - 'EventPluginUtils: Invalid `event`.' - ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); - }; -} - -/** - * Invokes `cb(event, listener, id)`. Avoids using call if no scope is - * provided. The `(listener,id)` pair effectively forms the "dispatch" but are - * kept separate to conserve memory. - */ -function forEachEventDispatch(event, cb) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - if ("production" !== "development") { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and IDs are two parallel arrays that are always in sync. - cb(event, dispatchListeners[i], dispatchIDs[i]); - } - } else if (dispatchListeners) { - cb(event, dispatchListeners, dispatchIDs); - } -} - -/** - * Default implementation of PluginModule.executeDispatch(). - * @param {SyntheticEvent} SyntheticEvent to handle - * @param {function} Application-level callback - * @param {string} domID DOM id to pass to the callback. - */ -function executeDispatch(event, listener, domID) { - event.currentTarget = injection.Mount.getNode(domID); - var returnValue = listener(event, domID); - event.currentTarget = null; - return returnValue; -} - -/** - * Standard/simple iteration through an event's collected dispatches. - */ -function executeDispatchesInOrder(event, cb) { - forEachEventDispatch(event, cb); - event._dispatchListeners = null; - event._dispatchIDs = null; -} - -/** - * Standard/simple iteration through an event's collected dispatches, but stops - * at the first dispatch execution returning true, and returns that id. - * - * @return id of the first dispatch execution who's listener returns true, or - * null if no listener returned true. - */ -function executeDispatchesInOrderStopAtTrueImpl(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - if ("production" !== "development") { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and IDs are two parallel arrays that are always in sync. - if (dispatchListeners[i](event, dispatchIDs[i])) { - return dispatchIDs[i]; - } - } - } else if (dispatchListeners) { - if (dispatchListeners(event, dispatchIDs)) { - return dispatchIDs; - } - } - return null; -} - -/** - * @see executeDispatchesInOrderStopAtTrueImpl - */ -function executeDispatchesInOrderStopAtTrue(event) { - var ret = executeDispatchesInOrderStopAtTrueImpl(event); - event._dispatchIDs = null; - event._dispatchListeners = null; - return ret; -} - -/** - * Execution of a "direct" dispatch - there must be at most one dispatch - * accumulated on the event or it is considered an error. It doesn't really make - * sense for an event with multiple dispatches (bubbled) to keep track of the - * return values at each dispatch execution, but it does tend to make sense when - * dealing with "direct" dispatches. - * - * @return The return value of executing the single dispatch. - */ -function executeDirectDispatch(event) { - if ("production" !== "development") { - validateEventDispatches(event); - } - var dispatchListener = event._dispatchListeners; - var dispatchID = event._dispatchIDs; - ("production" !== "development" ? invariant( - !Array.isArray(dispatchListener), - 'executeDirectDispatch(...): Invalid `event`.' - ) : invariant(!Array.isArray(dispatchListener))); - var res = dispatchListener ? - dispatchListener(event, dispatchID) : - null; - event._dispatchListeners = null; - event._dispatchIDs = null; - return res; -} - -/** - * @param {SyntheticEvent} event - * @return {bool} True iff number of dispatches accumulated is greater than 0. - */ -function hasDispatches(event) { - return !!event._dispatchListeners; -} - -/** - * General utilities that are useful in creating custom Event Plugins. - */ -var EventPluginUtils = { - isEndish: isEndish, - isMoveish: isMoveish, - isStartish: isStartish, - - executeDirectDispatch: executeDirectDispatch, - executeDispatch: executeDispatch, - executeDispatchesInOrder: executeDispatchesInOrder, - executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, - hasDispatches: hasDispatches, - injection: injection, - useTouchEvents: false -}; - -module.exports = EventPluginUtils; - -},{"135":135,"15":15}],20:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule EventPropagators - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPluginHub = _dereq_(17); - -var accumulateInto = _dereq_(105); -var forEachAccumulated = _dereq_(120); - -var PropagationPhases = EventConstants.PropagationPhases; -var getListener = EventPluginHub.getListener; - -/** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(id, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(id, registrationName); -} - -/** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. - */ -function accumulateDirectionalDispatches(domID, upwards, event) { - if ("production" !== "development") { - if (!domID) { - throw new Error('Dispatching id must not be null'); - } - } - var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; - var listener = listenerAtPhase(domID, event, phase); - if (listener) { - event._dispatchListeners = - accumulateInto(event._dispatchListeners, listener); - event._dispatchIDs = accumulateInto(event._dispatchIDs, domID); - } -} - -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We can not perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - EventPluginHub.injection.getInstanceHandle().traverseTwoPhase( - event.dispatchMarker, - accumulateDirectionalDispatches, - event - ); - } -} - - -/** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. - */ -function accumulateDispatches(id, ignoredDirection, event) { - if (event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(id, registrationName); - if (listener) { - event._dispatchListeners = - accumulateInto(event._dispatchListeners, listener); - event._dispatchIDs = accumulateInto(event._dispatchIDs, id); - } - } -} - -/** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event - */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event.dispatchMarker, null, event); - } -} - -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} - -function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) { - EventPluginHub.injection.getInstanceHandle().traverseEnterLeave( - fromID, - toID, - accumulateDispatches, - leave, - enter - ); -} - - -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} - - - -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing event a - * single one. - * - * @constructor EventPropagators - */ -var EventPropagators = { - accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, - accumulateDirectDispatches: accumulateDirectDispatches, - accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches -}; - -module.exports = EventPropagators; - -},{"105":105,"120":120,"15":15,"17":17}],21:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ExecutionEnvironment - */ - -/*jslint evil: true */ - -"use strict"; - -var canUseDOM = !!( - (typeof window !== 'undefined' && - window.document && window.document.createElement) -); - -/** - * Simple, lightweight module assisting with the detection and context of - * Worker. Helps avoid circular dependencies and allows code to reason about - * whether or not they are in a Worker, even if they never include the main - * `ReactWorker` dependency. - */ -var ExecutionEnvironment = { - - canUseDOM: canUseDOM, - - canUseWorkers: typeof Worker !== 'undefined', - - canUseEventListeners: - canUseDOM && !!(window.addEventListener || window.attachEvent), - - canUseViewport: canUseDOM && !!window.screen, - - isInWorker: !canUseDOM // For now, this is true - might change in the future. - -}; - -module.exports = ExecutionEnvironment; - -},{}],22:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule FallbackCompositionState - * @typechecks static-only - */ - -'use strict'; - -var PooledClass = _dereq_(28); - -var assign = _dereq_(27); -var getTextContentAccessor = _dereq_(130); - -/** - * This helper class stores information about text content of a target node, - * allowing comparison of content before and after a given event. - * - * Identify the node where selection currently begins, then observe - * both its text content and its current position in the DOM. Since the - * browser may natively replace the target node during composition, we can - * use its position to find its replacement. - * - * @param {DOMEventTarget} root - */ -function FallbackCompositionState(root) { - this._root = root; - this._startText = this.getText(); - this._fallbackText = null; -} - -assign(FallbackCompositionState.prototype, { - /** - * Get current text of input. - * - * @return {string} - */ - getText: function() { - if ('value' in this._root) { - return this._root.value; - } - return this._root[getTextContentAccessor()]; - }, - - /** - * Determine the differing substring between the initially stored - * text content and the current content. - * - * @return {string} - */ - getData: function() { - if (this._fallbackText) { - return this._fallbackText; - } - - var start; - var startValue = this._startText; - var startLength = startValue.length; - var end; - var endValue = this.getText(); - var endLength = endValue.length; - - for (start = 0; start < startLength; start++) { - if (startValue[start] !== endValue[start]) { - break; - } - } - - var minEnd = startLength - start; - for (end = 1; end <= minEnd; end++) { - if (startValue[startLength - end] !== endValue[endLength - end]) { - break; - } - } - - var sliceTail = end > 1 ? 1 - end : undefined; - this._fallbackText = endValue.slice(start, sliceTail); - return this._fallbackText; - } -}); - -PooledClass.addPoolingTo(FallbackCompositionState); - -module.exports = FallbackCompositionState; - -},{"130":130,"27":27,"28":28}],23:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule HTMLDOMPropertyConfig - */ - -/*jslint bitwise: true*/ - -'use strict'; - -var DOMProperty = _dereq_(10); -var ExecutionEnvironment = _dereq_(21); - -var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; -var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; -var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; -var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS; -var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; -var HAS_POSITIVE_NUMERIC_VALUE = - DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; -var HAS_OVERLOADED_BOOLEAN_VALUE = - DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; - -var hasSVG; -if (ExecutionEnvironment.canUseDOM) { - var implementation = document.implementation; - hasSVG = ( - implementation && - implementation.hasFeature && - implementation.hasFeature( - 'http://www.w3.org/TR/SVG11/feature#BasicStructure', - '1.1' - ) - ); -} - - -var HTMLDOMPropertyConfig = { - isCustomAttribute: RegExp.prototype.test.bind( - /^(data|aria)-[a-z_][a-z\d_.\-]*$/ - ), - Properties: { - /** - * Standard Properties - */ - accept: null, - acceptCharset: null, - accessKey: null, - action: null, - allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - allowTransparency: MUST_USE_ATTRIBUTE, - alt: null, - async: HAS_BOOLEAN_VALUE, - autoComplete: null, - // autoFocus is polyfilled/normalized by AutoFocusMixin - // autoFocus: HAS_BOOLEAN_VALUE, - autoPlay: HAS_BOOLEAN_VALUE, - cellPadding: null, - cellSpacing: null, - charSet: MUST_USE_ATTRIBUTE, - checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - classID: MUST_USE_ATTRIBUTE, - // To set className on SVG elements, it's necessary to use .setAttribute; - // this works on HTML elements too in all browsers except IE8. Conveniently, - // IE8 doesn't support SVG and so we can simply use the attribute in - // browsers that support SVG and the property in browsers that don't, - // regardless of whether the element is HTML or SVG. - className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY, - cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - colSpan: null, - content: null, - contentEditable: null, - contextMenu: MUST_USE_ATTRIBUTE, - controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - coords: null, - crossOrigin: null, - data: null, // For `<object />` acts as `src`. - dateTime: MUST_USE_ATTRIBUTE, - defer: HAS_BOOLEAN_VALUE, - dir: null, - disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - download: HAS_OVERLOADED_BOOLEAN_VALUE, - draggable: null, - encType: null, - form: MUST_USE_ATTRIBUTE, - formAction: MUST_USE_ATTRIBUTE, - formEncType: MUST_USE_ATTRIBUTE, - formMethod: MUST_USE_ATTRIBUTE, - formNoValidate: HAS_BOOLEAN_VALUE, - formTarget: MUST_USE_ATTRIBUTE, - frameBorder: MUST_USE_ATTRIBUTE, - headers: null, - height: MUST_USE_ATTRIBUTE, - hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - high: null, - href: null, - hrefLang: null, - htmlFor: null, - httpEquiv: null, - icon: null, - id: MUST_USE_PROPERTY, - label: null, - lang: null, - list: MUST_USE_ATTRIBUTE, - loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - low: null, - manifest: MUST_USE_ATTRIBUTE, - marginHeight: null, - marginWidth: null, - max: null, - maxLength: MUST_USE_ATTRIBUTE, - media: MUST_USE_ATTRIBUTE, - mediaGroup: null, - method: null, - min: null, - multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - name: null, - noValidate: HAS_BOOLEAN_VALUE, - open: HAS_BOOLEAN_VALUE, - optimum: null, - pattern: null, - placeholder: null, - poster: null, - preload: null, - radioGroup: null, - readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - rel: null, - required: HAS_BOOLEAN_VALUE, - role: MUST_USE_ATTRIBUTE, - rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - rowSpan: null, - sandbox: null, - scope: null, - scoped: HAS_BOOLEAN_VALUE, - scrolling: null, - seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - shape: null, - size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - sizes: MUST_USE_ATTRIBUTE, - span: HAS_POSITIVE_NUMERIC_VALUE, - spellCheck: null, - src: null, - srcDoc: MUST_USE_PROPERTY, - srcSet: MUST_USE_ATTRIBUTE, - start: HAS_NUMERIC_VALUE, - step: null, - style: null, - tabIndex: null, - target: null, - title: null, - type: null, - useMap: null, - value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS, - width: MUST_USE_ATTRIBUTE, - wmode: MUST_USE_ATTRIBUTE, - - /** - * Non-standard Properties - */ - // autoCapitalize and autoCorrect are supported in Mobile Safari for - // keyboard hints. - autoCapitalize: null, - autoCorrect: null, - // itemProp, itemScope, itemType are for - // Microdata support. See http://schema.org/docs/gs.html - itemProp: MUST_USE_ATTRIBUTE, - itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - itemType: MUST_USE_ATTRIBUTE, - // itemID and itemRef are for Microdata support as well but - // only specified in the the WHATWG spec document. See - // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api - itemID: MUST_USE_ATTRIBUTE, - itemRef: MUST_USE_ATTRIBUTE, - // property is supported for OpenGraph in meta tags. - property: null, - // IE-only attribute that controls focus behavior - unselectable: MUST_USE_ATTRIBUTE - }, - DOMAttributeNames: { - acceptCharset: 'accept-charset', - className: 'class', - htmlFor: 'for', - httpEquiv: 'http-equiv' - }, - DOMPropertyNames: { - autoCapitalize: 'autocapitalize', - autoComplete: 'autocomplete', - autoCorrect: 'autocorrect', - autoFocus: 'autofocus', - autoPlay: 'autoplay', - // `encoding` is equivalent to `enctype`, IE8 lacks an `enctype` setter. - // http://www.w3.org/TR/html5/forms.html#dom-fs-encoding - encType: 'encoding', - hrefLang: 'hreflang', - radioGroup: 'radiogroup', - spellCheck: 'spellcheck', - srcDoc: 'srcdoc', - srcSet: 'srcset' - } -}; - -module.exports = HTMLDOMPropertyConfig; - -},{"10":10,"21":21}],24:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule LinkedValueUtils - * @typechecks static-only - */ - -'use strict'; - -var ReactPropTypes = _dereq_(78); - -var invariant = _dereq_(135); - -var hasReadOnlyValue = { - 'button': true, - 'checkbox': true, - 'image': true, - 'hidden': true, - 'radio': true, - 'reset': true, - 'submit': true -}; - -function _assertSingleLink(input) { - ("production" !== "development" ? invariant( - input.props.checkedLink == null || input.props.valueLink == null, - 'Cannot provide a checkedLink and a valueLink. If you want to use ' + - 'checkedLink, you probably don\'t want to use valueLink and vice versa.' - ) : invariant(input.props.checkedLink == null || input.props.valueLink == null)); -} -function _assertValueLink(input) { - _assertSingleLink(input); - ("production" !== "development" ? invariant( - input.props.value == null && input.props.onChange == null, - 'Cannot provide a valueLink and a value or onChange event. If you want ' + - 'to use value or onChange, you probably don\'t want to use valueLink.' - ) : invariant(input.props.value == null && input.props.onChange == null)); -} - -function _assertCheckedLink(input) { - _assertSingleLink(input); - ("production" !== "development" ? invariant( - input.props.checked == null && input.props.onChange == null, - 'Cannot provide a checkedLink and a checked property or onChange event. ' + - 'If you want to use checked or onChange, you probably don\'t want to ' + - 'use checkedLink' - ) : invariant(input.props.checked == null && input.props.onChange == null)); -} - -/** - * @param {SyntheticEvent} e change event to handle - */ -function _handleLinkedValueChange(e) { - /*jshint validthis:true */ - this.props.valueLink.requestChange(e.target.value); -} - -/** - * @param {SyntheticEvent} e change event to handle - */ -function _handleLinkedCheckChange(e) { - /*jshint validthis:true */ - this.props.checkedLink.requestChange(e.target.checked); -} - -/** - * Provide a linked `value` attribute for controlled forms. You should not use - * this outside of the ReactDOM controlled form components. - */ -var LinkedValueUtils = { - Mixin: { - propTypes: { - value: function(props, propName, componentName) { - if (!props[propName] || - hasReadOnlyValue[props.type] || - props.onChange || - props.readOnly || - props.disabled) { - return null; - } - return new Error( - 'You provided a `value` prop to a form field without an ' + - '`onChange` handler. This will render a read-only field. If ' + - 'the field should be mutable use `defaultValue`. Otherwise, ' + - 'set either `onChange` or `readOnly`.' - ); - }, - checked: function(props, propName, componentName) { - if (!props[propName] || - props.onChange || - props.readOnly || - props.disabled) { - return null; - } - return new Error( - 'You provided a `checked` prop to a form field without an ' + - '`onChange` handler. This will render a read-only field. If ' + - 'the field should be mutable use `defaultChecked`. Otherwise, ' + - 'set either `onChange` or `readOnly`.' - ); - }, - onChange: ReactPropTypes.func - } - }, - - /** - * @param {ReactComponent} input Form component - * @return {*} current value of the input either from value prop or link. - */ - getValue: function(input) { - if (input.props.valueLink) { - _assertValueLink(input); - return input.props.valueLink.value; - } - return input.props.value; - }, - - /** - * @param {ReactComponent} input Form component - * @return {*} current checked status of the input either from checked prop - * or link. - */ - getChecked: function(input) { - if (input.props.checkedLink) { - _assertCheckedLink(input); - return input.props.checkedLink.value; - } - return input.props.checked; - }, - - /** - * @param {ReactComponent} input Form component - * @return {function} change callback either from onChange prop or link. - */ - getOnChange: function(input) { - if (input.props.valueLink) { - _assertValueLink(input); - return _handleLinkedValueChange; - } else if (input.props.checkedLink) { - _assertCheckedLink(input); - return _handleLinkedCheckChange; - } - return input.props.onChange; - } -}; - -module.exports = LinkedValueUtils; - -},{"135":135,"78":78}],25:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule LocalEventTrapMixin - */ - -'use strict'; - -var ReactBrowserEventEmitter = _dereq_(30); - -var accumulateInto = _dereq_(105); -var forEachAccumulated = _dereq_(120); -var invariant = _dereq_(135); - -function remove(event) { - event.remove(); -} - -var LocalEventTrapMixin = { - trapBubbledEvent:function(topLevelType, handlerBaseName) { - ("production" !== "development" ? invariant(this.isMounted(), 'Must be mounted to trap events') : invariant(this.isMounted())); - // If a component renders to null or if another component fatals and causes - // the state of the tree to be corrupted, `node` here can be null. - var node = this.getDOMNode(); - ("production" !== "development" ? invariant( - node, - 'LocalEventTrapMixin.trapBubbledEvent(...): Requires node to be rendered.' - ) : invariant(node)); - var listener = ReactBrowserEventEmitter.trapBubbledEvent( - topLevelType, - handlerBaseName, - node - ); - this._localEventListeners = - accumulateInto(this._localEventListeners, listener); - }, - - // trapCapturedEvent would look nearly identical. We don't implement that - // method because it isn't currently needed. - - componentWillUnmount:function() { - if (this._localEventListeners) { - forEachAccumulated(this._localEventListeners, remove); - } - } -}; - -module.exports = LocalEventTrapMixin; - -},{"105":105,"120":120,"135":135,"30":30}],26:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule MobileSafariClickEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(15); - -var emptyFunction = _dereq_(114); - -var topLevelTypes = EventConstants.topLevelTypes; - -/** - * Mobile Safari does not fire properly bubble click events on non-interactive - * elements, which means delegated click listeners do not fire. The workaround - * for this bug involves attaching an empty click listener on the target node. - * - * This particular plugin works around the bug by attaching an empty click - * listener on `touchstart` (which does fire on every element). - */ -var MobileSafariClickEventPlugin = { - - eventTypes: null, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - if (topLevelType === topLevelTypes.topTouchStart) { - var target = nativeEvent.target; - if (target && !target.onclick) { - target.onclick = emptyFunction; - } - } - } - -}; - -module.exports = MobileSafariClickEventPlugin; - -},{"114":114,"15":15}],27:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Object.assign - */ - -// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign - -'use strict'; - -function assign(target, sources) { - if (target == null) { - throw new TypeError('Object.assign target cannot be null or undefined'); - } - - var to = Object(target); - var hasOwnProperty = Object.prototype.hasOwnProperty; - - for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { - var nextSource = arguments[nextIndex]; - if (nextSource == null) { - continue; - } - - var from = Object(nextSource); - - // We don't currently support accessors nor proxies. Therefore this - // copy cannot throw. If we ever supported this then we must handle - // exceptions and side-effects. We don't support symbols so they won't - // be transferred. - - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - } - - return to; -} - -module.exports = assign; - -},{}],28:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule PooledClass - */ - -'use strict'; - -var invariant = _dereq_(135); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function(copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function(a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function(a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4, a5); - return instance; - } else { - return new Klass(a1, a2, a3, a4, a5); - } -}; - -var standardReleaser = function(instance) { - var Klass = this; - ("production" !== "development" ? invariant( - instance instanceof Klass, - 'Trying to release an instance into a pool of a different type.' - ) : invariant(instance instanceof Klass)); - if (instance.destructor) { - instance.destructor(); - } - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances (optional). - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function(CopyConstructor, pooler) { - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fiveArgumentPooler: fiveArgumentPooler -}; - -module.exports = PooledClass; - -},{"135":135}],29:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactBrowserComponentMixin - */ - -'use strict'; - -var findDOMNode = _dereq_(117); - -var ReactBrowserComponentMixin = { - /** - * Returns the DOM node rendered by this component. - * - * @return {DOMElement} The root node of this component. - * @final - * @protected - */ - getDOMNode: function() { - return findDOMNode(this); - } -}; - -module.exports = ReactBrowserComponentMixin; - -},{"117":117}],30:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactBrowserEventEmitter - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPluginHub = _dereq_(17); -var EventPluginRegistry = _dereq_(18); -var ReactEventEmitterMixin = _dereq_(61); -var ViewportMetrics = _dereq_(104); - -var assign = _dereq_(27); -var isEventSupported = _dereq_(136); - -/** - * Summary of `ReactBrowserEventEmitter` event handling: - * - * - Top-level delegation is used to trap most native browser events. This - * may only occur in the main thread and is the responsibility of - * ReactEventListener, which is injected and can therefore support pluggable - * event sources. This is the only work that occurs in the main thread. - * - * - We normalize and de-duplicate events to account for browser quirks. This - * may be done in the worker thread. - * - * - Forward these native events (with the associated top-level type used to - * trap it) to `EventPluginHub`, which in turn will ask plugins if they want - * to extract any synthetic events. - * - * - The `EventPluginHub` will then process each event by annotating them with - * "dispatches", a sequence of listeners and IDs that care about that event. - * - * - The `EventPluginHub` then dispatches the events. - * - * Overview of React and the event system: - * - * +------------+ . - * | DOM | . - * +------------+ . - * | . - * v . - * +------------+ . - * | ReactEvent | . - * | Listener | . - * +------------+ . +-----------+ - * | . +--------+|SimpleEvent| - * | . | |Plugin | - * +-----|------+ . v +-----------+ - * | | | . +--------------+ +------------+ - * | +-----------.--->|EventPluginHub| | Event | - * | | . | | +-----------+ | Propagators| - * | ReactEvent | . | | |TapEvent | |------------| - * | Emitter | . | |<---+|Plugin | |other plugin| - * | | . | | +-----------+ | utilities | - * | +-----------.--->| | +------------+ - * | | | . +--------------+ - * +-----|------+ . ^ +-----------+ - * | . | |Enter/Leave| - * + . +-------+|Plugin | - * +-------------+ . +-----------+ - * | application | . - * |-------------| . - * | | . - * | | . - * +-------------+ . - * . - * React Core . General Purpose Event Plugin System - */ - -var alreadyListeningTo = {}; -var isMonitoringScrollValue = false; -var reactTopListenersCounter = 0; - -// For events like 'submit' which don't consistently bubble (which we trap at a -// lower node than `document`), binding at `document` would cause duplicate -// events so we don't include them here -var topEventMapping = { - topBlur: 'blur', - topChange: 'change', - topClick: 'click', - topCompositionEnd: 'compositionend', - topCompositionStart: 'compositionstart', - topCompositionUpdate: 'compositionupdate', - topContextMenu: 'contextmenu', - topCopy: 'copy', - topCut: 'cut', - topDoubleClick: 'dblclick', - topDrag: 'drag', - topDragEnd: 'dragend', - topDragEnter: 'dragenter', - topDragExit: 'dragexit', - topDragLeave: 'dragleave', - topDragOver: 'dragover', - topDragStart: 'dragstart', - topDrop: 'drop', - topFocus: 'focus', - topInput: 'input', - topKeyDown: 'keydown', - topKeyPress: 'keypress', - topKeyUp: 'keyup', - topMouseDown: 'mousedown', - topMouseMove: 'mousemove', - topMouseOut: 'mouseout', - topMouseOver: 'mouseover', - topMouseUp: 'mouseup', - topPaste: 'paste', - topScroll: 'scroll', - topSelectionChange: 'selectionchange', - topTextInput: 'textInput', - topTouchCancel: 'touchcancel', - topTouchEnd: 'touchend', - topTouchMove: 'touchmove', - topTouchStart: 'touchstart', - topWheel: 'wheel' -}; - -/** - * To ensure no conflicts with other potential React instances on the page - */ -var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; - } - return alreadyListeningTo[mountAt[topListenersIDKey]]; -} - -/** - * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For - * example: - * - * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction); - * - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. - * - * @internal - */ -var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { - - /** - * Injectable event backend - */ - ReactEventListener: null, - - injection: { - /** - * @param {object} ReactEventListener - */ - injectReactEventListener: function(ReactEventListener) { - ReactEventListener.setHandleTopLevel( - ReactBrowserEventEmitter.handleTopLevel - ); - ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; - } - }, - - /** - * Sets whether or not any created callbacks should be enabled. - * - * @param {boolean} enabled True if callbacks should be enabled. - */ - setEnabled: function(enabled) { - if (ReactBrowserEventEmitter.ReactEventListener) { - ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); - } - }, - - /** - * @return {boolean} True if callbacks are enabled. - */ - isEnabled: function() { - return !!( - (ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()) - ); - }, - - /** - * We listen for bubbled touch events on the document object. - * - * Firefox v8.01 (and possibly others) exhibited strange behavior when - * mounting `onmousemove` events at some node that was not the document - * element. The symptoms were that if your mouse is not moving over something - * contained within that mount point (for example on the background) the - * top-level listeners for `onmousemove` won't be called. However, if you - * register the `mousemove` on the document object, then it will of course - * catch all `mousemove`s. This along with iOS quirks, justifies restricting - * top-level listeners to the document object only, at least for these - * movement types of events and possibly all events. - * - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - * - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but - * they bubble to document. - * - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {object} contentDocumentHandle Document which owns the container - */ - listenTo: function(registrationName, contentDocumentHandle) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry. - registrationNameDependencies[registrationName]; - - var topLevelTypes = EventConstants.topLevelTypes; - for (var i = 0, l = dependencies.length; i < l; i++) { - var dependency = dependencies[i]; - if (!( - (isListening.hasOwnProperty(dependency) && isListening[dependency]) - )) { - if (dependency === topLevelTypes.topWheel) { - if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'wheel', - mountAt - ); - } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'mousewheel', - mountAt - ); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'DOMMouseScroll', - mountAt - ); - } - } else if (dependency === topLevelTypes.topScroll) { - - if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topScroll, - 'scroll', - mountAt - ); - } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topScroll, - 'scroll', - ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE - ); - } - } else if (dependency === topLevelTypes.topFocus || - dependency === topLevelTypes.topBlur) { - - if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topFocus, - 'focus', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topBlur, - 'blur', - mountAt - ); - } else if (isEventSupported('focusin')) { - // IE has `focusin` and `focusout` events which bubble. - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topFocus, - 'focusin', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topBlur, - 'focusout', - mountAt - ); - } - - // to make sure blur and focus event listeners are only attached once - isListening[topLevelTypes.topBlur] = true; - isListening[topLevelTypes.topFocus] = true; - } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - dependency, - topEventMapping[dependency], - mountAt - ); - } - - isListening[dependency] = true; - } - } - }, - - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelType, - handlerBaseName, - handle - ); - }, - - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelType, - handlerBaseName, - handle - ); - }, - - /** - * Listens to window scroll and resize events. We cache scroll values so that - * application code can access them without triggering reflows. - * - * NOTE: Scroll events do not bubble. - * - * @see http://www.quirksmode.org/dom/events/scroll.html - */ - ensureScrollValueMonitoring: function() { - if (!isMonitoringScrollValue) { - var refresh = ViewportMetrics.refreshScrollValues; - ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); - isMonitoringScrollValue = true; - } - }, - - eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, - - registrationNameModules: EventPluginHub.registrationNameModules, - - putListener: EventPluginHub.putListener, - - getListener: EventPluginHub.getListener, - - deleteListener: EventPluginHub.deleteListener, - - deleteAllListeners: EventPluginHub.deleteAllListeners - -}); - -module.exports = ReactBrowserEventEmitter; - -},{"104":104,"136":136,"15":15,"17":17,"18":18,"27":27,"61":61}],31:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactChildReconciler - * @typechecks static-only - */ - -'use strict'; - -var ReactReconciler = _dereq_(81); - -var flattenChildren = _dereq_(118); -var instantiateReactComponent = _dereq_(134); -var shouldUpdateReactComponent = _dereq_(151); - -/** - * ReactChildReconciler provides helpers for initializing or updating a set of - * children. Its output is suitable for passing it onto ReactMultiChild which - * does diffed reordering and insertion. - */ -var ReactChildReconciler = { - - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildNodes Nested child maps. - * @return {?object} A set of child instances. - * @internal - */ - instantiateChildren: function(nestedChildNodes, transaction, context) { - var children = flattenChildren(nestedChildNodes); - for (var name in children) { - if (children.hasOwnProperty(name)) { - var child = children[name]; - // The rendered children must be turned into instances as they're - // mounted. - var childInstance = instantiateReactComponent(child, null); - children[name] = childInstance; - } - } - return children; - }, - - /** - * Updates the rendered children and returns a new set of children. - * - * @param {?object} prevChildren Previously initialized set of children. - * @param {?object} nextNestedChildNodes Nested child maps. - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @return {?object} A new set of child instances. - * @internal - */ - updateChildren: function( - prevChildren, - nextNestedChildNodes, - transaction, - context) { - // We currently don't have a way to track moves here but if we use iterators - // instead of for..in we can zip the iterators and check if an item has - // moved. - // TODO: If nothing has changed, return the prevChildren object so that we - // can quickly bailout if nothing has changed. - var nextChildren = flattenChildren(nextNestedChildNodes); - if (!nextChildren && !prevChildren) { - return null; - } - var name; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - var prevChild = prevChildren && prevChildren[name]; - var prevElement = prevChild && prevChild._currentElement; - var nextElement = nextChildren[name]; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - ReactReconciler.receiveComponent( - prevChild, nextElement, transaction, context - ); - nextChildren[name] = prevChild; - } else { - if (prevChild) { - ReactReconciler.unmountComponent(prevChild, name); - } - // The child must be instantiated before it's mounted. - var nextChildInstance = instantiateReactComponent( - nextElement, - null - ); - nextChildren[name] = nextChildInstance; - } - } - // Unmount children that are no longer present. - for (name in prevChildren) { - if (prevChildren.hasOwnProperty(name) && - !(nextChildren && nextChildren.hasOwnProperty(name))) { - ReactReconciler.unmountComponent(prevChildren[name]); - } - } - return nextChildren; - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. - * - * @param {?object} renderedChildren Previously initialized set of children. - * @internal - */ - unmountChildren: function(renderedChildren) { - for (var name in renderedChildren) { - var renderedChild = renderedChildren[name]; - ReactReconciler.unmountComponent(renderedChild); - } - } - -}; - -module.exports = ReactChildReconciler; - -},{"118":118,"134":134,"151":151,"81":81}],32:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactChildren - */ - -'use strict'; - -var PooledClass = _dereq_(28); -var ReactFragment = _dereq_(63); - -var traverseAllChildren = _dereq_(153); -var warning = _dereq_(154); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; -var threeArgumentPooler = PooledClass.threeArgumentPooler; - -/** - * PooledClass representing the bookkeeping associated with performing a child - * traversal. Allows avoiding binding callbacks. - * - * @constructor ForEachBookKeeping - * @param {!function} forEachFunction Function to perform traversal with. - * @param {?*} forEachContext Context to perform context with. - */ -function ForEachBookKeeping(forEachFunction, forEachContext) { - this.forEachFunction = forEachFunction; - this.forEachContext = forEachContext; -} -PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); - -function forEachSingleChild(traverseContext, child, name, i) { - var forEachBookKeeping = traverseContext; - forEachBookKeeping.forEachFunction.call( - forEachBookKeeping.forEachContext, child, i); -} - -/** - * Iterates through children that are typically specified as `props.children`. - * - * The provided forEachFunc(child, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc. - * @param {*} forEachContext Context for forEachContext. - */ -function forEachChildren(children, forEachFunc, forEachContext) { - if (children == null) { - return children; - } - - var traverseContext = - ForEachBookKeeping.getPooled(forEachFunc, forEachContext); - traverseAllChildren(children, forEachSingleChild, traverseContext); - ForEachBookKeeping.release(traverseContext); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * mapping. Allows avoiding binding callbacks. - * - * @constructor MapBookKeeping - * @param {!*} mapResult Object containing the ordered map of results. - * @param {!function} mapFunction Function to perform mapping with. - * @param {?*} mapContext Context to perform mapping with. - */ -function MapBookKeeping(mapResult, mapFunction, mapContext) { - this.mapResult = mapResult; - this.mapFunction = mapFunction; - this.mapContext = mapContext; -} -PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); - -function mapSingleChildIntoContext(traverseContext, child, name, i) { - var mapBookKeeping = traverseContext; - var mapResult = mapBookKeeping.mapResult; - - var keyUnique = !mapResult.hasOwnProperty(name); - if ("production" !== "development") { - ("production" !== "development" ? warning( - keyUnique, - 'ReactChildren.map(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ) : null); - } - - if (keyUnique) { - var mappedChild = - mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); - mapResult[name] = mappedChild; - } -} - -/** - * Maps children that are typically specified as `props.children`. - * - * The provided mapFunction(child, key, index) will be called for each - * leaf child. - * - * TODO: This may likely break any calls to `ReactChildren.map` that were - * previously relying on the fact that we guarded against null children. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} mapFunction. - * @param {*} mapContext Context for mapFunction. - * @return {object} Object containing the ordered map of results. - */ -function mapChildren(children, func, context) { - if (children == null) { - return children; - } - - var mapResult = {}; - var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); - traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); - MapBookKeeping.release(traverseContext); - return ReactFragment.create(mapResult); -} - -function forEachSingleChildDummy(traverseContext, child, name, i) { - return null; -} - -/** - * Count the number of children that are typically specified as - * `props.children`. - * - * @param {?*} children Children tree container. - * @return {number} The number of children. - */ -function countChildren(children, context) { - return traverseAllChildren(children, forEachSingleChildDummy, null); -} - -var ReactChildren = { - forEach: forEachChildren, - map: mapChildren, - count: countChildren -}; - -module.exports = ReactChildren; - -},{"153":153,"154":154,"28":28,"63":63}],33:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactClass - */ - -'use strict'; - -var ReactComponent = _dereq_(34); -var ReactCurrentOwner = _dereq_(39); -var ReactElement = _dereq_(57); -var ReactErrorUtils = _dereq_(60); -var ReactInstanceMap = _dereq_(67); -var ReactLifeCycle = _dereq_(68); -var ReactPropTypeLocations = _dereq_(77); -var ReactPropTypeLocationNames = _dereq_(76); -var ReactUpdateQueue = _dereq_(86); - -var assign = _dereq_(27); -var invariant = _dereq_(135); -var keyMirror = _dereq_(140); -var keyOf = _dereq_(141); -var warning = _dereq_(154); - -var MIXINS_KEY = keyOf({mixins: null}); - -/** - * Policies that describe methods in `ReactClassInterface`. - */ -var SpecPolicy = keyMirror({ - /** - * These methods may be defined only once by the class specification or mixin. - */ - DEFINE_ONCE: null, - /** - * These methods may be defined by both the class specification and mixins. - * Subsequent definitions will be chained. These methods must return void. - */ - DEFINE_MANY: null, - /** - * These methods are overriding the base class. - */ - OVERRIDE_BASE: null, - /** - * These methods are similar to DEFINE_MANY, except we assume they return - * objects. We try to merge the keys of the return values of all the mixed in - * functions. If there is a key conflict we throw. - */ - DEFINE_MANY_MERGED: null -}); - - -var injectedMixins = []; - -/** - * Composite components are higher-level components that compose other composite - * or native components. - * - * To create a new type of `ReactClass`, pass a specification of - * your new class to `React.createClass`. The only requirement of your class - * specification is that you implement a `render` method. - * - * var MyComponent = React.createClass({ - * render: function() { - * return <div>Hello World</div>; - * } - * }); - * - * The class specification supports a specific protocol of methods that have - * special meaning (e.g. `render`). See `ReactClassInterface` for - * more the comprehensive protocol. Any other properties and methods in the - * class specification will available on the prototype. - * - * @interface ReactClassInterface - * @internal - */ -var ReactClassInterface = { - - /** - * An array of Mixin objects to include when defining your component. - * - * @type {array} - * @optional - */ - mixins: SpecPolicy.DEFINE_MANY, - - /** - * An object containing properties and methods that should be defined on - * the component's constructor instead of its prototype (static methods). - * - * @type {object} - * @optional - */ - statics: SpecPolicy.DEFINE_MANY, - - /** - * Definition of prop types for this component. - * - * @type {object} - * @optional - */ - propTypes: SpecPolicy.DEFINE_MANY, - - /** - * Definition of context types for this component. - * - * @type {object} - * @optional - */ - contextTypes: SpecPolicy.DEFINE_MANY, - - /** - * Definition of context types this component sets for its children. - * - * @type {object} - * @optional - */ - childContextTypes: SpecPolicy.DEFINE_MANY, - - // ==== Definition methods ==== - - /** - * Invoked when the component is mounted. Values in the mapping will be set on - * `this.props` if that prop is not specified (i.e. using an `in` check). - * - * This method is invoked before `getInitialState` and therefore cannot rely - * on `this.state` or use `this.setState`. - * - * @return {object} - * @optional - */ - getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * Invoked once before the component is mounted. The return value will be used - * as the initial value of `this.state`. - * - * getInitialState: function() { - * return { - * isOn: false, - * fooBaz: new BazFoo() - * } - * } - * - * @return {object} - * @optional - */ - getInitialState: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * @return {object} - * @optional - */ - getChildContext: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * Uses props from `this.props` and state from `this.state` to render the - * structure of the component. - * - * No guarantees are made about when or how often this method is invoked, so - * it must not have side effects. - * - * render: function() { - * var name = this.props.name; - * return <div>Hello, {name}!</div>; - * } - * - * @return {ReactComponent} - * @nosideeffects - * @required - */ - render: SpecPolicy.DEFINE_ONCE, - - - - // ==== Delegate methods ==== - - /** - * Invoked when the component is initially created and about to be mounted. - * This may have side effects, but any external subscriptions or data created - * by this method must be cleaned up in `componentWillUnmount`. - * - * @optional - */ - componentWillMount: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component has been mounted and has a DOM representation. - * However, there is no guarantee that the DOM node is in the document. - * - * Use this as an opportunity to operate on the DOM when the component has - * been mounted (initialized and rendered) for the first time. - * - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidMount: SpecPolicy.DEFINE_MANY, - - /** - * Invoked before the component receives new props. - * - * Use this as an opportunity to react to a prop transition by updating the - * state using `this.setState`. Current props are accessed via `this.props`. - * - * componentWillReceiveProps: function(nextProps, nextContext) { - * this.setState({ - * likesIncreasing: nextProps.likeCount > this.props.likeCount - * }); - * } - * - * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop - * transition may cause a state change, but the opposite is not true. If you - * need it, you are probably looking for `componentWillUpdate`. - * - * @param {object} nextProps - * @optional - */ - componentWillReceiveProps: SpecPolicy.DEFINE_MANY, - - /** - * Invoked while deciding if the component should be updated as a result of - * receiving new props, state and/or context. - * - * Use this as an opportunity to `return false` when you're certain that the - * transition to the new props/state/context will not require a component - * update. - * - * shouldComponentUpdate: function(nextProps, nextState, nextContext) { - * return !equal(nextProps, this.props) || - * !equal(nextState, this.state) || - * !equal(nextContext, this.context); - * } - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @return {boolean} True if the component should update. - * @optional - */ - shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, - - /** - * Invoked when the component is about to update due to a transition from - * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` - * and `nextContext`. - * - * Use this as an opportunity to perform preparation before an update occurs. - * - * NOTE: You **cannot** use `this.setState()` in this method. - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @param {ReactReconcileTransaction} transaction - * @optional - */ - componentWillUpdate: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component's DOM representation has been updated. - * - * Use this as an opportunity to operate on the DOM when the component has - * been updated. - * - * @param {object} prevProps - * @param {?object} prevState - * @param {?object} prevContext - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidUpdate: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component is about to be removed from its parent and have - * its DOM representation destroyed. - * - * Use this as an opportunity to deallocate any external resources. - * - * NOTE: There is no `componentDidUnmount` since your component will have been - * destroyed by that point. - * - * @optional - */ - componentWillUnmount: SpecPolicy.DEFINE_MANY, - - - - // ==== Advanced methods ==== - - /** - * Updates the component's currently mounted DOM representation. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @internal - * @overridable - */ - updateComponent: SpecPolicy.OVERRIDE_BASE - -}; - -/** - * Mapping from class specification keys to special processing functions. - * - * Although these are declared like instance properties in the specification - * when defining classes using `React.createClass`, they are actually static - * and are accessible on the constructor instead of the prototype. Despite - * being static, they must be defined outside of the "statics" key under - * which all other static methods are defined. - */ -var RESERVED_SPEC_KEYS = { - displayName: function(Constructor, displayName) { - Constructor.displayName = displayName; - }, - mixins: function(Constructor, mixins) { - if (mixins) { - for (var i = 0; i < mixins.length; i++) { - mixSpecIntoComponent(Constructor, mixins[i]); - } - } - }, - childContextTypes: function(Constructor, childContextTypes) { - if ("production" !== "development") { - validateTypeDef( - Constructor, - childContextTypes, - ReactPropTypeLocations.childContext - ); - } - Constructor.childContextTypes = assign( - {}, - Constructor.childContextTypes, - childContextTypes - ); - }, - contextTypes: function(Constructor, contextTypes) { - if ("production" !== "development") { - validateTypeDef( - Constructor, - contextTypes, - ReactPropTypeLocations.context - ); - } - Constructor.contextTypes = assign( - {}, - Constructor.contextTypes, - contextTypes - ); - }, - /** - * Special case getDefaultProps which should move into statics but requires - * automatic merging. - */ - getDefaultProps: function(Constructor, getDefaultProps) { - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps = createMergedResultFunction( - Constructor.getDefaultProps, - getDefaultProps - ); - } else { - Constructor.getDefaultProps = getDefaultProps; - } - }, - propTypes: function(Constructor, propTypes) { - if ("production" !== "development") { - validateTypeDef( - Constructor, - propTypes, - ReactPropTypeLocations.prop - ); - } - Constructor.propTypes = assign( - {}, - Constructor.propTypes, - propTypes - ); - }, - statics: function(Constructor, statics) { - mixStaticSpecIntoComponent(Constructor, statics); - } -}; - -function validateTypeDef(Constructor, typeDef, location) { - for (var propName in typeDef) { - if (typeDef.hasOwnProperty(propName)) { - // use a warning instead of an invariant so components - // don't show up in prod but not in __DEV__ - ("production" !== "development" ? warning( - typeof typeDef[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - Constructor.displayName || 'ReactClass', - ReactPropTypeLocationNames[location], - propName - ) : null); - } - } -} - -function validateMethodOverride(proto, name) { - var specPolicy = ReactClassInterface.hasOwnProperty(name) ? - ReactClassInterface[name] : - null; - - // Disallow overriding of base class methods unless explicitly allowed. - if (ReactClassMixin.hasOwnProperty(name)) { - ("production" !== "development" ? invariant( - specPolicy === SpecPolicy.OVERRIDE_BASE, - 'ReactClassInterface: You are attempting to override ' + - '`%s` from your class specification. Ensure that your method names ' + - 'do not overlap with React methods.', - name - ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); - } - - // Disallow defining methods more than once unless explicitly allowed. - if (proto.hasOwnProperty(name)) { - ("production" !== "development" ? invariant( - specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED, - 'ReactClassInterface: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be due ' + - 'to a mixin.', - name - ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); - } -} - -/** - * Mixin helper which handles policy validation and reserved - * specification keys when building React classses. - */ -function mixSpecIntoComponent(Constructor, spec) { - if (!spec) { - return; - } - - ("production" !== "development" ? invariant( - typeof spec !== 'function', - 'ReactClass: You\'re attempting to ' + - 'use a component class as a mixin. Instead, just use a regular object.' - ) : invariant(typeof spec !== 'function')); - ("production" !== "development" ? invariant( - !ReactElement.isValidElement(spec), - 'ReactClass: You\'re attempting to ' + - 'use a component as a mixin. Instead, just use a regular object.' - ) : invariant(!ReactElement.isValidElement(spec))); - - var proto = Constructor.prototype; - - // By handling mixins before any other properties, we ensure the same - // chaining order is applied to methods with DEFINE_MANY policy, whether - // mixins are listed before or after these methods in the spec. - if (spec.hasOwnProperty(MIXINS_KEY)) { - RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); - } - - for (var name in spec) { - if (!spec.hasOwnProperty(name)) { - continue; - } - - if (name === MIXINS_KEY) { - // We have already handled mixins in a special case above - continue; - } - - var property = spec[name]; - validateMethodOverride(proto, name); - - if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { - RESERVED_SPEC_KEYS[name](Constructor, property); - } else { - // Setup methods on prototype: - // The following member methods should not be automatically bound: - // 1. Expected ReactClass methods (in the "interface"). - // 2. Overridden methods (that were mixed in). - var isReactClassMethod = - ReactClassInterface.hasOwnProperty(name); - var isAlreadyDefined = proto.hasOwnProperty(name); - var markedDontBind = property && property.__reactDontBind; - var isFunction = typeof property === 'function'; - var shouldAutoBind = - isFunction && - !isReactClassMethod && - !isAlreadyDefined && - !markedDontBind; - - if (shouldAutoBind) { - if (!proto.__reactAutoBindMap) { - proto.__reactAutoBindMap = {}; - } - proto.__reactAutoBindMap[name] = property; - proto[name] = property; - } else { - if (isAlreadyDefined) { - var specPolicy = ReactClassInterface[name]; - - // These cases should already be caught by validateMethodOverride - ("production" !== "development" ? invariant( - isReactClassMethod && ( - (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) - ), - 'ReactClass: Unexpected spec policy %s for key %s ' + - 'when mixing in component specs.', - specPolicy, - name - ) : invariant(isReactClassMethod && ( - (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) - ))); - - // For methods which are defined more than once, call the existing - // methods before calling the new property, merging if appropriate. - if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { - proto[name] = createMergedResultFunction(proto[name], property); - } else if (specPolicy === SpecPolicy.DEFINE_MANY) { - proto[name] = createChainedFunction(proto[name], property); - } - } else { - proto[name] = property; - if ("production" !== "development") { - // Add verbose displayName to the function, which helps when looking - // at profiling tools. - if (typeof property === 'function' && spec.displayName) { - proto[name].displayName = spec.displayName + '_' + name; - } - } - } - } - } - } -} - -function mixStaticSpecIntoComponent(Constructor, statics) { - if (!statics) { - return; - } - for (var name in statics) { - var property = statics[name]; - if (!statics.hasOwnProperty(name)) { - continue; - } - - var isReserved = name in RESERVED_SPEC_KEYS; - ("production" !== "development" ? invariant( - !isReserved, - 'ReactClass: You are attempting to define a reserved ' + - 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + - 'as an instance property instead; it will still be accessible on the ' + - 'constructor.', - name - ) : invariant(!isReserved)); - - var isInherited = name in Constructor; - ("production" !== "development" ? invariant( - !isInherited, - 'ReactClass: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be ' + - 'due to a mixin.', - name - ) : invariant(!isInherited)); - Constructor[name] = property; - } -} - -/** - * Merge two objects, but throw if both contain the same key. - * - * @param {object} one The first object, which is mutated. - * @param {object} two The second object - * @return {object} one after it has been mutated to contain everything in two. - */ -function mergeIntoWithNoDuplicateKeys(one, two) { - ("production" !== "development" ? invariant( - one && two && typeof one === 'object' && typeof two === 'object', - 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' - ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); - - for (var key in two) { - if (two.hasOwnProperty(key)) { - ("production" !== "development" ? invariant( - one[key] === undefined, - 'mergeIntoWithNoDuplicateKeys(): ' + - 'Tried to merge two objects with the same key: `%s`. This conflict ' + - 'may be due to a mixin; in particular, this may be caused by two ' + - 'getInitialState() or getDefaultProps() methods returning objects ' + - 'with clashing keys.', - key - ) : invariant(one[key] === undefined)); - one[key] = two[key]; - } - } - return one; -} - -/** - * Creates a function that invokes two functions and merges their return values. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createMergedResultFunction(one, two) { - return function mergedResult() { - var a = one.apply(this, arguments); - var b = two.apply(this, arguments); - if (a == null) { - return b; - } else if (b == null) { - return a; - } - var c = {}; - mergeIntoWithNoDuplicateKeys(c, a); - mergeIntoWithNoDuplicateKeys(c, b); - return c; - }; -} - -/** - * Creates a function that invokes two functions and ignores their return vales. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createChainedFunction(one, two) { - return function chainedFunction() { - one.apply(this, arguments); - two.apply(this, arguments); - }; -} - -/** - * Binds a method to the component. - * - * @param {object} component Component whose method is going to be bound. - * @param {function} method Method to be bound. - * @return {function} The bound method. - */ -function bindAutoBindMethod(component, method) { - var boundMethod = method.bind(component); - if ("production" !== "development") { - boundMethod.__reactBoundContext = component; - boundMethod.__reactBoundMethod = method; - boundMethod.__reactBoundArguments = null; - var componentName = component.constructor.displayName; - var _bind = boundMethod.bind; - /* eslint-disable block-scoped-var, no-undef */ - boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - // User is trying to bind() an autobound method; we effectively will - // ignore the value of "this" that the user is trying to use, so - // let's warn. - if (newThis !== component && newThis !== null) { - ("production" !== "development" ? warning( - false, - 'bind(): React component methods may only be bound to the ' + - 'component instance. See %s', - componentName - ) : null); - } else if (!args.length) { - ("production" !== "development" ? warning( - false, - 'bind(): You are binding a component method to the component. ' + - 'React does this for you automatically in a high-performance ' + - 'way, so you can safely remove this call. See %s', - componentName - ) : null); - return boundMethod; - } - var reboundMethod = _bind.apply(boundMethod, arguments); - reboundMethod.__reactBoundContext = component; - reboundMethod.__reactBoundMethod = method; - reboundMethod.__reactBoundArguments = args; - return reboundMethod; - /* eslint-enable */ - }; - } - return boundMethod; -} - -/** - * Binds all auto-bound methods in a component. - * - * @param {object} component Component whose method is going to be bound. - */ -function bindAutoBindMethods(component) { - for (var autoBindKey in component.__reactAutoBindMap) { - if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { - var method = component.__reactAutoBindMap[autoBindKey]; - component[autoBindKey] = bindAutoBindMethod( - component, - ReactErrorUtils.guard( - method, - component.constructor.displayName + '.' + autoBindKey - ) - ); - } - } -} - -var typeDeprecationDescriptor = { - enumerable: false, - get: function() { - var displayName = this.displayName || this.name || 'Component'; - ("production" !== "development" ? warning( - false, - '%s.type is deprecated. Use %s directly to access the class.', - displayName, - displayName - ) : null); - Object.defineProperty(this, 'type', { - value: this - }); - return this; - } -}; - -/** - * Add more to the ReactClass base class. These are all legacy features and - * therefore not already part of the modern ReactComponent. - */ -var ReactClassMixin = { - - /** - * TODO: This will be deprecated because state should always keep a consistent - * type signature and the only use case for this, is to avoid that. - */ - replaceState: function(newState, callback) { - ReactUpdateQueue.enqueueReplaceState(this, newState); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - }, - - /** - * Checks whether or not this composite component is mounted. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function() { - if ("production" !== "development") { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - ("production" !== "development" ? warning( - owner._warnedAboutRefsInRender, - '%s is accessing isMounted inside its render() function. ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ) : null); - owner._warnedAboutRefsInRender = true; - } - } - var internalInstance = ReactInstanceMap.get(this); - return ( - internalInstance && - internalInstance !== ReactLifeCycle.currentlyMountingInstance - ); - }, - - /** - * Sets a subset of the props. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - * @deprecated - */ - setProps: function(partialProps, callback) { - ReactUpdateQueue.enqueueSetProps(this, partialProps); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - }, - - /** - * Replace all the props. - * - * @param {object} newProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - * @deprecated - */ - replaceProps: function(newProps, callback) { - ReactUpdateQueue.enqueueReplaceProps(this, newProps); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - } -}; - -var ReactClassComponent = function() {}; -assign( - ReactClassComponent.prototype, - ReactComponent.prototype, - ReactClassMixin -); - -/** - * Module for creating composite components. - * - * @class ReactClass - */ -var ReactClass = { - - /** - * Creates a composite component class given a class specification. - * - * @param {object} spec Class specification (which must define `render`). - * @return {function} Component constructor function. - * @public - */ - createClass: function(spec) { - var Constructor = function(props, context) { - // This constructor is overridden by mocks. The argument is used - // by mocks to assert on what gets mounted. - - if ("production" !== "development") { - ("production" !== "development" ? warning( - this instanceof Constructor, - 'Something is calling a React component directly. Use a factory or ' + - 'JSX instead. See: https://fb.me/react-legacyfactory' - ) : null); - } - - // Wire up auto-binding - if (this.__reactAutoBindMap) { - bindAutoBindMethods(this); - } - - this.props = props; - this.context = context; - this.state = null; - - // ReactClasses doesn't have constructors. Instead, they use the - // getInitialState and componentWillMount methods for initialization. - - var initialState = this.getInitialState ? this.getInitialState() : null; - if ("production" !== "development") { - // We allow auto-mocks to proceed as if they're returning null. - if (typeof initialState === 'undefined' && - this.getInitialState._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - initialState = null; - } - } - ("production" !== "development" ? invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.getInitialState(): must return an object or null', - Constructor.displayName || 'ReactCompositeComponent' - ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); - - this.state = initialState; - }; - Constructor.prototype = new ReactClassComponent(); - Constructor.prototype.constructor = Constructor; - - injectedMixins.forEach( - mixSpecIntoComponent.bind(null, Constructor) - ); - - mixSpecIntoComponent(Constructor, spec); - - // Initialize the defaultProps property after all mixins have been merged - if (Constructor.getDefaultProps) { - Constructor.defaultProps = Constructor.getDefaultProps(); - } - - if ("production" !== "development") { - // This is a tag to indicate that the use of these method names is ok, - // since it's used with createClass. If it's not, then it's likely a - // mistake so we'll warn you to use the static property, property - // initializer or constructor respectively. - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps.isReactClassApproved = {}; - } - if (Constructor.prototype.getInitialState) { - Constructor.prototype.getInitialState.isReactClassApproved = {}; - } - } - - ("production" !== "development" ? invariant( - Constructor.prototype.render, - 'createClass(...): Class specification must implement a `render` method.' - ) : invariant(Constructor.prototype.render)); - - if ("production" !== "development") { - ("production" !== "development" ? warning( - !Constructor.prototype.componentShouldUpdate, - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - spec.displayName || 'A component' - ) : null); - } - - // Reduce time spent doing lookups by setting these on the prototype. - for (var methodName in ReactClassInterface) { - if (!Constructor.prototype[methodName]) { - Constructor.prototype[methodName] = null; - } - } - - // Legacy hook - Constructor.type = Constructor; - if ("production" !== "development") { - try { - Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - - return Constructor; - }, - - injection: { - injectMixin: function(mixin) { - injectedMixins.push(mixin); - } - } - -}; - -module.exports = ReactClass; - -},{"135":135,"140":140,"141":141,"154":154,"27":27,"34":34,"39":39,"57":57,"60":60,"67":67,"68":68,"76":76,"77":77,"86":86}],34:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactComponent - */ - -'use strict'; - -var ReactUpdateQueue = _dereq_(86); - -var invariant = _dereq_(135); -var warning = _dereq_(154); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactComponent(props, context) { - this.props = props; - this.context = context; -} - -/** - * Sets a subset of the state. Always use this to mutate - * state. You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * There is no guarantee that calls to `setState` will run synchronously, - * as they may eventually be batched together. You can provide an optional - * callback that will be executed when the call to setState is actually - * completed. - * - * When a function is provided to setState, it will be called at some point in - * the future (not synchronously). It will be called with the up to date - * component arguments (state, props, context). These values can be different - * from this.* because your function may be called after receiveProps but before - * shouldComponentUpdate, and this new state, props, and context will not yet be - * assigned to this. - * - * @param {object|function} partialState Next partial state or function to - * produce next partial state to be merged with current state. - * @param {?function} callback Called after state is updated. - * @final - * @protected - */ -ReactComponent.prototype.setState = function(partialState, callback) { - ("production" !== "development" ? invariant( - typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null, - 'setState(...): takes an object of state variables to update or a ' + - 'function which returns an object of state variables.' - ) : invariant(typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null)); - if ("production" !== "development") { - ("production" !== "development" ? warning( - partialState != null, - 'setState(...): You passed an undefined or null state object; ' + - 'instead, use forceUpdate().' - ) : null); - } - ReactUpdateQueue.enqueueSetState(this, partialState); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } -}; - -/** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {?function} callback Called after update is complete. - * @final - * @protected - */ -ReactComponent.prototype.forceUpdate = function(callback) { - ReactUpdateQueue.enqueueForceUpdate(this); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } -}; - -/** - * Deprecated APIs. These APIs used to exist on classic React classes but since - * we would like to deprecate them, we're not going to move them over to this - * modern base class. Instead, we define a getter that warns if it's accessed. - */ -if ("production" !== "development") { - var deprecatedAPIs = { - getDOMNode: [ - 'getDOMNode', - 'Use React.findDOMNode(component) instead.' - ], - isMounted: [ - 'isMounted', - 'Instead, make sure to clean up subscriptions and pending requests in ' + - 'componentWillUnmount to prevent memory leaks.' - ], - replaceProps: [ - 'replaceProps', - 'Instead call React.render again at the top level.' - ], - replaceState: [ - 'replaceState', - 'Refactor your code to use setState instead (see ' + - 'https://github.com/facebook/react/issues/3236).' - ], - setProps: [ - 'setProps', - 'Instead call React.render again at the top level.' - ] - }; - var defineDeprecationWarning = function(methodName, info) { - try { - Object.defineProperty(ReactComponent.prototype, methodName, { - get: function() { - ("production" !== "development" ? warning( - false, - '%s(...) is deprecated in plain JavaScript React classes. %s', - info[0], - info[1] - ) : null); - return undefined; - } - }); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - }; - for (var fnName in deprecatedAPIs) { - if (deprecatedAPIs.hasOwnProperty(fnName)) { - defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); - } - } -} - -module.exports = ReactComponent; - -},{"135":135,"154":154,"86":86}],35:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactComponentBrowserEnvironment - */ - -/*jslint evil: true */ - -'use strict'; - -var ReactDOMIDOperations = _dereq_(44); -var ReactMount = _dereq_(70); - -/** - * Abstracts away all functionality of the reconciler that requires knowledge of - * the browser context. TODO: These callers should be refactored to avoid the - * need for this injection. - */ -var ReactComponentBrowserEnvironment = { - - processChildrenUpdates: - ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, - - replaceNodeWithMarkupByID: - ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID, - - /** - * If a particular environment requires that some resources be cleaned up, - * specify this in the injected Mixin. In the DOM, we would likely want to - * purge any cached node ID lookups. - * - * @private - */ - unmountIDFromEnvironment: function(rootNodeID) { - ReactMount.purgeID(rootNodeID); - } - -}; - -module.exports = ReactComponentBrowserEnvironment; - -},{"44":44,"70":70}],36:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactComponentEnvironment - */ - -'use strict'; - -var invariant = _dereq_(135); - -var injected = false; - -var ReactComponentEnvironment = { - - /** - * Optionally injectable environment dependent cleanup hook. (server vs. - * browser etc). Example: A browser system caches DOM nodes based on component - * ID and must remove that cache entry when this instance is unmounted. - */ - unmountIDFromEnvironment: null, - - /** - * Optionally injectable hook for swapping out mount images in the middle of - * the tree. - */ - replaceNodeWithMarkupByID: null, - - /** - * Optionally injectable hook for processing a queue of child updates. Will - * later move into MultiChildComponents. - */ - processChildrenUpdates: null, - - injection: { - injectEnvironment: function(environment) { - ("production" !== "development" ? invariant( - !injected, - 'ReactCompositeComponent: injectEnvironment() can only be called once.' - ) : invariant(!injected)); - ReactComponentEnvironment.unmountIDFromEnvironment = - environment.unmountIDFromEnvironment; - ReactComponentEnvironment.replaceNodeWithMarkupByID = - environment.replaceNodeWithMarkupByID; - ReactComponentEnvironment.processChildrenUpdates = - environment.processChildrenUpdates; - injected = true; - } - } - -}; - -module.exports = ReactComponentEnvironment; - -},{"135":135}],37:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactCompositeComponent - */ - -'use strict'; - -var ReactComponentEnvironment = _dereq_(36); -var ReactContext = _dereq_(38); -var ReactCurrentOwner = _dereq_(39); -var ReactElement = _dereq_(57); -var ReactElementValidator = _dereq_(58); -var ReactInstanceMap = _dereq_(67); -var ReactLifeCycle = _dereq_(68); -var ReactNativeComponent = _dereq_(73); -var ReactPerf = _dereq_(75); -var ReactPropTypeLocations = _dereq_(77); -var ReactPropTypeLocationNames = _dereq_(76); -var ReactReconciler = _dereq_(81); -var ReactUpdates = _dereq_(87); - -var assign = _dereq_(27); -var emptyObject = _dereq_(115); -var invariant = _dereq_(135); -var shouldUpdateReactComponent = _dereq_(151); -var warning = _dereq_(154); - -function getDeclarationErrorAddendum(component) { - var owner = component._currentElement._owner || null; - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * ------------------ The Life-Cycle of a Composite Component ------------------ - * - * - constructor: Initialization of state. The instance is now retained. - * - componentWillMount - * - render - * - [children's constructors] - * - [children's componentWillMount and render] - * - [children's componentDidMount] - * - componentDidMount - * - * Update Phases: - * - componentWillReceiveProps (only called if parent updated) - * - shouldComponentUpdate - * - componentWillUpdate - * - render - * - [children's constructors or receive props phases] - * - componentDidUpdate - * - * - componentWillUnmount - * - [children's componentWillUnmount] - * - [children destroyed] - * - (destroyed): The instance is now blank, released by React and ready for GC. - * - * ----------------------------------------------------------------------------- - */ - -/** - * An incrementing ID assigned to each component when it is mounted. This is - * used to enforce the order in which `ReactUpdates` updates dirty components. - * - * @private - */ -var nextMountID = 1; - -/** - * @lends {ReactCompositeComponent.prototype} - */ -var ReactCompositeComponentMixin = { - - /** - * Base constructor for all composite component. - * - * @param {ReactElement} element - * @final - * @internal - */ - construct: function(element) { - this._currentElement = element; - this._rootNodeID = null; - this._instance = null; - - // See ReactUpdateQueue - this._pendingElement = null; - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - this._renderedComponent = null; - - this._context = null; - this._mountOrder = 0; - this._isTopLevel = false; - - // See ReactUpdates and ReactUpdateQueue. - this._pendingCallbacks = null; - }, - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function(rootID, transaction, context) { - this._context = context; - this._mountOrder = nextMountID++; - this._rootNodeID = rootID; - - var publicProps = this._processProps(this._currentElement.props); - var publicContext = this._processContext(this._currentElement._context); - - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); - - // Initialize the public class - var inst = new Component(publicProps, publicContext); - - if ("production" !== "development") { - // This will throw later in _renderValidatedComponent, but add an early - // warning now to help debugging - ("production" !== "development" ? warning( - inst.render != null, - '%s(...): No `render` method found on the returned component ' + - 'instance: you may have forgotten to define `render` in your ' + - 'component or you may have accidentally tried to render an element ' + - 'whose type is a function that isn\'t a React component.', - Component.displayName || Component.name || 'Component' - ) : null); - } - - // These should be set up in the constructor, but as a convenience for - // simpler class abstractions, we set them up after the fact. - inst.props = publicProps; - inst.context = publicContext; - inst.refs = emptyObject; - - this._instance = inst; - - // Store a reference from the instance back to the internal representation - ReactInstanceMap.set(inst, this); - - if ("production" !== "development") { - this._warnIfContextsDiffer(this._currentElement._context, context); - } - - if ("production" !== "development") { - // Since plain JS classes are defined without any special initialization - // logic, we can not catch common errors early. Therefore, we have to - // catch them here, at initialization time, instead. - ("production" !== "development" ? warning( - !inst.getInitialState || - inst.getInitialState.isReactClassApproved, - 'getInitialState was defined on %s, a plain JavaScript class. ' + - 'This is only supported for classes created using React.createClass. ' + - 'Did you mean to define a state property instead?', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - !inst.getDefaultProps || - inst.getDefaultProps.isReactClassApproved, - 'getDefaultProps was defined on %s, a plain JavaScript class. ' + - 'This is only supported for classes created using React.createClass. ' + - 'Use a static property to define defaultProps instead.', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - !inst.propTypes, - 'propTypes was defined as an instance property on %s. Use a static ' + - 'property to define propTypes instead.', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - !inst.contextTypes, - 'contextTypes was defined as an instance property on %s. Use a ' + - 'static property to define contextTypes instead.', - this.getName() || 'a component' - ) : null); - ("production" !== "development" ? warning( - typeof inst.componentShouldUpdate !== 'function', - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - (this.getName() || 'A component') - ) : null); - } - - var initialState = inst.state; - if (initialState === undefined) { - inst.state = initialState = null; - } - ("production" !== "development" ? invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.state: must be set to an object or null', - this.getName() || 'ReactCompositeComponent' - ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); - - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - var childContext; - var renderedElement; - - var previouslyMounting = ReactLifeCycle.currentlyMountingInstance; - ReactLifeCycle.currentlyMountingInstance = this; - try { - if (inst.componentWillMount) { - inst.componentWillMount(); - // When mounting, calls to `setState` by `componentWillMount` will set - // `this._pendingStateQueue` without triggering a re-render. - if (this._pendingStateQueue) { - inst.state = this._processPendingState(inst.props, inst.context); - } - } - - childContext = this._getValidatedChildContext(context); - renderedElement = this._renderValidatedComponent(childContext); - } finally { - ReactLifeCycle.currentlyMountingInstance = previouslyMounting; - } - - this._renderedComponent = this._instantiateReactComponent( - renderedElement, - this._currentElement.type // The wrapping type - ); - - var markup = ReactReconciler.mountComponent( - this._renderedComponent, - rootID, - transaction, - this._mergeChildContext(context, childContext) - ); - if (inst.componentDidMount) { - transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); - } - - return markup; - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function() { - var inst = this._instance; - - if (inst.componentWillUnmount) { - var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance; - ReactLifeCycle.currentlyUnmountingInstance = this; - try { - inst.componentWillUnmount(); - } finally { - ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting; - } - } - - ReactReconciler.unmountComponent(this._renderedComponent); - this._renderedComponent = null; - - // Reset pending fields - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - this._pendingCallbacks = null; - this._pendingElement = null; - - // These fields do not really need to be reset since this object is no - // longer accessible. - this._context = null; - this._rootNodeID = null; - - // Delete the reference from the instance to this internal representation - // which allow the internals to be properly cleaned up even if the user - // leaks a reference to the public instance. - ReactInstanceMap.remove(inst); - - // Some existing components rely on inst.props even after they've been - // destroyed (in event handlers). - // TODO: inst.props = null; - // TODO: inst.state = null; - // TODO: inst.context = null; - }, - - /** - * Schedule a partial update to the props. Only used for internal testing. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @internal - */ - _setPropsInternal: function(partialProps, callback) { - // This is a deoptimized path. We optimize for always having an element. - // This creates an extra internal element. - var element = this._pendingElement || this._currentElement; - this._pendingElement = ReactElement.cloneAndReplaceProps( - element, - assign({}, element.props, partialProps) - ); - ReactUpdates.enqueueUpdate(this, callback); - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes` - * - * @param {object} context - * @return {?object} - * @private - */ - _maskContext: function(context) { - var maskedContext = null; - // This really should be getting the component class for the element, - // but we know that we're not going to need it for built-ins. - if (typeof this._currentElement.type === 'string') { - return emptyObject; - } - var contextTypes = this._currentElement.type.contextTypes; - if (!contextTypes) { - return emptyObject; - } - maskedContext = {}; - for (var contextName in contextTypes) { - maskedContext[contextName] = context[contextName]; - } - return maskedContext; - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes`, and asserts that they are valid. - * - * @param {object} context - * @return {?object} - * @private - */ - _processContext: function(context) { - var maskedContext = this._maskContext(context); - if ("production" !== "development") { - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); - if (Component.contextTypes) { - this._checkPropTypes( - Component.contextTypes, - maskedContext, - ReactPropTypeLocations.context - ); - } - } - return maskedContext; - }, - - /** - * @param {object} currentContext - * @return {object} - * @private - */ - _getValidatedChildContext: function(currentContext) { - var inst = this._instance; - var childContext = inst.getChildContext && inst.getChildContext(); - if (childContext) { - ("production" !== "development" ? invariant( - typeof inst.constructor.childContextTypes === 'object', - '%s.getChildContext(): childContextTypes must be defined in order to ' + - 'use getChildContext().', - this.getName() || 'ReactCompositeComponent' - ) : invariant(typeof inst.constructor.childContextTypes === 'object')); - if ("production" !== "development") { - this._checkPropTypes( - inst.constructor.childContextTypes, - childContext, - ReactPropTypeLocations.childContext - ); - } - for (var name in childContext) { - ("production" !== "development" ? invariant( - name in inst.constructor.childContextTypes, - '%s.getChildContext(): key "%s" is not defined in childContextTypes.', - this.getName() || 'ReactCompositeComponent', - name - ) : invariant(name in inst.constructor.childContextTypes)); - } - return childContext; - } - return null; - }, - - _mergeChildContext: function(currentContext, childContext) { - if (childContext) { - return assign({}, currentContext, childContext); - } - return currentContext; - }, - - /** - * Processes props by setting default values for unspecified props and - * asserting that the props are valid. Does not mutate its argument; returns - * a new props object with defaults merged in. - * - * @param {object} newProps - * @return {object} - * @private - */ - _processProps: function(newProps) { - if ("production" !== "development") { - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); - if (Component.propTypes) { - this._checkPropTypes( - Component.propTypes, - newProps, - ReactPropTypeLocations.prop - ); - } - } - return newProps; - }, - - /** - * Assert that the props are valid - * - * @param {object} propTypes Map of prop name to a ReactPropType - * @param {object} props - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ - _checkPropTypes: function(propTypes, props, location) { - // TODO: Stop validating prop types here and only use the element - // validation. - var componentName = this.getName(); - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error; - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - ("production" !== "development" ? invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually ' + - 'from React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ) : invariant(typeof propTypes[propName] === 'function')); - error = propTypes[propName](props, propName, componentName, location); - } catch (ex) { - error = ex; - } - if (error instanceof Error) { - // We may want to extend this logic for similar errors in - // React.render calls, so I'm abstracting it away into - // a function to minimize refactoring in the future - var addendum = getDeclarationErrorAddendum(this); - - if (location === ReactPropTypeLocations.prop) { - // Preface gives us something to blacklist in warning module - ("production" !== "development" ? warning( - false, - 'Failed Composite propType: %s%s', - error.message, - addendum - ) : null); - } else { - ("production" !== "development" ? warning( - false, - 'Failed Context Types: %s%s', - error.message, - addendum - ) : null); - } - } - } - } - }, - - receiveComponent: function(nextElement, transaction, nextContext) { - var prevElement = this._currentElement; - var prevContext = this._context; - - this._pendingElement = null; - - this.updateComponent( - transaction, - prevElement, - nextElement, - prevContext, - nextContext - ); - }, - - /** - * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` - * is set, update the component. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function(transaction) { - if (this._pendingElement != null) { - ReactReconciler.receiveComponent( - this, - this._pendingElement || this._currentElement, - transaction, - this._context - ); - } - - if (this._pendingStateQueue !== null || this._pendingForceUpdate) { - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps( - this._currentElement - ); - } - - this.updateComponent( - transaction, - this._currentElement, - this._currentElement, - this._context, - this._context - ); - } - }, - - /** - * Compare two contexts, warning if they are different - * TODO: Remove this check when owner-context is removed - */ - _warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) { - ownerBasedContext = this._maskContext(ownerBasedContext); - parentBasedContext = this._maskContext(parentBasedContext); - var parentKeys = Object.keys(parentBasedContext).sort(); - var displayName = this.getName() || 'ReactCompositeComponent'; - for (var i = 0; i < parentKeys.length; i++) { - var key = parentKeys[i]; - ("production" !== "development" ? warning( - ownerBasedContext[key] === parentBasedContext[key], - 'owner-based and parent-based contexts differ ' + - '(values: `%s` vs `%s`) for key (%s) while mounting %s ' + - '(see: http://fb.me/react-context-by-parent)', - ownerBasedContext[key], - parentBasedContext[key], - key, - displayName - ) : null); - } - }, - - /** - * Perform an update to a mounted component. The componentWillReceiveProps and - * shouldComponentUpdate methods are called, then (assuming the update isn't - * skipped) the remaining update lifecycle methods are called and the DOM - * representation is updated. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevParentElement - * @param {ReactElement} nextParentElement - * @internal - * @overridable - */ - updateComponent: function( - transaction, - prevParentElement, - nextParentElement, - prevUnmaskedContext, - nextUnmaskedContext - ) { - var inst = this._instance; - - var nextContext = inst.context; - var nextProps = inst.props; - - // Distinguish between a props update versus a simple state update - if (prevParentElement !== nextParentElement) { - nextContext = this._processContext(nextParentElement._context); - nextProps = this._processProps(nextParentElement.props); - - if ("production" !== "development") { - if (nextUnmaskedContext != null) { - this._warnIfContextsDiffer( - nextParentElement._context, - nextUnmaskedContext - ); - } - } - - // An update here will schedule an update but immediately set - // _pendingStateQueue which will ensure that any state updates gets - // immediately reconciled instead of waiting for the next batch. - - if (inst.componentWillReceiveProps) { - inst.componentWillReceiveProps(nextProps, nextContext); - } - } - - var nextState = this._processPendingState(nextProps, nextContext); - - var shouldUpdate = - this._pendingForceUpdate || - !inst.shouldComponentUpdate || - inst.shouldComponentUpdate(nextProps, nextState, nextContext); - - if ("production" !== "development") { - ("production" !== "development" ? warning( - typeof shouldUpdate !== 'undefined', - '%s.shouldComponentUpdate(): Returned undefined instead of a ' + - 'boolean value. Make sure to return true or false.', - this.getName() || 'ReactCompositeComponent' - ) : null); - } - - if (shouldUpdate) { - this._pendingForceUpdate = false; - // Will set `this.props`, `this.state` and `this.context`. - this._performComponentUpdate( - nextParentElement, - nextProps, - nextState, - nextContext, - transaction, - nextUnmaskedContext - ); - } else { - // If it's determined that a component should not update, we still want - // to set props and state but we shortcut the rest of the update. - this._currentElement = nextParentElement; - this._context = nextUnmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - } - }, - - _processPendingState: function(props, context) { - var inst = this._instance; - var queue = this._pendingStateQueue; - var replace = this._pendingReplaceState; - this._pendingReplaceState = false; - this._pendingStateQueue = null; - - if (!queue) { - return inst.state; - } - - if (replace && queue.length === 1) { - return queue[0]; - } - - var nextState = assign({}, replace ? queue[0] : inst.state); - for (var i = replace ? 1 : 0; i < queue.length; i++) { - var partial = queue[i]; - assign( - nextState, - typeof partial === 'function' ? - partial.call(inst, nextState, props, context) : - partial - ); - } - - return nextState; - }, - - /** - * Merges new props and state, notifies delegate methods of update and - * performs update. - * - * @param {ReactElement} nextElement Next element - * @param {object} nextProps Next public object to set as properties. - * @param {?object} nextState Next object to set as state. - * @param {?object} nextContext Next public object to set as context. - * @param {ReactReconcileTransaction} transaction - * @param {?object} unmaskedContext - * @private - */ - _performComponentUpdate: function( - nextElement, - nextProps, - nextState, - nextContext, - transaction, - unmaskedContext - ) { - var inst = this._instance; - - var prevProps = inst.props; - var prevState = inst.state; - var prevContext = inst.context; - - if (inst.componentWillUpdate) { - inst.componentWillUpdate(nextProps, nextState, nextContext); - } - - this._currentElement = nextElement; - this._context = unmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - - this._updateRenderedComponent(transaction, unmaskedContext); - - if (inst.componentDidUpdate) { - transaction.getReactMountReady().enqueue( - inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), - inst - ); - } - }, - - /** - * Call the component's `render` method and update the DOM accordingly. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - _updateRenderedComponent: function(transaction, context) { - var prevComponentInstance = this._renderedComponent; - var prevRenderedElement = prevComponentInstance._currentElement; - var childContext = this._getValidatedChildContext(); - var nextRenderedElement = this._renderValidatedComponent(childContext); - if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { - ReactReconciler.receiveComponent( - prevComponentInstance, - nextRenderedElement, - transaction, - this._mergeChildContext(context, childContext) - ); - } else { - // These two IDs are actually the same! But nothing should rely on that. - var thisID = this._rootNodeID; - var prevComponentID = prevComponentInstance._rootNodeID; - ReactReconciler.unmountComponent(prevComponentInstance); - - this._renderedComponent = this._instantiateReactComponent( - nextRenderedElement, - this._currentElement.type - ); - var nextMarkup = ReactReconciler.mountComponent( - this._renderedComponent, - thisID, - transaction, - this._mergeChildContext(context, childContext) - ); - this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup); - } - }, - - /** - * @protected - */ - _replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) { - ReactComponentEnvironment.replaceNodeWithMarkupByID( - prevComponentID, - nextMarkup - ); - }, - - /** - * @protected - */ - _renderValidatedComponentWithoutOwnerOrContext: function() { - var inst = this._instance; - var renderedComponent = inst.render(); - if ("production" !== "development") { - // We allow auto-mocks to proceed as if they're returning null. - if (typeof renderedComponent === 'undefined' && - inst.render._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - renderedComponent = null; - } - } - - return renderedComponent; - }, - - /** - * @private - */ - _renderValidatedComponent: function(childContext) { - var renderedComponent; - var previousContext = ReactContext.current; - ReactContext.current = this._mergeChildContext( - this._currentElement._context, - childContext - ); - ReactCurrentOwner.current = this; - try { - renderedComponent = - this._renderValidatedComponentWithoutOwnerOrContext(); - } finally { - ReactContext.current = previousContext; - ReactCurrentOwner.current = null; - } - ("production" !== "development" ? invariant( - // TODO: An `isValidNode` function would probably be more appropriate - renderedComponent === null || renderedComponent === false || - ReactElement.isValidElement(renderedComponent), - '%s.render(): A valid ReactComponent must be returned. You may have ' + - 'returned undefined, an array or some other invalid object.', - this.getName() || 'ReactCompositeComponent' - ) : invariant(// TODO: An `isValidNode` function would probably be more appropriate - renderedComponent === null || renderedComponent === false || - ReactElement.isValidElement(renderedComponent))); - return renderedComponent; - }, - - /** - * Lazily allocates the refs object and stores `component` as `ref`. - * - * @param {string} ref Reference name. - * @param {component} component Component to store as `ref`. - * @final - * @private - */ - attachRef: function(ref, component) { - var inst = this.getPublicInstance(); - var refs = inst.refs === emptyObject ? (inst.refs = {}) : inst.refs; - refs[ref] = component.getPublicInstance(); - }, - - /** - * Detaches a reference name. - * - * @param {string} ref Name to dereference. - * @final - * @private - */ - detachRef: function(ref) { - var refs = this.getPublicInstance().refs; - delete refs[ref]; - }, - - /** - * Get a text description of the component that can be used to identify it - * in error messages. - * @return {string} The name or null. - * @internal - */ - getName: function() { - var type = this._currentElement.type; - var constructor = this._instance && this._instance.constructor; - return ( - type.displayName || (constructor && constructor.displayName) || - type.name || (constructor && constructor.name) || - null - ); - }, - - /** - * Get the publicly accessible representation of this component - i.e. what - * is exposed by refs and returned by React.render. Can be null for stateless - * components. - * - * @return {ReactComponent} the public component instance. - * @internal - */ - getPublicInstance: function() { - return this._instance; - }, - - // Stub - _instantiateReactComponent: null - -}; - -ReactPerf.measureMethods( - ReactCompositeComponentMixin, - 'ReactCompositeComponent', - { - mountComponent: 'mountComponent', - updateComponent: 'updateComponent', - _renderValidatedComponent: '_renderValidatedComponent' - } -); - -var ReactCompositeComponent = { - - Mixin: ReactCompositeComponentMixin - -}; - -module.exports = ReactCompositeComponent; - -},{"115":115,"135":135,"151":151,"154":154,"27":27,"36":36,"38":38,"39":39,"57":57,"58":58,"67":67,"68":68,"73":73,"75":75,"76":76,"77":77,"81":81,"87":87}],38:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactContext - */ - -'use strict'; - -var assign = _dereq_(27); -var emptyObject = _dereq_(115); -var warning = _dereq_(154); - -var didWarn = false; - -/** - * Keeps track of the current context. - * - * The context is automatically passed down the component ownership hierarchy - * and is accessible via `this.context` on ReactCompositeComponents. - */ -var ReactContext = { - - /** - * @internal - * @type {object} - */ - current: emptyObject, - - /** - * Temporarily extends the current context while executing scopedCallback. - * - * A typical use case might look like - * - * render: function() { - * var children = ReactContext.withContext({foo: 'foo'}, () => ( - * - * )); - * return <div>{children}</div>; - * } - * - * @param {object} newContext New context to merge into the existing context - * @param {function} scopedCallback Callback to run with the new context - * @return {ReactComponent|array<ReactComponent>} - */ - withContext: function(newContext, scopedCallback) { - if ("production" !== "development") { - ("production" !== "development" ? warning( - didWarn, - 'withContext is deprecated and will be removed in a future version. ' + - 'Use a wrapper component with getChildContext instead.' - ) : null); - - didWarn = true; - } - - var result; - var previousContext = ReactContext.current; - ReactContext.current = assign({}, previousContext, newContext); - try { - result = scopedCallback(); - } finally { - ReactContext.current = previousContext; - } - return result; - } - -}; - -module.exports = ReactContext; - -},{"115":115,"154":154,"27":27}],39:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactCurrentOwner - */ - -'use strict'; - -/** - * Keeps track of the current owner. - * - * The current owner is the component who should own any components that are - * currently being constructed. - * - * The depth indicate how many composite components are above this render level. - */ -var ReactCurrentOwner = { - - /** - * @internal - * @type {ReactComponent} - */ - current: null - -}; - -module.exports = ReactCurrentOwner; - -},{}],40:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOM - * @typechecks static-only - */ - -'use strict'; - -var ReactElement = _dereq_(57); -var ReactElementValidator = _dereq_(58); - -var mapObject = _dereq_(142); - -/** - * Create a factory that creates HTML tag elements. - * - * @param {string} tag Tag name (e.g. `div`). - * @private - */ -function createDOMFactory(tag) { - if ("production" !== "development") { - return ReactElementValidator.createFactory(tag); - } - return ReactElement.createFactory(tag); -} - -/** - * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. - * This is also accessible via `React.DOM`. - * - * @public - */ -var ReactDOM = mapObject({ - a: 'a', - abbr: 'abbr', - address: 'address', - area: 'area', - article: 'article', - aside: 'aside', - audio: 'audio', - b: 'b', - base: 'base', - bdi: 'bdi', - bdo: 'bdo', - big: 'big', - blockquote: 'blockquote', - body: 'body', - br: 'br', - button: 'button', - canvas: 'canvas', - caption: 'caption', - cite: 'cite', - code: 'code', - col: 'col', - colgroup: 'colgroup', - data: 'data', - datalist: 'datalist', - dd: 'dd', - del: 'del', - details: 'details', - dfn: 'dfn', - dialog: 'dialog', - div: 'div', - dl: 'dl', - dt: 'dt', - em: 'em', - embed: 'embed', - fieldset: 'fieldset', - figcaption: 'figcaption', - figure: 'figure', - footer: 'footer', - form: 'form', - h1: 'h1', - h2: 'h2', - h3: 'h3', - h4: 'h4', - h5: 'h5', - h6: 'h6', - head: 'head', - header: 'header', - hr: 'hr', - html: 'html', - i: 'i', - iframe: 'iframe', - img: 'img', - input: 'input', - ins: 'ins', - kbd: 'kbd', - keygen: 'keygen', - label: 'label', - legend: 'legend', - li: 'li', - link: 'link', - main: 'main', - map: 'map', - mark: 'mark', - menu: 'menu', - menuitem: 'menuitem', - meta: 'meta', - meter: 'meter', - nav: 'nav', - noscript: 'noscript', - object: 'object', - ol: 'ol', - optgroup: 'optgroup', - option: 'option', - output: 'output', - p: 'p', - param: 'param', - picture: 'picture', - pre: 'pre', - progress: 'progress', - q: 'q', - rp: 'rp', - rt: 'rt', - ruby: 'ruby', - s: 's', - samp: 'samp', - script: 'script', - section: 'section', - select: 'select', - small: 'small', - source: 'source', - span: 'span', - strong: 'strong', - style: 'style', - sub: 'sub', - summary: 'summary', - sup: 'sup', - table: 'table', - tbody: 'tbody', - td: 'td', - textarea: 'textarea', - tfoot: 'tfoot', - th: 'th', - thead: 'thead', - time: 'time', - title: 'title', - tr: 'tr', - track: 'track', - u: 'u', - ul: 'ul', - 'var': 'var', - video: 'video', - wbr: 'wbr', - - // SVG - circle: 'circle', - clipPath: 'clipPath', - defs: 'defs', - ellipse: 'ellipse', - g: 'g', - line: 'line', - linearGradient: 'linearGradient', - mask: 'mask', - path: 'path', - pattern: 'pattern', - polygon: 'polygon', - polyline: 'polyline', - radialGradient: 'radialGradient', - rect: 'rect', - stop: 'stop', - svg: 'svg', - text: 'text', - tspan: 'tspan' - -}, createDOMFactory); - -module.exports = ReactDOM; - -},{"142":142,"57":57,"58":58}],41:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMButton - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); - -var keyMirror = _dereq_(140); - -var button = ReactElement.createFactory('button'); - -var mouseListenerNames = keyMirror({ - onClick: true, - onDoubleClick: true, - onMouseDown: true, - onMouseMove: true, - onMouseUp: true, - onClickCapture: true, - onDoubleClickCapture: true, - onMouseDownCapture: true, - onMouseMoveCapture: true, - onMouseUpCapture: true -}); - -/** - * Implements a <button> native component that does not receive mouse events - * when `disabled` is set. - */ -var ReactDOMButton = ReactClass.createClass({ - displayName: 'ReactDOMButton', - tagName: 'BUTTON', - - mixins: [AutoFocusMixin, ReactBrowserComponentMixin], - - render: function() { - var props = {}; - - // Copy the props; except the mouse listeners if we're disabled - for (var key in this.props) { - if (this.props.hasOwnProperty(key) && - (!this.props.disabled || !mouseListenerNames[key])) { - props[key] = this.props[key]; - } - } - - return button(props, this.props.children); - } - -}); - -module.exports = ReactDOMButton; - -},{"140":140,"2":2,"29":29,"33":33,"57":57}],42:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMComponent - * @typechecks static-only - */ - -/* global hasOwnProperty:true */ - -'use strict'; - -var CSSPropertyOperations = _dereq_(5); -var DOMProperty = _dereq_(10); -var DOMPropertyOperations = _dereq_(11); -var ReactBrowserEventEmitter = _dereq_(30); -var ReactComponentBrowserEnvironment = - _dereq_(35); -var ReactMount = _dereq_(70); -var ReactMultiChild = _dereq_(71); -var ReactPerf = _dereq_(75); - -var assign = _dereq_(27); -var escapeTextContentForBrowser = _dereq_(116); -var invariant = _dereq_(135); -var isEventSupported = _dereq_(136); -var keyOf = _dereq_(141); -var warning = _dereq_(154); - -var deleteListener = ReactBrowserEventEmitter.deleteListener; -var listenTo = ReactBrowserEventEmitter.listenTo; -var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules; - -// For quickly matching children type, to test if can be treated as content. -var CONTENT_TYPES = {'string': true, 'number': true}; - -var STYLE = keyOf({style: null}); - -var ELEMENT_NODE_TYPE = 1; - -/** - * Optionally injectable operations for mutating the DOM - */ -var BackendIDOperations = null; - -/** - * @param {?object} props - */ -function assertValidProps(props) { - if (!props) { - return; - } - // Note the use of `==` which checks for null or undefined. - if (props.dangerouslySetInnerHTML != null) { - ("production" !== "development" ? invariant( - props.children == null, - 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' - ) : invariant(props.children == null)); - ("production" !== "development" ? invariant( - typeof props.dangerouslySetInnerHTML === 'object' && - '__html' in props.dangerouslySetInnerHTML, - '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + - 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + - 'for more information.' - ) : invariant(typeof props.dangerouslySetInnerHTML === 'object' && - '__html' in props.dangerouslySetInnerHTML)); - } - if ("production" !== "development") { - ("production" !== "development" ? warning( - props.innerHTML == null, - 'Directly setting property `innerHTML` is not permitted. ' + - 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' - ) : null); - ("production" !== "development" ? warning( - !props.contentEditable || props.children == null, - 'A component is `contentEditable` and contains `children` managed by ' + - 'React. It is now your responsibility to guarantee that none of ' + - 'those nodes are unexpectedly modified or duplicated. This is ' + - 'probably not intentional.' - ) : null); - } - ("production" !== "development" ? invariant( - props.style == null || typeof props.style === 'object', - 'The `style` prop expects a mapping from style properties to values, ' + - 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + - 'using JSX.' - ) : invariant(props.style == null || typeof props.style === 'object')); -} - -function putListener(id, registrationName, listener, transaction) { - if ("production" !== "development") { - // IE8 has no API for event capturing and the `onScroll` event doesn't - // bubble. - ("production" !== "development" ? warning( - registrationName !== 'onScroll' || isEventSupported('scroll', true), - 'This browser doesn\'t support the `onScroll` event' - ) : null); - } - var container = ReactMount.findReactContainerForID(id); - if (container) { - var doc = container.nodeType === ELEMENT_NODE_TYPE ? - container.ownerDocument : - container; - listenTo(registrationName, doc); - } - transaction.getPutListenerQueue().enqueuePutListener( - id, - registrationName, - listener - ); -} - -// For HTML, certain tags should omit their close tag. We keep a whitelist for -// those special cased tags. - -var omittedCloseTags = { - 'area': true, - 'base': true, - 'br': true, - 'col': true, - 'embed': true, - 'hr': true, - 'img': true, - 'input': true, - 'keygen': true, - 'link': true, - 'meta': true, - 'param': true, - 'source': true, - 'track': true, - 'wbr': true - // NOTE: menuitem's close tag should be omitted, but that causes problems. -}; - -// We accept any tag to be rendered but since this gets injected into abitrary -// HTML, we want to make sure that it's a safe tag. -// http://www.w3.org/TR/REC-xml/#NT-Name - -var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset -var validatedTagCache = {}; -var hasOwnProperty = {}.hasOwnProperty; - -function validateDangerousTag(tag) { - if (!hasOwnProperty.call(validatedTagCache, tag)) { - ("production" !== "development" ? invariant(VALID_TAG_REGEX.test(tag), 'Invalid tag: %s', tag) : invariant(VALID_TAG_REGEX.test(tag))); - validatedTagCache[tag] = true; - } -} - -/** - * Creates a new React class that is idempotent and capable of containing other - * React components. It accepts event listeners and DOM properties that are - * valid according to `DOMProperty`. - * - * - Event listeners: `onClick`, `onMouseDown`, etc. - * - DOM properties: `className`, `name`, `title`, etc. - * - * The `style` property functions differently from the DOM API. It accepts an - * object mapping of style properties to values. - * - * @constructor ReactDOMComponent - * @extends ReactMultiChild - */ -function ReactDOMComponent(tag) { - validateDangerousTag(tag); - this._tag = tag; - this._renderedChildren = null; - this._previousStyleCopy = null; - this._rootNodeID = null; -} - -ReactDOMComponent.displayName = 'ReactDOMComponent'; - -ReactDOMComponent.Mixin = { - - construct: function(element) { - this._currentElement = element; - }, - - /** - * Generates root tag markup then recurses. This method has side effects and - * is not idempotent. - * - * @internal - * @param {string} rootID The root DOM ID for this node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} The computed markup. - */ - mountComponent: function(rootID, transaction, context) { - this._rootNodeID = rootID; - assertValidProps(this._currentElement.props); - var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>'; - return ( - this._createOpenTagMarkupAndPutListeners(transaction) + - this._createContentMarkup(transaction, context) + - closeTag - ); - }, - - /** - * Creates markup for the open tag and all attributes. - * - * This method has side effects because events get registered. - * - * Iterating over object properties is faster than iterating over arrays. - * @see http://jsperf.com/obj-vs-arr-iteration - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} Markup of opening tag. - */ - _createOpenTagMarkupAndPutListeners: function(transaction) { - var props = this._currentElement.props; - var ret = '<' + this._tag; - - for (var propKey in props) { - if (!props.hasOwnProperty(propKey)) { - continue; - } - var propValue = props[propKey]; - if (propValue == null) { - continue; - } - if (registrationNameModules.hasOwnProperty(propKey)) { - putListener(this._rootNodeID, propKey, propValue, transaction); - } else { - if (propKey === STYLE) { - if (propValue) { - propValue = this._previousStyleCopy = assign({}, props.style); - } - propValue = CSSPropertyOperations.createMarkupForStyles(propValue); - } - var markup = - DOMPropertyOperations.createMarkupForProperty(propKey, propValue); - if (markup) { - ret += ' ' + markup; - } - } - } - - // For static pages, no need to put React ID and checksum. Saves lots of - // bytes. - if (transaction.renderToStaticMarkup) { - return ret + '>'; - } - - var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); - return ret + ' ' + markupForID + '>'; - }, - - /** - * Creates markup for the content between the tags. - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} context - * @return {string} Content markup. - */ - _createContentMarkup: function(transaction, context) { - var prefix = ''; - if (this._tag === 'listing' || - this._tag === 'pre' || - this._tag === 'textarea') { - // Add an initial newline because browsers ignore the first newline in - // a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody. - prefix = '\n'; - } - - var props = this._currentElement.props; - - // Intentional use of != to avoid catching zero/false. - var innerHTML = props.dangerouslySetInnerHTML; - if (innerHTML != null) { - if (innerHTML.__html != null) { - return prefix + innerHTML.__html; - } - } else { - var contentToUse = - CONTENT_TYPES[typeof props.children] ? props.children : null; - var childrenToUse = contentToUse != null ? null : props.children; - if (contentToUse != null) { - return prefix + escapeTextContentForBrowser(contentToUse); - } else if (childrenToUse != null) { - var mountImages = this.mountChildren( - childrenToUse, - transaction, - context - ); - return prefix + mountImages.join(''); - } - } - return prefix; - }, - - receiveComponent: function(nextElement, transaction, context) { - var prevElement = this._currentElement; - this._currentElement = nextElement; - this.updateComponent(transaction, prevElement, nextElement, context); - }, - - /** - * Updates a native DOM component after it has already been allocated and - * attached to the DOM. Reconciles the root DOM node, then recurses. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevElement - * @param {ReactElement} nextElement - * @internal - * @overridable - */ - updateComponent: function(transaction, prevElement, nextElement, context) { - assertValidProps(this._currentElement.props); - this._updateDOMProperties(prevElement.props, transaction); - this._updateDOMChildren(prevElement.props, transaction, context); - }, - - /** - * Reconciles the properties by detecting differences in property values and - * updating the DOM as necessary. This function is probably the single most - * critical path for performance optimization. - * - * TODO: Benchmark whether checking for changed values in memory actually - * improves performance (especially statically positioned elements). - * TODO: Benchmark the effects of putting this at the top since 99% of props - * do not change for a given reconciliation. - * TODO: Benchmark areas that can be improved with caching. - * - * @private - * @param {object} lastProps - * @param {ReactReconcileTransaction} transaction - */ - _updateDOMProperties: function(lastProps, transaction) { - var nextProps = this._currentElement.props; - var propKey; - var styleName; - var styleUpdates; - for (propKey in lastProps) { - if (nextProps.hasOwnProperty(propKey) || - !lastProps.hasOwnProperty(propKey)) { - continue; - } - if (propKey === STYLE) { - var lastStyle = this._previousStyleCopy; - for (styleName in lastStyle) { - if (lastStyle.hasOwnProperty(styleName)) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - this._previousStyleCopy = null; - } else if (registrationNameModules.hasOwnProperty(propKey)) { - deleteListener(this._rootNodeID, propKey); - } else if ( - DOMProperty.isStandardName[propKey] || - DOMProperty.isCustomAttribute(propKey)) { - BackendIDOperations.deletePropertyByID( - this._rootNodeID, - propKey - ); - } - } - for (propKey in nextProps) { - var nextProp = nextProps[propKey]; - var lastProp = propKey === STYLE ? - this._previousStyleCopy : - lastProps[propKey]; - if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) { - continue; - } - if (propKey === STYLE) { - if (nextProp) { - nextProp = this._previousStyleCopy = assign({}, nextProp); - } else { - this._previousStyleCopy = null; - } - if (lastProp) { - // Unset styles on `lastProp` but not on `nextProp`. - for (styleName in lastProp) { - if (lastProp.hasOwnProperty(styleName) && - (!nextProp || !nextProp.hasOwnProperty(styleName))) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - // Update styles that changed since `lastProp`. - for (styleName in nextProp) { - if (nextProp.hasOwnProperty(styleName) && - lastProp[styleName] !== nextProp[styleName]) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = nextProp[styleName]; - } - } - } else { - // Relies on `updateStylesByID` not mutating `styleUpdates`. - styleUpdates = nextProp; - } - } else if (registrationNameModules.hasOwnProperty(propKey)) { - putListener(this._rootNodeID, propKey, nextProp, transaction); - } else if ( - DOMProperty.isStandardName[propKey] || - DOMProperty.isCustomAttribute(propKey)) { - BackendIDOperations.updatePropertyByID( - this._rootNodeID, - propKey, - nextProp - ); - } - } - if (styleUpdates) { - BackendIDOperations.updateStylesByID( - this._rootNodeID, - styleUpdates - ); - } - }, - - /** - * Reconciles the children with the various properties that affect the - * children content. - * - * @param {object} lastProps - * @param {ReactReconcileTransaction} transaction - */ - _updateDOMChildren: function(lastProps, transaction, context) { - var nextProps = this._currentElement.props; - - var lastContent = - CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; - var nextContent = - CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; - - var lastHtml = - lastProps.dangerouslySetInnerHTML && - lastProps.dangerouslySetInnerHTML.__html; - var nextHtml = - nextProps.dangerouslySetInnerHTML && - nextProps.dangerouslySetInnerHTML.__html; - - // Note the use of `!=` which checks for null or undefined. - var lastChildren = lastContent != null ? null : lastProps.children; - var nextChildren = nextContent != null ? null : nextProps.children; - - // If we're switching from children to content/html or vice versa, remove - // the old content - var lastHasContentOrHtml = lastContent != null || lastHtml != null; - var nextHasContentOrHtml = nextContent != null || nextHtml != null; - if (lastChildren != null && nextChildren == null) { - this.updateChildren(null, transaction, context); - } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { - this.updateTextContent(''); - } - - if (nextContent != null) { - if (lastContent !== nextContent) { - this.updateTextContent('' + nextContent); - } - } else if (nextHtml != null) { - if (lastHtml !== nextHtml) { - BackendIDOperations.updateInnerHTMLByID( - this._rootNodeID, - nextHtml - ); - } - } else if (nextChildren != null) { - this.updateChildren(nextChildren, transaction, context); - } - }, - - /** - * Destroys all event registrations for this instance. Does not remove from - * the DOM. That must be done by the parent. - * - * @internal - */ - unmountComponent: function() { - this.unmountChildren(); - ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID); - ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); - this._rootNodeID = null; - } - -}; - -ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', { - mountComponent: 'mountComponent', - updateComponent: 'updateComponent' -}); - -assign( - ReactDOMComponent.prototype, - ReactDOMComponent.Mixin, - ReactMultiChild.Mixin -); - -ReactDOMComponent.injection = { - injectIDOperations: function(IDOperations) { - ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations; - } -}; - -module.exports = ReactDOMComponent; - -},{"10":10,"11":11,"116":116,"135":135,"136":136,"141":141,"154":154,"27":27,"30":30,"35":35,"5":5,"70":70,"71":71,"75":75}],43:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMForm - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var LocalEventTrapMixin = _dereq_(25); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); - -var form = ReactElement.createFactory('form'); - -/** - * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need - * to capture it on the <form> element itself. There are lots of hacks we could - * do to accomplish this, but the most reliable is to make <form> a - * composite component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMForm = ReactClass.createClass({ - displayName: 'ReactDOMForm', - tagName: 'FORM', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - // TODO: Instead of using `ReactDOM` directly, we should use JSX. However, - // `jshint` fails to parse JSX so in order for linting to work in the open - // source repo, we need to just use `ReactDOM.form`. - return form(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset'); - this.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit'); - } -}); - -module.exports = ReactDOMForm; - -},{"15":15,"25":25,"29":29,"33":33,"57":57}],44:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMIDOperations - * @typechecks static-only - */ - -/*jslint evil: true */ - -'use strict'; - -var CSSPropertyOperations = _dereq_(5); -var DOMChildrenOperations = _dereq_(9); -var DOMPropertyOperations = _dereq_(11); -var ReactMount = _dereq_(70); -var ReactPerf = _dereq_(75); - -var invariant = _dereq_(135); -var setInnerHTML = _dereq_(148); - -/** - * Errors for properties that should not be updated with `updatePropertyById()`. - * - * @type {object} - * @private - */ -var INVALID_PROPERTY_ERRORS = { - dangerouslySetInnerHTML: - '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', - style: '`style` must be set using `updateStylesByID()`.' -}; - -/** - * Operations used to process updates to DOM nodes. This is made injectable via - * `ReactDOMComponent.BackendIDOperations`. - */ -var ReactDOMIDOperations = { - - /** - * Updates a DOM node with new property values. This should only be used to - * update DOM properties in `DOMProperty`. - * - * @param {string} id ID of the node to update. - * @param {string} name A valid property name, see `DOMProperty`. - * @param {*} value New value of the property. - * @internal - */ - updatePropertyByID: function(id, name, value) { - var node = ReactMount.getNode(id); - ("production" !== "development" ? invariant( - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), - 'updatePropertyByID(...): %s', - INVALID_PROPERTY_ERRORS[name] - ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); - - // If we're updating to null or undefined, we should remove the property - // from the DOM node instead of inadvertantly setting to a string. This - // brings us in line with the same behavior we have on initial render. - if (value != null) { - DOMPropertyOperations.setValueForProperty(node, name, value); - } else { - DOMPropertyOperations.deleteValueForProperty(node, name); - } - }, - - /** - * Updates a DOM node to remove a property. This should only be used to remove - * DOM properties in `DOMProperty`. - * - * @param {string} id ID of the node to update. - * @param {string} name A property name to remove, see `DOMProperty`. - * @internal - */ - deletePropertyByID: function(id, name, value) { - var node = ReactMount.getNode(id); - ("production" !== "development" ? invariant( - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), - 'updatePropertyByID(...): %s', - INVALID_PROPERTY_ERRORS[name] - ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); - DOMPropertyOperations.deleteValueForProperty(node, name, value); - }, - - /** - * Updates a DOM node with new style values. If a value is specified as '', - * the corresponding style property will be unset. - * - * @param {string} id ID of the node to update. - * @param {object} styles Mapping from styles to values. - * @internal - */ - updateStylesByID: function(id, styles) { - var node = ReactMount.getNode(id); - CSSPropertyOperations.setValueForStyles(node, styles); - }, - - /** - * Updates a DOM node's innerHTML. - * - * @param {string} id ID of the node to update. - * @param {string} html An HTML string. - * @internal - */ - updateInnerHTMLByID: function(id, html) { - var node = ReactMount.getNode(id); - setInnerHTML(node, html); - }, - - /** - * Updates a DOM node's text content set by `props.content`. - * - * @param {string} id ID of the node to update. - * @param {string} content Text content. - * @internal - */ - updateTextContentByID: function(id, content) { - var node = ReactMount.getNode(id); - DOMChildrenOperations.updateTextContent(node, content); - }, - - /** - * Replaces a DOM node that exists in the document with markup. - * - * @param {string} id ID of child to be replaced. - * @param {string} markup Dangerous markup to inject in place of child. - * @internal - * @see {Danger.dangerouslyReplaceNodeWithMarkup} - */ - dangerouslyReplaceNodeWithMarkupByID: function(id, markup) { - var node = ReactMount.getNode(id); - DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); - }, - - /** - * Updates a component's children by processing a series of updates. - * - * @param {array<object>} updates List of update configurations. - * @param {array<string>} markup List of markup strings. - * @internal - */ - dangerouslyProcessChildrenUpdates: function(updates, markup) { - for (var i = 0; i < updates.length; i++) { - updates[i].parentNode = ReactMount.getNode(updates[i].parentID); - } - DOMChildrenOperations.processUpdates(updates, markup); - } -}; - -ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', { - updatePropertyByID: 'updatePropertyByID', - deletePropertyByID: 'deletePropertyByID', - updateStylesByID: 'updateStylesByID', - updateInnerHTMLByID: 'updateInnerHTMLByID', - updateTextContentByID: 'updateTextContentByID', - dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID', - dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates' -}); - -module.exports = ReactDOMIDOperations; - -},{"11":11,"135":135,"148":148,"5":5,"70":70,"75":75,"9":9}],45:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMIframe - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var LocalEventTrapMixin = _dereq_(25); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); - -var iframe = ReactElement.createFactory('iframe'); - -/** - * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to - * capture it on the <iframe> element itself. There are lots of hacks we could - * do to accomplish this, but the most reliable is to make <iframe> a composite - * component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMIframe = ReactClass.createClass({ - displayName: 'ReactDOMIframe', - tagName: 'IFRAME', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - return iframe(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load'); - } -}); - -module.exports = ReactDOMIframe; - -},{"15":15,"25":25,"29":29,"33":33,"57":57}],46:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMImg - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var LocalEventTrapMixin = _dereq_(25); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); - -var img = ReactElement.createFactory('img'); - -/** - * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to - * capture it on the <img> element itself. There are lots of hacks we could do - * to accomplish this, but the most reliable is to make <img> a composite - * component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMImg = ReactClass.createClass({ - displayName: 'ReactDOMImg', - tagName: 'IMG', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - return img(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load'); - this.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error'); - } -}); - -module.exports = ReactDOMImg; - -},{"15":15,"25":25,"29":29,"33":33,"57":57}],47:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMInput - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var DOMPropertyOperations = _dereq_(11); -var LinkedValueUtils = _dereq_(24); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); -var ReactMount = _dereq_(70); -var ReactUpdates = _dereq_(87); - -var assign = _dereq_(27); -var invariant = _dereq_(135); - -var input = ReactElement.createFactory('input'); - -var instancesByReactID = {}; - -function forceUpdateIfMounted() { - /*jshint validthis:true */ - if (this.isMounted()) { - this.forceUpdate(); - } -} - -/** - * Implements an <input> native component that allows setting these optional - * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. - * - * If `checked` or `value` are not supplied (or null/undefined), user actions - * that affect the checked state or value will trigger updates to the element. - * - * If they are supplied (and not null/undefined), the rendered element will not - * trigger updates to the element. Instead, the props must change in order for - * the rendered element to be updated. - * - * The rendered element will be initialized as unchecked (or `defaultChecked`) - * with an empty value (or `defaultValue`). - * - * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html - */ -var ReactDOMInput = ReactClass.createClass({ - displayName: 'ReactDOMInput', - tagName: 'INPUT', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], - - getInitialState: function() { - var defaultValue = this.props.defaultValue; - return { - initialChecked: this.props.defaultChecked || false, - initialValue: defaultValue != null ? defaultValue : null - }; - }, - - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - props.defaultChecked = null; - props.defaultValue = null; - - var value = LinkedValueUtils.getValue(this); - props.value = value != null ? value : this.state.initialValue; - - var checked = LinkedValueUtils.getChecked(this); - props.checked = checked != null ? checked : this.state.initialChecked; - - props.onChange = this._handleChange; - - return input(props, this.props.children); - }, - - componentDidMount: function() { - var id = ReactMount.getID(this.getDOMNode()); - instancesByReactID[id] = this; - }, - - componentWillUnmount: function() { - var rootNode = this.getDOMNode(); - var id = ReactMount.getID(rootNode); - delete instancesByReactID[id]; - }, - - componentDidUpdate: function(prevProps, prevState, prevContext) { - var rootNode = this.getDOMNode(); - if (this.props.checked != null) { - DOMPropertyOperations.setValueForProperty( - rootNode, - 'checked', - this.props.checked || false - ); - } - - var value = LinkedValueUtils.getValue(this); - if (value != null) { - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - // Here we use asap to wait until all updates have propagated, which - // is important when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - ReactUpdates.asap(forceUpdateIfMounted, this); - - var name = this.props.name; - if (this.props.type === 'radio' && name != null) { - var rootNode = this.getDOMNode(); - var queryRoot = rootNode; - - while (queryRoot.parentNode) { - queryRoot = queryRoot.parentNode; - } - - // If `rootNode.form` was non-null, then we could try `form.elements`, - // but that sometimes behaves strangely in IE8. We could also try using - // `form.getElementsByName`, but that will only return direct children - // and won't include inputs that use the HTML5 `form=` attribute. Since - // the input might not even be in a form, let's just use the global - // `querySelectorAll` to ensure we don't miss anything. - var group = queryRoot.querySelectorAll( - 'input[name=' + JSON.stringify('' + name) + '][type="radio"]'); - - for (var i = 0, groupLen = group.length; i < groupLen; i++) { - var otherNode = group[i]; - if (otherNode === rootNode || - otherNode.form !== rootNode.form) { - continue; - } - var otherID = ReactMount.getID(otherNode); - ("production" !== "development" ? invariant( - otherID, - 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + - 'same `name` is not supported.' - ) : invariant(otherID)); - var otherInstance = instancesByReactID[otherID]; - ("production" !== "development" ? invariant( - otherInstance, - 'ReactDOMInput: Unknown radio button ID %s.', - otherID - ) : invariant(otherInstance)); - // If this is a controlled radio button group, forcing the input that - // was previously checked to update will cause it to be come re-checked - // as appropriate. - ReactUpdates.asap(forceUpdateIfMounted, otherInstance); - } - } - - return returnValue; - } - -}); - -module.exports = ReactDOMInput; - -},{"11":11,"135":135,"2":2,"24":24,"27":27,"29":29,"33":33,"57":57,"70":70,"87":87}],48:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMOption - */ - -'use strict'; - -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); - -var warning = _dereq_(154); - -var option = ReactElement.createFactory('option'); - -/** - * Implements an <option> native component that warns when `selected` is set. - */ -var ReactDOMOption = ReactClass.createClass({ - displayName: 'ReactDOMOption', - tagName: 'OPTION', - - mixins: [ReactBrowserComponentMixin], - - componentWillMount: function() { - // TODO (yungsters): Remove support for `selected` in <option>. - if ("production" !== "development") { - ("production" !== "development" ? warning( - this.props.selected == null, - 'Use the `defaultValue` or `value` props on <select> instead of ' + - 'setting `selected` on <option>.' - ) : null); - } - }, - - render: function() { - return option(this.props, this.props.children); - } - -}); - -module.exports = ReactDOMOption; - -},{"154":154,"29":29,"33":33,"57":57}],49:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMSelect - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var LinkedValueUtils = _dereq_(24); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); -var ReactUpdates = _dereq_(87); - -var assign = _dereq_(27); - -var select = ReactElement.createFactory('select'); - -function updateOptionsIfPendingUpdateAndMounted() { - /*jshint validthis:true */ - if (this._pendingUpdate) { - this._pendingUpdate = false; - var value = LinkedValueUtils.getValue(this); - if (value != null && this.isMounted()) { - updateOptions(this, value); - } - } -} - -/** - * Validation function for `value` and `defaultValue`. - * @private - */ -function selectValueType(props, propName, componentName) { - if (props[propName] == null) { - return null; - } - if (props.multiple) { - if (!Array.isArray(props[propName])) { - return new Error( - ("The `" + propName + "` prop supplied to <select> must be an array if ") + - ("`multiple` is true.") - ); - } - } else { - if (Array.isArray(props[propName])) { - return new Error( - ("The `" + propName + "` prop supplied to <select> must be a scalar ") + - ("value if `multiple` is false.") - ); - } - } -} - -/** - * @param {ReactComponent} component Instance of ReactDOMSelect - * @param {*} propValue A stringable (with `multiple`, a list of stringables). - * @private - */ -function updateOptions(component, propValue) { - var selectedValue, i, l; - var options = component.getDOMNode().options; - - if (component.props.multiple) { - selectedValue = {}; - for (i = 0, l = propValue.length; i < l; i++) { - selectedValue['' + propValue[i]] = true; - } - for (i = 0, l = options.length; i < l; i++) { - var selected = selectedValue.hasOwnProperty(options[i].value); - if (options[i].selected !== selected) { - options[i].selected = selected; - } - } - } else { - // Do not set `select.value` as exact behavior isn't consistent across all - // browsers for all cases. - selectedValue = '' + propValue; - for (i = 0, l = options.length; i < l; i++) { - if (options[i].value === selectedValue) { - options[i].selected = true; - return; - } - } - if (options.length) { - options[0].selected = true; - } - } -} - -/** - * Implements a <select> native component that allows optionally setting the - * props `value` and `defaultValue`. If `multiple` is false, the prop must be a - * stringable. If `multiple` is true, the prop must be an array of stringables. - * - * If `value` is not supplied (or null/undefined), user actions that change the - * selected option will trigger updates to the rendered options. - * - * If it is supplied (and not null/undefined), the rendered options will not - * update in response to user actions. Instead, the `value` prop must change in - * order for the rendered options to update. - * - * If `defaultValue` is provided, any options with the supplied values will be - * selected. - */ -var ReactDOMSelect = ReactClass.createClass({ - displayName: 'ReactDOMSelect', - tagName: 'SELECT', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], - - propTypes: { - defaultValue: selectValueType, - value: selectValueType - }, - - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - props.onChange = this._handleChange; - props.value = null; - - return select(props, this.props.children); - }, - - componentWillMount: function() { - this._pendingUpdate = false; - }, - - componentDidMount: function() { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - updateOptions(this, value); - } else if (this.props.defaultValue != null) { - updateOptions(this, this.props.defaultValue); - } - }, - - componentDidUpdate: function(prevProps) { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - this._pendingUpdate = false; - updateOptions(this, value); - } else if (!prevProps.multiple !== !this.props.multiple) { - // For simplicity, reapply `defaultValue` if `multiple` is toggled. - if (this.props.defaultValue != null) { - updateOptions(this, this.props.defaultValue); - } else { - // Revert the select back to its default unselected state. - updateOptions(this, this.props.multiple ? [] : ''); - } - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - - this._pendingUpdate = true; - ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); - return returnValue; - } - -}); - -module.exports = ReactDOMSelect; - -},{"2":2,"24":24,"27":27,"29":29,"33":33,"57":57,"87":87}],50:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMSelection - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(21); - -var getNodeForCharacterOffset = _dereq_(128); -var getTextContentAccessor = _dereq_(130); - -/** - * While `isCollapsed` is available on the Selection object and `collapsed` - * is available on the Range object, IE11 sometimes gets them wrong. - * If the anchor/focus nodes and offsets are the same, the range is collapsed. - */ -function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) { - return anchorNode === focusNode && anchorOffset === focusOffset; -} - -/** - * Get the appropriate anchor and focus node/offset pairs for IE. - * - * The catch here is that IE's selection API doesn't provide information - * about whether the selection is forward or backward, so we have to - * behave as though it's always forward. - * - * IE text differs from modern selection in that it behaves as though - * block elements end with a new line. This means character offsets will - * differ between the two APIs. - * - * @param {DOMElement} node - * @return {object} - */ -function getIEOffsets(node) { - var selection = document.selection; - var selectedRange = selection.createRange(); - var selectedLength = selectedRange.text.length; - - // Duplicate selection so we can move range without breaking user selection. - var fromStart = selectedRange.duplicate(); - fromStart.moveToElementText(node); - fromStart.setEndPoint('EndToStart', selectedRange); - - var startOffset = fromStart.text.length; - var endOffset = startOffset + selectedLength; - - return { - start: startOffset, - end: endOffset - }; -} - -/** - * @param {DOMElement} node - * @return {?object} - */ -function getModernOffsets(node) { - var selection = window.getSelection && window.getSelection(); - - if (!selection || selection.rangeCount === 0) { - return null; - } - - var anchorNode = selection.anchorNode; - var anchorOffset = selection.anchorOffset; - var focusNode = selection.focusNode; - var focusOffset = selection.focusOffset; - - var currentRange = selection.getRangeAt(0); - - // If the node and offset values are the same, the selection is collapsed. - // `Selection.isCollapsed` is available natively, but IE sometimes gets - // this value wrong. - var isSelectionCollapsed = isCollapsed( - selection.anchorNode, - selection.anchorOffset, - selection.focusNode, - selection.focusOffset - ); - - var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; - - var tempRange = currentRange.cloneRange(); - tempRange.selectNodeContents(node); - tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); - - var isTempRangeCollapsed = isCollapsed( - tempRange.startContainer, - tempRange.startOffset, - tempRange.endContainer, - tempRange.endOffset - ); - - var start = isTempRangeCollapsed ? 0 : tempRange.toString().length; - var end = start + rangeLength; - - // Detect whether the selection is backward. - var detectionRange = document.createRange(); - detectionRange.setStart(anchorNode, anchorOffset); - detectionRange.setEnd(focusNode, focusOffset); - var isBackward = detectionRange.collapsed; - - return { - start: isBackward ? end : start, - end: isBackward ? start : end - }; -} - -/** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setIEOffsets(node, offsets) { - var range = document.selection.createRange().duplicate(); - var start, end; - - if (typeof offsets.end === 'undefined') { - start = offsets.start; - end = start; - } else if (offsets.start > offsets.end) { - start = offsets.end; - end = offsets.start; - } else { - start = offsets.start; - end = offsets.end; - } - - range.moveToElementText(node); - range.moveStart('character', start); - range.setEndPoint('EndToStart', range); - range.moveEnd('character', end - start); - range.select(); -} - -/** - * In modern non-IE browsers, we can support both forward and backward - * selections. - * - * Note: IE10+ supports the Selection object, but it does not support - * the `extend` method, which means that even in modern IE, it's not possible - * to programatically create a backward selection. Thus, for all IE - * versions, we use the old IE API to create our selections. - * - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setModernOffsets(node, offsets) { - if (!window.getSelection) { - return; - } - - var selection = window.getSelection(); - var length = node[getTextContentAccessor()].length; - var start = Math.min(offsets.start, length); - var end = typeof offsets.end === 'undefined' ? - start : Math.min(offsets.end, length); - - // IE 11 uses modern selection, but doesn't support the extend method. - // Flip backward selections, so we can set with a single range. - if (!selection.extend && start > end) { - var temp = end; - end = start; - start = temp; - } - - var startMarker = getNodeForCharacterOffset(node, start); - var endMarker = getNodeForCharacterOffset(node, end); - - if (startMarker && endMarker) { - var range = document.createRange(); - range.setStart(startMarker.node, startMarker.offset); - selection.removeAllRanges(); - - if (start > end) { - selection.addRange(range); - selection.extend(endMarker.node, endMarker.offset); - } else { - range.setEnd(endMarker.node, endMarker.offset); - selection.addRange(range); - } - } -} - -var useIEOffsets = ( - ExecutionEnvironment.canUseDOM && - 'selection' in document && - !('getSelection' in window) -); - -var ReactDOMSelection = { - /** - * @param {DOMElement} node - */ - getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets, - - /** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ - setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets -}; - -module.exports = ReactDOMSelection; - -},{"128":128,"130":130,"21":21}],51:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMTextComponent - * @typechecks static-only - */ - -'use strict'; - -var DOMPropertyOperations = _dereq_(11); -var ReactComponentBrowserEnvironment = - _dereq_(35); -var ReactDOMComponent = _dereq_(42); - -var assign = _dereq_(27); -var escapeTextContentForBrowser = _dereq_(116); - -/** - * Text nodes violate a couple assumptions that React makes about components: - * - * - When mounting text into the DOM, adjacent text nodes are merged. - * - Text nodes cannot be assigned a React root ID. - * - * This component is used to wrap strings in elements so that they can undergo - * the same reconciliation that is applied to elements. - * - * TODO: Investigate representing React components in the DOM with text nodes. - * - * @class ReactDOMTextComponent - * @extends ReactComponent - * @internal - */ -var ReactDOMTextComponent = function(props) { - // This constructor and its argument is currently used by mocks. -}; - -assign(ReactDOMTextComponent.prototype, { - - /** - * @param {ReactText} text - * @internal - */ - construct: function(text) { - // TODO: This is really a ReactText (ReactNode), not a ReactElement - this._currentElement = text; - this._stringText = '' + text; - - // Properties - this._rootNodeID = null; - this._mountIndex = 0; - }, - - /** - * Creates the markup for this text node. This node is not intended to have - * any features besides containing text content. - * - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} Markup for this text node. - * @internal - */ - mountComponent: function(rootID, transaction, context) { - this._rootNodeID = rootID; - var escapedText = escapeTextContentForBrowser(this._stringText); - - if (transaction.renderToStaticMarkup) { - // Normally we'd wrap this in a `span` for the reasons stated above, but - // since this is a situation where React won't take over (static pages), - // we can simply return the text as it is. - return escapedText; - } - - return ( - '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + - escapedText + - '</span>' - ); - }, - - /** - * Updates this component by updating the text content. - * - * @param {ReactText} nextText The next text content - * @param {ReactReconcileTransaction} transaction - * @internal - */ - receiveComponent: function(nextText, transaction) { - if (nextText !== this._currentElement) { - this._currentElement = nextText; - var nextStringText = '' + nextText; - if (nextStringText !== this._stringText) { - // TODO: Save this as pending props and use performUpdateIfNecessary - // and/or updateComponent to do the actual update for consistency with - // other component types? - this._stringText = nextStringText; - ReactDOMComponent.BackendIDOperations.updateTextContentByID( - this._rootNodeID, - nextStringText - ); - } - } - }, - - unmountComponent: function() { - ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); - } - -}); - -module.exports = ReactDOMTextComponent; - -},{"11":11,"116":116,"27":27,"35":35,"42":42}],52:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMTextarea - */ - -'use strict'; - -var AutoFocusMixin = _dereq_(2); -var DOMPropertyOperations = _dereq_(11); -var LinkedValueUtils = _dereq_(24); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); -var ReactUpdates = _dereq_(87); - -var assign = _dereq_(27); -var invariant = _dereq_(135); - -var warning = _dereq_(154); - -var textarea = ReactElement.createFactory('textarea'); - -function forceUpdateIfMounted() { - /*jshint validthis:true */ - if (this.isMounted()) { - this.forceUpdate(); - } -} - -/** - * Implements a <textarea> native component that allows setting `value`, and - * `defaultValue`. This differs from the traditional DOM API because value is - * usually set as PCDATA children. - * - * If `value` is not supplied (or null/undefined), user actions that affect the - * value will trigger updates to the element. - * - * If `value` is supplied (and not null/undefined), the rendered element will - * not trigger updates to the element. Instead, the `value` prop must change in - * order for the rendered element to be updated. - * - * The rendered element will be initialized with an empty value, the prop - * `defaultValue` if specified, or the children content (deprecated). - */ -var ReactDOMTextarea = ReactClass.createClass({ - displayName: 'ReactDOMTextarea', - tagName: 'TEXTAREA', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], - - getInitialState: function() { - var defaultValue = this.props.defaultValue; - // TODO (yungsters): Remove support for children content in <textarea>. - var children = this.props.children; - if (children != null) { - if ("production" !== "development") { - ("production" !== "development" ? warning( - false, - 'Use the `defaultValue` or `value` props instead of setting ' + - 'children on <textarea>.' - ) : null); - } - ("production" !== "development" ? invariant( - defaultValue == null, - 'If you supply `defaultValue` on a <textarea>, do not pass children.' - ) : invariant(defaultValue == null)); - if (Array.isArray(children)) { - ("production" !== "development" ? invariant( - children.length <= 1, - '<textarea> can only have at most one child.' - ) : invariant(children.length <= 1)); - children = children[0]; - } - - defaultValue = '' + children; - } - if (defaultValue == null) { - defaultValue = ''; - } - var value = LinkedValueUtils.getValue(this); - return { - // We save the initial value so that `ReactDOMComponent` doesn't update - // `textContent` (unnecessary since we update value). - // The initial value can be a boolean or object so that's why it's - // forced to be a string. - initialValue: '' + (value != null ? value : defaultValue) - }; - }, - - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - ("production" !== "development" ? invariant( - props.dangerouslySetInnerHTML == null, - '`dangerouslySetInnerHTML` does not make sense on <textarea>.' - ) : invariant(props.dangerouslySetInnerHTML == null)); - - props.defaultValue = null; - props.value = null; - props.onChange = this._handleChange; - - // Always set children to the same thing. In IE9, the selection range will - // get reset if `textContent` is mutated. - return textarea(props, this.state.initialValue); - }, - - componentDidUpdate: function(prevProps, prevState, prevContext) { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - var rootNode = this.getDOMNode(); - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - ReactUpdates.asap(forceUpdateIfMounted, this); - return returnValue; - } - -}); - -module.exports = ReactDOMTextarea; - -},{"11":11,"135":135,"154":154,"2":2,"24":24,"27":27,"29":29,"33":33,"57":57,"87":87}],53:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultBatchingStrategy - */ - -'use strict'; - -var ReactUpdates = _dereq_(87); -var Transaction = _dereq_(103); - -var assign = _dereq_(27); -var emptyFunction = _dereq_(114); - -var RESET_BATCHED_UPDATES = { - initialize: emptyFunction, - close: function() { - ReactDefaultBatchingStrategy.isBatchingUpdates = false; - } -}; - -var FLUSH_BATCHED_UPDATES = { - initialize: emptyFunction, - close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates) -}; - -var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES]; - -function ReactDefaultBatchingStrategyTransaction() { - this.reinitializeTransaction(); -} - -assign( - ReactDefaultBatchingStrategyTransaction.prototype, - Transaction.Mixin, - { - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - } - } -); - -var transaction = new ReactDefaultBatchingStrategyTransaction(); - -var ReactDefaultBatchingStrategy = { - isBatchingUpdates: false, - - /** - * Call the provided function in a context within which calls to `setState` - * and friends are batched such that components aren't updated unnecessarily. - */ - batchedUpdates: function(callback, a, b, c, d) { - var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; - - ReactDefaultBatchingStrategy.isBatchingUpdates = true; - - // The code is written this way to avoid extra allocations - if (alreadyBatchingUpdates) { - callback(a, b, c, d); - } else { - transaction.perform(callback, null, a, b, c, d); - } - } -}; - -module.exports = ReactDefaultBatchingStrategy; - -},{"103":103,"114":114,"27":27,"87":87}],54:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultInjection - */ - -'use strict'; - -var BeforeInputEventPlugin = _dereq_(3); -var ChangeEventPlugin = _dereq_(7); -var ClientReactRootIndex = _dereq_(8); -var DefaultEventPluginOrder = _dereq_(13); -var EnterLeaveEventPlugin = _dereq_(14); -var ExecutionEnvironment = _dereq_(21); -var HTMLDOMPropertyConfig = _dereq_(23); -var MobileSafariClickEventPlugin = _dereq_(26); -var ReactBrowserComponentMixin = _dereq_(29); -var ReactClass = _dereq_(33); -var ReactComponentBrowserEnvironment = - _dereq_(35); -var ReactDefaultBatchingStrategy = _dereq_(53); -var ReactDOMComponent = _dereq_(42); -var ReactDOMButton = _dereq_(41); -var ReactDOMForm = _dereq_(43); -var ReactDOMImg = _dereq_(46); -var ReactDOMIDOperations = _dereq_(44); -var ReactDOMIframe = _dereq_(45); -var ReactDOMInput = _dereq_(47); -var ReactDOMOption = _dereq_(48); -var ReactDOMSelect = _dereq_(49); -var ReactDOMTextarea = _dereq_(52); -var ReactDOMTextComponent = _dereq_(51); -var ReactElement = _dereq_(57); -var ReactEventListener = _dereq_(62); -var ReactInjection = _dereq_(64); -var ReactInstanceHandles = _dereq_(66); -var ReactMount = _dereq_(70); -var ReactReconcileTransaction = _dereq_(80); -var SelectEventPlugin = _dereq_(89); -var ServerReactRootIndex = _dereq_(90); -var SimpleEventPlugin = _dereq_(91); -var SVGDOMPropertyConfig = _dereq_(88); - -var createFullPageComponent = _dereq_(111); - -function autoGenerateWrapperClass(type) { - return ReactClass.createClass({ - tagName: type.toUpperCase(), - render: function() { - return new ReactElement( - type, - null, - null, - null, - null, - this.props - ); - } - }); -} - -function inject() { - ReactInjection.EventEmitter.injectReactEventListener( - ReactEventListener - ); - - /** - * Inject modules for resolving DOM hierarchy and plugin ordering. - */ - ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); - ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles); - ReactInjection.EventPluginHub.injectMount(ReactMount); - - /** - * Some important event plugins included by default (without having to require - * them). - */ - ReactInjection.EventPluginHub.injectEventPluginsByName({ - SimpleEventPlugin: SimpleEventPlugin, - EnterLeaveEventPlugin: EnterLeaveEventPlugin, - ChangeEventPlugin: ChangeEventPlugin, - MobileSafariClickEventPlugin: MobileSafariClickEventPlugin, - SelectEventPlugin: SelectEventPlugin, - BeforeInputEventPlugin: BeforeInputEventPlugin - }); - - ReactInjection.NativeComponent.injectGenericComponentClass( - ReactDOMComponent - ); - - ReactInjection.NativeComponent.injectTextComponentClass( - ReactDOMTextComponent - ); - - ReactInjection.NativeComponent.injectAutoWrapper( - autoGenerateWrapperClass - ); - - // This needs to happen before createFullPageComponent() otherwise the mixin - // won't be included. - ReactInjection.Class.injectMixin(ReactBrowserComponentMixin); - - ReactInjection.NativeComponent.injectComponentClasses({ - 'button': ReactDOMButton, - 'form': ReactDOMForm, - 'iframe': ReactDOMIframe, - 'img': ReactDOMImg, - 'input': ReactDOMInput, - 'option': ReactDOMOption, - 'select': ReactDOMSelect, - 'textarea': ReactDOMTextarea, - - 'html': createFullPageComponent('html'), - 'head': createFullPageComponent('head'), - 'body': createFullPageComponent('body') - }); - - ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); - ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); - - ReactInjection.EmptyComponent.injectEmptyComponent('noscript'); - - ReactInjection.Updates.injectReconcileTransaction( - ReactReconcileTransaction - ); - ReactInjection.Updates.injectBatchingStrategy( - ReactDefaultBatchingStrategy - ); - - ReactInjection.RootIndex.injectCreateReactRootIndex( - ExecutionEnvironment.canUseDOM ? - ClientReactRootIndex.createReactRootIndex : - ServerReactRootIndex.createReactRootIndex - ); - - ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); - ReactInjection.DOMComponent.injectIDOperations(ReactDOMIDOperations); - - if ("production" !== "development") { - var url = (ExecutionEnvironment.canUseDOM && window.location.href) || ''; - if ((/[?&]react_perf\b/).test(url)) { - var ReactDefaultPerf = _dereq_(55); - ReactDefaultPerf.start(); - } - } -} - -module.exports = { - inject: inject -}; - -},{"111":111,"13":13,"14":14,"21":21,"23":23,"26":26,"29":29,"3":3,"33":33,"35":35,"41":41,"42":42,"43":43,"44":44,"45":45,"46":46,"47":47,"48":48,"49":49,"51":51,"52":52,"53":53,"55":55,"57":57,"62":62,"64":64,"66":66,"7":7,"70":70,"8":8,"80":80,"88":88,"89":89,"90":90,"91":91}],55:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultPerf - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = _dereq_(10); -var ReactDefaultPerfAnalysis = _dereq_(56); -var ReactMount = _dereq_(70); -var ReactPerf = _dereq_(75); - -var performanceNow = _dereq_(146); - -function roundFloat(val) { - return Math.floor(val * 100) / 100; -} - -function addValue(obj, key, val) { - obj[key] = (obj[key] || 0) + val; -} - -var ReactDefaultPerf = { - _allMeasurements: [], // last item in the list is the current one - _mountStack: [0], - _injected: false, - - start: function() { - if (!ReactDefaultPerf._injected) { - ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); - } - - ReactDefaultPerf._allMeasurements.length = 0; - ReactPerf.enableMeasure = true; - }, - - stop: function() { - ReactPerf.enableMeasure = false; - }, - - getLastMeasurements: function() { - return ReactDefaultPerf._allMeasurements; - }, - - printExclusive: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); - console.table(summary.map(function(item) { - return { - 'Component class name': item.componentName, - 'Total inclusive time (ms)': roundFloat(item.inclusive), - 'Exclusive mount time (ms)': roundFloat(item.exclusive), - 'Exclusive render time (ms)': roundFloat(item.render), - 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count), - 'Render time per instance (ms)': roundFloat(item.render / item.count), - 'Instances': item.count - }; - })); - // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct - // number. - }, - - printInclusive: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); - console.table(summary.map(function(item) { - return { - 'Owner > component': item.componentName, - 'Inclusive time (ms)': roundFloat(item.time), - 'Instances': item.count - }; - })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - getMeasurementsSummaryMap: function(measurements) { - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( - measurements, - true - ); - return summary.map(function(item) { - return { - 'Owner > component': item.componentName, - 'Wasted time (ms)': item.time, - 'Instances': item.count - }; - }); - }, - - printWasted: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements)); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - printDOM: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); - console.table(summary.map(function(item) { - var result = {}; - result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; - result['type'] = item.type; - result['args'] = JSON.stringify(item.args); - return result; - })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - _recordWrite: function(id, fnName, totalTime, args) { - // TODO: totalTime isn't that useful since it doesn't count paints/reflows - var writes = - ReactDefaultPerf - ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] - .writes; - writes[id] = writes[id] || []; - writes[id].push({ - type: fnName, - time: totalTime, - args: args - }); - }, - - measure: function(moduleName, fnName, func) { - return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - var totalTime; - var rv; - var start; - - if (fnName === '_renderNewRootComponent' || - fnName === 'flushBatchedUpdates') { - // A "measurement" is a set of metrics recorded for each flush. We want - // to group the metrics for a given flush together so we can look at the - // components that rendered and the DOM operations that actually - // happened to determine the amount of "wasted work" performed. - ReactDefaultPerf._allMeasurements.push({ - exclusive: {}, - inclusive: {}, - render: {}, - counts: {}, - writes: {}, - displayNames: {}, - totalTime: 0 - }); - start = performanceNow(); - rv = func.apply(this, args); - ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ].totalTime = performanceNow() - start; - return rv; - } else if (fnName === '_mountImageIntoNode' || - moduleName === 'ReactDOMIDOperations') { - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (fnName === '_mountImageIntoNode') { - var mountID = ReactMount.getID(args[1]); - ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); - } else if (fnName === 'dangerouslyProcessChildrenUpdates') { - // special format - args[0].forEach(function(update) { - var writeArgs = {}; - if (update.fromIndex !== null) { - writeArgs.fromIndex = update.fromIndex; - } - if (update.toIndex !== null) { - writeArgs.toIndex = update.toIndex; - } - if (update.textContent !== null) { - writeArgs.textContent = update.textContent; - } - if (update.markupIndex !== null) { - writeArgs.markup = args[1][update.markupIndex]; - } - ReactDefaultPerf._recordWrite( - update.parentID, - update.type, - totalTime, - writeArgs - ); - }); - } else { - // basic format - ReactDefaultPerf._recordWrite( - args[0], - fnName, - totalTime, - Array.prototype.slice.call(args, 1) - ); - } - return rv; - } else if (moduleName === 'ReactCompositeComponent' && ( - (// TODO: receiveComponent()? - (fnName === 'mountComponent' || - fnName === 'updateComponent' || fnName === '_renderValidatedComponent')))) { - - if (typeof this._currentElement.type === 'string') { - return func.apply(this, args); - } - - var rootNodeID = fnName === 'mountComponent' ? - args[0] : - this._rootNodeID; - var isRender = fnName === '_renderValidatedComponent'; - var isMount = fnName === 'mountComponent'; - - var mountStack = ReactDefaultPerf._mountStack; - var entry = ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ]; - - if (isRender) { - addValue(entry.counts, rootNodeID, 1); - } else if (isMount) { - mountStack.push(0); - } - - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (isRender) { - addValue(entry.render, rootNodeID, totalTime); - } else if (isMount) { - var subMountTime = mountStack.pop(); - mountStack[mountStack.length - 1] += totalTime; - addValue(entry.exclusive, rootNodeID, totalTime - subMountTime); - addValue(entry.inclusive, rootNodeID, totalTime); - } else { - addValue(entry.inclusive, rootNodeID, totalTime); - } - - entry.displayNames[rootNodeID] = { - current: this.getName(), - owner: this._currentElement._owner ? - this._currentElement._owner.getName() : - '<root>' - }; - - return rv; - } else { - return func.apply(this, args); - } - }; - } -}; - -module.exports = ReactDefaultPerf; - -},{"10":10,"146":146,"56":56,"70":70,"75":75}],56:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultPerfAnalysis - */ - -var assign = _dereq_(27); - -// Don't try to save users less than 1.2ms (a number I made up) -var DONT_CARE_THRESHOLD = 1.2; -var DOM_OPERATION_TYPES = { - '_mountImageIntoNode': 'set innerHTML', - INSERT_MARKUP: 'set innerHTML', - MOVE_EXISTING: 'move', - REMOVE_NODE: 'remove', - TEXT_CONTENT: 'set textContent', - 'updatePropertyByID': 'update attribute', - 'deletePropertyByID': 'delete attribute', - 'updateStylesByID': 'update styles', - 'updateInnerHTMLByID': 'set innerHTML', - 'dangerouslyReplaceNodeWithMarkupByID': 'replace' -}; - -function getTotalTime(measurements) { - // TODO: return number of DOM ops? could be misleading. - // TODO: measure dropped frames after reconcile? - // TODO: log total time of each reconcile and the top-level component - // class that triggered it. - var totalTime = 0; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - totalTime += measurement.totalTime; - } - return totalTime; -} - -function getDOMSummary(measurements) { - var items = []; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var id; - - for (id in measurement.writes) { - measurement.writes[id].forEach(function(write) { - items.push({ - id: id, - type: DOM_OPERATION_TYPES[write.type] || write.type, - args: write.args - }); - }); - } - } - return items; -} - -function getExclusiveSummary(measurements) { - var candidates = {}; - var displayName; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); - - for (var id in allIDs) { - displayName = measurement.displayNames[id].current; - - candidates[displayName] = candidates[displayName] || { - componentName: displayName, - inclusive: 0, - exclusive: 0, - render: 0, - count: 0 - }; - if (measurement.render[id]) { - candidates[displayName].render += measurement.render[id]; - } - if (measurement.exclusive[id]) { - candidates[displayName].exclusive += measurement.exclusive[id]; - } - if (measurement.inclusive[id]) { - candidates[displayName].inclusive += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[displayName].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (displayName in candidates) { - if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { - arr.push(candidates[displayName]); - } - } - - arr.sort(function(a, b) { - return b.exclusive - a.exclusive; - }); - - return arr; -} - -function getInclusiveSummary(measurements, onlyClean) { - var candidates = {}; - var inclusiveKey; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); - var cleanComponents; - - if (onlyClean) { - cleanComponents = getUnchangedComponents(measurement); - } - - for (var id in allIDs) { - if (onlyClean && !cleanComponents[id]) { - continue; - } - - var displayName = measurement.displayNames[id]; - - // Inclusive time is not useful for many components without knowing where - // they are instantiated. So we aggregate inclusive time with both the - // owner and current displayName as the key. - inclusiveKey = displayName.owner + ' > ' + displayName.current; - - candidates[inclusiveKey] = candidates[inclusiveKey] || { - componentName: inclusiveKey, - time: 0, - count: 0 - }; - - if (measurement.inclusive[id]) { - candidates[inclusiveKey].time += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[inclusiveKey].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (inclusiveKey in candidates) { - if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { - arr.push(candidates[inclusiveKey]); - } - } - - arr.sort(function(a, b) { - return b.time - a.time; - }); - - return arr; -} - -function getUnchangedComponents(measurement) { - // For a given reconcile, look at which components did not actually - // render anything to the DOM and return a mapping of their ID to - // the amount of time it took to render the entire subtree. - var cleanComponents = {}; - var dirtyLeafIDs = Object.keys(measurement.writes); - var allIDs = assign({}, measurement.exclusive, measurement.inclusive); - - for (var id in allIDs) { - var isDirty = false; - // For each component that rendered, see if a component that triggered - // a DOM op is in its subtree. - for (var i = 0; i < dirtyLeafIDs.length; i++) { - if (dirtyLeafIDs[i].indexOf(id) === 0) { - isDirty = true; - break; - } - } - if (!isDirty && measurement.counts[id] > 0) { - cleanComponents[id] = true; - } - } - return cleanComponents; -} - -var ReactDefaultPerfAnalysis = { - getExclusiveSummary: getExclusiveSummary, - getInclusiveSummary: getInclusiveSummary, - getDOMSummary: getDOMSummary, - getTotalTime: getTotalTime -}; - -module.exports = ReactDefaultPerfAnalysis; - -},{"27":27}],57:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactElement - */ - -'use strict'; - -var ReactContext = _dereq_(38); -var ReactCurrentOwner = _dereq_(39); - -var assign = _dereq_(27); -var warning = _dereq_(154); - -var RESERVED_PROPS = { - key: true, - ref: true -}; - -/** - * Warn for mutations. - * - * @internal - * @param {object} object - * @param {string} key - */ -function defineWarningProperty(object, key) { - Object.defineProperty(object, key, { - - configurable: false, - enumerable: true, - - get: function() { - if (!this._store) { - return null; - } - return this._store[key]; - }, - - set: function(value) { - ("production" !== "development" ? warning( - false, - 'Don\'t set the %s property of the React element. Instead, ' + - 'specify the correct value when initially creating the element.', - key - ) : null); - this._store[key] = value; - } - - }); -} - -/** - * This is updated to true if the membrane is successfully created. - */ -var useMutationMembrane = false; - -/** - * Warn for mutations. - * - * @internal - * @param {object} element - */ -function defineMutationMembrane(prototype) { - try { - var pseudoFrozenProperties = { - props: true - }; - for (var key in pseudoFrozenProperties) { - defineWarningProperty(prototype, key); - } - useMutationMembrane = true; - } catch (x) { - // IE will fail on defineProperty - } -} - -/** - * Base constructor for all React elements. This is only used to make this - * work with a dynamic instanceof check. Nothing should live on this prototype. - * - * @param {*} type - * @param {string|object} ref - * @param {*} key - * @param {*} props - * @internal - */ -var ReactElement = function(type, key, ref, owner, context, props) { - // Built-in properties that belong on the element - this.type = type; - this.key = key; - this.ref = ref; - - // Record the component responsible for creating this element. - this._owner = owner; - - // TODO: Deprecate withContext, and then the context becomes accessible - // through the owner. - this._context = context; - - if ("production" !== "development") { - // The validation flag and props are currently mutative. We put them on - // an external backing store so that we can freeze the whole object. - // This can be replaced with a WeakMap once they are implemented in - // commonly used development environments. - this._store = {props: props, originalProps: assign({}, props)}; - - // To make comparing ReactElements easier for testing purposes, we make - // the validation flag non-enumerable (where possible, which should - // include every environment we run tests in), so the test framework - // ignores it. - try { - Object.defineProperty(this._store, 'validated', { - configurable: false, - enumerable: false, - writable: true - }); - } catch (x) { - } - this._store.validated = false; - - // We're not allowed to set props directly on the object so we early - // return and rely on the prototype membrane to forward to the backing - // store. - if (useMutationMembrane) { - Object.freeze(this); - return; - } - } - - this.props = props; -}; - -// We intentionally don't expose the function on the constructor property. -// ReactElement should be indistinguishable from a plain object. -ReactElement.prototype = { - _isReactElement: true -}; - -if ("production" !== "development") { - defineMutationMembrane(ReactElement.prototype); -} - -ReactElement.createElement = function(type, config, children) { - var propName; - - // Reserved names are extracted - var props = {}; - - var key = null; - var ref = null; - - if (config != null) { - ref = config.ref === undefined ? null : config.ref; - key = config.key === undefined ? null : '' + config.key; - // Remaining properties are added to a new props object - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - // Resolve default props - if (type && type.defaultProps) { - var defaultProps = type.defaultProps; - for (propName in defaultProps) { - if (typeof props[propName] === 'undefined') { - props[propName] = defaultProps[propName]; - } - } - } - - return new ReactElement( - type, - key, - ref, - ReactCurrentOwner.current, - ReactContext.current, - props - ); -}; - -ReactElement.createFactory = function(type) { - var factory = ReactElement.createElement.bind(null, type); - // Expose the type on the factory and the prototype so that it can be - // easily accessed on elements. E.g. <Foo />.type === Foo.type. - // This should not be named `constructor` since this may not be the function - // that created the element, and it may not even be a constructor. - // Legacy hook TODO: Warn if this is accessed - factory.type = type; - return factory; -}; - -ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { - var newElement = new ReactElement( - oldElement.type, - oldElement.key, - oldElement.ref, - oldElement._owner, - oldElement._context, - newProps - ); - - if ("production" !== "development") { - // If the key on the original is valid, then the clone is valid - newElement._store.validated = oldElement._store.validated; - } - return newElement; -}; - -ReactElement.cloneElement = function(element, config, children) { - var propName; - - // Original props are copied - var props = assign({}, element.props); - - // Reserved names are extracted - var key = element.key; - var ref = element.ref; - - // Owner will be preserved, unless ref is overridden - var owner = element._owner; - - if (config != null) { - if (config.ref !== undefined) { - // Silently steal the ref from the parent. - ref = config.ref; - owner = ReactCurrentOwner.current; - } - if (config.key !== undefined) { - key = '' + config.key; - } - // Remaining properties override existing props - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - return new ReactElement( - element.type, - key, - ref, - owner, - element._context, - props - ); -}; - -/** - * @param {?object} object - * @return {boolean} True if `object` is a valid component. - * @final - */ -ReactElement.isValidElement = function(object) { - // ReactTestUtils is often used outside of beforeEach where as React is - // within it. This leads to two different instances of React on the same - // page. To identify a element from a different React instance we use - // a flag instead of an instanceof check. - var isElement = !!(object && object._isReactElement); - // if (isElement && !(object instanceof ReactElement)) { - // This is an indicator that you're using multiple versions of React at the - // same time. This will screw with ownership and stuff. Fix it, please. - // TODO: We could possibly warn here. - // } - return isElement; -}; - -module.exports = ReactElement; - -},{"154":154,"27":27,"38":38,"39":39}],58:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactElementValidator - */ - -/** - * ReactElementValidator provides a wrapper around a element factory - * which validates the props passed to the element. This is intended to be - * used only in DEV and could be replaced by a static type checker for languages - * that support it. - */ - -'use strict'; - -var ReactElement = _dereq_(57); -var ReactFragment = _dereq_(63); -var ReactPropTypeLocations = _dereq_(77); -var ReactPropTypeLocationNames = _dereq_(76); -var ReactCurrentOwner = _dereq_(39); -var ReactNativeComponent = _dereq_(73); - -var getIteratorFn = _dereq_(126); -var invariant = _dereq_(135); -var warning = _dereq_(154); - -function getDeclarationErrorAddendum() { - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Warn if there's no key explicitly set on dynamic arrays of children or - * object keys are not valid. This allows us to keep track of children between - * updates. - */ -var ownerHasKeyUseWarning = {}; - -var loggedTypeFailures = {}; - -var NUMERIC_PROPERTY_REGEX = /^\d+$/; - -/** - * Gets the instance's name for use in warnings. - * - * @internal - * @return {?string} Display name or undefined - */ -function getName(instance) { - var publicInstance = instance && instance.getPublicInstance(); - if (!publicInstance) { - return undefined; - } - var constructor = publicInstance.constructor; - if (!constructor) { - return undefined; - } - return constructor.displayName || constructor.name || undefined; -} - -/** - * Gets the current owner's displayName for use in warnings. - * - * @internal - * @return {?string} Display name or undefined - */ -function getCurrentOwnerDisplayName() { - var current = ReactCurrentOwner.current; - return ( - current && getName(current) || undefined - ); -} - -/** - * Warn if the element doesn't have an explicit key assigned to it. - * This element is in an array. The array could grow and shrink or be - * reordered. All children that haven't already been validated are required to - * have a "key" property assigned to it. - * - * @internal - * @param {ReactElement} element Element that requires a key. - * @param {*} parentType element's parent's type. - */ -function validateExplicitKey(element, parentType) { - if (element._store.validated || element.key != null) { - return; - } - element._store.validated = true; - - warnAndMonitorForKeyUse( - 'Each child in an array or iterator should have a unique "key" prop.', - element, - parentType - ); -} - -/** - * Warn if the key is being defined as an object property but has an incorrect - * value. - * - * @internal - * @param {string} name Property name of the key. - * @param {ReactElement} element Component that requires a key. - * @param {*} parentType element's parent's type. - */ -function validatePropertyKey(name, element, parentType) { - if (!NUMERIC_PROPERTY_REGEX.test(name)) { - return; - } - warnAndMonitorForKeyUse( - 'Child objects should have non-numeric keys so ordering is preserved.', - element, - parentType - ); -} - -/** - * Shared warning and monitoring code for the key warnings. - * - * @internal - * @param {string} message The base warning that gets output. - * @param {ReactElement} element Component that requires a key. - * @param {*} parentType element's parent's type. - */ -function warnAndMonitorForKeyUse(message, element, parentType) { - var ownerName = getCurrentOwnerDisplayName(); - var parentName = typeof parentType === 'string' ? - parentType : parentType.displayName || parentType.name; - - var useName = ownerName || parentName; - var memoizer = ownerHasKeyUseWarning[message] || ( - (ownerHasKeyUseWarning[message] = {}) - ); - if (memoizer.hasOwnProperty(useName)) { - return; - } - memoizer[useName] = true; - - var parentOrOwnerAddendum = - ownerName ? (" Check the render method of " + ownerName + ".") : - parentName ? (" Check the React.render call using <" + parentName + ">.") : - ''; - - // Usually the current owner is the offender, but if it accepts children as a - // property, it may be the creator of the child that's responsible for - // assigning it a key. - var childOwnerAddendum = ''; - if (element && - element._owner && - element._owner !== ReactCurrentOwner.current) { - // Name of the component that originally created this child. - var childOwnerName = getName(element._owner); - - childOwnerAddendum = (" It was passed a child from " + childOwnerName + "."); - } - - ("production" !== "development" ? warning( - false, - message + '%s%s See https://fb.me/react-warning-keys for more information.', - parentOrOwnerAddendum, - childOwnerAddendum - ) : null); -} - -/** - * Ensure that every element either is passed in a static location, in an - * array with an explicit keys property defined, or in an object literal - * with valid key property. - * - * @internal - * @param {ReactNode} node Statically passed child of any type. - * @param {*} parentType node's parent's type. - */ -function validateChildKeys(node, parentType) { - if (Array.isArray(node)) { - for (var i = 0; i < node.length; i++) { - var child = node[i]; - if (ReactElement.isValidElement(child)) { - validateExplicitKey(child, parentType); - } - } - } else if (ReactElement.isValidElement(node)) { - // This element was passed in a valid location. - node._store.validated = true; - } else if (node) { - var iteratorFn = getIteratorFn(node); - // Entry iterators provide implicit keys. - if (iteratorFn) { - if (iteratorFn !== node.entries) { - var iterator = iteratorFn.call(node); - var step; - while (!(step = iterator.next()).done) { - if (ReactElement.isValidElement(step.value)) { - validateExplicitKey(step.value, parentType); - } - } - } - } else if (typeof node === 'object') { - var fragment = ReactFragment.extractIfFragment(node); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - validatePropertyKey(key, fragment[key], parentType); - } - } - } - } -} - -/** - * Assert that the props are valid - * - * @param {string} componentName Name of the component for error messages. - * @param {object} propTypes Map of prop name to a ReactPropType - * @param {object} props - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ -function checkPropTypes(componentName, propTypes, props, location) { - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - ("production" !== "development" ? invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ) : invariant(typeof propTypes[propName] === 'function')); - error = propTypes[propName](props, propName, componentName, location); - } catch (ex) { - error = ex; - } - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var addendum = getDeclarationErrorAddendum(this); - ("production" !== "development" ? warning(false, 'Failed propType: %s%s', error.message, addendum) : null); - } - } - } -} - -var warnedPropsMutations = {}; - -/** - * Warn about mutating props when setting `propName` on `element`. - * - * @param {string} propName The string key within props that was set - * @param {ReactElement} element - */ -function warnForPropsMutation(propName, element) { - var type = element.type; - var elementName = typeof type === 'string' ? type : type.displayName; - var ownerName = element._owner ? - element._owner.getPublicInstance().constructor.displayName : null; - - var warningKey = propName + '|' + elementName + '|' + ownerName; - if (warnedPropsMutations.hasOwnProperty(warningKey)) { - return; - } - warnedPropsMutations[warningKey] = true; - - var elementInfo = ''; - if (elementName) { - elementInfo = ' <' + elementName + ' />'; - } - var ownerInfo = ''; - if (ownerName) { - ownerInfo = ' The element was created by ' + ownerName + '.'; - } - - ("production" !== "development" ? warning( - false, - 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + - 'correct value when initially creating the element or use ' + - 'React.cloneElement to make a new element with updated props.%s', - propName, - elementInfo, - ownerInfo - ) : null); -} - -// Inline Object.is polyfill -function is(a, b) { - if (a !== a) { - // NaN - return b !== b; - } - if (a === 0 && b === 0) { - // +-0 - return 1 / a === 1 / b; - } - return a === b; -} - -/** - * Given an element, check if its props have been mutated since element - * creation (or the last call to this function). In particular, check if any - * new props have been added, which we can't directly catch by defining warning - * properties on the props object. - * - * @param {ReactElement} element - */ -function checkAndWarnForMutatedProps(element) { - if (!element._store) { - // Element was created using `new ReactElement` directly or with - // `ReactElement.createElement`; skip mutation checking - return; - } - - var originalProps = element._store.originalProps; - var props = element.props; - - for (var propName in props) { - if (props.hasOwnProperty(propName)) { - if (!originalProps.hasOwnProperty(propName) || - !is(originalProps[propName], props[propName])) { - warnForPropsMutation(propName, element); - - // Copy over the new value so that the two props objects match again - originalProps[propName] = props[propName]; - } - } - } -} - -/** - * Given an element, validate that its props follow the propTypes definition, - * provided by the type. - * - * @param {ReactElement} element - */ -function validatePropTypes(element) { - if (element.type == null) { - // This has already warned. Don't throw. - return; - } - // Extract the component class from the element. Converts string types - // to a composite class which may have propTypes. - // TODO: Validating a string's propTypes is not decoupled from the - // rendering target which is problematic. - var componentClass = ReactNativeComponent.getComponentClassForElement( - element - ); - var name = componentClass.displayName || componentClass.name; - if (componentClass.propTypes) { - checkPropTypes( - name, - componentClass.propTypes, - element.props, - ReactPropTypeLocations.prop - ); - } - if (typeof componentClass.getDefaultProps === 'function') { - ("production" !== "development" ? warning( - componentClass.getDefaultProps.isReactClassApproved, - 'getDefaultProps is only used on classic React.createClass ' + - 'definitions. Use a static property named `defaultProps` instead.' - ) : null); - } -} - -var ReactElementValidator = { - - checkAndWarnForMutatedProps: checkAndWarnForMutatedProps, - - createElement: function(type, props, children) { - // We warn in this case but don't throw. We expect the element creation to - // succeed and there will likely be errors in render. - ("production" !== "development" ? warning( - type != null, - 'React.createElement: type should not be null or undefined. It should ' + - 'be a string (for DOM elements) or a ReactClass (for composite ' + - 'components).' - ) : null); - - var element = ReactElement.createElement.apply(this, arguments); - - // The result can be nullish if a mock or a custom function is used. - // TODO: Drop this when these are no longer allowed as the type argument. - if (element == null) { - return element; - } - - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], type); - } - - validatePropTypes(element); - - return element; - }, - - createFactory: function(type) { - var validatedFactory = ReactElementValidator.createElement.bind( - null, - type - ); - // Legacy hook TODO: Warn if this is accessed - validatedFactory.type = type; - - if ("production" !== "development") { - try { - Object.defineProperty( - validatedFactory, - 'type', - { - enumerable: false, - get: function() { - ("production" !== "development" ? warning( - false, - 'Factory.type is deprecated. Access the class directly ' + - 'before passing it to createFactory.' - ) : null); - Object.defineProperty(this, 'type', { - value: type - }); - return type; - } - } - ); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - - - return validatedFactory; - }, - - cloneElement: function(element, props, children) { - var newElement = ReactElement.cloneElement.apply(this, arguments); - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], newElement.type); - } - validatePropTypes(newElement); - return newElement; - } - -}; - -module.exports = ReactElementValidator; - -},{"126":126,"135":135,"154":154,"39":39,"57":57,"63":63,"73":73,"76":76,"77":77}],59:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactEmptyComponent - */ - -'use strict'; - -var ReactElement = _dereq_(57); -var ReactInstanceMap = _dereq_(67); - -var invariant = _dereq_(135); - -var component; -// This registry keeps track of the React IDs of the components that rendered to -// `null` (in reality a placeholder such as `noscript`) -var nullComponentIDsRegistry = {}; - -var ReactEmptyComponentInjection = { - injectEmptyComponent: function(emptyComponent) { - component = ReactElement.createFactory(emptyComponent); - } -}; - -var ReactEmptyComponentType = function() {}; -ReactEmptyComponentType.prototype.componentDidMount = function() { - var internalInstance = ReactInstanceMap.get(this); - // TODO: Make sure we run these methods in the correct order, we shouldn't - // need this check. We're going to assume if we're here it means we ran - // componentWillUnmount already so there is no internal instance (it gets - // removed as part of the unmounting process). - if (!internalInstance) { - return; - } - registerNullComponentID(internalInstance._rootNodeID); -}; -ReactEmptyComponentType.prototype.componentWillUnmount = function() { - var internalInstance = ReactInstanceMap.get(this); - // TODO: Get rid of this check. See TODO in componentDidMount. - if (!internalInstance) { - return; - } - deregisterNullComponentID(internalInstance._rootNodeID); -}; -ReactEmptyComponentType.prototype.render = function() { - ("production" !== "development" ? invariant( - component, - 'Trying to return null from a render, but no null placeholder component ' + - 'was injected.' - ) : invariant(component)); - return component(); -}; - -var emptyElement = ReactElement.createElement(ReactEmptyComponentType); - -/** - * Mark the component as having rendered to null. - * @param {string} id Component's `_rootNodeID`. - */ -function registerNullComponentID(id) { - nullComponentIDsRegistry[id] = true; -} - -/** - * Unmark the component as having rendered to null: it renders to something now. - * @param {string} id Component's `_rootNodeID`. - */ -function deregisterNullComponentID(id) { - delete nullComponentIDsRegistry[id]; -} - -/** - * @param {string} id Component's `_rootNodeID`. - * @return {boolean} True if the component is rendered to null. - */ -function isNullComponentID(id) { - return !!nullComponentIDsRegistry[id]; -} - -var ReactEmptyComponent = { - emptyElement: emptyElement, - injection: ReactEmptyComponentInjection, - isNullComponentID: isNullComponentID -}; - -module.exports = ReactEmptyComponent; - -},{"135":135,"57":57,"67":67}],60:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactErrorUtils - * @typechecks - */ - -"use strict"; - -var ReactErrorUtils = { - /** - * Creates a guarded version of a function. This is supposed to make debugging - * of event handlers easier. To aid debugging with the browser's debugger, - * this currently simply returns the original function. - * - * @param {function} func Function to be executed - * @param {string} name The name of the guard - * @return {function} - */ - guard: function(func, name) { - return func; - } -}; - -module.exports = ReactErrorUtils; - -},{}],61:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactEventEmitterMixin - */ - -'use strict'; - -var EventPluginHub = _dereq_(17); - -function runEventQueueInBatch(events) { - EventPluginHub.enqueueEvents(events); - EventPluginHub.processEventQueue(); -} - -var ReactEventEmitterMixin = { - - /** - * Streams a fired top-level event to `EventPluginHub` where plugins have the - * opportunity to create `ReactEvent`s to be dispatched. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native environment event. - */ - handleTopLevel: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var events = EventPluginHub.extractEvents( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ); - - runEventQueueInBatch(events); - } -}; - -module.exports = ReactEventEmitterMixin; - -},{"17":17}],62:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactEventListener - * @typechecks static-only - */ - -'use strict'; - -var EventListener = _dereq_(16); -var ExecutionEnvironment = _dereq_(21); -var PooledClass = _dereq_(28); -var ReactInstanceHandles = _dereq_(66); -var ReactMount = _dereq_(70); -var ReactUpdates = _dereq_(87); - -var assign = _dereq_(27); -var getEventTarget = _dereq_(125); -var getUnboundedScrollPosition = _dereq_(131); - -/** - * Finds the parent React component of `node`. - * - * @param {*} node - * @return {?DOMEventTarget} Parent container, or `null` if the specified node - * is not nested. - */ -function findParent(node) { - // TODO: It may be a good idea to cache this to prevent unnecessary DOM - // traversal, but caching is difficult to do correctly without using a - // mutation observer to listen for all DOM changes. - var nodeID = ReactMount.getID(node); - var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID); - var container = ReactMount.findReactContainerForID(rootID); - var parent = ReactMount.getFirstReactDOM(container); - return parent; -} - -// Used to store ancestor hierarchy in top level callback -function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) { - this.topLevelType = topLevelType; - this.nativeEvent = nativeEvent; - this.ancestors = []; -} -assign(TopLevelCallbackBookKeeping.prototype, { - destructor: function() { - this.topLevelType = null; - this.nativeEvent = null; - this.ancestors.length = 0; - } -}); -PooledClass.addPoolingTo( - TopLevelCallbackBookKeeping, - PooledClass.twoArgumentPooler -); - -function handleTopLevelImpl(bookKeeping) { - var topLevelTarget = ReactMount.getFirstReactDOM( - getEventTarget(bookKeeping.nativeEvent) - ) || window; - - // Loop through the hierarchy, in case there's any nested components. - // It's important that we build the array of ancestors before calling any - // event handlers, because event handlers can modify the DOM, leading to - // inconsistencies with ReactMount's node cache. See #1105. - var ancestor = topLevelTarget; - while (ancestor) { - bookKeeping.ancestors.push(ancestor); - ancestor = findParent(ancestor); - } - - for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) { - topLevelTarget = bookKeeping.ancestors[i]; - var topLevelTargetID = ReactMount.getID(topLevelTarget) || ''; - ReactEventListener._handleTopLevel( - bookKeeping.topLevelType, - topLevelTarget, - topLevelTargetID, - bookKeeping.nativeEvent - ); - } -} - -function scrollValueMonitor(cb) { - var scrollPosition = getUnboundedScrollPosition(window); - cb(scrollPosition); -} - -var ReactEventListener = { - _enabled: true, - _handleTopLevel: null, - - WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null, - - setHandleTopLevel: function(handleTopLevel) { - ReactEventListener._handleTopLevel = handleTopLevel; - }, - - setEnabled: function(enabled) { - ReactEventListener._enabled = !!enabled; - }, - - isEnabled: function() { - return ReactEventListener._enabled; - }, - - - /** - * Traps top-level events by using event bubbling. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} handle Element on which to attach listener. - * @return {object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - var element = handle; - if (!element) { - return null; - } - return EventListener.listen( - element, - handlerBaseName, - ReactEventListener.dispatchEvent.bind(null, topLevelType) - ); - }, - - /** - * Traps a top-level event by using event capturing. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} handle Element on which to attach listener. - * @return {object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - var element = handle; - if (!element) { - return null; - } - return EventListener.capture( - element, - handlerBaseName, - ReactEventListener.dispatchEvent.bind(null, topLevelType) - ); - }, - - monitorScrollValue: function(refresh) { - var callback = scrollValueMonitor.bind(null, refresh); - EventListener.listen(window, 'scroll', callback); - }, - - dispatchEvent: function(topLevelType, nativeEvent) { - if (!ReactEventListener._enabled) { - return; - } - - var bookKeeping = TopLevelCallbackBookKeeping.getPooled( - topLevelType, - nativeEvent - ); - try { - // Event queue being processed in the same cycle allows - // `preventDefault`. - ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping); - } finally { - TopLevelCallbackBookKeeping.release(bookKeeping); - } - } -}; - -module.exports = ReactEventListener; - -},{"125":125,"131":131,"16":16,"21":21,"27":27,"28":28,"66":66,"70":70,"87":87}],63:[function(_dereq_,module,exports){ -/** - * Copyright 2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * -* @providesModule ReactFragment -*/ - -'use strict'; - -var ReactElement = _dereq_(57); - -var warning = _dereq_(154); - -/** - * We used to allow keyed objects to serve as a collection of ReactElements, - * or nested sets. This allowed us a way to explicitly key a set a fragment of - * components. This is now being replaced with an opaque data structure. - * The upgrade path is to call React.addons.createFragment({ key: value }) to - * create a keyed fragment. The resulting data structure is opaque, for now. - */ - -if ("production" !== "development") { - var fragmentKey = '_reactFragment'; - var didWarnKey = '_reactDidWarn'; - var canWarnForReactFragment = false; - - try { - // Feature test. Don't even try to issue this warning if we can't use - // enumerable: false. - - var dummy = function() { - return 1; - }; - - Object.defineProperty( - {}, - fragmentKey, - {enumerable: false, value: true} - ); - - Object.defineProperty( - {}, - 'key', - {enumerable: true, get: dummy} - ); - - canWarnForReactFragment = true; - } catch (x) { } - - var proxyPropertyAccessWithWarning = function(obj, key) { - Object.defineProperty(obj, key, { - enumerable: true, - get: function() { - ("production" !== "development" ? warning( - this[didWarnKey], - 'A ReactFragment is an opaque type. Accessing any of its ' + - 'properties is deprecated. Pass it to one of the React.Children ' + - 'helpers.' - ) : null); - this[didWarnKey] = true; - return this[fragmentKey][key]; - }, - set: function(value) { - ("production" !== "development" ? warning( - this[didWarnKey], - 'A ReactFragment is an immutable opaque type. Mutating its ' + - 'properties is deprecated.' - ) : null); - this[didWarnKey] = true; - this[fragmentKey][key] = value; - } - }); - }; - - var issuedWarnings = {}; - - var didWarnForFragment = function(fragment) { - // We use the keys and the type of the value as a heuristic to dedupe the - // warning to avoid spamming too much. - var fragmentCacheKey = ''; - for (var key in fragment) { - fragmentCacheKey += key + ':' + (typeof fragment[key]) + ','; - } - var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey]; - issuedWarnings[fragmentCacheKey] = true; - return alreadyWarnedOnce; - }; -} - -var ReactFragment = { - // Wrap a keyed object in an opaque proxy that warns you if you access any - // of its properties. - create: function(object) { - if ("production" !== "development") { - if (typeof object !== 'object' || !object || Array.isArray(object)) { - ("production" !== "development" ? warning( - false, - 'React.addons.createFragment only accepts a single object.', - object - ) : null); - return object; - } - if (ReactElement.isValidElement(object)) { - ("production" !== "development" ? warning( - false, - 'React.addons.createFragment does not accept a ReactElement ' + - 'without a wrapper object.' - ) : null); - return object; - } - if (canWarnForReactFragment) { - var proxy = {}; - Object.defineProperty(proxy, fragmentKey, { - enumerable: false, - value: object - }); - Object.defineProperty(proxy, didWarnKey, { - writable: true, - enumerable: false, - value: false - }); - for (var key in object) { - proxyPropertyAccessWithWarning(proxy, key); - } - Object.preventExtensions(proxy); - return proxy; - } - } - return object; - }, - // Extract the original keyed object from the fragment opaque type. Warn if - // a plain object is passed here. - extract: function(fragment) { - if ("production" !== "development") { - if (canWarnForReactFragment) { - if (!fragment[fragmentKey]) { - ("production" !== "development" ? warning( - didWarnForFragment(fragment), - 'Any use of a keyed object should be wrapped in ' + - 'React.addons.createFragment(object) before being passed as a ' + - 'child.' - ) : null); - return fragment; - } - return fragment[fragmentKey]; - } - } - return fragment; - }, - // Check if this is a fragment and if so, extract the keyed object. If it - // is a fragment-like object, warn that it should be wrapped. Ignore if we - // can't determine what kind of object this is. - extractIfFragment: function(fragment) { - if ("production" !== "development") { - if (canWarnForReactFragment) { - // If it is the opaque type, return the keyed object. - if (fragment[fragmentKey]) { - return fragment[fragmentKey]; - } - // Otherwise, check each property if it has an element, if it does - // it is probably meant as a fragment, so we can warn early. Defer, - // the warning to extract. - for (var key in fragment) { - if (fragment.hasOwnProperty(key) && - ReactElement.isValidElement(fragment[key])) { - // This looks like a fragment object, we should provide an - // early warning. - return ReactFragment.extract(fragment); - } - } - } - } - return fragment; - } -}; - -module.exports = ReactFragment; - -},{"154":154,"57":57}],64:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInjection - */ - -'use strict'; - -var DOMProperty = _dereq_(10); -var EventPluginHub = _dereq_(17); -var ReactComponentEnvironment = _dereq_(36); -var ReactClass = _dereq_(33); -var ReactEmptyComponent = _dereq_(59); -var ReactBrowserEventEmitter = _dereq_(30); -var ReactNativeComponent = _dereq_(73); -var ReactDOMComponent = _dereq_(42); -var ReactPerf = _dereq_(75); -var ReactRootIndex = _dereq_(83); -var ReactUpdates = _dereq_(87); - -var ReactInjection = { - Component: ReactComponentEnvironment.injection, - Class: ReactClass.injection, - DOMComponent: ReactDOMComponent.injection, - DOMProperty: DOMProperty.injection, - EmptyComponent: ReactEmptyComponent.injection, - EventPluginHub: EventPluginHub.injection, - EventEmitter: ReactBrowserEventEmitter.injection, - NativeComponent: ReactNativeComponent.injection, - Perf: ReactPerf.injection, - RootIndex: ReactRootIndex.injection, - Updates: ReactUpdates.injection -}; - -module.exports = ReactInjection; - -},{"10":10,"17":17,"30":30,"33":33,"36":36,"42":42,"59":59,"73":73,"75":75,"83":83,"87":87}],65:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInputSelection - */ - -'use strict'; - -var ReactDOMSelection = _dereq_(50); - -var containsNode = _dereq_(109); -var focusNode = _dereq_(119); -var getActiveElement = _dereq_(121); - -function isInDocument(node) { - return containsNode(document.documentElement, node); -} - -/** - * @ReactInputSelection: React input selection module. Based on Selection.js, - * but modified to be suitable for react and has a couple of bug fixes (doesn't - * assume buttons have range selections allowed). - * Input selection module for React. - */ -var ReactInputSelection = { - - hasSelectionCapabilities: function(elem) { - return elem && ( - ((elem.nodeName === 'INPUT' && elem.type === 'text') || - elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true') - ); - }, - - getSelectionInformation: function() { - var focusedElem = getActiveElement(); - return { - focusedElem: focusedElem, - selectionRange: - ReactInputSelection.hasSelectionCapabilities(focusedElem) ? - ReactInputSelection.getSelection(focusedElem) : - null - }; - }, - - /** - * @restoreSelection: If any selection information was potentially lost, - * restore it. This is useful when performing operations that could remove dom - * nodes and place them back in, resulting in focus being lost. - */ - restoreSelection: function(priorSelectionInformation) { - var curFocusedElem = getActiveElement(); - var priorFocusedElem = priorSelectionInformation.focusedElem; - var priorSelectionRange = priorSelectionInformation.selectionRange; - if (curFocusedElem !== priorFocusedElem && - isInDocument(priorFocusedElem)) { - if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { - ReactInputSelection.setSelection( - priorFocusedElem, - priorSelectionRange - ); - } - focusNode(priorFocusedElem); - } - }, - - /** - * @getSelection: Gets the selection bounds of a focused textarea, input or - * contentEditable node. - * -@input: Look up selection bounds of this input - * -@return {start: selectionStart, end: selectionEnd} - */ - getSelection: function(input) { - var selection; - - if ('selectionStart' in input) { - // Modern browser with input or textarea. - selection = { - start: input.selectionStart, - end: input.selectionEnd - }; - } else if (document.selection && input.nodeName === 'INPUT') { - // IE8 input. - var range = document.selection.createRange(); - // There can only be one selection per document in IE, so it must - // be in our element. - if (range.parentElement() === input) { - selection = { - start: -range.moveStart('character', -input.value.length), - end: -range.moveEnd('character', -input.value.length) - }; - } - } else { - // Content editable or old IE textarea. - selection = ReactDOMSelection.getOffsets(input); - } - - return selection || {start: 0, end: 0}; - }, - - /** - * @setSelection: Sets the selection bounds of a textarea or input and focuses - * the input. - * -@input Set selection bounds of this input or textarea - * -@offsets Object of same form that is returned from get* - */ - setSelection: function(input, offsets) { - var start = offsets.start; - var end = offsets.end; - if (typeof end === 'undefined') { - end = start; - } - - if ('selectionStart' in input) { - input.selectionStart = start; - input.selectionEnd = Math.min(end, input.value.length); - } else if (document.selection && input.nodeName === 'INPUT') { - var range = input.createTextRange(); - range.collapse(true); - range.moveStart('character', start); - range.moveEnd('character', end - start); - range.select(); - } else { - ReactDOMSelection.setOffsets(input, offsets); - } - } -}; - -module.exports = ReactInputSelection; - -},{"109":109,"119":119,"121":121,"50":50}],66:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInstanceHandles - * @typechecks static-only - */ - -'use strict'; - -var ReactRootIndex = _dereq_(83); - -var invariant = _dereq_(135); - -var SEPARATOR = '.'; -var SEPARATOR_LENGTH = SEPARATOR.length; - -/** - * Maximum depth of traversals before we consider the possibility of a bad ID. - */ -var MAX_TREE_DEPTH = 100; - -/** - * Creates a DOM ID prefix to use when mounting React components. - * - * @param {number} index A unique integer - * @return {string} React root ID. - * @internal - */ -function getReactRootIDString(index) { - return SEPARATOR + index.toString(36); -} - -/** - * Checks if a character in the supplied ID is a separator or the end. - * - * @param {string} id A React DOM ID. - * @param {number} index Index of the character to check. - * @return {boolean} True if the character is a separator or end of the ID. - * @private - */ -function isBoundary(id, index) { - return id.charAt(index) === SEPARATOR || index === id.length; -} - -/** - * Checks if the supplied string is a valid React DOM ID. - * - * @param {string} id A React DOM ID, maybe. - * @return {boolean} True if the string is a valid React DOM ID. - * @private - */ -function isValidID(id) { - return id === '' || ( - id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR - ); -} - -/** - * Checks if the first ID is an ancestor of or equal to the second ID. - * - * @param {string} ancestorID - * @param {string} descendantID - * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. - * @internal - */ -function isAncestorIDOf(ancestorID, descendantID) { - return ( - descendantID.indexOf(ancestorID) === 0 && - isBoundary(descendantID, ancestorID.length) - ); -} - -/** - * Gets the parent ID of the supplied React DOM ID, `id`. - * - * @param {string} id ID of a component. - * @return {string} ID of the parent, or an empty string. - * @private - */ -function getParentID(id) { - return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; -} - -/** - * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the - * supplied `destinationID`. If they are equal, the ID is returned. - * - * @param {string} ancestorID ID of an ancestor node of `destinationID`. - * @param {string} destinationID ID of the destination node. - * @return {string} Next ID on the path from `ancestorID` to `destinationID`. - * @private - */ -function getNextDescendantID(ancestorID, destinationID) { - ("production" !== "development" ? invariant( - isValidID(ancestorID) && isValidID(destinationID), - 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', - ancestorID, - destinationID - ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); - ("production" !== "development" ? invariant( - isAncestorIDOf(ancestorID, destinationID), - 'getNextDescendantID(...): React has made an invalid assumption about ' + - 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', - ancestorID, - destinationID - ) : invariant(isAncestorIDOf(ancestorID, destinationID))); - if (ancestorID === destinationID) { - return ancestorID; - } - // Skip over the ancestor and the immediate separator. Traverse until we hit - // another separator or we reach the end of `destinationID`. - var start = ancestorID.length + SEPARATOR_LENGTH; - var i; - for (i = start; i < destinationID.length; i++) { - if (isBoundary(destinationID, i)) { - break; - } - } - return destinationID.substr(0, i); -} - -/** - * Gets the nearest common ancestor ID of two IDs. - * - * Using this ID scheme, the nearest common ancestor ID is the longest common - * prefix of the two IDs that immediately preceded a "marker" in both strings. - * - * @param {string} oneID - * @param {string} twoID - * @return {string} Nearest common ancestor ID, or the empty string if none. - * @private - */ -function getFirstCommonAncestorID(oneID, twoID) { - var minLength = Math.min(oneID.length, twoID.length); - if (minLength === 0) { - return ''; - } - var lastCommonMarkerIndex = 0; - // Use `<=` to traverse until the "EOL" of the shorter string. - for (var i = 0; i <= minLength; i++) { - if (isBoundary(oneID, i) && isBoundary(twoID, i)) { - lastCommonMarkerIndex = i; - } else if (oneID.charAt(i) !== twoID.charAt(i)) { - break; - } - } - var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); - ("production" !== "development" ? invariant( - isValidID(longestCommonID), - 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', - oneID, - twoID, - longestCommonID - ) : invariant(isValidID(longestCommonID))); - return longestCommonID; -} - -/** - * Traverses the parent path between two IDs (either up or down). The IDs must - * not be the same, and there must exist a parent path between them. If the - * callback returns `false`, traversal is stopped. - * - * @param {?string} start ID at which to start traversal. - * @param {?string} stop ID at which to end traversal. - * @param {function} cb Callback to invoke each ID with. - * @param {?boolean} skipFirst Whether or not to skip the first node. - * @param {?boolean} skipLast Whether or not to skip the last node. - * @private - */ -function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { - start = start || ''; - stop = stop || ''; - ("production" !== "development" ? invariant( - start !== stop, - 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', - start - ) : invariant(start !== stop)); - var traverseUp = isAncestorIDOf(stop, start); - ("production" !== "development" ? invariant( - traverseUp || isAncestorIDOf(start, stop), - 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + - 'not have a parent path.', - start, - stop - ) : invariant(traverseUp || isAncestorIDOf(start, stop))); - // Traverse from `start` to `stop` one depth at a time. - var depth = 0; - var traverse = traverseUp ? getParentID : getNextDescendantID; - for (var id = start; /* until break */; id = traverse(id, stop)) { - var ret; - if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { - ret = cb(id, traverseUp, arg); - } - if (ret === false || id === stop) { - // Only break //after// visiting `stop`. - break; - } - ("production" !== "development" ? invariant( - depth++ < MAX_TREE_DEPTH, - 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + - 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', - start, stop - ) : invariant(depth++ < MAX_TREE_DEPTH)); - } -} - -/** - * Manages the IDs assigned to DOM representations of React components. This - * uses a specific scheme in order to traverse the DOM efficiently (e.g. in - * order to simulate events). - * - * @internal - */ -var ReactInstanceHandles = { - - /** - * Constructs a React root ID - * @return {string} A React root ID. - */ - createReactRootID: function() { - return getReactRootIDString(ReactRootIndex.createReactRootIndex()); - }, - - /** - * Constructs a React ID by joining a root ID with a name. - * - * @param {string} rootID Root ID of a parent component. - * @param {string} name A component's name (as flattened children). - * @return {string} A React ID. - * @internal - */ - createReactID: function(rootID, name) { - return rootID + name; - }, - - /** - * Gets the DOM ID of the React component that is the root of the tree that - * contains the React component with the supplied DOM ID. - * - * @param {string} id DOM ID of a React component. - * @return {?string} DOM ID of the React component that is the root. - * @internal - */ - getReactRootIDFromNodeID: function(id) { - if (id && id.charAt(0) === SEPARATOR && id.length > 1) { - var index = id.indexOf(SEPARATOR, 1); - return index > -1 ? id.substr(0, index) : id; - } - return null; - }, - - /** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * NOTE: Does not invoke the callback on the nearest common ancestor because - * nothing "entered" or "left" that element. - * - * @param {string} leaveID ID being left. - * @param {string} enterID ID being entered. - * @param {function} cb Callback to invoke on each entered/left ID. - * @param {*} upArg Argument to invoke the callback with on left IDs. - * @param {*} downArg Argument to invoke the callback with on entered IDs. - * @internal - */ - traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { - var ancestorID = getFirstCommonAncestorID(leaveID, enterID); - if (ancestorID !== leaveID) { - traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); - } - if (ancestorID !== enterID) { - traverseParentPath(ancestorID, enterID, cb, downArg, true, false); - } - }, - - /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseTwoPhase: function(targetID, cb, arg) { - if (targetID) { - traverseParentPath('', targetID, cb, arg, true, false); - traverseParentPath(targetID, '', cb, arg, false, true); - } - }, - - /** - * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For - * example, passing `.0.$row-0.1` would result in `cb` getting called - * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseAncestors: function(targetID, cb, arg) { - traverseParentPath('', targetID, cb, arg, true, false); - }, - - /** - * Exposed for unit testing. - * @private - */ - _getFirstCommonAncestorID: getFirstCommonAncestorID, - - /** - * Exposed for unit testing. - * @private - */ - _getNextDescendantID: getNextDescendantID, - - isAncestorIDOf: isAncestorIDOf, - - SEPARATOR: SEPARATOR - -}; - -module.exports = ReactInstanceHandles; - -},{"135":135,"83":83}],67:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactInstanceMap - */ - -'use strict'; - -/** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. - */ - -// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); -var ReactInstanceMap = { - - /** - * This API should be called `delete` but we'd have to make sure to always - * transform these to strings for IE support. When this transform is fully - * supported we can rename it. - */ - remove: function(key) { - key._reactInternalInstance = undefined; - }, - - get: function(key) { - return key._reactInternalInstance; - }, - - has: function(key) { - return key._reactInternalInstance !== undefined; - }, - - set: function(key, value) { - key._reactInternalInstance = value; - } - -}; - -module.exports = ReactInstanceMap; - -},{}],68:[function(_dereq_,module,exports){ -/** - * Copyright 2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactLifeCycle - */ - -'use strict'; - -/** - * This module manages the bookkeeping when a component is in the process - * of being mounted or being unmounted. This is used as a way to enforce - * invariants (or warnings) when it is not recommended to call - * setState/forceUpdate. - * - * currentlyMountingInstance: During the construction phase, it is not possible - * to trigger an update since the instance is not fully mounted yet. However, we - * currently allow this as a convenience for mutating the initial state. - * - * currentlyUnmountingInstance: During the unmounting phase, the instance is - * still mounted and can therefore schedule an update. However, this is not - * recommended and probably an error since it's about to be unmounted. - * Therefore we still want to trigger in an error for that case. - */ - -var ReactLifeCycle = { - currentlyMountingInstance: null, - currentlyUnmountingInstance: null -}; - -module.exports = ReactLifeCycle; - -},{}],69:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMarkupChecksum - */ - -'use strict'; - -var adler32 = _dereq_(106); - -var ReactMarkupChecksum = { - CHECKSUM_ATTR_NAME: 'data-react-checksum', - - /** - * @param {string} markup Markup string - * @return {string} Markup string with checksum attribute attached - */ - addChecksumToMarkup: function(markup) { - var checksum = adler32(markup); - return markup.replace( - '>', - ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' - ); - }, - - /** - * @param {string} markup to use - * @param {DOMElement} element root React element - * @returns {boolean} whether or not the markup is the same - */ - canReuseMarkup: function(markup, element) { - var existingChecksum = element.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - existingChecksum = existingChecksum && parseInt(existingChecksum, 10); - var markupChecksum = adler32(markup); - return markupChecksum === existingChecksum; - } -}; - -module.exports = ReactMarkupChecksum; - -},{"106":106}],70:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMount - */ - -'use strict'; - -var DOMProperty = _dereq_(10); -var ReactBrowserEventEmitter = _dereq_(30); -var ReactCurrentOwner = _dereq_(39); -var ReactElement = _dereq_(57); -var ReactElementValidator = _dereq_(58); -var ReactEmptyComponent = _dereq_(59); -var ReactInstanceHandles = _dereq_(66); -var ReactInstanceMap = _dereq_(67); -var ReactMarkupChecksum = _dereq_(69); -var ReactPerf = _dereq_(75); -var ReactReconciler = _dereq_(81); -var ReactUpdateQueue = _dereq_(86); -var ReactUpdates = _dereq_(87); - -var emptyObject = _dereq_(115); -var containsNode = _dereq_(109); -var getReactRootElementInContainer = _dereq_(129); -var instantiateReactComponent = _dereq_(134); -var invariant = _dereq_(135); -var setInnerHTML = _dereq_(148); -var shouldUpdateReactComponent = _dereq_(151); -var warning = _dereq_(154); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var nodeCache = {}; - -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; - -/** Mapping from reactRootID to React component instance. */ -var instancesByReactRootID = {}; - -/** Mapping from reactRootID to `container` nodes. */ -var containersByReactRootID = {}; - -if ("production" !== "development") { - /** __DEV__-only mapping from reactRootID to root elements. */ - var rootElementsByReactRootID = {}; -} - -// Used to store breadth-first search state in findComponentRoot. -var findComponentRootReusableArray = []; - -/** - * Finds the index of the first character - * that's not common between the two given strings. - * - * @return {number} the index of the character where the strings diverge - */ -function firstDifferenceIndex(string1, string2) { - var minLen = Math.min(string1.length, string2.length); - for (var i = 0; i < minLen; i++) { - if (string1.charAt(i) !== string2.charAt(i)) { - return i; - } - } - return string1.length === string2.length ? -1 : minLen; -} - -/** - * @param {DOMElement} container DOM element that may contain a React component. - * @return {?string} A "reactRoot" ID, if a React component is rendered. - */ -function getReactRootID(container) { - var rootElement = getReactRootElementInContainer(container); - return rootElement && ReactMount.getID(rootElement); -} - -/** - * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form - * element can return its control whose name or ID equals ATTR_NAME. All - * DOM nodes support `getAttributeNode` but this can also get called on - * other objects so just return '' if we're given something other than a - * DOM node (such as window). - * - * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. - * @return {string} ID of the supplied `domNode`. - */ -function getID(node) { - var id = internalGetID(node); - if (id) { - if (nodeCache.hasOwnProperty(id)) { - var cached = nodeCache[id]; - if (cached !== node) { - ("production" !== "development" ? invariant( - !isValid(cached, id), - 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', - ATTR_NAME, id - ) : invariant(!isValid(cached, id))); - - nodeCache[id] = node; - } - } else { - nodeCache[id] = node; - } - } - - return id; -} - -function internalGetID(node) { - // If node is something like a window, document, or text node, none of - // which support attributes or a .getAttribute method, gracefully return - // the empty string, as if the attribute were missing. - return node && node.getAttribute && node.getAttribute(ATTR_NAME) || ''; -} - -/** - * Sets the React-specific ID of the given node. - * - * @param {DOMElement} node The DOM node whose ID will be set. - * @param {string} id The value of the ID attribute. - */ -function setID(node, id) { - var oldID = internalGetID(node); - if (oldID !== id) { - delete nodeCache[oldID]; - } - node.setAttribute(ATTR_NAME, id); - nodeCache[id] = node; -} - -/** - * Finds the node with the supplied React-generated DOM ID. - * - * @param {string} id A React-generated DOM ID. - * @return {DOMElement} DOM node with the suppled `id`. - * @internal - */ -function getNode(id) { - if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { - nodeCache[id] = ReactMount.findReactNodeByID(id); - } - return nodeCache[id]; -} - -/** - * Finds the node with the supplied public React instance. - * - * @param {*} instance A public React instance. - * @return {?DOMElement} DOM node with the suppled `id`. - * @internal - */ -function getNodeFromInstance(instance) { - var id = ReactInstanceMap.get(instance)._rootNodeID; - if (ReactEmptyComponent.isNullComponentID(id)) { - return null; - } - if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { - nodeCache[id] = ReactMount.findReactNodeByID(id); - } - return nodeCache[id]; -} - -/** - * A node is "valid" if it is contained by a currently mounted container. - * - * This means that the node does not have to be contained by a document in - * order to be considered valid. - * - * @param {?DOMElement} node The candidate DOM node. - * @param {string} id The expected ID of the node. - * @return {boolean} Whether the node is contained by a mounted container. - */ -function isValid(node, id) { - if (node) { - ("production" !== "development" ? invariant( - internalGetID(node) === id, - 'ReactMount: Unexpected modification of `%s`', - ATTR_NAME - ) : invariant(internalGetID(node) === id)); - - var container = ReactMount.findReactContainerForID(id); - if (container && containsNode(container, node)) { - return true; - } - } - - return false; -} - -/** - * Causes the cache to forget about one React-specific ID. - * - * @param {string} id The ID to forget. - */ -function purgeID(id) { - delete nodeCache[id]; -} - -var deepestNodeSoFar = null; -function findDeepestCachedAncestorImpl(ancestorID) { - var ancestor = nodeCache[ancestorID]; - if (ancestor && isValid(ancestor, ancestorID)) { - deepestNodeSoFar = ancestor; - } else { - // This node isn't populated in the cache, so presumably none of its - // descendants are. Break out of the loop. - return false; - } -} - -/** - * Return the deepest cached node whose ID is a prefix of `targetID`. - */ -function findDeepestCachedAncestor(targetID) { - deepestNodeSoFar = null; - ReactInstanceHandles.traverseAncestors( - targetID, - findDeepestCachedAncestorImpl - ); - - var foundNode = deepestNodeSoFar; - deepestNodeSoFar = null; - return foundNode; -} - -/** - * Mounts this component and inserts it into the DOM. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function mountComponentIntoNode( - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup) { - var markup = ReactReconciler.mountComponent( - componentInstance, rootID, transaction, emptyObject - ); - componentInstance._isTopLevel = true; - ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup); -} - -/** - * Batched mount. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function batchedMountComponentIntoNode( - componentInstance, - rootID, - container, - shouldReuseMarkup) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - transaction.perform( - mountComponentIntoNode, - null, - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup - ); - ReactUpdates.ReactReconcileTransaction.release(transaction); -} - -/** - * Mounting is the process of initializing a React component by creating its - * representative DOM elements and inserting them into a supplied `container`. - * Any prior content inside `container` is destroyed in the process. - * - * ReactMount.render( - * component, - * document.getElementById('container') - * ); - * - * <div id="container"> <-- Supplied `container`. - * <div data-reactid=".3"> <-- Rendered reactRoot of React - * // ... component. - * </div> - * </div> - * - * Inside of `container`, the first element rendered is the "reactRoot". - */ -var ReactMount = { - /** Exposed for debugging purposes **/ - _instancesByReactRootID: instancesByReactRootID, - - /** - * This is a hook provided to support rendering React components while - * ensuring that the apparent scroll position of its `container` does not - * change. - * - * @param {DOMElement} container The `container` being rendered into. - * @param {function} renderCallback This must be called once to do the render. - */ - scrollMonitor: function(container, renderCallback) { - renderCallback(); - }, - - /** - * Take a component that's already mounted into the DOM and replace its props - * @param {ReactComponent} prevComponent component instance already in the DOM - * @param {ReactElement} nextElement component instance to render - * @param {DOMElement} container container to render into - * @param {?function} callback function triggered on completion - */ - _updateRootComponent: function( - prevComponent, - nextElement, - container, - callback) { - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - ReactMount.scrollMonitor(container, function() { - ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); - } - }); - - if ("production" !== "development") { - // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[getReactRootID(container)] = - getReactRootElementInContainer(container); - } - - return prevComponent; - }, - - /** - * Register a component into the instance map and starts scroll value - * monitoring - * @param {ReactComponent} nextComponent component instance to render - * @param {DOMElement} container container to render into - * @return {string} reactRoot ID prefix - */ - _registerComponent: function(nextComponent, container) { - ("production" !== "development" ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - '_registerComponent(...): Target container is not a DOM element.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); - - ReactBrowserEventEmitter.ensureScrollValueMonitoring(); - - var reactRootID = ReactMount.registerContainer(container); - instancesByReactRootID[reactRootID] = nextComponent; - return reactRootID; - }, - - /** - * Render a new component into the DOM. - * @param {ReactElement} nextElement element to render - * @param {DOMElement} container container to render into - * @param {boolean} shouldReuseMarkup if we should skip the markup insertion - * @return {ReactComponent} nextComponent - */ - _renderNewRootComponent: function( - nextElement, - container, - shouldReuseMarkup - ) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. - ("production" !== "development" ? warning( - ReactCurrentOwner.current == null, - '_renderNewRootComponent(): Render methods should be a pure function ' + - 'of props and state; triggering nested component updates from ' + - 'render is not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - var componentInstance = instantiateReactComponent(nextElement, null); - var reactRootID = ReactMount._registerComponent( - componentInstance, - container - ); - - // The initial render is synchronous but any updates that happen during - // rendering, in componentWillMount or componentDidMount, will be batched - // according to the current batching strategy. - - ReactUpdates.batchedUpdates( - batchedMountComponentIntoNode, - componentInstance, - reactRootID, - container, - shouldReuseMarkup - ); - - if ("production" !== "development") { - // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[reactRootID] = - getReactRootElementInContainer(container); - } - - return componentInstance; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - render: function(nextElement, container, callback) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(nextElement), - 'React.render(): Invalid component element.%s', - ( - typeof nextElement === 'string' ? - ' Instead of passing an element string, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - typeof nextElement === 'function' ? - ' Instead of passing a component class, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - // Check if it quacks like an element - nextElement != null && nextElement.props !== undefined ? - ' This may be caused by unintentionally loading two independent ' + - 'copies of React.' : - '' - ) - ) : invariant(ReactElement.isValidElement(nextElement))); - - var prevComponent = instancesByReactRootID[getReactRootID(container)]; - - if (prevComponent) { - var prevElement = prevComponent._currentElement; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - return ReactMount._updateRootComponent( - prevComponent, - nextElement, - container, - callback - ).getPublicInstance(); - } else { - ReactMount.unmountComponentAtNode(container); - } - } - - var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = - reactRootElement && ReactMount.isRenderedByReact(reactRootElement); - - if ("production" !== "development") { - if (!containerHasReactMarkup || reactRootElement.nextSibling) { - var rootElementSibling = reactRootElement; - while (rootElementSibling) { - if (ReactMount.isRenderedByReact(rootElementSibling)) { - ("production" !== "development" ? warning( - false, - 'render(): Target node has markup rendered by React, but there ' + - 'are unrelated nodes as well. This is most commonly caused by ' + - 'white-space inserted around server-rendered markup.' - ) : null); - break; - } - - rootElementSibling = rootElementSibling.nextSibling; - } - } - } - - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; - - var component = ReactMount._renderNewRootComponent( - nextElement, - container, - shouldReuseMarkup - ).getPublicInstance(); - if (callback) { - callback.call(component); - } - return component; - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into the supplied `container`. - * - * @param {function} constructor React component constructor. - * @param {?object} props Initial props of the component instance. - * @param {DOMElement} container DOM element to render into. - * @return {ReactComponent} Component instance rendered in `container`. - */ - constructAndRenderComponent: function(constructor, props, container) { - var element = ReactElement.createElement(constructor, props); - return ReactMount.render(element, container); - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into a container node identified by supplied `id`. - * - * @param {function} componentConstructor React component constructor - * @param {?object} props Initial props of the component instance. - * @param {string} id ID of the DOM element to render into. - * @return {ReactComponent} Component instance rendered in the container node. - */ - constructAndRenderComponentByID: function(constructor, props, id) { - var domNode = document.getElementById(id); - ("production" !== "development" ? invariant( - domNode, - 'Tried to get element with id of "%s" but it is not present on the page.', - id - ) : invariant(domNode)); - return ReactMount.constructAndRenderComponent(constructor, props, domNode); - }, - - /** - * Registers a container node into which React components will be rendered. - * This also creates the "reactRoot" ID that will be assigned to the element - * rendered within. - * - * @param {DOMElement} container DOM element to register as a container. - * @return {string} The "reactRoot" ID of elements rendered within. - */ - registerContainer: function(container) { - var reactRootID = getReactRootID(container); - if (reactRootID) { - // If one exists, make sure it is a valid "reactRoot" ID. - reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); - } - if (!reactRootID) { - // No valid "reactRoot" ID found, create one. - reactRootID = ReactInstanceHandles.createReactRootID(); - } - containersByReactRootID[reactRootID] = container; - return reactRootID; - }, - - /** - * Unmounts and destroys the React component rendered in the `container`. - * - * @param {DOMElement} container DOM element containing a React component. - * @return {boolean} True if a component was found in and unmounted from - * `container` - */ - unmountComponentAtNode: function(container) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (Strictly speaking, unmounting won't cause a - // render but we still don't expect to be in a render call here.) - ("production" !== "development" ? warning( - ReactCurrentOwner.current == null, - 'unmountComponentAtNode(): Render methods should be a pure function of ' + - 'props and state; triggering nested component updates from render is ' + - 'not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - ("production" !== "development" ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - 'unmountComponentAtNode(...): Target container is not a DOM element.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); - - var reactRootID = getReactRootID(container); - var component = instancesByReactRootID[reactRootID]; - if (!component) { - return false; - } - ReactMount.unmountComponentFromNode(component, container); - delete instancesByReactRootID[reactRootID]; - delete containersByReactRootID[reactRootID]; - if ("production" !== "development") { - delete rootElementsByReactRootID[reactRootID]; - } - return true; - }, - - /** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ - unmountComponentFromNode: function(instance, container) { - ReactReconciler.unmountComponent(instance); - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } - }, - - /** - * Finds the container DOM element that contains React component to which the - * supplied DOM `id` belongs. - * - * @param {string} id The ID of an element rendered by a React component. - * @return {?DOMElement} DOM element that contains the `id`. - */ - findReactContainerForID: function(id) { - var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); - var container = containersByReactRootID[reactRootID]; - - if ("production" !== "development") { - var rootElement = rootElementsByReactRootID[reactRootID]; - if (rootElement && rootElement.parentNode !== container) { - ("production" !== "development" ? invariant( - // Call internalGetID here because getID calls isValid which calls - // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID, - 'ReactMount: Root element ID differed from reactRootID.' - ) : invariant(// Call internalGetID here because getID calls isValid which calls - // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID)); - - var containerChild = container.firstChild; - if (containerChild && - reactRootID === internalGetID(containerChild)) { - // If the container has a new child with the same ID as the old - // root element, then rootElementsByReactRootID[reactRootID] is - // just stale and needs to be updated. The case that deserves a - // warning is when the container is empty. - rootElementsByReactRootID[reactRootID] = containerChild; - } else { - ("production" !== "development" ? warning( - false, - 'ReactMount: Root element has been removed from its original ' + - 'container. New container:', rootElement.parentNode - ) : null); - } - } - } - - return container; - }, - - /** - * Finds an element rendered by React with the supplied ID. - * - * @param {string} id ID of a DOM node in the React component. - * @return {DOMElement} Root DOM node of the React component. - */ - findReactNodeByID: function(id) { - var reactRoot = ReactMount.findReactContainerForID(id); - return ReactMount.findComponentRoot(reactRoot, id); - }, - - /** - * True if the supplied `node` is rendered by React. - * - * @param {*} node DOM Element to check. - * @return {boolean} True if the DOM Element appears to be rendered by React. - * @internal - */ - isRenderedByReact: function(node) { - if (node.nodeType !== 1) { - // Not a DOMElement, therefore not a React component - return false; - } - var id = ReactMount.getID(node); - return id ? id.charAt(0) === SEPARATOR : false; - }, - - /** - * Traverses up the ancestors of the supplied node to find a node that is a - * DOM representation of a React component. - * - * @param {*} node - * @return {?DOMEventTarget} - * @internal - */ - getFirstReactDOM: function(node) { - var current = node; - while (current && current.parentNode !== current) { - if (ReactMount.isRenderedByReact(current)) { - return current; - } - current = current.parentNode; - } - return null; - }, - - /** - * Finds a node with the supplied `targetID` inside of the supplied - * `ancestorNode`. Exploits the ID naming scheme to perform the search - * quickly. - * - * @param {DOMEventTarget} ancestorNode Search from this root. - * @pararm {string} targetID ID of the DOM representation of the component. - * @return {DOMEventTarget} DOM node with the supplied `targetID`. - * @internal - */ - findComponentRoot: function(ancestorNode, targetID) { - var firstChildren = findComponentRootReusableArray; - var childIndex = 0; - - var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; - - firstChildren[0] = deepestAncestor.firstChild; - firstChildren.length = 1; - - while (childIndex < firstChildren.length) { - var child = firstChildren[childIndex++]; - var targetChild; - - while (child) { - var childID = ReactMount.getID(child); - if (childID) { - // Even if we find the node we're looking for, we finish looping - // through its siblings to ensure they're cached so that we don't have - // to revisit this node again. Otherwise, we make n^2 calls to getID - // when visiting the many children of a single node in order. - - if (targetID === childID) { - targetChild = child; - } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { - // If we find a child whose ID is an ancestor of the given ID, - // then we can be sure that we only want to search the subtree - // rooted at this child, so we can throw out the rest of the - // search state. - firstChildren.length = childIndex = 0; - firstChildren.push(child.firstChild); - } - - } else { - // If this child had no ID, then there's a chance that it was - // injected automatically by the browser, as when a `<table>` - // element sprouts an extra `<tbody>` child as a side effect of - // `.innerHTML` parsing. Optimistically continue down this - // branch, but not before examining the other siblings. - firstChildren.push(child.firstChild); - } - - child = child.nextSibling; - } - - if (targetChild) { - // Emptying firstChildren/findComponentRootReusableArray is - // not necessary for correctness, but it helps the GC reclaim - // any nodes that were left at the end of the search. - firstChildren.length = 0; - - return targetChild; - } - } - - firstChildren.length = 0; - - ("production" !== "development" ? invariant( - false, - 'findComponentRoot(..., %s): Unable to find element. This probably ' + - 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + - 'usually due to forgetting a <tbody> when using tables, nesting tags ' + - 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + - 'parent. ' + - 'Try inspecting the child nodes of the element with React ID `%s`.', - targetID, - ReactMount.getID(ancestorNode) - ) : invariant(false)); - }, - - _mountImageIntoNode: function(markup, container, shouldReuseMarkup) { - ("production" !== "development" ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - 'mountComponentIntoNode(...): Target container is not valid.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); - - if (shouldReuseMarkup) { - var rootElement = getReactRootElementInContainer(container); - if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { - return; - } else { - var checksum = rootElement.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - - var rootMarkup = rootElement.outerHTML; - rootElement.setAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME, - checksum - ); - - var diffIndex = firstDifferenceIndex(markup, rootMarkup); - var difference = ' (client) ' + - markup.substring(diffIndex - 20, diffIndex + 20) + - '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); - - ("production" !== "development" ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document using ' + - 'server rendering but the checksum was invalid. This usually ' + - 'means you rendered a different component type or props on ' + - 'the client from the one on the server, or your render() ' + - 'methods are impure. React cannot handle this case due to ' + - 'cross-browser quirks by rendering at the document root. You ' + - 'should look for environment dependent code in your components ' + - 'and ensure the props are the same client and server side:\n%s', - difference - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); - - if ("production" !== "development") { - ("production" !== "development" ? warning( - false, - 'React attempted to reuse markup in a container but the ' + - 'checksum was invalid. This generally means that you are ' + - 'using server rendering and the markup generated on the ' + - 'server was not what the client was expecting. React injected ' + - 'new markup to compensate which works but you have lost many ' + - 'of the benefits of server rendering. Instead, figure out ' + - 'why the markup being generated is different on the client ' + - 'or server:\n%s', - difference - ) : null); - } - } - } - - ("production" !== "development" ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document but ' + - 'you didn\'t use server rendering. We can\'t do this ' + - 'without using server rendering due to cross-browser quirks. ' + - 'See React.renderToString() for server rendering.' - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); - - setInnerHTML(container, markup); - }, - - /** - * React ID utilities. - */ - - getReactRootID: getReactRootID, - - getID: getID, - - setID: setID, - - getNode: getNode, - - getNodeFromInstance: getNodeFromInstance, - - purgeID: purgeID -}; - -ReactPerf.measureMethods(ReactMount, 'ReactMount', { - _renderNewRootComponent: '_renderNewRootComponent', - _mountImageIntoNode: '_mountImageIntoNode' -}); - -module.exports = ReactMount; - -},{"10":10,"109":109,"115":115,"129":129,"134":134,"135":135,"148":148,"151":151,"154":154,"30":30,"39":39,"57":57,"58":58,"59":59,"66":66,"67":67,"69":69,"75":75,"81":81,"86":86,"87":87}],71:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMultiChild - * @typechecks static-only - */ - -'use strict'; - -var ReactComponentEnvironment = _dereq_(36); -var ReactMultiChildUpdateTypes = _dereq_(72); - -var ReactReconciler = _dereq_(81); -var ReactChildReconciler = _dereq_(31); - -/** - * Updating children of a component may trigger recursive updates. The depth is - * used to batch recursive updates to render markup more efficiently. - * - * @type {number} - * @private - */ -var updateDepth = 0; - -/** - * Queue of update configuration objects. - * - * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`. - * - * @type {array<object>} - * @private - */ -var updateQueue = []; - -/** - * Queue of markup to be rendered. - * - * @type {array<string>} - * @private - */ -var markupQueue = []; - -/** - * Enqueues markup to be rendered and inserted at a supplied index. - * - * @param {string} parentID ID of the parent component. - * @param {string} markup Markup that renders into an element. - * @param {number} toIndex Destination index. - * @private - */ -function enqueueMarkup(parentID, markup, toIndex) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.INSERT_MARKUP, - markupIndex: markupQueue.push(markup) - 1, - textContent: null, - fromIndex: null, - toIndex: toIndex - }); -} - -/** - * Enqueues moving an existing element to another index. - * - * @param {string} parentID ID of the parent component. - * @param {number} fromIndex Source index of the existing element. - * @param {number} toIndex Destination index of the element. - * @private - */ -function enqueueMove(parentID, fromIndex, toIndex) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.MOVE_EXISTING, - markupIndex: null, - textContent: null, - fromIndex: fromIndex, - toIndex: toIndex - }); -} - -/** - * Enqueues removing an element at an index. - * - * @param {string} parentID ID of the parent component. - * @param {number} fromIndex Index of the element to remove. - * @private - */ -function enqueueRemove(parentID, fromIndex) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.REMOVE_NODE, - markupIndex: null, - textContent: null, - fromIndex: fromIndex, - toIndex: null - }); -} - -/** - * Enqueues setting the text content. - * - * @param {string} parentID ID of the parent component. - * @param {string} textContent Text content to set. - * @private - */ -function enqueueTextContent(parentID, textContent) { - // NOTE: Null values reduce hidden classes. - updateQueue.push({ - parentID: parentID, - parentNode: null, - type: ReactMultiChildUpdateTypes.TEXT_CONTENT, - markupIndex: null, - textContent: textContent, - fromIndex: null, - toIndex: null - }); -} - -/** - * Processes any enqueued updates. - * - * @private - */ -function processQueue() { - if (updateQueue.length) { - ReactComponentEnvironment.processChildrenUpdates( - updateQueue, - markupQueue - ); - clearQueue(); - } -} - -/** - * Clears any enqueued updates. - * - * @private - */ -function clearQueue() { - updateQueue.length = 0; - markupQueue.length = 0; -} - -/** - * ReactMultiChild are capable of reconciling multiple children. - * - * @class ReactMultiChild - * @internal - */ -var ReactMultiChild = { - - /** - * Provides common functionality for components that must reconcile multiple - * children. This is used by `ReactDOMComponent` to mount, update, and - * unmount child components. - * - * @lends {ReactMultiChild.prototype} - */ - Mixin: { - - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildren Nested child maps. - * @return {array} An array of mounted representations. - * @internal - */ - mountChildren: function(nestedChildren, transaction, context) { - var children = ReactChildReconciler.instantiateChildren( - nestedChildren, transaction, context - ); - this._renderedChildren = children; - var mountImages = []; - var index = 0; - for (var name in children) { - if (children.hasOwnProperty(name)) { - var child = children[name]; - // Inlined for performance, see `ReactInstanceHandles.createReactID`. - var rootID = this._rootNodeID + name; - var mountImage = ReactReconciler.mountComponent( - child, - rootID, - transaction, - context - ); - child._mountIndex = index; - mountImages.push(mountImage); - index++; - } - } - return mountImages; - }, - - /** - * Replaces any rendered children with a text content string. - * - * @param {string} nextContent String of content. - * @internal - */ - updateTextContent: function(nextContent) { - updateDepth++; - var errorThrown = true; - try { - var prevChildren = this._renderedChildren; - // Remove any rendered children. - ReactChildReconciler.unmountChildren(prevChildren); - // TODO: The setTextContent operation should be enough - for (var name in prevChildren) { - if (prevChildren.hasOwnProperty(name)) { - this._unmountChildByName(prevChildren[name], name); - } - } - // Set new text content. - this.setTextContent(nextContent); - errorThrown = false; - } finally { - updateDepth--; - if (!updateDepth) { - if (errorThrown) { - clearQueue(); - } else { - processQueue(); - } - } - } - }, - - /** - * Updates the rendered children with new children. - * - * @param {?object} nextNestedChildren Nested child maps. - * @param {ReactReconcileTransaction} transaction - * @internal - */ - updateChildren: function(nextNestedChildren, transaction, context) { - updateDepth++; - var errorThrown = true; - try { - this._updateChildren(nextNestedChildren, transaction, context); - errorThrown = false; - } finally { - updateDepth--; - if (!updateDepth) { - if (errorThrown) { - clearQueue(); - } else { - processQueue(); - } - } - - } - }, - - /** - * Improve performance by isolating this hot code path from the try/catch - * block in `updateChildren`. - * - * @param {?object} nextNestedChildren Nested child maps. - * @param {ReactReconcileTransaction} transaction - * @final - * @protected - */ - _updateChildren: function(nextNestedChildren, transaction, context) { - var prevChildren = this._renderedChildren; - var nextChildren = ReactChildReconciler.updateChildren( - prevChildren, nextNestedChildren, transaction, context - ); - this._renderedChildren = nextChildren; - if (!nextChildren && !prevChildren) { - return; - } - var name; - // `nextIndex` will increment for each child in `nextChildren`, but - // `lastIndex` will be the last index visited in `prevChildren`. - var lastIndex = 0; - var nextIndex = 0; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - var prevChild = prevChildren && prevChildren[name]; - var nextChild = nextChildren[name]; - if (prevChild === nextChild) { - this.moveChild(prevChild, nextIndex, lastIndex); - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - prevChild._mountIndex = nextIndex; - } else { - if (prevChild) { - // Update `lastIndex` before `_mountIndex` gets unset by unmounting. - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - this._unmountChildByName(prevChild, name); - } - // The child must be instantiated before it's mounted. - this._mountChildByNameAtIndex( - nextChild, name, nextIndex, transaction, context - ); - } - nextIndex++; - } - // Remove children that are no longer present. - for (name in prevChildren) { - if (prevChildren.hasOwnProperty(name) && - !(nextChildren && nextChildren.hasOwnProperty(name))) { - this._unmountChildByName(prevChildren[name], name); - } - } - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. - * - * @internal - */ - unmountChildren: function() { - var renderedChildren = this._renderedChildren; - ReactChildReconciler.unmountChildren(renderedChildren); - this._renderedChildren = null; - }, - - /** - * Moves a child component to the supplied index. - * - * @param {ReactComponent} child Component to move. - * @param {number} toIndex Destination index of the element. - * @param {number} lastIndex Last index visited of the siblings of `child`. - * @protected - */ - moveChild: function(child, toIndex, lastIndex) { - // If the index of `child` is less than `lastIndex`, then it needs to - // be moved. Otherwise, we do not need to move it because a child will be - // inserted or moved before `child`. - if (child._mountIndex < lastIndex) { - enqueueMove(this._rootNodeID, child._mountIndex, toIndex); - } - }, - - /** - * Creates a child component. - * - * @param {ReactComponent} child Component to create. - * @param {string} mountImage Markup to insert. - * @protected - */ - createChild: function(child, mountImage) { - enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex); - }, - - /** - * Removes a child component. - * - * @param {ReactComponent} child Child to remove. - * @protected - */ - removeChild: function(child) { - enqueueRemove(this._rootNodeID, child._mountIndex); - }, - - /** - * Sets this text content string. - * - * @param {string} textContent Text content to set. - * @protected - */ - setTextContent: function(textContent) { - enqueueTextContent(this._rootNodeID, textContent); - }, - - /** - * Mounts a child with the supplied name. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to mount. - * @param {string} name Name of the child. - * @param {number} index Index at which to insert the child. - * @param {ReactReconcileTransaction} transaction - * @private - */ - _mountChildByNameAtIndex: function( - child, - name, - index, - transaction, - context) { - // Inlined for performance, see `ReactInstanceHandles.createReactID`. - var rootID = this._rootNodeID + name; - var mountImage = ReactReconciler.mountComponent( - child, - rootID, - transaction, - context - ); - child._mountIndex = index; - this.createChild(child, mountImage); - }, - - /** - * Unmounts a rendered child by name. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to unmount. - * @param {string} name Name of the child in `this._renderedChildren`. - * @private - */ - _unmountChildByName: function(child, name) { - this.removeChild(child); - child._mountIndex = null; - } - - } - -}; - -module.exports = ReactMultiChild; - -},{"31":31,"36":36,"72":72,"81":81}],72:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactMultiChildUpdateTypes - */ - -'use strict'; - -var keyMirror = _dereq_(140); - -/** - * When a component's children are updated, a series of update configuration - * objects are created in order to batch and serialize the required changes. - * - * Enumerates all the possible types of update configurations. - * - * @internal - */ -var ReactMultiChildUpdateTypes = keyMirror({ - INSERT_MARKUP: null, - MOVE_EXISTING: null, - REMOVE_NODE: null, - TEXT_CONTENT: null -}); - -module.exports = ReactMultiChildUpdateTypes; - -},{"140":140}],73:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactNativeComponent - */ - -'use strict'; - -var assign = _dereq_(27); -var invariant = _dereq_(135); - -var autoGenerateWrapperClass = null; -var genericComponentClass = null; -// This registry keeps track of wrapper classes around native tags -var tagToComponentClass = {}; -var textComponentClass = null; - -var ReactNativeComponentInjection = { - // This accepts a class that receives the tag string. This is a catch all - // that can render any kind of tag. - injectGenericComponentClass: function(componentClass) { - genericComponentClass = componentClass; - }, - // This accepts a text component class that takes the text string to be - // rendered as props. - injectTextComponentClass: function(componentClass) { - textComponentClass = componentClass; - }, - // This accepts a keyed object with classes as values. Each key represents a - // tag. That particular tag will use this class instead of the generic one. - injectComponentClasses: function(componentClasses) { - assign(tagToComponentClass, componentClasses); - }, - // Temporary hack since we expect DOM refs to behave like composites, - // for this release. - injectAutoWrapper: function(wrapperFactory) { - autoGenerateWrapperClass = wrapperFactory; - } -}; - -/** - * Get a composite component wrapper class for a specific tag. - * - * @param {ReactElement} element The tag for which to get the class. - * @return {function} The React class constructor function. - */ -function getComponentClassForElement(element) { - if (typeof element.type === 'function') { - return element.type; - } - var tag = element.type; - var componentClass = tagToComponentClass[tag]; - if (componentClass == null) { - tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag); - } - return componentClass; -} - -/** - * Get a native internal component class for a specific tag. - * - * @param {ReactElement} element The element to create. - * @return {function} The internal class constructor function. - */ -function createInternalComponent(element) { - ("production" !== "development" ? invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - element.type - ) : invariant(genericComponentClass)); - return new genericComponentClass(element.type, element.props); -} - -/** - * @param {ReactText} text - * @return {ReactComponent} - */ -function createInstanceForText(text) { - return new textComponentClass(text); -} - -/** - * @param {ReactComponent} component - * @return {boolean} - */ -function isTextComponent(component) { - return component instanceof textComponentClass; -} - -var ReactNativeComponent = { - getComponentClassForElement: getComponentClassForElement, - createInternalComponent: createInternalComponent, - createInstanceForText: createInstanceForText, - isTextComponent: isTextComponent, - injection: ReactNativeComponentInjection -}; - -module.exports = ReactNativeComponent; - -},{"135":135,"27":27}],74:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactOwner - */ - -'use strict'; - -var invariant = _dereq_(135); - -/** - * ReactOwners are capable of storing references to owned components. - * - * All components are capable of //being// referenced by owner components, but - * only ReactOwner components are capable of //referencing// owned components. - * The named reference is known as a "ref". - * - * Refs are available when mounted and updated during reconciliation. - * - * var MyComponent = React.createClass({ - * render: function() { - * return ( - * <div onClick={this.handleClick}> - * <CustomComponent ref="custom" /> - * </div> - * ); - * }, - * handleClick: function() { - * this.refs.custom.handleClick(); - * }, - * componentDidMount: function() { - * this.refs.custom.initialize(); - * } - * }); - * - * Refs should rarely be used. When refs are used, they should only be done to - * control data that is not handled by React's data flow. - * - * @class ReactOwner - */ -var ReactOwner = { - - /** - * @param {?object} object - * @return {boolean} True if `object` is a valid owner. - * @final - */ - isValidOwner: function(object) { - return !!( - (object && - typeof object.attachRef === 'function' && typeof object.detachRef === 'function') - ); - }, - - /** - * Adds a component by ref to an owner component. - * - * @param {ReactComponent} component Component to reference. - * @param {string} ref Name by which to refer to the component. - * @param {ReactOwner} owner Component on which to record the ref. - * @final - * @internal - */ - addComponentAsRefTo: function(component, ref, owner) { - ("production" !== "development" ? invariant( - ReactOwner.isValidOwner(owner), - 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to add a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ) : invariant(ReactOwner.isValidOwner(owner))); - owner.attachRef(ref, component); - }, - - /** - * Removes a component by ref from an owner component. - * - * @param {ReactComponent} component Component to dereference. - * @param {string} ref Name of the ref to remove. - * @param {ReactOwner} owner Component on which the ref is recorded. - * @final - * @internal - */ - removeComponentAsRefFrom: function(component, ref, owner) { - ("production" !== "development" ? invariant( - ReactOwner.isValidOwner(owner), - 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to remove a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ) : invariant(ReactOwner.isValidOwner(owner))); - // Check that `component` is still the current ref because we do not want to - // detach the ref if another component stole it. - if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) { - owner.detachRef(ref); - } - } - -}; - -module.exports = ReactOwner; - -},{"135":135}],75:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPerf - * @typechecks static-only - */ - -'use strict'; - -/** - * ReactPerf is a general AOP system designed to measure performance. This - * module only has the hooks: see ReactDefaultPerf for the analysis tool. - */ -var ReactPerf = { - /** - * Boolean to enable/disable measurement. Set to false by default to prevent - * accidental logging and perf loss. - */ - enableMeasure: false, - - /** - * Holds onto the measure function in use. By default, don't measure - * anything, but we'll override this if we inject a measure function. - */ - storedMeasure: _noMeasure, - - /** - * @param {object} object - * @param {string} objectName - * @param {object<string>} methodNames - */ - measureMethods: function(object, objectName, methodNames) { - if ("production" !== "development") { - for (var key in methodNames) { - if (!methodNames.hasOwnProperty(key)) { - continue; - } - object[key] = ReactPerf.measure( - objectName, - methodNames[key], - object[key] - ); - } - } - }, - - /** - * Use this to wrap methods you want to measure. Zero overhead in production. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ - measure: function(objName, fnName, func) { - if ("production" !== "development") { - var measuredFunc = null; - var wrapper = function() { - if (ReactPerf.enableMeasure) { - if (!measuredFunc) { - measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); - } - return measuredFunc.apply(this, arguments); - } - return func.apply(this, arguments); - }; - wrapper.displayName = objName + '_' + fnName; - return wrapper; - } - return func; - }, - - injection: { - /** - * @param {function} measure - */ - injectMeasure: function(measure) { - ReactPerf.storedMeasure = measure; - } - } -}; - -/** - * Simply passes through the measured function, without measuring it. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ -function _noMeasure(objName, fnName, func) { - return func; -} - -module.exports = ReactPerf; - -},{}],76:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypeLocationNames - */ - -'use strict'; - -var ReactPropTypeLocationNames = {}; - -if ("production" !== "development") { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; - -},{}],77:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypeLocations - */ - -'use strict'; - -var keyMirror = _dereq_(140); - -var ReactPropTypeLocations = keyMirror({ - prop: null, - context: null, - childContext: null -}); - -module.exports = ReactPropTypeLocations; - -},{"140":140}],78:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypes - */ - -'use strict'; - -var ReactElement = _dereq_(57); -var ReactFragment = _dereq_(63); -var ReactPropTypeLocationNames = _dereq_(76); - -var emptyFunction = _dereq_(114); - -/** - * Collection of methods that allow declaration and validation of props that are - * supplied to React components. Example usage: - * - * var Props = require('ReactPropTypes'); - * var MyArticle = React.createClass({ - * propTypes: { - * // An optional string prop named "description". - * description: Props.string, - * - * // A required enum prop named "category". - * category: Props.oneOf(['News','Photos']).isRequired, - * - * // A prop named "dialog" that requires an instance of Dialog. - * dialog: Props.instanceOf(Dialog).isRequired - * }, - * render: function() { ... } - * }); - * - * A more formal specification of how these methods are used: - * - * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) - * decl := ReactPropTypes.{type}(.isRequired)? - * - * Each and every declaration produces a function with the same signature. This - * allows the creation of custom validation functions. For example: - * - * var MyLink = React.createClass({ - * propTypes: { - * // An optional string or URI prop named "href". - * href: function(props, propName, componentName) { - * var propValue = props[propName]; - * if (propValue != null && typeof propValue !== 'string' && - * !(propValue instanceof URI)) { - * return new Error( - * 'Expected a string or an URI for ' + propName + ' in ' + - * componentName - * ); - * } - * } - * }, - * render: function() {...} - * }); - * - * @internal - */ - -var ANONYMOUS = '<<anonymous>>'; - -var elementTypeChecker = createElementTypeChecker(); -var nodeTypeChecker = createNodeChecker(); - -var ReactPropTypes = { - array: createPrimitiveTypeChecker('array'), - bool: createPrimitiveTypeChecker('boolean'), - func: createPrimitiveTypeChecker('function'), - number: createPrimitiveTypeChecker('number'), - object: createPrimitiveTypeChecker('object'), - string: createPrimitiveTypeChecker('string'), - - any: createAnyTypeChecker(), - arrayOf: createArrayOfTypeChecker, - element: elementTypeChecker, - instanceOf: createInstanceTypeChecker, - node: nodeTypeChecker, - objectOf: createObjectOfTypeChecker, - oneOf: createEnumTypeChecker, - oneOfType: createUnionTypeChecker, - shape: createShapeTypeChecker -}; - -function createChainableTypeChecker(validate) { - function checkType(isRequired, props, propName, componentName, location) { - componentName = componentName || ANONYMOUS; - if (props[propName] == null) { - var locationName = ReactPropTypeLocationNames[location]; - if (isRequired) { - return new Error( - ("Required " + locationName + " `" + propName + "` was not specified in ") + - ("`" + componentName + "`.") - ); - } - return null; - } else { - return validate(props, propName, componentName, location); - } - } - - var chainedCheckType = checkType.bind(null, false); - chainedCheckType.isRequired = checkType.bind(null, true); - - return chainedCheckType; -} - -function createPrimitiveTypeChecker(expectedType) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== expectedType) { - var locationName = ReactPropTypeLocationNames[location]; - // `propValue` being instance of, say, date/regexp, pass the 'object' - // check, but we can offer a more precise error message here rather than - // 'of type `object`'. - var preciseType = getPreciseType(propValue); - - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type `" + preciseType + "` ") + - ("supplied to `" + componentName + "`, expected `" + expectedType + "`.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createAnyTypeChecker() { - return createChainableTypeChecker(emptyFunction.thatReturns(null)); -} - -function createArrayOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - if (!Array.isArray(propValue)) { - var locationName = ReactPropTypeLocationNames[location]; - var propType = getPropType(propValue); - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type ") + - ("`" + propType + "` supplied to `" + componentName + "`, expected an array.") - ); - } - for (var i = 0; i < propValue.length; i++) { - var error = typeChecker(propValue, i, componentName, location); - if (error instanceof Error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createElementTypeChecker() { - function validate(props, propName, componentName, location) { - if (!ReactElement.isValidElement(props[propName])) { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected a ReactElement.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createInstanceTypeChecker(expectedClass) { - function validate(props, propName, componentName, location) { - if (!(props[propName] instanceof expectedClass)) { - var locationName = ReactPropTypeLocationNames[location]; - var expectedClassName = expectedClass.name || ANONYMOUS; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected instance of `" + expectedClassName + "`.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createEnumTypeChecker(expectedValues) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - for (var i = 0; i < expectedValues.length; i++) { - if (propValue === expectedValues[i]) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - var valuesString = JSON.stringify(expectedValues); - return new Error( - ("Invalid " + locationName + " `" + propName + "` of value `" + propValue + "` ") + - ("supplied to `" + componentName + "`, expected one of " + valuesString + ".") - ); - } - return createChainableTypeChecker(validate); -} - -function createObjectOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type ") + - ("`" + propType + "` supplied to `" + componentName + "`, expected an object.") - ); - } - for (var key in propValue) { - if (propValue.hasOwnProperty(key)) { - var error = typeChecker(propValue, key, componentName, location); - if (error instanceof Error) { - return error; - } - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createUnionTypeChecker(arrayOfTypeCheckers) { - function validate(props, propName, componentName, location) { - for (var i = 0; i < arrayOfTypeCheckers.length; i++) { - var checker = arrayOfTypeCheckers[i]; - if (checker(props, propName, componentName, location) == null) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`.") - ); - } - return createChainableTypeChecker(validate); -} - -function createNodeChecker() { - function validate(props, propName, componentName, location) { - if (!isNode(props[propName])) { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected a ReactNode.") - ); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createShapeTypeChecker(shapeTypes) { - function validate(props, propName, componentName, location) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type `" + propType + "` ") + - ("supplied to `" + componentName + "`, expected `object`.") - ); - } - for (var key in shapeTypes) { - var checker = shapeTypes[key]; - if (!checker) { - continue; - } - var error = checker(propValue, key, componentName, location); - if (error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function isNode(propValue) { - switch (typeof propValue) { - case 'number': - case 'string': - case 'undefined': - return true; - case 'boolean': - return !propValue; - case 'object': - if (Array.isArray(propValue)) { - return propValue.every(isNode); - } - if (propValue === null || ReactElement.isValidElement(propValue)) { - return true; - } - propValue = ReactFragment.extractIfFragment(propValue); - for (var k in propValue) { - if (!isNode(propValue[k])) { - return false; - } - } - return true; - default: - return false; - } -} - -// Equivalent of `typeof` but with special handling for array and regexp. -function getPropType(propValue) { - var propType = typeof propValue; - if (Array.isArray(propValue)) { - return 'array'; - } - if (propValue instanceof RegExp) { - // Old webkits (at least until Android 4.0) return 'function' rather than - // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ - // passes PropTypes.object. - return 'object'; - } - return propType; -} - -// This handles more types than `getPropType`. Only used for error messages. -// See `createPrimitiveTypeChecker`. -function getPreciseType(propValue) { - var propType = getPropType(propValue); - if (propType === 'object') { - if (propValue instanceof Date) { - return 'date'; - } else if (propValue instanceof RegExp) { - return 'regexp'; - } - } - return propType; -} - -module.exports = ReactPropTypes; - -},{"114":114,"57":57,"63":63,"76":76}],79:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPutListenerQueue - */ - -'use strict'; - -var PooledClass = _dereq_(28); -var ReactBrowserEventEmitter = _dereq_(30); - -var assign = _dereq_(27); - -function ReactPutListenerQueue() { - this.listenersToPut = []; -} - -assign(ReactPutListenerQueue.prototype, { - enqueuePutListener: function(rootNodeID, propKey, propValue) { - this.listenersToPut.push({ - rootNodeID: rootNodeID, - propKey: propKey, - propValue: propValue - }); - }, - - putListeners: function() { - for (var i = 0; i < this.listenersToPut.length; i++) { - var listenerToPut = this.listenersToPut[i]; - ReactBrowserEventEmitter.putListener( - listenerToPut.rootNodeID, - listenerToPut.propKey, - listenerToPut.propValue - ); - } - }, - - reset: function() { - this.listenersToPut.length = 0; - }, - - destructor: function() { - this.reset(); - } -}); - -PooledClass.addPoolingTo(ReactPutListenerQueue); - -module.exports = ReactPutListenerQueue; - -},{"27":27,"28":28,"30":30}],80:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactReconcileTransaction - * @typechecks static-only - */ - -'use strict'; - -var CallbackQueue = _dereq_(6); -var PooledClass = _dereq_(28); -var ReactBrowserEventEmitter = _dereq_(30); -var ReactInputSelection = _dereq_(65); -var ReactPutListenerQueue = _dereq_(79); -var Transaction = _dereq_(103); - -var assign = _dereq_(27); - -/** - * Ensures that, when possible, the selection range (currently selected text - * input) is not disturbed by performing the transaction. - */ -var SELECTION_RESTORATION = { - /** - * @return {Selection} Selection information. - */ - initialize: ReactInputSelection.getSelectionInformation, - /** - * @param {Selection} sel Selection information returned from `initialize`. - */ - close: ReactInputSelection.restoreSelection -}; - -/** - * Suppresses events (blur/focus) that could be inadvertently dispatched due to - * high level DOM manipulations (like temporarily removing a text input from the - * DOM). - */ -var EVENT_SUPPRESSION = { - /** - * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before - * the reconciliation. - */ - initialize: function() { - var currentlyEnabled = ReactBrowserEventEmitter.isEnabled(); - ReactBrowserEventEmitter.setEnabled(false); - return currentlyEnabled; - }, - - /** - * @param {boolean} previouslyEnabled Enabled status of - * `ReactBrowserEventEmitter` before the reconciliation occured. `close` - * restores the previous value. - */ - close: function(previouslyEnabled) { - ReactBrowserEventEmitter.setEnabled(previouslyEnabled); - } -}; - -/** - * Provides a queue for collecting `componentDidMount` and - * `componentDidUpdate` callbacks during the the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function() { - this.reactMountReady.reset(); - }, - - /** - * After DOM is flushed, invoke all registered `onDOMReady` callbacks. - */ - close: function() { - this.reactMountReady.notifyAll(); - } -}; - -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, - - close: function() { - this.putListenerQueue.putListeners(); - } -}; - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - SELECTION_RESTORATION, - EVENT_SUPPRESSION, - ON_DOM_READY_QUEUEING -]; - -/** - * Currently: - * - The order that these are listed in the transaction is critical: - * - Suppresses events. - * - Restores selection range. - * - * Future: - * - Restore document/overflow scroll positions that were unintentionally - * modified via DOM insertions above the top viewport boundary. - * - Implement/integrate with customized constraint based layout system and keep - * track of which dimensions must be remeasured. - * - * @class ReactReconcileTransaction - */ -function ReactReconcileTransaction() { - this.reinitializeTransaction(); - // Only server-side rendering really needs this option (see - // `ReactServerRendering`), but server-side uses - // `ReactServerRenderingTransaction` instead. This option is here so that it's - // accessible and defaults to false when `ReactDOMComponent` and - // `ReactTextComponent` checks it in `mountComponent`.` - this.renderToStaticMarkup = false; - this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array<object>} List of operation wrap proceedures. - * TODO: convert to array<TransactionWrapper> - */ - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function() { - return this.reactMountReady; - }, - - getPutListenerQueue: function() { - return this.putListenerQueue; - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. - */ - destructor: function() { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; - - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; - } -}; - - -assign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin); - -PooledClass.addPoolingTo(ReactReconcileTransaction); - -module.exports = ReactReconcileTransaction; - -},{"103":103,"27":27,"28":28,"30":30,"6":6,"65":65,"79":79}],81:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactReconciler - */ - -'use strict'; - -var ReactRef = _dereq_(82); -var ReactElementValidator = _dereq_(58); - -/** - * Helper to call ReactRef.attachRefs with this composite component, split out - * to avoid allocations in the transaction mount-ready queue. - */ -function attachRefs() { - ReactRef.attachRefs(this, this._currentElement); -} - -var ReactReconciler = { - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactComponent} internalInstance - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function(internalInstance, rootID, transaction, context) { - var markup = internalInstance.mountComponent(rootID, transaction, context); - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps( - internalInstance._currentElement - ); - } - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - return markup; - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function(internalInstance) { - ReactRef.detachRefs(internalInstance, internalInstance._currentElement); - internalInstance.unmountComponent(); - }, - - /** - * Update a component using a new element. - * - * @param {ReactComponent} internalInstance - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @internal - */ - receiveComponent: function( - internalInstance, nextElement, transaction, context - ) { - var prevElement = internalInstance._currentElement; - - if (nextElement === prevElement && nextElement._owner != null) { - // Since elements are immutable after the owner is rendered, - // we can do a cheap identity compare here to determine if this is a - // superfluous reconcile. It's possible for state to be mutable but such - // change should trigger an update of the owner which would recreate - // the element. We explicitly check for the existence of an owner since - // it's possible for an element created outside a composite to be - // deeply mutated and reused. - return; - } - - if ("production" !== "development") { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - var refsChanged = ReactRef.shouldUpdateRefs( - prevElement, - nextElement - ); - - if (refsChanged) { - ReactRef.detachRefs(internalInstance, prevElement); - } - - internalInstance.receiveComponent(nextElement, transaction, context); - - if (refsChanged) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - }, - - /** - * Flush any dirty changes in a component. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function( - internalInstance, - transaction - ) { - internalInstance.performUpdateIfNecessary(transaction); - } - -}; - -module.exports = ReactReconciler; - -},{"58":58,"82":82}],82:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactRef - */ - -'use strict'; - -var ReactOwner = _dereq_(74); - -var ReactRef = {}; - -function attachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(component.getPublicInstance()); - } else { - // Legacy ref - ReactOwner.addComponentAsRefTo(component, ref, owner); - } -} - -function detachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(null); - } else { - // Legacy ref - ReactOwner.removeComponentAsRefFrom(component, ref, owner); - } -} - -ReactRef.attachRefs = function(instance, element) { - var ref = element.ref; - if (ref != null) { - attachRef(ref, instance, element._owner); - } -}; - -ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { - // If either the owner or a `ref` has changed, make sure the newest owner - // has stored a reference to `this`, and the previous owner (if different) - // has forgotten the reference to `this`. We use the element instead - // of the public this.props because the post processing cannot determine - // a ref. The ref conceptually lives on the element. - - // TODO: Should this even be possible? The owner cannot change because - // it's forbidden by shouldUpdateReactComponent. The ref can change - // if you swap the keys of but not the refs. Reconsider where this check - // is made. It probably belongs where the key checking and - // instantiateReactComponent is done. - - return ( - nextElement._owner !== prevElement._owner || - nextElement.ref !== prevElement.ref - ); -}; - -ReactRef.detachRefs = function(instance, element) { - var ref = element.ref; - if (ref != null) { - detachRef(ref, instance, element._owner); - } -}; - -module.exports = ReactRef; - -},{"74":74}],83:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactRootIndex - * @typechecks - */ - -'use strict'; - -var ReactRootIndexInjection = { - /** - * @param {function} _createReactRootIndex - */ - injectCreateReactRootIndex: function(_createReactRootIndex) { - ReactRootIndex.createReactRootIndex = _createReactRootIndex; - } -}; - -var ReactRootIndex = { - createReactRootIndex: null, - injection: ReactRootIndexInjection -}; - -module.exports = ReactRootIndex; - -},{}],84:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks static-only - * @providesModule ReactServerRendering - */ -'use strict'; - -var ReactElement = _dereq_(57); -var ReactInstanceHandles = _dereq_(66); -var ReactMarkupChecksum = _dereq_(69); -var ReactServerRenderingTransaction = - _dereq_(85); - -var emptyObject = _dereq_(115); -var instantiateReactComponent = _dereq_(134); -var invariant = _dereq_(135); - -/** - * @param {ReactElement} element - * @return {string} the HTML markup - */ -function renderToString(element) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(element), - 'renderToString(): You must pass a valid ReactElement.' - ) : invariant(ReactElement.isValidElement(element))); - - var transaction; - try { - var id = ReactInstanceHandles.createReactRootID(); - transaction = ReactServerRenderingTransaction.getPooled(false); - - return transaction.perform(function() { - var componentInstance = instantiateReactComponent(element, null); - var markup = - componentInstance.mountComponent(id, transaction, emptyObject); - return ReactMarkupChecksum.addChecksumToMarkup(markup); - }, null); - } finally { - ReactServerRenderingTransaction.release(transaction); - } -} - -/** - * @param {ReactElement} element - * @return {string} the HTML markup, without the extra React ID and checksum - * (for generating static pages) - */ -function renderToStaticMarkup(element) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(element), - 'renderToStaticMarkup(): You must pass a valid ReactElement.' - ) : invariant(ReactElement.isValidElement(element))); - - var transaction; - try { - var id = ReactInstanceHandles.createReactRootID(); - transaction = ReactServerRenderingTransaction.getPooled(true); - - return transaction.perform(function() { - var componentInstance = instantiateReactComponent(element, null); - return componentInstance.mountComponent(id, transaction, emptyObject); - }, null); - } finally { - ReactServerRenderingTransaction.release(transaction); - } -} - -module.exports = { - renderToString: renderToString, - renderToStaticMarkup: renderToStaticMarkup -}; - -},{"115":115,"134":134,"135":135,"57":57,"66":66,"69":69,"85":85}],85:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactServerRenderingTransaction - * @typechecks - */ - -'use strict'; - -var PooledClass = _dereq_(28); -var CallbackQueue = _dereq_(6); -var ReactPutListenerQueue = _dereq_(79); -var Transaction = _dereq_(103); - -var assign = _dereq_(27); -var emptyFunction = _dereq_(114); - -/** - * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks - * during the performing of the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function() { - this.reactMountReady.reset(); - }, - - close: emptyFunction -}; - -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, - - close: emptyFunction -}; - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - ON_DOM_READY_QUEUEING -]; - -/** - * @class ReactServerRenderingTransaction - * @param {boolean} renderToStaticMarkup - */ -function ReactServerRenderingTransaction(renderToStaticMarkup) { - this.reinitializeTransaction(); - this.renderToStaticMarkup = renderToStaticMarkup; - this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array} Empty list of operation wrap proceedures. - */ - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function() { - return this.reactMountReady; - }, - - getPutListenerQueue: function() { - return this.putListenerQueue; - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. - */ - destructor: function() { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; - - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; - } -}; - - -assign( - ReactServerRenderingTransaction.prototype, - Transaction.Mixin, - Mixin -); - -PooledClass.addPoolingTo(ReactServerRenderingTransaction); - -module.exports = ReactServerRenderingTransaction; - -},{"103":103,"114":114,"27":27,"28":28,"6":6,"79":79}],86:[function(_dereq_,module,exports){ -/** - * Copyright 2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactUpdateQueue - */ - -'use strict'; - -var ReactLifeCycle = _dereq_(68); -var ReactCurrentOwner = _dereq_(39); -var ReactElement = _dereq_(57); -var ReactInstanceMap = _dereq_(67); -var ReactUpdates = _dereq_(87); - -var assign = _dereq_(27); -var invariant = _dereq_(135); -var warning = _dereq_(154); - -function enqueueUpdate(internalInstance) { - if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) { - // If we're in a componentWillMount handler, don't enqueue a rerender - // because ReactUpdates assumes we're in a browser context (which is - // wrong for server rendering) and we're about to do a render anyway. - // See bug in #1740. - ReactUpdates.enqueueUpdate(internalInstance); - } -} - -function getInternalInstanceReadyForUpdate(publicInstance, callerName) { - ("production" !== "development" ? invariant( - ReactCurrentOwner.current == null, - '%s(...): Cannot update during an existing state transition ' + - '(such as within `render`). Render methods should be a pure function ' + - 'of props and state.', - callerName - ) : invariant(ReactCurrentOwner.current == null)); - - var internalInstance = ReactInstanceMap.get(publicInstance); - if (!internalInstance) { - if ("production" !== "development") { - // Only warn when we have a callerName. Otherwise we should be silent. - // We're probably calling from enqueueCallback. We don't want to warn - // there because we already warned for the corresponding lifecycle method. - ("production" !== "development" ? warning( - !callerName, - '%s(...): Can only update a mounted or mounting component. ' + - 'This usually means you called %s() on an unmounted ' + - 'component. This is a no-op.', - callerName, - callerName - ) : null); - } - return null; - } - - if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) { - return null; - } - - return internalInstance; -} - -/** - * ReactUpdateQueue allows for state updates to be scheduled into a later - * reconciliation step. - */ -var ReactUpdateQueue = { - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback: function(publicInstance, callback) { - ("production" !== "development" ? invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ) : invariant(typeof callback === 'function')); - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); - - // Previously we would throw an error if we didn't have an internal - // instance. Since we want to make it a no-op instead, we mirror the same - // behavior we have in other enqueue* methods. - // We also need to ignore callbacks in componentWillMount. See - // enqueueUpdates. - if (!internalInstance || - internalInstance === ReactLifeCycle.currentlyMountingInstance) { - return null; - } - - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - // TODO: The callback here is ignored when setState is called from - // componentWillMount. Either fix it or disallow doing so completely in - // favor of getInitialState. Alternatively, we can disallow - // componentWillMount during server-side rendering. - enqueueUpdate(internalInstance); - }, - - enqueueCallbackInternal: function(internalInstance, callback) { - ("production" !== "development" ? invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ) : invariant(typeof callback === 'function')); - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - enqueueUpdate(internalInstance); - }, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldUpdateComponent`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function(publicInstance) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'forceUpdate' - ); - - if (!internalInstance) { - return; - } - - internalInstance._pendingForceUpdate = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function(publicInstance, completeState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceState' - ); - - if (!internalInstance) { - return; - } - - internalInstance._pendingStateQueue = [completeState]; - internalInstance._pendingReplaceState = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function(publicInstance, partialState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setState' - ); - - if (!internalInstance) { - return; - } - - var queue = - internalInstance._pendingStateQueue || - (internalInstance._pendingStateQueue = []); - queue.push(partialState); - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the props. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialProps Subset of the next props. - * @internal - */ - enqueueSetProps: function(publicInstance, partialProps) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setProps' - ); - - if (!internalInstance) { - return; - } - - ("production" !== "development" ? invariant( - internalInstance._isTopLevel, - 'setProps(...): You called `setProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(internalInstance._isTopLevel)); - - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; - var props = assign({}, element.props, partialProps); - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the props. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} props New props. - * @internal - */ - enqueueReplaceProps: function(publicInstance, props) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceProps' - ); - - if (!internalInstance) { - return; - } - - ("production" !== "development" ? invariant( - internalInstance._isTopLevel, - 'replaceProps(...): You called `replaceProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(internalInstance._isTopLevel)); - - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); - - enqueueUpdate(internalInstance); - }, - - enqueueElementInternal: function(internalInstance, newElement) { - internalInstance._pendingElement = newElement; - enqueueUpdate(internalInstance); - } - -}; - -module.exports = ReactUpdateQueue; - -},{"135":135,"154":154,"27":27,"39":39,"57":57,"67":67,"68":68,"87":87}],87:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactUpdates - */ - -'use strict'; - -var CallbackQueue = _dereq_(6); -var PooledClass = _dereq_(28); -var ReactCurrentOwner = _dereq_(39); -var ReactPerf = _dereq_(75); -var ReactReconciler = _dereq_(81); -var Transaction = _dereq_(103); - -var assign = _dereq_(27); -var invariant = _dereq_(135); -var warning = _dereq_(154); - -var dirtyComponents = []; -var asapCallbackQueue = CallbackQueue.getPooled(); -var asapEnqueued = false; - -var batchingStrategy = null; - -function ensureInjected() { - ("production" !== "development" ? invariant( - ReactUpdates.ReactReconcileTransaction && batchingStrategy, - 'ReactUpdates: must inject a reconcile transaction class and batching ' + - 'strategy' - ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy)); -} - -var NESTED_UPDATES = { - initialize: function() { - this.dirtyComponentsLength = dirtyComponents.length; - }, - close: function() { - if (this.dirtyComponentsLength !== dirtyComponents.length) { - // Additional updates were enqueued by componentDidUpdate handlers or - // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run - // these new updates so that if A's componentDidUpdate calls setState on - // B, B will update before the callback A's updater provided when calling - // setState. - dirtyComponents.splice(0, this.dirtyComponentsLength); - flushBatchedUpdates(); - } else { - dirtyComponents.length = 0; - } - } -}; - -var UPDATE_QUEUEING = { - initialize: function() { - this.callbackQueue.reset(); - }, - close: function() { - this.callbackQueue.notifyAll(); - } -}; - -var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; - -function ReactUpdatesFlushTransaction() { - this.reinitializeTransaction(); - this.dirtyComponentsLength = null; - this.callbackQueue = CallbackQueue.getPooled(); - this.reconcileTransaction = - ReactUpdates.ReactReconcileTransaction.getPooled(); -} - -assign( - ReactUpdatesFlushTransaction.prototype, - Transaction.Mixin, { - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - destructor: function() { - this.dirtyComponentsLength = null; - CallbackQueue.release(this.callbackQueue); - this.callbackQueue = null; - ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); - this.reconcileTransaction = null; - }, - - perform: function(method, scope, a) { - // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` - // with this transaction's wrappers around it. - return Transaction.Mixin.perform.call( - this, - this.reconcileTransaction.perform, - this.reconcileTransaction, - method, - scope, - a - ); - } -}); - -PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); - -function batchedUpdates(callback, a, b, c, d) { - ensureInjected(); - batchingStrategy.batchedUpdates(callback, a, b, c, d); -} - -/** - * Array comparator for ReactComponents by mount ordering. - * - * @param {ReactComponent} c1 first component you're comparing - * @param {ReactComponent} c2 second component you're comparing - * @return {number} Return value usable by Array.prototype.sort(). - */ -function mountOrderComparator(c1, c2) { - return c1._mountOrder - c2._mountOrder; -} - -function runBatchedUpdates(transaction) { - var len = transaction.dirtyComponentsLength; - ("production" !== "development" ? invariant( - len === dirtyComponents.length, - 'Expected flush transaction\'s stored dirty-components length (%s) to ' + - 'match dirty-components array length (%s).', - len, - dirtyComponents.length - ) : invariant(len === dirtyComponents.length)); - - // Since reconciling a component higher in the owner hierarchy usually (not - // always -- see shouldComponentUpdate()) will reconcile children, reconcile - // them before their children by sorting the array. - dirtyComponents.sort(mountOrderComparator); - - for (var i = 0; i < len; i++) { - // If a component is unmounted before pending changes apply, it will still - // be here, but we assume that it has cleared its _pendingCallbacks and - // that performUpdateIfNecessary is a noop. - var component = dirtyComponents[i]; - - // If performUpdateIfNecessary happens to enqueue any new updates, we - // shouldn't execute the callbacks until the next render happens, so - // stash the callbacks first - var callbacks = component._pendingCallbacks; - component._pendingCallbacks = null; - - ReactReconciler.performUpdateIfNecessary( - component, - transaction.reconcileTransaction - ); - - if (callbacks) { - for (var j = 0; j < callbacks.length; j++) { - transaction.callbackQueue.enqueue( - callbacks[j], - component.getPublicInstance() - ); - } - } - } -} - -var flushBatchedUpdates = function() { - // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents - // array and perform any updates enqueued by mount-ready handlers (i.e., - // componentDidUpdate) but we need to check here too in order to catch - // updates enqueued by setState callbacks and asap calls. - while (dirtyComponents.length || asapEnqueued) { - if (dirtyComponents.length) { - var transaction = ReactUpdatesFlushTransaction.getPooled(); - transaction.perform(runBatchedUpdates, null, transaction); - ReactUpdatesFlushTransaction.release(transaction); - } - - if (asapEnqueued) { - asapEnqueued = false; - var queue = asapCallbackQueue; - asapCallbackQueue = CallbackQueue.getPooled(); - queue.notifyAll(); - CallbackQueue.release(queue); - } - } -}; -flushBatchedUpdates = ReactPerf.measure( - 'ReactUpdates', - 'flushBatchedUpdates', - flushBatchedUpdates -); - -/** - * Mark a component as needing a rerender, adding an optional callback to a - * list of functions which will be executed once the rerender occurs. - */ -function enqueueUpdate(component) { - ensureInjected(); - - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (This is called by each top-level update - // function, like setProps, setState, forceUpdate, etc.; creation and - // destruction of top-level components is guarded in ReactMount.) - ("production" !== "development" ? warning( - ReactCurrentOwner.current == null, - 'enqueueUpdate(): Render methods should be a pure function of props ' + - 'and state; triggering nested component updates from render is not ' + - 'allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - if (!batchingStrategy.isBatchingUpdates) { - batchingStrategy.batchedUpdates(enqueueUpdate, component); - return; - } - - dirtyComponents.push(component); -} - -/** - * Enqueue a callback to be run at the end of the current batching cycle. Throws - * if no updates are currently being performed. - */ -function asap(callback, context) { - ("production" !== "development" ? invariant( - batchingStrategy.isBatchingUpdates, - 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + - 'updates are not being batched.' - ) : invariant(batchingStrategy.isBatchingUpdates)); - asapCallbackQueue.enqueue(callback, context); - asapEnqueued = true; -} - -var ReactUpdatesInjection = { - injectReconcileTransaction: function(ReconcileTransaction) { - ("production" !== "development" ? invariant( - ReconcileTransaction, - 'ReactUpdates: must provide a reconcile transaction class' - ) : invariant(ReconcileTransaction)); - ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; - }, - - injectBatchingStrategy: function(_batchingStrategy) { - ("production" !== "development" ? invariant( - _batchingStrategy, - 'ReactUpdates: must provide a batching strategy' - ) : invariant(_batchingStrategy)); - ("production" !== "development" ? invariant( - typeof _batchingStrategy.batchedUpdates === 'function', - 'ReactUpdates: must provide a batchedUpdates() function' - ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function')); - ("production" !== "development" ? invariant( - typeof _batchingStrategy.isBatchingUpdates === 'boolean', - 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' - ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean')); - batchingStrategy = _batchingStrategy; - } -}; - -var ReactUpdates = { - /** - * React references `ReactReconcileTransaction` using this property in order - * to allow dependency injection. - * - * @internal - */ - ReactReconcileTransaction: null, - - batchedUpdates: batchedUpdates, - enqueueUpdate: enqueueUpdate, - flushBatchedUpdates: flushBatchedUpdates, - injection: ReactUpdatesInjection, - asap: asap -}; - -module.exports = ReactUpdates; - -},{"103":103,"135":135,"154":154,"27":27,"28":28,"39":39,"6":6,"75":75,"81":81}],88:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SVGDOMPropertyConfig - */ - -/*jslint bitwise: true*/ - -'use strict'; - -var DOMProperty = _dereq_(10); - -var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; - -var SVGDOMPropertyConfig = { - Properties: { - clipPath: MUST_USE_ATTRIBUTE, - cx: MUST_USE_ATTRIBUTE, - cy: MUST_USE_ATTRIBUTE, - d: MUST_USE_ATTRIBUTE, - dx: MUST_USE_ATTRIBUTE, - dy: MUST_USE_ATTRIBUTE, - fill: MUST_USE_ATTRIBUTE, - fillOpacity: MUST_USE_ATTRIBUTE, - fontFamily: MUST_USE_ATTRIBUTE, - fontSize: MUST_USE_ATTRIBUTE, - fx: MUST_USE_ATTRIBUTE, - fy: MUST_USE_ATTRIBUTE, - gradientTransform: MUST_USE_ATTRIBUTE, - gradientUnits: MUST_USE_ATTRIBUTE, - markerEnd: MUST_USE_ATTRIBUTE, - markerMid: MUST_USE_ATTRIBUTE, - markerStart: MUST_USE_ATTRIBUTE, - offset: MUST_USE_ATTRIBUTE, - opacity: MUST_USE_ATTRIBUTE, - patternContentUnits: MUST_USE_ATTRIBUTE, - patternUnits: MUST_USE_ATTRIBUTE, - points: MUST_USE_ATTRIBUTE, - preserveAspectRatio: MUST_USE_ATTRIBUTE, - r: MUST_USE_ATTRIBUTE, - rx: MUST_USE_ATTRIBUTE, - ry: MUST_USE_ATTRIBUTE, - spreadMethod: MUST_USE_ATTRIBUTE, - stopColor: MUST_USE_ATTRIBUTE, - stopOpacity: MUST_USE_ATTRIBUTE, - stroke: MUST_USE_ATTRIBUTE, - strokeDasharray: MUST_USE_ATTRIBUTE, - strokeLinecap: MUST_USE_ATTRIBUTE, - strokeOpacity: MUST_USE_ATTRIBUTE, - strokeWidth: MUST_USE_ATTRIBUTE, - textAnchor: MUST_USE_ATTRIBUTE, - transform: MUST_USE_ATTRIBUTE, - version: MUST_USE_ATTRIBUTE, - viewBox: MUST_USE_ATTRIBUTE, - x1: MUST_USE_ATTRIBUTE, - x2: MUST_USE_ATTRIBUTE, - x: MUST_USE_ATTRIBUTE, - y1: MUST_USE_ATTRIBUTE, - y2: MUST_USE_ATTRIBUTE, - y: MUST_USE_ATTRIBUTE - }, - DOMAttributeNames: { - clipPath: 'clip-path', - fillOpacity: 'fill-opacity', - fontFamily: 'font-family', - fontSize: 'font-size', - gradientTransform: 'gradientTransform', - gradientUnits: 'gradientUnits', - markerEnd: 'marker-end', - markerMid: 'marker-mid', - markerStart: 'marker-start', - patternContentUnits: 'patternContentUnits', - patternUnits: 'patternUnits', - preserveAspectRatio: 'preserveAspectRatio', - spreadMethod: 'spreadMethod', - stopColor: 'stop-color', - stopOpacity: 'stop-opacity', - strokeDasharray: 'stroke-dasharray', - strokeLinecap: 'stroke-linecap', - strokeOpacity: 'stroke-opacity', - strokeWidth: 'stroke-width', - textAnchor: 'text-anchor', - viewBox: 'viewBox' - } -}; - -module.exports = SVGDOMPropertyConfig; - -},{"10":10}],89:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SelectEventPlugin - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPropagators = _dereq_(20); -var ReactInputSelection = _dereq_(65); -var SyntheticEvent = _dereq_(95); - -var getActiveElement = _dereq_(121); -var isTextInputElement = _dereq_(138); -var keyOf = _dereq_(141); -var shallowEqual = _dereq_(150); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - select: { - phasedRegistrationNames: { - bubbled: keyOf({onSelect: null}), - captured: keyOf({onSelectCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topContextMenu, - topLevelTypes.topFocus, - topLevelTypes.topKeyDown, - topLevelTypes.topMouseDown, - topLevelTypes.topMouseUp, - topLevelTypes.topSelectionChange - ] - } -}; - -var activeElement = null; -var activeElementID = null; -var lastSelection = null; -var mouseDown = false; - -/** - * Get an object which is a unique representation of the current selection. - * - * The return value will not be consistent across nodes or browsers, but - * two identical selections on the same node will return identical objects. - * - * @param {DOMElement} node - * @param {object} - */ -function getSelection(node) { - if ('selectionStart' in node && - ReactInputSelection.hasSelectionCapabilities(node)) { - return { - start: node.selectionStart, - end: node.selectionEnd - }; - } else if (window.getSelection) { - var selection = window.getSelection(); - return { - anchorNode: selection.anchorNode, - anchorOffset: selection.anchorOffset, - focusNode: selection.focusNode, - focusOffset: selection.focusOffset - }; - } else if (document.selection) { - var range = document.selection.createRange(); - return { - parentElement: range.parentElement(), - text: range.text, - top: range.boundingTop, - left: range.boundingLeft - }; - } -} - -/** - * Poll selection to see whether it's changed. - * - * @param {object} nativeEvent - * @return {?SyntheticEvent} - */ -function constructSelectEvent(nativeEvent) { - // Ensure we have the right element, and that the user is not dragging a - // selection (this matches native `select` event behavior). In HTML5, select - // fires only on input and textarea thus if there's no focused element we - // won't dispatch. - if (mouseDown || - activeElement == null || - activeElement !== getActiveElement()) { - return null; - } - - // Only fire when selection has actually changed. - var currentSelection = getSelection(activeElement); - if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { - lastSelection = currentSelection; - - var syntheticEvent = SyntheticEvent.getPooled( - eventTypes.select, - activeElementID, - nativeEvent - ); - - syntheticEvent.type = 'select'; - syntheticEvent.target = activeElement; - - EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); - - return syntheticEvent; - } -} - -/** - * This plugin creates an `onSelect` event that normalizes select events - * across form elements. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - contentEditable - * - * This differs from native browser implementations in the following ways: - * - Fires on contentEditable fields as well as inputs. - * - Fires for collapsed selection. - * - Fires after user input. - */ -var SelectEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - switch (topLevelType) { - // Track the input node that has focus. - case topLevelTypes.topFocus: - if (isTextInputElement(topLevelTarget) || - topLevelTarget.contentEditable === 'true') { - activeElement = topLevelTarget; - activeElementID = topLevelTargetID; - lastSelection = null; - } - break; - case topLevelTypes.topBlur: - activeElement = null; - activeElementID = null; - lastSelection = null; - break; - - // Don't fire the event while the user is dragging. This matches the - // semantics of the native select event. - case topLevelTypes.topMouseDown: - mouseDown = true; - break; - case topLevelTypes.topContextMenu: - case topLevelTypes.topMouseUp: - mouseDown = false; - return constructSelectEvent(nativeEvent); - - // Chrome and IE fire non-standard event when selection is changed (and - // sometimes when it hasn't). - // Firefox doesn't support selectionchange, so check selection status - // after each key entry. The selection changes after keydown and before - // keyup, but we check on keydown as well in the case of holding down a - // key, when multiple keydown events are fired but only one keyup is. - case topLevelTypes.topSelectionChange: - case topLevelTypes.topKeyDown: - case topLevelTypes.topKeyUp: - return constructSelectEvent(nativeEvent); - } - } -}; - -module.exports = SelectEventPlugin; - -},{"121":121,"138":138,"141":141,"15":15,"150":150,"20":20,"65":65,"95":95}],90:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ServerReactRootIndex - * @typechecks - */ - -'use strict'; - -/** - * Size of the reactRoot ID space. We generate random numbers for React root - * IDs and if there's a collision the events and DOM update system will - * get confused. In the future we need a way to generate GUIDs but for - * now this will work on a smaller scale. - */ -var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53); - -var ServerReactRootIndex = { - createReactRootIndex: function() { - return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX); - } -}; - -module.exports = ServerReactRootIndex; - -},{}],91:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SimpleEventPlugin - */ - -'use strict'; - -var EventConstants = _dereq_(15); -var EventPluginUtils = _dereq_(19); -var EventPropagators = _dereq_(20); -var SyntheticClipboardEvent = _dereq_(92); -var SyntheticEvent = _dereq_(95); -var SyntheticFocusEvent = _dereq_(96); -var SyntheticKeyboardEvent = _dereq_(98); -var SyntheticMouseEvent = _dereq_(99); -var SyntheticDragEvent = _dereq_(94); -var SyntheticTouchEvent = _dereq_(100); -var SyntheticUIEvent = _dereq_(101); -var SyntheticWheelEvent = _dereq_(102); - -var getEventCharCode = _dereq_(122); - -var invariant = _dereq_(135); -var keyOf = _dereq_(141); -var warning = _dereq_(154); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - blur: { - phasedRegistrationNames: { - bubbled: keyOf({onBlur: true}), - captured: keyOf({onBlurCapture: true}) - } - }, - click: { - phasedRegistrationNames: { - bubbled: keyOf({onClick: true}), - captured: keyOf({onClickCapture: true}) - } - }, - contextMenu: { - phasedRegistrationNames: { - bubbled: keyOf({onContextMenu: true}), - captured: keyOf({onContextMenuCapture: true}) - } - }, - copy: { - phasedRegistrationNames: { - bubbled: keyOf({onCopy: true}), - captured: keyOf({onCopyCapture: true}) - } - }, - cut: { - phasedRegistrationNames: { - bubbled: keyOf({onCut: true}), - captured: keyOf({onCutCapture: true}) - } - }, - doubleClick: { - phasedRegistrationNames: { - bubbled: keyOf({onDoubleClick: true}), - captured: keyOf({onDoubleClickCapture: true}) - } - }, - drag: { - phasedRegistrationNames: { - bubbled: keyOf({onDrag: true}), - captured: keyOf({onDragCapture: true}) - } - }, - dragEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onDragEnd: true}), - captured: keyOf({onDragEndCapture: true}) - } - }, - dragEnter: { - phasedRegistrationNames: { - bubbled: keyOf({onDragEnter: true}), - captured: keyOf({onDragEnterCapture: true}) - } - }, - dragExit: { - phasedRegistrationNames: { - bubbled: keyOf({onDragExit: true}), - captured: keyOf({onDragExitCapture: true}) - } - }, - dragLeave: { - phasedRegistrationNames: { - bubbled: keyOf({onDragLeave: true}), - captured: keyOf({onDragLeaveCapture: true}) - } - }, - dragOver: { - phasedRegistrationNames: { - bubbled: keyOf({onDragOver: true}), - captured: keyOf({onDragOverCapture: true}) - } - }, - dragStart: { - phasedRegistrationNames: { - bubbled: keyOf({onDragStart: true}), - captured: keyOf({onDragStartCapture: true}) - } - }, - drop: { - phasedRegistrationNames: { - bubbled: keyOf({onDrop: true}), - captured: keyOf({onDropCapture: true}) - } - }, - focus: { - phasedRegistrationNames: { - bubbled: keyOf({onFocus: true}), - captured: keyOf({onFocusCapture: true}) - } - }, - input: { - phasedRegistrationNames: { - bubbled: keyOf({onInput: true}), - captured: keyOf({onInputCapture: true}) - } - }, - keyDown: { - phasedRegistrationNames: { - bubbled: keyOf({onKeyDown: true}), - captured: keyOf({onKeyDownCapture: true}) - } - }, - keyPress: { - phasedRegistrationNames: { - bubbled: keyOf({onKeyPress: true}), - captured: keyOf({onKeyPressCapture: true}) - } - }, - keyUp: { - phasedRegistrationNames: { - bubbled: keyOf({onKeyUp: true}), - captured: keyOf({onKeyUpCapture: true}) - } - }, - load: { - phasedRegistrationNames: { - bubbled: keyOf({onLoad: true}), - captured: keyOf({onLoadCapture: true}) - } - }, - error: { - phasedRegistrationNames: { - bubbled: keyOf({onError: true}), - captured: keyOf({onErrorCapture: true}) - } - }, - // Note: We do not allow listening to mouseOver events. Instead, use the - // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`. - mouseDown: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseDown: true}), - captured: keyOf({onMouseDownCapture: true}) - } - }, - mouseMove: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseMove: true}), - captured: keyOf({onMouseMoveCapture: true}) - } - }, - mouseOut: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseOut: true}), - captured: keyOf({onMouseOutCapture: true}) - } - }, - mouseOver: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseOver: true}), - captured: keyOf({onMouseOverCapture: true}) - } - }, - mouseUp: { - phasedRegistrationNames: { - bubbled: keyOf({onMouseUp: true}), - captured: keyOf({onMouseUpCapture: true}) - } - }, - paste: { - phasedRegistrationNames: { - bubbled: keyOf({onPaste: true}), - captured: keyOf({onPasteCapture: true}) - } - }, - reset: { - phasedRegistrationNames: { - bubbled: keyOf({onReset: true}), - captured: keyOf({onResetCapture: true}) - } - }, - scroll: { - phasedRegistrationNames: { - bubbled: keyOf({onScroll: true}), - captured: keyOf({onScrollCapture: true}) - } - }, - submit: { - phasedRegistrationNames: { - bubbled: keyOf({onSubmit: true}), - captured: keyOf({onSubmitCapture: true}) - } - }, - touchCancel: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchCancel: true}), - captured: keyOf({onTouchCancelCapture: true}) - } - }, - touchEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchEnd: true}), - captured: keyOf({onTouchEndCapture: true}) - } - }, - touchMove: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchMove: true}), - captured: keyOf({onTouchMoveCapture: true}) - } - }, - touchStart: { - phasedRegistrationNames: { - bubbled: keyOf({onTouchStart: true}), - captured: keyOf({onTouchStartCapture: true}) - } - }, - wheel: { - phasedRegistrationNames: { - bubbled: keyOf({onWheel: true}), - captured: keyOf({onWheelCapture: true}) - } - } -}; - -var topLevelEventsToDispatchConfig = { - topBlur: eventTypes.blur, - topClick: eventTypes.click, - topContextMenu: eventTypes.contextMenu, - topCopy: eventTypes.copy, - topCut: eventTypes.cut, - topDoubleClick: eventTypes.doubleClick, - topDrag: eventTypes.drag, - topDragEnd: eventTypes.dragEnd, - topDragEnter: eventTypes.dragEnter, - topDragExit: eventTypes.dragExit, - topDragLeave: eventTypes.dragLeave, - topDragOver: eventTypes.dragOver, - topDragStart: eventTypes.dragStart, - topDrop: eventTypes.drop, - topError: eventTypes.error, - topFocus: eventTypes.focus, - topInput: eventTypes.input, - topKeyDown: eventTypes.keyDown, - topKeyPress: eventTypes.keyPress, - topKeyUp: eventTypes.keyUp, - topLoad: eventTypes.load, - topMouseDown: eventTypes.mouseDown, - topMouseMove: eventTypes.mouseMove, - topMouseOut: eventTypes.mouseOut, - topMouseOver: eventTypes.mouseOver, - topMouseUp: eventTypes.mouseUp, - topPaste: eventTypes.paste, - topReset: eventTypes.reset, - topScroll: eventTypes.scroll, - topSubmit: eventTypes.submit, - topTouchCancel: eventTypes.touchCancel, - topTouchEnd: eventTypes.touchEnd, - topTouchMove: eventTypes.touchMove, - topTouchStart: eventTypes.touchStart, - topWheel: eventTypes.wheel -}; - -for (var type in topLevelEventsToDispatchConfig) { - topLevelEventsToDispatchConfig[type].dependencies = [type]; -} - -var SimpleEventPlugin = { - - eventTypes: eventTypes, - - /** - * Same as the default implementation, except cancels the event when return - * value is false. This behavior will be disabled in a future release. - * - * @param {object} Event to be dispatched. - * @param {function} Application-level callback. - * @param {string} domID DOM ID to pass to the callback. - */ - executeDispatch: function(event, listener, domID) { - var returnValue = EventPluginUtils.executeDispatch(event, listener, domID); - - ("production" !== "development" ? warning( - typeof returnValue !== 'boolean', - 'Returning `false` from an event handler is deprecated and will be ' + - 'ignored in a future release. Instead, manually call ' + - 'e.stopPropagation() or e.preventDefault(), as appropriate.' - ) : null); - - if (returnValue === false) { - event.stopPropagation(); - event.preventDefault(); - } - }, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; - if (!dispatchConfig) { - return null; - } - var EventConstructor; - switch (topLevelType) { - case topLevelTypes.topInput: - case topLevelTypes.topLoad: - case topLevelTypes.topError: - case topLevelTypes.topReset: - case topLevelTypes.topSubmit: - // HTML Events - // @see http://www.w3.org/TR/html5/index.html#events-0 - EventConstructor = SyntheticEvent; - break; - case topLevelTypes.topKeyPress: - // FireFox creates a keypress event for function keys too. This removes - // the unwanted keypress events. Enter is however both printable and - // non-printable. One would expect Tab to be as well (but it isn't). - if (getEventCharCode(nativeEvent) === 0) { - return null; - } - /* falls through */ - case topLevelTypes.topKeyDown: - case topLevelTypes.topKeyUp: - EventConstructor = SyntheticKeyboardEvent; - break; - case topLevelTypes.topBlur: - case topLevelTypes.topFocus: - EventConstructor = SyntheticFocusEvent; - break; - case topLevelTypes.topClick: - // Firefox creates a click event on right mouse clicks. This removes the - // unwanted click events. - if (nativeEvent.button === 2) { - return null; - } - /* falls through */ - case topLevelTypes.topContextMenu: - case topLevelTypes.topDoubleClick: - case topLevelTypes.topMouseDown: - case topLevelTypes.topMouseMove: - case topLevelTypes.topMouseOut: - case topLevelTypes.topMouseOver: - case topLevelTypes.topMouseUp: - EventConstructor = SyntheticMouseEvent; - break; - case topLevelTypes.topDrag: - case topLevelTypes.topDragEnd: - case topLevelTypes.topDragEnter: - case topLevelTypes.topDragExit: - case topLevelTypes.topDragLeave: - case topLevelTypes.topDragOver: - case topLevelTypes.topDragStart: - case topLevelTypes.topDrop: - EventConstructor = SyntheticDragEvent; - break; - case topLevelTypes.topTouchCancel: - case topLevelTypes.topTouchEnd: - case topLevelTypes.topTouchMove: - case topLevelTypes.topTouchStart: - EventConstructor = SyntheticTouchEvent; - break; - case topLevelTypes.topScroll: - EventConstructor = SyntheticUIEvent; - break; - case topLevelTypes.topWheel: - EventConstructor = SyntheticWheelEvent; - break; - case topLevelTypes.topCopy: - case topLevelTypes.topCut: - case topLevelTypes.topPaste: - EventConstructor = SyntheticClipboardEvent; - break; - } - ("production" !== "development" ? invariant( - EventConstructor, - 'SimpleEventPlugin: Unhandled event type, `%s`.', - topLevelType - ) : invariant(EventConstructor)); - var event = EventConstructor.getPooled( - dispatchConfig, - topLevelTargetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - -}; - -module.exports = SimpleEventPlugin; - -},{"100":100,"101":101,"102":102,"122":122,"135":135,"141":141,"15":15,"154":154,"19":19,"20":20,"92":92,"94":94,"95":95,"96":96,"98":98,"99":99}],92:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticClipboardEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(95); - -/** - * @interface Event - * @see http://www.w3.org/TR/clipboard-apis/ - */ -var ClipboardEventInterface = { - clipboardData: function(event) { - return ( - 'clipboardData' in event ? - event.clipboardData : - window.clipboardData - ); - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); - -module.exports = SyntheticClipboardEvent; - -},{"95":95}],93:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticCompositionEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(95); - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents - */ -var CompositionEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticCompositionEvent( - dispatchConfig, - dispatchMarker, - nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass( - SyntheticCompositionEvent, - CompositionEventInterface -); - -module.exports = SyntheticCompositionEvent; - -},{"95":95}],94:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticDragEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticMouseEvent = _dereq_(99); - -/** - * @interface DragEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var DragEventInterface = { - dataTransfer: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); - -module.exports = SyntheticDragEvent; - -},{"99":99}],95:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticEvent - * @typechecks static-only - */ - -'use strict'; - -var PooledClass = _dereq_(28); - -var assign = _dereq_(27); -var emptyFunction = _dereq_(114); -var getEventTarget = _dereq_(125); - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var EventInterface = { - type: null, - target: getEventTarget, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: emptyFunction.thatReturnsNull, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function(event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; - -/** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. - * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - */ -function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) { - this.dispatchConfig = dispatchConfig; - this.dispatchMarker = dispatchMarker; - this.nativeEvent = nativeEvent; - - var Interface = this.constructor.Interface; - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } - var normalize = Interface[propName]; - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - this[propName] = nativeEvent[propName]; - } - } - - var defaultPrevented = nativeEvent.defaultPrevented != null ? - nativeEvent.defaultPrevented : - nativeEvent.returnValue === false; - if (defaultPrevented) { - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - } else { - this.isDefaultPrevented = emptyFunction.thatReturnsFalse; - } - this.isPropagationStopped = emptyFunction.thatReturnsFalse; -} - -assign(SyntheticEvent.prototype, { - - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; - if (event.preventDefault) { - event.preventDefault(); - } else { - event.returnValue = false; - } - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - }, - - stopPropagation: function() { - var event = this.nativeEvent; - if (event.stopPropagation) { - event.stopPropagation(); - } else { - event.cancelBubble = true; - } - this.isPropagationStopped = emptyFunction.thatReturnsTrue; - }, - - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function() { - this.isPersistent = emptyFunction.thatReturnsTrue; - }, - - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: emptyFunction.thatReturnsFalse, - - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function() { - var Interface = this.constructor.Interface; - for (var propName in Interface) { - this[propName] = null; - } - this.dispatchConfig = null; - this.dispatchMarker = null; - this.nativeEvent = null; - } - -}); - -SyntheticEvent.Interface = EventInterface; - -/** - * Helper to reduce boilerplate when creating subclasses. - * - * @param {function} Class - * @param {?object} Interface - */ -SyntheticEvent.augmentClass = function(Class, Interface) { - var Super = this; - - var prototype = Object.create(Super.prototype); - assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - - Class.Interface = assign({}, Super.Interface, Interface); - Class.augmentClass = Super.augmentClass; - - PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler); -}; - -PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler); - -module.exports = SyntheticEvent; - -},{"114":114,"125":125,"27":27,"28":28}],96:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticFocusEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(101); - -/** - * @interface FocusEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var FocusEventInterface = { - relatedTarget: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); - -module.exports = SyntheticFocusEvent; - -},{"101":101}],97:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticInputEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(95); - -/** - * @interface Event - * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 - * /#events-inputevents - */ -var InputEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticInputEvent( - dispatchConfig, - dispatchMarker, - nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass( - SyntheticInputEvent, - InputEventInterface -); - -module.exports = SyntheticInputEvent; - -},{"95":95}],98:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticKeyboardEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(101); - -var getEventCharCode = _dereq_(122); -var getEventKey = _dereq_(123); -var getEventModifierState = _dereq_(124); - -/** - * @interface KeyboardEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var KeyboardEventInterface = { - key: getEventKey, - location: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - repeat: null, - locale: null, - getModifierState: getEventModifierState, - // Legacy Interface - charCode: function(event) { - // `charCode` is the result of a KeyPress event and represents the value of - // the actual printable character. - - // KeyPress is deprecated, but its replacement is not yet final and not - // implemented in any major browser. Only KeyPress has charCode. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - return 0; - }, - keyCode: function(event) { - // `keyCode` is the result of a KeyDown/Up event and represents the value of - // physical keyboard key. - - // The actual meaning of the value depends on the users' keyboard layout - // which cannot be detected. Assuming that it is a US keyboard layout - // provides a surprisingly accurate mapping for US and European users. - // Due to this, it is left to the user to implement at this time. - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - }, - which: function(event) { - // `which` is an alias for either `keyCode` or `charCode` depending on the - // type of the event. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); - -module.exports = SyntheticKeyboardEvent; - -},{"101":101,"122":122,"123":123,"124":124}],99:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticMouseEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(101); -var ViewportMetrics = _dereq_(104); - -var getEventModifierState = _dereq_(124); - -/** - * @interface MouseEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var MouseEventInterface = { - screenX: null, - screenY: null, - clientX: null, - clientY: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - getModifierState: getEventModifierState, - button: function(event) { - // Webkit, Firefox, IE9+ - // which: 1 2 3 - // button: 0 1 2 (standard) - var button = event.button; - if ('which' in event) { - return button; - } - // IE<9 - // which: undefined - // button: 0 0 0 - // button: 1 4 2 (onmouseup) - return button === 2 ? 2 : button === 4 ? 1 : 0; - }, - buttons: null, - relatedTarget: function(event) { - return event.relatedTarget || ( - ((event.fromElement === event.srcElement ? event.toElement : event.fromElement)) - ); - }, - // "Proprietary" Interface. - pageX: function(event) { - return 'pageX' in event ? - event.pageX : - event.clientX + ViewportMetrics.currentScrollLeft; - }, - pageY: function(event) { - return 'pageY' in event ? - event.pageY : - event.clientY + ViewportMetrics.currentScrollTop; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); - -module.exports = SyntheticMouseEvent; - -},{"101":101,"104":104,"124":124}],100:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticTouchEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticUIEvent = _dereq_(101); - -var getEventModifierState = _dereq_(124); - -/** - * @interface TouchEvent - * @see http://www.w3.org/TR/touch-events/ - */ -var TouchEventInterface = { - touches: null, - targetTouches: null, - changedTouches: null, - altKey: null, - metaKey: null, - ctrlKey: null, - shiftKey: null, - getModifierState: getEventModifierState -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); - -module.exports = SyntheticTouchEvent; - -},{"101":101,"124":124}],101:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticUIEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticEvent = _dereq_(95); - -var getEventTarget = _dereq_(125); - -/** - * @interface UIEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var UIEventInterface = { - view: function(event) { - if (event.view) { - return event.view; - } - - var target = getEventTarget(event); - if (target != null && target.window === target) { - // target is a window object - return target; - } - - var doc = target.ownerDocument; - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - if (doc) { - return doc.defaultView || doc.parentWindow; - } else { - return window; - } - }, - detail: function(event) { - return event.detail || 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); - -module.exports = SyntheticUIEvent; - -},{"125":125,"95":95}],102:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule SyntheticWheelEvent - * @typechecks static-only - */ - -'use strict'; - -var SyntheticMouseEvent = _dereq_(99); - -/** - * @interface WheelEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var WheelEventInterface = { - deltaX: function(event) { - return ( - 'deltaX' in event ? event.deltaX : - // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). - 'wheelDeltaX' in event ? -event.wheelDeltaX : 0 - ); - }, - deltaY: function(event) { - return ( - 'deltaY' in event ? event.deltaY : - // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). - 'wheelDeltaY' in event ? -event.wheelDeltaY : - // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). - 'wheelDelta' in event ? -event.wheelDelta : 0 - ); - }, - deltaZ: null, - - // Browsers without "deltaMode" is reporting in raw wheel delta where one - // notch on the scroll is always +/- 120, roughly equivalent to pixels. - // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or - // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. - deltaMode: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticMouseEvent} - */ -function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); -} - -SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); - -module.exports = SyntheticWheelEvent; - -},{"99":99}],103:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Transaction - */ - -'use strict'; - -var invariant = _dereq_(135); - -/** - * `Transaction` creates a black box that is able to wrap any method such that - * certain invariants are maintained before and after the method is invoked - * (Even if an exception is thrown while invoking the wrapped method). Whoever - * instantiates a transaction can provide enforcers of the invariants at - * creation time. The `Transaction` class itself will supply one additional - * automatic invariant for you - the invariant that any transaction instance - * should not be run while it is already being run. You would typically create a - * single instance of a `Transaction` for reuse multiple times, that potentially - * is used to wrap several different methods. Wrappers are extremely simple - - * they only require implementing two methods. - * - * <pre> - * wrappers (injected at creation time) - * + + - * | | - * +-----------------|--------|--------------+ - * | v | | - * | +---------------+ | | - * | +--| wrapper1 |---|----+ | - * | | +---------------+ v | | - * | | +-------------+ | | - * | | +----| wrapper2 |--------+ | - * | | | +-------------+ | | | - * | | | | | | - * | v v v v | wrapper - * | +---+ +---+ +---------+ +---+ +---+ | invariants - * perform(anyMethod) | | | | | | | | | | | | maintained - * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|--------> - * | | | | | | | | | | | | - * | | | | | | | | | | | | - * | | | | | | | | | | | | - * | +---+ +---+ +---------+ +---+ +---+ | - * | initialize close | - * +-----------------------------------------+ - * </pre> - * - * Use cases: - * - Preserving the input selection ranges before/after reconciliation. - * Restoring selection even in the event of an unexpected error. - * - Deactivating events while rearranging the DOM, preventing blurs/focuses, - * while guaranteeing that afterwards, the event system is reactivated. - * - Flushing a queue of collected DOM mutations to the main UI thread after a - * reconciliation takes place in a worker thread. - * - Invoking any collected `componentDidUpdate` callbacks after rendering new - * content. - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue - * to preserve the `scrollTop` (an automatic scroll aware DOM). - * - (Future use case): Layout calculations before and after DOM updates. - * - * Transactional plugin API: - * - A module that has an `initialize` method that returns any precomputation. - * - and a `close` method that accepts the precomputation. `close` is invoked - * when the wrapped process is completed, or has failed. - * - * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules - * that implement `initialize` and `close`. - * @return {Transaction} Single transaction for reuse in thread. - * - * @class Transaction - */ -var Mixin = { - /** - * Sets up this instance so that it is prepared for collecting metrics. Does - * so such that this setup method may be used on an instance that is already - * initialized, in a way that does not consume additional memory upon reuse. - * That can be useful if you decide to make your subclass of this mixin a - * "PooledClass". - */ - reinitializeTransaction: function() { - this.transactionWrappers = this.getTransactionWrappers(); - if (!this.wrapperInitData) { - this.wrapperInitData = []; - } else { - this.wrapperInitData.length = 0; - } - this._isInTransaction = false; - }, - - _isInTransaction: false, - - /** - * @abstract - * @return {Array<TransactionWrapper>} Array of transaction wrappers. - */ - getTransactionWrappers: null, - - isInTransaction: function() { - return !!this._isInTransaction; - }, - - /** - * Executes the function within a safety window. Use this for the top level - * methods that result in large amounts of computation/mutations that would - * need to be safety checked. - * - * @param {function} method Member of scope to call. - * @param {Object} scope Scope to invoke from. - * @param {Object?=} args... Arguments to pass to the method (optional). - * Helps prevent need to bind in many cases. - * @return Return value from `method`. - */ - perform: function(method, scope, a, b, c, d, e, f) { - ("production" !== "development" ? invariant( - !this.isInTransaction(), - 'Transaction.perform(...): Cannot initialize a transaction when there ' + - 'is already an outstanding transaction.' - ) : invariant(!this.isInTransaction())); - var errorThrown; - var ret; - try { - this._isInTransaction = true; - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // one of these calls threw. - errorThrown = true; - this.initializeAll(0); - ret = method.call(scope, a, b, c, d, e, f); - errorThrown = false; - } finally { - try { - if (errorThrown) { - // If `method` throws, prefer to show that stack trace over any thrown - // by invoking `closeAll`. - try { - this.closeAll(0); - } catch (err) { - } - } else { - // Since `method` didn't throw, we don't want to silence the exception - // here. - this.closeAll(0); - } - } finally { - this._isInTransaction = false; - } - } - return ret; - }, - - initializeAll: function(startIndex) { - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - try { - // Catching errors makes debugging more difficult, so we start with the - // OBSERVED_ERROR state before overwriting it with the real return value - // of initialize -- if it's still set to OBSERVED_ERROR in the finally - // block, it means wrapper.initialize threw. - this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; - this.wrapperInitData[i] = wrapper.initialize ? - wrapper.initialize.call(this) : - null; - } finally { - if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { - // The initializer for wrapper i threw an error; initialize the - // remaining wrappers but silence any exceptions from them to ensure - // that the first error is the one to bubble up. - try { - this.initializeAll(i + 1); - } catch (err) { - } - } - } - } - }, - - /** - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into - * them the respective return values of `this.transactionWrappers.init[i]` - * (`close`rs that correspond to initializers that failed will not be - * invoked). - */ - closeAll: function(startIndex) { - ("production" !== "development" ? invariant( - this.isInTransaction(), - 'Transaction.closeAll(): Cannot close transaction when none are open.' - ) : invariant(this.isInTransaction())); - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - var initData = this.wrapperInitData[i]; - var errorThrown; - try { - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // wrapper.close threw. - errorThrown = true; - if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) { - wrapper.close.call(this, initData); - } - errorThrown = false; - } finally { - if (errorThrown) { - // The closer for wrapper i threw an error; close the remaining - // wrappers but silence any exceptions from them to ensure that the - // first error is the one to bubble up. - try { - this.closeAll(i + 1); - } catch (e) { - } - } - } - } - this.wrapperInitData.length = 0; - } -}; - -var Transaction = { - - Mixin: Mixin, - - /** - * Token to look for to determine if an error occured. - */ - OBSERVED_ERROR: {} - -}; - -module.exports = Transaction; - -},{"135":135}],104:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ViewportMetrics - */ - -'use strict'; - -var ViewportMetrics = { - - currentScrollLeft: 0, - - currentScrollTop: 0, - - refreshScrollValues: function(scrollPosition) { - ViewportMetrics.currentScrollLeft = scrollPosition.x; - ViewportMetrics.currentScrollTop = scrollPosition.y; - } - -}; - -module.exports = ViewportMetrics; - -},{}],105:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule accumulateInto - */ - -'use strict'; - -var invariant = _dereq_(135); - -/** - * - * Accumulates items that must not be null or undefined into the first one. This - * is used to conserve memory by avoiding array allocations, and thus sacrifices - * API cleanness. Since `current` can be null before being passed in and not - * null after this function, make sure to assign it back to `current`: - * - * `a = accumulateInto(a, b);` - * - * This API should be sparingly used. Try `accumulate` for something cleaner. - * - * @return {*|array<*>} An accumulation of items. - */ - -function accumulateInto(current, next) { - ("production" !== "development" ? invariant( - next != null, - 'accumulateInto(...): Accumulated items must not be null or undefined.' - ) : invariant(next != null)); - if (current == null) { - return next; - } - - // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - var currentIsArray = Array.isArray(current); - var nextIsArray = Array.isArray(next); - - if (currentIsArray && nextIsArray) { - current.push.apply(current, next); - return current; - } - - if (currentIsArray) { - current.push(next); - return current; - } - - if (nextIsArray) { - // A bit too dangerous to mutate `next`. - return [current].concat(next); - } - - return [current, next]; -} - -module.exports = accumulateInto; - -},{"135":135}],106:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule adler32 - */ - -/* jslint bitwise:true */ - -'use strict'; - -var MOD = 65521; - -// This is a clean-room implementation of adler32 designed for detecting -// if markup is not what we expect it to be. It does not need to be -// cryptographically strong, only reasonably good at detecting if markup -// generated on the server is different than that on the client. -function adler32(data) { - var a = 1; - var b = 0; - for (var i = 0; i < data.length; i++) { - a = (a + data.charCodeAt(i)) % MOD; - b = (b + a) % MOD; - } - return a | (b << 16); -} - -module.exports = adler32; - -},{}],107:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule camelize - * @typechecks - */ - -var _hyphenPattern = /-(.)/g; - -/** - * Camelcases a hyphenated string, for example: - * - * > camelize('background-color') - * < "backgroundColor" - * - * @param {string} string - * @return {string} - */ -function camelize(string) { - return string.replace(_hyphenPattern, function(_, character) { - return character.toUpperCase(); - }); -} - -module.exports = camelize; - -},{}],108:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule camelizeStyleName - * @typechecks - */ - -"use strict"; - -var camelize = _dereq_(107); - -var msPattern = /^-ms-/; - -/** - * Camelcases a hyphenated CSS property name, for example: - * - * > camelizeStyleName('background-color') - * < "backgroundColor" - * > camelizeStyleName('-moz-transition') - * < "MozTransition" - * > camelizeStyleName('-ms-transition') - * < "msTransition" - * - * As Andi Smith suggests - * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix - * is converted to lowercase `ms`. - * - * @param {string} string - * @return {string} - */ -function camelizeStyleName(string) { - return camelize(string.replace(msPattern, 'ms-')); -} - -module.exports = camelizeStyleName; - -},{"107":107}],109:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule containsNode - * @typechecks - */ - -var isTextNode = _dereq_(139); - -/*jslint bitwise:true */ - -/** - * Checks if a given DOM node contains or is another DOM node. - * - * @param {?DOMNode} outerNode Outer DOM node. - * @param {?DOMNode} innerNode Inner DOM node. - * @return {boolean} True if `outerNode` contains or is `innerNode`. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if (outerNode.contains) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; - -},{"139":139}],110:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createArrayFromMixed - * @typechecks - */ - -var toArray = _dereq_(152); - -/** - * Perform a heuristic test to determine if an object is "array-like". - * - * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" - * Joshu replied: "Mu." - * - * This function determines if its argument has "array nature": it returns - * true if the argument is an actual array, an `arguments' object, or an - * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). - * - * It will return false for other array-like objects like Filelist. - * - * @param {*} obj - * @return {boolean} - */ -function hasArrayNature(obj) { - return ( - // not null/false - !!obj && - // arrays are objects, NodeLists are functions in Safari - (typeof obj == 'object' || typeof obj == 'function') && - // quacks like an array - ('length' in obj) && - // not window - !('setInterval' in obj) && - // no DOM node should be considered an array-like - // a 'select' element has 'length' and 'item' properties on IE8 - (typeof obj.nodeType != 'number') && - ( - // a real array - (// HTMLCollection/NodeList - (Array.isArray(obj) || - // arguments - ('callee' in obj) || 'item' in obj)) - ) - ); -} - -/** - * Ensure that the argument is an array by wrapping it in an array if it is not. - * Creates a copy of the argument if it is already an array. - * - * This is mostly useful idiomatically: - * - * var createArrayFromMixed = require('createArrayFromMixed'); - * - * function takesOneOrMoreThings(things) { - * things = createArrayFromMixed(things); - * ... - * } - * - * This allows you to treat `things' as an array, but accept scalars in the API. - * - * If you need to convert an array-like object, like `arguments`, into an array - * use toArray instead. - * - * @param {*} obj - * @return {array} - */ -function createArrayFromMixed(obj) { - if (!hasArrayNature(obj)) { - return [obj]; - } else if (Array.isArray(obj)) { - return obj.slice(); - } else { - return toArray(obj); - } -} - -module.exports = createArrayFromMixed; - -},{"152":152}],111:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createFullPageComponent - * @typechecks - */ - -'use strict'; - -// Defeat circular references by requiring this directly. -var ReactClass = _dereq_(33); -var ReactElement = _dereq_(57); - -var invariant = _dereq_(135); - -/** - * Create a component that will throw an exception when unmounted. - * - * Components like <html> <head> and <body> can't be removed or added - * easily in a cross-browser way, however it's valuable to be able to - * take advantage of React's reconciliation for styling and <title> - * management. So we just document it and throw in dangerous cases. - * - * @param {string} tag The tag to wrap - * @return {function} convenience constructor of new component - */ -function createFullPageComponent(tag) { - var elementFactory = ReactElement.createFactory(tag); - - var FullPageComponent = ReactClass.createClass({ - tagName: tag.toUpperCase(), - displayName: 'ReactFullPageComponent' + tag, - - componentWillUnmount: function() { - ("production" !== "development" ? invariant( - false, - '%s tried to unmount. Because of cross-browser quirks it is ' + - 'impossible to unmount some top-level components (eg <html>, <head>, ' + - 'and <body>) reliably and efficiently. To fix this, have a single ' + - 'top-level component that never unmounts render these elements.', - this.constructor.displayName - ) : invariant(false)); - }, - - render: function() { - return elementFactory(this.props); - } - }); - - return FullPageComponent; -} - -module.exports = createFullPageComponent; - -},{"135":135,"33":33,"57":57}],112:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createNodesFromMarkup - * @typechecks - */ - -/*jslint evil: true, sub: true */ - -var ExecutionEnvironment = _dereq_(21); - -var createArrayFromMixed = _dereq_(110); -var getMarkupWrap = _dereq_(127); -var invariant = _dereq_(135); - -/** - * Dummy container used to render all markup. - */ -var dummyNode = - ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Pattern used by `getNodeName`. - */ -var nodeNamePattern = /^\s*<(\w+)/; - -/** - * Extracts the `nodeName` of the first element in a string of markup. - * - * @param {string} markup String of markup. - * @return {?string} Node name of the supplied markup. - */ -function getNodeName(markup) { - var nodeNameMatch = markup.match(nodeNamePattern); - return nodeNameMatch && nodeNameMatch[1].toLowerCase(); -} - -/** - * Creates an array containing the nodes rendered from the supplied markup. The - * optionally supplied `handleScript` function will be invoked once for each - * <script> element that is rendered. If no `handleScript` function is supplied, - * an exception is thrown if any <script> elements are rendered. - * - * @param {string} markup A string of valid HTML markup. - * @param {?function} handleScript Invoked once for each rendered <script>. - * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. - */ -function createNodesFromMarkup(markup, handleScript) { - var node = dummyNode; - ("production" !== "development" ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode)); - var nodeName = getNodeName(markup); - - var wrap = nodeName && getMarkupWrap(nodeName); - if (wrap) { - node.innerHTML = wrap[1] + markup + wrap[2]; - - var wrapDepth = wrap[0]; - while (wrapDepth--) { - node = node.lastChild; - } - } else { - node.innerHTML = markup; - } - - var scripts = node.getElementsByTagName('script'); - if (scripts.length) { - ("production" !== "development" ? invariant( - handleScript, - 'createNodesFromMarkup(...): Unexpected <script> element rendered.' - ) : invariant(handleScript)); - createArrayFromMixed(scripts).forEach(handleScript); - } - - var nodes = createArrayFromMixed(node.childNodes); - while (node.lastChild) { - node.removeChild(node.lastChild); - } - return nodes; -} - -module.exports = createNodesFromMarkup; - -},{"110":110,"127":127,"135":135,"21":21}],113:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule dangerousStyleValue - * @typechecks static-only - */ - -'use strict'; - -var CSSProperty = _dereq_(4); - -var isUnitlessNumber = CSSProperty.isUnitlessNumber; - -/** - * Convert a value into the proper css writable value. The style name `name` - * should be logical (no hyphens), as specified - * in `CSSProperty.isUnitlessNumber`. - * - * @param {string} name CSS property name such as `topMargin`. - * @param {*} value CSS property value such as `10px`. - * @return {string} Normalized style value with dimensions applied. - */ -function dangerousStyleValue(name, value) { - // Note that we've removed escapeTextForBrowser() calls here since the - // whole string will be escaped when the attribute is injected into - // the markup. If you provide unsafe user data here they can inject - // arbitrary CSS which may be problematic (I couldn't repro this): - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ - // This is not an XSS hole but instead a potential CSS injection issue - // which has lead to a greater discussion about how we're going to - // trust URLs moving forward. See #2115901 - - var isEmpty = value == null || typeof value === 'boolean' || value === ''; - if (isEmpty) { - return ''; - } - - var isNonNumeric = isNaN(value); - if (isNonNumeric || value === 0 || - isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { - return '' + value; // cast to string - } - - if (typeof value === 'string') { - value = value.trim(); - } - return value + 'px'; -} - -module.exports = dangerousStyleValue; - -},{"4":4}],114:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule emptyFunction - */ - -function makeEmptyFunction(arg) { - return function() { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -function emptyFunction() {} - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function() { return this; }; -emptyFunction.thatReturnsArgument = function(arg) { return arg; }; - -module.exports = emptyFunction; - -},{}],115:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule emptyObject - */ - -"use strict"; - -var emptyObject = {}; - -if ("production" !== "development") { - Object.freeze(emptyObject); -} - -module.exports = emptyObject; - -},{}],116:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule escapeTextContentForBrowser - */ - -'use strict'; - -var ESCAPE_LOOKUP = { - '&': '&', - '>': '>', - '<': '<', - '"': '"', - '\'': ''' -}; - -var ESCAPE_REGEX = /[&><"']/g; - -function escaper(match) { - return ESCAPE_LOOKUP[match]; -} - -/** - * Escapes text to prevent scripting attacks. - * - * @param {*} text Text value to escape. - * @return {string} An escaped string. - */ -function escapeTextContentForBrowser(text) { - return ('' + text).replace(ESCAPE_REGEX, escaper); -} - -module.exports = escapeTextContentForBrowser; - -},{}],117:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule findDOMNode - * @typechecks static-only - */ - -'use strict'; - -var ReactCurrentOwner = _dereq_(39); -var ReactInstanceMap = _dereq_(67); -var ReactMount = _dereq_(70); - -var invariant = _dereq_(135); -var isNode = _dereq_(137); -var warning = _dereq_(154); - -/** - * Returns the DOM node rendered by this element. - * - * @param {ReactComponent|DOMElement} componentOrElement - * @return {DOMElement} The root node of this element. - */ -function findDOMNode(componentOrElement) { - if ("production" !== "development") { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - ("production" !== "development" ? warning( - owner._warnedAboutRefsInRender, - '%s is accessing getDOMNode or findDOMNode inside its render(). ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ) : null); - owner._warnedAboutRefsInRender = true; - } - } - if (componentOrElement == null) { - return null; - } - if (isNode(componentOrElement)) { - return componentOrElement; - } - if (ReactInstanceMap.has(componentOrElement)) { - return ReactMount.getNodeFromInstance(componentOrElement); - } - ("production" !== "development" ? invariant( - componentOrElement.render == null || - typeof componentOrElement.render !== 'function', - 'Component (with keys: %s) contains `render` method ' + - 'but is not mounted in the DOM', - Object.keys(componentOrElement) - ) : invariant(componentOrElement.render == null || - typeof componentOrElement.render !== 'function')); - ("production" !== "development" ? invariant( - false, - 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', - Object.keys(componentOrElement) - ) : invariant(false)); -} - -module.exports = findDOMNode; - -},{"135":135,"137":137,"154":154,"39":39,"67":67,"70":70}],118:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule flattenChildren - */ - -'use strict'; - -var traverseAllChildren = _dereq_(153); -var warning = _dereq_(154); - -/** - * @param {function} traverseContext Context passed through traversal. - * @param {?ReactComponent} child React child component. - * @param {!string} name String name of key path to child. - */ -function flattenSingleChildIntoContext(traverseContext, child, name) { - // We found a component instance. - var result = traverseContext; - var keyUnique = !result.hasOwnProperty(name); - if ("production" !== "development") { - ("production" !== "development" ? warning( - keyUnique, - 'flattenChildren(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ) : null); - } - if (keyUnique && child != null) { - result[name] = child; - } -} - -/** - * Flattens children that are typically specified as `props.children`. Any null - * children will not be included in the resulting object. - * @return {!object} flattened children keyed by name. - */ -function flattenChildren(children) { - if (children == null) { - return children; - } - var result = {}; - traverseAllChildren(children, flattenSingleChildIntoContext, result); - return result; -} - -module.exports = flattenChildren; - -},{"153":153,"154":154}],119:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule focusNode - */ - -"use strict"; - -/** - * @param {DOMElement} node input/textarea to focus - */ -function focusNode(node) { - // IE8 can throw "Can't move focus to the control because it is invisible, - // not enabled, or of a type that does not accept the focus." for all kinds of - // reasons that are too expensive and fragile to test. - try { - node.focus(); - } catch(e) { - } -} - -module.exports = focusNode; - -},{}],120:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule forEachAccumulated - */ - -'use strict'; - -/** - * @param {array} an "accumulation" of items which is either an Array or - * a single item. Useful when paired with the `accumulate` module. This is a - * simple utility that allows us to reason about a collection of items, but - * handling the case when there is exactly one item (and we do not need to - * allocate an array). - */ -var forEachAccumulated = function(arr, cb, scope) { - if (Array.isArray(arr)) { - arr.forEach(cb, scope); - } else if (arr) { - cb.call(scope, arr); - } -}; - -module.exports = forEachAccumulated; - -},{}],121:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getActiveElement - * @typechecks - */ - -/** - * Same as document.activeElement but wraps in a try-catch block. In IE it is - * not safe to call document.activeElement if there is nothing focused. - * - * The activeElement will be null only if the document body is not yet defined. - */ -function getActiveElement() /*?DOMElement*/ { - try { - return document.activeElement || document.body; - } catch (e) { - return document.body; - } -} - -module.exports = getActiveElement; - -},{}],122:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventCharCode - * @typechecks static-only - */ - -'use strict'; - -/** - * `charCode` represents the actual "character code" and is safe to use with - * `String.fromCharCode`. As such, only keys that correspond to printable - * characters produce a valid `charCode`, the only exception to this is Enter. - * The Tab-key is considered non-printable and does not have a `charCode`, - * presumably because it does not produce a tab-character in browsers. - * - * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `charCode` property. - */ -function getEventCharCode(nativeEvent) { - var charCode; - var keyCode = nativeEvent.keyCode; - - if ('charCode' in nativeEvent) { - charCode = nativeEvent.charCode; - - // FF does not set `charCode` for the Enter-key, check against `keyCode`. - if (charCode === 0 && keyCode === 13) { - charCode = 13; - } - } else { - // IE8 does not implement `charCode`, but `keyCode` has the correct value. - charCode = keyCode; - } - - // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. - // Must not discard the (non-)printable Enter-key. - if (charCode >= 32 || charCode === 13) { - return charCode; - } - - return 0; -} - -module.exports = getEventCharCode; - -},{}],123:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventKey - * @typechecks static-only - */ - -'use strict'; - -var getEventCharCode = _dereq_(122); - -/** - * Normalization of deprecated HTML5 `key` values - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var normalizeKey = { - 'Esc': 'Escape', - 'Spacebar': ' ', - 'Left': 'ArrowLeft', - 'Up': 'ArrowUp', - 'Right': 'ArrowRight', - 'Down': 'ArrowDown', - 'Del': 'Delete', - 'Win': 'OS', - 'Menu': 'ContextMenu', - 'Apps': 'ContextMenu', - 'Scroll': 'ScrollLock', - 'MozPrintableKey': 'Unidentified' -}; - -/** - * Translation from legacy `keyCode` to HTML5 `key` - * Only special keys supported, all others depend on keyboard layout or browser - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var translateToKey = { - 8: 'Backspace', - 9: 'Tab', - 12: 'Clear', - 13: 'Enter', - 16: 'Shift', - 17: 'Control', - 18: 'Alt', - 19: 'Pause', - 20: 'CapsLock', - 27: 'Escape', - 32: ' ', - 33: 'PageUp', - 34: 'PageDown', - 35: 'End', - 36: 'Home', - 37: 'ArrowLeft', - 38: 'ArrowUp', - 39: 'ArrowRight', - 40: 'ArrowDown', - 45: 'Insert', - 46: 'Delete', - 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', - 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', - 144: 'NumLock', - 145: 'ScrollLock', - 224: 'Meta' -}; - -/** - * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `key` property. - */ -function getEventKey(nativeEvent) { - if (nativeEvent.key) { - // Normalize inconsistent values reported by browsers due to - // implementations of a working draft specification. - - // FireFox implements `key` but returns `MozPrintableKey` for all - // printable characters (normalized to `Unidentified`), ignore it. - var key = normalizeKey[nativeEvent.key] || nativeEvent.key; - if (key !== 'Unidentified') { - return key; - } - } - - // Browser does not implement `key`, polyfill as much of it as we can. - if (nativeEvent.type === 'keypress') { - var charCode = getEventCharCode(nativeEvent); - - // The enter-key is technically both printable and non-printable and can - // thus be captured by `keypress`, no other non-printable key should. - return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); - } - if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { - // While user keyboard layout determines the actual meaning of each - // `keyCode` value, almost all function keys have a universal value. - return translateToKey[nativeEvent.keyCode] || 'Unidentified'; - } - return ''; -} - -module.exports = getEventKey; - -},{"122":122}],124:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventModifierState - * @typechecks static-only - */ - -'use strict'; - -/** - * Translation from modifier key to the associated property in the event. - * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers - */ - -var modifierKeyToProp = { - 'Alt': 'altKey', - 'Control': 'ctrlKey', - 'Meta': 'metaKey', - 'Shift': 'shiftKey' -}; - -// IE8 does not implement getModifierState so we simply map it to the only -// modifier keys exposed by the event itself, does not support Lock-keys. -// Currently, all major browsers except Chrome seems to support Lock-keys. -function modifierStateGetter(keyArg) { - /*jshint validthis:true */ - var syntheticEvent = this; - var nativeEvent = syntheticEvent.nativeEvent; - if (nativeEvent.getModifierState) { - return nativeEvent.getModifierState(keyArg); - } - var keyProp = modifierKeyToProp[keyArg]; - return keyProp ? !!nativeEvent[keyProp] : false; -} - -function getEventModifierState(nativeEvent) { - return modifierStateGetter; -} - -module.exports = getEventModifierState; - -},{}],125:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getEventTarget - * @typechecks static-only - */ - -'use strict'; - -/** - * Gets the target node from a native browser event by accounting for - * inconsistencies in browser DOM APIs. - * - * @param {object} nativeEvent Native browser event. - * @return {DOMEventTarget} Target node. - */ -function getEventTarget(nativeEvent) { - var target = nativeEvent.target || nativeEvent.srcElement || window; - // Safari may fire events on text nodes (Node.TEXT_NODE is 3). - // @see http://www.quirksmode.org/js/events_properties.html - return target.nodeType === 3 ? target.parentNode : target; -} - -module.exports = getEventTarget; - -},{}],126:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getIteratorFn - * @typechecks static-only - */ - -'use strict'; - -/* global Symbol */ -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && ( - (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]) - ); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; - -},{}],127:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getMarkupWrap - */ - -var ExecutionEnvironment = _dereq_(21); - -var invariant = _dereq_(135); - -/** - * Dummy container used to detect which wraps are necessary. - */ -var dummyNode = - ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Some browsers cannot use `innerHTML` to render certain elements standalone, - * so we wrap them, render the wrapped nodes, then extract the desired node. - * - * In IE8, certain elements cannot render alone, so wrap all elements ('*'). - */ -var shouldWrap = { - // Force wrapping for SVG elements because if they get created inside a <div>, - // they will be initialized in the wrong namespace (and will not display). - 'circle': true, - 'clipPath': true, - 'defs': true, - 'ellipse': true, - 'g': true, - 'line': true, - 'linearGradient': true, - 'path': true, - 'polygon': true, - 'polyline': true, - 'radialGradient': true, - 'rect': true, - 'stop': true, - 'text': true -}; - -var selectWrap = [1, '<select multiple="true">', '</select>']; -var tableWrap = [1, '<table>', '</table>']; -var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; - -var svgWrap = [1, '<svg>', '</svg>']; - -var markupWrap = { - '*': [1, '?<div>', '</div>'], - - 'area': [1, '<map>', '</map>'], - 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], - 'legend': [1, '<fieldset>', '</fieldset>'], - 'param': [1, '<object>', '</object>'], - 'tr': [2, '<table><tbody>', '</tbody></table>'], - - 'optgroup': selectWrap, - 'option': selectWrap, - - 'caption': tableWrap, - 'colgroup': tableWrap, - 'tbody': tableWrap, - 'tfoot': tableWrap, - 'thead': tableWrap, - - 'td': trWrap, - 'th': trWrap, - - 'circle': svgWrap, - 'clipPath': svgWrap, - 'defs': svgWrap, - 'ellipse': svgWrap, - 'g': svgWrap, - 'line': svgWrap, - 'linearGradient': svgWrap, - 'path': svgWrap, - 'polygon': svgWrap, - 'polyline': svgWrap, - 'radialGradient': svgWrap, - 'rect': svgWrap, - 'stop': svgWrap, - 'text': svgWrap -}; - -/** - * Gets the markup wrap configuration for the supplied `nodeName`. - * - * NOTE: This lazily detects which wraps are necessary for the current browser. - * - * @param {string} nodeName Lowercase `nodeName`. - * @return {?array} Markup wrap configuration, if applicable. - */ -function getMarkupWrap(nodeName) { - ("production" !== "development" ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode)); - if (!markupWrap.hasOwnProperty(nodeName)) { - nodeName = '*'; - } - if (!shouldWrap.hasOwnProperty(nodeName)) { - if (nodeName === '*') { - dummyNode.innerHTML = '<link />'; - } else { - dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; - } - shouldWrap[nodeName] = !dummyNode.firstChild; - } - return shouldWrap[nodeName] ? markupWrap[nodeName] : null; -} - - -module.exports = getMarkupWrap; - -},{"135":135,"21":21}],128:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getNodeForCharacterOffset - */ - -'use strict'; - -/** - * Given any node return the first leaf node without children. - * - * @param {DOMElement|DOMTextNode} node - * @return {DOMElement|DOMTextNode} - */ -function getLeafNode(node) { - while (node && node.firstChild) { - node = node.firstChild; - } - return node; -} - -/** - * Get the next sibling within a container. This will walk up the - * DOM if a node's siblings have been exhausted. - * - * @param {DOMElement|DOMTextNode} node - * @return {?DOMElement|DOMTextNode} - */ -function getSiblingNode(node) { - while (node) { - if (node.nextSibling) { - return node.nextSibling; - } - node = node.parentNode; - } -} - -/** - * Get object describing the nodes which contain characters at offset. - * - * @param {DOMElement|DOMTextNode} root - * @param {number} offset - * @return {?object} - */ -function getNodeForCharacterOffset(root, offset) { - var node = getLeafNode(root); - var nodeStart = 0; - var nodeEnd = 0; - - while (node) { - if (node.nodeType === 3) { - nodeEnd = nodeStart + node.textContent.length; - - if (nodeStart <= offset && nodeEnd >= offset) { - return { - node: node, - offset: offset - nodeStart - }; - } - - nodeStart = nodeEnd; - } - - node = getLeafNode(getSiblingNode(node)); - } -} - -module.exports = getNodeForCharacterOffset; - -},{}],129:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getReactRootElementInContainer - */ - -'use strict'; - -var DOC_NODE_TYPE = 9; - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -module.exports = getReactRootElementInContainer; - -},{}],130:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getTextContentAccessor - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(21); - -var contentKey = null; - -/** - * Gets the key used to access text content on a DOM node. - * - * @return {?string} Key used to access text content. - * @internal - */ -function getTextContentAccessor() { - if (!contentKey && ExecutionEnvironment.canUseDOM) { - // Prefer textContent to innerText because many browsers support both but - // SVG <text> elements don't support innerText even when <div> does. - contentKey = 'textContent' in document.documentElement ? - 'textContent' : - 'innerText'; - } - return contentKey; -} - -module.exports = getTextContentAccessor; - -},{"21":21}],131:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getUnboundedScrollPosition - * @typechecks - */ - -"use strict"; - -/** - * Gets the scroll position of the supplied element or window. - * - * The return values are unbounded, unlike `getScrollPosition`. This means they - * may be negative or exceed the element boundaries (which is possible using - * inertial scrolling). - * - * @param {DOMWindow|DOMElement} scrollable - * @return {object} Map with `x` and `y` keys. - */ -function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; - } - return { - x: scrollable.scrollLeft, - y: scrollable.scrollTop - }; -} - -module.exports = getUnboundedScrollPosition; - -},{}],132:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule hyphenate - * @typechecks - */ - -var _uppercasePattern = /([A-Z])/g; - -/** - * Hyphenates a camelcased string, for example: - * - * > hyphenate('backgroundColor') - * < "background-color" - * - * For CSS style names, use `hyphenateStyleName` instead which works properly - * with all vendor prefixes, including `ms`. - * - * @param {string} string - * @return {string} - */ -function hyphenate(string) { - return string.replace(_uppercasePattern, '-$1').toLowerCase(); -} - -module.exports = hyphenate; - -},{}],133:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule hyphenateStyleName - * @typechecks - */ - -"use strict"; - -var hyphenate = _dereq_(132); - -var msPattern = /^ms-/; - -/** - * Hyphenates a camelcased CSS property name, for example: - * - * > hyphenateStyleName('backgroundColor') - * < "background-color" - * > hyphenateStyleName('MozTransition') - * < "-moz-transition" - * > hyphenateStyleName('msTransition') - * < "-ms-transition" - * - * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix - * is converted to `-ms-`. - * - * @param {string} string - * @return {string} - */ -function hyphenateStyleName(string) { - return hyphenate(string).replace(msPattern, '-ms-'); -} - -module.exports = hyphenateStyleName; - -},{"132":132}],134:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule instantiateReactComponent - * @typechecks static-only - */ - -'use strict'; - -var ReactCompositeComponent = _dereq_(37); -var ReactEmptyComponent = _dereq_(59); -var ReactNativeComponent = _dereq_(73); - -var assign = _dereq_(27); -var invariant = _dereq_(135); -var warning = _dereq_(154); - -// To avoid a cyclic dependency, we create the final class in this module -var ReactCompositeComponentWrapper = function() { }; -assign( - ReactCompositeComponentWrapper.prototype, - ReactCompositeComponent.Mixin, - { - _instantiateReactComponent: instantiateReactComponent - } -); - -/** - * Check if the type reference is a known internal type. I.e. not a user - * provided composite type. - * - * @param {function} type - * @return {boolean} Returns true if this is a valid internal type. - */ -function isInternalComponentType(type) { - return ( - typeof type === 'function' && - typeof type.prototype !== 'undefined' && - typeof type.prototype.mountComponent === 'function' && - typeof type.prototype.receiveComponent === 'function' - ); -} - -/** - * Given a ReactNode, create an instance that will actually be mounted. - * - * @param {ReactNode} node - * @param {*} parentCompositeType The composite type that resolved this. - * @return {object} A new instance of the element's constructor. - * @protected - */ -function instantiateReactComponent(node, parentCompositeType) { - var instance; - - if (node === null || node === false) { - node = ReactEmptyComponent.emptyElement; - } - - if (typeof node === 'object') { - var element = node; - if ("production" !== "development") { - ("production" !== "development" ? warning( - element && (typeof element.type === 'function' || - typeof element.type === 'string'), - 'Only functions or strings can be mounted as React components.' - ) : null); - } - - // Special case string values - if (parentCompositeType === element.type && - typeof element.type === 'string') { - // Avoid recursion if the wrapper renders itself. - instance = ReactNativeComponent.createInternalComponent(element); - // All native components are currently wrapped in a composite so we're - // safe to assume that this is what we should instantiate. - } else if (isInternalComponentType(element.type)) { - // This is temporarily available for custom components that are not string - // represenations. I.e. ART. Once those are updated to use the string - // representation, we can drop this code path. - instance = new element.type(element); - } else { - instance = new ReactCompositeComponentWrapper(); - } - } else if (typeof node === 'string' || typeof node === 'number') { - instance = ReactNativeComponent.createInstanceForText(node); - } else { - ("production" !== "development" ? invariant( - false, - 'Encountered invalid React node of type %s', - typeof node - ) : invariant(false)); - } - - if ("production" !== "development") { - ("production" !== "development" ? warning( - typeof instance.construct === 'function' && - typeof instance.mountComponent === 'function' && - typeof instance.receiveComponent === 'function' && - typeof instance.unmountComponent === 'function', - 'Only React Components can be mounted.' - ) : null); - } - - // Sets up the instance. This can probably just move into the constructor now. - instance.construct(node); - - // These two fields are used by the DOM and ART diffing algorithms - // respectively. Instead of using expandos on components, we should be - // storing the state needed by the diffing algorithms elsewhere. - instance._mountIndex = 0; - instance._mountImage = null; - - if ("production" !== "development") { - instance._isOwnerNecessary = false; - instance._warnedAboutRefsInRender = false; - } - - // Internal instances should fully constructed at this point, so they should - // not get any new fields added to them at this point. - if ("production" !== "development") { - if (Object.preventExtensions) { - Object.preventExtensions(instance); - } - } - - return instance; -} - -module.exports = instantiateReactComponent; - -},{"135":135,"154":154,"27":27,"37":37,"59":59,"73":73}],135:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule invariant - */ - -"use strict"; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if ("production" !== "development") { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - 'Invariant Violation: ' + - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - -},{}],136:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isEventSupported - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(21); - -var useHasFeature; -if (ExecutionEnvironment.canUseDOM) { - useHasFeature = - document.implementation && - document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; -} - -/** - * Checks if an event is supported in the current execution environment. - * - * NOTE: This will not work correctly for non-generic events such as `change`, - * `reset`, `load`, `error`, and `select`. - * - * Borrows from Modernizr. - * - * @param {string} eventNameSuffix Event name, e.g. "click". - * @param {?boolean} capture Check if the capture phase is supported. - * @return {boolean} True if the event is supported. - * @internal - * @license Modernizr 3.0.0pre (Custom Build) | MIT - */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || - capture && !('addEventListener' in document)) { - return false; - } - - var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; - - if (!isSupported) { - var element = document.createElement('div'); - element.setAttribute(eventName, 'return;'); - isSupported = typeof element[eventName] === 'function'; - } - - if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { - // This is the only way to test support for the `wheel` event in IE9+. - isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); - } - - return isSupported; -} - -module.exports = isEventSupported; - -},{"21":21}],137:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isNode - * @typechecks - */ - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM node. - */ -function isNode(object) { - return !!(object && ( - ((typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && - typeof object.nodeType === 'number' && - typeof object.nodeName === 'string')) - )); -} - -module.exports = isNode; - -},{}],138:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isTextInputElement - */ - -'use strict'; - -/** - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary - */ -var supportedInputTypes = { - 'color': true, - 'date': true, - 'datetime': true, - 'datetime-local': true, - 'email': true, - 'month': true, - 'number': true, - 'password': true, - 'range': true, - 'search': true, - 'tel': true, - 'text': true, - 'time': true, - 'url': true, - 'week': true -}; - -function isTextInputElement(elem) { - return elem && ( - (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type] || elem.nodeName === 'TEXTAREA') - ); -} - -module.exports = isTextInputElement; - -},{}],139:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isTextNode - * @typechecks - */ - -var isNode = _dereq_(137); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; - -},{"137":137}],140:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule keyMirror - * @typechecks static-only - */ - -'use strict'; - -var invariant = _dereq_(135); - -/** - * Constructs an enumeration with keys equal to their value. - * - * For example: - * - * var COLORS = keyMirror({blue: null, red: null}); - * var myColor = COLORS.blue; - * var isColorValid = !!COLORS[myColor]; - * - * The last line could not be performed if the values of the generated enum were - * not equal to their keys. - * - * Input: {key1: val1, key2: val2} - * Output: {key1: key1, key2: key2} - * - * @param {object} obj - * @return {object} - */ -var keyMirror = function(obj) { - var ret = {}; - var key; - ("production" !== "development" ? invariant( - obj instanceof Object && !Array.isArray(obj), - 'keyMirror(...): Argument must be an object.' - ) : invariant(obj instanceof Object && !Array.isArray(obj))); - for (key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - ret[key] = key; - } - return ret; -}; - -module.exports = keyMirror; - -},{"135":135}],141:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule keyOf - */ - -/** - * Allows extraction of a minified key. Let's the build system minify keys - * without loosing the ability to dynamically use key strings as values - * themselves. Pass in an object with a single key/val pair and it will return - * you the string key of that single record. Suppose you want to grab the - * value for a key 'className' inside of an object. Key/val minification may - * have aliased that key to be 'xa12'. keyOf({className: null}) will return - * 'xa12' in that case. Resolve keys you want to use once at startup time, then - * reuse those resolutions. - */ -var keyOf = function(oneKeyObj) { - var key; - for (key in oneKeyObj) { - if (!oneKeyObj.hasOwnProperty(key)) { - continue; - } - return key; - } - return null; -}; - - -module.exports = keyOf; - -},{}],142:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule mapObject - */ - -'use strict'; - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Executes the provided `callback` once for each enumerable own property in the - * object and constructs a new object from the results. The `callback` is - * invoked with three arguments: - * - * - the property value - * - the property name - * - the object being traversed - * - * Properties that are added after the call to `mapObject` will not be visited - * by `callback`. If the values of existing properties are changed, the value - * passed to `callback` will be the value at the time `mapObject` visits them. - * Properties that are deleted before being visited are not visited. - * - * @grep function objectMap() - * @grep function objMap() - * - * @param {?object} object - * @param {function} callback - * @param {*} context - * @return {?object} - */ -function mapObject(object, callback, context) { - if (!object) { - return null; - } - var result = {}; - for (var name in object) { - if (hasOwnProperty.call(object, name)) { - result[name] = callback.call(context, object[name], name, object); - } - } - return result; -} - -module.exports = mapObject; - -},{}],143:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule memoizeStringOnly - * @typechecks static-only - */ - -'use strict'; - -/** - * Memoizes the return value of a function that accepts one string argument. - * - * @param {function} callback - * @return {function} - */ -function memoizeStringOnly(callback) { - var cache = {}; - return function(string) { - if (!cache.hasOwnProperty(string)) { - cache[string] = callback.call(this, string); - } - return cache[string]; - }; -} - -module.exports = memoizeStringOnly; - -},{}],144:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule onlyChild - */ -'use strict'; - -var ReactElement = _dereq_(57); - -var invariant = _dereq_(135); - -/** - * Returns the first child in a collection of children and verifies that there - * is only one child in the collection. The current implementation of this - * function assumes that a single child gets passed without a wrapper, but the - * purpose of this helper function is to abstract away the particular structure - * of children. - * - * @param {?object} children Child collection structure. - * @return {ReactComponent} The first and only `ReactComponent` contained in the - * structure. - */ -function onlyChild(children) { - ("production" !== "development" ? invariant( - ReactElement.isValidElement(children), - 'onlyChild must be passed a children with exactly one child.' - ) : invariant(ReactElement.isValidElement(children))); - return children; -} - -module.exports = onlyChild; - -},{"135":135,"57":57}],145:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule performance - * @typechecks - */ - -"use strict"; - -var ExecutionEnvironment = _dereq_(21); - -var performance; - -if (ExecutionEnvironment.canUseDOM) { - performance = - window.performance || - window.msPerformance || - window.webkitPerformance; -} - -module.exports = performance || {}; - -},{"21":21}],146:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule performanceNow - * @typechecks - */ - -var performance = _dereq_(145); - -/** - * Detect if we can use `window.performance.now()` and gracefully fallback to - * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now - * because of Facebook's testing infrastructure. - */ -if (!performance || !performance.now) { - performance = Date; -} - -var performanceNow = performance.now.bind(performance); - -module.exports = performanceNow; - -},{"145":145}],147:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule quoteAttributeValueForBrowser - */ - -'use strict'; - -var escapeTextContentForBrowser = _dereq_(116); - -/** - * Escapes attribute value to prevent scripting attacks. - * - * @param {*} value Value to escape. - * @return {string} An escaped string. - */ -function quoteAttributeValueForBrowser(value) { - return '"' + escapeTextContentForBrowser(value) + '"'; -} - -module.exports = quoteAttributeValueForBrowser; - -},{"116":116}],148:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule setInnerHTML - */ - -/* globals MSApp */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(21); - -var WHITESPACE_TEST = /^[ \r\n\t\f]/; -var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; - -/** - * Set the innerHTML property of a node, ensuring that whitespace is preserved - * even in IE8. - * - * @param {DOMElement} node - * @param {string} html - * @internal - */ -var setInnerHTML = function(node, html) { - node.innerHTML = html; -}; - -// Win8 apps: Allow all html to be inserted -if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { - setInnerHTML = function(node, html) { - MSApp.execUnsafeLocalFunction(function() { - node.innerHTML = html; - }); - }; -} - -if (ExecutionEnvironment.canUseDOM) { - // IE8: When updating a just created node with innerHTML only leading - // whitespace is removed. When updating an existing node with innerHTML - // whitespace in root TextNodes is also collapsed. - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html - - // Feature detection; only IE8 is known to behave improperly like this. - var testElement = document.createElement('div'); - testElement.innerHTML = ' '; - if (testElement.innerHTML === '') { - setInnerHTML = function(node, html) { - // Magic theory: IE8 supposedly differentiates between added and updated - // nodes when processing innerHTML, innerHTML on updated nodes suffers - // from worse whitespace behavior. Re-adding a node like this triggers - // the initial and more favorable whitespace behavior. - // TODO: What to do on a detached node? - if (node.parentNode) { - node.parentNode.replaceChild(node, node); - } - - // We also implement a workaround for non-visible tags disappearing into - // thin air on IE8, this only happens if there is no visible text - // in-front of the non-visible tags. Piggyback on the whitespace fix - // and simply check if any non-visible tags appear in the source. - if (WHITESPACE_TEST.test(html) || - html[0] === '<' && NONVISIBLE_TEST.test(html)) { - // Recover leading whitespace by temporarily prepending any character. - // \uFEFF has the potential advantage of being zero-width/invisible. - node.innerHTML = '\uFEFF' + html; - - // deleteData leaves an empty `TextNode` which offsets the index of all - // children. Definitely want to avoid this. - var textNode = node.firstChild; - if (textNode.data.length === 1) { - node.removeChild(textNode); - } else { - textNode.deleteData(0, 1); - } - } else { - node.innerHTML = html; - } - }; - } -} - -module.exports = setInnerHTML; - -},{"21":21}],149:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule setTextContent - */ - -'use strict'; - -var ExecutionEnvironment = _dereq_(21); -var escapeTextContentForBrowser = _dereq_(116); -var setInnerHTML = _dereq_(148); - -/** - * Set the textContent property of a node, ensuring that whitespace is preserved - * even in IE8. innerText is a poor substitute for textContent and, among many - * issues, inserts <br> instead of the literal newline chars. innerHTML behaves - * as it should. - * - * @param {DOMElement} node - * @param {string} text - * @internal - */ -var setTextContent = function(node, text) { - node.textContent = text; -}; - -if (ExecutionEnvironment.canUseDOM) { - if (!('textContent' in document.documentElement)) { - setTextContent = function(node, text) { - setInnerHTML(node, escapeTextContentForBrowser(text)); - }; - } -} - -module.exports = setTextContent; - -},{"116":116,"148":148,"21":21}],150:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule shallowEqual - */ - -'use strict'; - -/** - * Performs equality by iterating through keys on an object and returning - * false when any key has values which are not strictly equal between - * objA and objB. Returns true when the values of all keys are strictly equal. - * - * @return {boolean} - */ -function shallowEqual(objA, objB) { - if (objA === objB) { - return true; - } - var key; - // Test for A's keys different from B. - for (key in objA) { - if (objA.hasOwnProperty(key) && - (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { - return false; - } - } - // Test for B's keys missing from A. - for (key in objB) { - if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { - return false; - } - } - return true; -} - -module.exports = shallowEqual; - -},{}],151:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule shouldUpdateReactComponent - * @typechecks static-only - */ - -'use strict'; - -var warning = _dereq_(154); - -/** - * Given a `prevElement` and `nextElement`, determines if the existing - * instance should be updated as opposed to being destroyed or replaced by a new - * instance. Both arguments are elements. This ensures that this logic can - * operate on stateless trees without any backing instance. - * - * @param {?object} prevElement - * @param {?object} nextElement - * @return {boolean} True if the existing instance should be updated. - * @protected - */ -function shouldUpdateReactComponent(prevElement, nextElement) { - if (prevElement != null && nextElement != null) { - var prevType = typeof prevElement; - var nextType = typeof nextElement; - if (prevType === 'string' || prevType === 'number') { - return (nextType === 'string' || nextType === 'number'); - } else { - if (nextType === 'object' && - prevElement.type === nextElement.type && - prevElement.key === nextElement.key) { - var ownersMatch = prevElement._owner === nextElement._owner; - var prevName = null; - var nextName = null; - var nextDisplayName = null; - if ("production" !== "development") { - if (!ownersMatch) { - if (prevElement._owner != null && - prevElement._owner.getPublicInstance() != null && - prevElement._owner.getPublicInstance().constructor != null) { - prevName = - prevElement._owner.getPublicInstance().constructor.displayName; - } - if (nextElement._owner != null && - nextElement._owner.getPublicInstance() != null && - nextElement._owner.getPublicInstance().constructor != null) { - nextName = - nextElement._owner.getPublicInstance().constructor.displayName; - } - if (nextElement.type != null && - nextElement.type.displayName != null) { - nextDisplayName = nextElement.type.displayName; - } - if (nextElement.type != null && typeof nextElement.type === 'string') { - nextDisplayName = nextElement.type; - } - if (typeof nextElement.type !== 'string' || - nextElement.type === 'input' || - nextElement.type === 'textarea') { - if ((prevElement._owner != null && - prevElement._owner._isOwnerNecessary === false) || - (nextElement._owner != null && - nextElement._owner._isOwnerNecessary === false)) { - if (prevElement._owner != null) { - prevElement._owner._isOwnerNecessary = true; - } - if (nextElement._owner != null) { - nextElement._owner._isOwnerNecessary = true; - } - ("production" !== "development" ? warning( - false, - '<%s /> is being rendered by both %s and %s using the same ' + - 'key (%s) in the same place. Currently, this means that ' + - 'they don\'t preserve state. This behavior should be very ' + - 'rare so we\'re considering deprecating it. Please contact ' + - 'the React team and explain your use case so that we can ' + - 'take that into consideration.', - nextDisplayName || 'Unknown Component', - prevName || '[Unknown]', - nextName || '[Unknown]', - prevElement.key - ) : null); - } - } - } - } - return ownersMatch; - } - } - } - return false; -} - -module.exports = shouldUpdateReactComponent; - -},{"154":154}],152:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule toArray - * @typechecks - */ - -var invariant = _dereq_(135); - -/** - * Convert array-like objects to arrays. - * - * This API assumes the caller knows the contents of the data type. For less - * well defined inputs use createArrayFromMixed. - * - * @param {object|function|filelist} obj - * @return {array} - */ -function toArray(obj) { - var length = obj.length; - - // Some browse builtin objects can report typeof 'function' (e.g. NodeList in - // old versions of Safari). - ("production" !== "development" ? invariant( - !Array.isArray(obj) && - (typeof obj === 'object' || typeof obj === 'function'), - 'toArray: Array-like object expected' - ) : invariant(!Array.isArray(obj) && - (typeof obj === 'object' || typeof obj === 'function'))); - - ("production" !== "development" ? invariant( - typeof length === 'number', - 'toArray: Object needs a length property' - ) : invariant(typeof length === 'number')); - - ("production" !== "development" ? invariant( - length === 0 || - (length - 1) in obj, - 'toArray: Object should have keys for indices' - ) : invariant(length === 0 || - (length - 1) in obj)); - - // Old IE doesn't give collections access to hasOwnProperty. Assume inputs - // without method will throw during the slice call and skip straight to the - // fallback. - if (obj.hasOwnProperty) { - try { - return Array.prototype.slice.call(obj); - } catch (e) { - // IE < 9 does not support Array#slice on collections objects - } - } - - // Fall back to copying key by key. This assumes all keys have a value, - // so will not preserve sparsely populated inputs. - var ret = Array(length); - for (var ii = 0; ii < length; ii++) { - ret[ii] = obj[ii]; - } - return ret; -} - -module.exports = toArray; - -},{"135":135}],153:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule traverseAllChildren - */ - -'use strict'; - -var ReactElement = _dereq_(57); -var ReactFragment = _dereq_(63); -var ReactInstanceHandles = _dereq_(66); - -var getIteratorFn = _dereq_(126); -var invariant = _dereq_(135); -var warning = _dereq_(154); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; -var SUBSEPARATOR = ':'; - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var userProvidedKeyEscaperLookup = { - '=': '=0', - '.': '=1', - ':': '=2' -}; - -var userProvidedKeyEscapeRegex = /[=.:]/g; - -var didWarnAboutMaps = false; - -function userProvidedKeyEscaper(match) { - return userProvidedKeyEscaperLookup[match]; -} - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - if (component && component.key != null) { - // Explicit key - return wrapUserProvidedKey(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * Escape a component key so that it is safe to use in a reactid. - * - * @param {*} key Component key to be escaped. - * @return {string} An escaped string. - */ -function escapeUserProvidedKey(text) { - return ('' + text).replace( - userProvidedKeyEscapeRegex, - userProvidedKeyEscaper - ); -} - -/** - * Wrap a `key` value explicitly provided by the user to distinguish it from - * implicitly-generated keys generated by a component's index in its parent. - * - * @param {string} key Value of a user-provided `key` attribute - * @return {string} - */ -function wrapUserProvidedKey(key) { - return '$' + escapeUserProvidedKey(key); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!number} indexSoFar Number of children encountered until this point. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl( - children, - nameSoFar, - indexSoFar, - callback, - traverseContext -) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || - type === 'string' || - type === 'number' || - ReactElement.isValidElement(children)) { - callback( - traverseContext, - children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar, - indexSoFar - ); - return 1; - } - - var child, nextName, nextIndex; - var subtreeCount = 0; // Count of children found in the current subtree. - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - getComponentKey(child, i) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - getComponentKey(child, ii++) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } else { - if ("production" !== "development") { - ("production" !== "development" ? warning( - didWarnAboutMaps, - 'Using Maps as children is not yet fully supported. It is an ' + - 'experimental feature that might be removed. Convert it to a ' + - 'sequence / iterable of keyed ReactElements instead.' - ) : null); - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } - } - } else if (type === 'object') { - ("production" !== "development" ? invariant( - children.nodeType !== 1, - 'traverseAllChildren(...): Encountered an invalid child; DOM ' + - 'elements are not valid children of React components.' - ) : invariant(children.nodeType !== 1)); - var fragment = ReactFragment.extract(children); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - child = fragment[key]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(key) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', 0, callback, traverseContext); -} - -module.exports = traverseAllChildren; - -},{"126":126,"135":135,"154":154,"57":57,"63":63,"66":66}],154:[function(_dereq_,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule warning - */ - -"use strict"; - -var emptyFunction = _dereq_(114); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if ("production" !== "development") { - warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (format.length < 10 || /^[s\W]*$/.test(format)) { - throw new Error( - 'The warning format should be able to uniquely identify this ' + - 'warning. Please, use a more descriptive format than: ' + format - ); - } - - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. - } - - if (!condition) { - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); - console.warn(message); - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch(x) {} - } - }; -} - -module.exports = warning; - -},{"114":114}]},{},[1])(1) -});
\ No newline at end of file diff --git a/server/sonar-web/src/main/js/libs/third-party/react.min.js b/server/sonar-web/src/main/js/libs/third-party/react.min.js deleted file mode 100644 index 64aca4baa23..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/react.min.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * React v0.13.3 - * - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.React=e()}}(function(){return function e(t,n,r){function o(a,u){if(!n[a]){if(!t[a]){var s="function"==typeof require&&require;if(!u&&s)return s(a,!0);if(i)return i(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){var n=t[a][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(e,t,n){"use strict";var r=e(19),o=e(32),i=e(34),a=e(33),u=e(38),s=e(39),l=e(55),c=(e(56),e(40)),p=e(51),d=e(54),f=e(64),h=e(68),m=e(73),v=e(76),g=e(79),y=e(82),C=e(27),E=e(115),b=e(142);d.inject();var _=l.createElement,x=l.createFactory,D=l.cloneElement,M=m.measure("React","render",h.render),N={Children:{map:o.map,forEach:o.forEach,count:o.count,only:b},Component:i,DOM:c,PropTypes:v,initializeTouchEvents:function(e){r.useTouchEvents=e},createClass:a.createClass,createElement:_,cloneElement:D,createFactory:x,createMixin:function(e){return e},constructAndRenderComponent:h.constructAndRenderComponent,constructAndRenderComponentByID:h.constructAndRenderComponentByID,findDOMNode:E,render:M,renderToString:y.renderToString,renderToStaticMarkup:y.renderToStaticMarkup,unmountComponentAtNode:h.unmountComponentAtNode,isValidElement:l.isValidElement,withContext:u.withContext,__spread:C};"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject&&__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({CurrentOwner:s,InstanceHandles:f,Mount:h,Reconciler:g,TextComponent:p});N.version="0.13.3",t.exports=N},{115:115,142:142,19:19,27:27,32:32,33:33,34:34,38:38,39:39,40:40,51:51,54:54,55:55,56:56,64:64,68:68,73:73,76:76,79:79,82:82}],2:[function(e,t,n){"use strict";var r=e(117),o={componentDidMount:function(){this.props.autoFocus&&r(this.getDOMNode())}};t.exports=o},{117:117}],3:[function(e,t,n){"use strict";function r(){var e=window.opera;return"object"==typeof e&&"function"==typeof e.version&&parseInt(e.version(),10)<=12}function o(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}function i(e){switch(e){case T.topCompositionStart:return P.compositionStart;case T.topCompositionEnd:return P.compositionEnd;case T.topCompositionUpdate:return P.compositionUpdate}}function a(e,t){return e===T.topKeyDown&&t.keyCode===b}function u(e,t){switch(e){case T.topKeyUp:return-1!==E.indexOf(t.keyCode);case T.topKeyDown:return t.keyCode!==b;case T.topKeyPress:case T.topMouseDown:case T.topBlur:return!0;default:return!1}}function s(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}function l(e,t,n,r){var o,l;if(_?o=i(e):w?u(e,r)&&(o=P.compositionEnd):a(e,r)&&(o=P.compositionStart),!o)return null;M&&(w||o!==P.compositionStart?o===P.compositionEnd&&w&&(l=w.getData()):w=v.getPooled(t));var c=g.getPooled(o,n,r);if(l)c.data=l;else{var p=s(r);null!==p&&(c.data=p)}return h.accumulateTwoPhaseDispatches(c),c}function c(e,t){switch(e){case T.topCompositionEnd:return s(t);case T.topKeyPress:var n=t.which;return n!==N?null:(R=!0,I);case T.topTextInput:var r=t.data;return r===I&&R?null:r;default:return null}}function p(e,t){if(w){if(e===T.topCompositionEnd||u(e,t)){var n=w.getData();return v.release(w),w=null,n}return null}switch(e){case T.topPaste:return null;case T.topKeyPress:return t.which&&!o(t)?String.fromCharCode(t.which):null;case T.topCompositionEnd:return M?null:t.data;default:return null}}function d(e,t,n,r){var o;if(o=D?c(e,r):p(e,r),!o)return null;var i=y.getPooled(P.beforeInput,n,r);return i.data=o,h.accumulateTwoPhaseDispatches(i),i}var f=e(15),h=e(20),m=e(21),v=e(22),g=e(91),y=e(95),C=e(139),E=[9,13,27,32],b=229,_=m.canUseDOM&&"CompositionEvent"in window,x=null;m.canUseDOM&&"documentMode"in document&&(x=document.documentMode);var D=m.canUseDOM&&"TextEvent"in window&&!x&&!r(),M=m.canUseDOM&&(!_||x&&x>8&&11>=x),N=32,I=String.fromCharCode(N),T=f.topLevelTypes,P={beforeInput:{phasedRegistrationNames:{bubbled:C({onBeforeInput:null}),captured:C({onBeforeInputCapture:null})},dependencies:[T.topCompositionEnd,T.topKeyPress,T.topTextInput,T.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:C({onCompositionEnd:null}),captured:C({onCompositionEndCapture:null})},dependencies:[T.topBlur,T.topCompositionEnd,T.topKeyDown,T.topKeyPress,T.topKeyUp,T.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:C({onCompositionStart:null}),captured:C({onCompositionStartCapture:null})},dependencies:[T.topBlur,T.topCompositionStart,T.topKeyDown,T.topKeyPress,T.topKeyUp,T.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:C({onCompositionUpdate:null}),captured:C({onCompositionUpdateCapture:null})},dependencies:[T.topBlur,T.topCompositionUpdate,T.topKeyDown,T.topKeyPress,T.topKeyUp,T.topMouseDown]}},R=!1,w=null,O={eventTypes:P,extractEvents:function(e,t,n,r){return[l(e,t,n,r),d(e,t,n,r)]}};t.exports=O},{139:139,15:15,20:20,21:21,22:22,91:91,95:95}],4:[function(e,t,n){"use strict";function r(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var o={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0},i=["Webkit","ms","Moz","O"];Object.keys(o).forEach(function(e){i.forEach(function(t){o[r(t,e)]=o[e]})});var a={background:{backgroundImage:!0,backgroundPosition:!0,backgroundRepeat:!0,backgroundColor:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0}},u={isUnitlessNumber:o,shorthandPropertyExpansions:a};t.exports=u},{}],5:[function(e,t,n){"use strict";var r=e(4),o=e(21),i=(e(106),e(111)),a=e(131),u=e(141),s=(e(150),u(function(e){return a(e)})),l="cssFloat";o.canUseDOM&&void 0===document.documentElement.style.cssFloat&&(l="styleFloat");var c={createMarkupForStyles:function(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];null!=r&&(t+=s(n)+":",t+=i(n,r)+";")}return t||null},setValueForStyles:function(e,t){var n=e.style;for(var o in t)if(t.hasOwnProperty(o)){var a=i(o,t[o]);if("float"===o&&(o=l),a)n[o]=a;else{var u=r.shorthandPropertyExpansions[o];if(u)for(var s in u)n[s]="";else n[o]=""}}}};t.exports=c},{106:106,111:111,131:131,141:141,150:150,21:21,4:4}],6:[function(e,t,n){"use strict";function r(){this._callbacks=null,this._contexts=null}var o=e(28),i=e(27),a=e(133);i(r.prototype,{enqueue:function(e,t){this._callbacks=this._callbacks||[],this._contexts=this._contexts||[],this._callbacks.push(e),this._contexts.push(t)},notifyAll:function(){var e=this._callbacks,t=this._contexts;if(e){a(e.length===t.length),this._callbacks=null,this._contexts=null;for(var n=0,r=e.length;r>n;n++)e[n].call(t[n]);e.length=0,t.length=0}},reset:function(){this._callbacks=null,this._contexts=null},destructor:function(){this.reset()}}),o.addPoolingTo(r),t.exports=r},{133:133,27:27,28:28}],7:[function(e,t,n){"use strict";function r(e){return"SELECT"===e.nodeName||"INPUT"===e.nodeName&&"file"===e.type}function o(e){var t=x.getPooled(T.change,R,e);E.accumulateTwoPhaseDispatches(t),_.batchedUpdates(i,t)}function i(e){C.enqueueEvents(e),C.processEventQueue()}function a(e,t){P=e,R=t,P.attachEvent("onchange",o)}function u(){P&&(P.detachEvent("onchange",o),P=null,R=null)}function s(e,t,n){return e===I.topChange?n:void 0}function l(e,t,n){e===I.topFocus?(u(),a(t,n)):e===I.topBlur&&u()}function c(e,t){P=e,R=t,w=e.value,O=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(P,"value",k),P.attachEvent("onpropertychange",d)}function p(){P&&(delete P.value,P.detachEvent("onpropertychange",d),P=null,R=null,w=null,O=null)}function d(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==w&&(w=t,o(e))}}function f(e,t,n){return e===I.topInput?n:void 0}function h(e,t,n){e===I.topFocus?(p(),c(t,n)):e===I.topBlur&&p()}function m(e,t,n){return e!==I.topSelectionChange&&e!==I.topKeyUp&&e!==I.topKeyDown||!P||P.value===w?void 0:(w=P.value,R)}function v(e){return"INPUT"===e.nodeName&&("checkbox"===e.type||"radio"===e.type)}function g(e,t,n){return e===I.topClick?n:void 0}var y=e(15),C=e(17),E=e(20),b=e(21),_=e(85),x=e(93),D=e(134),M=e(136),N=e(139),I=y.topLevelTypes,T={change:{phasedRegistrationNames:{bubbled:N({onChange:null}),captured:N({onChangeCapture:null})},dependencies:[I.topBlur,I.topChange,I.topClick,I.topFocus,I.topInput,I.topKeyDown,I.topKeyUp,I.topSelectionChange]}},P=null,R=null,w=null,O=null,S=!1;b.canUseDOM&&(S=D("change")&&(!("documentMode"in document)||document.documentMode>8));var A=!1;b.canUseDOM&&(A=D("input")&&(!("documentMode"in document)||document.documentMode>9));var k={get:function(){return O.get.call(this)},set:function(e){w=""+e,O.set.call(this,e)}},L={eventTypes:T,extractEvents:function(e,t,n,o){var i,a;if(r(t)?S?i=s:a=l:M(t)?A?i=f:(i=m,a=h):v(t)&&(i=g),i){var u=i(e,t,n);if(u){var c=x.getPooled(T.change,u,o);return E.accumulateTwoPhaseDispatches(c),c}}a&&a(e,t,n)}};t.exports=L},{134:134,136:136,139:139,15:15,17:17,20:20,21:21,85:85,93:93}],8:[function(e,t,n){"use strict";var r=0,o={createReactRootIndex:function(){return r++}};t.exports=o},{}],9:[function(e,t,n){"use strict";function r(e,t,n){e.insertBefore(t,e.childNodes[n]||null)}var o=e(12),i=e(70),a=e(145),u=e(133),s={dangerouslyReplaceNodeWithMarkup:o.dangerouslyReplaceNodeWithMarkup,updateTextContent:a,processUpdates:function(e,t){for(var n,s=null,l=null,c=0;c<e.length;c++)if(n=e[c],n.type===i.MOVE_EXISTING||n.type===i.REMOVE_NODE){var p=n.fromIndex,d=n.parentNode.childNodes[p],f=n.parentID;u(d),s=s||{},s[f]=s[f]||[],s[f][p]=d,l=l||[],l.push(d)}var h=o.dangerouslyRenderMarkup(t);if(l)for(var m=0;m<l.length;m++)l[m].parentNode.removeChild(l[m]);for(var v=0;v<e.length;v++)switch(n=e[v],n.type){case i.INSERT_MARKUP:r(n.parentNode,h[n.markupIndex],n.toIndex);break;case i.MOVE_EXISTING:r(n.parentNode,s[n.parentID][n.fromIndex],n.toIndex);break;case i.TEXT_CONTENT:a(n.parentNode,n.textContent);break;case i.REMOVE_NODE:}}};t.exports=s},{12:12,133:133,145:145,70:70}],10:[function(e,t,n){"use strict";function r(e,t){return(e&t)===t}var o=e(133),i={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(e){var t=e.Properties||{},n=e.DOMAttributeNames||{},a=e.DOMPropertyNames||{},s=e.DOMMutationMethods||{};e.isCustomAttribute&&u._isCustomAttributeFunctions.push(e.isCustomAttribute);for(var l in t){o(!u.isStandardName.hasOwnProperty(l)),u.isStandardName[l]=!0;var c=l.toLowerCase();if(u.getPossibleStandardName[c]=l,n.hasOwnProperty(l)){var p=n[l];u.getPossibleStandardName[p]=l,u.getAttributeName[l]=p}else u.getAttributeName[l]=c;u.getPropertyName[l]=a.hasOwnProperty(l)?a[l]:l,s.hasOwnProperty(l)?u.getMutationMethod[l]=s[l]:u.getMutationMethod[l]=null;var d=t[l];u.mustUseAttribute[l]=r(d,i.MUST_USE_ATTRIBUTE),u.mustUseProperty[l]=r(d,i.MUST_USE_PROPERTY),u.hasSideEffects[l]=r(d,i.HAS_SIDE_EFFECTS),u.hasBooleanValue[l]=r(d,i.HAS_BOOLEAN_VALUE),u.hasNumericValue[l]=r(d,i.HAS_NUMERIC_VALUE),u.hasPositiveNumericValue[l]=r(d,i.HAS_POSITIVE_NUMERIC_VALUE),u.hasOverloadedBooleanValue[l]=r(d,i.HAS_OVERLOADED_BOOLEAN_VALUE),o(!u.mustUseAttribute[l]||!u.mustUseProperty[l]),o(u.mustUseProperty[l]||!u.hasSideEffects[l]),o(!!u.hasBooleanValue[l]+!!u.hasNumericValue[l]+!!u.hasOverloadedBooleanValue[l]<=1)}}},a={},u={ID_ATTRIBUTE_NAME:"data-reactid",isStandardName:{},getPossibleStandardName:{},getAttributeName:{},getPropertyName:{},getMutationMethod:{},mustUseAttribute:{},mustUseProperty:{},hasSideEffects:{},hasBooleanValue:{},hasNumericValue:{},hasPositiveNumericValue:{},hasOverloadedBooleanValue:{},_isCustomAttributeFunctions:[],isCustomAttribute:function(e){for(var t=0;t<u._isCustomAttributeFunctions.length;t++){var n=u._isCustomAttributeFunctions[t];if(n(e))return!0}return!1},getDefaultValueForProperty:function(e,t){var n,r=a[e];return r||(a[e]=r={}),t in r||(n=document.createElement(e),r[t]=n[t]),r[t]},injection:i};t.exports=u},{133:133}],11:[function(e,t,n){"use strict";function r(e,t){return null==t||o.hasBooleanValue[e]&&!t||o.hasNumericValue[e]&&isNaN(t)||o.hasPositiveNumericValue[e]&&1>t||o.hasOverloadedBooleanValue[e]&&t===!1}var o=e(10),i=e(143),a=(e(150),{createMarkupForID:function(e){return o.ID_ATTRIBUTE_NAME+"="+i(e)},createMarkupForProperty:function(e,t){if(o.isStandardName.hasOwnProperty(e)&&o.isStandardName[e]){if(r(e,t))return"";var n=o.getAttributeName[e];return o.hasBooleanValue[e]||o.hasOverloadedBooleanValue[e]&&t===!0?n:n+"="+i(t)}return o.isCustomAttribute(e)?null==t?"":e+"="+i(t):null},setValueForProperty:function(e,t,n){if(o.isStandardName.hasOwnProperty(t)&&o.isStandardName[t]){var i=o.getMutationMethod[t];if(i)i(e,n);else if(r(t,n))this.deleteValueForProperty(e,t);else if(o.mustUseAttribute[t])e.setAttribute(o.getAttributeName[t],""+n);else{var a=o.getPropertyName[t];o.hasSideEffects[t]&&""+e[a]==""+n||(e[a]=n)}}else o.isCustomAttribute(t)&&(null==n?e.removeAttribute(t):e.setAttribute(t,""+n))},deleteValueForProperty:function(e,t){if(o.isStandardName.hasOwnProperty(t)&&o.isStandardName[t]){var n=o.getMutationMethod[t];if(n)n(e,void 0);else if(o.mustUseAttribute[t])e.removeAttribute(o.getAttributeName[t]);else{var r=o.getPropertyName[t],i=o.getDefaultValueForProperty(e.nodeName,r);o.hasSideEffects[t]&&""+e[r]===i||(e[r]=i)}}else o.isCustomAttribute(t)&&e.removeAttribute(t)}});t.exports=a},{10:10,143:143,150:150}],12:[function(e,t,n){"use strict";function r(e){return e.substring(1,e.indexOf(" "))}var o=e(21),i=e(110),a=e(112),u=e(125),s=e(133),l=/^(<[^ \/>]+)/,c="data-danger-index",p={dangerouslyRenderMarkup:function(e){s(o.canUseDOM);for(var t,n={},p=0;p<e.length;p++)s(e[p]),t=r(e[p]),t=u(t)?t:"*",n[t]=n[t]||[],n[t][p]=e[p];var d=[],f=0;for(t in n)if(n.hasOwnProperty(t)){var h,m=n[t];for(h in m)if(m.hasOwnProperty(h)){var v=m[h];m[h]=v.replace(l,"$1 "+c+'="'+h+'" ')}for(var g=i(m.join(""),a),y=0;y<g.length;++y){var C=g[y];C.hasAttribute&&C.hasAttribute(c)&&(h=+C.getAttribute(c),C.removeAttribute(c),s(!d.hasOwnProperty(h)),d[h]=C,f+=1)}}return s(f===d.length),s(d.length===e.length),d},dangerouslyReplaceNodeWithMarkup:function(e,t){s(o.canUseDOM),s(t),s("html"!==e.tagName.toLowerCase());var n=i(t,a)[0];e.parentNode.replaceChild(n,e)}};t.exports=p},{110:110,112:112,125:125,133:133,21:21}],13:[function(e,t,n){"use strict";var r=e(139),o=[r({ResponderEventPlugin:null}),r({SimpleEventPlugin:null}),r({TapEventPlugin:null}),r({EnterLeaveEventPlugin:null}),r({ChangeEventPlugin:null}),r({SelectEventPlugin:null}),r({BeforeInputEventPlugin:null}),r({AnalyticsEventPlugin:null}),r({MobileSafariClickEventPlugin:null})];t.exports=o},{139:139}],14:[function(e,t,n){"use strict";var r=e(15),o=e(20),i=e(97),a=e(68),u=e(139),s=r.topLevelTypes,l=a.getFirstReactDOM,c={mouseEnter:{registrationName:u({onMouseEnter:null}),dependencies:[s.topMouseOut,s.topMouseOver]},mouseLeave:{registrationName:u({onMouseLeave:null}),dependencies:[s.topMouseOut,s.topMouseOver]}},p=[null,null],d={eventTypes:c,extractEvents:function(e,t,n,r){if(e===s.topMouseOver&&(r.relatedTarget||r.fromElement))return null;if(e!==s.topMouseOut&&e!==s.topMouseOver)return null;var u;if(t.window===t)u=t;else{var d=t.ownerDocument;u=d?d.defaultView||d.parentWindow:window}var f,h;if(e===s.topMouseOut?(f=t,h=l(r.relatedTarget||r.toElement)||u):(f=u,h=t),f===h)return null;var m=f?a.getID(f):"",v=h?a.getID(h):"",g=i.getPooled(c.mouseLeave,m,r);g.type="mouseleave",g.target=f,g.relatedTarget=h;var y=i.getPooled(c.mouseEnter,v,r);return y.type="mouseenter",y.target=h,y.relatedTarget=f,o.accumulateEnterLeaveDispatches(g,y,m,v),p[0]=g,p[1]=y,p}};t.exports=d},{139:139,15:15,20:20,68:68,97:97}],15:[function(e,t,n){"use strict";var r=e(138),o=r({bubbled:null,captured:null}),i=r({topBlur:null,topChange:null,topClick:null,topCompositionEnd:null,topCompositionStart:null,topCompositionUpdate:null,topContextMenu:null,topCopy:null,topCut:null,topDoubleClick:null,topDrag:null,topDragEnd:null,topDragEnter:null,topDragExit:null,topDragLeave:null,topDragOver:null,topDragStart:null,topDrop:null,topError:null,topFocus:null,topInput:null,topKeyDown:null,topKeyPress:null,topKeyUp:null,topLoad:null,topMouseDown:null,topMouseMove:null,topMouseOut:null,topMouseOver:null,topMouseUp:null,topPaste:null,topReset:null,topScroll:null,topSelectionChange:null,topSubmit:null,topTextInput:null,topTouchCancel:null,topTouchEnd:null,topTouchMove:null,topTouchStart:null,topWheel:null}),a={topLevelTypes:i,PropagationPhases:o};t.exports=a},{138:138}],16:[function(e,t,n){var r=e(112),o={listen:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!1),{remove:function(){e.removeEventListener(t,n,!1)}}):e.attachEvent?(e.attachEvent("on"+t,n),{remove:function(){e.detachEvent("on"+t,n)}}):void 0},capture:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!0),{remove:function(){e.removeEventListener(t,n,!0)}}):{remove:r}},registerDefault:function(){}};t.exports=o},{112:112}],17:[function(e,t,n){"use strict";var r=e(18),o=e(19),i=e(103),a=e(118),u=e(133),s={},l=null,c=function(e){if(e){var t=o.executeDispatch,n=r.getPluginModuleForEvent(e);n&&n.executeDispatch&&(t=n.executeDispatch),o.executeDispatchesInOrder(e,t),e.isPersistent()||e.constructor.release(e)}},p=null,d={injection:{injectMount:o.injection.injectMount,injectInstanceHandle:function(e){p=e},getInstanceHandle:function(){return p},injectEventPluginOrder:r.injectEventPluginOrder,injectEventPluginsByName:r.injectEventPluginsByName},eventNameDispatchConfigs:r.eventNameDispatchConfigs,registrationNameModules:r.registrationNameModules,putListener:function(e,t,n){u(!n||"function"==typeof n);var r=s[t]||(s[t]={});r[e]=n},getListener:function(e,t){var n=s[t];return n&&n[e]},deleteListener:function(e,t){var n=s[t];n&&delete n[e]},deleteAllListeners:function(e){for(var t in s)delete s[t][e]},extractEvents:function(e,t,n,o){for(var a,u=r.plugins,s=0,l=u.length;l>s;s++){var c=u[s];if(c){var p=c.extractEvents(e,t,n,o);p&&(a=i(a,p))}}return a},enqueueEvents:function(e){e&&(l=i(l,e))},processEventQueue:function(){var e=l;l=null,a(e,c),u(!l)},__purge:function(){s={}},__getListenerBank:function(){return s}};t.exports=d},{103:103,118:118,133:133,18:18,19:19}],18:[function(e,t,n){"use strict";function r(){if(u)for(var e in s){var t=s[e],n=u.indexOf(e);if(a(n>-1),!l.plugins[n]){a(t.extractEvents),l.plugins[n]=t;var r=t.eventTypes;for(var i in r)a(o(r[i],t,i))}}}function o(e,t,n){a(!l.eventNameDispatchConfigs.hasOwnProperty(n)),l.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var o in r)if(r.hasOwnProperty(o)){var u=r[o];i(u,t,n)}return!0}return e.registrationName?(i(e.registrationName,t,n),!0):!1}function i(e,t,n){a(!l.registrationNameModules[e]),l.registrationNameModules[e]=t,l.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var a=e(133),u=null,s={},l={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(e){a(!u),u=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var o=e[n];s.hasOwnProperty(n)&&s[n]===o||(a(!s[n]),s[n]=o,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return l.registrationNameModules[t.registrationName]||null;for(var n in t.phasedRegistrationNames)if(t.phasedRegistrationNames.hasOwnProperty(n)){var r=l.registrationNameModules[t.phasedRegistrationNames[n]];if(r)return r}return null},_resetEventPlugins:function(){u=null;for(var e in s)s.hasOwnProperty(e)&&delete s[e];l.plugins.length=0;var t=l.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=l.registrationNameModules;for(var o in r)r.hasOwnProperty(o)&&delete r[o]}};t.exports=l},{133:133}],19:[function(e,t,n){"use strict";function r(e){return e===v.topMouseUp||e===v.topTouchEnd||e===v.topTouchCancel}function o(e){return e===v.topMouseMove||e===v.topTouchMove}function i(e){return e===v.topMouseDown||e===v.topTouchStart}function a(e,t){var n=e._dispatchListeners,r=e._dispatchIDs;if(Array.isArray(n))for(var o=0;o<n.length&&!e.isPropagationStopped();o++)t(e,n[o],r[o]);else n&&t(e,n,r)}function u(e,t,n){e.currentTarget=m.Mount.getNode(n);var r=t(e,n);return e.currentTarget=null,r}function s(e,t){a(e,t),e._dispatchListeners=null,e._dispatchIDs=null}function l(e){var t=e._dispatchListeners,n=e._dispatchIDs;if(Array.isArray(t)){for(var r=0;r<t.length&&!e.isPropagationStopped();r++)if(t[r](e,n[r]))return n[r]}else if(t&&t(e,n))return n;return null}function c(e){var t=l(e);return e._dispatchIDs=null,e._dispatchListeners=null,t}function p(e){var t=e._dispatchListeners,n=e._dispatchIDs;h(!Array.isArray(t));var r=t?t(e,n):null;return e._dispatchListeners=null,e._dispatchIDs=null,r}function d(e){return!!e._dispatchListeners}var f=e(15),h=e(133),m={Mount:null,injectMount:function(e){m.Mount=e}},v=f.topLevelTypes,g={isEndish:r,isMoveish:o,isStartish:i,executeDirectDispatch:p,executeDispatch:u,executeDispatchesInOrder:s,executeDispatchesInOrderStopAtTrue:c,hasDispatches:d,injection:m,useTouchEvents:!1};t.exports=g},{133:133,15:15}],20:[function(e,t,n){"use strict";function r(e,t,n){var r=t.dispatchConfig.phasedRegistrationNames[n];return v(e,r)}function o(e,t,n){var o=t?m.bubbled:m.captured,i=r(e,n,o);i&&(n._dispatchListeners=f(n._dispatchListeners,i),n._dispatchIDs=f(n._dispatchIDs,e))}function i(e){e&&e.dispatchConfig.phasedRegistrationNames&&d.injection.getInstanceHandle().traverseTwoPhase(e.dispatchMarker,o,e)}function a(e,t,n){if(n&&n.dispatchConfig.registrationName){var r=n.dispatchConfig.registrationName,o=v(e,r);o&&(n._dispatchListeners=f(n._dispatchListeners,o),n._dispatchIDs=f(n._dispatchIDs,e))}}function u(e){e&&e.dispatchConfig.registrationName&&a(e.dispatchMarker,null,e)}function s(e){h(e,i)}function l(e,t,n,r){d.injection.getInstanceHandle().traverseEnterLeave(n,r,a,e,t)}function c(e){h(e,u)}var p=e(15),d=e(17),f=e(103),h=e(118),m=p.PropagationPhases,v=d.getListener,g={accumulateTwoPhaseDispatches:s,accumulateDirectDispatches:c,accumulateEnterLeaveDispatches:l};t.exports=g},{103:103,118:118,15:15,17:17}],21:[function(e,t,n){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),o={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};t.exports=o},{}],22:[function(e,t,n){"use strict";function r(e){this._root=e,this._startText=this.getText(),this._fallbackText=null}var o=e(28),i=e(27),a=e(128);i(r.prototype,{getText:function(){return"value"in this._root?this._root.value:this._root[a()]},getData:function(){if(this._fallbackText)return this._fallbackText;var e,t,n=this._startText,r=n.length,o=this.getText(),i=o.length;for(e=0;r>e&&n[e]===o[e];e++);var a=r-e;for(t=1;a>=t&&n[r-t]===o[i-t];t++);var u=t>1?1-t:void 0;return this._fallbackText=o.slice(e,u),this._fallbackText}}),o.addPoolingTo(r),t.exports=r},{128:128,27:27,28:28}],23:[function(e,t,n){"use strict";var r,o=e(10),i=e(21),a=o.injection.MUST_USE_ATTRIBUTE,u=o.injection.MUST_USE_PROPERTY,s=o.injection.HAS_BOOLEAN_VALUE,l=o.injection.HAS_SIDE_EFFECTS,c=o.injection.HAS_NUMERIC_VALUE,p=o.injection.HAS_POSITIVE_NUMERIC_VALUE,d=o.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(i.canUseDOM){var f=document.implementation;r=f&&f.hasFeature&&f.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var h={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:a|s,allowTransparency:a,alt:null,async:s,autoComplete:null,autoPlay:s,cellPadding:null,cellSpacing:null,charSet:a,checked:u|s,classID:a,className:r?a:u,cols:a|p,colSpan:null,content:null,contentEditable:null,contextMenu:a,controls:u|s,coords:null,crossOrigin:null,data:null,dateTime:a,defer:s,dir:null,disabled:a|s,download:d,draggable:null,encType:null,form:a,formAction:a,formEncType:a,formMethod:a,formNoValidate:s,formTarget:a,frameBorder:a,headers:null,height:a,hidden:a|s,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:u,label:null,lang:null,list:a,loop:u|s,low:null,manifest:a,marginHeight:null,marginWidth:null,max:null,maxLength:a,media:a,mediaGroup:null,method:null,min:null,multiple:u|s,muted:u|s,name:null,noValidate:s,open:s,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:u|s,rel:null,required:s,role:a,rows:a|p,rowSpan:null,sandbox:null,scope:null,scoped:s,scrolling:null,seamless:a|s,selected:u|s,shape:null,size:a|p,sizes:a,span:p,spellCheck:null,src:null,srcDoc:u,srcSet:a,start:c,step:null,style:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:u|l,width:a,wmode:a,autoCapitalize:null,autoCorrect:null,itemProp:a,itemScope:a|s,itemType:a,itemID:a,itemRef:a,property:null,unselectable:a},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoCorrect:"autocorrect",autoFocus:"autofocus",autoPlay:"autoplay",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};t.exports=h},{10:10,21:21}],24:[function(e,t,n){"use strict";function r(e){l(null==e.props.checkedLink||null==e.props.valueLink)}function o(e){r(e),l(null==e.props.value&&null==e.props.onChange)}function i(e){r(e),l(null==e.props.checked&&null==e.props.onChange)}function a(e){this.props.valueLink.requestChange(e.target.value)}function u(e){this.props.checkedLink.requestChange(e.target.checked)}var s=e(76),l=e(133),c={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0},p={Mixin:{propTypes:{value:function(e,t,n){return!e[t]||c[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")},onChange:s.func}},getValue:function(e){return e.props.valueLink?(o(e),e.props.valueLink.value):e.props.value},getChecked:function(e){return e.props.checkedLink?(i(e),e.props.checkedLink.value):e.props.checked},getOnChange:function(e){return e.props.valueLink?(o(e),a):e.props.checkedLink?(i(e),u):e.props.onChange}};t.exports=p},{133:133,76:76}],25:[function(e,t,n){"use strict";function r(e){e.remove()}var o=e(30),i=e(103),a=e(118),u=e(133),s={trapBubbledEvent:function(e,t){u(this.isMounted());var n=this.getDOMNode();u(n);var r=o.trapBubbledEvent(e,t,n);this._localEventListeners=i(this._localEventListeners,r)},componentWillUnmount:function(){this._localEventListeners&&a(this._localEventListeners,r)}};t.exports=s},{103:103,118:118,133:133,30:30}],26:[function(e,t,n){"use strict";var r=e(15),o=e(112),i=r.topLevelTypes,a={eventTypes:null,extractEvents:function(e,t,n,r){if(e===i.topTouchStart){var a=r.target;a&&!a.onclick&&(a.onclick=o)}}};t.exports=a},{112:112,15:15}],27:[function(e,t,n){"use strict";function r(e,t){if(null==e)throw new TypeError("Object.assign target cannot be null or undefined");for(var n=Object(e),r=Object.prototype.hasOwnProperty,o=1;o<arguments.length;o++){var i=arguments[o];if(null!=i){var a=Object(i);for(var u in a)r.call(a,u)&&(n[u]=a[u])}}return n}t.exports=r},{}],28:[function(e,t,n){"use strict";var r=e(133),o=function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)},i=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},a=function(e,t,n){var r=this;if(r.instancePool.length){var o=r.instancePool.pop();return r.call(o,e,t,n),o}return new r(e,t,n)},u=function(e,t,n,r,o){var i=this;if(i.instancePool.length){var a=i.instancePool.pop();return i.call(a,e,t,n,r,o),a}return new i(e,t,n,r,o)},s=function(e){var t=this;r(e instanceof t),e.destructor&&e.destructor(),t.instancePool.length<t.poolSize&&t.instancePool.push(e)},l=10,c=o,p=function(e,t){var n=e;return n.instancePool=[],n.getPooled=t||c,n.poolSize||(n.poolSize=l),n.release=s,n},d={addPoolingTo:p,oneArgumentPooler:o,twoArgumentPooler:i,threeArgumentPooler:a,fiveArgumentPooler:u};t.exports=d},{133:133}],29:[function(e,t,n){"use strict";var r=e(115),o={getDOMNode:function(){return r(this)}};t.exports=o},{115:115}],30:[function(e,t,n){"use strict";function r(e){return Object.prototype.hasOwnProperty.call(e,m)||(e[m]=f++,p[e[m]]={}),p[e[m]]}var o=e(15),i=e(17),a=e(18),u=e(59),s=e(102),l=e(27),c=e(134),p={},d=!1,f=0,h={topBlur:"blur",topChange:"change",topClick:"click",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topScroll:"scroll",topSelectionChange:"selectionchange",topTextInput:"textInput",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",topTouchStart:"touchstart",topWheel:"wheel"},m="_reactListenersID"+String(Math.random()).slice(2),v=l({},u,{ReactEventListener:null,injection:{injectReactEventListener:function(e){e.setHandleTopLevel(v.handleTopLevel),v.ReactEventListener=e}},setEnabled:function(e){v.ReactEventListener&&v.ReactEventListener.setEnabled(e)},isEnabled:function(){return!(!v.ReactEventListener||!v.ReactEventListener.isEnabled())},listenTo:function(e,t){for(var n=t,i=r(n),u=a.registrationNameDependencies[e],s=o.topLevelTypes,l=0,p=u.length;p>l;l++){var d=u[l];i.hasOwnProperty(d)&&i[d]||(d===s.topWheel?c("wheel")?v.ReactEventListener.trapBubbledEvent(s.topWheel,"wheel",n):c("mousewheel")?v.ReactEventListener.trapBubbledEvent(s.topWheel,"mousewheel",n):v.ReactEventListener.trapBubbledEvent(s.topWheel,"DOMMouseScroll",n):d===s.topScroll?c("scroll",!0)?v.ReactEventListener.trapCapturedEvent(s.topScroll,"scroll",n):v.ReactEventListener.trapBubbledEvent(s.topScroll,"scroll",v.ReactEventListener.WINDOW_HANDLE):d===s.topFocus||d===s.topBlur?(c("focus",!0)?(v.ReactEventListener.trapCapturedEvent(s.topFocus,"focus",n),v.ReactEventListener.trapCapturedEvent(s.topBlur,"blur",n)):c("focusin")&&(v.ReactEventListener.trapBubbledEvent(s.topFocus,"focusin",n),v.ReactEventListener.trapBubbledEvent(s.topBlur,"focusout",n)),i[s.topBlur]=!0,i[s.topFocus]=!0):h.hasOwnProperty(d)&&v.ReactEventListener.trapBubbledEvent(d,h[d],n),i[d]=!0)}},trapBubbledEvent:function(e,t,n){ -return v.ReactEventListener.trapBubbledEvent(e,t,n)},trapCapturedEvent:function(e,t,n){return v.ReactEventListener.trapCapturedEvent(e,t,n)},ensureScrollValueMonitoring:function(){if(!d){var e=s.refreshScrollValues;v.ReactEventListener.monitorScrollValue(e),d=!0}},eventNameDispatchConfigs:i.eventNameDispatchConfigs,registrationNameModules:i.registrationNameModules,putListener:i.putListener,getListener:i.getListener,deleteListener:i.deleteListener,deleteAllListeners:i.deleteAllListeners});t.exports=v},{102:102,134:134,15:15,17:17,18:18,27:27,59:59}],31:[function(e,t,n){"use strict";var r=e(79),o=e(116),i=e(132),a=e(147),u={instantiateChildren:function(e,t,n){var r=o(e);for(var a in r)if(r.hasOwnProperty(a)){var u=r[a],s=i(u,null);r[a]=s}return r},updateChildren:function(e,t,n,u){var s=o(t);if(!s&&!e)return null;var l;for(l in s)if(s.hasOwnProperty(l)){var c=e&&e[l],p=c&&c._currentElement,d=s[l];if(a(p,d))r.receiveComponent(c,d,n,u),s[l]=c;else{c&&r.unmountComponent(c,l);var f=i(d,null);s[l]=f}}for(l in e)!e.hasOwnProperty(l)||s&&s.hasOwnProperty(l)||r.unmountComponent(e[l]);return s},unmountChildren:function(e){for(var t in e){var n=e[t];r.unmountComponent(n)}}};t.exports=u},{116:116,132:132,147:147,79:79}],32:[function(e,t,n){"use strict";function r(e,t){this.forEachFunction=e,this.forEachContext=t}function o(e,t,n,r){var o=e;o.forEachFunction.call(o.forEachContext,t,r)}function i(e,t,n){if(null==e)return e;var i=r.getPooled(t,n);f(e,o,i),r.release(i)}function a(e,t,n){this.mapResult=e,this.mapFunction=t,this.mapContext=n}function u(e,t,n,r){var o=e,i=o.mapResult,a=!i.hasOwnProperty(n);if(a){var u=o.mapFunction.call(o.mapContext,t,r);i[n]=u}}function s(e,t,n){if(null==e)return e;var r={},o=a.getPooled(r,t,n);return f(e,u,o),a.release(o),d.create(r)}function l(e,t,n,r){return null}function c(e,t){return f(e,l,null)}var p=e(28),d=e(61),f=e(149),h=(e(150),p.twoArgumentPooler),m=p.threeArgumentPooler;p.addPoolingTo(r,h),p.addPoolingTo(a,m);var v={forEach:i,map:s,count:c};t.exports=v},{149:149,150:150,28:28,61:61}],33:[function(e,t,n){"use strict";function r(e,t){var n=D.hasOwnProperty(t)?D[t]:null;N.hasOwnProperty(t)&&y(n===_.OVERRIDE_BASE),e.hasOwnProperty(t)&&y(n===_.DEFINE_MANY||n===_.DEFINE_MANY_MERGED)}function o(e,t){if(t){y("function"!=typeof t),y(!d.isValidElement(t));var n=e.prototype;t.hasOwnProperty(b)&&M.mixins(e,t.mixins);for(var o in t)if(t.hasOwnProperty(o)&&o!==b){var i=t[o];if(r(n,o),M.hasOwnProperty(o))M[o](e,i);else{var a=D.hasOwnProperty(o),l=n.hasOwnProperty(o),c=i&&i.__reactDontBind,p="function"==typeof i,f=p&&!a&&!l&&!c;if(f)n.__reactAutoBindMap||(n.__reactAutoBindMap={}),n.__reactAutoBindMap[o]=i,n[o]=i;else if(l){var h=D[o];y(a&&(h===_.DEFINE_MANY_MERGED||h===_.DEFINE_MANY)),h===_.DEFINE_MANY_MERGED?n[o]=u(n[o],i):h===_.DEFINE_MANY&&(n[o]=s(n[o],i))}else n[o]=i}}}}function i(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var o=n in M;y(!o);var i=n in e;y(!i),e[n]=r}}}function a(e,t){y(e&&t&&"object"==typeof e&&"object"==typeof t);for(var n in t)t.hasOwnProperty(n)&&(y(void 0===e[n]),e[n]=t[n]);return e}function u(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);if(null==n)return r;if(null==r)return n;var o={};return a(o,n),a(o,r),o}}function s(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}function l(e,t){var n=t.bind(e);return n}function c(e){for(var t in e.__reactAutoBindMap)if(e.__reactAutoBindMap.hasOwnProperty(t)){var n=e.__reactAutoBindMap[t];e[t]=l(e,f.guard(n,e.constructor.displayName+"."+t))}}var p=e(34),d=(e(39),e(55)),f=e(58),h=e(65),m=e(66),v=(e(75),e(74),e(84)),g=e(27),y=e(133),C=e(138),E=e(139),b=(e(150),E({mixins:null})),_=C({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),x=[],D={mixins:_.DEFINE_MANY,statics:_.DEFINE_MANY,propTypes:_.DEFINE_MANY,contextTypes:_.DEFINE_MANY,childContextTypes:_.DEFINE_MANY,getDefaultProps:_.DEFINE_MANY_MERGED,getInitialState:_.DEFINE_MANY_MERGED,getChildContext:_.DEFINE_MANY_MERGED,render:_.DEFINE_ONCE,componentWillMount:_.DEFINE_MANY,componentDidMount:_.DEFINE_MANY,componentWillReceiveProps:_.DEFINE_MANY,shouldComponentUpdate:_.DEFINE_ONCE,componentWillUpdate:_.DEFINE_MANY,componentDidUpdate:_.DEFINE_MANY,componentWillUnmount:_.DEFINE_MANY,updateComponent:_.OVERRIDE_BASE},M={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n<t.length;n++)o(e,t[n])},childContextTypes:function(e,t){e.childContextTypes=g({},e.childContextTypes,t)},contextTypes:function(e,t){e.contextTypes=g({},e.contextTypes,t)},getDefaultProps:function(e,t){e.getDefaultProps?e.getDefaultProps=u(e.getDefaultProps,t):e.getDefaultProps=t},propTypes:function(e,t){e.propTypes=g({},e.propTypes,t)},statics:function(e,t){i(e,t)}},N={replaceState:function(e,t){v.enqueueReplaceState(this,e),t&&v.enqueueCallback(this,t)},isMounted:function(){var e=h.get(this);return e&&e!==m.currentlyMountingInstance},setProps:function(e,t){v.enqueueSetProps(this,e),t&&v.enqueueCallback(this,t)},replaceProps:function(e,t){v.enqueueReplaceProps(this,e),t&&v.enqueueCallback(this,t)}},I=function(){};g(I.prototype,p.prototype,N);var T={createClass:function(e){var t=function(e,t){this.__reactAutoBindMap&&c(this),this.props=e,this.context=t,this.state=null;var n=this.getInitialState?this.getInitialState():null;y("object"==typeof n&&!Array.isArray(n)),this.state=n};t.prototype=new I,t.prototype.constructor=t,x.forEach(o.bind(null,t)),o(t,e),t.getDefaultProps&&(t.defaultProps=t.getDefaultProps()),y(t.prototype.render);for(var n in D)t.prototype[n]||(t.prototype[n]=null);return t.type=t,t},injection:{injectMixin:function(e){x.push(e)}}};t.exports=T},{133:133,138:138,139:139,150:150,27:27,34:34,39:39,55:55,58:58,65:65,66:66,74:74,75:75,84:84}],34:[function(e,t,n){"use strict";function r(e,t){this.props=e,this.context=t}{var o=e(84),i=e(133);e(150)}r.prototype.setState=function(e,t){i("object"==typeof e||"function"==typeof e||null==e),o.enqueueSetState(this,e),t&&o.enqueueCallback(this,t)},r.prototype.forceUpdate=function(e){o.enqueueForceUpdate(this),e&&o.enqueueCallback(this,e)};t.exports=r},{133:133,150:150,84:84}],35:[function(e,t,n){"use strict";var r=e(44),o=e(68),i={processChildrenUpdates:r.dangerouslyProcessChildrenUpdates,replaceNodeWithMarkupByID:r.dangerouslyReplaceNodeWithMarkupByID,unmountIDFromEnvironment:function(e){o.purgeID(e)}};t.exports=i},{44:44,68:68}],36:[function(e,t,n){"use strict";var r=e(133),o=!1,i={unmountIDFromEnvironment:null,replaceNodeWithMarkupByID:null,processChildrenUpdates:null,injection:{injectEnvironment:function(e){r(!o),i.unmountIDFromEnvironment=e.unmountIDFromEnvironment,i.replaceNodeWithMarkupByID=e.replaceNodeWithMarkupByID,i.processChildrenUpdates=e.processChildrenUpdates,o=!0}}};t.exports=i},{133:133}],37:[function(e,t,n){"use strict";function r(e){var t=e._currentElement._owner||null;if(t){var n=t.getName();if(n)return" Check the render method of `"+n+"`."}return""}var o=e(36),i=e(38),a=e(39),u=e(55),s=(e(56),e(65)),l=e(66),c=e(71),p=e(73),d=e(75),f=(e(74),e(79)),h=e(85),m=e(27),v=e(113),g=e(133),y=e(147),C=(e(150),1),E={construct:function(e){this._currentElement=e,this._rootNodeID=null,this._instance=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._isTopLevel=!1,this._pendingCallbacks=null},mountComponent:function(e,t,n){this._context=n,this._mountOrder=C++,this._rootNodeID=e;var r=this._processProps(this._currentElement.props),o=this._processContext(this._currentElement._context),i=c.getComponentClassForElement(this._currentElement),a=new i(r,o);a.props=r,a.context=o,a.refs=v,this._instance=a,s.set(a,this);var u=a.state;void 0===u&&(a.state=u=null),g("object"==typeof u&&!Array.isArray(u)),this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1;var p,d,h=l.currentlyMountingInstance;l.currentlyMountingInstance=this;try{a.componentWillMount&&(a.componentWillMount(),this._pendingStateQueue&&(a.state=this._processPendingState(a.props,a.context))),p=this._getValidatedChildContext(n),d=this._renderValidatedComponent(p)}finally{l.currentlyMountingInstance=h}this._renderedComponent=this._instantiateReactComponent(d,this._currentElement.type);var m=f.mountComponent(this._renderedComponent,e,t,this._mergeChildContext(n,p));return a.componentDidMount&&t.getReactMountReady().enqueue(a.componentDidMount,a),m},unmountComponent:function(){var e=this._instance;if(e.componentWillUnmount){var t=l.currentlyUnmountingInstance;l.currentlyUnmountingInstance=this;try{e.componentWillUnmount()}finally{l.currentlyUnmountingInstance=t}}f.unmountComponent(this._renderedComponent),this._renderedComponent=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=null,s.remove(e)},_setPropsInternal:function(e,t){var n=this._pendingElement||this._currentElement;this._pendingElement=u.cloneAndReplaceProps(n,m({},n.props,e)),h.enqueueUpdate(this,t)},_maskContext:function(e){var t=null;if("string"==typeof this._currentElement.type)return v;var n=this._currentElement.type.contextTypes;if(!n)return v;t={};for(var r in n)t[r]=e[r];return t},_processContext:function(e){var t=this._maskContext(e);return t},_getValidatedChildContext:function(e){var t=this._instance,n=t.getChildContext&&t.getChildContext();if(n){g("object"==typeof t.constructor.childContextTypes);for(var r in n)g(r in t.constructor.childContextTypes);return n}return null},_mergeChildContext:function(e,t){return t?m({},e,t):e},_processProps:function(e){return e},_checkPropTypes:function(e,t,n){var o=this.getName();for(var i in e)if(e.hasOwnProperty(i)){var a;try{g("function"==typeof e[i]),a=e[i](t,i,o,n)}catch(u){a=u}a instanceof Error&&(r(this),n===d.prop)}},receiveComponent:function(e,t,n){var r=this._currentElement,o=this._context;this._pendingElement=null,this.updateComponent(t,r,e,o,n)},performUpdateIfNecessary:function(e){null!=this._pendingElement&&f.receiveComponent(this,this._pendingElement||this._currentElement,e,this._context),(null!==this._pendingStateQueue||this._pendingForceUpdate)&&this.updateComponent(e,this._currentElement,this._currentElement,this._context,this._context)},_warnIfContextsDiffer:function(e,t){e=this._maskContext(e),t=this._maskContext(t);for(var n=Object.keys(t).sort(),r=(this.getName()||"ReactCompositeComponent",0);r<n.length;r++)n[r]},updateComponent:function(e,t,n,r,o){var i=this._instance,a=i.context,u=i.props;t!==n&&(a=this._processContext(n._context),u=this._processProps(n.props),i.componentWillReceiveProps&&i.componentWillReceiveProps(u,a));var s=this._processPendingState(u,a),l=this._pendingForceUpdate||!i.shouldComponentUpdate||i.shouldComponentUpdate(u,s,a);l?(this._pendingForceUpdate=!1,this._performComponentUpdate(n,u,s,a,e,o)):(this._currentElement=n,this._context=o,i.props=u,i.state=s,i.context=a)},_processPendingState:function(e,t){var n=this._instance,r=this._pendingStateQueue,o=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!r)return n.state;if(o&&1===r.length)return r[0];for(var i=m({},o?r[0]:n.state),a=o?1:0;a<r.length;a++){var u=r[a];m(i,"function"==typeof u?u.call(n,i,e,t):u)}return i},_performComponentUpdate:function(e,t,n,r,o,i){var a=this._instance,u=a.props,s=a.state,l=a.context;a.componentWillUpdate&&a.componentWillUpdate(t,n,r),this._currentElement=e,this._context=i,a.props=t,a.state=n,a.context=r,this._updateRenderedComponent(o,i),a.componentDidUpdate&&o.getReactMountReady().enqueue(a.componentDidUpdate.bind(a,u,s,l),a)},_updateRenderedComponent:function(e,t){var n=this._renderedComponent,r=n._currentElement,o=this._getValidatedChildContext(),i=this._renderValidatedComponent(o);if(y(r,i))f.receiveComponent(n,i,e,this._mergeChildContext(t,o));else{var a=this._rootNodeID,u=n._rootNodeID;f.unmountComponent(n),this._renderedComponent=this._instantiateReactComponent(i,this._currentElement.type);var s=f.mountComponent(this._renderedComponent,a,e,this._mergeChildContext(t,o));this._replaceNodeWithMarkupByID(u,s)}},_replaceNodeWithMarkupByID:function(e,t){o.replaceNodeWithMarkupByID(e,t)},_renderValidatedComponentWithoutOwnerOrContext:function(){var e=this._instance,t=e.render();return t},_renderValidatedComponent:function(e){var t,n=i.current;i.current=this._mergeChildContext(this._currentElement._context,e),a.current=this;try{t=this._renderValidatedComponentWithoutOwnerOrContext()}finally{i.current=n,a.current=null}return g(null===t||t===!1||u.isValidElement(t)),t},attachRef:function(e,t){var n=this.getPublicInstance(),r=n.refs===v?n.refs={}:n.refs;r[e]=t.getPublicInstance()},detachRef:function(e){var t=this.getPublicInstance().refs;delete t[e]},getName:function(){var e=this._currentElement.type,t=this._instance&&this._instance.constructor;return e.displayName||t&&t.displayName||e.name||t&&t.name||null},getPublicInstance:function(){return this._instance},_instantiateReactComponent:null};p.measureMethods(E,"ReactCompositeComponent",{mountComponent:"mountComponent",updateComponent:"updateComponent",_renderValidatedComponent:"_renderValidatedComponent"});var b={Mixin:E};t.exports=b},{113:113,133:133,147:147,150:150,27:27,36:36,38:38,39:39,55:55,56:56,65:65,66:66,71:71,73:73,74:74,75:75,79:79,85:85}],38:[function(e,t,n){"use strict";var r=e(27),o=e(113),i=(e(150),{current:o,withContext:function(e,t){var n,o=i.current;i.current=r({},o,e);try{n=t()}finally{i.current=o}return n}});t.exports=i},{113:113,150:150,27:27}],39:[function(e,t,n){"use strict";var r={current:null};t.exports=r},{}],40:[function(e,t,n){"use strict";function r(e){return o.createFactory(e)}var o=e(55),i=(e(56),e(140)),a=i({a:"a",abbr:"abbr",address:"address",area:"area",article:"article",aside:"aside",audio:"audio",b:"b",base:"base",bdi:"bdi",bdo:"bdo",big:"big",blockquote:"blockquote",body:"body",br:"br",button:"button",canvas:"canvas",caption:"caption",cite:"cite",code:"code",col:"col",colgroup:"colgroup",data:"data",datalist:"datalist",dd:"dd",del:"del",details:"details",dfn:"dfn",dialog:"dialog",div:"div",dl:"dl",dt:"dt",em:"em",embed:"embed",fieldset:"fieldset",figcaption:"figcaption",figure:"figure",footer:"footer",form:"form",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",head:"head",header:"header",hr:"hr",html:"html",i:"i",iframe:"iframe",img:"img",input:"input",ins:"ins",kbd:"kbd",keygen:"keygen",label:"label",legend:"legend",li:"li",link:"link",main:"main",map:"map",mark:"mark",menu:"menu",menuitem:"menuitem",meta:"meta",meter:"meter",nav:"nav",noscript:"noscript",object:"object",ol:"ol",optgroup:"optgroup",option:"option",output:"output",p:"p",param:"param",picture:"picture",pre:"pre",progress:"progress",q:"q",rp:"rp",rt:"rt",ruby:"ruby",s:"s",samp:"samp",script:"script",section:"section",select:"select",small:"small",source:"source",span:"span",strong:"strong",style:"style",sub:"sub",summary:"summary",sup:"sup",table:"table",tbody:"tbody",td:"td",textarea:"textarea",tfoot:"tfoot",th:"th",thead:"thead",time:"time",title:"title",tr:"tr",track:"track",u:"u",ul:"ul","var":"var",video:"video",wbr:"wbr",circle:"circle",clipPath:"clipPath",defs:"defs",ellipse:"ellipse",g:"g",line:"line",linearGradient:"linearGradient",mask:"mask",path:"path",pattern:"pattern",polygon:"polygon",polyline:"polyline",radialGradient:"radialGradient",rect:"rect",stop:"stop",svg:"svg",text:"text",tspan:"tspan"},r);t.exports=a},{140:140,55:55,56:56}],41:[function(e,t,n){"use strict";var r=e(2),o=e(29),i=e(33),a=e(55),u=e(138),s=a.createFactory("button"),l=u({onClick:!0,onDoubleClick:!0,onMouseDown:!0,onMouseMove:!0,onMouseUp:!0,onClickCapture:!0,onDoubleClickCapture:!0,onMouseDownCapture:!0,onMouseMoveCapture:!0,onMouseUpCapture:!0}),c=i.createClass({displayName:"ReactDOMButton",tagName:"BUTTON",mixins:[r,o],render:function(){var e={};for(var t in this.props)!this.props.hasOwnProperty(t)||this.props.disabled&&l[t]||(e[t]=this.props[t]);return s(e,this.props.children)}});t.exports=c},{138:138,2:2,29:29,33:33,55:55}],42:[function(e,t,n){"use strict";function r(e){e&&(null!=e.dangerouslySetInnerHTML&&(g(null==e.children),g("object"==typeof e.dangerouslySetInnerHTML&&"__html"in e.dangerouslySetInnerHTML)),g(null==e.style||"object"==typeof e.style))}function o(e,t,n,r){var o=d.findReactContainerForID(e);if(o){var i=o.nodeType===D?o.ownerDocument:o;E(t,i)}r.getPutListenerQueue().enqueuePutListener(e,t,n)}function i(e){P.call(T,e)||(g(I.test(e)),T[e]=!0)}function a(e){i(e),this._tag=e,this._renderedChildren=null,this._previousStyleCopy=null,this._rootNodeID=null}var u=e(5),s=e(10),l=e(11),c=e(30),p=e(35),d=e(68),f=e(69),h=e(73),m=e(27),v=e(114),g=e(133),y=(e(134),e(139)),C=(e(150),c.deleteListener),E=c.listenTo,b=c.registrationNameModules,_={string:!0,number:!0},x=y({style:null}),D=1,M=null,N={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},I=/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/,T={},P={}.hasOwnProperty;a.displayName="ReactDOMComponent",a.Mixin={construct:function(e){this._currentElement=e},mountComponent:function(e,t,n){this._rootNodeID=e,r(this._currentElement.props);var o=N[this._tag]?"":"</"+this._tag+">";return this._createOpenTagMarkupAndPutListeners(t)+this._createContentMarkup(t,n)+o},_createOpenTagMarkupAndPutListeners:function(e){var t=this._currentElement.props,n="<"+this._tag;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];if(null!=i)if(b.hasOwnProperty(r))o(this._rootNodeID,r,i,e);else{r===x&&(i&&(i=this._previousStyleCopy=m({},t.style)),i=u.createMarkupForStyles(i));var a=l.createMarkupForProperty(r,i);a&&(n+=" "+a)}}if(e.renderToStaticMarkup)return n+">";var s=l.createMarkupForID(this._rootNodeID);return n+" "+s+">"},_createContentMarkup:function(e,t){var n="";("listing"===this._tag||"pre"===this._tag||"textarea"===this._tag)&&(n="\n");var r=this._currentElement.props,o=r.dangerouslySetInnerHTML;if(null!=o){if(null!=o.__html)return n+o.__html}else{var i=_[typeof r.children]?r.children:null,a=null!=i?null:r.children;if(null!=i)return n+v(i);if(null!=a){var u=this.mountChildren(a,e,t);return n+u.join("")}}return n},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,o){r(this._currentElement.props),this._updateDOMProperties(t.props,e),this._updateDOMChildren(t.props,e,o)},_updateDOMProperties:function(e,t){var n,r,i,a=this._currentElement.props;for(n in e)if(!a.hasOwnProperty(n)&&e.hasOwnProperty(n))if(n===x){var u=this._previousStyleCopy;for(r in u)u.hasOwnProperty(r)&&(i=i||{},i[r]="");this._previousStyleCopy=null}else b.hasOwnProperty(n)?C(this._rootNodeID,n):(s.isStandardName[n]||s.isCustomAttribute(n))&&M.deletePropertyByID(this._rootNodeID,n);for(n in a){var l=a[n],c=n===x?this._previousStyleCopy:e[n];if(a.hasOwnProperty(n)&&l!==c)if(n===x)if(l?l=this._previousStyleCopy=m({},l):this._previousStyleCopy=null,c){for(r in c)!c.hasOwnProperty(r)||l&&l.hasOwnProperty(r)||(i=i||{},i[r]="");for(r in l)l.hasOwnProperty(r)&&c[r]!==l[r]&&(i=i||{},i[r]=l[r])}else i=l;else b.hasOwnProperty(n)?o(this._rootNodeID,n,l,t):(s.isStandardName[n]||s.isCustomAttribute(n))&&M.updatePropertyByID(this._rootNodeID,n,l)}i&&M.updateStylesByID(this._rootNodeID,i)},_updateDOMChildren:function(e,t,n){var r=this._currentElement.props,o=_[typeof e.children]?e.children:null,i=_[typeof r.children]?r.children:null,a=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,u=r.dangerouslySetInnerHTML&&r.dangerouslySetInnerHTML.__html,s=null!=o?null:e.children,l=null!=i?null:r.children,c=null!=o||null!=a,p=null!=i||null!=u;null!=s&&null==l?this.updateChildren(null,t,n):c&&!p&&this.updateTextContent(""),null!=i?o!==i&&this.updateTextContent(""+i):null!=u?a!==u&&M.updateInnerHTMLByID(this._rootNodeID,u):null!=l&&this.updateChildren(l,t,n)},unmountComponent:function(){this.unmountChildren(),c.deleteAllListeners(this._rootNodeID),p.unmountIDFromEnvironment(this._rootNodeID),this._rootNodeID=null}},h.measureMethods(a,"ReactDOMComponent",{mountComponent:"mountComponent",updateComponent:"updateComponent"}),m(a.prototype,a.Mixin,f.Mixin),a.injection={injectIDOperations:function(e){a.BackendIDOperations=M=e}},t.exports=a},{10:10,11:11,114:114,133:133,134:134,139:139,150:150,27:27,30:30,35:35,5:5,68:68,69:69,73:73}],43:[function(e,t,n){"use strict";var r=e(15),o=e(25),i=e(29),a=e(33),u=e(55),s=u.createFactory("form"),l=a.createClass({displayName:"ReactDOMForm",tagName:"FORM",mixins:[i,o],render:function(){return s(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topReset,"reset"),this.trapBubbledEvent(r.topLevelTypes.topSubmit,"submit")}});t.exports=l},{15:15,25:25,29:29,33:33,55:55}],44:[function(e,t,n){"use strict";var r=e(5),o=e(9),i=e(11),a=e(68),u=e(73),s=e(133),l=e(144),c={dangerouslySetInnerHTML:"`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.",style:"`style` must be set using `updateStylesByID()`."},p={updatePropertyByID:function(e,t,n){var r=a.getNode(e);s(!c.hasOwnProperty(t)),null!=n?i.setValueForProperty(r,t,n):i.deleteValueForProperty(r,t)},deletePropertyByID:function(e,t,n){var r=a.getNode(e);s(!c.hasOwnProperty(t)),i.deleteValueForProperty(r,t,n)},updateStylesByID:function(e,t){var n=a.getNode(e);r.setValueForStyles(n,t)},updateInnerHTMLByID:function(e,t){var n=a.getNode(e);l(n,t)},updateTextContentByID:function(e,t){var n=a.getNode(e);o.updateTextContent(n,t)},dangerouslyReplaceNodeWithMarkupByID:function(e,t){var n=a.getNode(e);o.dangerouslyReplaceNodeWithMarkup(n,t)},dangerouslyProcessChildrenUpdates:function(e,t){for(var n=0;n<e.length;n++)e[n].parentNode=a.getNode(e[n].parentID);o.processUpdates(e,t)}};u.measureMethods(p,"ReactDOMIDOperations",{updatePropertyByID:"updatePropertyByID",deletePropertyByID:"deletePropertyByID",updateStylesByID:"updateStylesByID",updateInnerHTMLByID:"updateInnerHTMLByID",updateTextContentByID:"updateTextContentByID",dangerouslyReplaceNodeWithMarkupByID:"dangerouslyReplaceNodeWithMarkupByID",dangerouslyProcessChildrenUpdates:"dangerouslyProcessChildrenUpdates"}),t.exports=p},{11:11,133:133,144:144,5:5,68:68,73:73,9:9}],45:[function(e,t,n){"use strict";var r=e(15),o=e(25),i=e(29),a=e(33),u=e(55),s=u.createFactory("iframe"),l=a.createClass({displayName:"ReactDOMIframe",tagName:"IFRAME",mixins:[i,o],render:function(){return s(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topLoad,"load")}});t.exports=l},{15:15,25:25,29:29,33:33,55:55}],46:[function(e,t,n){"use strict";var r=e(15),o=e(25),i=e(29),a=e(33),u=e(55),s=u.createFactory("img"),l=a.createClass({displayName:"ReactDOMImg",tagName:"IMG",mixins:[i,o],render:function(){return s(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topLoad,"load"),this.trapBubbledEvent(r.topLevelTypes.topError,"error")}});t.exports=l},{15:15,25:25,29:29,33:33,55:55}],47:[function(e,t,n){"use strict";function r(){this.isMounted()&&this.forceUpdate()}var o=e(2),i=e(11),a=e(24),u=e(29),s=e(33),l=e(55),c=e(68),p=e(85),d=e(27),f=e(133),h=l.createFactory("input"),m={},v=s.createClass({displayName:"ReactDOMInput",tagName:"INPUT",mixins:[o,a.Mixin,u],getInitialState:function(){var e=this.props.defaultValue;return{initialChecked:this.props.defaultChecked||!1,initialValue:null!=e?e:null}},render:function(){var e=d({},this.props);e.defaultChecked=null,e.defaultValue=null;var t=a.getValue(this);e.value=null!=t?t:this.state.initialValue;var n=a.getChecked(this);return e.checked=null!=n?n:this.state.initialChecked,e.onChange=this._handleChange,h(e,this.props.children)},componentDidMount:function(){var e=c.getID(this.getDOMNode());m[e]=this},componentWillUnmount:function(){var e=this.getDOMNode(),t=c.getID(e);delete m[t]},componentDidUpdate:function(e,t,n){var r=this.getDOMNode();null!=this.props.checked&&i.setValueForProperty(r,"checked",this.props.checked||!1);var o=a.getValue(this);null!=o&&i.setValueForProperty(r,"value",""+o)},_handleChange:function(e){var t,n=a.getOnChange(this);n&&(t=n.call(this,e)),p.asap(r,this);var o=this.props.name;if("radio"===this.props.type&&null!=o){for(var i=this.getDOMNode(),u=i;u.parentNode;)u=u.parentNode;for(var s=u.querySelectorAll("input[name="+JSON.stringify(""+o)+'][type="radio"]'),l=0,d=s.length;d>l;l++){var h=s[l];if(h!==i&&h.form===i.form){var v=c.getID(h);f(v);var g=m[v];f(g),p.asap(r,g)}}}return t}});t.exports=v},{11:11,133:133,2:2,24:24,27:27,29:29,33:33,55:55,68:68,85:85}],48:[function(e,t,n){"use strict";var r=e(29),o=e(33),i=e(55),a=(e(150),i.createFactory("option")),u=o.createClass({displayName:"ReactDOMOption",tagName:"OPTION",mixins:[r],componentWillMount:function(){},render:function(){return a(this.props,this.props.children)}});t.exports=u},{150:150,29:29,33:33,55:55}],49:[function(e,t,n){"use strict";function r(){if(this._pendingUpdate){this._pendingUpdate=!1;var e=u.getValue(this);null!=e&&this.isMounted()&&i(this,e)}}function o(e,t,n){if(null==e[t])return null;if(e.multiple){if(!Array.isArray(e[t]))return new Error("The `"+t+"` prop supplied to <select> must be an array if `multiple` is true.")}else if(Array.isArray(e[t]))return new Error("The `"+t+"` prop supplied to <select> must be a scalar value if `multiple` is false.")}function i(e,t){var n,r,o,i=e.getDOMNode().options;if(e.props.multiple){for(n={},r=0,o=t.length;o>r;r++)n[""+t[r]]=!0;for(r=0,o=i.length;o>r;r++){var a=n.hasOwnProperty(i[r].value);i[r].selected!==a&&(i[r].selected=a)}}else{for(n=""+t,r=0,o=i.length;o>r;r++)if(i[r].value===n)return void(i[r].selected=!0);i.length&&(i[0].selected=!0)}}var a=e(2),u=e(24),s=e(29),l=e(33),c=e(55),p=e(85),d=e(27),f=c.createFactory("select"),h=l.createClass({displayName:"ReactDOMSelect",tagName:"SELECT",mixins:[a,u.Mixin,s],propTypes:{defaultValue:o,value:o},render:function(){var e=d({},this.props);return e.onChange=this._handleChange,e.value=null,f(e,this.props.children)},componentWillMount:function(){this._pendingUpdate=!1},componentDidMount:function(){var e=u.getValue(this);null!=e?i(this,e):null!=this.props.defaultValue&&i(this,this.props.defaultValue)},componentDidUpdate:function(e){var t=u.getValue(this);null!=t?(this._pendingUpdate=!1,i(this,t)):!e.multiple!=!this.props.multiple&&(null!=this.props.defaultValue?i(this,this.props.defaultValue):i(this,this.props.multiple?[]:""))},_handleChange:function(e){var t,n=u.getOnChange(this);return n&&(t=n.call(this,e)),this._pendingUpdate=!0,p.asap(r,this),t}});t.exports=h},{2:2,24:24,27:27,29:29,33:33,55:55,85:85}],50:[function(e,t,n){"use strict";function r(e,t,n,r){return e===n&&t===r}function o(e){var t=document.selection,n=t.createRange(),r=n.text.length,o=n.duplicate();o.moveToElementText(e),o.setEndPoint("EndToStart",n);var i=o.text.length,a=i+r;return{start:i,end:a}}function i(e){var t=window.getSelection&&window.getSelection();if(!t||0===t.rangeCount)return null;var n=t.anchorNode,o=t.anchorOffset,i=t.focusNode,a=t.focusOffset,u=t.getRangeAt(0),s=r(t.anchorNode,t.anchorOffset,t.focusNode,t.focusOffset),l=s?0:u.toString().length,c=u.cloneRange();c.selectNodeContents(e),c.setEnd(u.startContainer,u.startOffset);var p=r(c.startContainer,c.startOffset,c.endContainer,c.endOffset),d=p?0:c.toString().length,f=d+l,h=document.createRange();h.setStart(n,o),h.setEnd(i,a);var m=h.collapsed;return{start:m?f:d,end:m?d:f}}function a(e,t){var n,r,o=document.selection.createRange().duplicate();"undefined"==typeof t.end?(n=t.start,r=n):t.start>t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),o.moveToElementText(e),o.moveStart("character",n),o.setEndPoint("EndToStart",o),o.moveEnd("character",r-n),o.select()}function u(e,t){if(window.getSelection){var n=window.getSelection(),r=e[c()].length,o=Math.min(t.start,r),i="undefined"==typeof t.end?o:Math.min(t.end,r);if(!n.extend&&o>i){var a=i;i=o,o=a}var u=l(e,o),s=l(e,i);if(u&&s){var p=document.createRange();p.setStart(u.node,u.offset),n.removeAllRanges(),o>i?(n.addRange(p),n.extend(s.node,s.offset)):(p.setEnd(s.node,s.offset),n.addRange(p))}}}var s=e(21),l=e(126),c=e(128),p=s.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:p?o:i,setOffsets:p?a:u};t.exports=d},{126:126,128:128,21:21}],51:[function(e,t,n){"use strict";var r=e(11),o=e(35),i=e(42),a=e(27),u=e(114),s=function(e){};a(s.prototype,{construct:function(e){this._currentElement=e,this._stringText=""+e,this._rootNodeID=null,this._mountIndex=0},mountComponent:function(e,t,n){this._rootNodeID=e;var o=u(this._stringText);return t.renderToStaticMarkup?o:"<span "+r.createMarkupForID(e)+">"+o+"</span>"},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;n!==this._stringText&&(this._stringText=n,i.BackendIDOperations.updateTextContentByID(this._rootNodeID,n))}},unmountComponent:function(){o.unmountIDFromEnvironment(this._rootNodeID)}}),t.exports=s},{11:11,114:114,27:27,35:35,42:42}],52:[function(e,t,n){"use strict";function r(){this.isMounted()&&this.forceUpdate()}var o=e(2),i=e(11),a=e(24),u=e(29),s=e(33),l=e(55),c=e(85),p=e(27),d=e(133),f=(e(150),l.createFactory("textarea")),h=s.createClass({displayName:"ReactDOMTextarea",tagName:"TEXTAREA",mixins:[o,a.Mixin,u],getInitialState:function(){var e=this.props.defaultValue,t=this.props.children;null!=t&&(d(null==e),Array.isArray(t)&&(d(t.length<=1),t=t[0]),e=""+t),null==e&&(e="");var n=a.getValue(this);return{initialValue:""+(null!=n?n:e)}},render:function(){var e=p({},this.props);return d(null==e.dangerouslySetInnerHTML),e.defaultValue=null,e.value=null,e.onChange=this._handleChange,f(e,this.state.initialValue)},componentDidUpdate:function(e,t,n){var r=a.getValue(this);if(null!=r){var o=this.getDOMNode();i.setValueForProperty(o,"value",""+r)}},_handleChange:function(e){var t,n=a.getOnChange(this);return n&&(t=n.call(this,e)),c.asap(r,this),t}});t.exports=h},{11:11,133:133,150:150,2:2,24:24,27:27,29:29,33:33,55:55,85:85}],53:[function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var o=e(85),i=e(101),a=e(27),u=e(112),s={initialize:u,close:function(){d.isBatchingUpdates=!1}},l={initialize:u,close:o.flushBatchedUpdates.bind(o)},c=[l,s];a(r.prototype,i.Mixin,{getTransactionWrappers:function(){return c}});var p=new r,d={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,o){var i=d.isBatchingUpdates;d.isBatchingUpdates=!0,i?e(t,n,r,o):p.perform(e,null,t,n,r,o)}};t.exports=d},{101:101,112:112,27:27,85:85}],54:[function(e,t,n){"use strict";function r(e){return h.createClass({tagName:e.toUpperCase(),render:function(){return new T(e,null,null,null,null,this.props)}})}function o(){R.EventEmitter.injectReactEventListener(P),R.EventPluginHub.injectEventPluginOrder(s),R.EventPluginHub.injectInstanceHandle(w),R.EventPluginHub.injectMount(O),R.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:L,EnterLeaveEventPlugin:l,ChangeEventPlugin:a,MobileSafariClickEventPlugin:d,SelectEventPlugin:A,BeforeInputEventPlugin:i}),R.NativeComponent.injectGenericComponentClass(g),R.NativeComponent.injectTextComponentClass(I),R.NativeComponent.injectAutoWrapper(r),R.Class.injectMixin(f),R.NativeComponent.injectComponentClasses({button:y,form:C,iframe:_,img:E,input:x,option:D,select:M,textarea:N,html:F("html"),head:F("head"),body:F("body")}),R.DOMProperty.injectDOMPropertyConfig(p),R.DOMProperty.injectDOMPropertyConfig(U),R.EmptyComponent.injectEmptyComponent("noscript"),R.Updates.injectReconcileTransaction(S),R.Updates.injectBatchingStrategy(v),R.RootIndex.injectCreateReactRootIndex(c.canUseDOM?u.createReactRootIndex:k.createReactRootIndex),R.Component.injectEnvironment(m),R.DOMComponent.injectIDOperations(b)}var i=e(3),a=e(7),u=e(8),s=e(13),l=e(14),c=e(21),p=e(23),d=e(26),f=e(29),h=e(33),m=e(35),v=e(53),g=e(42),y=e(41),C=e(43),E=e(46),b=e(44),_=e(45),x=e(47),D=e(48),M=e(49),N=e(52),I=e(51),T=e(55),P=e(60),R=e(62),w=e(64),O=e(68),S=e(78),A=e(87),k=e(88),L=e(89),U=e(86),F=e(109); - -t.exports={inject:o}},{109:109,13:13,14:14,21:21,23:23,26:26,29:29,3:3,33:33,35:35,41:41,42:42,43:43,44:44,45:45,46:46,47:47,48:48,49:49,51:51,52:52,53:53,55:55,60:60,62:62,64:64,68:68,7:7,78:78,8:8,86:86,87:87,88:88,89:89}],55:[function(e,t,n){"use strict";var r=e(38),o=e(39),i=e(27),a=(e(150),{key:!0,ref:!0}),u=function(e,t,n,r,o,i){this.type=e,this.key=t,this.ref=n,this._owner=r,this._context=o,this.props=i};u.prototype={_isReactElement:!0},u.createElement=function(e,t,n){var i,s={},l=null,c=null;if(null!=t){c=void 0===t.ref?null:t.ref,l=void 0===t.key?null:""+t.key;for(i in t)t.hasOwnProperty(i)&&!a.hasOwnProperty(i)&&(s[i]=t[i])}var p=arguments.length-2;if(1===p)s.children=n;else if(p>1){for(var d=Array(p),f=0;p>f;f++)d[f]=arguments[f+2];s.children=d}if(e&&e.defaultProps){var h=e.defaultProps;for(i in h)"undefined"==typeof s[i]&&(s[i]=h[i])}return new u(e,l,c,o.current,r.current,s)},u.createFactory=function(e){var t=u.createElement.bind(null,e);return t.type=e,t},u.cloneAndReplaceProps=function(e,t){var n=new u(e.type,e.key,e.ref,e._owner,e._context,t);return n},u.cloneElement=function(e,t,n){var r,s=i({},e.props),l=e.key,c=e.ref,p=e._owner;if(null!=t){void 0!==t.ref&&(c=t.ref,p=o.current),void 0!==t.key&&(l=""+t.key);for(r in t)t.hasOwnProperty(r)&&!a.hasOwnProperty(r)&&(s[r]=t[r])}var d=arguments.length-2;if(1===d)s.children=n;else if(d>1){for(var f=Array(d),h=0;d>h;h++)f[h]=arguments[h+2];s.children=f}return new u(e.type,l,c,p,e._context,s)},u.isValidElement=function(e){var t=!(!e||!e._isReactElement);return t},t.exports=u},{150:150,27:27,38:38,39:39}],56:[function(e,t,n){"use strict";function r(){if(y.current){var e=y.current.getName();if(e)return" Check the render method of `"+e+"`."}return""}function o(e){var t=e&&e.getPublicInstance();if(!t)return void 0;var n=t.constructor;return n?n.displayName||n.name||void 0:void 0}function i(){var e=y.current;return e&&o(e)||void 0}function a(e,t){e._store.validated||null!=e.key||(e._store.validated=!0,s('Each child in an array or iterator should have a unique "key" prop.',e,t))}function u(e,t,n){D.test(e)&&s("Child objects should have non-numeric keys so ordering is preserved.",t,n)}function s(e,t,n){var r=i(),a="string"==typeof n?n:n.displayName||n.name,u=r||a,s=_[e]||(_[e]={});if(!s.hasOwnProperty(u)){s[u]=!0;var l="";if(t&&t._owner&&t._owner!==y.current){var c=o(t._owner);l=" It was passed a child from "+c+"."}}}function l(e,t){if(Array.isArray(e))for(var n=0;n<e.length;n++){var r=e[n];m.isValidElement(r)&&a(r,t)}else if(m.isValidElement(e))e._store.validated=!0;else if(e){var o=E(e);if(o){if(o!==e.entries)for(var i,s=o.call(e);!(i=s.next()).done;)m.isValidElement(i.value)&&a(i.value,t)}else if("object"==typeof e){var l=v.extractIfFragment(e);for(var c in l)l.hasOwnProperty(c)&&u(c,l[c],t)}}}function c(e,t,n,o){for(var i in t)if(t.hasOwnProperty(i)){var a;try{b("function"==typeof t[i]),a=t[i](n,i,e,o)}catch(u){a=u}a instanceof Error&&!(a.message in x)&&(x[a.message]=!0,r(this))}}function p(e,t){var n=t.type,r="string"==typeof n?n:n.displayName,o=t._owner?t._owner.getPublicInstance().constructor.displayName:null,i=e+"|"+r+"|"+o;if(!M.hasOwnProperty(i)){M[i]=!0;var a="";r&&(a=" <"+r+" />");var u="";o&&(u=" The element was created by "+o+".")}}function d(e,t){return e!==e?t!==t:0===e&&0===t?1/e===1/t:e===t}function f(e){if(e._store){var t=e._store.originalProps,n=e.props;for(var r in n)n.hasOwnProperty(r)&&(t.hasOwnProperty(r)&&d(t[r],n[r])||(p(r,e),t[r]=n[r]))}}function h(e){if(null!=e.type){var t=C.getComponentClassForElement(e),n=t.displayName||t.name;t.propTypes&&c(n,t.propTypes,e.props,g.prop),"function"==typeof t.getDefaultProps}}var m=e(55),v=e(61),g=e(75),y=(e(74),e(39)),C=e(71),E=e(124),b=e(133),_=(e(150),{}),x={},D=/^\d+$/,M={},N={checkAndWarnForMutatedProps:f,createElement:function(e,t,n){var r=m.createElement.apply(this,arguments);if(null==r)return r;for(var o=2;o<arguments.length;o++)l(arguments[o],e);return h(r),r},createFactory:function(e){var t=N.createElement.bind(null,e);return t.type=e,t},cloneElement:function(e,t,n){for(var r=m.cloneElement.apply(this,arguments),o=2;o<arguments.length;o++)l(arguments[o],r.type);return h(r),r}};t.exports=N},{124:124,133:133,150:150,39:39,55:55,61:61,71:71,74:74,75:75}],57:[function(e,t,n){"use strict";function r(e){c[e]=!0}function o(e){delete c[e]}function i(e){return!!c[e]}var a,u=e(55),s=e(65),l=e(133),c={},p={injectEmptyComponent:function(e){a=u.createFactory(e)}},d=function(){};d.prototype.componentDidMount=function(){var e=s.get(this);e&&r(e._rootNodeID)},d.prototype.componentWillUnmount=function(){var e=s.get(this);e&&o(e._rootNodeID)},d.prototype.render=function(){return l(a),a()};var f=u.createElement(d),h={emptyElement:f,injection:p,isNullComponentID:i};t.exports=h},{133:133,55:55,65:65}],58:[function(e,t,n){"use strict";var r={guard:function(e,t){return e}};t.exports=r},{}],59:[function(e,t,n){"use strict";function r(e){o.enqueueEvents(e),o.processEventQueue()}var o=e(17),i={handleTopLevel:function(e,t,n,i){var a=o.extractEvents(e,t,n,i);r(a)}};t.exports=i},{17:17}],60:[function(e,t,n){"use strict";function r(e){var t=p.getID(e),n=c.getReactRootIDFromNodeID(t),r=p.findReactContainerForID(n),o=p.getFirstReactDOM(r);return o}function o(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function i(e){for(var t=p.getFirstReactDOM(h(e.nativeEvent))||window,n=t;n;)e.ancestors.push(n),n=r(n);for(var o=0,i=e.ancestors.length;i>o;o++){t=e.ancestors[o];var a=p.getID(t)||"";v._handleTopLevel(e.topLevelType,t,a,e.nativeEvent)}}function a(e){var t=m(window);e(t)}var u=e(16),s=e(21),l=e(28),c=e(64),p=e(68),d=e(85),f=e(27),h=e(123),m=e(129);f(o.prototype,{destructor:function(){this.topLevelType=null,this.nativeEvent=null,this.ancestors.length=0}}),l.addPoolingTo(o,l.twoArgumentPooler);var v={_enabled:!0,_handleTopLevel:null,WINDOW_HANDLE:s.canUseDOM?window:null,setHandleTopLevel:function(e){v._handleTopLevel=e},setEnabled:function(e){v._enabled=!!e},isEnabled:function(){return v._enabled},trapBubbledEvent:function(e,t,n){var r=n;return r?u.listen(r,t,v.dispatchEvent.bind(null,e)):null},trapCapturedEvent:function(e,t,n){var r=n;return r?u.capture(r,t,v.dispatchEvent.bind(null,e)):null},monitorScrollValue:function(e){var t=a.bind(null,e);u.listen(window,"scroll",t)},dispatchEvent:function(e,t){if(v._enabled){var n=o.getPooled(e,t);try{d.batchedUpdates(i,n)}finally{o.release(n)}}}};t.exports=v},{123:123,129:129,16:16,21:21,27:27,28:28,64:64,68:68,85:85}],61:[function(e,t,n){"use strict";var r=(e(55),e(150),{create:function(e){return e},extract:function(e){return e},extractIfFragment:function(e){return e}});t.exports=r},{150:150,55:55}],62:[function(e,t,n){"use strict";var r=e(10),o=e(17),i=e(36),a=e(33),u=e(57),s=e(30),l=e(71),c=e(42),p=e(73),d=e(81),f=e(85),h={Component:i.injection,Class:a.injection,DOMComponent:c.injection,DOMProperty:r.injection,EmptyComponent:u.injection,EventPluginHub:o.injection,EventEmitter:s.injection,NativeComponent:l.injection,Perf:p.injection,RootIndex:d.injection,Updates:f.injection};t.exports=h},{10:10,17:17,30:30,33:33,36:36,42:42,57:57,71:71,73:73,81:81,85:85}],63:[function(e,t,n){"use strict";function r(e){return i(document.documentElement,e)}var o=e(50),i=e(107),a=e(117),u=e(119),s={hasSelectionCapabilities:function(e){return e&&("INPUT"===e.nodeName&&"text"===e.type||"TEXTAREA"===e.nodeName||"true"===e.contentEditable)},getSelectionInformation:function(){var e=u();return{focusedElem:e,selectionRange:s.hasSelectionCapabilities(e)?s.getSelection(e):null}},restoreSelection:function(e){var t=u(),n=e.focusedElem,o=e.selectionRange;t!==n&&r(n)&&(s.hasSelectionCapabilities(n)&&s.setSelection(n,o),a(n))},getSelection:function(e){var t;if("selectionStart"in e)t={start:e.selectionStart,end:e.selectionEnd};else if(document.selection&&"INPUT"===e.nodeName){var n=document.selection.createRange();n.parentElement()===e&&(t={start:-n.moveStart("character",-e.value.length),end:-n.moveEnd("character",-e.value.length)})}else t=o.getOffsets(e);return t||{start:0,end:0}},setSelection:function(e,t){var n=t.start,r=t.end;if("undefined"==typeof r&&(r=n),"selectionStart"in e)e.selectionStart=n,e.selectionEnd=Math.min(r,e.value.length);else if(document.selection&&"INPUT"===e.nodeName){var i=e.createTextRange();i.collapse(!0),i.moveStart("character",n),i.moveEnd("character",r-n),i.select()}else o.setOffsets(e,t)}};t.exports=s},{107:107,117:117,119:119,50:50}],64:[function(e,t,n){"use strict";function r(e){return f+e.toString(36)}function o(e,t){return e.charAt(t)===f||t===e.length}function i(e){return""===e||e.charAt(0)===f&&e.charAt(e.length-1)!==f}function a(e,t){return 0===t.indexOf(e)&&o(t,e.length)}function u(e){return e?e.substr(0,e.lastIndexOf(f)):""}function s(e,t){if(d(i(e)&&i(t)),d(a(e,t)),e===t)return e;var n,r=e.length+h;for(n=r;n<t.length&&!o(t,n);n++);return t.substr(0,n)}function l(e,t){var n=Math.min(e.length,t.length);if(0===n)return"";for(var r=0,a=0;n>=a;a++)if(o(e,a)&&o(t,a))r=a;else if(e.charAt(a)!==t.charAt(a))break;var u=e.substr(0,r);return d(i(u)),u}function c(e,t,n,r,o,i){e=e||"",t=t||"",d(e!==t);var l=a(t,e);d(l||a(e,t));for(var c=0,p=l?u:s,f=e;;f=p(f,t)){var h;if(o&&f===e||i&&f===t||(h=n(f,l,r)),h===!1||f===t)break;d(c++<m)}}var p=e(81),d=e(133),f=".",h=f.length,m=100,v={createReactRootID:function(){return r(p.createReactRootIndex())},createReactID:function(e,t){return e+t},getReactRootIDFromNodeID:function(e){if(e&&e.charAt(0)===f&&e.length>1){var t=e.indexOf(f,1);return t>-1?e.substr(0,t):e}return null},traverseEnterLeave:function(e,t,n,r,o){var i=l(e,t);i!==e&&c(e,i,n,r,!1,!0),i!==t&&c(i,t,n,o,!0,!1)},traverseTwoPhase:function(e,t,n){e&&(c("",e,t,n,!0,!1),c(e,"",t,n,!1,!0))},traverseAncestors:function(e,t,n){c("",e,t,n,!0,!1)},_getFirstCommonAncestorID:l,_getNextDescendantID:s,isAncestorIDOf:a,SEPARATOR:f};t.exports=v},{133:133,81:81}],65:[function(e,t,n){"use strict";var r={remove:function(e){e._reactInternalInstance=void 0},get:function(e){return e._reactInternalInstance},has:function(e){return void 0!==e._reactInternalInstance},set:function(e,t){e._reactInternalInstance=t}};t.exports=r},{}],66:[function(e,t,n){"use strict";var r={currentlyMountingInstance:null,currentlyUnmountingInstance:null};t.exports=r},{}],67:[function(e,t,n){"use strict";var r=e(104),o={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return e.replace(">"," "+o.CHECKSUM_ATTR_NAME+'="'+t+'">')},canReuseMarkup:function(e,t){var n=t.getAttribute(o.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var i=r(e);return i===n}};t.exports=o},{104:104}],68:[function(e,t,n){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;n>r;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function o(e){var t=P(e);return t&&K.getID(t)}function i(e){var t=a(e);if(t)if(L.hasOwnProperty(t)){var n=L[t];n!==e&&(w(!c(n,t)),L[t]=e)}else L[t]=e;return t}function a(e){return e&&e.getAttribute&&e.getAttribute(k)||""}function u(e,t){var n=a(e);n!==t&&delete L[n],e.setAttribute(k,t),L[t]=e}function s(e){return L.hasOwnProperty(e)&&c(L[e],e)||(L[e]=K.findReactNodeByID(e)),L[e]}function l(e){var t=b.get(e)._rootNodeID;return C.isNullComponentID(t)?null:(L.hasOwnProperty(t)&&c(L[t],t)||(L[t]=K.findReactNodeByID(t)),L[t])}function c(e,t){if(e){w(a(e)===t);var n=K.findReactContainerForID(t);if(n&&T(n,e))return!0}return!1}function p(e){delete L[e]}function d(e){var t=L[e];return t&&c(t,e)?void(W=t):!1}function f(e){W=null,E.traverseAncestors(e,d);var t=W;return W=null,t}function h(e,t,n,r,o){var i=D.mountComponent(e,t,r,I);e._isTopLevel=!0,K._mountImageIntoNode(i,n,o)}function m(e,t,n,r){var o=N.ReactReconcileTransaction.getPooled();o.perform(h,null,e,t,n,o,r),N.ReactReconcileTransaction.release(o)}var v=e(10),g=e(30),y=(e(39),e(55)),C=(e(56),e(57)),E=e(64),b=e(65),_=e(67),x=e(73),D=e(79),M=e(84),N=e(85),I=e(113),T=e(107),P=e(127),R=e(132),w=e(133),O=e(144),S=e(147),A=(e(150),E.SEPARATOR),k=v.ID_ATTRIBUTE_NAME,L={},U=1,F=9,B={},V={},j=[],W=null,K={_instancesByReactRootID:B,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r){return K.scrollMonitor(n,function(){M.enqueueElementInternal(e,t),r&&M.enqueueCallbackInternal(e,r)}),e},_registerComponent:function(e,t){w(t&&(t.nodeType===U||t.nodeType===F)),g.ensureScrollValueMonitoring();var n=K.registerContainer(t);return B[n]=e,n},_renderNewRootComponent:function(e,t,n){var r=R(e,null),o=K._registerComponent(r,t);return N.batchedUpdates(m,r,o,t,n),r},render:function(e,t,n){w(y.isValidElement(e));var r=B[o(t)];if(r){var i=r._currentElement;if(S(i,e))return K._updateRootComponent(r,e,t,n).getPublicInstance();K.unmountComponentAtNode(t)}var a=P(t),u=a&&K.isRenderedByReact(a),s=u&&!r,l=K._renderNewRootComponent(e,t,s).getPublicInstance();return n&&n.call(l),l},constructAndRenderComponent:function(e,t,n){var r=y.createElement(e,t);return K.render(r,n)},constructAndRenderComponentByID:function(e,t,n){var r=document.getElementById(n);return w(r),K.constructAndRenderComponent(e,t,r)},registerContainer:function(e){var t=o(e);return t&&(t=E.getReactRootIDFromNodeID(t)),t||(t=E.createReactRootID()),V[t]=e,t},unmountComponentAtNode:function(e){w(e&&(e.nodeType===U||e.nodeType===F));var t=o(e),n=B[t];return n?(K.unmountComponentFromNode(n,e),delete B[t],delete V[t],!0):!1},unmountComponentFromNode:function(e,t){for(D.unmountComponent(e),t.nodeType===F&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)},findReactContainerForID:function(e){var t=E.getReactRootIDFromNodeID(e),n=V[t];return n},findReactNodeByID:function(e){var t=K.findReactContainerForID(e);return K.findComponentRoot(t,e)},isRenderedByReact:function(e){if(1!==e.nodeType)return!1;var t=K.getID(e);return t?t.charAt(0)===A:!1},getFirstReactDOM:function(e){for(var t=e;t&&t.parentNode!==t;){if(K.isRenderedByReact(t))return t;t=t.parentNode}return null},findComponentRoot:function(e,t){var n=j,r=0,o=f(t)||e;for(n[0]=o.firstChild,n.length=1;r<n.length;){for(var i,a=n[r++];a;){var u=K.getID(a);u?t===u?i=a:E.isAncestorIDOf(u,t)&&(n.length=r=0,n.push(a.firstChild)):n.push(a.firstChild),a=a.nextSibling}if(i)return n.length=0,i}n.length=0,w(!1)},_mountImageIntoNode:function(e,t,n){if(w(t&&(t.nodeType===U||t.nodeType===F)),n){var o=P(t);if(_.canReuseMarkup(e,o))return;var i=o.getAttribute(_.CHECKSUM_ATTR_NAME);o.removeAttribute(_.CHECKSUM_ATTR_NAME);var a=o.outerHTML;o.setAttribute(_.CHECKSUM_ATTR_NAME,i);var u=r(e,a);" (client) "+e.substring(u-20,u+20)+"\n (server) "+a.substring(u-20,u+20),w(t.nodeType!==F)}w(t.nodeType!==F),O(t,e)},getReactRootID:o,getID:i,setID:u,getNode:s,getNodeFromInstance:l,purgeID:p};x.measureMethods(K,"ReactMount",{_renderNewRootComponent:"_renderNewRootComponent",_mountImageIntoNode:"_mountImageIntoNode"}),t.exports=K},{10:10,107:107,113:113,127:127,132:132,133:133,144:144,147:147,150:150,30:30,39:39,55:55,56:56,57:57,64:64,65:65,67:67,73:73,79:79,84:84,85:85}],69:[function(e,t,n){"use strict";function r(e,t,n){h.push({parentID:e,parentNode:null,type:c.INSERT_MARKUP,markupIndex:m.push(t)-1,textContent:null,fromIndex:null,toIndex:n})}function o(e,t,n){h.push({parentID:e,parentNode:null,type:c.MOVE_EXISTING,markupIndex:null,textContent:null,fromIndex:t,toIndex:n})}function i(e,t){h.push({parentID:e,parentNode:null,type:c.REMOVE_NODE,markupIndex:null,textContent:null,fromIndex:t,toIndex:null})}function a(e,t){h.push({parentID:e,parentNode:null,type:c.TEXT_CONTENT,markupIndex:null,textContent:t,fromIndex:null,toIndex:null})}function u(){h.length&&(l.processChildrenUpdates(h,m),s())}function s(){h.length=0,m.length=0}var l=e(36),c=e(70),p=e(79),d=e(31),f=0,h=[],m=[],v={Mixin:{mountChildren:function(e,t,n){var r=d.instantiateChildren(e,t,n);this._renderedChildren=r;var o=[],i=0;for(var a in r)if(r.hasOwnProperty(a)){var u=r[a],s=this._rootNodeID+a,l=p.mountComponent(u,s,t,n);u._mountIndex=i,o.push(l),i++}return o},updateTextContent:function(e){f++;var t=!0;try{var n=this._renderedChildren;d.unmountChildren(n);for(var r in n)n.hasOwnProperty(r)&&this._unmountChildByName(n[r],r);this.setTextContent(e),t=!1}finally{f--,f||(t?s():u())}},updateChildren:function(e,t,n){f++;var r=!0;try{this._updateChildren(e,t,n),r=!1}finally{f--,f||(r?s():u())}},_updateChildren:function(e,t,n){var r=this._renderedChildren,o=d.updateChildren(r,e,t,n);if(this._renderedChildren=o,o||r){var i,a=0,u=0;for(i in o)if(o.hasOwnProperty(i)){var s=r&&r[i],l=o[i];s===l?(this.moveChild(s,u,a),a=Math.max(s._mountIndex,a),s._mountIndex=u):(s&&(a=Math.max(s._mountIndex,a),this._unmountChildByName(s,i)),this._mountChildByNameAtIndex(l,i,u,t,n)),u++}for(i in r)!r.hasOwnProperty(i)||o&&o.hasOwnProperty(i)||this._unmountChildByName(r[i],i)}},unmountChildren:function(){var e=this._renderedChildren;d.unmountChildren(e),this._renderedChildren=null},moveChild:function(e,t,n){e._mountIndex<n&&o(this._rootNodeID,e._mountIndex,t)},createChild:function(e,t){r(this._rootNodeID,t,e._mountIndex)},removeChild:function(e){i(this._rootNodeID,e._mountIndex)},setTextContent:function(e){a(this._rootNodeID,e)},_mountChildByNameAtIndex:function(e,t,n,r,o){var i=this._rootNodeID+t,a=p.mountComponent(e,i,r,o);e._mountIndex=n,this.createChild(e,a)},_unmountChildByName:function(e,t){this.removeChild(e),e._mountIndex=null}}};t.exports=v},{31:31,36:36,70:70,79:79}],70:[function(e,t,n){"use strict";var r=e(138),o=r({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,TEXT_CONTENT:null});t.exports=o},{138:138}],71:[function(e,t,n){"use strict";function r(e){if("function"==typeof e.type)return e.type;var t=e.type,n=p[t];return null==n&&(p[t]=n=l(t)),n}function o(e){return s(c),new c(e.type,e.props)}function i(e){return new d(e)}function a(e){return e instanceof d}var u=e(27),s=e(133),l=null,c=null,p={},d=null,f={injectGenericComponentClass:function(e){c=e},injectTextComponentClass:function(e){d=e},injectComponentClasses:function(e){u(p,e)},injectAutoWrapper:function(e){l=e}},h={getComponentClassForElement:r,createInternalComponent:o,createInstanceForText:i,isTextComponent:a,injection:f};t.exports=h},{133:133,27:27}],72:[function(e,t,n){"use strict";var r=e(133),o={isValidOwner:function(e){return!(!e||"function"!=typeof e.attachRef||"function"!=typeof e.detachRef)},addComponentAsRefTo:function(e,t,n){r(o.isValidOwner(n)),n.attachRef(t,e)},removeComponentAsRefFrom:function(e,t,n){r(o.isValidOwner(n)),n.getPublicInstance().refs[t]===e.getPublicInstance()&&n.detachRef(t)}};t.exports=o},{133:133}],73:[function(e,t,n){"use strict";function r(e,t,n){return n}var o={enableMeasure:!1,storedMeasure:r,measureMethods:function(e,t,n){},measure:function(e,t,n){return n},injection:{injectMeasure:function(e){o.storedMeasure=e}}};t.exports=o},{}],74:[function(e,t,n){"use strict";var r={};t.exports=r},{}],75:[function(e,t,n){"use strict";var r=e(138),o=r({prop:null,context:null,childContext:null});t.exports=o},{138:138}],76:[function(e,t,n){"use strict";function r(e){function t(t,n,r,o,i){if(o=o||b,null==n[r]){var a=C[i];return t?new Error("Required "+a+" `"+r+"` was not specified in "+("`"+o+"`.")):null}return e(n,r,o,i)}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function o(e){function t(t,n,r,o){var i=t[n],a=m(i);if(a!==e){var u=C[o],s=v(i);return new Error("Invalid "+u+" `"+n+"` of type `"+s+"` "+("supplied to `"+r+"`, expected `"+e+"`."))}return null}return r(t)}function i(){return r(E.thatReturns(null))}function a(e){function t(t,n,r,o){var i=t[n];if(!Array.isArray(i)){var a=C[o],u=m(i);return new Error("Invalid "+a+" `"+n+"` of type "+("`"+u+"` supplied to `"+r+"`, expected an array."))}for(var s=0;s<i.length;s++){var l=e(i,s,r,o);if(l instanceof Error)return l}return null}return r(t)}function u(){function e(e,t,n,r){if(!g.isValidElement(e[t])){var o=C[r];return new Error("Invalid "+o+" `"+t+"` supplied to "+("`"+n+"`, expected a ReactElement."))}return null}return r(e)}function s(e){function t(t,n,r,o){if(!(t[n]instanceof e)){var i=C[o],a=e.name||b;return new Error("Invalid "+i+" `"+n+"` supplied to "+("`"+r+"`, expected instance of `"+a+"`."))}return null}return r(t)}function l(e){function t(t,n,r,o){for(var i=t[n],a=0;a<e.length;a++)if(i===e[a])return null;var u=C[o],s=JSON.stringify(e);return new Error("Invalid "+u+" `"+n+"` of value `"+i+"` "+("supplied to `"+r+"`, expected one of "+s+"."))}return r(t)}function c(e){function t(t,n,r,o){var i=t[n],a=m(i);if("object"!==a){var u=C[o];return new Error("Invalid "+u+" `"+n+"` of type "+("`"+a+"` supplied to `"+r+"`, expected an object."))}for(var s in i)if(i.hasOwnProperty(s)){var l=e(i,s,r,o);if(l instanceof Error)return l}return null}return r(t)}function p(e){function t(t,n,r,o){for(var i=0;i<e.length;i++){var a=e[i];if(null==a(t,n,r,o))return null}var u=C[o];return new Error("Invalid "+u+" `"+n+"` supplied to "+("`"+r+"`."))}return r(t)}function d(){function e(e,t,n,r){if(!h(e[t])){var o=C[r];return new Error("Invalid "+o+" `"+t+"` supplied to "+("`"+n+"`, expected a ReactNode."))}return null}return r(e)}function f(e){function t(t,n,r,o){var i=t[n],a=m(i);if("object"!==a){var u=C[o];return new Error("Invalid "+u+" `"+n+"` of type `"+a+"` "+("supplied to `"+r+"`, expected `object`."))}for(var s in e){var l=e[s];if(l){var c=l(i,s,r,o);if(c)return c}}return null}return r(t)}function h(e){switch(typeof e){case"number":case"string":case"undefined":return!0;case"boolean":return!e;case"object":if(Array.isArray(e))return e.every(h);if(null===e||g.isValidElement(e))return!0;e=y.extractIfFragment(e);for(var t in e)if(!h(e[t]))return!1;return!0;default:return!1}}function m(e){var t=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":t}function v(e){var t=m(e);if("object"===t){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return t}var g=e(55),y=e(61),C=e(74),E=e(112),b="<<anonymous>>",_=u(),x=d(),D={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),any:i(),arrayOf:a,element:_,instanceOf:s,node:x,objectOf:c,oneOf:l,oneOfType:p,shape:f};t.exports=D},{112:112,55:55,61:61,74:74}],77:[function(e,t,n){"use strict";function r(){this.listenersToPut=[]}var o=e(28),i=e(30),a=e(27);a(r.prototype,{enqueuePutListener:function(e,t,n){this.listenersToPut.push({rootNodeID:e,propKey:t,propValue:n})},putListeners:function(){for(var e=0;e<this.listenersToPut.length;e++){var t=this.listenersToPut[e];i.putListener(t.rootNodeID,t.propKey,t.propValue)}},reset:function(){this.listenersToPut.length=0},destructor:function(){this.reset()}}),o.addPoolingTo(r),t.exports=r},{27:27,28:28,30:30}],78:[function(e,t,n){"use strict";function r(){this.reinitializeTransaction(),this.renderToStaticMarkup=!1,this.reactMountReady=o.getPooled(null),this.putListenerQueue=s.getPooled()}var o=e(6),i=e(28),a=e(30),u=e(63),s=e(77),l=e(101),c=e(27),p={initialize:u.getSelectionInformation,close:u.restoreSelection},d={initialize:function(){var e=a.isEnabled();return a.setEnabled(!1),e},close:function(e){a.setEnabled(e)}},f={initialize:function(){this.reactMountReady.reset()},close:function(){this.reactMountReady.notifyAll()}},h={initialize:function(){this.putListenerQueue.reset()},close:function(){this.putListenerQueue.putListeners()}},m=[h,p,d,f],v={getTransactionWrappers:function(){return m},getReactMountReady:function(){return this.reactMountReady},getPutListenerQueue:function(){return this.putListenerQueue},destructor:function(){o.release(this.reactMountReady),this.reactMountReady=null,s.release(this.putListenerQueue),this.putListenerQueue=null}};c(r.prototype,l.Mixin,v),i.addPoolingTo(r),t.exports=r},{101:101,27:27,28:28,30:30,6:6,63:63,77:77}],79:[function(e,t,n){"use strict";function r(){o.attachRefs(this,this._currentElement)}var o=e(80),i=(e(56),{mountComponent:function(e,t,n,o){var i=e.mountComponent(t,n,o);return n.getReactMountReady().enqueue(r,e),i},unmountComponent:function(e){o.detachRefs(e,e._currentElement),e.unmountComponent()},receiveComponent:function(e,t,n,i){var a=e._currentElement;if(t!==a||null==t._owner){var u=o.shouldUpdateRefs(a,t);u&&o.detachRefs(e,a),e.receiveComponent(t,n,i),u&&n.getReactMountReady().enqueue(r,e)}},performUpdateIfNecessary:function(e,t){e.performUpdateIfNecessary(t)}});t.exports=i},{56:56,80:80}],80:[function(e,t,n){"use strict";function r(e,t,n){"function"==typeof e?e(t.getPublicInstance()):i.addComponentAsRefTo(t,e,n)}function o(e,t,n){"function"==typeof e?e(null):i.removeComponentAsRefFrom(t,e,n)}var i=e(72),a={};a.attachRefs=function(e,t){var n=t.ref;null!=n&&r(n,e,t._owner)},a.shouldUpdateRefs=function(e,t){return t._owner!==e._owner||t.ref!==e.ref},a.detachRefs=function(e,t){var n=t.ref;null!=n&&o(n,e,t._owner)},t.exports=a},{72:72}],81:[function(e,t,n){"use strict";var r={injectCreateReactRootIndex:function(e){o.createReactRootIndex=e}},o={createReactRootIndex:null,injection:r};t.exports=o},{}],82:[function(e,t,n){"use strict";function r(e){p(i.isValidElement(e));var t;try{var n=a.createReactRootID();return t=s.getPooled(!1),t.perform(function(){var r=c(e,null),o=r.mountComponent(n,t,l);return u.addChecksumToMarkup(o)},null)}finally{s.release(t)}}function o(e){p(i.isValidElement(e));var t;try{var n=a.createReactRootID();return t=s.getPooled(!0),t.perform(function(){var r=c(e,null);return r.mountComponent(n,t,l)},null)}finally{s.release(t)}}var i=e(55),a=e(64),u=e(67),s=e(83),l=e(113),c=e(132),p=e(133);t.exports={renderToString:r,renderToStaticMarkup:o}},{113:113,132:132,133:133,55:55,64:64,67:67,83:83}],83:[function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.reactMountReady=i.getPooled(null),this.putListenerQueue=a.getPooled()}var o=e(28),i=e(6),a=e(77),u=e(101),s=e(27),l=e(112),c={initialize:function(){this.reactMountReady.reset()},close:l},p={initialize:function(){this.putListenerQueue.reset()},close:l},d=[p,c],f={getTransactionWrappers:function(){return d},getReactMountReady:function(){return this.reactMountReady},getPutListenerQueue:function(){return this.putListenerQueue},destructor:function(){i.release(this.reactMountReady),this.reactMountReady=null,a.release(this.putListenerQueue),this.putListenerQueue=null}};s(r.prototype,u.Mixin,f),o.addPoolingTo(r),t.exports=r},{101:101,112:112,27:27,28:28,6:6,77:77}],84:[function(e,t,n){"use strict";function r(e){e!==i.currentlyMountingInstance&&l.enqueueUpdate(e)}function o(e,t){p(null==a.current);var n=s.get(e);return n?n===i.currentlyUnmountingInstance?null:n:null}var i=e(66),a=e(39),u=e(55),s=e(65),l=e(85),c=e(27),p=e(133),d=(e(150),{enqueueCallback:function(e,t){p("function"==typeof t);var n=o(e);return n&&n!==i.currentlyMountingInstance?(n._pendingCallbacks?n._pendingCallbacks.push(t):n._pendingCallbacks=[t],void r(n)):null},enqueueCallbackInternal:function(e,t){p("function"==typeof t),e._pendingCallbacks?e._pendingCallbacks.push(t):e._pendingCallbacks=[t],r(e)},enqueueForceUpdate:function(e){var t=o(e,"forceUpdate");t&&(t._pendingForceUpdate=!0,r(t))},enqueueReplaceState:function(e,t){var n=o(e,"replaceState");n&&(n._pendingStateQueue=[t],n._pendingReplaceState=!0,r(n))},enqueueSetState:function(e,t){var n=o(e,"setState");if(n){var i=n._pendingStateQueue||(n._pendingStateQueue=[]);i.push(t),r(n)}},enqueueSetProps:function(e,t){var n=o(e,"setProps");if(n){p(n._isTopLevel);var i=n._pendingElement||n._currentElement,a=c({},i.props,t);n._pendingElement=u.cloneAndReplaceProps(i,a),r(n)}},enqueueReplaceProps:function(e,t){var n=o(e,"replaceProps");if(n){p(n._isTopLevel);var i=n._pendingElement||n._currentElement;n._pendingElement=u.cloneAndReplaceProps(i,t),r(n)}},enqueueElementInternal:function(e,t){e._pendingElement=t,r(e)}});t.exports=d},{133:133,150:150,27:27,39:39,55:55,65:65,66:66,85:85}],85:[function(e,t,n){"use strict";function r(){v(N.ReactReconcileTransaction&&E)}function o(){this.reinitializeTransaction(),this.dirtyComponentsLength=null,this.callbackQueue=c.getPooled(),this.reconcileTransaction=N.ReactReconcileTransaction.getPooled()}function i(e,t,n,o,i){r(),E.batchedUpdates(e,t,n,o,i)}function a(e,t){return e._mountOrder-t._mountOrder}function u(e){var t=e.dirtyComponentsLength;v(t===g.length),g.sort(a);for(var n=0;t>n;n++){var r=g[n],o=r._pendingCallbacks;if(r._pendingCallbacks=null,f.performUpdateIfNecessary(r,e.reconcileTransaction),o)for(var i=0;i<o.length;i++)e.callbackQueue.enqueue(o[i],r.getPublicInstance())}}function s(e){return r(),E.isBatchingUpdates?void g.push(e):void E.batchedUpdates(s,e)}function l(e,t){v(E.isBatchingUpdates),y.enqueue(e,t),C=!0}var c=e(6),p=e(28),d=(e(39),e(73)),f=e(79),h=e(101),m=e(27),v=e(133),g=(e(150),[]),y=c.getPooled(),C=!1,E=null,b={initialize:function(){this.dirtyComponentsLength=g.length},close:function(){this.dirtyComponentsLength!==g.length?(g.splice(0,this.dirtyComponentsLength),D()):g.length=0}},_={initialize:function(){this.callbackQueue.reset()},close:function(){this.callbackQueue.notifyAll()}},x=[b,_];m(o.prototype,h.Mixin,{getTransactionWrappers:function(){return x},destructor:function(){this.dirtyComponentsLength=null,c.release(this.callbackQueue),this.callbackQueue=null,N.ReactReconcileTransaction.release(this.reconcileTransaction),this.reconcileTransaction=null},perform:function(e,t,n){return h.Mixin.perform.call(this,this.reconcileTransaction.perform,this.reconcileTransaction,e,t,n)}}),p.addPoolingTo(o);var D=function(){for(;g.length||C;){if(g.length){var e=o.getPooled();e.perform(u,null,e),o.release(e)}if(C){C=!1;var t=y;y=c.getPooled(),t.notifyAll(),c.release(t)}}};D=d.measure("ReactUpdates","flushBatchedUpdates",D);var M={injectReconcileTransaction:function(e){v(e),N.ReactReconcileTransaction=e},injectBatchingStrategy:function(e){v(e),v("function"==typeof e.batchedUpdates),v("boolean"==typeof e.isBatchingUpdates),E=e}},N={ReactReconcileTransaction:null,batchedUpdates:i,enqueueUpdate:s,flushBatchedUpdates:D,injection:M,asap:l};t.exports=N},{101:101,133:133,150:150,27:27,28:28,39:39,6:6,73:73,79:79}],86:[function(e,t,n){"use strict";var r=e(10),o=r.injection.MUST_USE_ATTRIBUTE,i={Properties:{clipPath:o,cx:o,cy:o,d:o,dx:o,dy:o,fill:o,fillOpacity:o,fontFamily:o,fontSize:o,fx:o,fy:o,gradientTransform:o,gradientUnits:o,markerEnd:o,markerMid:o,markerStart:o,offset:o,opacity:o,patternContentUnits:o,patternUnits:o,points:o,preserveAspectRatio:o,r:o,rx:o,ry:o,spreadMethod:o,stopColor:o,stopOpacity:o,stroke:o,strokeDasharray:o,strokeLinecap:o,strokeOpacity:o,strokeWidth:o,textAnchor:o,transform:o,version:o,viewBox:o,x1:o,x2:o,x:o,y1:o,y2:o,y:o},DOMAttributeNames:{clipPath:"clip-path",fillOpacity:"fill-opacity",fontFamily:"font-family",fontSize:"font-size",gradientTransform:"gradientTransform",gradientUnits:"gradientUnits",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",patternContentUnits:"patternContentUnits",patternUnits:"patternUnits",preserveAspectRatio:"preserveAspectRatio",spreadMethod:"spreadMethod",stopColor:"stop-color",stopOpacity:"stop-opacity",strokeDasharray:"stroke-dasharray",strokeLinecap:"stroke-linecap",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",viewBox:"viewBox"}};t.exports=i},{10:10}],87:[function(e,t,n){"use strict";function r(e){if("selectionStart"in e&&u.hasSelectionCapabilities(e))return{start:e.selectionStart,end:e.selectionEnd};if(window.getSelection){var t=window.getSelection();return{anchorNode:t.anchorNode,anchorOffset:t.anchorOffset,focusNode:t.focusNode,focusOffset:t.focusOffset}}if(document.selection){var n=document.selection.createRange();return{parentElement:n.parentElement(),text:n.text,top:n.boundingTop,left:n.boundingLeft}}}function o(e){if(y||null==m||m!==l())return null;var t=r(m);if(!g||!d(g,t)){g=t;var n=s.getPooled(h.select,v,e);return n.type="select",n.target=m,a.accumulateTwoPhaseDispatches(n),n}}var i=e(15),a=e(20),u=e(63),s=e(93),l=e(119),c=e(136),p=e(139),d=e(146),f=i.topLevelTypes,h={select:{phasedRegistrationNames:{bubbled:p({onSelect:null}),captured:p({onSelectCapture:null})},dependencies:[f.topBlur,f.topContextMenu,f.topFocus,f.topKeyDown,f.topMouseDown,f.topMouseUp,f.topSelectionChange] -}},m=null,v=null,g=null,y=!1,C={eventTypes:h,extractEvents:function(e,t,n,r){switch(e){case f.topFocus:(c(t)||"true"===t.contentEditable)&&(m=t,v=n,g=null);break;case f.topBlur:m=null,v=null,g=null;break;case f.topMouseDown:y=!0;break;case f.topContextMenu:case f.topMouseUp:return y=!1,o(r);case f.topSelectionChange:case f.topKeyDown:case f.topKeyUp:return o(r)}}};t.exports=C},{119:119,136:136,139:139,146:146,15:15,20:20,63:63,93:93}],88:[function(e,t,n){"use strict";var r=Math.pow(2,53),o={createReactRootIndex:function(){return Math.ceil(Math.random()*r)}};t.exports=o},{}],89:[function(e,t,n){"use strict";var r=e(15),o=e(19),i=e(20),a=e(90),u=e(93),s=e(94),l=e(96),c=e(97),p=e(92),d=e(98),f=e(99),h=e(100),m=e(120),v=e(133),g=e(139),y=(e(150),r.topLevelTypes),C={blur:{phasedRegistrationNames:{bubbled:g({onBlur:!0}),captured:g({onBlurCapture:!0})}},click:{phasedRegistrationNames:{bubbled:g({onClick:!0}),captured:g({onClickCapture:!0})}},contextMenu:{phasedRegistrationNames:{bubbled:g({onContextMenu:!0}),captured:g({onContextMenuCapture:!0})}},copy:{phasedRegistrationNames:{bubbled:g({onCopy:!0}),captured:g({onCopyCapture:!0})}},cut:{phasedRegistrationNames:{bubbled:g({onCut:!0}),captured:g({onCutCapture:!0})}},doubleClick:{phasedRegistrationNames:{bubbled:g({onDoubleClick:!0}),captured:g({onDoubleClickCapture:!0})}},drag:{phasedRegistrationNames:{bubbled:g({onDrag:!0}),captured:g({onDragCapture:!0})}},dragEnd:{phasedRegistrationNames:{bubbled:g({onDragEnd:!0}),captured:g({onDragEndCapture:!0})}},dragEnter:{phasedRegistrationNames:{bubbled:g({onDragEnter:!0}),captured:g({onDragEnterCapture:!0})}},dragExit:{phasedRegistrationNames:{bubbled:g({onDragExit:!0}),captured:g({onDragExitCapture:!0})}},dragLeave:{phasedRegistrationNames:{bubbled:g({onDragLeave:!0}),captured:g({onDragLeaveCapture:!0})}},dragOver:{phasedRegistrationNames:{bubbled:g({onDragOver:!0}),captured:g({onDragOverCapture:!0})}},dragStart:{phasedRegistrationNames:{bubbled:g({onDragStart:!0}),captured:g({onDragStartCapture:!0})}},drop:{phasedRegistrationNames:{bubbled:g({onDrop:!0}),captured:g({onDropCapture:!0})}},focus:{phasedRegistrationNames:{bubbled:g({onFocus:!0}),captured:g({onFocusCapture:!0})}},input:{phasedRegistrationNames:{bubbled:g({onInput:!0}),captured:g({onInputCapture:!0})}},keyDown:{phasedRegistrationNames:{bubbled:g({onKeyDown:!0}),captured:g({onKeyDownCapture:!0})}},keyPress:{phasedRegistrationNames:{bubbled:g({onKeyPress:!0}),captured:g({onKeyPressCapture:!0})}},keyUp:{phasedRegistrationNames:{bubbled:g({onKeyUp:!0}),captured:g({onKeyUpCapture:!0})}},load:{phasedRegistrationNames:{bubbled:g({onLoad:!0}),captured:g({onLoadCapture:!0})}},error:{phasedRegistrationNames:{bubbled:g({onError:!0}),captured:g({onErrorCapture:!0})}},mouseDown:{phasedRegistrationNames:{bubbled:g({onMouseDown:!0}),captured:g({onMouseDownCapture:!0})}},mouseMove:{phasedRegistrationNames:{bubbled:g({onMouseMove:!0}),captured:g({onMouseMoveCapture:!0})}},mouseOut:{phasedRegistrationNames:{bubbled:g({onMouseOut:!0}),captured:g({onMouseOutCapture:!0})}},mouseOver:{phasedRegistrationNames:{bubbled:g({onMouseOver:!0}),captured:g({onMouseOverCapture:!0})}},mouseUp:{phasedRegistrationNames:{bubbled:g({onMouseUp:!0}),captured:g({onMouseUpCapture:!0})}},paste:{phasedRegistrationNames:{bubbled:g({onPaste:!0}),captured:g({onPasteCapture:!0})}},reset:{phasedRegistrationNames:{bubbled:g({onReset:!0}),captured:g({onResetCapture:!0})}},scroll:{phasedRegistrationNames:{bubbled:g({onScroll:!0}),captured:g({onScrollCapture:!0})}},submit:{phasedRegistrationNames:{bubbled:g({onSubmit:!0}),captured:g({onSubmitCapture:!0})}},touchCancel:{phasedRegistrationNames:{bubbled:g({onTouchCancel:!0}),captured:g({onTouchCancelCapture:!0})}},touchEnd:{phasedRegistrationNames:{bubbled:g({onTouchEnd:!0}),captured:g({onTouchEndCapture:!0})}},touchMove:{phasedRegistrationNames:{bubbled:g({onTouchMove:!0}),captured:g({onTouchMoveCapture:!0})}},touchStart:{phasedRegistrationNames:{bubbled:g({onTouchStart:!0}),captured:g({onTouchStartCapture:!0})}},wheel:{phasedRegistrationNames:{bubbled:g({onWheel:!0}),captured:g({onWheelCapture:!0})}}},E={topBlur:C.blur,topClick:C.click,topContextMenu:C.contextMenu,topCopy:C.copy,topCut:C.cut,topDoubleClick:C.doubleClick,topDrag:C.drag,topDragEnd:C.dragEnd,topDragEnter:C.dragEnter,topDragExit:C.dragExit,topDragLeave:C.dragLeave,topDragOver:C.dragOver,topDragStart:C.dragStart,topDrop:C.drop,topError:C.error,topFocus:C.focus,topInput:C.input,topKeyDown:C.keyDown,topKeyPress:C.keyPress,topKeyUp:C.keyUp,topLoad:C.load,topMouseDown:C.mouseDown,topMouseMove:C.mouseMove,topMouseOut:C.mouseOut,topMouseOver:C.mouseOver,topMouseUp:C.mouseUp,topPaste:C.paste,topReset:C.reset,topScroll:C.scroll,topSubmit:C.submit,topTouchCancel:C.touchCancel,topTouchEnd:C.touchEnd,topTouchMove:C.touchMove,topTouchStart:C.touchStart,topWheel:C.wheel};for(var b in E)E[b].dependencies=[b];var _={eventTypes:C,executeDispatch:function(e,t,n){var r=o.executeDispatch(e,t,n);r===!1&&(e.stopPropagation(),e.preventDefault())},extractEvents:function(e,t,n,r){var o=E[e];if(!o)return null;var g;switch(e){case y.topInput:case y.topLoad:case y.topError:case y.topReset:case y.topSubmit:g=u;break;case y.topKeyPress:if(0===m(r))return null;case y.topKeyDown:case y.topKeyUp:g=l;break;case y.topBlur:case y.topFocus:g=s;break;case y.topClick:if(2===r.button)return null;case y.topContextMenu:case y.topDoubleClick:case y.topMouseDown:case y.topMouseMove:case y.topMouseOut:case y.topMouseOver:case y.topMouseUp:g=c;break;case y.topDrag:case y.topDragEnd:case y.topDragEnter:case y.topDragExit:case y.topDragLeave:case y.topDragOver:case y.topDragStart:case y.topDrop:g=p;break;case y.topTouchCancel:case y.topTouchEnd:case y.topTouchMove:case y.topTouchStart:g=d;break;case y.topScroll:g=f;break;case y.topWheel:g=h;break;case y.topCopy:case y.topCut:case y.topPaste:g=a}v(g);var C=g.getPooled(o,n,r);return i.accumulateTwoPhaseDispatches(C),C}};t.exports=_},{100:100,120:120,133:133,139:139,15:15,150:150,19:19,20:20,90:90,92:92,93:93,94:94,96:96,97:97,98:98,99:99}],90:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(93),i={clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}};o.augmentClass(r,i),t.exports=r},{93:93}],91:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(93),i={data:null};o.augmentClass(r,i),t.exports=r},{93:93}],92:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(97),i={dataTransfer:null};o.augmentClass(r,i),t.exports=r},{97:97}],93:[function(e,t,n){"use strict";function r(e,t,n){this.dispatchConfig=e,this.dispatchMarker=t,this.nativeEvent=n;var r=this.constructor.Interface;for(var o in r)if(r.hasOwnProperty(o)){var i=r[o];i?this[o]=i(n):this[o]=n[o]}var u=null!=n.defaultPrevented?n.defaultPrevented:n.returnValue===!1;u?this.isDefaultPrevented=a.thatReturnsTrue:this.isDefaultPrevented=a.thatReturnsFalse,this.isPropagationStopped=a.thatReturnsFalse}var o=e(28),i=e(27),a=e(112),u=e(123),s={type:null,target:u,currentTarget:a.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};i(r.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e.preventDefault?e.preventDefault():e.returnValue=!1,this.isDefaultPrevented=a.thatReturnsTrue},stopPropagation:function(){var e=this.nativeEvent;e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,this.isPropagationStopped=a.thatReturnsTrue},persist:function(){this.isPersistent=a.thatReturnsTrue},isPersistent:a.thatReturnsFalse,destructor:function(){var e=this.constructor.Interface;for(var t in e)this[t]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),r.Interface=s,r.augmentClass=function(e,t){var n=this,r=Object.create(n.prototype);i(r,e.prototype),e.prototype=r,e.prototype.constructor=e,e.Interface=i({},n.Interface,t),e.augmentClass=n.augmentClass,o.addPoolingTo(e,o.threeArgumentPooler)},o.addPoolingTo(r,o.threeArgumentPooler),t.exports=r},{112:112,123:123,27:27,28:28}],94:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(99),i={relatedTarget:null};o.augmentClass(r,i),t.exports=r},{99:99}],95:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(93),i={data:null};o.augmentClass(r,i),t.exports=r},{93:93}],96:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(99),i=e(120),a=e(121),u=e(122),s={key:a,location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:u,charCode:function(e){return"keypress"===e.type?i(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?i(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}};o.augmentClass(r,s),t.exports=r},{120:120,121:121,122:122,99:99}],97:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(99),i=e(102),a=e(122),u={screenX:null,screenY:null,clientX:null,clientY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:a,button:function(e){var t=e.button;return"which"in e?t:2===t?2:4===t?1:0},buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)},pageX:function(e){return"pageX"in e?e.pageX:e.clientX+i.currentScrollLeft},pageY:function(e){return"pageY"in e?e.pageY:e.clientY+i.currentScrollTop}};o.augmentClass(r,u),t.exports=r},{102:102,122:122,99:99}],98:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(99),i=e(122),a={touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:i};o.augmentClass(r,a),t.exports=r},{122:122,99:99}],99:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(93),i=e(123),a={view:function(e){if(e.view)return e.view;var t=i(e);if(null!=t&&t.window===t)return t;var n=t.ownerDocument;return n?n.defaultView||n.parentWindow:window},detail:function(e){return e.detail||0}};o.augmentClass(r,a),t.exports=r},{123:123,93:93}],100:[function(e,t,n){"use strict";function r(e,t,n){o.call(this,e,t,n)}var o=e(97),i={deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null};o.augmentClass(r,i),t.exports=r},{97:97}],101:[function(e,t,n){"use strict";var r=e(133),o={reinitializeTransaction:function(){this.transactionWrappers=this.getTransactionWrappers(),this.wrapperInitData?this.wrapperInitData.length=0:this.wrapperInitData=[],this._isInTransaction=!1},_isInTransaction:!1,getTransactionWrappers:null,isInTransaction:function(){return!!this._isInTransaction},perform:function(e,t,n,o,i,a,u,s){r(!this.isInTransaction());var l,c;try{this._isInTransaction=!0,l=!0,this.initializeAll(0),c=e.call(t,n,o,i,a,u,s),l=!1}finally{try{if(l)try{this.closeAll(0)}catch(p){}else this.closeAll(0)}finally{this._isInTransaction=!1}}return c},initializeAll:function(e){for(var t=this.transactionWrappers,n=e;n<t.length;n++){var r=t[n];try{this.wrapperInitData[n]=i.OBSERVED_ERROR,this.wrapperInitData[n]=r.initialize?r.initialize.call(this):null}finally{if(this.wrapperInitData[n]===i.OBSERVED_ERROR)try{this.initializeAll(n+1)}catch(o){}}}},closeAll:function(e){r(this.isInTransaction());for(var t=this.transactionWrappers,n=e;n<t.length;n++){var o,a=t[n],u=this.wrapperInitData[n];try{o=!0,u!==i.OBSERVED_ERROR&&a.close&&a.close.call(this,u),o=!1}finally{if(o)try{this.closeAll(n+1)}catch(s){}}}this.wrapperInitData.length=0}},i={Mixin:o,OBSERVED_ERROR:{}};t.exports=i},{133:133}],102:[function(e,t,n){"use strict";var r={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(e){r.currentScrollLeft=e.x,r.currentScrollTop=e.y}};t.exports=r},{}],103:[function(e,t,n){"use strict";function r(e,t){if(o(null!=t),null==e)return t;var n=Array.isArray(e),r=Array.isArray(t);return n&&r?(e.push.apply(e,t),e):n?(e.push(t),e):r?[e].concat(t):[e,t]}var o=e(133);t.exports=r},{133:133}],104:[function(e,t,n){"use strict";function r(e){for(var t=1,n=0,r=0;r<e.length;r++)t=(t+e.charCodeAt(r))%o,n=(n+t)%o;return t|n<<16}var o=65521;t.exports=r},{}],105:[function(e,t,n){function r(e){return e.replace(o,function(e,t){return t.toUpperCase()})}var o=/-(.)/g;t.exports=r},{}],106:[function(e,t,n){"use strict";function r(e){return o(e.replace(i,"ms-"))}var o=e(105),i=/^-ms-/;t.exports=r},{105:105}],107:[function(e,t,n){function r(e,t){return e&&t?e===t?!0:o(e)?!1:o(t)?r(e,t.parentNode):e.contains?e.contains(t):e.compareDocumentPosition?!!(16&e.compareDocumentPosition(t)):!1:!1}var o=e(137);t.exports=r},{137:137}],108:[function(e,t,n){function r(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"length"in e&&!("setInterval"in e)&&"number"!=typeof e.nodeType&&(Array.isArray(e)||"callee"in e||"item"in e)}function o(e){return r(e)?Array.isArray(e)?e.slice():i(e):[e]}var i=e(148);t.exports=o},{148:148}],109:[function(e,t,n){"use strict";function r(e){var t=i.createFactory(e),n=o.createClass({tagName:e.toUpperCase(),displayName:"ReactFullPageComponent"+e,componentWillUnmount:function(){a(!1)},render:function(){return t(this.props)}});return n}var o=e(33),i=e(55),a=e(133);t.exports=r},{133:133,33:33,55:55}],110:[function(e,t,n){function r(e){var t=e.match(c);return t&&t[1].toLowerCase()}function o(e,t){var n=l;s(!!l);var o=r(e),i=o&&u(o);if(i){n.innerHTML=i[1]+e+i[2];for(var c=i[0];c--;)n=n.lastChild}else n.innerHTML=e;var p=n.getElementsByTagName("script");p.length&&(s(t),a(p).forEach(t));for(var d=a(n.childNodes);n.lastChild;)n.removeChild(n.lastChild);return d}var i=e(21),a=e(108),u=e(125),s=e(133),l=i.canUseDOM?document.createElement("div"):null,c=/^\s*<(\w+)/;t.exports=o},{108:108,125:125,133:133,21:21}],111:[function(e,t,n){"use strict";function r(e,t){var n=null==t||"boolean"==typeof t||""===t;if(n)return"";var r=isNaN(t);return r||0===t||i.hasOwnProperty(e)&&i[e]?""+t:("string"==typeof t&&(t=t.trim()),t+"px")}var o=e(4),i=o.isUnitlessNumber;t.exports=r},{4:4}],112:[function(e,t,n){function r(e){return function(){return e}}function o(){}o.thatReturns=r,o.thatReturnsFalse=r(!1),o.thatReturnsTrue=r(!0),o.thatReturnsNull=r(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},t.exports=o},{}],113:[function(e,t,n){"use strict";var r={};t.exports=r},{}],114:[function(e,t,n){"use strict";function r(e){return i[e]}function o(e){return(""+e).replace(a,r)}var i={"&":"&",">":">","<":"<",'"':""","'":"'"},a=/[&><"']/g;t.exports=o},{}],115:[function(e,t,n){"use strict";function r(e){return null==e?null:u(e)?e:o.has(e)?i.getNodeFromInstance(e):(a(null==e.render||"function"!=typeof e.render),void a(!1))}{var o=(e(39),e(65)),i=e(68),a=e(133),u=e(135);e(150)}t.exports=r},{133:133,135:135,150:150,39:39,65:65,68:68}],116:[function(e,t,n){"use strict";function r(e,t,n){var r=e,o=!r.hasOwnProperty(n);o&&null!=t&&(r[n]=t)}function o(e){if(null==e)return e;var t={};return i(e,r,t),t}{var i=e(149);e(150)}t.exports=o},{149:149,150:150}],117:[function(e,t,n){"use strict";function r(e){try{e.focus()}catch(t){}}t.exports=r},{}],118:[function(e,t,n){"use strict";var r=function(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)};t.exports=r},{}],119:[function(e,t,n){function r(){try{return document.activeElement||document.body}catch(e){return document.body}}t.exports=r},{}],120:[function(e,t,n){"use strict";function r(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}t.exports=r},{}],121:[function(e,t,n){"use strict";function r(e){if(e.key){var t=i[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=o(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?a[e.keyCode]||"Unidentified":""}var o=e(120),i={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},a={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};t.exports=r},{120:120}],122:[function(e,t,n){"use strict";function r(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=i[e];return r?!!n[r]:!1}function o(e){return r}var i={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};t.exports=o},{}],123:[function(e,t,n){"use strict";function r(e){var t=e.target||e.srcElement||window;return 3===t.nodeType?t.parentNode:t}t.exports=r},{}],124:[function(e,t,n){"use strict";function r(e){var t=e&&(o&&e[o]||e[i]);return"function"==typeof t?t:void 0}var o="function"==typeof Symbol&&Symbol.iterator,i="@@iterator";t.exports=r},{}],125:[function(e,t,n){function r(e){return i(!!a),d.hasOwnProperty(e)||(e="*"),u.hasOwnProperty(e)||("*"===e?a.innerHTML="<link />":a.innerHTML="<"+e+"></"+e+">",u[e]=!a.firstChild),u[e]?d[e]:null}var o=e(21),i=e(133),a=o.canUseDOM?document.createElement("div"):null,u={circle:!0,clipPath:!0,defs:!0,ellipse:!0,g:!0,line:!0,linearGradient:!0,path:!0,polygon:!0,polyline:!0,radialGradient:!0,rect:!0,stop:!0,text:!0},s=[1,'<select multiple="true">',"</select>"],l=[1,"<table>","</table>"],c=[3,"<table><tbody><tr>","</tr></tbody></table>"],p=[1,"<svg>","</svg>"],d={"*":[1,"?<div>","</div>"],area:[1,"<map>","</map>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],legend:[1,"<fieldset>","</fieldset>"],param:[1,"<object>","</object>"],tr:[2,"<table><tbody>","</tbody></table>"],optgroup:s,option:s,caption:l,colgroup:l,tbody:l,tfoot:l,thead:l,td:c,th:c,circle:p,clipPath:p,defs:p,ellipse:p,g:p,line:p,linearGradient:p,path:p,polygon:p,polyline:p,radialGradient:p,rect:p,stop:p,text:p};t.exports=r},{133:133,21:21}],126:[function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function o(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function i(e,t){for(var n=r(e),i=0,a=0;n;){if(3===n.nodeType){if(a=i+n.textContent.length,t>=i&&a>=t)return{node:n,offset:t-i};i=a}n=r(o(n))}}t.exports=i},{}],127:[function(e,t,n){"use strict";function r(e){return e?e.nodeType===o?e.documentElement:e.firstChild:null}var o=9;t.exports=r},{}],128:[function(e,t,n){"use strict";function r(){return!i&&o.canUseDOM&&(i="textContent"in document.documentElement?"textContent":"innerText"),i}var o=e(21),i=null;t.exports=r},{21:21}],129:[function(e,t,n){"use strict";function r(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}t.exports=r},{}],130:[function(e,t,n){function r(e){return e.replace(o,"-$1").toLowerCase()}var o=/([A-Z])/g;t.exports=r},{}],131:[function(e,t,n){"use strict";function r(e){return o(e).replace(i,"-ms-")}var o=e(130),i=/^ms-/;t.exports=r},{130:130}],132:[function(e,t,n){"use strict";function r(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function o(e,t){var n;if((null===e||e===!1)&&(e=a.emptyElement),"object"==typeof e){var o=e;n=t===o.type&&"string"==typeof o.type?u.createInternalComponent(o):r(o.type)?new o.type(o):new c}else"string"==typeof e||"number"==typeof e?n=u.createInstanceForText(e):l(!1);return n.construct(e),n._mountIndex=0,n._mountImage=null,n}var i=e(37),a=e(57),u=e(71),s=e(27),l=e(133),c=(e(150),function(){});s(c.prototype,i.Mixin,{_instantiateReactComponent:o}),t.exports=o},{133:133,150:150,27:27,37:37,57:57,71:71}],133:[function(e,t,n){"use strict";var r=function(e,t,n,r,o,i,a,u){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,i,a,u],c=0;s=new Error("Invariant Violation: "+t.replace(/%s/g,function(){return l[c++]}))}throw s.framesToPop=1,s}};t.exports=r},{}],134:[function(e,t,n){"use strict";function r(e,t){if(!i.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var a=document.createElement("div");a.setAttribute(n,"return;"),r="function"==typeof a[n]}return!r&&o&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var o,i=e(21);i.canUseDOM&&(o=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),t.exports=r},{21:21}],135:[function(e,t,n){function r(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}t.exports=r},{}],136:[function(e,t,n){"use strict";function r(e){return e&&("INPUT"===e.nodeName&&o[e.type]||"TEXTAREA"===e.nodeName)}var o={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};t.exports=r},{}],137:[function(e,t,n){function r(e){return o(e)&&3==e.nodeType}var o=e(135);t.exports=r},{135:135}],138:[function(e,t,n){"use strict";var r=e(133),o=function(e){var t,n={};r(e instanceof Object&&!Array.isArray(e));for(t in e)e.hasOwnProperty(t)&&(n[t]=t);return n};t.exports=o},{133:133}],139:[function(e,t,n){var r=function(e){var t;for(t in e)if(e.hasOwnProperty(t))return t;return null};t.exports=r},{}],140:[function(e,t,n){"use strict";function r(e,t,n){if(!e)return null;var r={};for(var i in e)o.call(e,i)&&(r[i]=t.call(n,e[i],i,e));return r}var o=Object.prototype.hasOwnProperty;t.exports=r},{}],141:[function(e,t,n){"use strict";function r(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}t.exports=r},{}],142:[function(e,t,n){"use strict";function r(e){return i(o.isValidElement(e)),e}var o=e(55),i=e(133);t.exports=r},{133:133,55:55}],143:[function(e,t,n){"use strict";function r(e){return'"'+o(e)+'"'}var o=e(114);t.exports=r},{114:114}],144:[function(e,t,n){"use strict";var r=e(21),o=/^[ \r\n\t\f]/,i=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,a=function(e,t){e.innerHTML=t};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(a=function(e,t){MSApp.execUnsafeLocalFunction(function(){e.innerHTML=t})}),r.canUseDOM){var u=document.createElement("div");u.innerHTML=" ",""===u.innerHTML&&(a=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&i.test(t)){e.innerHTML="\ufeff"+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t})}t.exports=a},{21:21}],145:[function(e,t,n){"use strict";var r=e(21),o=e(114),i=e(144),a=function(e,t){e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(a=function(e,t){i(e,o(t))})),t.exports=a},{114:114,144:144,21:21}],146:[function(e,t,n){"use strict";function r(e,t){if(e===t)return!0;var n;for(n in e)if(e.hasOwnProperty(n)&&(!t.hasOwnProperty(n)||e[n]!==t[n]))return!1;for(n in t)if(t.hasOwnProperty(n)&&!e.hasOwnProperty(n))return!1;return!0}t.exports=r},{}],147:[function(e,t,n){"use strict";function r(e,t){if(null!=e&&null!=t){var n=typeof e,r=typeof t;if("string"===n||"number"===n)return"string"===r||"number"===r;if("object"===r&&e.type===t.type&&e.key===t.key){var o=e._owner===t._owner;return o}}return!1}e(150);t.exports=r},{150:150}],148:[function(e,t,n){function r(e){var t=e.length;if(o(!Array.isArray(e)&&("object"==typeof e||"function"==typeof e)),o("number"==typeof t),o(0===t||t-1 in e),e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(n){}for(var r=Array(t),i=0;t>i;i++)r[i]=e[i];return r}var o=e(133);t.exports=r},{133:133}],149:[function(e,t,n){"use strict";function r(e){return v[e]}function o(e,t){return e&&null!=e.key?a(e.key):t.toString(36)}function i(e){return(""+e).replace(g,r)}function a(e){return"$"+i(e)}function u(e,t,n,r,i){var s=typeof e;if(("undefined"===s||"boolean"===s)&&(e=null),null===e||"string"===s||"number"===s||l.isValidElement(e))return r(i,e,""===t?h+o(e,0):t,n),1;var p,v,g,y=0;if(Array.isArray(e))for(var C=0;C<e.length;C++)p=e[C],v=(""!==t?t+m:h)+o(p,C),g=n+y,y+=u(p,v,g,r,i);else{var E=d(e);if(E){var b,_=E.call(e);if(E!==e.entries)for(var x=0;!(b=_.next()).done;)p=b.value,v=(""!==t?t+m:h)+o(p,x++),g=n+y,y+=u(p,v,g,r,i);else for(;!(b=_.next()).done;){var D=b.value;D&&(p=D[1],v=(""!==t?t+m:h)+a(D[0])+m+o(p,0),g=n+y,y+=u(p,v,g,r,i))}}else if("object"===s){f(1!==e.nodeType);var M=c.extract(e);for(var N in M)M.hasOwnProperty(N)&&(p=M[N],v=(""!==t?t+m:h)+a(N)+m+o(p,0),g=n+y,y+=u(p,v,g,r,i))}}return y}function s(e,t,n){return null==e?0:u(e,"",0,t,n)}var l=e(55),c=e(61),p=e(64),d=e(124),f=e(133),h=(e(150),p.SEPARATOR),m=":",v={"=":"=0",".":"=1",":":"=2"},g=/[=.:]/g;t.exports=s},{124:124,133:133,150:150,55:55,61:61,64:64}],150:[function(e,t,n){"use strict";var r=e(112),o=r;t.exports=o},{112:112}]},{},[1])(1)});
\ No newline at end of file diff --git a/server/sonar-web/src/main/js/libs/third-party/require.js b/server/sonar-web/src/main/js/libs/third-party/require.js deleted file mode 100644 index 7bf4ea9146d..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/require.js +++ /dev/null @@ -1,2083 +0,0 @@ -/** vim: et:ts=4:sw=4:sts=4 - * @license RequireJS 2.1.17 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details - */ -//Not using strict: uneven strict support in browsers, #392, and causes -//problems with requirejs.exec()/transpiler plugins that may not be strict. -/*jslint regexp: true, nomen: true, sloppy: true */ -/*global window, navigator, document, importScripts, setTimeout, opera */ - -var requirejs, require, define; -(function (global) { - var req, s, head, baseElement, dataMain, src, - interactiveScript, currentlyAddingScript, mainScript, subPath, - version = '2.1.17', - commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, - cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, - jsSuffixRegExp = /\.js$/, - currDirRegExp = /^\.\//, - op = Object.prototype, - ostring = op.toString, - hasOwn = op.hasOwnProperty, - ap = Array.prototype, - apsp = ap.splice, - isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), - isWebWorker = !isBrowser && typeof importScripts !== 'undefined', - //PS3 indicates loaded and complete, but need to wait for complete - //specifically. Sequence is 'loading', 'loaded', execution, - // then 'complete'. The UA check is unfortunate, but not sure how - //to feature test w/o causing perf issues. - readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? - /^complete$/ : /^(complete|loaded)$/, - defContextName = '_', - //Oh the tragedy, detecting opera. See the usage of isOpera for reason. - isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', - contexts = {}, - cfg = {}, - globalDefQueue = [], - useInteractive = false; - - function isFunction(it) { - return ostring.call(it) === '[object Function]'; - } - - function isArray(it) { - return ostring.call(it) === '[object Array]'; - } - - /** - * Helper function for iterating over an array. If the func returns - * a true value, it will break out of the loop. - */ - function each(ary, func) { - if (ary) { - var i; - for (i = 0; i < ary.length; i += 1) { - if (ary[i] && func(ary[i], i, ary)) { - break; - } - } - } - } - - /** - * Helper function for iterating over an array backwards. If the func - * returns a true value, it will break out of the loop. - */ - function eachReverse(ary, func) { - if (ary) { - var i; - for (i = ary.length - 1; i > -1; i -= 1) { - if (ary[i] && func(ary[i], i, ary)) { - break; - } - } - } - } - - function hasProp(obj, prop) { - return hasOwn.call(obj, prop); - } - - function getOwn(obj, prop) { - return hasProp(obj, prop) && obj[prop]; - } - - /** - * Cycles over properties in an object and calls a function for each - * property value. If the function returns a truthy value, then the - * iteration is stopped. - */ - function eachProp(obj, func) { - var prop; - for (prop in obj) { - if (hasProp(obj, prop)) { - if (func(obj[prop], prop)) { - break; - } - } - } - } - - /** - * Simple function to mix in properties from source into target, - * but only if target does not already have a property of the same name. - */ - function mixin(target, source, force, deepStringMixin) { - if (source) { - eachProp(source, function (value, prop) { - if (force || !hasProp(target, prop)) { - if (deepStringMixin && typeof value === 'object' && value && - !isArray(value) && !isFunction(value) && - !(value instanceof RegExp)) { - - if (!target[prop]) { - target[prop] = {}; - } - mixin(target[prop], value, force, deepStringMixin); - } else { - target[prop] = value; - } - } - }); - } - return target; - } - - //Similar to Function.prototype.bind, but the 'this' object is specified - //first, since it is easier to read/figure out what 'this' will be. - function bind(obj, fn) { - return function () { - return fn.apply(obj, arguments); - }; - } - - function scripts() { - return document.getElementsByTagName('script'); - } - - function defaultOnError(err) { - throw err; - } - - //Allow getting a global that is expressed in - //dot notation, like 'a.b.c'. - function getGlobal(value) { - if (!value) { - return value; - } - var g = global; - each(value.split('.'), function (part) { - g = g[part]; - }); - return g; - } - - /** - * Constructs an error with a pointer to an URL with more information. - * @param {String} id the error ID that maps to an ID on a web page. - * @param {String} message human readable error. - * @param {Error} [err] the original error, if there is one. - * - * @returns {Error} - */ - function makeError(id, msg, err, requireModules) { - var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); - e.requireType = id; - e.requireModules = requireModules; - if (err) { - e.originalError = err; - } - return e; - } - - if (typeof define !== 'undefined') { - //If a define is already in play via another AMD loader, - //do not overwrite. - return; - } - - if (typeof requirejs !== 'undefined') { - if (isFunction(requirejs)) { - //Do not overwrite an existing requirejs instance. - return; - } - cfg = requirejs; - requirejs = undefined; - } - - //Allow for a require config object - if (typeof require !== 'undefined' && !isFunction(require)) { - //assume it is a config object. - cfg = require; - require = undefined; - } - - function newContext(contextName) { - var inCheckLoaded, Module, context, handlers, - checkLoadedTimeoutId, - config = { - //Defaults. Do not set a default for map - //config to speed up normalize(), which - //will run faster if there is no default. - waitSeconds: 7, - baseUrl: './', - paths: {}, - bundles: {}, - pkgs: {}, - shim: {}, - config: {} - }, - registry = {}, - //registry of just enabled modules, to speed - //cycle breaking code when lots of modules - //are registered, but not activated. - enabledRegistry = {}, - undefEvents = {}, - defQueue = [], - defined = {}, - urlFetched = {}, - bundlesMap = {}, - requireCounter = 1, - unnormalizedCounter = 1; - - /** - * Trims the . and .. from an array of path segments. - * It will keep a leading path segment if a .. will become - * the first path segment, to help with module name lookups, - * which act like paths, but can be remapped. But the end result, - * all paths that use this function should look normalized. - * NOTE: this method MODIFIES the input array. - * @param {Array} ary the array of path segments. - */ - function trimDots(ary) { - var i, part; - for (i = 0; i < ary.length; i++) { - part = ary[i]; - if (part === '.') { - ary.splice(i, 1); - i -= 1; - } else if (part === '..') { - // If at the start, or previous value is still .., - // keep them so that when converted to a path it may - // still work when converted to a path, even though - // as an ID it is less than ideal. In larger point - // releases, may be better to just kick out an error. - if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') { - continue; - } else if (i > 0) { - ary.splice(i - 1, 2); - i -= 2; - } - } - } - } - - /** - * Given a relative module name, like ./something, normalize it to - * a real name that can be mapped to a path. - * @param {String} name the relative name - * @param {String} baseName a real name that the name arg is relative - * to. - * @param {Boolean} applyMap apply the map config to the value. Should - * only be done if this normalization is for a dependency ID. - * @returns {String} normalized name - */ - function normalize(name, baseName, applyMap) { - var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, - foundMap, foundI, foundStarMap, starI, normalizedBaseParts, - baseParts = (baseName && baseName.split('/')), - map = config.map, - starMap = map && map['*']; - - //Adjust any relative paths. - if (name) { - name = name.split('/'); - lastIndex = name.length - 1; - - // If wanting node ID compatibility, strip .js from end - // of IDs. Have to do this here, and not in nameToUrl - // because node allows either .js or non .js to map - // to same file. - if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { - name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); - } - - // Starts with a '.' so need the baseName - if (name[0].charAt(0) === '.' && baseParts) { - //Convert baseName to array, and lop off the last part, - //so that . matches that 'directory' and not name of the baseName's - //module. For instance, baseName of 'one/two/three', maps to - //'one/two/three.js', but we want the directory, 'one/two' for - //this normalization. - normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); - name = normalizedBaseParts.concat(name); - } - - trimDots(name); - name = name.join('/'); - } - - //Apply map config if available. - if (applyMap && map && (baseParts || starMap)) { - nameParts = name.split('/'); - - outerLoop: for (i = nameParts.length; i > 0; i -= 1) { - nameSegment = nameParts.slice(0, i).join('/'); - - if (baseParts) { - //Find the longest baseName segment match in the config. - //So, do joins on the biggest to smallest lengths of baseParts. - for (j = baseParts.length; j > 0; j -= 1) { - mapValue = getOwn(map, baseParts.slice(0, j).join('/')); - - //baseName segment has config, find if it has one for - //this name. - if (mapValue) { - mapValue = getOwn(mapValue, nameSegment); - if (mapValue) { - //Match, update name to the new value. - foundMap = mapValue; - foundI = i; - break outerLoop; - } - } - } - } - - //Check for a star map match, but just hold on to it, - //if there is a shorter segment match later in a matching - //config, then favor over this star map. - if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { - foundStarMap = getOwn(starMap, nameSegment); - starI = i; - } - } - - if (!foundMap && foundStarMap) { - foundMap = foundStarMap; - foundI = starI; - } - - if (foundMap) { - nameParts.splice(0, foundI, foundMap); - name = nameParts.join('/'); - } - } - - // If the name points to a package's name, use - // the package main instead. - pkgMain = getOwn(config.pkgs, name); - - return pkgMain ? pkgMain : name; - } - - function removeScript(name) { - if (isBrowser) { - each(scripts(), function (scriptNode) { - if (scriptNode.getAttribute('data-requiremodule') === name && - scriptNode.getAttribute('data-requirecontext') === context.contextName) { - scriptNode.parentNode.removeChild(scriptNode); - return true; - } - }); - } - } - - function hasPathFallback(id) { - var pathConfig = getOwn(config.paths, id); - if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { - //Pop off the first array value, since it failed, and - //retry - pathConfig.shift(); - context.require.undef(id); - - //Custom require that does not do map translation, since - //ID is "absolute", already mapped/resolved. - context.makeRequire(null, { - skipMap: true - })([id]); - - return true; - } - } - - //Turns a plugin!resource to [plugin, resource] - //with the plugin being undefined if the name - //did not have a plugin prefix. - function splitPrefix(name) { - var prefix, - index = name ? name.indexOf('!') : -1; - if (index > -1) { - prefix = name.substring(0, index); - name = name.substring(index + 1, name.length); - } - return [prefix, name]; - } - - /** - * Creates a module mapping that includes plugin prefix, module - * name, and path. If parentModuleMap is provided it will - * also normalize the name via require.normalize() - * - * @param {String} name the module name - * @param {String} [parentModuleMap] parent module map - * for the module name, used to resolve relative names. - * @param {Boolean} isNormalized: is the ID already normalized. - * This is true if this call is done for a define() module ID. - * @param {Boolean} applyMap: apply the map config to the ID. - * Should only be true if this map is for a dependency. - * - * @returns {Object} - */ - function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { - var url, pluginModule, suffix, nameParts, - prefix = null, - parentName = parentModuleMap ? parentModuleMap.name : null, - originalName = name, - isDefine = true, - normalizedName = ''; - - //If no name, then it means it is a require call, generate an - //internal name. - if (!name) { - isDefine = false; - name = '_@r' + (requireCounter += 1); - } - - nameParts = splitPrefix(name); - prefix = nameParts[0]; - name = nameParts[1]; - - if (prefix) { - prefix = normalize(prefix, parentName, applyMap); - pluginModule = getOwn(defined, prefix); - } - - //Account for relative paths if there is a base name. - if (name) { - if (prefix) { - if (pluginModule && pluginModule.normalize) { - //Plugin is loaded, use its normalize method. - normalizedName = pluginModule.normalize(name, function (name) { - return normalize(name, parentName, applyMap); - }); - } else { - // If nested plugin references, then do not try to - // normalize, as it will not normalize correctly. This - // places a restriction on resourceIds, and the longer - // term solution is not to normalize until plugins are - // loaded and all normalizations to allow for async - // loading of a loader plugin. But for now, fixes the - // common uses. Details in #1131 - normalizedName = name.indexOf('!') === -1 ? - normalize(name, parentName, applyMap) : - name; - } - } else { - //A regular module. - normalizedName = normalize(name, parentName, applyMap); - - //Normalized name may be a plugin ID due to map config - //application in normalize. The map config values must - //already be normalized, so do not need to redo that part. - nameParts = splitPrefix(normalizedName); - prefix = nameParts[0]; - normalizedName = nameParts[1]; - isNormalized = true; - - url = context.nameToUrl(normalizedName); - } - } - - //If the id is a plugin id that cannot be determined if it needs - //normalization, stamp it with a unique ID so two matching relative - //ids that may conflict can be separate. - suffix = prefix && !pluginModule && !isNormalized ? - '_unnormalized' + (unnormalizedCounter += 1) : - ''; - - return { - prefix: prefix, - name: normalizedName, - parentMap: parentModuleMap, - unnormalized: !!suffix, - url: url, - originalName: originalName, - isDefine: isDefine, - id: (prefix ? - prefix + '!' + normalizedName : - normalizedName) + suffix - }; - } - - function getModule(depMap) { - var id = depMap.id, - mod = getOwn(registry, id); - - if (!mod) { - mod = registry[id] = new context.Module(depMap); - } - - return mod; - } - - function on(depMap, name, fn) { - var id = depMap.id, - mod = getOwn(registry, id); - - if (hasProp(defined, id) && - (!mod || mod.defineEmitComplete)) { - if (name === 'defined') { - fn(defined[id]); - } - } else { - mod = getModule(depMap); - if (mod.error && name === 'error') { - fn(mod.error); - } else { - mod.on(name, fn); - } - } - } - - function onError(err, errback) { - var ids = err.requireModules, - notified = false; - - if (errback) { - errback(err); - } else { - each(ids, function (id) { - var mod = getOwn(registry, id); - if (mod) { - //Set error on module, so it skips timeout checks. - mod.error = err; - if (mod.events.error) { - notified = true; - mod.emit('error', err); - } - } - }); - - if (!notified) { - req.onError(err); - } - } - } - - /** - * Internal method to transfer globalQueue items to this context's - * defQueue. - */ - function takeGlobalQueue() { - //Push all the globalDefQueue items into the context's defQueue - if (globalDefQueue.length) { - //Array splice in the values since the context code has a - //local var ref to defQueue, so cannot just reassign the one - //on context. - apsp.apply(defQueue, - [defQueue.length, 0].concat(globalDefQueue)); - globalDefQueue = []; - } - } - - handlers = { - 'require': function (mod) { - if (mod.require) { - return mod.require; - } else { - return (mod.require = context.makeRequire(mod.map)); - } - }, - 'exports': function (mod) { - mod.usingExports = true; - if (mod.map.isDefine) { - if (mod.exports) { - return (defined[mod.map.id] = mod.exports); - } else { - return (mod.exports = defined[mod.map.id] = {}); - } - } - }, - 'module': function (mod) { - if (mod.module) { - return mod.module; - } else { - return (mod.module = { - id: mod.map.id, - uri: mod.map.url, - config: function () { - return getOwn(config.config, mod.map.id) || {}; - }, - exports: mod.exports || (mod.exports = {}) - }); - } - } - }; - - function cleanRegistry(id) { - //Clean up machinery used for waiting modules. - delete registry[id]; - delete enabledRegistry[id]; - } - - function breakCycle(mod, traced, processed) { - var id = mod.map.id; - - if (mod.error) { - mod.emit('error', mod.error); - } else { - traced[id] = true; - each(mod.depMaps, function (depMap, i) { - var depId = depMap.id, - dep = getOwn(registry, depId); - - //Only force things that have not completed - //being defined, so still in the registry, - //and only if it has not been matched up - //in the module already. - if (dep && !mod.depMatched[i] && !processed[depId]) { - if (getOwn(traced, depId)) { - mod.defineDep(i, defined[depId]); - mod.check(); //pass false? - } else { - breakCycle(dep, traced, processed); - } - } - }); - processed[id] = true; - } - } - - function checkLoaded() { - var err, usingPathFallback, - waitInterval = config.waitSeconds * 1000, - //It is possible to disable the wait interval by using waitSeconds of 0. - expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), - noLoads = [], - reqCalls = [], - stillLoading = false, - needCycleCheck = true; - - //Do not bother if this call was a result of a cycle break. - if (inCheckLoaded) { - return; - } - - inCheckLoaded = true; - - //Figure out the state of all the modules. - eachProp(enabledRegistry, function (mod) { - var map = mod.map, - modId = map.id; - - //Skip things that are not enabled or in error state. - if (!mod.enabled) { - return; - } - - if (!map.isDefine) { - reqCalls.push(mod); - } - - if (!mod.error) { - //If the module should be executed, and it has not - //been inited and time is up, remember it. - if (!mod.inited && expired) { - if (hasPathFallback(modId)) { - usingPathFallback = true; - stillLoading = true; - } else { - noLoads.push(modId); - removeScript(modId); - } - } else if (!mod.inited && mod.fetched && map.isDefine) { - stillLoading = true; - if (!map.prefix) { - //No reason to keep looking for unfinished - //loading. If the only stillLoading is a - //plugin resource though, keep going, - //because it may be that a plugin resource - //is waiting on a non-plugin cycle. - return (needCycleCheck = false); - } - } - } - }); - - if (expired && noLoads.length) { - //If wait time expired, throw error of unloaded modules. - err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); - err.contextName = context.contextName; - return onError(err); - } - - //Not expired, check for a cycle. - if (needCycleCheck) { - each(reqCalls, function (mod) { - breakCycle(mod, {}, {}); - }); - } - - //If still waiting on loads, and the waiting load is something - //other than a plugin resource, or there are still outstanding - //scripts, then just try back later. - if ((!expired || usingPathFallback) && stillLoading) { - //Something is still waiting to load. Wait for it, but only - //if a timeout is not already in effect. - if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { - checkLoadedTimeoutId = setTimeout(function () { - checkLoadedTimeoutId = 0; - checkLoaded(); - }, 50); - } - } - - inCheckLoaded = false; - } - - Module = function (map) { - this.events = getOwn(undefEvents, map.id) || {}; - this.map = map; - this.shim = getOwn(config.shim, map.id); - this.depExports = []; - this.depMaps = []; - this.depMatched = []; - this.pluginMaps = {}; - this.depCount = 0; - - /* this.exports this.factory - this.depMaps = [], - this.enabled, this.fetched - */ - }; - - Module.prototype = { - init: function (depMaps, factory, errback, options) { - options = options || {}; - - //Do not do more inits if already done. Can happen if there - //are multiple define calls for the same module. That is not - //a normal, common case, but it is also not unexpected. - if (this.inited) { - return; - } - - this.factory = factory; - - if (errback) { - //Register for errors on this module. - this.on('error', errback); - } else if (this.events.error) { - //If no errback already, but there are error listeners - //on this module, set up an errback to pass to the deps. - errback = bind(this, function (err) { - this.emit('error', err); - }); - } - - //Do a copy of the dependency array, so that - //source inputs are not modified. For example - //"shim" deps are passed in here directly, and - //doing a direct modification of the depMaps array - //would affect that config. - this.depMaps = depMaps && depMaps.slice(0); - - this.errback = errback; - - //Indicate this module has be initialized - this.inited = true; - - this.ignore = options.ignore; - - //Could have option to init this module in enabled mode, - //or could have been previously marked as enabled. However, - //the dependencies are not known until init is called. So - //if enabled previously, now trigger dependencies as enabled. - if (options.enabled || this.enabled) { - //Enable this module and dependencies. - //Will call this.check() - this.enable(); - } else { - this.check(); - } - }, - - defineDep: function (i, depExports) { - //Because of cycles, defined callback for a given - //export can be called more than once. - if (!this.depMatched[i]) { - this.depMatched[i] = true; - this.depCount -= 1; - this.depExports[i] = depExports; - } - }, - - fetch: function () { - if (this.fetched) { - return; - } - this.fetched = true; - - context.startTime = (new Date()).getTime(); - - var map = this.map; - - //If the manager is for a plugin managed resource, - //ask the plugin to load it now. - if (this.shim) { - context.makeRequire(this.map, { - enableBuildCallback: true - })(this.shim.deps || [], bind(this, function () { - return map.prefix ? this.callPlugin() : this.load(); - })); - } else { - //Regular dependency. - return map.prefix ? this.callPlugin() : this.load(); - } - }, - - load: function () { - var url = this.map.url; - - //Regular dependency. - if (!urlFetched[url]) { - urlFetched[url] = true; - context.load(this.map.id, url); - } - }, - - /** - * Checks if the module is ready to define itself, and if so, - * define it. - */ - check: function () { - if (!this.enabled || this.enabling) { - return; - } - - var err, cjsModule, - id = this.map.id, - depExports = this.depExports, - exports = this.exports, - factory = this.factory; - - if (!this.inited) { - this.fetch(); - } else if (this.error) { - this.emit('error', this.error); - } else if (!this.defining) { - //The factory could trigger another require call - //that would result in checking this module to - //define itself again. If already in the process - //of doing that, skip this work. - this.defining = true; - - if (this.depCount < 1 && !this.defined) { - if (isFunction(factory)) { - //If there is an error listener, favor passing - //to that instead of throwing an error. However, - //only do it for define()'d modules. require - //errbacks should not be called for failures in - //their callbacks (#699). However if a global - //onError is set, use that. - if ((this.events.error && this.map.isDefine) || - req.onError !== defaultOnError) { - try { - exports = context.execCb(id, factory, depExports, exports); - } catch (e) { - err = e; - } - } else { - exports = context.execCb(id, factory, depExports, exports); - } - - // Favor return value over exports. If node/cjs in play, - // then will not have a return value anyway. Favor - // module.exports assignment over exports object. - if (this.map.isDefine && exports === undefined) { - cjsModule = this.module; - if (cjsModule) { - exports = cjsModule.exports; - } else if (this.usingExports) { - //exports already set the defined value. - exports = this.exports; - } - } - - if (err) { - err.requireMap = this.map; - err.requireModules = this.map.isDefine ? [this.map.id] : null; - err.requireType = this.map.isDefine ? 'define' : 'require'; - return onError((this.error = err)); - } - - } else { - //Just a literal value - exports = factory; - } - - this.exports = exports; - - if (this.map.isDefine && !this.ignore) { - defined[id] = exports; - - if (req.onResourceLoad) { - req.onResourceLoad(context, this.map, this.depMaps); - } - } - - //Clean up - cleanRegistry(id); - - this.defined = true; - } - - //Finished the define stage. Allow calling check again - //to allow define notifications below in the case of a - //cycle. - this.defining = false; - - if (this.defined && !this.defineEmitted) { - this.defineEmitted = true; - this.emit('defined', this.exports); - this.defineEmitComplete = true; - } - - } - }, - - callPlugin: function () { - var map = this.map, - id = map.id, - //Map already normalized the prefix. - pluginMap = makeModuleMap(map.prefix); - - //Mark this as a dependency for this plugin, so it - //can be traced for cycles. - this.depMaps.push(pluginMap); - - on(pluginMap, 'defined', bind(this, function (plugin) { - var load, normalizedMap, normalizedMod, - bundleId = getOwn(bundlesMap, this.map.id), - name = this.map.name, - parentName = this.map.parentMap ? this.map.parentMap.name : null, - localRequire = context.makeRequire(map.parentMap, { - enableBuildCallback: true - }); - - //If current map is not normalized, wait for that - //normalized name to load instead of continuing. - if (this.map.unnormalized) { - //Normalize the ID if the plugin allows it. - if (plugin.normalize) { - name = plugin.normalize(name, function (name) { - return normalize(name, parentName, true); - }) || ''; - } - - //prefix and name should already be normalized, no need - //for applying map config again either. - normalizedMap = makeModuleMap(map.prefix + '!' + name, - this.map.parentMap); - on(normalizedMap, - 'defined', bind(this, function (value) { - this.init([], function () { return value; }, null, { - enabled: true, - ignore: true - }); - })); - - normalizedMod = getOwn(registry, normalizedMap.id); - if (normalizedMod) { - //Mark this as a dependency for this plugin, so it - //can be traced for cycles. - this.depMaps.push(normalizedMap); - - if (this.events.error) { - normalizedMod.on('error', bind(this, function (err) { - this.emit('error', err); - })); - } - normalizedMod.enable(); - } - - return; - } - - //If a paths config, then just load that file instead to - //resolve the plugin, as it is built into that paths layer. - if (bundleId) { - this.map.url = context.nameToUrl(bundleId); - this.load(); - return; - } - - load = bind(this, function (value) { - this.init([], function () { return value; }, null, { - enabled: true - }); - }); - - load.error = bind(this, function (err) { - this.inited = true; - this.error = err; - err.requireModules = [id]; - - //Remove temp unnormalized modules for this module, - //since they will never be resolved otherwise now. - eachProp(registry, function (mod) { - if (mod.map.id.indexOf(id + '_unnormalized') === 0) { - cleanRegistry(mod.map.id); - } - }); - - onError(err); - }); - - //Allow plugins to load other code without having to know the - //context or how to 'complete' the load. - load.fromText = bind(this, function (text, textAlt) { - /*jslint evil: true */ - var moduleName = map.name, - moduleMap = makeModuleMap(moduleName), - hasInteractive = useInteractive; - - //As of 2.1.0, support just passing the text, to reinforce - //fromText only being called once per resource. Still - //support old style of passing moduleName but discard - //that moduleName in favor of the internal ref. - if (textAlt) { - text = textAlt; - } - - //Turn off interactive script matching for IE for any define - //calls in the text, then turn it back on at the end. - if (hasInteractive) { - useInteractive = false; - } - - //Prime the system by creating a module instance for - //it. - getModule(moduleMap); - - //Transfer any config to this other module. - if (hasProp(config.config, id)) { - config.config[moduleName] = config.config[id]; - } - - try { - req.exec(text); - } catch (e) { - return onError(makeError('fromtexteval', - 'fromText eval for ' + id + - ' failed: ' + e, - e, - [id])); - } - - if (hasInteractive) { - useInteractive = true; - } - - //Mark this as a dependency for the plugin - //resource - this.depMaps.push(moduleMap); - - //Support anonymous modules. - context.completeLoad(moduleName); - - //Bind the value of that module to the value for this - //resource ID. - localRequire([moduleName], load); - }); - - //Use parentName here since the plugin's name is not reliable, - //could be some weird string with no path that actually wants to - //reference the parentName's path. - plugin.load(map.name, localRequire, load, config); - })); - - context.enable(pluginMap, this); - this.pluginMaps[pluginMap.id] = pluginMap; - }, - - enable: function () { - enabledRegistry[this.map.id] = this; - this.enabled = true; - - //Set flag mentioning that the module is enabling, - //so that immediate calls to the defined callbacks - //for dependencies do not trigger inadvertent load - //with the depCount still being zero. - this.enabling = true; - - //Enable each dependency - each(this.depMaps, bind(this, function (depMap, i) { - var id, mod, handler; - - if (typeof depMap === 'string') { - //Dependency needs to be converted to a depMap - //and wired up to this module. - depMap = makeModuleMap(depMap, - (this.map.isDefine ? this.map : this.map.parentMap), - false, - !this.skipMap); - this.depMaps[i] = depMap; - - handler = getOwn(handlers, depMap.id); - - if (handler) { - this.depExports[i] = handler(this); - return; - } - - this.depCount += 1; - - on(depMap, 'defined', bind(this, function (depExports) { - this.defineDep(i, depExports); - this.check(); - })); - - if (this.errback) { - on(depMap, 'error', bind(this, this.errback)); - } else if (this.events.error) { - // No direct errback on this module, but something - // else is listening for errors, so be sure to - // propagate the error correctly. - on(depMap, 'error', bind(this, function(err) { - this.emit('error', err); - })); - } - } - - id = depMap.id; - mod = registry[id]; - - //Skip special modules like 'require', 'exports', 'module' - //Also, don't call enable if it is already enabled, - //important in circular dependency cases. - if (!hasProp(handlers, id) && mod && !mod.enabled) { - context.enable(depMap, this); - } - })); - - //Enable each plugin that is used in - //a dependency - eachProp(this.pluginMaps, bind(this, function (pluginMap) { - var mod = getOwn(registry, pluginMap.id); - if (mod && !mod.enabled) { - context.enable(pluginMap, this); - } - })); - - this.enabling = false; - - this.check(); - }, - - on: function (name, cb) { - var cbs = this.events[name]; - if (!cbs) { - cbs = this.events[name] = []; - } - cbs.push(cb); - }, - - emit: function (name, evt) { - each(this.events[name], function (cb) { - cb(evt); - }); - if (name === 'error') { - //Now that the error handler was triggered, remove - //the listeners, since this broken Module instance - //can stay around for a while in the registry. - delete this.events[name]; - } - } - }; - - function callGetModule(args) { - //Skip modules already defined. - if (!hasProp(defined, args[0])) { - getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); - } - } - - function removeListener(node, func, name, ieName) { - //Favor detachEvent because of IE9 - //issue, see attachEvent/addEventListener comment elsewhere - //in this file. - if (node.detachEvent && !isOpera) { - //Probably IE. If not it will throw an error, which will be - //useful to know. - if (ieName) { - node.detachEvent(ieName, func); - } - } else { - node.removeEventListener(name, func, false); - } - } - - /** - * Given an event from a script node, get the requirejs info from it, - * and then removes the event listeners on the node. - * @param {Event} evt - * @returns {Object} - */ - function getScriptData(evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - var node = evt.currentTarget || evt.srcElement; - - //Remove the listeners once here. - removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); - removeListener(node, context.onScriptError, 'error'); - - return { - node: node, - id: node && node.getAttribute('data-requiremodule') - }; - } - - function intakeDefines() { - var args; - - //Any defined modules in the global queue, intake them now. - takeGlobalQueue(); - - //Make sure any remaining defQueue items get properly processed. - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); - } else { - //args are id, deps, factory. Should be normalized by the - //define() function. - callGetModule(args); - } - } - } - - context = { - config: config, - contextName: contextName, - registry: registry, - defined: defined, - urlFetched: urlFetched, - defQueue: defQueue, - Module: Module, - makeModuleMap: makeModuleMap, - nextTick: req.nextTick, - onError: onError, - - /** - * Set a configuration for the context. - * @param {Object} cfg config object to integrate. - */ - configure: function (cfg) { - //Make sure the baseUrl ends in a slash. - if (cfg.baseUrl) { - if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { - cfg.baseUrl += '/'; - } - } - - //Save off the paths since they require special processing, - //they are additive. - var shim = config.shim, - objs = { - paths: true, - bundles: true, - config: true, - map: true - }; - - eachProp(cfg, function (value, prop) { - if (objs[prop]) { - if (!config[prop]) { - config[prop] = {}; - } - mixin(config[prop], value, true, true); - } else { - config[prop] = value; - } - }); - - //Reverse map the bundles - if (cfg.bundles) { - eachProp(cfg.bundles, function (value, prop) { - each(value, function (v) { - if (v !== prop) { - bundlesMap[v] = prop; - } - }); - }); - } - - //Merge shim - if (cfg.shim) { - eachProp(cfg.shim, function (value, id) { - //Normalize the structure - if (isArray(value)) { - value = { - deps: value - }; - } - if ((value.exports || value.init) && !value.exportsFn) { - value.exportsFn = context.makeShimExports(value); - } - shim[id] = value; - }); - config.shim = shim; - } - - //Adjust packages if necessary. - if (cfg.packages) { - each(cfg.packages, function (pkgObj) { - var location, name; - - pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; - - name = pkgObj.name; - location = pkgObj.location; - if (location) { - config.paths[name] = pkgObj.location; - } - - //Save pointer to main module ID for pkg name. - //Remove leading dot in main, so main paths are normalized, - //and remove any trailing .js, since different package - //envs have different conventions: some use a module name, - //some use a file name. - config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') - .replace(currDirRegExp, '') - .replace(jsSuffixRegExp, ''); - }); - } - - //If there are any "waiting to execute" modules in the registry, - //update the maps for them, since their info, like URLs to load, - //may have changed. - eachProp(registry, function (mod, id) { - //If module already has init called, since it is too - //late to modify them, and ignore unnormalized ones - //since they are transient. - if (!mod.inited && !mod.map.unnormalized) { - mod.map = makeModuleMap(id); - } - }); - - //If a deps array or a config callback is specified, then call - //require with those args. This is useful when require is defined as a - //config object before require.js is loaded. - if (cfg.deps || cfg.callback) { - context.require(cfg.deps || [], cfg.callback); - } - }, - - makeShimExports: function (value) { - function fn() { - var ret; - if (value.init) { - ret = value.init.apply(global, arguments); - } - return ret || (value.exports && getGlobal(value.exports)); - } - return fn; - }, - - makeRequire: function (relMap, options) { - options = options || {}; - - function localRequire(deps, callback, errback) { - var id, map, requireMod; - - if (options.enableBuildCallback && callback && isFunction(callback)) { - callback.__requireJsBuild = true; - } - - if (typeof deps === 'string') { - if (isFunction(callback)) { - //Invalid call - return onError(makeError('requireargs', 'Invalid require call'), errback); - } - - //If require|exports|module are requested, get the - //value for them from the special handlers. Caveat: - //this only works while module is being defined. - if (relMap && hasProp(handlers, deps)) { - return handlers[deps](registry[relMap.id]); - } - - //Synchronous access to one module. If require.get is - //available (as in the Node adapter), prefer that. - if (req.get) { - return req.get(context, deps, relMap, localRequire); - } - - //Normalize module name, if it contains . or .. - map = makeModuleMap(deps, relMap, false, true); - id = map.id; - - if (!hasProp(defined, id)) { - return onError(makeError('notloaded', 'Module name "' + - id + - '" has not been loaded yet for context: ' + - contextName + - (relMap ? '' : '. Use require([])'))); - } - return defined[id]; - } - - //Grab defines waiting in the global queue. - intakeDefines(); - - //Mark all the dependencies as needing to be loaded. - context.nextTick(function () { - //Some defines could have been added since the - //require call, collect them. - intakeDefines(); - - requireMod = getModule(makeModuleMap(null, relMap)); - - //Store if map config should be applied to this require - //call for dependencies. - requireMod.skipMap = options.skipMap; - - requireMod.init(deps, callback, errback, { - enabled: true - }); - - checkLoaded(); - }); - - return localRequire; - } - - mixin(localRequire, { - isBrowser: isBrowser, - - /** - * Converts a module name + .extension into an URL path. - * *Requires* the use of a module name. It does not support using - * plain URLs like nameToUrl. - */ - toUrl: function (moduleNamePlusExt) { - var ext, - index = moduleNamePlusExt.lastIndexOf('.'), - segment = moduleNamePlusExt.split('/')[0], - isRelative = segment === '.' || segment === '..'; - - //Have a file extension alias, and it is not the - //dots from a relative path. - if (index !== -1 && (!isRelative || index > 1)) { - ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); - moduleNamePlusExt = moduleNamePlusExt.substring(0, index); - } - - return context.nameToUrl(normalize(moduleNamePlusExt, - relMap && relMap.id, true), ext, true); - }, - - defined: function (id) { - return hasProp(defined, makeModuleMap(id, relMap, false, true).id); - }, - - specified: function (id) { - id = makeModuleMap(id, relMap, false, true).id; - return hasProp(defined, id) || hasProp(registry, id); - } - }); - - //Only allow undef on top level require calls - if (!relMap) { - localRequire.undef = function (id) { - //Bind any waiting define() calls to this context, - //fix for #408 - takeGlobalQueue(); - - var map = makeModuleMap(id, relMap, true), - mod = getOwn(registry, id); - - removeScript(id); - - delete defined[id]; - delete urlFetched[map.url]; - delete undefEvents[id]; - - //Clean queued defines too. Go backwards - //in array so that the splices do not - //mess up the iteration. - eachReverse(defQueue, function(args, i) { - if(args[0] === id) { - defQueue.splice(i, 1); - } - }); - - if (mod) { - //Hold on to listeners in case the - //module will be attempted to be reloaded - //using a different config. - if (mod.events.defined) { - undefEvents[id] = mod.events; - } - - cleanRegistry(id); - } - }; - } - - return localRequire; - }, - - /** - * Called to enable a module if it is still in the registry - * awaiting enablement. A second arg, parent, the parent module, - * is passed in for context, when this method is overridden by - * the optimizer. Not shown here to keep code compact. - */ - enable: function (depMap) { - var mod = getOwn(registry, depMap.id); - if (mod) { - getModule(depMap).enable(); - } - }, - - /** - * Internal method used by environment adapters to complete a load event. - * A load event could be a script load or just a load pass from a synchronous - * load call. - * @param {String} moduleName the name of the module to potentially complete. - */ - completeLoad: function (moduleName) { - var found, args, mod, - shim = getOwn(config.shim, moduleName) || {}, - shExports = shim.exports; - - takeGlobalQueue(); - - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - args[0] = moduleName; - //If already found an anonymous module and bound it - //to this name, then this is some other anon module - //waiting for its completeLoad to fire. - if (found) { - break; - } - found = true; - } else if (args[0] === moduleName) { - //Found matching define call for this script! - found = true; - } - - callGetModule(args); - } - - //Do this after the cycle of callGetModule in case the result - //of those calls/init calls changes the registry. - mod = getOwn(registry, moduleName); - - if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { - if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { - if (hasPathFallback(moduleName)) { - return; - } else { - return onError(makeError('nodefine', - 'No define call for ' + moduleName, - null, - [moduleName])); - } - } else { - //A script that does not call define(), so just simulate - //the call for it. - callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); - } - } - - checkLoaded(); - }, - - /** - * Converts a module name to a file path. Supports cases where - * moduleName may actually be just an URL. - * Note that it **does not** call normalize on the moduleName, - * it is assumed to have already been normalized. This is an - * internal API, not a public one. Use toUrl for the public API. - */ - nameToUrl: function (moduleName, ext, skipExt) { - var paths, syms, i, parentModule, url, - parentPath, bundleId, - pkgMain = getOwn(config.pkgs, moduleName); - - if (pkgMain) { - moduleName = pkgMain; - } - - bundleId = getOwn(bundlesMap, moduleName); - - if (bundleId) { - return context.nameToUrl(bundleId, ext, skipExt); - } - - //If a colon is in the URL, it indicates a protocol is used and it is just - //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) - //or ends with .js, then assume the user meant to use an url and not a module id. - //The slash is important for protocol-less URLs as well as full paths. - if (req.jsExtRegExp.test(moduleName)) { - //Just a plain path, not module name lookup, so just return it. - //Add extension if it is included. This is a bit wonky, only non-.js things pass - //an extension, this method probably needs to be reworked. - url = moduleName + (ext || ''); - } else { - //A module that needs to be converted to a path. - paths = config.paths; - - syms = moduleName.split('/'); - //For each module name segment, see if there is a path - //registered for it. Start with most specific name - //and work up from it. - for (i = syms.length; i > 0; i -= 1) { - parentModule = syms.slice(0, i).join('/'); - - parentPath = getOwn(paths, parentModule); - if (parentPath) { - //If an array, it means there are a few choices, - //Choose the one that is desired - if (isArray(parentPath)) { - parentPath = parentPath[0]; - } - syms.splice(0, i, parentPath); - break; - } - } - - //Join the path parts together, then figure out if baseUrl is needed. - url = syms.join('/'); - url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); - url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; - } - - return config.urlArgs ? url + - ((url.indexOf('?') === -1 ? '?' : '&') + - config.urlArgs) : url; - }, - - //Delegates to req.load. Broken out as a separate function to - //allow overriding in the optimizer. - load: function (id, url) { - req.load(context, id, url); - }, - - /** - * Executes a module callback function. Broken out as a separate function - * solely to allow the build system to sequence the files in the built - * layer in the right sequence. - * - * @private - */ - execCb: function (name, callback, args, exports) { - return callback.apply(exports, args); - }, - - /** - * callback for script loads, used to check status of loading. - * - * @param {Event} evt the event from the browser for the script - * that was loaded. - */ - onScriptLoad: function (evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - if (evt.type === 'load' || - (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { - //Reset interactive script so a script node is not held onto for - //to long. - interactiveScript = null; - - //Pull out the name of the module and the context. - var data = getScriptData(evt); - context.completeLoad(data.id); - } - }, - - /** - * Callback for script errors. - */ - onScriptError: function (evt) { - var data = getScriptData(evt); - if (!hasPathFallback(data.id)) { - return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); - } - } - }; - - context.require = context.makeRequire(); - return context; - } - - /** - * Main entry point. - * - * If the only argument to require is a string, then the module that - * is represented by that string is fetched for the appropriate context. - * - * If the first argument is an array, then it will be treated as an array - * of dependency string names to fetch. An optional function callback can - * be specified to execute when all of those dependencies are available. - * - * Make a local req variable to help Caja compliance (it assumes things - * on a require that are not standardized), and to give a short - * name for minification/local scope use. - */ - req = requirejs = function (deps, callback, errback, optional) { - - //Find the right context, use default - var context, config, - contextName = defContextName; - - // Determine if have config object in the call. - if (!isArray(deps) && typeof deps !== 'string') { - // deps is a config object - config = deps; - if (isArray(callback)) { - // Adjust args if there are dependencies - deps = callback; - callback = errback; - errback = optional; - } else { - deps = []; - } - } - - if (config && config.context) { - contextName = config.context; - } - - context = getOwn(contexts, contextName); - if (!context) { - context = contexts[contextName] = req.s.newContext(contextName); - } - - if (config) { - context.configure(config); - } - - return context.require(deps, callback, errback); - }; - - /** - * Support require.config() to make it easier to cooperate with other - * AMD loaders on globally agreed names. - */ - req.config = function (config) { - return req(config); - }; - - /** - * Execute something after the current tick - * of the event loop. Override for other envs - * that have a better solution than setTimeout. - * @param {Function} fn function to execute later. - */ - req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { - setTimeout(fn, 4); - } : function (fn) { fn(); }; - - /** - * Export require as a global, but only if it does not already exist. - */ - if (!require) { - require = req; - } - - req.version = version; - - //Used to filter out dependencies that are already paths. - req.jsExtRegExp = /^\/|:|\?|\.js$/; - req.isBrowser = isBrowser; - s = req.s = { - contexts: contexts, - newContext: newContext - }; - - //Create default context. - req({}); - - //Exports some context-sensitive methods on global require. - each([ - 'toUrl', - 'undef', - 'defined', - 'specified' - ], function (prop) { - //Reference from contexts instead of early binding to default context, - //so that during builds, the latest instance of the default context - //with its config gets used. - req[prop] = function () { - var ctx = contexts[defContextName]; - return ctx.require[prop].apply(ctx, arguments); - }; - }); - - if (isBrowser) { - head = s.head = document.getElementsByTagName('head')[0]; - //If BASE tag is in play, using appendChild is a problem for IE6. - //When that browser dies, this can be removed. Details in this jQuery bug: - //http://dev.jquery.com/ticket/2709 - baseElement = document.getElementsByTagName('base')[0]; - if (baseElement) { - head = s.head = baseElement.parentNode; - } - } - - /** - * Any errors that require explicitly generates will be passed to this - * function. Intercept/override it if you want custom error handling. - * @param {Error} err the error object. - */ - req.onError = defaultOnError; - - /** - * Creates the node for the load command. Only used in browser envs. - */ - req.createNode = function (config, moduleName, url) { - var node = config.xhtml ? - document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : - document.createElement('script'); - node.type = config.scriptType || 'text/javascript'; - node.charset = 'utf-8'; - node.async = true; - return node; - }; - - /** - * Does the request to load a module for the browser case. - * Make this a separate function to allow other environments - * to override it. - * - * @param {Object} context the require context to find state. - * @param {String} moduleName the name of the module. - * @param {Object} url the URL to the module. - */ - req.load = function (context, moduleName, url) { - var config = (context && context.config) || {}, - node; - if (isBrowser) { - //In the browser so use a script tag - node = req.createNode(config, moduleName, url); - - node.setAttribute('data-requirecontext', context.contextName); - node.setAttribute('data-requiremodule', moduleName); - - //Set up load listener. Test attachEvent first because IE9 has - //a subtle issue in its addEventListener and script onload firings - //that do not match the behavior of all other browsers with - //addEventListener support, which fire the onload event for a - //script right after the script execution. See: - //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution - //UNFORTUNATELY Opera implements attachEvent but does not follow the script - //script execution mode. - if (node.attachEvent && - //Check if node.attachEvent is artificially added by custom script or - //natively supported by browser - //read https://github.com/jrburke/requirejs/issues/187 - //if we can NOT find [native code] then it must NOT natively supported. - //in IE8, node.attachEvent does not have toString() - //Note the test for "[native code" with no closing brace, see: - //https://github.com/jrburke/requirejs/issues/273 - !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && - !isOpera) { - //Probably IE. IE (at least 6-8) do not fire - //script onload right after executing the script, so - //we cannot tie the anonymous define call to a name. - //However, IE reports the script as being in 'interactive' - //readyState at the time of the define call. - useInteractive = true; - - node.attachEvent('onreadystatechange', context.onScriptLoad); - //It would be great to add an error handler here to catch - //404s in IE9+. However, onreadystatechange will fire before - //the error handler, so that does not help. If addEventListener - //is used, then IE will fire error before load, but we cannot - //use that pathway given the connect.microsoft.com issue - //mentioned above about not doing the 'script execute, - //then fire the script load event listener before execute - //next script' that other browsers do. - //Best hope: IE10 fixes the issues, - //and then destroys all installs of IE 6-9. - //node.attachEvent('onerror', context.onScriptError); - } else { - node.addEventListener('load', context.onScriptLoad, false); - node.addEventListener('error', context.onScriptError, false); - } - node.src = url; - - //For some cache cases in IE 6-8, the script executes before the end - //of the appendChild execution, so to tie an anonymous define - //call to the module name (which is stored on the node), hold on - //to a reference to this node, but clear after the DOM insertion. - currentlyAddingScript = node; - if (baseElement) { - head.insertBefore(node, baseElement); - } else { - head.appendChild(node); - } - currentlyAddingScript = null; - - return node; - } else if (isWebWorker) { - try { - //In a web worker, use importScripts. This is not a very - //efficient use of importScripts, importScripts will block until - //its script is downloaded and evaluated. However, if web workers - //are in play, the expectation that a build has been done so that - //only one script needs to be loaded anyway. This may need to be - //reevaluated if other use cases become common. - importScripts(url); - - //Account for anonymous modules - context.completeLoad(moduleName); - } catch (e) { - context.onError(makeError('importscripts', - 'importScripts failed for ' + - moduleName + ' at ' + url, - e, - [moduleName])); - } - } - }; - - function getInteractiveScript() { - if (interactiveScript && interactiveScript.readyState === 'interactive') { - return interactiveScript; - } - - eachReverse(scripts(), function (script) { - if (script.readyState === 'interactive') { - return (interactiveScript = script); - } - }); - return interactiveScript; - } - - //Look for a data-main script attribute, which could also adjust the baseUrl. - if (isBrowser && !cfg.skipDataMain) { - //Figure out baseUrl. Get it from the script tag with require.js in it. - eachReverse(scripts(), function (script) { - //Set the 'head' where we can append children by - //using the script's parent. - if (!head) { - head = script.parentNode; - } - - //Look for a data-main attribute to set main script for the page - //to load. If it is there, the path to data main becomes the - //baseUrl, if it is not already set. - dataMain = script.getAttribute('data-main'); - if (dataMain) { - //Preserve dataMain in case it is a path (i.e. contains '?') - mainScript = dataMain; - - //Set final baseUrl if there is not already an explicit one. - if (!cfg.baseUrl) { - //Pull off the directory of data-main for use as the - //baseUrl. - src = mainScript.split('/'); - mainScript = src.pop(); - subPath = src.length ? src.join('/') + '/' : './'; - - cfg.baseUrl = subPath; - } - - //Strip off any trailing .js since mainScript is now - //like a module name. - mainScript = mainScript.replace(jsSuffixRegExp, ''); - - //If mainScript is still a path, fall back to dataMain - if (req.jsExtRegExp.test(mainScript)) { - mainScript = dataMain; - } - - //Put the data-main script in the files to load. - cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; - - return true; - } - }); - } - - /** - * The function that handles definitions of modules. Differs from - * require() in that a string for the module should be the first argument, - * and the function to execute after dependencies are loaded should - * return a value to define the module corresponding to the first argument's - * name. - */ - define = function (name, deps, callback) { - var node, context; - - //Allow for anonymous modules - if (typeof name !== 'string') { - //Adjust args appropriately - callback = deps; - deps = name; - name = null; - } - - //This module may not have dependencies - if (!isArray(deps)) { - callback = deps; - deps = null; - } - - //If no name, and callback is a function, then figure out if it a - //CommonJS thing with dependencies. - if (!deps && isFunction(callback)) { - deps = []; - //Remove comments from the callback string, - //look for require calls, and pull them into the dependencies, - //but only if there are function args. - if (callback.length) { - callback - .toString() - .replace(commentRegExp, '') - .replace(cjsRequireRegExp, function (match, dep) { - deps.push(dep); - }); - - //May be a CommonJS thing even without require calls, but still - //could use exports, and module. Avoid doing exports and module - //work though if it just needs require. - //REQUIRES the function to expect the CommonJS variables in the - //order listed below. - deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); - } - } - - //If in IE 6-8 and hit an anonymous define() call, do the interactive - //work. - if (useInteractive) { - node = currentlyAddingScript || getInteractiveScript(); - if (node) { - if (!name) { - name = node.getAttribute('data-requiremodule'); - } - context = contexts[node.getAttribute('data-requirecontext')]; - } - } - - //Always save off evaluating the def call until the script onload handler. - //This allows multiple modules to be in a file without prematurely - //tracing dependencies, and allows for anonymous module support, - //where the module name is not known until the script onload event - //occurs. If no context, use the global queue, and get it processed - //in the onscript load callback. - (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); - }; - - define.amd = { - jQuery: true - }; - - - /** - * Executes the text. Normally just uses eval, but can be modified - * to use a better, environment-specific call. Only used for transpiling - * loader plugins, not for plain JS modules. - * @param {String} text the text to execute/evaluate. - */ - req.exec = function (text) { - /*jslint evil: true */ - return eval(text); - }; - - //Set up with config info. - req(cfg); -}(this)); diff --git a/server/sonar-web/src/main/js/libs/third-party/shim/backbone-shim.js b/server/sonar-web/src/main/js/libs/third-party/shim/backbone-shim.js deleted file mode 100644 index 041e0eae3ef..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/shim/backbone-shim.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function () { - return window.Backbone; -}); diff --git a/server/sonar-web/src/main/js/libs/third-party/shim/jquery-shim.js b/server/sonar-web/src/main/js/libs/third-party/shim/jquery-shim.js deleted file mode 100644 index aa31e60d459..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/shim/jquery-shim.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function () { - return window.jQuery; -}); diff --git a/server/sonar-web/src/main/js/libs/third-party/shim/marionette-shim.js b/server/sonar-web/src/main/js/libs/third-party/shim/marionette-shim.js deleted file mode 100644 index 84220542147..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/shim/marionette-shim.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function () { - return window.Marionette; -}); diff --git a/server/sonar-web/src/main/js/libs/third-party/shim/moment-shim.js b/server/sonar-web/src/main/js/libs/third-party/shim/moment-shim.js deleted file mode 100644 index 32de3fe3a1d..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/shim/moment-shim.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function () { - return window.moment; -}); diff --git a/server/sonar-web/src/main/js/libs/third-party/shim/underscore-shim.js b/server/sonar-web/src/main/js/libs/third-party/shim/underscore-shim.js deleted file mode 100644 index c49e9f8fc1c..00000000000 --- a/server/sonar-web/src/main/js/libs/third-party/shim/underscore-shim.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function () { - return window._; -}); diff --git a/server/sonar-web/src/main/js/main/app.js b/server/sonar-web/src/main/js/main/app.js new file mode 100644 index 00000000000..a9f70a8f899 --- /dev/null +++ b/server/sonar-web/src/main/js/main/app.js @@ -0,0 +1,39 @@ +import 'babelify/polyfill'; +import $ from 'jquery'; +import _ from 'underscore'; +import Backbone from 'backbone'; +import 'whatwg-fetch'; +import '../libs/third-party/backbone-super.js'; +import './processes'; +import Navigation from './nav/app'; + +// set the Backbone's $ +Backbone.$ = $; + + +function requestLocalizationBundle () { + return new Promise(resolve => window.requestMessages().done(resolve)); +} + +function startNavigation () { + return new Navigation().start(); +} + +function prepareAppOptions (navResponse) { + let appOptions = { el: '#content' }; + appOptions.rootQualifiers = navResponse.global.qualifiers; + if (navResponse.component) { + appOptions.component = { + id: navResponse.component.uuid, + key: navResponse.component.key, + name: navResponse.component.name, + qualifier: _.last(navResponse.component.breadcrumbs).qualifier + }; + } + return appOptions; +} + +window.sonarqube.appStarted = Promise.resolve() + .then(requestLocalizationBundle) + .then(startNavigation) + .then(prepareAppOptions); diff --git a/server/sonar-web/src/main/js/main/nav/app.js b/server/sonar-web/src/main/js/main/nav/app.js new file mode 100644 index 00000000000..a193fef0415 --- /dev/null +++ b/server/sonar-web/src/main/js/main/nav/app.js @@ -0,0 +1,65 @@ +import React from 'react'; +import GlobalNav from './global/global-nav'; +import ComponentNav from './component/component-nav'; +import SettingsNav from './settings/settings-nav'; +import {getGlobalNavigation, getComponentNavigation, getSettingsNavigation} from '../../api/nav'; +import {getTasksForComponent} from '../../api/ce'; +import '../../components/workspace/main'; +import '../../helpers/handlebars-helpers'; + +export default class App { + start () { + let options = window.sonarqube; + + return new Promise((resolve) => { + let response = {}, + requests = []; + + requests.push( + App.renderGlobalNav(options).then(r => response.global = r) + ); + + if (options.space === 'component') { + requests.push( + App.renderComponentNav(options).then(r => response.component = r) + ); + } else if (options.space === 'settings') { + requests.push( + App.renderSettingsNav(options).then(r => response.settings = r) + ); + } + + Promise.all(requests).then(() => resolve(response)); + }); + } + + static renderGlobalNav (options) { + return getGlobalNavigation().then(r => { + const el = document.getElementById('global-navigation'); + if (el) { + React.render(<GlobalNav {...options} {...r}/>, el); + } + return r; + }); + } + + static renderComponentNav (options) { + return getComponentNavigation(options.componentKey).then(r => { + const el = document.getElementById('context-navigation'); + if (el) { + React.render(<ComponentNav component={r} conf={r.configuration || {}}/>, el); + } + return r; + }); + } + + static renderSettingsNav (options) { + return getSettingsNavigation().then(r => { + const el = document.getElementById('context-navigation'); + if (el) { + React.render(<SettingsNav {...options}/>, el); + } + return r; + }); + } +} diff --git a/server/sonar-web/src/main/js/apps/nav/component/component-nav-breadcrumbs.jsx b/server/sonar-web/src/main/js/main/nav/component/component-nav-breadcrumbs.js index d128d5ac002..d128d5ac002 100644 --- a/server/sonar-web/src/main/js/apps/nav/component/component-nav-breadcrumbs.jsx +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-breadcrumbs.js diff --git a/server/sonar-web/src/main/js/apps/nav/component/component-nav-favorite.jsx b/server/sonar-web/src/main/js/main/nav/component/component-nav-favorite.js index 8e2b8624abd..645dbac507c 100644 --- a/server/sonar-web/src/main/js/apps/nav/component/component-nav-favorite.jsx +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-favorite.js @@ -1,5 +1,5 @@ import React from 'react'; -import Favorite from 'components/shared/favorite'; +import Favorite from '../../../components/shared/favorite'; export default React.createClass({ render() { diff --git a/server/sonar-web/src/main/js/apps/nav/component/component-nav-menu.jsx b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js index b7db14235b9..b7db14235b9 100644 --- a/server/sonar-web/src/main/js/apps/nav/component/component-nav-menu.jsx +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js diff --git a/server/sonar-web/src/main/js/apps/nav/component/component-nav-meta.jsx b/server/sonar-web/src/main/js/main/nav/component/component-nav-meta.js index 45061352e56..45061352e56 100644 --- a/server/sonar-web/src/main/js/apps/nav/component/component-nav-meta.jsx +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-meta.js diff --git a/server/sonar-web/src/main/js/apps/nav/component/component-nav.jsx b/server/sonar-web/src/main/js/main/nav/component/component-nav.js index 917d54a6899..f4c6ee1c976 100644 --- a/server/sonar-web/src/main/js/apps/nav/component/component-nav.jsx +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav.js @@ -1,35 +1,22 @@ import $ from 'jquery'; import _ from 'underscore'; import React from 'react'; -import {STATUSES} from '../../background-tasks/constants'; +import {STATUSES} from '../../../apps/background-tasks/constants'; import {getTasksForComponent} from '../../../api/ce'; import ComponentNavFavorite from './component-nav-favorite'; import ComponentNavBreadcrumbs from './component-nav-breadcrumbs'; import ComponentNavMeta from './component-nav-meta'; import ComponentNavMenu from './component-nav-menu'; +import RecentHistory from './recent-history'; export default React.createClass({ - getInitialState() { - return { component: {}, conf: {} }; - }, - componentDidMount() { - this.loadDetails().then(this.loadStatus); - }, - - loadDetails() { - const url = `${window.baseUrl}/api/navigation/component`; - const data = { componentKey: this.props.componentKey }; - return $.get(url, data).done(r => { - this.setState({ - component: r, - conf: r.configuration || {} - }); - }); + this.loadStatus(); + this.populateRecentHistory(); }, - loadStatus(component) { - getTasksForComponent(component.uuid).done(r => { + loadStatus() { + getTasksForComponent(this.props.component.uuid).then(r => { this.setState({ isPending: !!_.findWhere(r.queue, { status: STATUSES.PENDING }), isInProgress: !!_.findWhere(r.queue, { status: STATUSES.IN_PROGRESS }), @@ -38,6 +25,13 @@ export default React.createClass({ }); }, + populateRecentHistory() { + let qualifier = _.last(this.props.component.breadcrumbs).qualifier; + if (['TRK', 'VW', 'DEV'].indexOf(qualifier) !== -1) { + RecentHistory.add(this.props.component.key, this.props.component.name, qualifier.toLowerCase()); + } + }, + initTooltips() { $('[data-toggle="tooltip"]', React.findDOMNode(this)).tooltip({ container: 'body', @@ -51,21 +45,22 @@ export default React.createClass({ return ( <div className="container"> <ComponentNavFavorite - component={this.state.component.key} - favorite={this.state.component.isFavorite} - canBeFavorite={this.state.component.canBeFavorite}/> + component={this.props.component.key} + favorite={this.props.component.isFavorite} + canBeFavorite={this.props.component.canBeFavorite}/> <ComponentNavBreadcrumbs - breadcrumbs={this.state.component.breadcrumbs}/> + breadcrumbs={this.props.component.breadcrumbs}/> <ComponentNavMeta + {...this.props} {...this.state} - version={this.state.component.version} - snapshotDate={this.state.component.snapshotDate}/> + version={this.props.component.version} + snapshotDate={this.props.component.snapshotDate}/> <ComponentNavMenu - component={this.state.component} - conf={this.state.conf}/> + component={this.props.component} + conf={this.props.conf}/> </div> ); } diff --git a/server/sonar-web/src/main/js/main/nav/component/recent-history.js b/server/sonar-web/src/main/js/main/nav/component/recent-history.js new file mode 100644 index 00000000000..0e5523ed25c --- /dev/null +++ b/server/sonar-web/src/main/js/main/nav/component/recent-history.js @@ -0,0 +1,41 @@ +import _ from 'underscore'; + +const STORAGE_KEY = 'sonar_recent_history'; +const HISTORY_LIMIT = 10; + +export default class RecentHistory { + static get () { + var history = localStorage.getItem(STORAGE_KEY); + if (history == null) { + history = []; + } else { + try { + history = JSON.parse(history); + } catch (e) { + RecentHistory.clear(); + history = []; + } + } + return history; + } + + static set (newHistory) { + localStorage.setItem(STORAGE_KEY, JSON.stringify(newHistory)); + } + + static clear () { + localStorage.removeItem(STORAGE_KEY); + } + + static add (componentKey, componentName, icon) { + var sonarHistory = RecentHistory.get(); + + if (componentKey) { + var newEntry = { key: componentKey, name: componentName, icon: icon }; + var newHistory = _.reject(sonarHistory, entry => entry.key === newEntry.key); + newHistory.unshift(newEntry); + newHistory = _.first(newHistory, HISTORY_LIMIT); + RecentHistory.set(newHistory); + } + } +} diff --git a/server/sonar-web/src/main/js/apps/nav/dashboard-name-mixin.jsx b/server/sonar-web/src/main/js/main/nav/dashboard-name-mixin.js index e8366f137c7..e8366f137c7 100644 --- a/server/sonar-web/src/main/js/apps/nav/dashboard-name-mixin.jsx +++ b/server/sonar-web/src/main/js/main/nav/dashboard-name-mixin.js diff --git a/server/sonar-web/src/main/js/apps/nav/global/global-nav-branding.jsx b/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js index 680654fc37e..680654fc37e 100644 --- a/server/sonar-web/src/main/js/apps/nav/global/global-nav-branding.jsx +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js diff --git a/server/sonar-web/src/main/js/apps/nav/global/global-nav-menu.jsx b/server/sonar-web/src/main/js/main/nav/global/global-nav-menu.js index 6249b8b11fb..6249b8b11fb 100644 --- a/server/sonar-web/src/main/js/apps/nav/global/global-nav-menu.jsx +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-menu.js diff --git a/server/sonar-web/src/main/js/apps/nav/global/global-nav-search.jsx b/server/sonar-web/src/main/js/main/nav/global/global-nav-search.js index 48fadbfe6eb..48fadbfe6eb 100644 --- a/server/sonar-web/src/main/js/apps/nav/global/global-nav-search.jsx +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-search.js diff --git a/server/sonar-web/src/main/js/apps/nav/global/global-nav-user.jsx b/server/sonar-web/src/main/js/main/nav/global/global-nav-user.js index d07c9a4d201..f5544b35613 100644 --- a/server/sonar-web/src/main/js/apps/nav/global/global-nav-user.jsx +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-user.js @@ -1,5 +1,6 @@ import React from 'react'; -import Avatar from 'components/shared/avatar'; +import Avatar from '../../../components/shared/avatar'; +import RecentHistory from '../component/recent-history'; export default React.createClass({ renderAuthenticated() { @@ -32,17 +33,13 @@ export default React.createClass({ handleLogin(e) { e.preventDefault(); const returnTo = window.location.pathname + window.location.search; - const loginUrl = `${window.baseUrl}/sessions/new?return_to=${encodeURIComponent(returnTo)}${window.location.hash}`; - window.location = loginUrl; + window.location = `${window.baseUrl}/sessions/new?return_to=${encodeURIComponent(returnTo)}${window.location.hash}`; }, handleLogout(e) { e.preventDefault(); - if (window.sonarRecentHistory) { - window.sonarRecentHistory.clear(); - } - const logoutUrl = `${window.baseUrl}/sessions/logout`; - window.location = logoutUrl; + RecentHistory.clear(); + window.location = `${window.baseUrl}/sessions/logout`; }, render() { diff --git a/server/sonar-web/src/main/js/apps/nav/global/global-nav.jsx b/server/sonar-web/src/main/js/main/nav/global/global-nav.js index ebbdc07db5c..80d38163e8a 100644 --- a/server/sonar-web/src/main/js/apps/nav/global/global-nav.jsx +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav.js @@ -1,4 +1,3 @@ -import $ from 'jquery'; import React from 'react'; import GlobalNavBranding from './global-nav-branding'; import GlobalNavMenu from './global-nav-menu'; @@ -7,12 +6,7 @@ import GlobalNavSearch from './global-nav-search'; import ShortcutsHelpView from './shortcuts-help-view'; export default React.createClass({ - getInitialState() { - return this.props; - }, - componentDidMount() { - this.loadGlobalNavDetails(); window.addEventListener('keypress', this.onKeyPress); }, @@ -20,12 +14,6 @@ export default React.createClass({ window.removeEventListener('keypress', this.onKeyPress); }, - loadGlobalNavDetails() { - $.get(`${window.baseUrl}/api/navigation/global`).done(r => { - this.setState(r); - }); - }, - onKeyPress(e) { var tagName = e.target.tagName; if (tagName !== 'INPUT' && tagName !== 'SELECT' && tagName !== 'TEXTAREA') { @@ -44,13 +32,13 @@ export default React.createClass({ render() { return ( <div className="container"> - <GlobalNavBranding {...this.state}/> + <GlobalNavBranding {...this.props}/> - <GlobalNavMenu {...this.state}/> + <GlobalNavMenu {...this.props}/> <ul className="nav navbar-nav navbar-right"> - <GlobalNavUser {...this.state}/> - <GlobalNavSearch {...this.state}/> + <GlobalNavUser {...this.props}/> + <GlobalNavSearch {...this.props}/> <li> <a onClick={this.openHelp} href="#"> <i className="icon-help navbar-icon"/> diff --git a/server/sonar-web/src/main/js/apps/nav/global/search-view.js b/server/sonar-web/src/main/js/main/nav/global/search-view.js index 12e170da60b..90cd6c065c1 100644 --- a/server/sonar-web/src/main/js/apps/nav/global/search-view.js +++ b/server/sonar-web/src/main/js/main/nav/global/search-view.js @@ -2,12 +2,15 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; -import SelectableCollectionView from 'components/common/selectable-collection-view'; -import '../templates'; +import SelectableCollectionView from '../../../components/common/selectable-collection-view'; +import SearchItemTemplate from '../templates/nav-search-item.hbs'; +import EmptySearchTemplate from '../templates/nav-search-empty.hbs'; +import SearchTemplate from '../templates/nav-search.hbs'; +import RecentHistory from '../component/recent-history'; var SearchItemView = Marionette.ItemView.extend({ tagName: 'li', - template: Templates['nav-search-item'], + template: SearchItemTemplate, select: function () { this.$el.addClass('active'); @@ -30,7 +33,7 @@ var SearchItemView = Marionette.ItemView.extend({ SearchEmptyView = Marionette.ItemView.extend({ tagName: 'li', - template: Templates['nav-search-empty'] + template: EmptySearchTemplate }), SearchResultsView = SelectableCollectionView.extend({ @@ -43,7 +46,7 @@ var SearchItemView = Marionette.ItemView.extend({ export default Marionette.LayoutView.extend({ className: 'navbar-search', tagName: 'form', - template: Templates['nav-search'], + template: SearchTemplate, regions: { resultsRegion: '.js-search-results' @@ -52,7 +55,7 @@ export default Marionette.LayoutView.extend({ events: { 'submit': 'onSubmit', 'keydown .js-search-input': 'onKeyDown', - 'keyup .js-search-input': 'debouncedOnKeyUp' + 'keyup .js-search-input': 'onKeyUp' }, initialize: function () { @@ -67,7 +70,7 @@ export default Marionette.LayoutView.extend({ this.resetResultsToDefault(); } this.resultsView = new SearchResultsView({ collection: this.results }); - this.debouncedOnKeyUp = _.debounce(this.onKeyUp, 400); + this.debouncedSearch = _.debounce(this.search, 250); this._bufferedValue = ''; }, @@ -107,7 +110,7 @@ export default Marionette.LayoutView.extend({ if (this.searchRequest != null && this.searchRequest.abort != null) { this.searchRequest.abort(); } - this.searchRequest = this.search(value); + this.searchRequest = this.debouncedSearch(value); }, onSubmit: function () { @@ -130,8 +133,8 @@ export default Marionette.LayoutView.extend({ }, resetResultsToDefault: function () { - var recentHistory = JSON.parse(localStorage.getItem('sonar_recent_history')), - history = (recentHistory || []).map(function (historyItem, index) { + var recentHistory = RecentHistory.get(), + history = recentHistory.map(function (historyItem, index) { var url = baseUrl + '/dashboard/index?id=' + encodeURIComponent(historyItem.key) + window.dashboardParameters(true); return { diff --git a/server/sonar-web/src/main/js/main/nav/global/shortcuts-help-view.js b/server/sonar-web/src/main/js/main/nav/global/shortcuts-help-view.js new file mode 100644 index 00000000000..8a430f7e430 --- /dev/null +++ b/server/sonar-web/src/main/js/main/nav/global/shortcuts-help-view.js @@ -0,0 +1,9 @@ +import ModalView from '../../../components/common/modals'; +import ShortcutsHelpTemplate from '../templates/nav-shortcuts-help.hbs'; + +export default ModalView.extend({ + className: 'modal modal-large', + template: ShortcutsHelpTemplate +}); + + diff --git a/server/sonar-web/src/main/js/apps/nav/links-mixin.jsx b/server/sonar-web/src/main/js/main/nav/links-mixin.js index 72f70966d93..72f70966d93 100644 --- a/server/sonar-web/src/main/js/apps/nav/links-mixin.jsx +++ b/server/sonar-web/src/main/js/main/nav/links-mixin.js diff --git a/server/sonar-web/src/main/js/apps/nav/settings/settings-nav.jsx b/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js index 87de9371fc3..0a5cccb3e88 100644 --- a/server/sonar-web/src/main/js/apps/nav/settings/settings-nav.jsx +++ b/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js @@ -5,18 +5,10 @@ import LinksMixin from '../links-mixin'; export default React.createClass({ mixins: [LinksMixin], - getInitialState() { + getDefaultProps() { return { extensions: [] }; }, - componentDidMount() { - this.loadDetails(); - }, - - loadDetails() { - $.get(`${window.baseUrl}/api/navigation/settings`).done(r => this.setState(r)); - }, - render() { return ( <div className="container"> @@ -33,7 +25,7 @@ export default React.createClass({ {this.renderLink('/settings', window.t('settings.page'))} {this.renderLink('/metrics', 'Custom Metrics')} {this.renderLink('/admin_dashboards', window.t('default_dashboards.page'))} - {this.state.extensions.map(e => this.renderLink(e.url, e.name))} + {this.props.extensions.map(e => this.renderLink(e.url, e.name))} </ul> </li> diff --git a/server/sonar-web/src/main/js/apps/nav/templates/nav-search-empty.hbs b/server/sonar-web/src/main/js/main/nav/templates/nav-search-empty.hbs index fb76e686612..fb76e686612 100644 --- a/server/sonar-web/src/main/js/apps/nav/templates/nav-search-empty.hbs +++ b/server/sonar-web/src/main/js/main/nav/templates/nav-search-empty.hbs diff --git a/server/sonar-web/src/main/js/apps/nav/templates/nav-search-item.hbs b/server/sonar-web/src/main/js/main/nav/templates/nav-search-item.hbs index 855b5175187..855b5175187 100644 --- a/server/sonar-web/src/main/js/apps/nav/templates/nav-search-item.hbs +++ b/server/sonar-web/src/main/js/main/nav/templates/nav-search-item.hbs diff --git a/server/sonar-web/src/main/js/apps/nav/templates/nav-search.hbs b/server/sonar-web/src/main/js/main/nav/templates/nav-search.hbs index 68e1f3ad168..68e1f3ad168 100644 --- a/server/sonar-web/src/main/js/apps/nav/templates/nav-search.hbs +++ b/server/sonar-web/src/main/js/main/nav/templates/nav-search.hbs diff --git a/server/sonar-web/src/main/js/apps/nav/templates/nav-shortcuts-help.hbs b/server/sonar-web/src/main/js/main/nav/templates/nav-shortcuts-help.hbs index 2ef8a865b8b..2ef8a865b8b 100644 --- a/server/sonar-web/src/main/js/apps/nav/templates/nav-shortcuts-help.hbs +++ b/server/sonar-web/src/main/js/main/nav/templates/nav-shortcuts-help.hbs diff --git a/server/sonar-web/src/main/js/main/processes.js b/server/sonar-web/src/main/js/main/processes.js new file mode 100644 index 00000000000..510fd42a338 --- /dev/null +++ b/server/sonar-web/src/main/js/main/processes.js @@ -0,0 +1,167 @@ +import $ from 'jquery'; +import Backbone from 'backbone'; +import Marionette from 'backbone.marionette'; + +var defaults = { + queue: {}, + timeout: 300, + fadeTimeout: 100 +}; + +var Process = Backbone.Model.extend({ + defaults: { + state: 'ok' + }, + + timeout: function () { + this.set({ + state: 'timeout', + message: 'Still Working...' + }); + }, + + finish: function (options) { + options = _.defaults(options || {}, { force: false }); + if (this.get('state') !== 'failed' || !!options.force) { + this.trigger('destroy', this, this.collection, options); + } + }, + + fail: function (message) { + var that = this, + msg = message || t('process.fail'); + if (msg === 'process.fail') { + // no translation + msg = 'An error happened, some parts of the page might not render correctly. ' + + 'Please contact the administrator if you keep on experiencing this error.'; + } + clearInterval(this.get('timer')); + this.set({ + state: 'failed', + message: msg + }); + this.set('state', 'failed'); + setTimeout(function () { + that.finish({ force: true }); + }, 5000); + } + }), + + Processes = Backbone.Collection.extend({ + model: Process + }), + + ProcessesView = Marionette.ItemView.extend({ + tagName: 'ul', + className: 'processes-container', + + collectionEvents: { + 'all': 'render' + }, + + render: function () { + var failed = this.collection.findWhere({ state: 'failed' }), + timeout = this.collection.findWhere({ state: 'timeout' }), + el; + this.$el.empty(); + if (failed != null) { + el = $('<li></li>') + .html(failed.get('message')) + .addClass('process-spinner process-spinner-failed shown'); + var close = $('<button></button>').html('<i class="icon-close"></i>').addClass('process-spinner-close'); + close.appendTo(el); + close.on('click', function () { + failed.finish({ force: true }); + }); + el.appendTo(this.$el); + } else if (timeout != null) { + el = $('<li></li>') + .html(timeout.get('message')) + .addClass('process-spinner shown'); + el.appendTo(this.$el); + } + return this; + } + }); + + +var processes = new Processes(), + processesView = new ProcessesView({ + collection: processes + }); + +/** + * Add background process + * @returns {number} + */ +function addBackgroundProcess () { + var uid = _.uniqueId('process'), + process = new Process({ + id: uid, + timer: setTimeout(function () { + process.timeout(); + }, defaults.timeout) + }); + processes.add(process); + return uid; +} + +/** + * Finish background process + * @param {number} uid + */ +function finishBackgroundProcess (uid) { + var process = processes.get(uid); + if (process != null) { + process.finish(); + } +} + +/** + * Fail background process + * @param {number} uid + * @param {string} message + */ +function failBackgroundProcess (uid, message) { + var process = processes.get(uid); + if (process != null) { + process.fail(message); + } +} + +/** + * Handle ajax error + * @param jqXHR + */ +function handleAjaxError (jqXHR) { + if (jqXHR.processId != null) { + var message = null; + if (jqXHR != null && jqXHR.responseJSON != null && jqXHR.responseJSON.errors != null) { + message = _.pluck(jqXHR.responseJSON.errors, 'msg').join('. '); + } + failBackgroundProcess(jqXHR.processId, message); + } +} + + +$.ajaxSetup({ + beforeSend: function (jqXHR) { + jqXHR.processId = addBackgroundProcess(); + }, + complete: function (jqXHR) { + if (jqXHR.processId != null) { + finishBackgroundProcess(jqXHR.processId); + } + }, + statusCode: { + 400: handleAjaxError, + 401: handleAjaxError, + 403: handleAjaxError, + 500: handleAjaxError + } +}); + + +$(function () { + processesView.render().$el.insertBefore('#footer'); +}); diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/widget.js b/server/sonar-web/src/main/js/widgets/issue-filter/widget.js index d5f9eab5643..c492ef5d2c0 100644 --- a/server/sonar-web/src/main/js/widgets/issue-filter/widget.js +++ b/server/sonar-web/src/main/js/widgets/issue-filter/widget.js @@ -1,336 +1,352 @@ -define(['./templates'], function () { +import $ from 'jquery'; +import _ from 'underscore'; +import Backbone from 'backbone'; +import Handlebars from 'hbsfy/runtime'; +import Marionette from 'backbone.marionette'; - var $ = jQuery, - FACET_LIMIT = 15, - defaultComparator = function (item) { - return -item.count; - }, - defaultFilter = function (item) { - var items = this.query[this.property]; - return items == null || - (items != null && items.split(',').indexOf(item.val) !== -1); - }, - defaultLabel = function (item) { - return item.val; - }, - defaultLink = function (item, property, query, index, items, mode) { - var criterion = {}; - criterion[property] = item.val; - var r = _.extend({}, query, criterion); - if (mode === 'debt') { - r.facetMode = 'debt'; +import Template from './templates/widget-issue-filter.hbs'; +import ActionPlansTemplate from './templates/widget-issue-filter-action-plans.hbs'; +import AssigneesTemplate from './templates/widget-issue-filter-assignees.hbs'; +import ResolutionsTemplate from './templates/widget-issue-filter-resolutions.hbs'; +import SeveritiesTemplate from './templates/widget-issue-filter-severities.hbs'; +import StatusesTemplate from './templates/widget-issue-filter-statuses.hbs'; + +import LimitPartial from './templates/_widget-issue-filter-limit.hbs'; +import TotalPartial from './templates/_widget-issue-filter-total.hbs'; + +import '../../helpers/handlebars-helpers'; + +var FACET_LIMIT = 15, + defaultComparator = function (item) { + return -item.count; + }, + defaultFilter = function (item) { + var items = this.query[this.property]; + return items == null || + (items != null && items.split(',').indexOf(item.val) !== -1); + }, + defaultLabel = function (item) { + return item.val; + }, + defaultLink = function (item, property, query, index, items, mode) { + var criterion = {}; + criterion[property] = item.val; + var r = _.extend({}, query, criterion); + if (mode === 'debt') { + r.facetMode = 'debt'; + } + if (r.componentKey != null) { + return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + + '#' + getQuery(_.omit(r, 'componentKey')); + } else { + return baseUrl + '/issues/search#' + getQuery(r); + } + }, + byDistributionConf = { + 'severities': { + template: SeveritiesTemplate, + comparator: function (item) { + var order = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO']; + return order.indexOf(item.val); } - if (r.componentKey != null) { - return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + - '#' + getQuery(_.omit(r, 'componentKey')); - } else { - return baseUrl + '/issues/search#' + getQuery(r); + }, + 'statuses': { + template: StatusesTemplate, + comparator: function (item) { + var order = ['OPEN', 'REOPENED', 'CONFIRMED', 'RESOLVED', 'CLOSED']; + return order.indexOf(item.val); + }, + filter: function (item) { + var unresolvedQuery = '' + this.query.resolved === 'false', + resolvedStatus = item.val === 'RESOLVED' || item.val === 'CLOSED'; + return !(unresolvedQuery && resolvedStatus); } }, - byDistributionConf = { - 'severities': { - template: 'widget-issue-filter-severities', - comparator: function (item) { - var order = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO']; - return order.indexOf(item.val); - } + 'resolutions': { + template: ResolutionsTemplate, + comparator: function (item) { + var order = ['', 'FALSE-POSITIVE', 'WONTFIX', 'FIXED', 'REMOVED']; + return order.indexOf(item.val); }, - 'statuses': { - template: 'widget-issue-filter-statuses', - comparator: function (item) { - var order = ['OPEN', 'REOPENED', 'CONFIRMED', 'RESOLVED', 'CLOSED']; - return order.indexOf(item.val); - }, - filter: function (item) { - var unresolvedQuery = '' + this.query.resolved === 'false', - resolvedStatus = item.val === 'RESOLVED' || item.val === 'CLOSED'; - return !(unresolvedQuery && resolvedStatus); + filter: function (item) { + if ('' + this.query.resolved === 'false') { + return item.val === ''; + } else { + return defaultFilter.call(this, item); } - }, - 'resolutions': { - template: 'widget-issue-filter-resolutions', - comparator: function (item) { - var order = ['', 'FALSE-POSITIVE', 'WONTFIX', 'FIXED', 'REMOVED']; - return order.indexOf(item.val); - }, - filter: function (item) { - if ('' + this.query.resolved === 'false') { - return item.val === ''; - } else { - return defaultFilter.call(this, item); + } + }, + 'rules': { + label: function (item, r) { + if (_.isArray(r.rules)) { + var rule = _.findWhere(r.rules, { key: item.val }); + if (rule != null) { + return rule.name; } } - }, - 'rules': { - label: function (item, r) { - if (_.isArray(r.rules)) { - var rule = _.findWhere(r.rules, { key: item.val }); - if (rule != null) { - return rule.name; - } + } + }, + 'projectUuids': { + label: function (item, r) { + if (_.isArray(r.projects)) { + var project = _.findWhere(r.projects, { uuid: item.val }); + if (project != null) { + return project.name; } } - }, - 'projectUuids': { - label: function (item, r) { - if (_.isArray(r.projects)) { - var project = _.findWhere(r.projects, { uuid: item.val }); - if (project != null) { - return project.name; - } + } + }, + 'assignees': { + template: AssigneesTemplate, + label: function (item, r) { + if (_.isArray(r.users)) { + var user = _.findWhere(r.users, { login: item.val }); + if (user != null) { + return user.name; } } }, - 'assignees': { - template: 'widget-issue-filter-assignees', - label: function (item, r) { - if (_.isArray(r.users)) { - var user = _.findWhere(r.users, { login: item.val }); - if (user != null) { - return user.name; - } - } - }, - filter: function (item) { - if ('' + this.query.assigned === 'false') { - return item.val === ''; - } else { - return defaultFilter.call(this, item); + filter: function (item) { + if ('' + this.query.assigned === 'false') { + return item.val === ''; + } else { + return defaultFilter.call(this, item); + } + } + }, + 'languages': { + label: function (item, r) { + if (_.isArray(r.languages)) { + var lang = _.findWhere(r.languages, { key: item.val }); + if (lang != null) { + return lang.name; } } - }, - 'languages': { - label: function (item, r) { - if (_.isArray(r.languages)) { - var lang = _.findWhere(r.languages, { key: item.val }); - if (lang != null) { - return lang.name; - } + } + }, + 'reporters': { + label: function (item, r) { + if (_.isArray(r.users)) { + var reporter = _.findWhere(r.users, { login: item.val }); + if (reporter != null) { + return reporter.name; } } - }, - 'reporters': { - label: function (item, r) { - if (_.isArray(r.users)) { - var reporter = _.findWhere(r.users, { login: item.val }); - if (reporter != null) { - return reporter.name; - } + } + }, + 'actionPlans': { + template: ActionPlansTemplate, + label: function (item, r) { + if (_.isArray(r.actionPlans)) { + var actionPlan = _.findWhere(r.actionPlans, { key: item.val }); + if (actionPlan != null) { + return actionPlan.name; } } }, - 'actionPlans': { - template: 'widget-issue-filter-action-plans', - label: function (item, r) { - if (_.isArray(r.actionPlans)) { - var actionPlan = _.findWhere(r.actionPlans, { key: item.val }); - if (actionPlan != null) { - return actionPlan.name; - } - } - }, - filter: function (item) { - if ('' + this.query.planned === 'false') { - return item.val === ''; - } else { - return defaultFilter.call(this, item); - } + filter: function (item) { + if ('' + this.query.planned === 'false') { + return item.val === ''; + } else { + return defaultFilter.call(this, item); } + } + }, + 'createdAt': { + comparator: function (item) { + return -moment(item.val).unix(); }, - 'createdAt': { - comparator: function (item) { - return -moment(item.val).unix(); - }, - label: function (item, r, items, index, query) { - var beginning = moment(item.val), - endDate = query.createdBefore != null ? moment(query.createdBefore) : moment(), - ending = index < items.length - 1 ? moment(items[index + 1].val).subtract(1, 'days') : endDate, - isSameDay = ending.diff(beginning, 'days') <= 1; - return beginning.format('LL') + (isSameDay ? '' : (' – ' + ending.format('LL'))); - }, - link: function (item, property, query, index, items, mode) { - var createdAfter = moment(item.val), - endDate = query.createdBefore != null ? moment(query.createdBefore) : moment(), - createdBefore = index < items.length - 1 ? moment(items[index + 1].val).subtract(1, 'days') : endDate, - isSameDay = createdBefore.diff(createdAfter, 'days') <= 1; - if (isSameDay) { - createdBefore.add(1, 'days'); - } - var r = _.extend({}, query, { - createdAfter: createdAfter.format('YYYY-MM-DD'), - createdBefore: createdBefore.format('YYYY-MM-DD') - }); - if (mode === 'debt') { - r.facetMode = 'debt'; - } - if (r.componentKey != null) { - return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + - '#' + getQuery(_.omit(r, 'componentKey')); - } else { - return baseUrl + '/issues/search#' + getQuery(r); - } + label: function (item, r, items, index, query) { + var beginning = moment(item.val), + endDate = query.createdBefore != null ? moment(query.createdBefore) : moment(), + ending = index < items.length - 1 ? moment(items[index + 1].val).subtract(1, 'days') : endDate, + isSameDay = ending.diff(beginning, 'days') <= 1; + return beginning.format('LL') + (isSameDay ? '' : (' – ' + ending.format('LL'))); + }, + link: function (item, property, query, index, items, mode) { + var createdAfter = moment(item.val), + endDate = query.createdBefore != null ? moment(query.createdBefore) : moment(), + createdBefore = index < items.length - 1 ? moment(items[index + 1].val).subtract(1, 'days') : endDate, + isSameDay = createdBefore.diff(createdAfter, 'days') <= 1; + if (isSameDay) { + createdBefore.add(1, 'days'); + } + var r = _.extend({}, query, { + createdAfter: createdAfter.format('YYYY-MM-DD'), + createdBefore: createdBefore.format('YYYY-MM-DD') + }); + if (mode === 'debt') { + r.facetMode = 'debt'; + } + if (r.componentKey != null) { + return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + + '#' + getQuery(_.omit(r, 'componentKey')); + } else { + return baseUrl + '/issues/search#' + getQuery(r); } } - }; + } + }; - function getQuery (query, separator) { - separator = separator || '|'; - var route = []; - _.forEach(query, function (value, property) { - route.push('' + property + '=' + encodeURIComponent(value)); - }); - return route.join(separator); +function getQuery (query, separator) { + separator = separator || '|'; + var route = []; + _.forEach(query, function (value, property) { + route.push('' + property + '=' + encodeURIComponent(value)); + }); + return route.join(separator); +} + +Handlebars.registerHelper('issueFilterItemLink', function (query, property, value, mode) { + var criterion = {}; + criterion[property] = value; + var r = _.extend({}, query, criterion); + if (mode === 'debt') { + r.facetMode = 'debt'; + } + if (r.componentKey != null) { + return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + + '#' + getQuery(_.omit(r, 'componentKey')); + } else { + return baseUrl + '/issues/search#' + getQuery(r); } +}); - Handlebars.registerHelper('issueFilterItemLink', function (query, property, value, mode) { - var criterion = {}; - criterion[property] = value; - var r = _.extend({}, query, criterion); - if (mode === 'debt') { - r.facetMode = 'debt'; - } - if (r.componentKey != null) { - return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + - '#' + getQuery(_.omit(r, 'componentKey')); - } else { - return baseUrl + '/issues/search#' + getQuery(r); - } - }); +Handlebars.registerHelper('issueFilterTotalLink', function (query, mode) { + var r = _.extend({}, query); + if (mode === 'debt') { + r.facetMode = 'debt'; + } + if (r.componentKey != null) { + return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + + '#' + getQuery(_.omit(r, 'componentKey')); + } else { + return baseUrl + '/issues/search#' + getQuery(r); + } +}); - Handlebars.registerHelper('issueFilterTotalLink', function (query, mode) { - var r = _.extend({}, query); - if (mode === 'debt') { - r.facetMode = 'debt'; - } - if (r.componentKey != null) { - return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) + - '#' + getQuery(_.omit(r, 'componentKey')); - } else { - return baseUrl + '/issues/search#' + getQuery(r); - } - }); +Handlebars.registerHelper('issueFilterValue', function (value, mode) { + var formatter = mode === 'debt' ? 'SHORT_WORK_DUR' : 'SHORT_INT'; + return window.formatMeasure(value, formatter); +}); - Handlebars.registerHelper('issueFilterValue', function (value, mode) { - var formatter = mode === 'debt' ? 'SHORT_WORK_DUR' : 'SHORT_INT'; - return window.formatMeasure(value, formatter); - }); +Handlebars.registerPartial('_widget-issue-filter-limit', LimitPartial); +Handlebars.registerPartial('_widget-issue-filter-total', TotalPartial); - return Marionette.ItemView.extend({ +export default Marionette.ItemView.extend({ - getTemplate: function () { - var template = this.conf != null && this.conf.template != null ? this.conf.template : 'widget-issue-filter'; - return Templates[template]; - }, + getTemplate: function () { + return this.conf != null && this.conf.template != null ? + this.conf.template : Template; + }, - initialize: function () { - this.shouldIgnorePeriod = false; - this.model = new Backbone.Model({ - query: this.options.query, - parsedQuery: this.getParsedQuery(), - property: this.options.distributionAxis - }); + initialize: function () { + this.shouldIgnorePeriod = false; + this.model = new Backbone.Model({ + query: this.options.query, + parsedQuery: this.getParsedQuery(), + property: this.options.distributionAxis + }); - // Ignore the period date if the filter contains any date criteria - // `this.shouldIgnorePeriod` is set in `this.getParsedQuery()` - if (!this.shouldIgnorePeriod) { - this.model.set({ periodDate: this.options.periodDate }); - } + // Ignore the period date if the filter contains any date criteria + // `this.shouldIgnorePeriod` is set in `this.getParsedQuery()` + if (!this.shouldIgnorePeriod) { + this.model.set({ periodDate: this.options.periodDate }); + } - this.listenTo(this.model, 'change', this.render); - this.conf = byDistributionConf[this.options.distributionAxis]; - this.query = this.getParsedQuery(); - this.requestIssues(); - }, + this.listenTo(this.model, 'change', this.render); + this.conf = byDistributionConf[this.options.distributionAxis]; + this.query = this.getParsedQuery(); + this.requestIssues(); + }, - getParsedQuery: function () { - var queryString = this.options.query || '', - query = {}; - queryString.split('|').forEach(function (criterionString) { - var criterion = criterionString.split('='); - if (criterion.length === 2) { - query[criterion[0]] = criterion[1]; - } - }); - if (this.options.componentKey != null) { - _.extend(query, { componentKey: this.options.componentKey }); + getParsedQuery: function () { + var queryString = this.options.query || '', + query = {}; + queryString.split('|').forEach(function (criterionString) { + var criterion = criterionString.split('='); + if (criterion.length === 2) { + query[criterion[0]] = criterion[1]; } - if (!this.hasDateFilter(query) && this.options.periodDate != null) { - _.extend(query, { createdAfter: this.options.periodDate }); - } else { - this.shouldIgnorePeriod = true; - } - return query; - }, - - hasDateFilter: function (query) { - var q = query || this.model.get('parsedQuery'); - return _.some(['createdAt', 'createdBefore', 'createdAfter', 'createdInLast'], function (p) { - return q[p] != null; - }); - }, + }); + if (this.options.componentKey != null) { + _.extend(query, { componentKey: this.options.componentKey }); + } + if (!this.hasDateFilter(query) && this.options.periodDate != null) { + _.extend(query, { createdAfter: this.options.periodDate }); + } else { + this.shouldIgnorePeriod = true; + } + return query; + }, - sortItems: function (items) { - var comparator = this.conf != null && this.conf.comparator != null ? this.conf.comparator : defaultComparator; - return _.sortBy(items, comparator); - }, + hasDateFilter: function (query) { + var q = query || this.model.get('parsedQuery'); + return _.some(['createdAt', 'createdBefore', 'createdAfter', 'createdInLast'], function (p) { + return q[p] != null; + }); + }, - filterItems: function (items) { - var filter = this.conf != null && this.conf.filter != null ? this.conf.filter : defaultFilter; - return _.filter(items, filter, { query: this.query, property: this.options.distributionAxis }); - }, + sortItems: function (items) { + var comparator = this.conf != null && this.conf.comparator != null ? this.conf.comparator : defaultComparator; + return _.sortBy(items, comparator); + }, - withLink: function (items) { - var link = this.conf != null && this.conf.link != null ? this.conf.link : defaultLink, - property = this.options.distributionAxis, - mode = this.options.displayMode, - query = this.model.get('parsedQuery'); - return items.map(function (item, index) { - return _.extend(item, { searchLink: link(item, property, query, index, items, mode) }); - }); - }, + filterItems: function (items) { + var filter = this.conf != null && this.conf.filter != null ? this.conf.filter : defaultFilter; + return _.filter(items, filter, { query: this.query, property: this.options.distributionAxis }); + }, - withLabels: function (items) { - var label = this.conf != null && this.conf.label != null ? this.conf.label : defaultLabel, - r = this.model.get('rawResponse'), - query = this.model.get('parsedQuery'); - return items.map(function (item, index) { - return _.extend(item, { label: label(item, r, items, index, query) }); - }); - }, + withLink: function (items) { + var link = this.conf != null && this.conf.link != null ? this.conf.link : defaultLink, + property = this.options.distributionAxis, + mode = this.options.displayMode, + query = this.model.get('parsedQuery'); + return items.map(function (item, index) { + return _.extend(item, { searchLink: link(item, property, query, index, items, mode) }); + }); + }, - requestIssues: function () { - var that = this, - facetMode = this.options.displayMode, - url = baseUrl + '/api/issues/search', - options = _.extend({}, this.query, { - ps: 1, - facets: this.options.distributionAxis, - facetMode: facetMode - }); - if (this.options.componentUuid != null) { - _.extend(options, { componentUuids: this.options.componentUuid }); - } - if (this.options.periodDate != null && !this.shouldIgnorePeriod) { - _.extend(options, { createdAfter: this.options.periodDate }); - } - return $.get(url, options).done(function (r) { - if (_.isArray(r.facets) && r.facets.length === 1) { - // save response object, but do not trigger repaint - that.model.set({ rawResponse: r }, { silent: true }); - var items = that.sortItems(that.withLabels(that.withLink(that.filterItems(r.facets[0].values)))); - that.model.set({ - items: items, - maxResultsReached: items.length >= FACET_LIMIT, - maxResults: items.length, - total: facetMode === 'debt' ? r.debtTotal : r.total - }); - } - }); - }, + withLabels: function (items) { + var label = this.conf != null && this.conf.label != null ? this.conf.label : defaultLabel, + r = this.model.get('rawResponse'), + query = this.model.get('parsedQuery'); + return items.map(function (item, index) { + return _.extend(item, { label: label(item, r, items, index, query) }); + }); + }, - serializeData: function () { - return _.extend(this._super(), { displayMode: this.options.displayMode }); + requestIssues: function () { + var that = this, + facetMode = this.options.displayMode, + url = baseUrl + '/api/issues/search', + options = _.extend({}, this.query, { + ps: 1, + facets: this.options.distributionAxis, + facetMode: facetMode + }); + if (this.options.componentUuid != null) { + _.extend(options, { componentUuids: this.options.componentUuid }); } - }); + if (this.options.periodDate != null && !this.shouldIgnorePeriod) { + _.extend(options, { createdAfter: this.options.periodDate }); + } + return $.get(url, options).done(function (r) { + if (_.isArray(r.facets) && r.facets.length === 1) { + // save response object, but do not trigger repaint + that.model.set({ rawResponse: r }, { silent: true }); + var items = that.sortItems(that.withLabels(that.withLink(that.filterItems(r.facets[0].values)))); + that.model.set({ + items: items, + maxResultsReached: items.length >= FACET_LIMIT, + maxResults: items.length, + total: facetMode === 'debt' ? r.debtTotal : r.total + }); + } + }); + }, + serializeData: function () { + return _.extend(this._super(), { displayMode: this.options.displayMode }); + } }); diff --git a/server/sonar-web/src/main/js/libs/widgets/base.js b/server/sonar-web/src/main/js/widgets/old/base.js index a54faa989c9..a54faa989c9 100644 --- a/server/sonar-web/src/main/js/libs/widgets/base.js +++ b/server/sonar-web/src/main/js/widgets/old/base.js diff --git a/server/sonar-web/src/main/js/libs/widgets/bubble-chart.js b/server/sonar-web/src/main/js/widgets/old/bubble-chart.js index 6452b33e093..6452b33e093 100644 --- a/server/sonar-web/src/main/js/libs/widgets/bubble-chart.js +++ b/server/sonar-web/src/main/js/widgets/old/bubble-chart.js diff --git a/server/sonar-web/src/main/js/libs/widgets/histogram.js b/server/sonar-web/src/main/js/widgets/old/histogram.js index df902e893f6..df902e893f6 100644 --- a/server/sonar-web/src/main/js/libs/widgets/histogram.js +++ b/server/sonar-web/src/main/js/widgets/old/histogram.js diff --git a/server/sonar-web/src/main/js/libs/widgets/pie-chart.js b/server/sonar-web/src/main/js/widgets/old/pie-chart.js index f3d81e7f639..f3d81e7f639 100644 --- a/server/sonar-web/src/main/js/libs/widgets/pie-chart.js +++ b/server/sonar-web/src/main/js/widgets/old/pie-chart.js diff --git a/server/sonar-web/src/main/js/libs/widgets/stack-area.js b/server/sonar-web/src/main/js/widgets/old/stack-area.js index 91997759d7f..91997759d7f 100644 --- a/server/sonar-web/src/main/js/libs/widgets/stack-area.js +++ b/server/sonar-web/src/main/js/widgets/old/stack-area.js diff --git a/server/sonar-web/src/main/js/libs/widgets/tag-cloud.js b/server/sonar-web/src/main/js/widgets/old/tag-cloud.js index d09f38b55bb..d09f38b55bb 100644 --- a/server/sonar-web/src/main/js/libs/widgets/tag-cloud.js +++ b/server/sonar-web/src/main/js/widgets/old/tag-cloud.js diff --git a/server/sonar-web/src/main/js/libs/widgets/timeline.js b/server/sonar-web/src/main/js/widgets/old/timeline.js index 1744ee6b17e..1744ee6b17e 100644 --- a/server/sonar-web/src/main/js/libs/widgets/timeline.js +++ b/server/sonar-web/src/main/js/widgets/old/timeline.js diff --git a/server/sonar-web/src/main/js/libs/widgets/treemap.js b/server/sonar-web/src/main/js/widgets/old/treemap.js index a4007265382..a4007265382 100644 --- a/server/sonar-web/src/main/js/libs/widgets/treemap.js +++ b/server/sonar-web/src/main/js/widgets/old/treemap.js diff --git a/server/sonar-web/src/main/js/libs/widgets/widget.js b/server/sonar-web/src/main/js/widgets/old/widget.js index 193725cbfd6..193725cbfd6 100644 --- a/server/sonar-web/src/main/js/libs/widgets/widget.js +++ b/server/sonar-web/src/main/js/widgets/old/widget.js diff --git a/server/sonar-web/src/main/js/libs/widgets/word-cloud.js b/server/sonar-web/src/main/js/widgets/old/word-cloud.js index 15fd7e9e96e..15fd7e9e96e 100644 --- a/server/sonar-web/src/main/js/libs/widgets/word-cloud.js +++ b/server/sonar-web/src/main/js/widgets/old/word-cloud.js diff --git a/server/sonar-web/src/main/js/widgets/widgets.js b/server/sonar-web/src/main/js/widgets/widgets.js new file mode 100644 index 00000000000..1a01c0c284a --- /dev/null +++ b/server/sonar-web/src/main/js/widgets/widgets.js @@ -0,0 +1,12 @@ +import './old/base'; + +import './old/bubble-chart'; +import './old/histogram'; +import './old/pie-chart'; +import './old/stack-area'; +import './old/tag-cloud'; +import './old/timeline'; +import './old/treemap'; +import './old/word-cloud'; + +import './old/widget'; diff --git a/server/sonar-web/src/main/less/components/page.less b/server/sonar-web/src/main/less/components/page.less index fd6f2f7f756..0e69b19f819 100644 --- a/server/sonar-web/src/main/less/components/page.less +++ b/server/sonar-web/src/main/less/components/page.less @@ -2,6 +2,11 @@ @import (reference) "../mixins"; @import (reference) "../init/links"; +body { + min-height: 100vh; + display: flex; + flex-direction: column; +} .page { .clearfix; @@ -14,8 +19,14 @@ } .page-wrapper { - min-height: ~"calc(100vh - @{pageFooterHeight})"; - .box-sizing(border-box); + box-sizing: border-box; + flex: 1; +} + +.page-wrapper-simple { + display: flex; + justify-content: center; + align-items: center; } .page-wrapper-global { @@ -27,12 +38,10 @@ } .page-simple { - max-width: 400px; - margin: 10vh auto; + width: 400px; padding: 40px; border: 1px solid @barBorderColor; background-color: #fff; - text-align: left; } .page-header { @@ -76,22 +85,4 @@ a { .link-base-color; } -} - -@supports (display: flex) { - body { - min-height: 100vh; - display: flex; - flex-flow: column nowrap; - justify-content: space-between; - } - - .page-wrapper { - flex: 1; - min-height: 0 !important; - } - - .page-simple { - margin-bottom: 0; - } -} +}
\ No newline at end of file diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb index b9e16dc489d..bbc906a0f3d 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb @@ -69,9 +69,5 @@ </div> <% content_for :extra_script do %> - <script> - require(['apps/account/app'], function (App) { - App.start(); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/account.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb index 52765748951..62aedd51b29 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb @@ -1,7 +1,6 @@ <% content_for :extra_script do %> <script> - require(['apps/api-documentation/app'], function (App) { - App.start({ el: '#content', urlRoot: baseUrl + '/api_documentation' }); - }); + window.sonarqube.urlRoot = window.baseUrl + '/api_documentation'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/api-documentation.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/background_tasks/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/background_tasks/index.html.erb index 5a05fdc08dc..18cce998a6f 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/background_tasks/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/background_tasks/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/background-tasks/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/background-tasks.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/index.html.erb index 804ed54db8f..7d421c9d66d 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/coding-rules/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/coding-rules.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/component/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/component/index.html.erb index 5f6a94409f2..27fe285b3d7 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/component/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/component/index.html.erb @@ -1,16 +1,15 @@ <% content_for :extra_script do %> <script type="text/javascript"> (function () { - var file = { + window.sonarqube.el = '#body'; + window.sonarqube.file = { uuid: '<%= @resource.uuid -%>', key: '<%= @resource.key -%>' <% if @line %>, line: <%= @line -%><% end %> }; - require(['apps/source-viewer/app'], function (App) { - App.start({ el: '#body', file: file }) - }); })(); </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/source-viewer.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/component_issues/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/component_issues/index.html.erb index d3a46e6eeda..b2b853e610b 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/component_issues/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/component_issues/index.html.erb @@ -1,15 +1,13 @@ <% content_for :extra_script do %> <script> (function () { - var config = { + window.sonarqube.config = { resource: '<%= escape_javascript @resource.uuid -%>', resourceQualifier: '<%= escape_javascript @resource.qualifier -%>', resourceName: '<%= escape_javascript @resource.name -%>', periodDate: <% if @period %>'<%= escape_javascript @snapshot.period_datetime(@period) -%>'<% else %>null<% end %> }; - require(['apps/issues/app-context'], function (App) { - App.start({ el: '#content', config: config }); - }); })(); </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/component-issues.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/custom_measures/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/custom_measures/index.html.erb index 54ba4fcdac4..8a7e139e257 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/custom_measures/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/custom_measures/index.html.erb @@ -1,7 +1,6 @@ <% content_for :extra_script do %> <script> - require(['apps/custom-measures/app'], function (App) { - App.start({ el: '#content', projectId: '<%= @resource.uuid -%>' }); - }); + window.sonarqube.projectId = '<%= @resource.uuid -%>'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/custom-measures.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb index 8a798237370..48b2288e5fa 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb @@ -1,3 +1,8 @@ +<% content_for :script do %> + <script src="<%= ApplicationController.root_context -%>/js/bundles/dashboard.js?v=<%= sonar_version -%>"></script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/widgets.js?v=<%= sonar_version -%>"></script> +<% end %> + <div class="page" id="dashboard"> <%= render :partial => 'header', :locals => {:back => true} %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb index 2f1ea47272e..132fe9ded98 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb @@ -1,3 +1,9 @@ +<% content_for :script do %> + <script src="<%= ApplicationController.root_context -%>/js/bundles/dashboard.js?v=<%= sonar_version -%>"></script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/widgets.js?v=<%= sonar_version -%>"></script> +<% end %> + + <div class="page" id="dashboard"> <% if @resource -%> <span class="hidden" id="is-project-dashboard"> </span> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb index 23e483f5746..72416ed82eb 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb @@ -7,15 +7,14 @@ (function () { jQuery('.navbar-context').remove(); jQuery('.page-wrapper-context').addClass('page-wrapper-global').removeClass('page-wrapper-context'); - var file = { + window.sonarqube.el = '#source-viewer'; + window.sonarqube.file = { uuid: '<%= @resource.uuid -%>', key: '<%= @resource.key -%>' }; - require(['apps/source-viewer/app'], function (App) { - App.start({ el: '#source-viewer', file: file }) - }); })(); </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/source-viewer.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb index f5386bde638..e8fb8f0d03c 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb @@ -135,8 +135,7 @@ <% content_for :extra_script do %> <script> - require(['apps/drilldown/app'], function (App) { - App.start({ el: '#source-viewer' }); - }); + window.sonarqube.el = '#source-viewer'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/drilldown.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/groups/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/groups/index.html.erb index ecf82ae97bb..e3bee63260c 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/groups/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/groups/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/groups/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/groups.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/issues/search.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/issues/search.html.erb index 0c105bbd322..b1baf27f96c 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/issues/search.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/issues/search.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/issues/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/issues.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb index 76d72a88776..c5dbab53411 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb @@ -16,6 +16,7 @@ </script> <% end %> +<script src="<%= ApplicationController.root_context -%>/js/bundles/main.js?v=<%= sonar_version -%>"></script> <%= yield :extra_script -%> </body> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb index 8e16db96445..47493d9f646 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb @@ -43,18 +43,10 @@ $j(document).ready(function () {$j('.open-modal').modal()}); moment.lang(window.pageLang); numeral.language(window.pageLang); - requirejs.config({ - baseUrl: baseUrl + '/js', - urlArgs: 'v=<%= sonar_version -%>', - paths: { - 'react': 'libs/third-party/react-with-addons', - 'underscore': 'libs/third-party/shim/underscore-shim', - 'jquery': 'libs/third-party/shim/jquery-shim', - 'backbone': 'libs/third-party/shim/backbone-shim', - 'backbone.marionette': 'libs/third-party/shim/marionette-shim', - 'moment': 'libs/third-party/shim/moment-shim' - } - }); + </script> + <script> + window.sonarqube = {}; + window.sonarqube.el = '#content'; </script> <%= yield :script -%> </head> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar.html.erb index dd25b284589..88a863b31d4 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar.html.erb @@ -1,5 +1,3 @@ -<%= render 'layouts/recent_history' -%> - <% selected_section = controller.class::SECTION if defined?(controller.class::SECTION) if selected_section == Navigation::SECTION_RESOURCE && !@project && !@resource @@ -11,19 +9,15 @@ <script> (function () { - var options = {}; <% if selected_section == Navigation::SECTION_RESOURCE %> - options.space = 'component'; - options.componentKey = '<%= escape_javascript @project.key -%>'; + window.sonarqube.space = 'component'; + window.sonarqube.componentKey = '<%= escape_javascript @project.key -%>'; <% end %> <% if selected_section == Navigation::SECTION_CONFIGURATION %> - options.space = 'settings'; + window.sonarqube.space = 'settings'; <% end %> window.SS.isUserAdmin = <%= current_user && is_admin? ? 'true' : 'false' -%>; - require(['apps/nav/app'], function (App) { - App.start(options); - }); })(); </script> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_recent_history.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_recent_history.html.erb deleted file mode 100644 index 51b81a44d3f..00000000000 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_recent_history.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -<script> - var sonarRecentHistory = new Sonar.RecentHistory(); - <% if @resource && Project.root_qualifiers.include?(@resource.qualifier) %> - sonarRecentHistory.add( - '<%= escape_javascript(h(@resource.key)) -%>', - '<%= escape_javascript(h(@resource.name)) -%>', - '<%= escape_javascript @resource.qualifier.downcase -%>'); - <% end %> -</script> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/nonav.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/nonav.html.erb index 752b5eb24ff..fa874372628 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/nonav.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/nonav.html.erb @@ -10,11 +10,9 @@ </div> </nav> -<div> - <div id="bd"> - <div id="nonav" class="page-simple"> - <div id="content"><%= yield %></div> - </div> +<div id="bd" class="page-wrapper page-wrapper-simple"> + <div id="nonav" class="page-simple"> + <div id="content"><%= yield %></div> </div> </div> @@ -37,6 +35,7 @@ })(window.jQuery); </script> +<script src="<%= ApplicationController.root_context -%>/js/bundles/main.js?v=<%= sonar_version -%>"></script> <%= yield :extra_script -%> </body></html> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/maintenance/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/maintenance/index.html.erb index 19d88d4c4f6..346aa13f860 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/maintenance/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/maintenance/index.html.erb @@ -1,8 +1,7 @@ <% content_for :extra_script do %> <script> - require(['apps/maintenance/app'], function (App) { - App.start({ el: '#content', setup: false }); - }); + window.sonarqube.setup = false; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/maintenance.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/markdown/help.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/markdown/help.html.erb index 662ff4366d1..6f667bc45cd 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/markdown/help.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/markdown/help.html.erb @@ -1,6 +1,8 @@ <div id="markdown-full-help"></div> -<script> - require(['apps/markdown/app'], function (App) { - App.start({ el: '#markdown-full-help' }); - }); -</script> + +<% content_for :extra_script do %> + <script> + window.sonarqube.el = '#markdown-full-help'; + </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/markdown.js?v=<%= sonar_version -%>"></script> +<% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/measures/search.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/measures/search.html.erb index f731ded1dc9..f9cedf7d9ac 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/measures/search.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/measures/search.html.erb @@ -125,9 +125,5 @@ ]; </script> - <script> - require(['apps/measures/app'], function (App) { - App.start(); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/measures.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/metrics/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/metrics/index.html.erb index a4c68b18805..5a8e0641d97 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/metrics/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/metrics/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/metrics/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/metrics.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/permission_templates/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/permission_templates/index.html.erb index caf72cbf4e4..fb97f387c59 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/permission_templates/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/permission_templates/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/permission-templates/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/permission-templates.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb index 9f4ee19f8cc..3c52faf87d9 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb @@ -1,7 +1,6 @@ <% content_for :extra_script do %> <script> - require(['apps/quality-profiles/app'], function (App) { - App.start({ el: '#content', urlRoot: baseUrl + '/profiles' }); - }); + window.sonarqube.urlRoot = baseUrl + '/profiles'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/quality-profiles.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/background_tasks.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/background_tasks.html.erb index 43ebdf92fc1..ba6d27a4da6 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/background_tasks.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/background_tasks.html.erb @@ -1,7 +1,6 @@ <% content_for :extra_script do %> <script> - require(['apps/background-tasks/app'], function (App) { - App.start({ el: '#content', componentId: '<%= @project.uuid -%>' }); - }); + window.sonarqube.componentId = '<%= @project.uuid -%>'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/background-tasks.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb index f4288382090..2ffe436320a 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb @@ -1,7 +1,6 @@ <% content_for :extra_script do %> <script> - require(['apps/project-permissions/app'], function (App) { - App.start({ el: '#content', componentId: '<%= @project.uuid -%>' }); - }); + window.sonarqube.componentId = '<%= @project.uuid -%>'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/project-permissions.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/projects/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/projects/index.html.erb index 0ccfdf38a4e..e9c8ffd9ad8 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/projects/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/projects/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/projects/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/projects.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb index 9563962a02a..54b071e6e5a 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb @@ -1,7 +1,6 @@ <% content_for :extra_script do %> <script> - require(['apps/quality-gates/app'], function (App) { - App.start({ el: '#content', urlRoot: baseUrl + '/quality_gates' }); - }); + window.sonarqube.urlRoot = baseUrl + '/quality_gates'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/quality-gates.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/global.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/global.html.erb index 99a961b12b3..3c79bb2feca 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/global.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/global.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/global-permissions/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/global-permissions.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb index db45ae6982e..df0126ffd09 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/project-permissions/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/project-permissions.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/index.html.erb index d3dacd3e7f3..a06263ce445 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/index.html.erb @@ -1,8 +1,7 @@ <% content_for :extra_script do %> <script> - require(['apps/maintenance/app'], function (App) { - App.start({ el: '#content', setup: true }); - }); + window.sonarqube.setup = true; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/maintenance.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb index 9b3301cde48..f80abacd882 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/index.html.erb @@ -17,8 +17,6 @@ <% content_for :extra_script do %> - <script> - require(['apps/system/app']); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/system.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/updatecenter/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/updatecenter/index.html.erb index 80cb9c67be0..21e4db24e3a 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/updatecenter/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/updatecenter/index.html.erb @@ -1,7 +1,7 @@ <% content_for :extra_script do %> <script> - require(['apps/update-center/app'], function (App) { - App.start({ el: '#content', urlRoot: baseUrl + '/updatecenter' }); - }); + window.sonarqube.urlRoot = baseUrl + '/updatecenter'; </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/update-center.js?v=<%= sonar_version -%>"></script> <% end %> + diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/users/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/users/index.html.erb index 8b2ce266a10..56d012090af 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/users/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/users/index.html.erb @@ -1,7 +1,3 @@ <% content_for :extra_script do %> - <script> - require(['apps/users/app'], function (App) { - App.start({ el: '#content' }); - }); - </script> + <script src="<%= ApplicationController.root_context -%>/js/bundles/users.js?v=<%= sonar_version -%>"></script> <% end %> diff --git a/server/sonar-web/test/helpers/test-page.js b/server/sonar-web/test/helpers/test-page.js index f9c7d5a5456..f0fbbd5f238 100644 --- a/server/sonar-web/test/helpers/test-page.js +++ b/server/sonar-web/test/helpers/test-page.js @@ -169,15 +169,26 @@ define(function (require) { }); }; + Command.prototype.startAppBrowserify = function (app) { + return new this.constructor(this, function () { + return this.parent + .execute(function (app) { + var appScript = document.createElement('script'); + appScript.setAttribute('src', '../../src/main/webapp/js/bundles/' + app + '.js'); + document.body.appendChild(appScript); + }, [app]) + .sleep(1000); + }); + }; + Command.prototype.open = function (hash) { - var url = 'test/medium/base.html?' + Date.now(); + var url = 'test/medium/base.html'; if (hash) { url += hash; } return new this.constructor(this, function () { return this.parent .get(require.toUrl(url)) - .mockFromString('/api/l10n/index', '{}') .checkElementExist('#content'); }); }; diff --git a/server/sonar-web/test/intern.js b/server/sonar-web/test/intern.js index 20e008b1e2a..7fab8d5d7b1 100644 --- a/server/sonar-web/test/intern.js +++ b/server/sonar-web/test/intern.js @@ -4,7 +4,7 @@ define(['intern'], function (intern) { tunnel = useBrowserStack ? 'BrowserStackTunnel' : 'NullTunnel'; return { - excludeInstrumentation: /(((test|third-party|node_modules)\/)|(templates.js$))/, + excludeInstrumentation: true, defaultTimeout: 60 * 1000, @@ -19,7 +19,6 @@ define(['intern'], function (intern) { functionalSuites: [ 'test/medium/api-documentation.spec', 'test/medium/coding-rules.spec', - 'test/medium/computation.spec', 'test/medium/custom-measures.spec', 'test/medium/global-permissions.spec', 'test/medium/groups.spec', diff --git a/server/sonar-web/test/medium/api-documentation.spec.js b/server/sonar-web/test/medium/api-documentation.spec.js index aa1de98b69b..b0ed5b8331c 100644 --- a/server/sonar-web/test/medium/api-documentation.spec.js +++ b/server/sonar-web/test/medium/api-documentation.spec.js @@ -7,7 +7,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/webservices/list', 'api-documentation/list.json') - .startApp('api-documentation', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('api-documentation') .checkElementExist('.api-documentation-results .list-group-item') .checkElementCount('.api-documentation-results .list-group-item', 2) .checkElementInclude('.list-group-item[data-path="api/public"] .list-group-item-heading', 'api/public') @@ -30,7 +30,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/webservices/list', 'api-documentation/list.json') - .startApp('api-documentation', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('api-documentation') .checkElementExist('.api-documentation-results .list-group-item') .clickElement('.list-group-item[data-path="api/public"]') .checkElementCount('.search-navigator-workspace-details .panel', 2) @@ -50,7 +50,7 @@ define(function (require) { .open() .mockFromFile('/api/webservices/list', 'api-documentation/list.json') .mockFromFile('/api/webservices/response_example', 'api-documentation/response-example.json') - .startApp('api-documentation', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('api-documentation') .checkElementExist('.api-documentation-results .list-group-item') .clickElement('.list-group-item[data-path="api/public"]') .clickElement('.panel[data-action="undo"] .js-show-response-example') @@ -58,24 +58,24 @@ define(function (require) { .checkElementInclude('.panel[data-action="undo"] pre', 'leia.organa'); }); - bdd.it('should open WS permalink', function () { - return this.remote - .open('#api/public') - .mockFromFile('/api/webservices/list', 'api-documentation/list.json') - .startApp('api-documentation', { urlRoot: '/test/medium/base.html' }) - .checkElementExist('.api-documentation-results .list-group-item') - .checkElementExist('.panel[data-web-service="api/public"]') - .checkElementCount('.panel[data-web-service="api/public"]', 2); - }); - - bdd.it('should open action permalink', function () { - return this.remote - .open('#api/internal/move') - .mockFromFile('/api/webservices/list', 'api-documentation/list.json') - .startApp('api-documentation', { urlRoot: '/test/medium/base.html' }) - .checkElementExist('.api-documentation-results .list-group-item') - .checkElementExist('.panel[data-web-service="api/internal"]') - .checkElementExist('.panel[data-web-service="api/internal"][data-action="move"]'); - }); + //bdd.it('should open WS permalink', function () { + // return this.remote + // .open('#api/public') + // .mockFromFile('/api/webservices/list', 'api-documentation/list.json') + // .startAppBrowserify('api-documentation') + // .checkElementExist('.api-documentation-results .list-group-item') + // .checkElementExist('.panel[data-web-service="api/public"]') + // .checkElementCount('.panel[data-web-service="api/public"]', 2); + //}); + // + //bdd.it('should open action permalink', function () { + // return this.remote + // .open('#api/internal/move') + // .mockFromFile('/api/webservices/list', 'api-documentation/list.json') + // .startAppBrowserify('api-documentation') + // .checkElementExist('.api-documentation-results .list-group-item') + // .checkElementExist('.panel[data-web-service="api/internal"]') + // .checkElementExist('.panel[data-web-service="api/internal"][data-action="move"]'); + //}); }); }); diff --git a/server/sonar-web/test/medium/base.html b/server/sonar-web/test/medium/base.html index 3586627281e..aca0d14ad6a 100644 --- a/server/sonar-web/test/medium/base.html +++ b/server/sonar-web/test/medium/base.html @@ -1,84 +1,43 @@ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <link href="../../build/css/sonar.css" rel="stylesheet" media="all"> - <script src="../../build/js/libs/translate.js"></script> - <script src="../../build/js/libs/third-party/jquery.js"></script> - <script src="../../build/js/libs/third-party/jquery-ui.js"></script> - <script src="../../build/js/libs/third-party/d3.js"></script> - <script src="../../build/js/libs/third-party/latinize.js"></script> - <script src="../../build/js/libs/third-party/underscore.js"></script> - <script src="../../build/js/libs/third-party/backbone.js"></script> - <script src="../../build/js/libs/third-party/backbone-super.js"></script> - <script src="../../build/js/libs/third-party/backbone.marionette.js"></script> - <script src="../../build/js/libs/third-party/handlebars.js"></script> - <script src="../../build/js/libs/third-party/select2.js"></script> - <script src="../../build/js/libs/third-party/keymaster.js"></script> - <script src="../../build/js/libs/third-party/moment.js"></script> - <script src="../../build/js/libs/third-party/numeral.js"></script> - <script src="../../build/js/libs/third-party/numeral-languages.js"></script> - <script src="../../build/js/libs/third-party/bootstrap/tooltip.js"></script> - <script src="../../build/js/libs/third-party/bootstrap/dropdown.js"></script> - <script src="../../build/js/libs/third-party/md5.js"></script> - <script src="../../build/js/libs/select2-jquery-ui-fix.js"></script> - <script src="../../build/js/libs/widgets/base.js"></script> - <script src="../../build/js/libs/widgets/widget.js"></script> - <script src="../../build/js/libs/widgets/bubble-chart.js"></script> - <script src="../../build/js/libs/widgets/timeline.js"></script> - <script src="../../build/js/libs/widgets/stack-area.js"></script> - <script src="../../build/js/libs/widgets/pie-chart.js"></script> - <script src="../../build/js/libs/widgets/histogram.js"></script> - <script src="../../build/js/libs/widgets/word-cloud.js"></script> - <script src="../../build/js/libs/widgets/tag-cloud.js"></script> - <script src="../../build/js/libs/widgets/treemap.js"></script> - <script src="../../build/js/libs/graphics/pie-chart.js"></script> - <script src="../../build/js/libs/graphics/barchart.js"></script> - <script src="../../build/js/libs/sortable.js"></script> - <script src="../../build/js/libs/inputs.js"></script> - <script src="../../build/js/libs/dialogs.js"></script> - <script src="../../build/js/libs/processes.js"></script> - <script src="../../build/js/libs/jquery-isolated-scroll.js"></script> - <script src="../../build/js/libs/handlebars-extensions.js"></script> - <script src="../../build/js/libs/application.js"></script> - <script src="../../build/js/libs/csv.js"></script> - <script src="../../build/js/libs/dashboard.js"></script> - <script src="../../build/js/libs/recent-history.js"></script> - <script src="../../build/js/libs/third-party/jquery.mockjax.js"></script> - <script src="../../build/js/libs/third-party/require.js"></script> - <script>var baseUrl = ''; - var $j = jQuery.noConflict(); - window.suppressTranslationWarnings = true; - jQuery.mockjaxSettings.contentType = 'text/json'; - jQuery.mockjaxSettings.responseTime = 50; - jQuery(document).ready(function () { - $j('.open-modal').modal(); - }); - window.SS = { - hoursInDay: 8, - user: '', - userName: '', - userEmail: '', - lf: { - enableGravatar: false, - gravatarServerUrl: '' - }, - updateCenterActive: true - }; - </script> + <link href="../../src/main/webapp/css/sonar.css" rel="stylesheet" media="all"> + <script src="../../src/main/webapp/js/sonar.js"></script> + <script src="../../src/main/js/libs/third-party/jquery.mockjax.js"></script> <script> - requirejs.config({ - baseUrl: baseUrl + '../../build/js', - paths: { - 'react': 'libs/third-party/react-with-addons', - 'underscore': 'libs/third-party/shim/underscore-shim', - 'jquery': 'libs/third-party/shim/jquery-shim', - 'backbone': 'libs/third-party/shim/backbone-shim', - 'backbone.marionette': 'libs/third-party/shim/marionette-shim' - } + var baseUrl = ''; + var $j = jQuery.noConflict(); + window.suppressTranslationWarnings = true; + jQuery.mockjaxSettings.contentType = 'text/json'; + jQuery.mockjaxSettings.responseTime = 50; + jQuery(document).ready(function () { + $j('.open-modal').modal(); }); + window.SS = { + hoursInDay: 8, + user: '', + userName: '', + userEmail: '', + lf: { + enableGravatar: false, + gravatarServerUrl: '' + }, + updateCenterActive: true + }; + </script> + <script> + window.sonarqube = {}; + window.sonarqube.el = '#content'; + window.sonarqube.urlRoot = '/test/medium/base.html'; + window.sonarqube.projectId = 'eb294572-a6a4-43cf-acc2-33c2fe37c02e' + window.sonarqube.file = { uuid: 'uuid', key: 'key' }; + </script> + <script> + jQuery.mockjax({ url: '/api/l10n/index', responseText:'{}' }); </script> </head> <body> <div id="content"></div> +<script src="../../src/main/webapp/js/bundles/main.js"></script> </body> </html> diff --git a/server/sonar-web/test/medium/coding-rules.spec.js b/server/sonar-web/test/medium/coding-rules.spec.js index 849496b6ff6..ac363c87c2b 100644 --- a/server/sonar-web/test/medium/coding-rules.spec.js +++ b/server/sonar-web/test/medium/coding-rules.spec.js @@ -11,7 +11,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search-no-available-profiles.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show-no-available-profiles.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-detail-header') @@ -26,7 +26,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search-profile-facet.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', '609') .clickElement('[data-property="qprofile"] .js-facet-toggle') @@ -56,7 +56,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', '609') .clearMocks() @@ -78,7 +78,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-detail-header') @@ -93,7 +93,7 @@ define(function (require) { .mockFromFile('/api/rules/show', 'coding-rules-spec/show-activate-profile.json') .mockFromString('/api/qualityprofiles/activate_rule', '{}') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-detail-header') @@ -117,7 +117,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search-create-custom-rules.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clearMocks() .mockFromFile('/api/rules/show', 'coding-rules-spec/show-create-custom-rules.json') @@ -144,7 +144,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search-create-custom-rules.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .forceJSON() .checkElementExist('.coding-rule.selected') .clearMocks() @@ -179,7 +179,7 @@ define(function (require) { .mockFromFile('/api/rules/create', 'coding-rules-spec/show-create-manual-rule.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show-create-manual-rule.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .forceJSON() .checkElementExist('.js-create-manual-rule') .clickElement('.js-create-manual-rule') @@ -201,7 +201,7 @@ define(function (require) { .mockFromFile('/api/rules/create', 'coding-rules-spec/show-create-manual-rule.json', { status: 409 }) .mockFromFile('/api/rules/show', 'coding-rules-spec/show-create-manual-rule.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .forceJSON() .checkElementExist('.js-create-manual-rule') .clickElement('.js-create-manual-rule') @@ -231,7 +231,7 @@ define(function (require) { .mockFromFile('/api/rules/show', 'coding-rules-spec/show-delete-custom-rule.json') .mockFromString('/api/rules/delete', '{}') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('#coding-rules-detail-custom-rules .coding-rules-detail-list-name') @@ -248,7 +248,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search-delete-manual-rule-before.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show-delete-manual-rule.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .forceJSON() .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') @@ -271,7 +271,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search-show-cutsom-rule.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show-show-cutsom-rule.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('#coding-rules-detail-custom-rules .coding-rules-detail-list-name') @@ -286,7 +286,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search-deprecated.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .checkElementInclude('.coding-rule.selected', 'DEPRECATED'); }); @@ -298,7 +298,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search-show-details.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show-show-details.json') .mockFromString('/api/issues/search', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-detail-header') @@ -333,7 +333,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search-empty.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.search-navigator-facet-box') .checkElementNotExist('.coding-rule') .checkElementInclude('#coding-rules-total', 0) @@ -345,7 +345,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.search-navigator-facet-box') .checkElementCount('.search-navigator-facet-box', 13); }); @@ -355,7 +355,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .checkElementInclude('.coding-rule.selected', 'Values passed to SQL commands should be sanitized') .checkElementInclude('.coding-rule.selected', 'Java') @@ -373,7 +373,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show.json') .mockFromFile('/api/issues/search', 'coding-rules-spec/issues-search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-most-violated-projects') @@ -389,7 +389,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementCount('.coding-rule', 25) .checkElementInclude('.coding-rule', 'Values passed to SQL commands should be sanitized') @@ -403,7 +403,7 @@ define(function (require) { .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-detail-header') @@ -424,7 +424,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected .js-rule-filter') .checkElementInclude('#coding-rules-total', '609') .clickElement('.js-rule-filter') @@ -441,7 +441,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', '609') .checkElementExist('.search-navigator-facet-box-forbidden[data-property="active_severities"]') @@ -475,7 +475,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', '609') .clearMocks() @@ -496,7 +496,7 @@ define(function (require) { .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromString('/api/qualityprofiles/activate_rules', '{ "succeeded": 225 }') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .forceJSON() .checkElementExist('.coding-rule') .checkElementExist('.js-bulk-change') @@ -521,7 +521,7 @@ define(function (require) { .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromString('/api/qualityprofiles/activate_rules', '{ "succeeded": 225, "failed": 395 }') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .forceJSON() .checkElementExist('.coding-rule') .checkElementExist('.js-bulk-change') @@ -544,7 +544,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .clickElement('.js-facet[data-value="java"]') .checkElementExist('.js-bulk-change') @@ -565,7 +565,7 @@ define(function (require) { { data: { activation: true } }) .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromString('/api/qualityprofiles/deactivate_rules', '{ "succeeded": 7 }') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .clickElement('[data-property="qprofile"] .js-facet-toggle') .checkElementExist('.js-facet[data-value="java-default-with-mojo-conventions-49307"]') @@ -588,7 +588,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementExist('.search-navigator-facet-box-collapsed[data-property="debt_characteristics"]') .clearMocks() @@ -621,7 +621,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .clearMocks() @@ -683,7 +683,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementExist('.search-navigator-facet-box-collapsed[data-property="is_template"]') @@ -716,7 +716,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromString('/api/languages/list', '{"languages":[{"key":"custom","name":"Custom"}]}', { data: { q: 'custom' } }) - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .clickElement('[data-property="languages"] .select2-choice') .checkElementExist('.select2-search') @@ -746,7 +746,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', 609) .clearMocks() @@ -761,7 +761,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', 609) .clearMocks() @@ -781,7 +781,7 @@ define(function (require) { .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromFile('/api/rules/show', 'coding-rules-spec/show.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule.selected') .clickElement('.coding-rule.selected .js-rule') .checkElementExist('.coding-rules-detail-header') @@ -795,7 +795,7 @@ define(function (require) { .open() .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementInclude('#coding-rules-total', '609') .checkElementExist('.search-navigator-facet-box-forbidden[data-property="inheritance"]') @@ -851,7 +851,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementNotExist('.coding-rule-activation') .clickElement('[data-property="qprofile"] .js-facet-toggle') @@ -874,7 +874,7 @@ define(function (require) { { data: { activation: 'false' } }) .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') .mockFromString('/api/qualityprofiles/activate_rule', '{}') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementNotExist('.coding-rule-activation') .clickElement('[data-property="qprofile"] .js-facet-toggle') @@ -901,7 +901,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .checkElementNotExist('.coding-rule-activation') .clickElement('[data-property="qprofile"] .js-facet-toggle') @@ -943,7 +943,7 @@ define(function (require) { rule_key: 'common-java:FailedUnitTests' } }) - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .checkElementExist('.coding-rule') .clickElement('[data-property="qprofile"] .js-facet-toggle') .checkElementExist('.js-facet[data-value="java-default-with-mojo-conventions-49307"]') @@ -978,7 +978,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/rules/app', 'coding-rules-spec/app.json') .mockFromFile('/api/rules/search', 'coding-rules-spec/search.json') - .startApp('coding-rules') + .startAppBrowserify('coding-rules') .clickElement('[data-property="qprofile"] .js-facet-toggle') .checkElementExist('.js-facet[data-value="java-default-with-mojo-conventions-49307"]') .clearMocks() diff --git a/server/sonar-web/test/medium/custom-measures.spec.js b/server/sonar-web/test/medium/custom-measures.spec.js index 87c97ad6dcd..775e47a8c12 100644 --- a/server/sonar-web/test/medium/custom-measures.spec.js +++ b/server/sonar-web/test/medium/custom-measures.spec.js @@ -10,7 +10,7 @@ define(function (require) { .open() .mockFromFile('/api/custom_measures/search', 'custom-measures-spec/search.json', { data: { projectId: projectId } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .checkElementCount('#custom-measures-list tr[data-id]', 4) .checkElementInclude('#custom-measures-list .js-custom-measure-value', '35') .checkElementInclude('#custom-measures-list .js-custom-measure-metric-name', 'Distribution') @@ -29,7 +29,7 @@ define(function (require) { .open() .mockFromFile('/api/custom_measures/search', 'custom-measures-spec/search-big-1.json', { data: { projectId: projectId } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .checkElementCount('#custom-measures-list tr[data-id]', 2) .checkElementNotExist('[data-id="3"]') .clearMocks() @@ -46,7 +46,7 @@ define(function (require) { .mockFromFile('/api/custom_measures/search', 'custom-measures-spec/search.json', { data: { projectId: projectId } }) .mockFromFile('/api/metrics/search', 'custom-measures-spec/metrics.json', { data: { isCustom: true } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .checkElementCount('#custom-measures-list tr[data-id]', 4) .clickElement('#custom-measures-create') .checkElementExist('#create-custom-measure-form') @@ -74,7 +74,7 @@ define(function (require) { .mockFromFile('/api/custom_measures/search', 'custom-measures-spec/search.json', { data: { projectId: projectId } }) .mockFromFile('/api/metrics/search', 'custom-measures-spec/metrics.json', { data: { isCustom: true } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .clickElement('#custom-measures-create') .checkElementExist('#create-custom-measure-form') .checkElementCount('#create-custom-measure-metric option', 1) @@ -88,7 +88,7 @@ define(function (require) { { data: { projectId: projectId } }) .mockFromFile('/api/metrics/search', 'custom-measures-spec/metrics-limited.json', { data: { isCustom: true } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .clickElement('#custom-measures-create') .checkElementExist('#create-custom-measure-form') .checkElementNotExist('#create-custom-measure-metric') @@ -102,7 +102,7 @@ define(function (require) { .mockFromFile('/api/custom_measures/search', 'custom-measures-spec/search.json', { data: { projectId: projectId } }) .mockFromFile('/api/metrics/search', 'custom-measures-spec/metrics.json', { data: { isCustom: true } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .clickElement('[data-id="5"] .js-custom-measure-update') .checkElementExist('#create-custom-measure-form') .clearMocks() @@ -126,7 +126,7 @@ define(function (require) { .open() .mockFromFile('/api/custom_measures/search', 'custom-measures-spec/search.json', { data: { projectId: projectId } }) - .startApp('custom-measures', { projectId: projectId }) + .startAppBrowserify('custom-measures') .clickElement('[data-id="5"] .js-custom-measure-delete') .checkElementExist('#delete-custom-measure-form', 1) .clearMocks() diff --git a/server/sonar-web/test/medium/global-permissions.spec.js b/server/sonar-web/test/medium/global-permissions.spec.js index 93ef4354229..8e65281fac2 100644 --- a/server/sonar-web/test/medium/global-permissions.spec.js +++ b/server/sonar-web/test/medium/global-permissions.spec.js @@ -9,7 +9,7 @@ define(function (require) { .mockFromFile('/api/permissions/search_global_permissions', 'permissions/global-permissions.json') .mockFromFile('/api/permissions/users', 'permissions/users.json') .mockFromFile('/api/permissions/groups', 'permissions/groups.json') - .startApp('global-permissions') + .startAppBrowserify('global-permissions') .checkElementExist('#global-permissions-header') .checkElementExist('#global-permissions-list') .checkElementCount('#global-permissions-list > li', 6) diff --git a/server/sonar-web/test/medium/groups.spec.js b/server/sonar-web/test/medium/groups.spec.js index 90f157a70e0..dbaa59bdc55 100644 --- a/server/sonar-web/test/medium/groups.spec.js +++ b/server/sonar-web/test/medium/groups.spec.js @@ -7,7 +7,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search.json') - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .checkElementExist('#groups-list ul') .checkElementCount('#groups-list li[data-id]', 2) @@ -23,7 +23,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search.json') - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .checkElementCount('#groups-list li[data-id]', 2) .clearMocks() @@ -44,7 +44,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search-big-1.json') - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .checkElementCount('#groups-list li[data-id]', 1) .checkElementInclude('#groups-list-footer', '1/2') @@ -60,7 +60,7 @@ define(function (require) { .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search.json') .mockFromFile('/api/user_groups/users*', 'groups-spec/users.json') - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .checkElementNotInclude('#content', 'Bob') .clickElement('[data-id="1"] .js-group-users') @@ -73,7 +73,7 @@ define(function (require) { .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search.json') .mockFromFile('/api/user_groups/create', 'groups-spec/error.json', { status: 400 }) - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .checkElementCount('#groups-list li[data-id]', 2) .clickElement('#groups-create') @@ -98,7 +98,7 @@ define(function (require) { .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search.json') .mockFromFile('/api/user_groups/update', 'groups-spec/error.json', { status: 400 }) - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .clickElement('[data-id="2"] .js-group-update') .checkElementExist('#create-group-form') @@ -121,7 +121,7 @@ define(function (require) { .open() .mockFromFile('/api/user_groups/search', 'groups-spec/search.json') .mockFromFile('/api/user_groups/delete', 'groups-spec/error.json', { status: 400 }) - .startApp('groups') + .startAppBrowserify('groups') .checkElementInclude('#content', 'sonar-users') .clickElement('[data-id="1"] .js-group-delete') .checkElementExist('#delete-group-form') diff --git a/server/sonar-web/test/medium/issues.spec.js b/server/sonar-web/test/medium/issues.spec.js index 94b52657fc3..4683fc73308 100644 --- a/server/sonar-web/test/medium/issues.spec.js +++ b/server/sonar-web/test/medium/issues.spec.js @@ -10,7 +10,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementCount('.js-filter', 2) .checkElementCount('.js-filter[data-id="1"]', 1) .checkElementCount('.js-filter[data-id="2"]', 1); @@ -23,7 +23,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .clickElement('.search-navigator-filters-show-list') .clickElement('.js-filter[data-id="2"]') .checkElementCount('.js-filter-copy', 1) @@ -39,7 +39,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .clickElement('.search-navigator-filters-show-list') .clickElement('.js-filter[data-id="2"]') .checkElementCount('.js-filter-copy', 1) @@ -59,7 +59,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementExist('.facet[data-value=BLOCKER]') .checkElementExist('.facet[data-value=CRITICAL]') .checkElementExist('.facet[data-value=MAJOR]') @@ -98,7 +98,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementCount('.issue', 50) .clearMocks() .mockFromFile('/api/issues/search', 'issues-spec/search-reopened.json', { data: { severities: 'BLOCKER' } }) @@ -116,7 +116,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementExist('.js-selection') .checkElementNotExist('.js-selection.icon-checkbox-checked') .checkElementExist('.issue .js-toggle') @@ -142,7 +142,7 @@ define(function (require) { .mockFromFile('/api/issues/search', 'issues-spec/search.json') .mockFromString('/issues/bulk_change_form*', '<div id="bulk-change-form">bulk change form</div>', { contentType: 'text/plain' }) - .startApp('issues') + .startAppBrowserify('issues') .clickElement('#issues-bulk-change') .clickElement('.js-bulk-change') .checkElementExist('#bulk-change-form') @@ -161,7 +161,7 @@ define(function (require) { .mockFromFile('/api/issues/search', 'issues-spec/search.json') .mockFromString('/issues/bulk_change_form*', '<div id="bulk-change-form">bulk change form</div>', { contentType: 'text/plain' }) - .startApp('issues') + .startAppBrowserify('issues') .checkElementExist('.js-selection') .checkElementNotExist('.js-selection.icon-checkbox-checked') .checkElementExist('.issue .js-toggle') @@ -189,7 +189,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/app', 'issues-spec/app.json') .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search-filter-similar-issues.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementCount('.issue', 2) .clickElement('.issue.selected .js-issue-filter') .checkElementExist('.bubble-popup') @@ -223,7 +223,7 @@ define(function (require) { .mockFromFile('/api/issues/search', 'issues-page-should-open-issue-permalink/search.json', { data: { issues: issueKey } }) .mockFromFile('/api/components/app', 'issues-page-should-open-issue-permalink/components-app.json') .mockFromFile('/api/sources/lines', 'issues-page-should-open-issue-permalink/lines.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementExist('.source-line') .checkElementInclude('.source-line', 'public void executeOn(Project project, SensorContext context') .checkElementCount('.issue', 1) @@ -238,7 +238,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search-rules-facet.json', { data: { facets: 'rules' } }) .mockFromFile('/api/issues/search', 'issues-spec/search.json') - .startApp('issues') + .startAppBrowserify('issues') .clickElement('[data-property="rules"] .js-facet-toggle') .checkElementCount('[data-property="rules"] .js-facet', 13) .checkElementInclude('[data-property="rules"] .js-facet:nth-child(1)', 'Objects should be compared with'); @@ -252,7 +252,7 @@ define(function (require) { .mockFromFile('/api/issue_filters/search', 'issues-spec/issue-filters.json') .mockFromFile('/api/issues/search', 'issues-spec/search.json') .mockFromFile('/api/issues/do_transition', 'issues-spec/show-fp-new.json') - .startApp('issues') + .startAppBrowserify('issues') .checkElementExist('.issue.selected') .clickElement('.issue.selected .js-issue-transition') .clickElement('.js-issue-transition[data-value="falsepositive"]') diff --git a/server/sonar-web/test/medium/maintenance.spec.js b/server/sonar-web/test/medium/maintenance.spec.js index 32f8c05e263..afc7c539cea 100644 --- a/server/sonar-web/test/medium/maintenance.spec.js +++ b/server/sonar-web/test/medium/maintenance.spec.js @@ -7,7 +7,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/system/status', 'maintenance-spec/status-up.json') - .startApp('maintenance', { setup: false }) + .startAppBrowserify('maintenance', { setup: false }) .checkElementExist('.maintenance-title') .checkElementExist('.maintenance-title') .checkElementExist('.maintenance-text'); @@ -17,7 +17,7 @@ define(function (require) { return this.remote .open() .mockFromFile('/api/system/status', 'maintenance-spec/status-up.json') - .startApp('maintenance', { setup: false }) + .startAppBrowserify('maintenance', { setup: false }) .checkElementExist('.maintenance-title') .checkElementNotExist('.maintenance-title.text-danger') .clearMocks() diff --git a/server/sonar-web/test/medium/metrics.spec.js b/server/sonar-web/test/medium/metrics.spec.js index fc480dc6e71..e86d5d93ed8 100644 --- a/server/sonar-web/test/medium/metrics.spec.js +++ b/server/sonar-web/test/medium/metrics.spec.js @@ -9,7 +9,7 @@ define(function (require) { .mockFromFile('/api/metrics/domains', 'metrics-spec/domains.json') .mockFromFile('/api/metrics/types', 'metrics-spec/types.json') .mockFromFile('/api/metrics/search', 'metrics-spec/search.json') - .startApp('metrics') + .startAppBrowserify('metrics') .checkElementExist('#metrics-list li') .checkElementCount('#metrics-list li[data-id]', 3) .checkElementInclude('#metrics-list .js-metric-name', 'Business value') @@ -28,7 +28,7 @@ define(function (require) { .mockFromFile('/api/metrics/domains', 'metrics-spec/domains.json') .mockFromFile('/api/metrics/types', 'metrics-spec/types.json') .mockFromFile('/api/metrics/search', 'metrics-spec/search-big-1.json') - .startApp('metrics') + .startAppBrowserify('metrics') .checkElementExist('#metrics-list li') .checkElementCount('#metrics-list li[data-id]', 2) .checkElementInclude('#metrics-list-footer', '2/3') @@ -46,7 +46,7 @@ define(function (require) { .mockFromFile('/api/metrics/types', 'metrics-spec/types.json') .mockFromFile('/api/metrics/search', 'metrics-spec/search.json') .mockFromFile('/api/metrics/create', 'metrics-spec/error.json', { status: 400 }) - .startApp('metrics') + .startAppBrowserify('metrics') .checkElementExist('#metrics-list li') .checkElementCount('#metrics-list li[data-id]', 3) .clickElement('#metrics-create') @@ -78,7 +78,7 @@ define(function (require) { .mockFromFile('/api/metrics/types', 'metrics-spec/types.json') .mockFromFile('/api/metrics/search', 'metrics-spec/search.json') .mockFromFile('/api/metrics/update', 'metrics-spec/error.json', { status: 400 }) - .startApp('metrics') + .startAppBrowserify('metrics') .checkElementExist('#metrics-list li') .clickElement('[data-id="3"] .js-metric-update') .checkElementExist('#create-metric-form') @@ -110,7 +110,7 @@ define(function (require) { .mockFromFile('/api/metrics/types', 'metrics-spec/types.json') .mockFromFile('/api/metrics/search', 'metrics-spec/search.json') .mockFromFile('/api/metrics/delete', 'metrics-spec/error.json', { status: 400 }) - .startApp('metrics') + .startAppBrowserify('metrics') .checkElementExist('#metrics-list li') .clickElement('[data-id="3"] .js-metric-delete') .checkElementExist('#delete-metric-form') diff --git a/server/sonar-web/test/medium/project-permissions.spec.js b/server/sonar-web/test/medium/project-permissions.spec.js index f26b9d1d53b..6ed89b073f8 100644 --- a/server/sonar-web/test/medium/project-permissions.spec.js +++ b/server/sonar-web/test/medium/project-permissions.spec.js @@ -8,7 +8,7 @@ define(function (require) { .open() .mockFromFile('/api/permissions/search_project_permissions', 'permissions/project-permissions.json') .mockFromFile('/api/permissions/search_templates', 'permissions/permission-templates.json') - .startApp('project-permissions') + .startAppBrowserify('project-permissions') .checkElementExist('#project-permissions-header') .checkElementExist('#projects') .checkElementCount('#projects > thead > tr > th', 4) @@ -25,7 +25,7 @@ define(function (require) { .open() .mockFromFile('/api/permissions/search_project_permissions', 'permissions/project-permissions.json') .mockFromFile('/api/permissions/search_templates', 'permissions/permission-templates.json') - .startApp('project-permissions') + .startAppBrowserify('project-permissions') .checkElementInclude('#projects > tbody > tr:first-child td:nth-child(1)', 'My Project') .checkElementInclude('#projects > tbody > tr:first-child td:nth-child(2)', '3') .checkElementInclude('#projects > tbody > tr:first-child td:nth-child(2)', '4') @@ -47,7 +47,7 @@ define(function (require) { .open() .mockFromFile('/api/permissions/search_project_permissions', 'permissions/project-permissions.json') .mockFromFile('/api/permissions/search_templates', 'permissions/permission-templates.json') - .startApp('project-permissions') + .startAppBrowserify('project-permissions') .checkElementInclude('#projects > tbody > tr:first-child td:nth-child(1)', 'My Project') .checkElementInclude('#projects > tbody > tr:first-child td:nth-child(2)', '3') .checkElementInclude('#projects > tbody > tr:first-child td:nth-child(2)', '4') diff --git a/server/sonar-web/test/medium/quality-gates.spec.js b/server/sonar-web/test/medium/quality-gates.spec.js index 515b0e50e41..79f79ef4b27 100644 --- a/server/sonar-web/test/medium/quality-gates.spec.js +++ b/server/sonar-web/test/medium/quality-gates.spec.js @@ -8,7 +8,7 @@ define(function (require) { .open() .mockFromFile('/api/qualitygates/app', 'quality-gates-spec/app.json') .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 3) .checkElementInclude('.js-list .list-group-item', 'SonarQube way') @@ -23,7 +23,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/app', 'quality-gates-spec/app-anonymous.json') .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-id="1"]') .checkElementExist('.search-navigator-header-component') @@ -50,7 +50,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/app', 'quality-gates-spec/app.json') .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-id="1"]') .checkElementExist('.search-navigator-header-component') @@ -75,7 +75,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show-another.json', { data: { id: 5 } }) .mockFromFile('/api/qualitygates/search?gateId=5', 'quality-gates-spec/projects.json') - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.select-list-list li') .checkElementCount('.select-list-list li', 1) @@ -89,7 +89,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) .mockFromFile('/api/qualitygates/rename', 'quality-gates-spec/rename.json', { data: { id: 1, name: 'New Name' } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.search-navigator-header-component') .clickElement('#quality-gate-rename') @@ -108,7 +108,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show-created.json', { data: { id: 6 } }) .mockFromFile('/api/qualitygates/copy', 'quality-gates-spec/copy.json', { data: { id: 1, name: 'New Name' } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.search-navigator-header-component') .clickElement('#quality-gate-copy') @@ -127,7 +127,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show-another.json', { data: { id: 5 } }) .mockFromString('/api/qualitygates/set_as_default', '{}', { data: { id: 5 } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.search-navigator-header-component') .checkElementNotExist('.js-list .list-group-item.active .badge') @@ -145,7 +145,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) .mockFromString('/api/qualitygates/unset_default', '{}', { data: { id: 1 } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.search-navigator-header-component') .checkElementExist('.js-list .list-group-item.active .badge') @@ -165,7 +165,7 @@ define(function (require) { { status: 400, data: { name: 'Bad' } }) .mockFromFile('/api/qualitygates/create', 'quality-gates-spec/create.json', { data: { name: 'New Name' } }) .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show-created.json', { data: { id: 6 } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('#quality-gate-add') .checkElementExist('#quality-gate-form-name') @@ -187,7 +187,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show-another.json', { data: { id: 5 } }) .mockFromString('/api/qualitygates/destroy', '{"errors":[{"msg": "error"}]}', { status: 400 }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.search-navigator-header-component') .checkElementCount('.js-list .list-group-item', 3) @@ -210,7 +210,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show-another.json', { data: { id: 5 } }) .mockFromFile('/api/qualitygates/create_condition', 'quality-gates-spec/create-condition.json', { data: { gateId: 5, metric: 'complexity', op: 'GT', period: '1', warning: '3', error: '4' } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.search-navigator-header-component') .checkElementCount('.js-conditions [name="error"]', 0) @@ -241,7 +241,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) .mockFromFile('/api/qualitygates/update_condition', 'quality-gates-spec/update-condition.json', { data: { id: 1, warning: '173' } }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.update-condition') .checkElementExist('.js-conditions tr:first-child .update-condition[disabled]') @@ -260,7 +260,7 @@ define(function (require) { .mockFromFile('/api/qualitygates/list', 'quality-gates-spec/list.json') .mockFromFile('/api/qualitygates/show', 'quality-gates-spec/show.json', { data: { id: 1 } }) .mockFromString('/api/qualitygates/delete_condition', '{"errors":[{"msg": "error"}]}', { status: 400 }) - .startApp('quality-gates', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-gates', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementExist('.delete-condition') .checkElementCount('.delete-condition', 8) diff --git a/server/sonar-web/test/medium/quality-profiles.spec.js b/server/sonar-web/test/medium/quality-profiles.spec.js index 1d89f75ad33..ecafd4b0c01 100644 --- a/server/sonar-web/test/medium/quality-profiles.spec.js +++ b/server/sonar-web/test/medium/quality-profiles.spec.js @@ -10,7 +10,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/search', 'quality-profiles/search.json') .mockFromFile('/api/qualityprofiles/exporters', 'quality-profiles/exporters.json') .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 5) .checkElementInclude('.js-list .list-group-item', 'Sonar way') @@ -30,7 +30,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/search', 'quality-profiles/search.json') .mockFromFile('/api/qualityprofiles/exporters', 'quality-profiles/exporters.json') .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 5) .checkElementExist('.js-list .list-group-item[data-key="java-sonar-way-67887"]:not(.hidden)') @@ -64,7 +64,7 @@ define(function (require) { { data: { qprofile: 'java-sonar-way-67887', activation: 'true' } }) .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json', { data: { profileKey: 'java-sonar-way-67887' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="java-sonar-way-67887"]') .checkElementExist('.search-navigator-header-component') @@ -91,7 +91,7 @@ define(function (require) { { data: { qprofile: 'java-sonar-way-67887', activation: 'true' } }) .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json', { data: { profileKey: 'java-sonar-way-67887' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="java-sonar-way-67887"]') .checkElementExist('.search-navigator-header-component') @@ -118,7 +118,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance-plus.json', { data: { profileKey: 'java-inherited-profile-85155' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="java-inherited-profile-85155"]') .checkElementExist('.search-navigator-header-component') @@ -144,7 +144,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/projects?key=php-psr-2-46772', 'quality-profiles/projects.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="php-psr-2-46772"]') .checkElementExist('#quality-profile-projects') @@ -163,7 +163,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'quality-profiles/rules.json', { data: { qprofile: 'java-inherited-profile-85155', activation: 'true' } }) .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance-plus.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="java-inherited-profile-85155"]') .checkElementExist('#quality-profile-ancestors') @@ -188,7 +188,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/copy', 'quality-profiles/copy.json', { data: { fromKey: 'java-sonar-way-67887', toName: 'Copied Profile' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 5) .clickElement('.js-list .list-group-item[data-key="java-sonar-way-67887"]') @@ -212,7 +212,7 @@ define(function (require) { .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="java-sonar-way-67887"]') .checkElementExist('#quality-profile-rename') @@ -238,7 +238,7 @@ define(function (require) { .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementNotExist('.js-list .list-group-item[data-key="php-psr-2-46772"] .badge') .checkElementExist('.js-list .list-group-item[data-key="php-sonar-way-10778"] .badge') @@ -264,7 +264,7 @@ define(function (require) { .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 6) .clickElement('.js-list .list-group-item[data-key="java-copied-profile-11711"]') @@ -291,7 +291,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/qualityprofiles/importers', 'quality-profiles/importers-empty.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 5) .clickElement('#quality-profiles-create') @@ -309,7 +309,7 @@ define(function (require) { .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .list-group-item', 5) .clickElement('#quality-profiles-actions') @@ -328,7 +328,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/qualityprofiles/importers', 'quality-profiles/importers.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('#quality-profiles-create') .checkElementExist('.modal') @@ -353,7 +353,7 @@ define(function (require) { .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .checkElementCount('.js-list .js-list-language', 1) .checkElementCount('.js-list .list-group-item', 1) @@ -380,7 +380,7 @@ define(function (require) { .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance-change-parent.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-list .list-group-item') .clickElement('.js-list .list-group-item[data-key="java-inherited-profile-85155"]') .checkElementExist('#quality-profile-change-parent') @@ -409,7 +409,7 @@ define(function (require) { .mockFromFile('/api/languages/list', 'quality-profiles/languages.json') .mockFromFile('/api/rules/search', 'quality-profiles/rules.json') .mockFromFile('/api/qualityprofiles/inheritance', 'quality-profiles/inheritance.json') - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('#quality-profile-rename') .checkElementCount('.js-list .list-group-item.active', 1) .checkElementInclude('.js-list .list-group-item.active', 'Sonar way') @@ -434,7 +434,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/changelog', 'quality-profiles/changelog.json', { data: { profileKey: 'java-sonar-way-67887' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('#quality-profile-changelog-form-submit') .checkElementNotExist('.js-show-more-changelog') .clickElement('#quality-profile-changelog-form-submit') @@ -485,7 +485,7 @@ define(function (require) { profileKey: 'java-sonar-way-67887' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-show-more-changelog') .checkElementCount('#quality-profile-changelog tbody tr', 2) .clearMocks() @@ -513,7 +513,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/compare', 'quality-profiles/compare.json', { data: { leftKey: 'java-sonar-way-67887', rightKey: 'java-copied-profile-11711' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('#quality-profile-comparison-form-submit') .checkElementCount('#quality-profile-comparison-with-key option', 1) .clickElement('#quality-profile-comparison-form-submit') @@ -543,7 +543,7 @@ define(function (require) { .mockFromFile('/api/qualityprofiles/compare', 'quality-profiles/compare.json', { data: { leftKey: 'java-sonar-way-67887', rightKey: 'java-copied-profile-11711' } }) - .startApp('quality-profiles', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('quality-profiles', { urlRoot: '/test/medium/base.html' }) .checkElementExist('#quality-profile-comparison table') .checkElementCount('#quality-profile-comparison-with-key option', 1) .checkElementCount('.js-comparison-in-left', 2) diff --git a/server/sonar-web/test/medium/source-viewer.spec.js b/server/sonar-web/test/medium/source-viewer.spec.js index e318f7f19e8..3583853ee7e 100644 --- a/server/sonar-web/test/medium/source-viewer.spec.js +++ b/server/sonar-web/test/medium/source-viewer.spec.js @@ -14,7 +14,7 @@ define(function (require) { .mockFromFile('/api/issues/search', 'source-viewer-spec/issues-with-precise-location.json', { data: { componentUuids: 'uuid' } }) - .startApp('source-viewer', { file: file }) + .startAppBrowserify('source-viewer', { file: file }) .checkElementExist('.source-line-code[data-line-number="3"] .source-line-code-issue') .checkElementInclude('.source-line-code[data-line-number="3"] .source-line-code-issue', '14 So') @@ -37,7 +37,7 @@ define(function (require) { .mockFromFile('/api/issues/search', 'source-viewer-spec/issues-with-precise-location.json', { data: { componentUuids: 'uuid' } }) - .startApp('source-viewer', { file: file }) + .startAppBrowserify('source-viewer', { file: file }) .checkElementExist('.source-line-code[data-line-number="3"] .source-line-code-issue') .checkElementInclude('.source-line-code[data-line-number="3"] .source-line-code-issue', '14 So') .clickElement('.source-line-with-issues[data-line-number="3"]') @@ -56,7 +56,7 @@ define(function (require) { .mockFromFile('/api/issues/search', 'source-viewer-spec/issues-with-precise-location.json', { data: { componentUuids: 'uuid' } }) - .startApp('source-viewer', { file: file }) + .startAppBrowserify('source-viewer', { file: file }) .checkElementExist('.source-line-code[data-line-number="9"] .source-line-code-issue') .checkElementInclude('.source-line-code[data-line-number="9"] .source-line-code-issue', 'sion') .clickElement('.source-line-with-issues[data-line-number="9"]') @@ -75,7 +75,7 @@ define(function (require) { .mockFromFile('/api/components/app', 'source-viewer-spec/app.json', { data: { uuid: 'uuid' } }) .mockFromFile('/api/sources/lines', 'source-viewer-spec/lines.json', { data: { uuid: 'uuid' } }) .mockFromFile('/api/issues/search', 'source-viewer-spec/several-issues-on-a-line.json') - .startApp('source-viewer', { file: file }) + .startAppBrowserify('source-viewer', { file: file }) .checkElementExist('.source-line-issues[data-line-number="3"] .icon-severity-critical') .checkElementExist('.source-line-issues[data-line-number="3"] .source-line-issues-counter') .checkElementInclude('.source-line-issues[data-line-number="3"] .source-line-issues-counter', 2) diff --git a/server/sonar-web/test/medium/update-center.spec.js b/server/sonar-web/test/medium/update-center.spec.js index 40277c7ebc3..3acc5961cd5 100644 --- a/server/sonar-web/test/medium/update-center.spec.js +++ b/server/sonar-web/test/medium/update-center.spec.js @@ -10,7 +10,7 @@ define(function (require) { .mockFromFile('/api/plugins/installed', 'update-center-spec/installed.json') .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 5) .checkElementInclude('li[data-id="scmgit"] .js-plugin-name', 'Git') @@ -36,7 +36,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromFile('/api/system/upgrades', 'update-center-spec/system-updates.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-system]', 1) .checkElementInclude('li[data-system] .js-plugin-name', 'SonarQube 5.3') @@ -55,7 +55,7 @@ define(function (require) { .mockFromFile('/api/plugins/installed', 'update-center-spec/installed.json') .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 5) .checkElementExist('li[data-id="scmgit"]') @@ -69,7 +69,7 @@ define(function (require) { .mockFromFile('/api/plugins/installed', 'update-center-spec/installed.json') .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 4) .checkElementExist('li[data-id="scmgit"]') @@ -82,7 +82,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 3) .checkElementNotExist('li[data-id="scmgit"]') @@ -99,7 +99,7 @@ define(function (require) { .execute(function () { window.SS.updateCenterActive = false; }) - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 5) .checkElementExist('li[data-id="scmgit"]') @@ -119,7 +119,7 @@ define(function (require) { .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/system/upgrades', 'update-center-spec/system-updates.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 5) .checkElementExist('li[data-id="javascript"]') @@ -164,7 +164,7 @@ define(function (require) { .mockFromFile('/api/plugins/installed', 'update-center-spec/installed.json') .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementCount('li[data-id]', 5) .checkElementNotExist('li.hidden[data-id]') @@ -182,7 +182,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementCount('li[data-id]:not(.hidden)', 3) .clickElement('li[data-id="abap"] .js-plugin-category') .checkElementCount('li[data-id]:not(.hidden)', 2); @@ -195,7 +195,7 @@ define(function (require) { .mockFromFile('/api/plugins/installed', 'update-center-spec/installed.json') .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .clickElement('li[data-id="python"] .js-changelog') .checkElementExist('.bubble-popup') @@ -211,7 +211,7 @@ define(function (require) { .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .clickElement('li[data-id="abap"] .js-changelog') .checkElementExist('.bubble-popup') @@ -229,7 +229,7 @@ define(function (require) { .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromString('/api/plugins/update', '{}', { data: { key: 'scmgit' } }) - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .clickElement('li[data-id="scmgit"] .js-update') .checkElementNotExist('li[data-id="scmgit"] .js-spinner') @@ -244,7 +244,7 @@ define(function (require) { .mockFromFile('/api/plugins/updates', 'update-center-spec/updates.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromString('/api/plugins/uninstall', '{}', { data: { key: 'scmgit' } }) - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .clickElement('li[data-id="scmgit"] .js-uninstall') .checkElementNotExist('li[data-id="scmgit"] .js-spinner') @@ -258,7 +258,7 @@ define(function (require) { .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromString('/api/plugins/install', '{}', { data: { key: 'android' } }) - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .clickElement('li[data-id="android"] .js-install') .checkElementNotExist('li[data-id="android"] .js-spinner') @@ -272,7 +272,7 @@ define(function (require) { .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromString('/api/plugins/cancel_all', '{}') - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementExist('.js-pending') .clickElement('.js-cancel-all') @@ -286,7 +286,7 @@ define(function (require) { .mockFromFile('/api/plugins/available', 'update-center-spec/available.json') .mockFromFile('/api/plugins/pending', 'update-center-spec/pending.json') .mockFromString('/api/plugins/install', '{}', { data: { key: 'abap' } }) - .startApp('update-center', { urlRoot: '/test/medium/base.html' }) + .startAppBrowserify('update-center', { urlRoot: '/test/medium/base.html' }) .checkElementExist('.js-plugin-name') .checkElementExist('li[data-id="abap"] .js-terms') .checkElementExist('li[data-id="abap"] .js-install[disabled]') diff --git a/server/sonar-web/test/medium/users.spec.js b/server/sonar-web/test/medium/users.spec.js index e950e631f86..50b906c353d 100644 --- a/server/sonar-web/test/medium/users.spec.js +++ b/server/sonar-web/test/medium/users.spec.js @@ -8,7 +8,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search.json') - .startApp('users') + .startAppBrowserify('users') .checkElementCount('#users-list li[data-login]', 3) .checkElementInclude('#users-list .js-user-login', 'smith') .checkElementInclude('#users-list .js-user-name', 'Bob') @@ -30,7 +30,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search.json') - .startApp('users') + .startAppBrowserify('users') .checkElementCount('#users-list li[data-login]', 3) .clearMocks() .mockFromFile('/api/users/search', 'users-spec/search-filtered.json') @@ -51,7 +51,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search-big-1.json') - .startApp('users') + .startAppBrowserify('users') .checkElementCount('#users-list li[data-login]', 2) .clearMocks() .mockFromFile('/api/users/search', 'users-spec/search-big-2.json') @@ -65,7 +65,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search.json') - .startApp('users') + .startAppBrowserify('users') .checkElementCount('#users-list li[data-login]', 3) .clickElement('#users-create') .checkElementCount('#create-user-form', 1) @@ -93,7 +93,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search.json') - .startApp('users') + .startAppBrowserify('users') .clickElement('[data-login="smith"] .js-user-update') .checkElementCount('#create-user-form', 1) .clearMocks() @@ -116,7 +116,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search.json') - .startApp('users') + .startAppBrowserify('users') .clickElement('[data-login="smith"] .js-user-change-password') .checkElementCount('#change-user-password-form', 1) .clearMocks() @@ -136,7 +136,7 @@ define(function (require) { .open() .mockFromString('/api/l10n/index', '{}') .mockFromFile('/api/users/search', 'users-spec/search.json') - .startApp('users') + .startAppBrowserify('users') .clickElement('[data-login="smith"] .js-user-deactivate') .checkElementCount('#deactivate-user-form', 1) .clearMocks() diff --git a/server/sonar-web/tests/apps/background-tasks-test.js b/server/sonar-web/tests/apps/background-tasks-test.js index 22f2531a36e..6e79e2d7f71 100644 --- a/server/sonar-web/tests/apps/background-tasks-test.js +++ b/server/sonar-web/tests/apps/background-tasks-test.js @@ -1,6 +1,5 @@ /* eslint no-unused-expressions: 0 */ import React from 'react/addons'; -import App from '../../src/main/js/apps/background-tasks/app'; import Header from '../../src/main/js/apps/background-tasks/header'; import Stats from '../../src/main/js/apps/background-tasks/stats'; import Search from '../../src/main/js/apps/background-tasks/search'; @@ -15,12 +14,6 @@ let sinon = require('sinon'); chai.use(require('sinon-chai')); describe('Background Tasks', function () { - describe('App', () => { - it('should have #start()', () => { - expect(App.start).to.be.a('function'); - }); - }); - describe('Constants', () => { it('should have STATUSES', () => { expect(STATUSES).to.be.a('object'); diff --git a/server/sonar-web/tests/apps/nav-test.js b/server/sonar-web/tests/nav-test.js index d31802ec897..c06cfa81723 100644 --- a/server/sonar-web/tests/apps/nav-test.js +++ b/server/sonar-web/tests/nav-test.js @@ -1,5 +1,5 @@ import React from 'react/addons'; -import ComponentNavBreadcrumbs from '../../src/main/js/apps/nav/component/component-nav-breadcrumbs'; +import ComponentNavBreadcrumbs from '../src/main/js/main/nav/component/component-nav-breadcrumbs'; let TestUtils = React.addons.TestUtils; let expect = require('chai').expect; |