<commit_before>import gulp from             'gulp';
import rename from           'gulp-rename';
import babel from            'gulp-babel';
import sass from             'gulp-sass';
import csso from             'gulp-csso';
import prefix from           'gulp-autoprefixer';
import cp from               'child_process';
import imagemin from         'imagemin';
import imageminPngquant from 'imagemin-pngquant';
import browserSync from      'browser-sync';
import jscpd from            'gulp-jscpd';
import uglify from           'gulp-uglify';
import concat from           'gulp-concat';
import jshint from           'gulp-jshint';
import plumber from          'gulp-plumber';
import changed from          'gulp-changed';
import webpack from          'gulp-webpack';
import rmvHtmlComnts from    'gulp-remove-html-comments';
import debug from            'gulp-debug';
import colorShort from       'postcss-color-short';
import pxtorem from          'postcss-pxtorem';
import size from             'postcss-size';
import cssMqpacker from      'css-mqpacker';
import focus from            'postcss-focus';
import jsonlint from         'gulp-jsonlint';
import postcss from          'gulp-postcss';

const paths = {
  // css
  cssAll:     'assets/css/*.*',
  css:        'assets/css/*.css',
  sassAll:    'assets/css/*/*.*',
  sassAllAll: 'assets/css/*/*/*.*',
  sass:       'assets/css/main.sass',
  cssMin:     'assets/css/min/',

  // js
  jsAll:  'assets/js/*.*',
  jsMain: 'assets/js/*.js',
  jsMin:  'assets/js/min/common.min.js',

  //images
  imagesAll: 'assets/img/*.*',
  imagesMin: 'assets/img/min/',

  // html
  includes: '_includes/*.html',
  site:     '_site'
}

const jekyll = process.platform === 'win32' ? 'jekyll.bat' : 'jekyll',
  messages = {
    jekyllBuild: 'Running: jekyll build'
};

// task jekyll-build
gulp.task('jekyll-build', (done) => {
  browserSync.notify(messages.jekyllBuild);
  return cp.spawn( jekyll , ['build'], {stdio: 'inherit'})
    .on('close', done);
});

// task jekyll-rebuild
gulp.task('jekyll-rebuild', ['jekyll-build'], () => browserSync.reload());

// task browser-sync
gulp.task('browser-sync', ['jekyll-build'], () => {
  browserSync({
    server: {
      baseDir: paths.site
    },
    host: "localhost",
    notify: false
  });
});

// task css
gulp.task('css', () => {
  const processors = [
    colorShort,
    focus,
    size,
    pxtorem,
    cssMqpacker
  ];
  return gulp.src(paths.sass)
    .pipe(postcss(processors))
    .pipe(sass({
      includePaths: ['css'],
      onError: browserSync.notify
    }))
    .pipe(prefix(['last 15 versions', '> 1%', 'ie 8', 'ie 7'], { cascade: true }))
    .pipe(csso())
    .pipe(rename({suffix: '.min'}))
    .pipe(debug({title: 'Checking:'}))
    .pipe(gulp.dest(paths.cssMin));
});

// task html
gulp.task('html', () => {
  return gulp.src(paths.includes)
    .pipe(rmvHtmlComnts())
    .pipe(gulp.dest(''));
});

// task image
gulp.task('image', () => {
  return gulp.src(paths.imagesAll)
    .pipe(imageminPngquant({quality: '65-80', speed: 4})())
    .pipe(debug({title: 'Checking:'}))
    .pipe(gulp.dest(paths.imagesMin));
});

// this part response for all stuff with js
gulp.task('js', () => {
  return gulp.src(paths.jsMain)
    //.pipe(webpack())
    .pipe(babel({
      presets: ['es2015']
    }))
    .pipe(jscpd({
      'min-lines': 1,
      verbose    : true
    }))
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    .pipe(concat(paths.jsMin))
    .pipe(changed(paths.jsAll))
    .pipe(uglify())
    .pipe(debug({title: 'Checking:'}))
    .pipe(gulp.dest(''))
});

// watch changes and run tasks
gulp.task('watch', () => {
  gulp.watch(paths.sassAll, ['css', 'jekyll-build', 'jekyll-rebuild']);
  gulp.watch(paths.sassAllAll, ['css', 'jekyll-build', 'jekyll-rebuild']);
  gulp.watch(paths.cssAll, ['css', 'jekyll-build', 'jekyll-rebuild']);
  gulp.watch(paths.jsAll, ['js', 'jekyll-build', 'jekyll-rebuild']);
  gulp.watch(paths.includes, ['jekyll-build', 'jekyll-rebuild']);
});

// Prevent pipe breaking caused by errors from gulp plugins
gulp.task('plumber', () => {
  return gulp.src(['css', 'js', 'html'], {read: false})
    .pipe(plumber())
    .pipe(debug({title: 'Checking:'}));
});

// task default
gulp.task('default', () => {
  gulp.start('image', 'plumber', 'browser-sync', 'watch', 'css', 'js', 'jekyll-build', 'jekyll-rebuild');
});
<commit_msg>update gulp from 3.9.1 to 4<commit_after>// Main
import postcss          from 'gulp-postcss';
import gulp             from 'gulp';

// Gulp-plugins
import rmvHtmlComnts    from 'gulp-remove-html-comments';
import prefix           from 'gulp-autoprefixer';
import sourcemaps       from 'gulp-sourcemaps';
import jsonlint         from 'gulp-jsonlint';
import htmlmin          from 'gulp-htmlmin';
import plumber          from 'gulp-plumber';
import changed          from 'gulp-changed';
import rename           from 'gulp-rename';
import concat           from 'gulp-concat';
import jshint           from 'gulp-jshint';
import notify           from 'gulp-notify';
import babel            from 'gulp-babel';
import jscpd            from 'gulp-jscpd';
import debug            from 'gulp-debug';
import uglify           from 'gulp-uglify';
import sass             from 'gulp-sass';
import csso             from 'gulp-csso';
import gulpIf           from 'gulp-if';

// Postcss-plugins
import colorShort       from 'postcss-color-short';
import pxtorem          from 'postcss-pxtorem';
import focus            from 'postcss-focus';
import size             from 'postcss-size';

// Other
import imageminPngquant from 'imagemin-pngquant';
import combiner         from 'stream-combiner2';
import cp               from 'child_process';
import cssMqpacker      from 'css-mqpacker';
import browserSync      from 'browser-sync';
import imagemin         from 'imagemin';
import del              from 'del';

const isDevelopment = !process.env.NODE_ENV || process.env.NODE_ENV === 'devlopment'; // NODE_ENV=production gulp

const paths = {
  // css
  css: {
    sassAll:  'assets/css/*/*/*.*',
    sassMain: 'assets/css/main.sass',
    cssMin:   'assets/css/min/'
  },

  // js
  js: {
    jsMain: 'assets/js/*.js',
    jsMin:  'assets/js/min/'
  },

  //images
  img: {
    imagesAll: 'assets/img/*.*',
    imagesMin: 'assets/img/min/'
  },

  // html
  html: {
    includes: '_includes/*.html',
    site:     '_site',
    main:     '*.html'
  }
}

const jekyll = process.platform === 'win32' ? 'jekyll.bat' : 'jekyll',
  messages = {
    build: 'Running: jekyll build'
};

// Assets
// ========================
gulp.task('assets:css', () => {
  let processors = [
      cssMqpacker,
      colorShort,
      pxtorem,
      focus,
      size
    ]
  let combined = combiner.obj([
    gulp.src(paths.css.sassMain),
      plumber(),
      changed(paths.css.cssMin),
      gulpIf(isDevelopment, sourcemaps.init()),
      sass({
        includePaths: ['assets/css/'],
        onError: browserSync.notify
      }),
      postcss(processors),
      prefix({ browsers: ['> 1%', 'ie 8', 'ie 7', 'ie 6'], cascade: false }),
      csso(),
      rename({suffix: '.min'}),
      debug({title: 'Checking CSS:'}),
      gulpIf(isDevelopment, sourcemaps.write('.')),
      gulp.dest(paths.css.cssMin)
  ])
  combined.on('error', console.error.bind(console))
  return combined;
});
gulp.task('assets:js', () => {
  let combined = combiner.obj([
    gulp.src(paths.js.jsMain),
      plumber(),
      changed(paths.js.jsMain),
      babel({
        presets: ['es2015']
      }),
      jshint(),
      jshint.reporter('jshint-stylish'),
      jscpd(),
      concat(paths.js.jsMain),
      uglify(),
      rename({
        dirname: paths.js.jsMin,
        basename: "common",
        suffix: ".min",
        extname: ".js"
      }),
      debug({title: 'Checking JavaScript:'}),
    gulp.dest('./')
  ])
  combined.on('error', console.error.bind(console))
  return combined;
});
gulp.task('assets:json', () => {
  let combined = combiner.obj([
    gulp.src('*.json'),
      plumber(),
      jsonlint(),
      jsonlint.reporter(),
      jsonlint.failOnError(),
      debug({title: 'Checking JSON:'}),
    gulp.dest('.')
  ])
  combined.on('error', console.error.bind(console))
  return combined;
});
gulp.task('assets:image', () => {
  let combined = combiner.obj([
    gulp.src(paths.img.imagesAll),
      imageminPngquant({quality: '50', speed: 40})(),
      debug({title: 'Checking Images:'}),
    gulp.dest(paths.img.imagesMin)
  ])
  combined.on('error', console.error.bind(console))
  return combined;
});

// Browser
// ========================
gulp.task('browser:build', done => {
  browserSync.notify(messages.build);
  return cp.spawn( jekyll , ['build'], {stdio: 'inherit'})
    .on('close', done)
});
gulp.task('browser:rebuild', () => browserSync.reload());
gulp.task('browser:sync', () => {
  browserSync.init({
    server: {
      baseDir: paths.html.site
    },
    host: "localhost",
    notify: false
  })
  gulp.watch(paths.css.sassMain, gulp.series('assets:css', 'browser:build', 'browser:rebuild'));
  gulp.watch(paths.css.sassAll, gulp.series('assets:css', 'browser:build', 'browser:rebuild'));
  gulp.watch(paths.js.jsMain, gulp.series('assets:js', 'browser:build', 'browser:rebuild'));
  gulp.watch(paths.html.includes, gulp.series('browser:build', 'browser:rebuild'));
  gulp.watch(paths.html.main, gulp.series('browser:build', 'browser:rebuild'));
});

// Cleen
// ========================
gulp.task('clean:del', done => {
  return del(paths.html.site)
  done();
});

// DEPLOY
// html
gulp.task('deploy:html', () => {
  let combined = combiner.obj([
    gulp.src(paths.html.includes),
      rmvHtmlComnts(),
      htmlmin({collapseWhitespace: true}),
      debug({title: 'Checking HTML:'}),
    gulp.dest(paths.html.includes)
  ])
  combined.on('error', console.error.bind(console))
  return combined;
});

// image
gulp.task('deploy:image', () => {
  let combined = combiner.obj([
    gulp.src(paths.img.imagesAll),
      imageminPngquant({quality: '100', speed: 1})(),
      debug({title: 'Checking Images:'}),
    gulp.dest(paths.img.imagesMin)
  ])
  combined.on('error', console.error.bind(console))
  return combined;
});

const browser = gulp.parallel('browser:build', 'browser:rebuild', 'browser:sync');
const assets = gulp.parallel('assets:js', 'assets:css', 'assets:json', 'assets:image');
const clean = gulp.parallel('clean:del');
const build = gulp.series(clean, gulp.parallel(assets, browser));
const deploy = gulp.parallel('deploy:image', 'deploy:html');
export { build, clean, assets, browser, deploy };
export default build;
<|endoftext|>


<commit_before>/**
 * Import node modules
 */
import gulp         from 'gulp';
import sass         from 'gulp-sass';
import rename       from 'gulp-rename';
import postcss      from 'gulp-postcss';
import autoprefixer from 'autoprefixer';
import cssnano      from 'cssnano';
import g_zip        from 'gulp-zip';
import uglify       from 'gulp-uglify';
import rollup       from 'gulp-rollup';
import nodeResolve  from 'rollup-plugin-node-resolve';
import commonjs     from 'rollup-plugin-commonjs';
import babel        from 'rollup-plugin-babel';
import plumber      from 'gulp-plumber';
import aigis        from 'gulp-aigis';
import browserSync  from 'browser-sync';

const dir = {
  src: {
    css  : 'src/css',
    js   : 'src/js',
    font : 'src/font',
    aigis: 'src/aigis'
  },
  dist: {
    css  : 'dist/css',
    js   : 'dist/js',
    font : 'dist/font',
    aigis: 'dist/aigis'
  }
};

/**
 * Sass to CSS
 */
export function css() {
  return gulp.src(
      [
        dir.src.css + '/basis.scss',
        dir.src.css + '/plugin/basis-ie9/basis-ie9.scss'
      ],
      {base: dir.src.css}
    )
    .pipe(plumber())
    .pipe(sass({
      outputStyle: 'expanded',
      includePaths: require('node-normalize-scss').includePaths
    }))
    .pipe(postcss([
      autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
      })
    ]))
    .pipe(gulp.dest(dir.dist.css))
    .pipe(postcss([
      cssnano({
        'zindex': false
      })
    ]))
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest(dir.dist.css));
}

/**
 * Build javascript
 */
export function js() {
  gulp.src(dir.src.js + '/**/*.js')
    .pipe(plumber())
    .pipe(rollup({
      allowRealFiles: true,
      input: dir.src.js + '/basis.js',
      external: ['jquery'],
      output: {
        globals: {
          jquery: "jQuery"
        },
        format: 'iife'
      },
      plugins: [
        nodeResolve({ jsnext: true }),
        commonjs(),
        babel({
          presets: [
            [
              "env", {
                "modules": false,
                "targets": {
                  "browsers": ['last 2 versions']
                }
              }
            ]
          ],
          plugins: ['external-helpers'],
          babelrc: false
        })
      ]
    }))
    .pipe(gulp.dest(dir.dist.js))
    .on('end', () => {
      return gulp.src([dir.dist.js + '/basis.js'])
        .pipe(uglify())
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(dir.dist.js));
    });
}

/**
 * Build font
 */
export function font() {
  return gulp.src(dir.src.font + '/*')
    .pipe(gulp.dest(dir.dist.font));
}

/**
 * Build
 */
export const build = gulp.parallel(css, js, font);

/**
 * Styleguide
 */
gulp.task('aigis:update', gulp.series(() => {
  return gulp.src(dir.src.aigis + '/aigis_config.yml').pipe(aigis());
}, 'aigis:css', 'aigis:js'));

gulp.task('aigis:build', gulp.series('build', 'aigis:update'));

/**
 * Sass to CSS
 */
gulp.task('aigis:css', () => {
  return gulp.src(dir.src.aigis + '/assets/css/*.scss', {
      base: dir.src.aigis + '/assets/css'
    })
    .pipe(plumber())
    .pipe(sass({
      outputStyle: 'expanded',
      includePaths: require('node-normalize-scss').includePaths
    }))
    .pipe(postcss([
      autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
      })
    ]))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/css'))
    .pipe(postcss([
      cssnano({
        'zindex': false
      })
    ]))
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/css'));
});

/**
 * Build javascript
 */
gulp.task('aigis:js', () => {
  gulp.src(dir.src.aigis + '/assets/js/*.js')
    .pipe(plumber())
    .pipe(rollup({
      allowRealFiles: true,
      input: dir.src.aigis + '/assets/js/app.js',
      external: ['jquery'],
      output: {
        globals: {
          jquery: "jQuery"
        },
        format: 'iife'
      },
      plugins: [
        nodeResolve({ jsnext: true }),
        commonjs(),
        babel({
          presets: [
            [
              "env", {
                "modules": false,
                "targets": {
                  "browsers": ['last 2 versions']
                }
              }
            ]
          ],
          plugins: ['external-helpers'],
          babelrc: false
        })
      ]
    }))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/js'))
    .on('end', () => {
      return gulp.src([dir.dist.aigis + '/aigis_assets/js/app.js'])
        .pipe(uglify())
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/js'));
    });
});

/**
 * Auto Build
 */
export function watch() {
  gulp.watch([dir.src.css + '/**/*.scss'], gulp.series(css, 'aigis:update'));

  gulp.watch([dir.src.js + '/**/*.js'], gulp.series(js, 'aigis:update'));

  gulp.watch([dir.src.aigis + '/**/*.ejs'], gulp.task('aigis:update'));

  gulp.watch([dir.src.aigis + '/assets/css/**/*.scss'], gulp.task('aigis:css'));

  gulp.watch([dir.src.aigis + '/assets/js/**/*.js'], gulp.task('aigis:js'));
}

/**
 * Browsersync
 */
export const server = gulp.series('aigis:build', () => {
  browserSync.init( {
    server: {
      baseDir: dir.dist.aigis + '/'
    },
    files: [
      dir.dist.aigis + '/index.html',
      dir.dist.aigis + '/aigis_assets/css/style.min.css'
    ]
  });
});

/**
 * Creates the zip file
 */
export function zip() {
  return gulp.src(
      [
        '**',
        '.editorconfig',
        '.gitignore',
        '!node_modules',
        '!node_modules/**',
        '!basis.zip'
      ]
      , {base: './'}
    )
    .pipe(g_zip('basis.zip'))
    .pipe(gulp.dest('./'));
}

/**
 * Sass tests
 */
export function test() {
  return gulp.src('./tests/tests.scss')
    .pipe(plumber())
    .pipe(sass())
    .pipe(gulp.dest('./tests'));
}

export default gulp.parallel(watch, server);
<commit_msg>stream end event to gulp.series()<commit_after>/**
 * Import node modules
 */
import gulp         from 'gulp';
import sass         from 'gulp-sass';
import rename       from 'gulp-rename';
import postcss      from 'gulp-postcss';
import autoprefixer from 'autoprefixer';
import cssnano      from 'cssnano';
import g_zip        from 'gulp-zip';
import uglify       from 'gulp-uglify';
import rollup       from 'gulp-rollup';
import nodeResolve  from 'rollup-plugin-node-resolve';
import commonjs     from 'rollup-plugin-commonjs';
import babel        from 'rollup-plugin-babel';
import plumber      from 'gulp-plumber';
import aigis        from 'gulp-aigis';
import browserSync  from 'browser-sync';

const dir = {
  src: {
    css  : 'src/css',
    js   : 'src/js',
    font : 'src/font',
    aigis: 'src/aigis'
  },
  dist: {
    css  : 'dist/css',
    js   : 'dist/js',
    font : 'dist/font',
    aigis: 'dist/aigis'
  }
};

/**
 * Sass to CSS
 */
export function css() {
  return gulp.src(
      [
        dir.src.css + '/basis.scss',
        dir.src.css + '/plugin/basis-ie9/basis-ie9.scss'
      ],
      {base: dir.src.css}
    )
    .pipe(plumber())
    .pipe(sass({
      outputStyle: 'expanded',
      includePaths: require('node-normalize-scss').includePaths
    }))
    .pipe(postcss([
      autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
      })
    ]))
    .pipe(gulp.dest(dir.dist.css))
    .pipe(postcss([
      cssnano({
        'zindex': false
      })
    ]))
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest(dir.dist.css));
}

/**
 * Build javascript
 */
export const js = gulp.series(() => {
  gulp.src(dir.src.js + '/**/*.js')
    .pipe(plumber())
    .pipe(rollup({
      allowRealFiles: true,
      input: dir.src.js + '/basis.js',
      external: ['jquery'],
      output: {
        globals: {
          jquery: "jQuery"
        },
        format: 'iife'
      },
      plugins: [
        nodeResolve({ jsnext: true }),
        commonjs(),
        babel({
          presets: [
            [
              "env", {
                "modules": false,
                "targets": {
                  "browsers": ['last 2 versions']
                }
              }
            ]
          ],
          plugins: ['external-helpers'],
          babelrc: false
        })
      ]
    }))
    .pipe(gulp.dest(dir.dist.js));
}, () => {
  return gulp.src([dir.dist.js + '/basis.js'])
    .pipe(uglify())
    .pipe(rename({suffix: '.min'}))
    .pipe(gulp.dest(dir.dist.js));
});

/**
 * Build font
 */
export function font() {
  return gulp.src(dir.src.font + '/*')
    .pipe(gulp.dest(dir.dist.font));
}

/**
 * Build
 */
export const build = gulp.parallel(css, js, font);

/**
 * Styleguide
 */
gulp.task('aigis:update', gulp.series(() => {
  return gulp.src(dir.src.aigis + '/aigis_config.yml').pipe(aigis());
}, 'aigis:css', 'aigis:js'));

gulp.task('aigis:build', gulp.series(build, 'aigis:update'));

/**
 * Sass to CSS
 */
gulp.task('aigis:css', () => {
  return gulp.src(dir.src.aigis + '/assets/css/*.scss', {
      base: dir.src.aigis + '/assets/css'
    })
    .pipe(plumber())
    .pipe(sass({
      outputStyle: 'expanded',
      includePaths: require('node-normalize-scss').includePaths
    }))
    .pipe(postcss([
      autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
      })
    ]))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/css'))
    .pipe(postcss([
      cssnano({
        'zindex': false
      })
    ]))
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/css'));
});

/**
 * Build javascript
 */
gulp.task('aigis:js', gulp.series(() => {
  return gulp.src(dir.src.aigis + '/assets/js/*.js')
    .pipe(plumber())
    .pipe(rollup({
      allowRealFiles: true,
      input: dir.src.aigis + '/assets/js/app.js',
      external: ['jquery'],
      output: {
        globals: {
          jquery: "jQuery"
        },
        format: 'iife'
      },
      plugins: [
        nodeResolve({ jsnext: true }),
        commonjs(),
        babel({
          presets: [
            [
              "env", {
                "modules": false,
                "targets": {
                  "browsers": ['last 2 versions']
                }
              }
            ]
          ],
          plugins: ['external-helpers'],
          babelrc: false
        })
      ]
    }))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/js'));
}), () => {
  return gulp.src([dir.dist.aigis + '/aigis_assets/js/app.js'])
    .pipe(uglify())
    .pipe(rename({suffix: '.min'}))
    .pipe(gulp.dest(dir.dist.aigis + '/aigis_assets/js'));
});

/**
 * Auto Build
 */
export function watch() {
  gulp.watch([dir.src.css + '/**/*.scss'], gulp.series(css, 'aigis:update'));

  gulp.watch([dir.src.js + '/**/*.js'], gulp.series(js, 'aigis:update'));

  gulp.watch([dir.src.aigis + '/**/*.ejs'], gulp.task('aigis:update'));

  gulp.watch([dir.src.aigis + '/assets/css/**/*.scss'], gulp.task('aigis:css'));

  gulp.watch([dir.src.aigis + '/assets/js/**/*.js'], gulp.task('aigis:js'));
}

/**
 * Browsersync
 */
export const server = gulp.series('aigis:build', () => {
  browserSync.init( {
    server: {
      baseDir: dir.dist.aigis + '/'
    },
    files: [
      dir.dist.aigis + '/index.html',
      dir.dist.aigis + '/aigis_assets/css/style.min.css'
    ]
  });
});

/**
 * Creates the zip file
 */
export function zip() {
  return gulp.src(
      [
        '**',
        '.editorconfig',
        '.gitignore',
        '!node_modules',
        '!node_modules/**',
        '!basis.zip'
      ]
      , {base: './'}
    )
    .pipe(g_zip('basis.zip'))
    .pipe(gulp.dest('./'));
}

/**
 * Sass tests
 */
export function test() {
  return gulp.src('./tests/tests.scss')
    .pipe(plumber())
    .pipe(sass())
    .pipe(gulp.dest('./tests'));
}

export default gulp.parallel(watch, server);
<|endoftext|>


<commit_before>'use strict'

const unixfsEngine = require('ipfs-unixfs-engine')
const importer = unixfsEngine.importer
const exporter = unixfsEngine.exporter
const promisify = require('promisify-es6')
const pull = require('pull-stream')
const sort = require('pull-sort')
const pushable = require('pull-pushable')
const toStream = require('pull-stream-to-stream')
const toPull = require('stream-to-pull-stream')
const deferred = require('pull-defer')
const waterfall = require('async/waterfall')
const isStream = require('is-stream')
const Duplex = require('readable-stream').Duplex
const CID = require('cids')
const toB58String = require('multihashes').toB58String

function noop () {}

function prepareFile (self, opts, file, callback) {
  opts = opts || {}

  waterfall([
    (cb) => self.object.get(file.multihash, cb),
    (node, cb) => {
      let cid = new CID(node.multihash)

      if (opts['cid-version'] === 1) {
        cid = cid.toV1()
      }

      const b58Hash = cid.toBaseEncodedString()

      cb(null, {
        path: file.path || b58Hash,
        hash: b58Hash,
        size: node.size
      })
    }
  ], callback)
}

function normalizeContent (content) {
  if (!Array.isArray(content)) {
    content = [content]
  }

  return content.map((data) => {
    // Buffer input
    if (Buffer.isBuffer(data)) {
      data = { path: '', content: pull.values([data]) }
    }

    // Readable stream input
    if (isStream.readable(data)) {
      data = { path: '', content: toPull.source(data) }
    }

    if (data && data.content && typeof data.content !== 'function') {
      if (Buffer.isBuffer(data.content)) {
        data.content = pull.values([data.content])
      }

      if (isStream.readable(data.content)) {
        data.content = toPull.source(data.content)
      }
    }

    return data
  })
}

class AddHelper extends Duplex {
  constructor (pullStream, push, options) {
    super(Object.assign({ objectMode: true }, options))
    this._pullStream = pullStream
    this._pushable = push
    this._waitingPullFlush = []
  }

  _read () {
    this._pullStream(null, (end, data) => {
      while (this._waitingPullFlush.length) {
        const cb = this._waitingPullFlush.shift()
        cb()
      }
      if (end) {
        if (end instanceof Error) {
          this.emit('error', end)
        }
      } else {
        this.push(data)
      }
    })
  }

  _write (chunk, encoding, callback) {
    this._waitingPullFlush.push(callback)
    this._pushable.push(chunk)
  }
}

module.exports = function files (self) {
  function _addPullStream (options) {
    const opts = Object.assign({}, {
      shardSplitThreshold: self._options.EXPERIMENTAL.sharding
        ? 1000
        : Infinity
    }, options)

    let total = 0
    let prog = opts.progress || (() => {})
    const progress = (bytes) => {
      total += bytes
      prog(total)
    }

    opts.progress = progress
    return pull(
      pull.map(normalizeContent),
      pull.flatten(),
      importer(self._ipldResolver, opts),
      pull.asyncMap(prepareFile.bind(null, self, opts))
    )
  }

  function _catPullStream (ipfsPath) {
    if (typeof ipfsPath === 'function') {
      throw new Error('You must supply an ipfsPath')
    }

    const d = deferred.source()

    pull(
      exporter(ipfsPath, self._ipldResolver),
      pull.collect((err, files) => {
        if (err) { d.end(err) }
        if (!files || !files.length) {
          return d.abort(new Error('No such file'))
        }

        if (files.length > 1) {
          files = files.filter((file) => file.path === ipfsPath)
        }

        const file = files[0]

        const content = file.content
        if (!content && file.type === 'dir') {
          return d.abort(new Error('this dag node is a directory'))
        }
        d.resolve(content)
      })
    )

    return d
  }

  function _lsPullStreamImmutable (ipfsPath) {
    return pull(
      exporter(ipfsPath, self._ipldResolver, { maxDepth: 1 }),
      pull.filter((node) => node.depth === 1),
      pull.map((node) => {
        node = Object.assign({}, node, { hash: toB58String(node.hash) })
        delete node.content
        return node
      })
    )
  }

  return {
    add: promisify((data, options, callback) => {
      if (typeof options === 'function') {
        callback = options
        options = {}
      } else if (!callback || typeof callback !== 'function') {
        callback = noop
      }

      if (typeof data !== 'object' &&
          !Buffer.isBuffer(data) &&
          !isStream(data)) {
        return callback(new Error('Invalid arguments, data must be an object, Buffer or readable stream'))
      }

      pull(
        pull.values([data]),
        _addPullStream(options),
        sort((a, b) => {
          if (a.path < b.path) return 1
          if (a.path > b.path) return -1
          return 0
        }),
        pull.collect(callback)
      )
    }),

    addReadableStream: (options) => {
      options = options || {}

      const p = pushable()
      const s = pull(
        p,
        _addPullStream(options)
      )

      const retStream = new AddHelper(s, p)

      retStream.once('finish', () => p.end())

      return retStream
    },

    addPullStream: _addPullStream,

    cat: promisify((ipfsPath, callback) => {
      pull(
        _catPullStream(ipfsPath),
        pull.collect((err, buffers) => {
          if (err) { return callback(err) }
          callback(null, Buffer.concat(buffers))
        })
      )
    }),

    catReadableStream: (ipfsPath) => toStream.source(_catPullStream(ipfsPath)),

    catPullStream: _catPullStream,

    get: promisify((ipfsPath, callback) => {
      pull(
        exporter(ipfsPath, self._ipldResolver),
        pull.asyncMap((file, cb) => {
          if (file.content) {
            pull(
              file.content,
              pull.collect((err, buffers) => {
                if (err) { return cb(err) }
                file.content = Buffer.concat(buffers)
                cb(null, file)
              })
            )
          } else {
            cb(null, file)
          }
        }),
        pull.collect(callback)
      )
    }),

    getReadableStream: (ipfsPath) => {
      return toStream.source(
        pull(
          exporter(ipfsPath, self._ipldResolver),
          pull.map((file) => {
            if (file.content) {
              file.content = toStream.source(file.content)
              file.content.pause()
            }

            return file
          })
        )
      )
    },

    getPullStream: (ipfsPath) => {
      return exporter(ipfsPath, self._ipldResolver)
    },

    lsImmutable: promisify((ipfsPath, callback) => {
      pull(
        _lsPullStreamImmutable(ipfsPath),
        pull.collect((err, values) => {
          if (err) {
            return callback(err)
          }
          callback(null, values)
        })
      )
    }),

    lsReadableStreamImmutable: (ipfsPath) => {
      return toStream.source(_lsPullStreamImmutable(ipfsPath))
    },

    lsPullStreamImmutable: _lsPullStreamImmutable
  }
}
<commit_msg>fix: cat: test file existence after filtering (#1148)<commit_after>'use strict'

const unixfsEngine = require('ipfs-unixfs-engine')
const importer = unixfsEngine.importer
const exporter = unixfsEngine.exporter
const promisify = require('promisify-es6')
const pull = require('pull-stream')
const sort = require('pull-sort')
const pushable = require('pull-pushable')
const toStream = require('pull-stream-to-stream')
const toPull = require('stream-to-pull-stream')
const deferred = require('pull-defer')
const waterfall = require('async/waterfall')
const isStream = require('is-stream')
const Duplex = require('readable-stream').Duplex
const CID = require('cids')
const toB58String = require('multihashes').toB58String

function noop () {}

function prepareFile (self, opts, file, callback) {
  opts = opts || {}

  waterfall([
    (cb) => self.object.get(file.multihash, cb),
    (node, cb) => {
      let cid = new CID(node.multihash)

      if (opts['cid-version'] === 1) {
        cid = cid.toV1()
      }

      const b58Hash = cid.toBaseEncodedString()

      cb(null, {
        path: file.path || b58Hash,
        hash: b58Hash,
        size: node.size
      })
    }
  ], callback)
}

function normalizeContent (content) {
  if (!Array.isArray(content)) {
    content = [content]
  }

  return content.map((data) => {
    // Buffer input
    if (Buffer.isBuffer(data)) {
      data = { path: '', content: pull.values([data]) }
    }

    // Readable stream input
    if (isStream.readable(data)) {
      data = { path: '', content: toPull.source(data) }
    }

    if (data && data.content && typeof data.content !== 'function') {
      if (Buffer.isBuffer(data.content)) {
        data.content = pull.values([data.content])
      }

      if (isStream.readable(data.content)) {
        data.content = toPull.source(data.content)
      }
    }

    return data
  })
}

class AddHelper extends Duplex {
  constructor (pullStream, push, options) {
    super(Object.assign({ objectMode: true }, options))
    this._pullStream = pullStream
    this._pushable = push
    this._waitingPullFlush = []
  }

  _read () {
    this._pullStream(null, (end, data) => {
      while (this._waitingPullFlush.length) {
        const cb = this._waitingPullFlush.shift()
        cb()
      }
      if (end) {
        if (end instanceof Error) {
          this.emit('error', end)
        }
      } else {
        this.push(data)
      }
    })
  }

  _write (chunk, encoding, callback) {
    this._waitingPullFlush.push(callback)
    this._pushable.push(chunk)
  }
}

module.exports = function files (self) {
  function _addPullStream (options) {
    const opts = Object.assign({}, {
      shardSplitThreshold: self._options.EXPERIMENTAL.sharding
        ? 1000
        : Infinity
    }, options)

    let total = 0
    let prog = opts.progress || (() => {})
    const progress = (bytes) => {
      total += bytes
      prog(total)
    }

    opts.progress = progress
    return pull(
      pull.map(normalizeContent),
      pull.flatten(),
      importer(self._ipldResolver, opts),
      pull.asyncMap(prepareFile.bind(null, self, opts))
    )
  }

  function _catPullStream (ipfsPath) {
    if (typeof ipfsPath === 'function') {
      throw new Error('You must supply an ipfsPath')
    }

    ipfsPath = normalizePath(ipfsPath)
    const pathComponents = ipfsPath.split('/')
    const restPath = normalizePath(pathComponents.slice(1).join('/'))
    const filterFile = (file) => (restPath && file.path === restPath) || (file.path === ipfsPath)

    const d = deferred.source()

    pull(
      exporter(ipfsPath, self._ipldResolver),
      pull.collect((err, files) => {
        if (err) { return d.abort(err) }
        if (files && files.length > 1) {
          files = files.filter(filterFile)
        }
        if (!files || !files.length) {
          return d.abort(new Error('No such file'))
        }

        const file = files[0]
        const content = file.content
        if (!content && file.type === 'dir') {
          return d.abort(new Error('this dag node is a directory'))
        }
        d.resolve(content)
      })
    )

    return d
  }

  function _lsPullStreamImmutable (ipfsPath) {
    return pull(
      exporter(ipfsPath, self._ipldResolver, { maxDepth: 1 }),
      pull.filter((node) => node.depth === 1),
      pull.map((node) => {
        node = Object.assign({}, node, { hash: toB58String(node.hash) })
        delete node.content
        return node
      })
    )
  }

  return {
    add: promisify((data, options, callback) => {
      if (typeof options === 'function') {
        callback = options
        options = {}
      } else if (!callback || typeof callback !== 'function') {
        callback = noop
      }

      if (typeof data !== 'object' &&
          !Buffer.isBuffer(data) &&
          !isStream(data)) {
        return callback(new Error('Invalid arguments, data must be an object, Buffer or readable stream'))
      }

      pull(
        pull.values([data]),
        _addPullStream(options),
        sort((a, b) => {
          if (a.path < b.path) return 1
          if (a.path > b.path) return -1
          return 0
        }),
        pull.collect(callback)
      )
    }),

    addReadableStream: (options) => {
      options = options || {}

      const p = pushable()
      const s = pull(
        p,
        _addPullStream(options)
      )

      const retStream = new AddHelper(s, p)

      retStream.once('finish', () => p.end())

      return retStream
    },

    addPullStream: _addPullStream,

    cat: promisify((ipfsPath, callback) => {
      pull(
        _catPullStream(ipfsPath),
        pull.collect((err, buffers) => {
          if (err) { return callback(err) }
          callback(null, Buffer.concat(buffers))
        })
      )
    }),

    catReadableStream: (ipfsPath) => toStream.source(_catPullStream(ipfsPath)),

    catPullStream: _catPullStream,

    get: promisify((ipfsPath, callback) => {
      pull(
        exporter(ipfsPath, self._ipldResolver),
        pull.asyncMap((file, cb) => {
          if (file.content) {
            pull(
              file.content,
              pull.collect((err, buffers) => {
                if (err) { return cb(err) }
                file.content = Buffer.concat(buffers)
                cb(null, file)
              })
            )
          } else {
            cb(null, file)
          }
        }),
        pull.collect(callback)
      )
    }),

    getReadableStream: (ipfsPath) => {
      return toStream.source(
        pull(
          exporter(ipfsPath, self._ipldResolver),
          pull.map((file) => {
            if (file.content) {
              file.content = toStream.source(file.content)
              file.content.pause()
            }

            return file
          })
        )
      )
    },

    getPullStream: (ipfsPath) => {
      return exporter(ipfsPath, self._ipldResolver)
    },

    lsImmutable: promisify((ipfsPath, callback) => {
      pull(
        _lsPullStreamImmutable(ipfsPath),
        pull.collect((err, values) => {
          if (err) {
            return callback(err)
          }
          callback(null, values)
        })
      )
    }),

    lsReadableStreamImmutable: (ipfsPath) => {
      return toStream.source(_lsPullStreamImmutable(ipfsPath))
    },

    lsPullStreamImmutable: _lsPullStreamImmutable
  }
}

function normalizePath (path) {
  if (Buffer.isBuffer(path)) {
    path = toB58String(path)
  }
  if (path.indexOf('/ipfs/') === 0) {
    path = path.substring('/ipfs/'.length)
  }
  if (path.charAt(path.length - 1) === '/') {
    path = path.substring(0, path.length - 1)
  }

  return path
}
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import {createStyleSheet} from 'stylishly';
import {
  Table,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
} from 'material-ui/Table';
import Paper from 'material-ui/Paper';
import Checkbox from 'material-ui/Checkbox';

const styleSheet = createStyleSheet('SelectableTable', () => {
  return {
    paper: {
      width: '100%',
      marginTop: 30,
    },
  };
});

let dataId = 0;

function createData(name, calories, fat, carbs, protein) {
  dataId++;
  return {id: dataId, name, calories, fat, carbs, protein};
}

const data = [
  createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
  createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
  createData('Eclair', 262, 16.0, 24, 6.0),
  createData('Cupcake', 305, 3.7, 67, 4.3),
  createData('Gingerbread', 356, 16.0, 49, 3.9),
];

export default class SelectableTable extends Component {
  static contextTypes = {
    styleManager: PropTypes.object.isRequired,
  };

  state = {
    selected: [],
  };

  handleSelectAllClick = (event, checked) => {
    if (checked) {
      return this.setState({selected: data.map((n) => n.id)});
    }
    return this.setState({selected: []});
  };

  handleClick = (event, id) => {
    const {selected} = this.state;
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1)
      );
    }

    this.setState({selected: newSelected});
  };

  isSelected = (id) => {
    return this.state.selected.indexOf(id) !== -1;
  }

  render() {
    const classes = this.context.styleManager.render(styleSheet);

    return (
      <Paper zDepth={2} className={classes.paper}>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell checkbox={true}>
                <Checkbox onChange={this.handleSelectAllClick} />
              </TableCell>
              <TableCell padding={false}>Dessert (100g serving)</TableCell>
              <TableCell numeric={true}>Calories</TableCell>
              <TableCell numeric={true}>Fat (g)</TableCell>
              <TableCell numeric={true}>Carbs (g)</TableCell>
              <TableCell numeric={true}>Protein (g)</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {data.map((n) => {
              const selected = this.isSelected(n.id);
              return (
                <TableRow
                  hover={true}
                  onClick={(event) => this.handleClick(event, n.id)}
                  key={n.id}
                  selected={selected}
                >
                  <TableCell checkbox={true}>
                    <Checkbox checked={selected} />
                  </TableCell>
                  <TableCell padding={false}>{n.name}</TableCell>
                  <TableCell numeric={true}>{n.calories}</TableCell>
                  <TableCell numeric={true}>{n.fat}</TableCell>
                  <TableCell numeric={true}>{n.carbs}</TableCell>
                  <TableCell numeric={true}>{n.protein}</TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </Paper>
    );
  }
}

<commit_msg>Remove old example<commit_after><|endoftext|>


<commit_before>(function(global) {
    'use strict';
    // rule-based url building is based on werkzeug.contrib.jsrouting

    function BuildError(message) {
        var args = [];
        var arg_str;
        if (arguments.length > 1) {
            arg_str = JSON.stringify(Array.prototype.slice.call(arguments, 1));
            arg_str = arg_str.substring(1, arg_str.length - 1);
        }
        this.name = 'BuildError';
        this.message = message + (arg_str ? ': ' + arg_str : '');
        // remove the following when http://code.google.com/p/chromium/issues/detail?id=228909 is fixed
        var err = new Error(this.message);
        err.name = this.name;
        return err;
    }
    BuildError.prototype = new Error();
    BuildError.prototype.constructor = BuildError;

    var converter_functions = {
        // Put any converter functions for custom URL converters here. The key is the converter's python class name.
        // If there is no function, encodeURIComponent is used - so there's no need to put default converters here!
        ListConverter: function(value) {
            if (_.isArray(value)) {
                value = value.join('-');
            }
            return encodeURIComponent(value);
        }
    };

    function split_obj(obj) {
        // Splits an object into keys and values (and the object itself for convenience)
        var names = [];
        var values = [];
        for (var name in obj) {
            names.push(name);
            values.push(obj[name]);
        }
        return { names: names, values: values, original: obj };
    }

    function suitable(rule, args) {
        // Checks if a rule is suitable for the given arguments
        var default_args = split_obj(rule.defaults || {});
        var diff_arg_names = _.difference(rule.args, default_args.names);
        var i;

        // If a rule arg that has no default value is missing, the rule is not suitable
        for (i = 0; i < diff_arg_names.length; i++) {
            if (!~_.indexOf(args.names, diff_arg_names[i])) {
                return false;
            }
        }

        if (_.difference(rule.args, args.names).length == 0) {
            if (!rule.defaults) {
                return true;
            }
            // If a default argument is provided with a different value, the rule is not suitable
            for (i = 0; i < default_args.names.length; i++) {
                var key = default_args.names[i];
                var value = default_args.values[i];
                if (value != args.original[key]) {
                    return false;
                }
            }
        }

        return true;
    }

    function build(rule, args) {
        var tmp = [];
        var processed = rule.args.slice();
        for (var i = 0; i < rule.trace.length; i++) {
            var part = rule.trace[i];
            if (part.is_dynamic) {
                var converter = converter_functions[rule.converters[part.data]] || encodeURIComponent;
                var value = converter(args.original[part.data]);
                if (value === null) {
                    return null;
                }
                tmp.push(value);
                processed.push(part.name);
            }
            else {
                tmp.push(part.data);
            }
        }
        tmp = tmp.join('');
        var pipe = tmp.indexOf('|');
        // if we had subdomain routes, the subdomain would come before the pipe
        var url = tmp.substring(pipe + 1);
        var unprocessed = _.difference(args.names, processed);
        return { url: url, unprocessed: unprocessed };
    }

    function fix_params(params) {
        var clean_params = {};
        for (var key in params) {
            var value = params[key];
            if (value === undefined || value === null) {
                // convert them to a string
                value = '' + value
            }
            if (!_.isObject(value) || _.isArray(value)) {
                clean_params[key] = value;
            }
        }
        return clean_params;
    }

    function build_url(template, params, fragment) {
        var qsParams, url;

        params = fix_params(params);

        if (typeof template == 'string') {
            url = template;
            qsParams = params || {};
        }
        else if (template.type == 'flask_rules') {
            var args = split_obj(params || {});
            for (var i = 0; i < template.rules.length; i++) {
                var rule = template.rules[i];
                if (suitable(rule, args)) {
                    var res = build(rule, args);
                    if (res === null) {
                        continue;
                    }
                    url = res.url;
                    qsParams = _.pick(params, res.unprocessed);
                    break;
                }
            }

            if (!url) {
                throw new BuildError('Could not build an URL', template.endpoint, params);
            }

            url = Indico.Urls.Base + url;
        }
        else {
            throw new BuildError('Invalid URL template', template);
        }

        var qs = $.param(qsParams);
        if (qs) {
            url += (~url.indexOf('?') ? '&' : '?') + qs;
        }
        if (fragment) {
            url += '#' + fragment;
        }
        return url;
    }

    global.BuildError = BuildError;
    global.build_url = build_url;
})(window);
<commit_msg>[FIX] Empty param handling in JS url building<commit_after>(function(global) {
    'use strict';
    // rule-based url building is based on werkzeug.contrib.jsrouting

    function BuildError(message) {
        var args = [];
        var arg_str;
        if (arguments.length > 1) {
            arg_str = JSON.stringify(Array.prototype.slice.call(arguments, 1));
            arg_str = arg_str.substring(1, arg_str.length - 1);
        }
        this.name = 'BuildError';
        this.message = message + (arg_str ? ': ' + arg_str : '');
        // remove the following when http://code.google.com/p/chromium/issues/detail?id=228909 is fixed
        var err = new Error(this.message);
        err.name = this.name;
        return err;
    }
    BuildError.prototype = new Error();
    BuildError.prototype.constructor = BuildError;

    var converter_functions = {
        // Put any converter functions for custom URL converters here. The key is the converter's python class name.
        // If there is no function, encodeURIComponent is used - so there's no need to put default converters here!
        ListConverter: function(value) {
            if (_.isArray(value)) {
                value = value.join('-');
            }
            return encodeURIComponent(value);
        }
    };

    function split_obj(obj) {
        // Splits an object into keys and values (and the object itself for convenience)
        var names = [];
        var values = [];
        for (var name in obj) {
            names.push(name);
            values.push(obj[name]);
        }
        return { names: names, values: values, original: obj };
    }

    function suitable(rule, args) {
        // Checks if a rule is suitable for the given arguments
        var default_args = split_obj(rule.defaults || {});
        var diff_arg_names = _.difference(rule.args, default_args.names);
        var i;

        // If a rule arg that has no default value is missing, the rule is not suitable
        for (i = 0; i < diff_arg_names.length; i++) {
            if (!~_.indexOf(args.names, diff_arg_names[i])) {
                return false;
            }
        }

        if (_.difference(rule.args, args.names).length == 0) {
            if (!rule.defaults) {
                return true;
            }
            // If a default argument is provided with a different value, the rule is not suitable
            for (i = 0; i < default_args.names.length; i++) {
                var key = default_args.names[i];
                var value = default_args.values[i];
                if (value != args.original[key]) {
                    return false;
                }
            }
        }

        return true;
    }

    function build(rule, args) {
        var tmp = [];
        var processed = rule.args.slice();
        for (var i = 0; i < rule.trace.length; i++) {
            var part = rule.trace[i];
            if (part.is_dynamic) {
                var converter = converter_functions[rule.converters[part.data]] || encodeURIComponent;
                var value = converter(args.original[part.data]);
                if (value === null) {
                    return null;
                }
                tmp.push(value);
                processed.push(part.name);
            }
            else {
                tmp.push(part.data);
            }
        }
        tmp = tmp.join('');
        var pipe = tmp.indexOf('|');
        // if we had subdomain routes, the subdomain would come before the pipe
        var url = tmp.substring(pipe + 1);
        var unprocessed = _.difference(args.names, processed);
        return { url: url, unprocessed: unprocessed };
    }

    function fix_params(params) {
        var clean_params = {};
        for (var key in params) {
            var value = params[key];
            if (value === '') {
                continue;
            }
            if (value === undefined || value === null) {
                // convert them to a string
                value = '' + value
            }
            if (!_.isObject(value) || _.isArray(value)) {
                clean_params[key] = value;
            }
        }
        return clean_params;
    }

    function build_url(template, params, fragment) {
        var qsParams, url;

        params = fix_params(params);

        if (typeof template == 'string') {
            url = template;
            qsParams = params || {};
        }
        else if (template.type == 'flask_rules') {
            var args = split_obj(params || {});
            for (var i = 0; i < template.rules.length; i++) {
                var rule = template.rules[i];
                if (suitable(rule, args)) {
                    var res = build(rule, args);
                    if (res === null) {
                        continue;
                    }
                    url = res.url;
                    qsParams = _.pick(params, res.unprocessed);
                    break;
                }
            }

            if (!url) {
                throw new BuildError('Could not build an URL', template.endpoint, params);
            }

            url = Indico.Urls.Base + url;
        }
        else {
            throw new BuildError('Invalid URL template', template);
        }

        var qs = $.param(qsParams);
        if (qs) {
            url += (~url.indexOf('?') ? '&' : '?') + qs;
        }
        if (fragment) {
            url += '#' + fragment;
        }
        return url;
    }

    global.BuildError = BuildError;
    global.build_url = build_url;
})(window);
<|endoftext|>


<commit_before><commit_msg>Add missing semicolon<commit_after><|endoftext|>


<commit_before>var FiltersUI = React.createClass(
{
    filterColumns: [],

    componentWillMount: function()
    {
        this.filterColumns.push(GameColumns[0]);
        this.filterColumns.push(GameColumns[3]);
        this.filterColumns.push(GameColumns[4]);
        this.filterColumns.push(GameColumns[5]);
        this.filterColumns.push(GameColumns[6]);
        this.filterColumns.push(GameColumns[7]);
        this.filterColumns.push(GameColumns[8]);
    },

    getInitialState: function()
    {
        var answer;

        if (localStorage.filters)
        {
            var filters = JSON.parse(localStorage.filters);
            answer = {};

            filters.forEach(function(filter)
            {
                answer[filter.columnKey] = filter;
            });
        }
        else
        {
            answer = this.createDefaults();
        }

        return answer;
    },

    render: function()
    {
        var rows = [];

        this.filterColumns.forEach(function(column)
        {
            rows.push(this.createRow(rows.length, column));
        }, this);

        var filterTable = React.DOM.table(
        {
            className: "filterTable",
        }, rows);

        var rows2 = [];
        rows2.push(React.DOM.tr(
        {
            key: 0,
        }, React.DOM.td(
        {
            colSpan: 2,
        }, filterTable)));

        // var restoreButton = React.DOM.button(
        // {
        // onClick: this.restoreActionPerformed,
        // }, "Restore Defaults");
        var unfilterButton = React.DOM.button(
        {
            onClick: this.unfilterActionPerformed,
        }, "Remove Filter");
        var filterButton = React.DOM.button(
        {
            onClick: this.filterActionPerformed,
        }, "Apply Filter");
        rows2.push(React.DOM.tr(
        {
            key: 1,
        }, // React.DOM.td({}, restoreButton),
        React.DOM.td({}, unfilterButton), React.DOM.td({}, filterButton)));

        return React.DOM.table(
        {
            className: "filtersUI",
        }, rows2);
    },

    createCell: function(key, column, value)
    {
        return React.DOM.td(
        {
            key: key,
            className: column.className,
            column: column.key,
        }, value);
    },

    createDefaults: function()
    {
        return (
        {
            boardGameRank: GameDatabase.newFilter("boardGameRank", false, 1, false, 20),
            yearPublished: GameDatabase.newFilter("yearPublished", false, 2000, false, 2015),
            geekRating: GameDatabase.newFilter("geekRating", true, 7.2, false, 10),
            minPlayers: GameDatabase.newFilter("minPlayers", true, 2, true, 3),
            maxPlayers: GameDatabase.newFilter("maxPlayers", true, 4, false, 6),
            minPlayTime: GameDatabase.newFilter("minPlayTime", true, 30, false, 120),
            maxPlayTime: GameDatabase.newFilter("maxPlayTime", false, 30, true, 120),
        });
    },

    createFilter: function(columnKey)
    {
        var isMinEnabled = document.getElementById(columnKey + "MinChecked").checked;

        var minValue = document.getElementById(columnKey + "Min").value;
        minValue = (minValue ? parseFloat(minValue) : undefined);
        LOGGER.debug(columnKey + " isMinEnabled, minValue = " + isMinEnabled + " " + minValue);

        var isMaxEnabled = document.getElementById(columnKey + "MaxChecked").checked;

        var maxValue = document.getElementById(columnKey + "Max").value;
        maxValue = (maxValue ? parseFloat(maxValue) : undefined);
        LOGGER.debug(columnKey + " isMaxEnabled, maxValue = " + isMaxEnabled + " " + maxValue);

        return GameDatabase.newFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue);
    },

    createRow: function(key, column)
    {
        var cells = [];
        var filter = this.state[column.key];
        if (!filter) { throw "ERROR: missing filter for column = " + column.key; }

        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "MinChecked",
            type: "checkbox",
            defaultChecked: filter.isMinEnabled,
        })));
        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "Min",
            type: "number",
            className: "filterField",
            defaultValue: filter.minValue,
        })));

        cells.push(React.DOM.td(
        {
            key: cells.length,
            className: "filterLabel",
            column: column.key,
        }, "\u2264 " + column.label + " \u2264"));

        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "MaxChecked",
            type: "checkbox",
            defaultChecked: filter.isMaxEnabled,
        })));
        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "Max",
            type: "number",
            className: "filterField",
            defaultValue: filter.maxValue,
        })));

        return React.DOM.tr(
        {
            key: key
        }, cells);
    },

    filterActionPerformed: function(event)
    {
        LOGGER.info("FiltersUI.filterActionPerformed() start");

        var filters = [];

        this.filterColumns.forEach(function(column)
        {
            filters.push(this.createFilter(column.key));
        }, this);

        this.trigger("applyFilters", filters);
        localStorage.filters = JSON.stringify(filters);

        LOGGER.info("FiltersUI.filterActionPerformed() end");
    },

    // restoreActionPerformed: function(event)
    // {
    // LOGGER.info("FiltersUI.restoreActionPerformed() start");
    //
    // var filters = [];
    // this.setState(this.createDefaults());
    //
    // LOGGER.info("FiltersUI.restoreActionPerformed() end");
    // },

    unfilterActionPerformed: function(event)
    {
        LOGGER.info("FiltersUI.unfilterActionPerformed() start");

        var filters = [];

        this.trigger("applyFilters", filters);

        LOGGER.info("FiltersUI.unfilterActionPerformed() end");
    },
});

MicroEvent.mixin(FiltersUI);
<commit_msg>Updated the default filter settings.<commit_after>var FiltersUI = React.createClass(
{
    filterColumns: [],

    componentWillMount: function()
    {
        this.filterColumns.push(GameColumns[0]);
        this.filterColumns.push(GameColumns[3]);
        this.filterColumns.push(GameColumns[4]);
        this.filterColumns.push(GameColumns[5]);
        this.filterColumns.push(GameColumns[6]);
        this.filterColumns.push(GameColumns[7]);
        this.filterColumns.push(GameColumns[8]);
    },

    getInitialState: function()
    {
        var answer;

        if (localStorage.filters)
        {
            var filters = JSON.parse(localStorage.filters);
            answer = {};

            filters.forEach(function(filter)
            {
                answer[filter.columnKey] = filter;
            });
        }
        else
        {
            answer = this.createDefaults();
        }

        return answer;
    },

    render: function()
    {
        var rows = [];

        this.filterColumns.forEach(function(column)
        {
            rows.push(this.createRow(rows.length, column));
        }, this);

        var filterTable = React.DOM.table(
        {
            className: "filterTable",
        }, rows);

        var rows2 = [];
        rows2.push(React.DOM.tr(
        {
            key: 0,
        }, React.DOM.td(
        {
            colSpan: 2,
        }, filterTable)));

        // var restoreButton = React.DOM.button(
        // {
        // onClick: this.restoreActionPerformed,
        // }, "Restore Defaults");
        var unfilterButton = React.DOM.button(
        {
            onClick: this.unfilterActionPerformed,
        }, "Remove Filter");
        var filterButton = React.DOM.button(
        {
            onClick: this.filterActionPerformed,
        }, "Apply Filter");
        rows2.push(React.DOM.tr(
        {
            key: 1,
        }, // React.DOM.td({}, restoreButton),
        React.DOM.td({}, unfilterButton), React.DOM.td({}, filterButton)));

        return React.DOM.table(
        {
            className: "filtersUI",
        }, rows2);
    },

    createCell: function(key, column, value)
    {
        return React.DOM.td(
        {
            key: key,
            className: column.className,
            column: column.key,
        }, value);
    },

    createDefaults: function()
    {
        return (
        {
            boardGameRank: GameDatabase.newFilter("boardGameRank", false, 1, false, 20),
            yearPublished: GameDatabase.newFilter("yearPublished", false, 2005, false, 2015),
            geekRating: GameDatabase.newFilter("geekRating", false, 7.2, false, 10),
            minPlayers: GameDatabase.newFilter("minPlayers", true, 2, true, 3),
            maxPlayers: GameDatabase.newFilter("maxPlayers", true, 4, false, 6),
            minPlayTime: GameDatabase.newFilter("minPlayTime", true, 30, false, 120),
            maxPlayTime: GameDatabase.newFilter("maxPlayTime", false, 30, true, 120),
        });
    },

    createFilter: function(columnKey)
    {
        var isMinEnabled = document.getElementById(columnKey + "MinChecked").checked;

        var minValue = document.getElementById(columnKey + "Min").value;
        minValue = (minValue ? parseFloat(minValue) : undefined);
        LOGGER.debug(columnKey + " isMinEnabled, minValue = " + isMinEnabled + " " + minValue);

        var isMaxEnabled = document.getElementById(columnKey + "MaxChecked").checked;

        var maxValue = document.getElementById(columnKey + "Max").value;
        maxValue = (maxValue ? parseFloat(maxValue) : undefined);
        LOGGER.debug(columnKey + " isMaxEnabled, maxValue = " + isMaxEnabled + " " + maxValue);

        return GameDatabase.newFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue);
    },

    createRow: function(key, column)
    {
        var cells = [];
        var filter = this.state[column.key];
        if (!filter) { throw "ERROR: missing filter for column = " + column.key; }

        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "MinChecked",
            type: "checkbox",
            defaultChecked: filter.isMinEnabled,
        })));
        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "Min",
            type: "number",
            className: "filterField",
            defaultValue: filter.minValue,
        })));

        cells.push(React.DOM.td(
        {
            key: cells.length,
            className: "filterLabel",
            column: column.key,
        }, "\u2264 " + column.label + " \u2264"));

        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "MaxChecked",
            type: "checkbox",
            defaultChecked: filter.isMaxEnabled,
        })));
        cells.push(this.createCell(cells.length, column, React.DOM.input(
        {
            key: cells.length,
            id: column.key + "Max",
            type: "number",
            className: "filterField",
            defaultValue: filter.maxValue,
        })));

        return React.DOM.tr(
        {
            key: key
        }, cells);
    },

    filterActionPerformed: function(event)
    {
        LOGGER.info("FiltersUI.filterActionPerformed() start");

        var filters = [];

        this.filterColumns.forEach(function(column)
        {
            filters.push(this.createFilter(column.key));
        }, this);

        this.trigger("applyFilters", filters);
        localStorage.filters = JSON.stringify(filters);

        LOGGER.info("FiltersUI.filterActionPerformed() end");
    },

    // restoreActionPerformed: function(event)
    // {
    // LOGGER.info("FiltersUI.restoreActionPerformed() start");
    //
    // var filters = [];
    // this.setState(this.createDefaults());
    //
    // LOGGER.info("FiltersUI.restoreActionPerformed() end");
    // },

    unfilterActionPerformed: function(event)
    {
        LOGGER.info("FiltersUI.unfilterActionPerformed() start");

        var filters = [];

        this.trigger("applyFilters", filters);

        LOGGER.info("FiltersUI.unfilterActionPerformed() end");
    },
});

MicroEvent.mixin(FiltersUI);
<|endoftext|>


<commit_before>dojo.provide("dijit.Menu");

dojo.require("dijit._Widget");
dojo.require("dijit._Container");
dojo.require("dijit._Templated");

dojo.declare(
	"dijit.Menu",
	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
{
	constructor: function() {
		this._bindings = [];
	},

	templateString:
			'
' +
				'

'+
			'
',

	// targetNodeIds: String[]
	//	Array of dom node ids of nodes to attach to.
	//	Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
	targetNodeIds: [],

	// contextMenuForWindow: Boolean
	//	if true, right clicking anywhere on the window will cause this context menu to open;
	//	if false, must specify targetNodeIds
	contextMenuForWindow: false,

	// parentMenu: Widget
	// pointer to menu that displayed me
	parentMenu: null,

	// popupDelay: Integer
	//	number of milliseconds before hovering (without clicking) causes the popup to automatically open
	popupDelay: 500,

	// _contextMenuWithMouse: Boolean
	//	used to record mouse and keyboard events to determine if a context
	//	menu is being opened with the keyboard or the mouse
	_contextMenuWithMouse: false,

	postCreate: function(){
		if(this.contextMenuForWindow){
			this.bindDomNode(dojo.body());
		}else{
			dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
		}
		this.connectKeyNavHandlers([dojo.keys.UP_ARROW], [dojo.keys.DOWN_ARROW]);
	},

	startup: function(){
		dojo.forEach(this.getChildren(), function(child){ child.startup(); });
		this.startupKeyNavChildren();
	},

	onExecute: function(){
		// summary: attach point for notification about when a menu item has been executed
	},

	onCancel: function(/*Boolean*/ closeAll){
		// summary: attach point for notification about when the user cancels the current menu
	},

	_moveToPopup: function(/*Event*/ evt){
		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
			this.focusedChild._onClick(evt);
		}
	},

	_onKeyPress: function(/*Event*/ evt){
		// summary
		//	Handle keyboard based menu navigation.
		if(evt.ctrlKey || evt.altKey){ return; }

		switch(evt.keyCode){
			case dojo.keys.RIGHT_ARROW:
				this._moveToPopup(evt);
				dojo.stopEvent(evt);
				break;
			case dojo.keys.LEFT_ARROW:
				if(this.parentMenu){
					this.onCancel(false);
				}else{
					dojo.stopEvent(evt);
				}
				break;
		}
	},

	onItemHover: function(/*MenuItem*/ item){
		this.focusChild(item);

		if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
			this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
		}
	},

	_onChildBlur: function(item){
		// Close all popups that are open and descendants of this menu
		dijit.popup.close(item.popup);
		item._blur();
		this._stopPopupTimer();
	},

	onItemUnhover: function(/*MenuItem*/ item){
	},

	_stopPopupTimer: function(){
		if(this.hover_timer){
			clearTimeout(this.hover_timer);
			this.hover_timer = null;
		}
	},

	_getTopMenu: function(){
		for(var top=this; top.parentMenu; top=top.parentMenu);
		return top;
	},

	onItemClick: function(/*Widget*/ item){
		// summary: user defined function to handle clicks on an item
		// summary: internal function for clicks
		if(item.disabled){ return false; }

		if(item.popup){
			if(!this.is_open){
				this._openPopup();
			}
		}else{
			// before calling user defined handler, close hierarchy of menus
			// and restore focus to place it was when menu was opened
			this.onExecute();

			// user defined handler for click
			item.onClick();
		}
	},

	// thanks burstlib!
	_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el) {
		//	summary
		//	returns the window reference of the passed iframe
		var win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
			// Moz. TODO: is this available when defaultView isn't?
			dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||
			(iframe_el.name && document.frames[iframe_el.name]) || null;
		return win;	//	Window
	},

	_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
		//	summary
		//	returns a reference to the document object inside iframe_el
		var doc = iframe_el.contentDocument // W3
			|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
			|| (iframe_el.name && document.frames[iframe_el.name] && document.frames[iframe_el.name].document)
			|| null;
		return doc;	//	HTMLDocument
	},

	bindDomNode: function(/*String|DomNode*/ node){
		// summary: attach menu to given node
		node = dojo.byId(node);

		//TODO: this is to support context popups in Editor.  Maybe this shouldn't be in dijit.Menu
		var win = dijit.getDocumentWindow(node.ownerDocument);
		if(node.tagName.toLowerCase()=="iframe"){
			win = this._iframeContentWindow(node);
			node = dojo.withGlobal(win, dojo.body);
		}

		// to capture these events at the top level,
		// attach to document, not body
		var cn = (node == dojo.body() ? dojo.doc : node);

		node[this.id] = this._bindings.push([
			dojo.connect(cn, "oncontextmenu", this, "_openMyself"),
			dojo.connect(cn, "onkeydown", this, "_contextKey"),
			dojo.connect(cn, "onmousedown", this, "_contextMouse")
		]);
	},

	unBindDomNode: function(/*String|DomNode*/ nodeName){
		// summary: detach menu from given node
		var node = dojo.byId(nodeName);
		var bid = node[this.id]-1, b = this._bindings[bid];
		dojo.forEach(b, dojo.disconnect);
		delete this._bindings[bid];
	},

	_contextKey: function(e){
		this._contextMenuWithMouse = false;
		if (e.keyCode == dojo.keys.F10) {
			dojo.stopEvent(e);
			if (e.shiftKey && e.type=="keydown") {
				// FF: copying the wrong property from e will cause the system
				// context menu to appear in spite of stopEvent. Don't know
				// exactly which properties cause this effect.
				var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
				_e.preventDefault = _e.stopPropagation = function(){};
				// IE: without the delay, focus work in "open" causes the system
				// context menu to appear in spite of stopEvent.
				window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
			}
		}
	},

	_contextMouse: function(e){
		this._contextMenuWithMouse = true;
	},

	_openMyself: function(/*Event*/ e){
		// summary:
		//		Internal function for opening myself when the user
		//		does a right-click or something similar

		dojo.stopEvent(e);

		// Get coordinates.
		// if we are opening the menu with the mouse or on safari open
		// the menu at the mouse cursor
		// (Safari does not have a keyboard command to open the context menu
		// and we don't currently have a reliable way to determine
		// _contextMenuWithMouse on Safari)
		var x,y;
		if(dojo.isSafari || this._contextMenuWithMouse){
			x=e.pageX;
			y=e.pageY;
		}else{
			// otherwise open near e.target
			var coords = dojo.coords(e.target, true);
			x = coords.x + 10;
			y = coords.y + 10;
		}

		var self=this;
		var savedFocus = dijit.getFocus(this);
		function closeAndRestoreFocus(){
			// user has clicked on a menu or popup
			dijit.focus(savedFocus);
			dijit.popup.close(self);
		}
		dijit.popup.open({
			popup: this,
			x: x,
			y: y,
			onExecute: closeAndRestoreFocus,
			onCancel: closeAndRestoreFocus,
			orient: this.isLeftToRight() ? 'L' : 'R'
		});
		this.focus();

		this._onBlur = function(){
			// Usually the parent closes the child widget but if this is a context
			// menu then there is no parent
			dijit.popup.close(this);
			// don't try to restore focus; user has clicked another part of the screen
			// and set focus there
		}
	},

	onOpen: function(/*Event*/ e){
		// summary
		//		Open menu relative to the mouse
		this.isShowingNow = true;
	},

	onClose: function(){
		// summary: callback when this menu is closed
		this._stopPopupTimer();
		this.parentMenu = null;
		this.isShowingNow = false;
		this.currentPopup = null;
		if(this.focusedChild){
			this._onChildBlur(this.focusedChild);
			this.focusedChild = null;
		}
	},

	_openPopup: function(){
		// summary: open the popup to the side of the current menu item
		this._stopPopupTimer();
		var from_item = this.focusedChild;
		var popup = from_item.popup;

		if(popup.isShowingNow){ return; }
		popup.parentMenu = this;
		var self = this;
		dijit.popup.open({
			parent: this,
			popup: popup,
			around: from_item.arrowCell,
			orient: this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'},
			onCancel: function(){
				// called when the child menu is canceled
				dijit.popup.close(popup);
				from_item.focus();	// put focus back on my node
				self.currentPopup = null;
			}
		});

		this.currentPopup = popup;

		if(popup.focus){
			popup.focus();
		}
	}
}
);

dojo.declare(
	"dijit.MenuItem",
	[dijit._Widget, dijit._Templated, dijit._Contained],
{
	// summary
	//	A line item in a Menu2

	// Make 3 columns
	//   icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
	templateString:
		 '
'
		+'

	'
		+'	'
		+''
			+'
'
			+'+'
			+'
'
		+'	'
		+'
',

	// label: String
	//	menu text
	label: '',

	// iconClass: String
	//	class to apply to div in button to make it display an icon
	iconClass: "",

	// disabled: Boolean
	//  if true, the menu item is disabled
	//  if false, the menu item is enabled
	disabled: false,

	postCreate: function(){
		dojo.setSelectable(this.domNode, false);
		this.setDisabled(this.disabled);
		if(this.label){
			this.containerNode.innerHTML=this.label;
		}
	},

	_onHover: function(){
		// summary: callback when mouse is moved onto menu item
		this.getParent().onItemHover(this);
	},

	_onUnhover: function(){
		// summary: callback when mouse is moved off of menu item
		// if we are unhovering the currently selected item
		// then unselect it
		this.getParent().onItemUnhover(this);
	},

	_onClick: function(evt){
		this.getParent().onItemClick(this);
		dojo.stopEvent(evt);
	},

	onClick: function() {
		// summary
		//	User defined function to handle clicks
	},

	focus: function(){
		dojo.addClass(this.domNode, 'dijitMenuItemHover');
		try{
			dijit.focus(this.containerNode);
		}catch(e){
			// this throws on IE (at least) in some scenarios
		}
	},

	_blur: function(){
		dojo.removeClass(this.domNode, 'dijitMenuItemHover');
	},

	setDisabled: function(/*Boolean*/ value){
		// summary: enable or disable this menu item
		this.disabled = value;
		dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
		dijit.setWaiState(this.containerNode, 'disabled', value ? 'true' : 'false');
	}
});

dojo.declare(
	"dijit.PopupMenuItem",
	dijit.MenuItem,
{
	_fillContent: function(){
		// my inner HTML contains both the menu item text and a popup widget, like
		//

		//		pick me
		//		<popup> ... </popup>
		//

		// the first part holds the menu item text and the second part is the popup
		if(this.srcNodeRef){
			var nodes = dojo.query("*", this.srcNodeRef);
			dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);

			// save pointer to srcNode so we can grab the drop down widget after it's instantiated
			this.dropDownContainer = this.srcNodeRef;
		}
	},

	startup: function(){
		// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
		// land now.  move it to document.body.
		if(!this.popup){
			var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
			this.popup = dijit.byNode(node);
		}
		dojo.body().appendChild(this.popup.domNode);

		this.popup.domNode.style.display="none";
		dojo.addClass(this.expand, "dijitMenuExpandEnabled");
		dojo.style(this.expand, "display", "");
		dijit.setWaiState(this.containerNode, "haspopup", "true");
	}
});

dojo.declare(
	"dijit.MenuSeparator",
	[dijit._Widget, dijit._Templated, dijit._Contained],
{
	// summary
	//	A line between two menu items

	templateString: '
'
			+'

'
			+'

'
			+'
',

	postCreate: function(){
		dojo.setSelectable(this.domNode, false);
	},

	isFocusable: function(){
		// summary:
		//		over ride to always return false
		return false;
	}
});
<commit_msg>refs #4820 - documnetation updates<commit_after>dojo.provide("dijit.Menu");

dojo.require("dijit._Widget");
dojo.require("dijit._Container");
dojo.require("dijit._Templated");

dojo.declare("dijit.Menu",
	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
	{
	constructor: function() {
		this._bindings = [];
	},

	templateString:
			'
' +
				'

'+
			'
',

	// targetNodeIds: String[]
	//	Array of dom node ids of nodes to attach to.
	//	Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
	targetNodeIds: [],

	// contextMenuForWindow: Boolean
	//	if true, right clicking anywhere on the window will cause this context menu to open;
	//	if false, must specify targetNodeIds
	contextMenuForWindow: false,

	// parentMenu: Widget
	// pointer to menu that displayed me
	parentMenu: null,

	// popupDelay: Integer
	//	number of milliseconds before hovering (without clicking) causes the popup to automatically open
	popupDelay: 500,

	// _contextMenuWithMouse: Boolean
	//	used to record mouse and keyboard events to determine if a context
	//	menu is being opened with the keyboard or the mouse
	_contextMenuWithMouse: false,

	postCreate: function(){
		if(this.contextMenuForWindow){
			this.bindDomNode(dojo.body());
		}else{
			dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
		}
		this.connectKeyNavHandlers([dojo.keys.UP_ARROW], [dojo.keys.DOWN_ARROW]);
	},

	startup: function(){
		dojo.forEach(this.getChildren(), function(child){ child.startup(); });
		this.startupKeyNavChildren();
	},

	onExecute: function(){
		// summary: attach point for notification about when a menu item has been executed
	},

	onCancel: function(/*Boolean*/ closeAll){
		// summary: attach point for notification about when the user cancels the current menu
	},

	_moveToPopup: function(/*Event*/ evt){
		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
			this.focusedChild._onClick(evt);
		}
	},

	_onKeyPress: function(/*Event*/ evt){
		// summary: Handle keyboard based menu navigation.
		if(evt.ctrlKey || evt.altKey){ return; }

		switch(evt.keyCode){
			case dojo.keys.RIGHT_ARROW:
				this._moveToPopup(evt);
				dojo.stopEvent(evt);
				break;
			case dojo.keys.LEFT_ARROW:
				if(this.parentMenu){
					this.onCancel(false);
				}else{
					dojo.stopEvent(evt);
				}
				break;
		}
	},

	onItemHover: function(/*MenuItem*/ item){
		// summary: Called when cursor is over a MenuItem
		this.focusChild(item);

		if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
			this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
		}
	},

	_onChildBlur: function(item){
		// summary: Close all popups that are open and descendants of this menu
		dijit.popup.close(item.popup);
		item._blur();
		this._stopPopupTimer();
	},

	onItemUnhover: function(/*MenuItem*/ item){
		// summary: Callback fires when mouse exits a MenuItem
	},

	_stopPopupTimer: function(){
		if(this.hover_timer){
			clearTimeout(this.hover_timer);
			this.hover_timer = null;
		}
	},

	_getTopMenu: function(){
		for(var top=this; top.parentMenu; top=top.parentMenu);
		return top;
	},

	onItemClick: function(/*Widget*/ item){
		// summary: user defined function to handle clicks on an item
		if(item.disabled){ return false; }

		if(item.popup){
			if(!this.is_open){
				this._openPopup();
			}
		}else{
			// before calling user defined handler, close hierarchy of menus
			// and restore focus to place it was when menu was opened
			this.onExecute();

			// user defined handler for click
			item.onClick();
		}
	},

	// thanks burstlib!
	_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el) {
		// summary:
		//	Returns the window reference of the passed iframe
		var win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
			// Moz. TODO: is this available when defaultView isn't?
			dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||
			(iframe_el.name && document.frames[iframe_el.name]) || null;
		return win;	//	Window
	},

	_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
		// summary:
		//	Returns a reference to the document object inside iframe_el
		var doc = iframe_el.contentDocument // W3
			|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
			|| (iframe_el.name && document.frames[iframe_el.name] && document.frames[iframe_el.name].document)
			|| null;
		return doc;	//	HTMLDocument
	},

	bindDomNode: function(/*String|DomNode*/ node){
		// summary: attach menu to given node
		node = dojo.byId(node);

		//TODO: this is to support context popups in Editor.  Maybe this shouldn't be in dijit.Menu
		var win = dijit.getDocumentWindow(node.ownerDocument);
		if(node.tagName.toLowerCase()=="iframe"){
			win = this._iframeContentWindow(node);
			node = dojo.withGlobal(win, dojo.body);
		}

		// to capture these events at the top level,
		// attach to document, not body
		var cn = (node == dojo.body() ? dojo.doc : node);

		node[this.id] = this._bindings.push([
			dojo.connect(cn, "oncontextmenu", this, "_openMyself"),
			dojo.connect(cn, "onkeydown", this, "_contextKey"),
			dojo.connect(cn, "onmousedown", this, "_contextMouse")
		]);
	},

	unBindDomNode: function(/*String|DomNode*/ nodeName){
		// summary: detach menu from given node
		var node = dojo.byId(nodeName);
		var bid = node[this.id]-1, b = this._bindings[bid];
		dojo.forEach(b, dojo.disconnect);
		delete this._bindings[bid];
	},

	_contextKey: function(e){
		this._contextMenuWithMouse = false;
		if (e.keyCode == dojo.keys.F10) {
			dojo.stopEvent(e);
			if (e.shiftKey && e.type=="keydown") {
				// FF: copying the wrong property from e will cause the system
				// context menu to appear in spite of stopEvent. Don't know
				// exactly which properties cause this effect.
				var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
				_e.preventDefault = _e.stopPropagation = function(){};
				// IE: without the delay, focus work in "open" causes the system
				// context menu to appear in spite of stopEvent.
				window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
			}
		}
	},

	_contextMouse: function(e){
		this._contextMenuWithMouse = true;
	},

	_openMyself: function(/*Event*/ e){
		// summary:
		//		Internal function for opening myself when the user
		//		does a right-click or something similar

		dojo.stopEvent(e);

		// Get coordinates.
		// if we are opening the menu with the mouse or on safari open
		// the menu at the mouse cursor
		// (Safari does not have a keyboard command to open the context menu
		// and we don't currently have a reliable way to determine
		// _contextMenuWithMouse on Safari)
		var x,y;
		if(dojo.isSafari || this._contextMenuWithMouse){
			x=e.pageX;
			y=e.pageY;
		}else{
			// otherwise open near e.target
			var coords = dojo.coords(e.target, true);
			x = coords.x + 10;
			y = coords.y + 10;
		}

		var self=this;
		var savedFocus = dijit.getFocus(this);
		function closeAndRestoreFocus(){
			// user has clicked on a menu or popup
			dijit.focus(savedFocus);
			dijit.popup.close(self);
		}
		dijit.popup.open({
			popup: this,
			x: x,
			y: y,
			onExecute: closeAndRestoreFocus,
			onCancel: closeAndRestoreFocus,
			orient: this.isLeftToRight() ? 'L' : 'R'
		});
		this.focus();

		this._onBlur = function(){
			// Usually the parent closes the child widget but if this is a context
			// menu then there is no parent
			dijit.popup.close(this);
			// don't try to restore focus; user has clicked another part of the screen
			// and set focus there
		}
	},

	onOpen: function(/*Event*/ e){
		// summary: Open menu relative to the mouse
		this.isShowingNow = true;
	},

	onClose: function(){
		// summary: callback when this menu is closed
		this._stopPopupTimer();
		this.parentMenu = null;
		this.isShowingNow = false;
		this.currentPopup = null;
		if(this.focusedChild){
			this._onChildBlur(this.focusedChild);
			this.focusedChild = null;
		}
	},

	_openPopup: function(){
		// summary: open the popup to the side of the current menu item
		this._stopPopupTimer();
		var from_item = this.focusedChild;
		var popup = from_item.popup;

		if(popup.isShowingNow){ return; }
		popup.parentMenu = this;
		var self = this;
		dijit.popup.open({
			parent: this,
			popup: popup,
			around: from_item.arrowCell,
			orient: this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'},
			onCancel: function(){
				// called when the child menu is canceled
				dijit.popup.close(popup);
				from_item.focus();	// put focus back on my node
				self.currentPopup = null;
			}
		});

		this.currentPopup = popup;

		if(popup.focus){
			popup.focus();
		}
	}
}
);

dojo.declare("dijit.MenuItem",
	[dijit._Widget, dijit._Templated, dijit._Contained],
	{
	// summary: A line item in a Menu Widget

	// Make 3 columns
	//   icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
	templateString:
		 '
'
		+'

	'
		+'	'
		+''
			+'
'
			+'+'
			+'
'
		+'	'
		+'
',

	// label: String
	//	menu text
	label: '',

	// iconClass: String
	//	class to apply to div in button to make it display an icon
	iconClass: "",

	// disabled: Boolean
	//  if true, the menu item is disabled
	//  if false, the menu item is enabled
	disabled: false,

	postCreate: function(){
		dojo.setSelectable(this.domNode, false);
		this.setDisabled(this.disabled);
		if(this.label){
			this.containerNode.innerHTML=this.label;
		}
	},

	_onHover: function(){
		// summary: callback when mouse is moved onto menu item
		this.getParent().onItemHover(this);
	},

	_onUnhover: function(){
		// summary: callback when mouse is moved off of menu item

		// if we are unhovering the currently selected item
		// then unselect it
		this.getParent().onItemUnhover(this);
	},

	_onClick: function(evt){
		this.getParent().onItemClick(this);
		dojo.stopEvent(evt);
	},

	onClick: function() {
		// summary: User defined function to handle clicks
	},

	focus: function(){
		dojo.addClass(this.domNode, 'dijitMenuItemHover');
		try{
			dijit.focus(this.containerNode);
		}catch(e){
			// this throws on IE (at least) in some scenarios
		}
	},

	_blur: function(){
		dojo.removeClass(this.domNode, 'dijitMenuItemHover');
	},

	setDisabled: function(/*Boolean*/ value){
		// summary: enable or disable this menu item
		this.disabled = value;
		dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
		dijit.setWaiState(this.containerNode, 'disabled', value ? 'true' : 'false');
	}
});

dojo.declare("dijit.PopupMenuItem",
	dijit.MenuItem,
	{
	_fillContent: function(){
		// summary: The innerHTML contains both the menu item text and a popup widget
		// description: the first part holds the menu item text and the second part is the popup
		// example:
		// |

		// |		pick me
		// |		<popup> ... </popup>
		// |

		if(this.srcNodeRef){
			var nodes = dojo.query("*", this.srcNodeRef);
			dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);

			// save pointer to srcNode so we can grab the drop down widget after it's instantiated
			this.dropDownContainer = this.srcNodeRef;
		}
	},

	startup: function(){
		// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
		// land now.  move it to document.body.
		if(!this.popup){
			var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
			this.popup = dijit.byNode(node);
		}
		dojo.body().appendChild(this.popup.domNode);

		this.popup.domNode.style.display="none";
		dojo.addClass(this.expand, "dijitMenuExpandEnabled");
		dojo.style(this.expand, "display", "");
		dijit.setWaiState(this.containerNode, "haspopup", "true");
	}
});

dojo.declare("dijit.MenuSeparator",
	[dijit._Widget, dijit._Templated, dijit._Contained],
	{
	// summary: A line between two menu items

	templateString: '
'
			+'

'
			+'

'
			+'
',

	postCreate: function(){
		dojo.setSelectable(this.domNode, false);
	},

	isFocusable: function(){
		// summary: over ride to always return false
		return false; // Boolean
	}
});
<|endoftext|>