<commit_before>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * 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.
 */

MODEL({
  name: 'AppController',

  requires: [
    'DAOListView',
    'PopupChoiceView',
    'PredicatedView',
    'ScrollView',
    'SwipeAltView',
    'ViewChoice'
  ],

  exports: [
    'ActionButton'
  ],

  properties: [
    {
      name: 'model'
    },
    {
      name: 'name',
      defaultValueFn: function() { return this.model.plural; },
    },
    {
      name: 'dao'
    },
    {
      name: 'sortChoices',
      help: 'Possible sorting options for the view.'
    },
    {
      name: 'citationView',
      defaultValueFn: function() { return this.model.name + 'CitationView'; }
    },
    {
      name: 'citationRenderer',
      defaultValueFn: function() { return this.model.name + 'CitationRenderer'; }
    },
    {
      name: 'sortOrder',
      defaultValueFn: function() { return this.sortChoices ? this.sortChoices[0][0] : ''; }
    },
    {
      name: 'sortOrderView',
      lazyFactory: function() {
        if ( ! this.sortChoices ) return '';
        return this.PopupChoiceView.create({
          iconUrl: 'images/ic_sort_24dp.png',
          data$: this.sortOrder$,
          choices: this.sortChoices
        });
      }
    },
    {
      name: 'filterChoices'
    },
    {
      name: 'filteredDAO',
      model_: 'DAOProperty',
      help: 'Top-level filtered DAO. Further filtered by each canned query.'
    },
    {
      name: 'queryParser',
      lazyFactory: function() { return QueryParserFactory(this.model); }
    },
    {
      model_: 'BooleanProperty',
      name: 'editableCitationViews',
      defaultValue: false,
      help: 'True if you want to allow the citation views to be editable.'
    },
    {
      name: 'filteredDAOView',
      lazyFactory: function() {
        var DAOListView = this.ScrollView.xbind({
          model: this.model,
          mode: this.editableCitationViews ? 'read-write' : 'read-only',
          rowView: this.citationView,
          runway: 500
        });

        if ( ! this.filterChoices ) return DAOListView.create({ dao: this.filteredDAO$Proxy });
        var self = this;
        var views = this.filterChoices.map(function(filter) {
            return self.ViewChoice.create({
              view: self.PredicatedView.create({
                predicate: ( typeof filter[0] === "string" ?
                             self.queryParser.parseString(filter[0]) :
                             filter[0] ) || TRUE,
                dao: self.filteredDAO$Proxy,
                view: DAOListView.create()
              }),

              label: filter[1]
            });
          });

        return this.SwipeAltView.create({ views: views });
      }
    },
    {
      model_: 'BooleanProperty',
      defaultValue: false,
      name: 'searchMode'
    },
    {
      name: 'q',
      displayWidth: 25,
      view: {factory_: 'TextFieldView', type: 'search', onKeyMode: true, placeholder: 'Search'} // TODO: change placeholder?
    },
    {
      model_: 'FunctionProperty',
      name: 'menuFactory'
    },
    {
      name: 'createAction',
      type: 'Action'
    },
    {
      name: 'ActionButton',
      lazyFactory: function() {
        return ActionButtonCView.xbind({
          alpha:      1,
          width:      48,
          height:     44,
          iconWidth:  24,
          iconHeight: 24
        });
      }
    }
  ],
  actions: [
    {
      name: 'menu',
      iconUrl: 'images/ic_menu_24dp.png',
      label: '',
      action: function() {
        this.X.stack.slideView(this.menuFactory());
      }
    },
    {
      name: 'previousQuery',
    },
    {
      name: 'enterSearchMode',
      iconUrl: 'images/ic_search_24dp.png',
      label: '',
      action: function() {
        this.previousQuery = this.q;
        this.searchMode = true;
      }
    },
    {
      name: 'leaveSearchMode',
      iconUrl: 'images/ic_arrow_back_24dp.png',
      label: '',
      action: function() {
        this.q = this.previousQuery;
        this.searchMode = false;
      }
    }
  ],
  methods: {
    init: function() {
      this.SUPER();

      var self = this;
      Events.dynamic(
        function() { self.sortOrder; self.q; },
        function() {
          var query = (self.queryParser.parseString(self.q) || TRUE).partialEval();
          self.filteredDAO = self.dao.where(query).orderBy(self.sortOrder);
        }
      );
    }
  },
  templates: [
    function toDetailHTML() {/*
    <div id="<%= this.setClass('searchMode', function() { return self.data.searchMode; }, this.id) %>"  class="mdui-app-controller">

           $$menu
           $$name{mode: 'read-only', className: 'name'} $$enterSearchMode %%data.sortOrderView

           $$leaveSearchMode{className: 'backButton'} $$q

       %%data.filteredDAOView
       <% if ( this.data.createAction ) out(this.createActionView(this.data.createAction, { data: this.data, className: 'createButton', color: 'white', font: '30px Roboto Arial', alpha: 1, width: 44, height: 44, radius: 22, background: '#e51c23'})); %>

    <%
      this.addInitializer(function() {
        if ( self.filterChoices ) {
          var v = self.data.filteredDAOView;
          v.index$.addListener(function() {
            self.qView.$.placeholder = "Search " + v.views[v.index].label.toLowerCase();
          });
        }
        self.data.searchMode$.addListener(EventService.merged(function() {
          self.qView.$.focus();
        }, 100));

      });

      this.on('touchstart', function(){ console.log('blurring'); self.qView.$.blur(); }, this.data.filteredDAOView.id);
      this.on('click', function(){ console.log('focusing'); self.qView.$.focus(); }, this.qView.id);
    %>
  */},
    function CSS() {/*
      body { background: white; }
   */}
  ]
});

MODEL({
  name: 'PositionedAppControllerView',
  traits: ['PositionedDOMViewTrait'],
  extendsModel: 'DetailView',

  requires: [ 'CanvasScrollView', ],
  properties: [
  ],

  methods: {
    init: function() {
      this.SUPER();
      var self = this;
      this.X.dynamic(function() { self.width; self.height; }, this.layout);
    },
    toInnerHTML: function() {
      this.destroy();
      var out = "";
      var renderer = FOAM.lookup(this.data.citationRenderer, this.X);

      var view = this.filteredDAOView = this.CanvasScrollView({
        dao: this.data.filteredDAO$Proxy,
        renderer: renderer.create({})
      });
      view = view.toPositionedView_();
      out += view.toHTML();
      this.addChild(view);
      return out;
    },
    initHTML: function() {
      this.SUPER();
      this.layout();
    }
  },

  listeners: [
    {
      name: 'layout',
      code: function() {
        if ( ! this.$ ) return;

        var children = this.children;
        var count = children.length;
        children[0].x = 0;
        children[0].y = 0;
        children[0].z = 0;
        children[0].width = this.width;
        children[0].height = this.height;
      }
    }
  ]
});
<commit_msg>Fix contexting in AppController's override of ActionButtonCView<commit_after>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * 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.
 */

MODEL({
  name: 'AppController',

  requires: [
    'ActionButtonCView',
    'DAOListView',
    'PopupChoiceView',
    'PredicatedView',
    'ScrollView',
    'SwipeAltView',
    'ViewChoice'
  ],

  exports: [
    'ActionButton'
  ],

  properties: [
    {
      name: 'model'
    },
    {
      name: 'name',
      defaultValueFn: function() { return this.model.plural; },
    },
    {
      name: 'dao'
    },
    {
      name: 'sortChoices',
      help: 'Possible sorting options for the view.'
    },
    {
      name: 'citationView',
      defaultValueFn: function() { return this.model.name + 'CitationView'; }
    },
    {
      name: 'citationRenderer',
      defaultValueFn: function() { return this.model.name + 'CitationRenderer'; }
    },
    {
      name: 'sortOrder',
      defaultValueFn: function() { return this.sortChoices ? this.sortChoices[0][0] : ''; }
    },
    {
      name: 'sortOrderView',
      lazyFactory: function() {
        if ( ! this.sortChoices ) return '';
        return this.PopupChoiceView.create({
          iconUrl: 'images/ic_sort_24dp.png',
          data$: this.sortOrder$,
          choices: this.sortChoices
        });
      }
    },
    {
      name: 'filterChoices'
    },
    {
      name: 'filteredDAO',
      model_: 'DAOProperty',
      help: 'Top-level filtered DAO. Further filtered by each canned query.'
    },
    {
      name: 'queryParser',
      lazyFactory: function() { return QueryParserFactory(this.model); }
    },
    {
      model_: 'BooleanProperty',
      name: 'editableCitationViews',
      defaultValue: false,
      help: 'True if you want to allow the citation views to be editable.'
    },
    {
      name: 'filteredDAOView',
      lazyFactory: function() {
        var DAOListView = this.ScrollView.xbind({
          model: this.model,
          mode: this.editableCitationViews ? 'read-write' : 'read-only',
          rowView: this.citationView,
          runway: 500
        });

        if ( ! this.filterChoices ) return DAOListView.create({ dao: this.filteredDAO$Proxy });
        var self = this;
        var views = this.filterChoices.map(function(filter) {
            return self.ViewChoice.create({
              view: self.PredicatedView.create({
                predicate: ( typeof filter[0] === "string" ?
                             self.queryParser.parseString(filter[0]) :
                             filter[0] ) || TRUE,
                dao: self.filteredDAO$Proxy,
                view: DAOListView.create()
              }),

              label: filter[1]
            });
          });

        return this.SwipeAltView.create({ views: views });
      }
    },
    {
      model_: 'BooleanProperty',
      defaultValue: false,
      name: 'searchMode'
    },
    {
      name: 'q',
      displayWidth: 25,
      view: {factory_: 'TextFieldView', type: 'search', onKeyMode: true, placeholder: 'Search'} // TODO: change placeholder?
    },
    {
      model_: 'FunctionProperty',
      name: 'menuFactory'
    },
    {
      name: 'createAction',
      type: 'Action'
    },
    {
      name: 'ActionButton',
      lazyFactory: function() {
        return this.ActionButtonCView.xbind({
          alpha:      1,
          width:      48,
          height:     44,
          iconWidth:  24,
          iconHeight: 24
        });
      }
    }
  ],
  actions: [
    {
      name: 'menu',
      iconUrl: 'images/ic_menu_24dp.png',
      label: '',
      action: function() {
        this.X.stack.slideView(this.menuFactory());
      }
    },
    {
      name: 'previousQuery',
    },
    {
      name: 'enterSearchMode',
      iconUrl: 'images/ic_search_24dp.png',
      label: '',
      action: function() {
        this.previousQuery = this.q;
        this.searchMode = true;
      }
    },
    {
      name: 'leaveSearchMode',
      iconUrl: 'images/ic_arrow_back_24dp.png',
      label: '',
      action: function() {
        this.q = this.previousQuery;
        this.searchMode = false;
      }
    }
  ],
  methods: {
    init: function() {
      this.SUPER();

      var self = this;
      Events.dynamic(
        function() { self.sortOrder; self.q; },
        function() {
          var query = (self.queryParser.parseString(self.q) || TRUE).partialEval();
          self.filteredDAO = self.dao.where(query).orderBy(self.sortOrder);
        }
      );
    }
  },
  templates: [
    function toDetailHTML() {/*
    <div id="<%= this.setClass('searchMode', function() { return self.data.searchMode; }, this.id) %>"  class="mdui-app-controller">

           $$menu
           $$name{mode: 'read-only', className: 'name'} $$enterSearchMode %%data.sortOrderView

           $$leaveSearchMode{className: 'backButton'} $$q

       %%data.filteredDAOView
       <% if ( this.data.createAction ) out(this.createActionView(this.data.createAction, { data: this.data, className: 'createButton', color: 'white', font: '30px Roboto Arial', alpha: 1, width: 44, height: 44, radius: 22, background: '#e51c23'})); %>

    <%
      this.addInitializer(function() {
        if ( self.filterChoices ) {
          var v = self.data.filteredDAOView;
          v.index$.addListener(function() {
            self.qView.$.placeholder = "Search " + v.views[v.index].label.toLowerCase();
          });
        }
        self.data.searchMode$.addListener(EventService.merged(function() {
          self.qView.$.focus();
        }, 100));

      });

      this.on('touchstart', function(){ console.log('blurring'); self.qView.$.blur(); }, this.data.filteredDAOView.id);
      this.on('click', function(){ console.log('focusing'); self.qView.$.focus(); }, this.qView.id);
    %>
  */},
    function CSS() {/*
      body { background: white; }
   */}
  ]
});

MODEL({
  name: 'PositionedAppControllerView',
  traits: ['PositionedDOMViewTrait'],
  extendsModel: 'DetailView',

  requires: [ 'CanvasScrollView', ],
  properties: [
  ],

  methods: {
    init: function() {
      this.SUPER();
      var self = this;
      this.X.dynamic(function() { self.width; self.height; }, this.layout);
    },
    toInnerHTML: function() {
      this.destroy();
      var out = "";
      var renderer = FOAM.lookup(this.data.citationRenderer, this.X);

      var view = this.filteredDAOView = this.CanvasScrollView({
        dao: this.data.filteredDAO$Proxy,
        renderer: renderer.create({})
      });
      view = view.toPositionedView_();
      out += view.toHTML();
      this.addChild(view);
      return out;
    },
    initHTML: function() {
      this.SUPER();
      this.layout();
    }
  },

  listeners: [
    {
      name: 'layout',
      code: function() {
        if ( ! this.$ ) return;

        var children = this.children;
        var count = children.length;
        children[0].x = 0;
        children[0].y = 0;
        children[0].z = 0;
        children[0].width = this.width;
        children[0].height = this.height;
      }
    }
  ]
});
<|endoftext|>


<commit_before>// Generated on 2013-10-25 using generator-jekyllrb 0.4.0
'use strict';

// Directory reference:
//   css: assets/css
//   sass: assets/_scss
//   javascript: assets/js<% if (jsPre === 'coffeescript') { %>
//   coffeescript: assets/_coffee<% } %>
//   images: assets/img
//   fonts: assets/fonts

module.exports = function (grunt) {
  // Show elapsed time after tasks run
  require('time-grunt')(grunt);
  // Load all Grunt tasks
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    // Configurable paths
    yeoman: {
      app: 'app',
      dist: 'dist'
    },
    watch: {
      sass: {
        files: ['<%%= yeoman.app %>/assets/_scss/**/*.{scss,sass}'],
        tasks: ['sass:server']
      },<% if (jsPre === 'coffeescript') { %>
      coffee: {
        files: ['<%%= yeoman.app %>/assets/_coffee/**/*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/**/*.coffee'],
        tasks: ['coffee:test']
      },<% } %>
      jekyll: {
        files: [
          '<%%= yeoman.app %>/**/*.{html,yml,md,mkd,markdown}',
          '_config.yml',
          '!<%%= yeoman.app %>/_bower_components'
        ],
        tasks: ['jekyll:server']
      },
      livereload: {
        options: {
          livereload: '<%%= connect.options.livereload %>'
        },
        files: [
          '.jekyll/**/*.html',
          '{.tmp,<%%= yeoman.app %>}/assets/css/**/*.css',
          '{.tmp,<%%= yeoman.app %>}/<%%= js %>/**/*.js',
          '<%%= yeoman.app %>/assets/img/**/*.{gif,jpg,jpeg,png,svg,webp}'
        ]
      }
    },
    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: 'localhost'
      },
      livereload: {
        options: {
          open: true,
          base: [
            '.tmp',
            '.jekyll',
            '<%%= yeoman.app %>'
          ]
        }
      },
      dist: {
        options: {
          open: true,
          base: [
            '<%%= yeoman.dist %>'
          ]
        }
      },
      test: {
        options: {
          base: [
            '.tmp',
            '.jekyll',
            'test',
            '<%%= yeoman.app %>'
          ]
        }
      }
    },
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%%= yeoman.dist %>/*',
            // Running Jekyll also cleans the target directory.  Exclude any
            // non-standard `keep_files` here (e.g., the generated files
            // directory from Jekyll Picture Tag).
            '!<%%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: [
        '.tmp',
        '.jekyll'
      ]
    },
    sass: {
      options: {
        bundleExec: true,
        debugInfo: false,
        lineNumbers: false,
        loadPath: '<%%= yeoman.app %>/_bower_components'
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/assets/_scss',
          src: '*.{scss,sass}',
          dest: '.tmp/assets/css',
          ext: '.css'
        }]
      },
      server: {
        options: {
          debugInfo: true,
          lineNumbers: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/assets/_scss',
          src: '*.{scss,sass}',
          dest: '.tmp/assets/css',
          ext: '.css'
        }]
      }
    },<% if (jsPre === 'coffeescript') { %>
    coffee: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/assets/_coffee',
          src: '**/*.coffee',
          dest: '.tmp/assets/js',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '**/*.coffee',
          dest: '.tmp/spec',
          ext: '.js'
        }]
      }
    },<% } %>
    jekyll: {
      options: {
        bundleExec: true,
        config: '_config.yml,_config.build.yml',
        src: '<%%= yeoman.app %>'
      },
      dist: {
        options: {
          dest: '<%%= yeoman.dist %>'
        }
      },
      server: {
        options: {
          config: '_config.yml',
          dest: '.jekyll'
        }
      },
      check: {
        options: {
          doctor: true
        }
      }
    },
    // UseminPrepare will only scan a single page for usemin blocks. If you
    // use usemin blocks that aren't in index.html, create a usemin manifest
    // page (hackery!) and point this task there.
    useminPrepare: {
      options: {
        dest: '<%%= yeoman.dist %>'
      },
      html: '<%%= yeoman.dist %>/index.html'
    },
    usemin: {
      options: {
        basedir: '<%%= yeoman.dist %>',
        dirs: ['<%%= yeoman.dist %>/**/*']
      },
      html: ['<%%= yeoman.dist %>/**/*.html'],
      css: ['<%%= yeoman.dist %>/assets/css/**/*.css']
    },
    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.html',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    // Usemin adds files to concat
    concat: {},
    // Usemin adds files to uglify
    uglify: {},
    // Usemin adds files to cssmin
    cssmin: {
      dist: {
        options: {
          check: 'gzip'
        }
      }
    },
    imagemin: {
      dist: {
        options: {
          progressive: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.{jpg,jpeg,png}',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.svg',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%%= yeoman.app %>',
          src: [
            // Jekyll processes and moves HTML and text files
            // Usemin moves CSS and javascript inside of Usemin blocks
            // Copy moves asset files and directories
            'assets/img/**/*',
            'assets/fonts/**/*',
            // Like Jekyll, exclude files & folders prefixed with an underscore
            '!**/_*{,/**}'
            // Explicitly add any files your site needs for distribution here
            //'_bower_components/jquery/jquery.js',
            // 'favicon.ico',
            // 'apple-touch*.png'
          ],
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    rev: {
      options: {
        length: 4
      },
      dist: {
        files: {
          src: [
            '<%%= yeoman.dist %>/assets/js/**/*.js',
            '<%%= yeoman.dist %>/assets/css/**/*.css',
            '<%%= yeoman.dist %>/assets/img/**/*.{gif,jpg,jpeg,png,svg,webp}',
            '<%%= yeoman.dist %>/assets/fonts/**/*.{eot*,otf,svg,ttf,woff}'
          ]
        }
      }
    },<% if (deploy) { %>
    buildcontrol: {
      dist: {
        options: {
          dir: 'dist',
          commit: true,
          push: true,
          message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%',
          remote: '<%= deployRemote %>',
          branch: '<%= deployBranch %>'
        }
      }
    },<% } %><% if (deployHost === 'GitHub Pages' && ghPagesProject === 'project') { %>
    replace: {
      dist: {
        options: {
          patterns: [
            {
              match: /("?)\/?assets\//g,
              replacement: '$1http://<%= ghOwner %>.github.io/<%= ghRepo %>/assets/'
            }
          ]
        },
        files: [
          {
            expand: true,
            src: ['dist/**/*.html']
          }
        ]
      }
    },<% } %>
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%%= yeoman.app %>/assets/js/**/*.js',
        'test/spec/**/*.js',
        '!<%%= yeoman.app %>/assets/js/vendor/**/*'
      ]
    },
    csscss: {
      options: {
        bundleExec: true,
        minMatch: 4,
        ignoreProperties: '-moz-appearance,-ms-appearance,-o-appearance,-webkit-appearance',
        ignoreSassMixins: false,
        colorize: true,
        shorthand: false,
        verbose: true
      },
      check: {
        src: ['.tmp/assets/css/screen.css']
      }
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      check: {
        src: ['.tmp/assets/css/screen.css']
      }
    },
    concurrent: {
      server: [
        'sass:server',<% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %>
        'jekyll:server'
      ],
      dist: [
        'sass:dist',<% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %>
        'copy:dist'
      ]
    }
  });

  // Define Tasks
  grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'concurrent:server',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('check', [
    'clean:server',
    'jekyll:check',
    'sass:dist',<% if (jsPre === 'coffeescript') { %>
    'coffee:dist',<% } %>
    'jshint:all',
    'csscss:check',
    'csslint:check'
  ]);

  // No real tests yet. Add your own.
  grunt.registerTask('test', [
    // 'clean:server',
    // 'concurrent:test',
    // 'connect:test'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    // Jekyll cleans files from the target directory, so must run first
    'jekyll:dist',
    'concurrent:dist',
    'useminPrepare',
    'concat',
    'cssmin',
    'uglify',
    'imagemin',
    'svgmin',
    'rev',
    'usemin',
    'htmlmin'
  ]);<% if (deploy) { %>

  grunt.registerTask('deploy', [
    'default',<% if (deployHost === 'GitHub Pages' && ghPagesProject === 'project') { %>
    'replace',<% } %>
    'buildcontrol'
  ]);<% } %>

  grunt.registerTask('default', [
    'check',
    'test',
    'build'
  ]);
};
<commit_msg>Grunt replace for anchors.<commit_after>// Generated on 2013-10-25 using generator-jekyllrb 0.4.0
'use strict';

// Directory reference:
//   css: assets/css
//   sass: assets/_scss
//   javascript: assets/js<% if (jsPre === 'coffeescript') { %>
//   coffeescript: assets/_coffee<% } %>
//   images: assets/img
//   fonts: assets/fonts

module.exports = function (grunt) {
  // Show elapsed time after tasks run
  require('time-grunt')(grunt);
  // Load all Grunt tasks
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    // Configurable paths
    yeoman: {
      app: 'app',
      dist: 'dist'
    },
    watch: {
      sass: {
        files: ['<%%= yeoman.app %>/assets/_scss/**/*.{scss,sass}'],
        tasks: ['sass:server']
      },<% if (jsPre === 'coffeescript') { %>
      coffee: {
        files: ['<%%= yeoman.app %>/assets/_coffee/**/*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/**/*.coffee'],
        tasks: ['coffee:test']
      },<% } %>
      jekyll: {
        files: [
          '<%%= yeoman.app %>/**/*.{html,yml,md,mkd,markdown}',
          '_config.yml',
          '!<%%= yeoman.app %>/_bower_components'
        ],
        tasks: ['jekyll:server']
      },
      livereload: {
        options: {
          livereload: '<%%= connect.options.livereload %>'
        },
        files: [
          '.jekyll/**/*.html',
          '{.tmp,<%%= yeoman.app %>}/assets/css/**/*.css',
          '{.tmp,<%%= yeoman.app %>}/<%%= js %>/**/*.js',
          '<%%= yeoman.app %>/assets/img/**/*.{gif,jpg,jpeg,png,svg,webp}'
        ]
      }
    },
    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: 'localhost'
      },
      livereload: {
        options: {
          open: true,
          base: [
            '.tmp',
            '.jekyll',
            '<%%= yeoman.app %>'
          ]
        }
      },
      dist: {
        options: {
          open: true,
          base: [
            '<%%= yeoman.dist %>'
          ]
        }
      },
      test: {
        options: {
          base: [
            '.tmp',
            '.jekyll',
            'test',
            '<%%= yeoman.app %>'
          ]
        }
      }
    },
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%%= yeoman.dist %>/*',
            // Running Jekyll also cleans the target directory.  Exclude any
            // non-standard `keep_files` here (e.g., the generated files
            // directory from Jekyll Picture Tag).
            '!<%%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: [
        '.tmp',
        '.jekyll'
      ]
    },
    sass: {
      options: {
        bundleExec: true,
        debugInfo: false,
        lineNumbers: false,
        loadPath: '<%%= yeoman.app %>/_bower_components'
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/assets/_scss',
          src: '*.{scss,sass}',
          dest: '.tmp/assets/css',
          ext: '.css'
        }]
      },
      server: {
        options: {
          debugInfo: true,
          lineNumbers: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/assets/_scss',
          src: '*.{scss,sass}',
          dest: '.tmp/assets/css',
          ext: '.css'
        }]
      }
    },<% if (jsPre === 'coffeescript') { %>
    coffee: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.app %>/assets/_coffee',
          src: '**/*.coffee',
          dest: '.tmp/assets/js',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '**/*.coffee',
          dest: '.tmp/spec',
          ext: '.js'
        }]
      }
    },<% } %>
    jekyll: {
      options: {
        bundleExec: true,
        config: '_config.yml,_config.build.yml',
        src: '<%%= yeoman.app %>'
      },
      dist: {
        options: {
          dest: '<%%= yeoman.dist %>'
        }
      },
      server: {
        options: {
          config: '_config.yml',
          dest: '.jekyll'
        }
      },
      check: {
        options: {
          doctor: true
        }
      }
    },
    // UseminPrepare will only scan a single page for usemin blocks. If you
    // use usemin blocks that aren't in index.html, create a usemin manifest
    // page (hackery!) and point this task there.
    useminPrepare: {
      options: {
        dest: '<%%= yeoman.dist %>'
      },
      html: '<%%= yeoman.dist %>/index.html'
    },
    usemin: {
      options: {
        basedir: '<%%= yeoman.dist %>',
        dirs: ['<%%= yeoman.dist %>/**/*']
      },
      html: ['<%%= yeoman.dist %>/**/*.html'],
      css: ['<%%= yeoman.dist %>/assets/css/**/*.css']
    },
    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.html',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    // Usemin adds files to concat
    concat: {},
    // Usemin adds files to uglify
    uglify: {},
    // Usemin adds files to cssmin
    cssmin: {
      dist: {
        options: {
          check: 'gzip'
        }
      }
    },
    imagemin: {
      dist: {
        options: {
          progressive: true
        },
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.{jpg,jpeg,png}',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%%= yeoman.dist %>',
          src: '**/*.svg',
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%%= yeoman.app %>',
          src: [
            // Jekyll processes and moves HTML and text files
            // Usemin moves CSS and javascript inside of Usemin blocks
            // Copy moves asset files and directories
            'assets/img/**/*',
            'assets/fonts/**/*',
            // Like Jekyll, exclude files & folders prefixed with an underscore
            '!**/_*{,/**}'
            // Explicitly add any files your site needs for distribution here
            //'_bower_components/jquery/jquery.js',
            // 'favicon.ico',
            // 'apple-touch*.png'
          ],
          dest: '<%%= yeoman.dist %>'
        }]
      }
    },
    rev: {
      options: {
        length: 4
      },
      dist: {
        files: {
          src: [
            '<%%= yeoman.dist %>/assets/js/**/*.js',
            '<%%= yeoman.dist %>/assets/css/**/*.css',
            '<%%= yeoman.dist %>/assets/img/**/*.{gif,jpg,jpeg,png,svg,webp}',
            '<%%= yeoman.dist %>/assets/fonts/**/*.{eot*,otf,svg,ttf,woff}'
          ]
        }
      }
    },<% if (deploy) { %>
    buildcontrol: {
      dist: {
        options: {
          dir: 'dist',
          commit: true,
          push: true,
          message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%',
          remote: '<%= deployRemote %>',
          branch: '<%= deployBranch %>'
        }
      }
    },<% } %><% if (deployHost === 'GitHub Pages' && ghPagesProject === 'project') { %>
    replace: {
      dist: {
        options: {
          patterns: [
            {
              match: /("?)\/?assets\//g,
              replacement: '$1http://<%= ghOwner %>.github.io/<%= ghRepo %>/assets/'
            },
            {
              match: /(<a[^>]*href="?)(\/?)/g,
              replacement: '$1http://<%= ghOwner %>.github.io/<%= ghRepo %>/'
            }
          ]
        },
        files: [
          {
            expand: true,
            src: ['dist/**/*.html']
          }
        ]
      }
    },<% } %>
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%%= yeoman.app %>/assets/js/**/*.js',
        'test/spec/**/*.js',
        '!<%%= yeoman.app %>/assets/js/vendor/**/*'
      ]
    },
    csscss: {
      options: {
        bundleExec: true,
        minMatch: 4,
        ignoreProperties: '-moz-appearance,-ms-appearance,-o-appearance,-webkit-appearance',
        ignoreSassMixins: false,
        colorize: true,
        shorthand: false,
        verbose: true
      },
      check: {
        src: ['.tmp/assets/css/screen.css']
      }
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      check: {
        src: ['.tmp/assets/css/screen.css']
      }
    },
    concurrent: {
      server: [
        'sass:server',<% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %>
        'jekyll:server'
      ],
      dist: [
        'sass:dist',<% if (jsPre === 'coffeescript') { %>
        'coffee:dist',<% } %>
        'copy:dist'
      ]
    }
  });

  // Define Tasks
  grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'concurrent:server',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('check', [
    'clean:server',
    'jekyll:check',
    'sass:dist',<% if (jsPre === 'coffeescript') { %>
    'coffee:dist',<% } %>
    'jshint:all',
    'csscss:check',
    'csslint:check'
  ]);

  // No real tests yet. Add your own.
  grunt.registerTask('test', [
    // 'clean:server',
    // 'concurrent:test',
    // 'connect:test'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    // Jekyll cleans files from the target directory, so must run first
    'jekyll:dist',
    'concurrent:dist',
    'useminPrepare',
    'concat',
    'cssmin',
    'uglify',
    'imagemin',
    'svgmin',
    'rev',
    'usemin',
    'htmlmin'
  ]);<% if (deploy) { %>

  grunt.registerTask('deploy', [
    'default',<% if (deployHost === 'GitHub Pages' && ghPagesProject === 'project') { %>
    'replace',<% } %>
    'buildcontrol'
  ]);<% } %>

  grunt.registerTask('default', [
    'check',
    'test',
    'build'
  ]);
};
<|endoftext|>


<commit_before>describe('Runtime Middleware', function() {
  const baseDir = 'noflo-ui';
  let mw = null;
  let iframe = null;
  let runtimeDefinition = {
    id: '7695e97e-79a5-4a22-879d-847ec9592136',
    protocol: 'iframe',
    type: 'noflo-nodejs',
    address: '/base/spec/mockruntime.html',
    project: '090356f9-dfa6-4b10-b4ea-03038faf68be',
  };
  before(function(done) {
    this.timeout(4000);
    mw = window.middleware('ui/RuntimeMiddleware', baseDir);
    mw.before(done);
  });
  beforeEach(() => mw.beforeEach());
  afterEach(() => mw.afterEach());

  // Set up a fake runtime connection and test that we can play both ends
  describe('receiving a storage:ready action', () => {
    it('should pass it out as-is', (done) => {
      const action = 'storage:ready';
      const payload = {
        runtimes: [
          runtimeDefinition,
        ],
      };
      mw.receivePassCheck(action, (received) => {
        chai.expect(received.runtimes).to.be.an('array');
        chai.expect(received.runtimes.length).to.equal(2);
        chai.expect(received.runtimes[0]).to.eql(runtimeDefinition);
      }, done);
      mw.send(action, payload, payload);
    });
  });
  describe('receiving a storage:opened action', () => {
    it('should connect and pass the storage:opened action', (done) => {
      const action = 'storage:opened';
      const payload = {
        state: 'ok',
        project: {
          id: '090356f9-dfa6-4b10-b4ea-03038faf68be',
          graphs: [],
          components: [],
          type: 'noflo-nodejs',
        },
        graphs: [],
        remote: [],
      };
      const capabilities = [
        'protocol:graph',
        'protocol:component',
        'protocol:network',
        'protocol:runtime'
      ];
      let tries = 0;
      let maxTries = 100;
      const waitForIframe = () => {
        if (runtimeDefinition.querySelector) {
          iframe = document.body.querySelector(runtimeDefinition.querySelector);
          iframe.addEventListener('load', () => {
            iframe.contentWindow.handleProtocolMessage(function(msg, send) {
              chai.expect(msg.protocol).to.equal('runtime');
              chai.expect(msg.command).to.equal('getruntime');
              send('runtime', 'runtime', {
                id: runtimeDefinition.id,
                type: runtimeDefinition.type,
                capabilities,
                version: '0.7',
              });
              setTimeout(() => {
                done();
              }, 1000);
            });
          });
          return;
        }
        if (tries >= maxTries) {
          return done(new Error('No iframe found'));
        }
        setTimeout(waitForIframe, 100);
      };
      mw.send(action, payload, {
        runtimes: [
          runtimeDefinition,
        ],
        compatible: [
          runtimeDefinition,
        ],
        projects: [
          payload.project,
        ],
      });
      waitForIframe();
    }).timeout(4000);
    it('should have added properties from runtime to the definition', () => {
      chai.expect(runtimeDefinition.capabilities).to.be.an('array');
      chai.expect(runtimeDefinition.version).to.equal('0.7');
    });
    it('should have requested components from runtime', () => {
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('list');
        send('component', 'componentsready', 0);
      });
    });
  });
  describe('receiving a context:edges action', () => {
    it('should pass it out as-is', (done) => {
      const sentEdges = [{
        from: {
          node: 'Foo',
          port: 'out'
        },
        to: {
          node: 'Bar',
          port: 'in'
        }
      }];
      mw.receivePassCheck('context:edges', (received) => {
        chai.expect(received).to.eql(sentEdges);
      }, done);
      mw.send('context:edges', sentEdges, {
        graphs: [
          {
             name: 'foo'
          }
        ],
        runtime: runtimeDefinition,
      });
    });
    it('should send selected edges to the runtime', function(done) {
      const expectedEdges = [{
        src: {
          node: 'Foo',
          port: 'out'
        },
        tgt: {
          node: 'Bar',
          port: 'in'
        },
      }];
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('network');
        chai.expect(msg.command).to.equal('edges');
        chai.expect(msg.payload.graph).to.equal('foo');
        chai.expect(msg.payload.edges).to.eql(expectedEdges);
        done();
      });
    });
  });
});
<commit_msg>Allow test more time<commit_after>describe('Runtime Middleware', function() {
  const baseDir = 'noflo-ui';
  let mw = null;
  let iframe = null;
  let runtimeDefinition = {
    id: '7695e97e-79a5-4a22-879d-847ec9592136',
    protocol: 'iframe',
    type: 'noflo-nodejs',
    address: '/base/spec/mockruntime.html',
    project: '090356f9-dfa6-4b10-b4ea-03038faf68be',
  };
  before(function(done) {
    this.timeout(4000);
    mw = window.middleware('ui/RuntimeMiddleware', baseDir);
    mw.before(done);
  });
  beforeEach(() => mw.beforeEach());
  afterEach(() => mw.afterEach());

  // Set up a fake runtime connection and test that we can play both ends
  describe('receiving a storage:ready action', () => {
    it('should pass it out as-is', (done) => {
      const action = 'storage:ready';
      const payload = {
        runtimes: [
          runtimeDefinition,
        ],
      };
      mw.receivePassCheck(action, (received) => {
        chai.expect(received.runtimes).to.be.an('array');
        chai.expect(received.runtimes.length).to.equal(2);
        chai.expect(received.runtimes[0]).to.eql(runtimeDefinition);
      }, done);
      mw.send(action, payload, payload);
    });
  });
  describe('receiving a storage:opened action', () => {
    it('should connect and pass the storage:opened action', (done) => {
      const action = 'storage:opened';
      const payload = {
        state: 'ok',
        project: {
          id: '090356f9-dfa6-4b10-b4ea-03038faf68be',
          graphs: [],
          components: [],
          type: 'noflo-nodejs',
        },
        graphs: [],
        remote: [],
      };
      const capabilities = [
        'protocol:graph',
        'protocol:component',
        'protocol:network',
        'protocol:runtime'
      ];
      let tries = 0;
      let maxTries = 100;
      const waitForIframe = () => {
        if (runtimeDefinition.querySelector) {
          iframe = document.body.querySelector(runtimeDefinition.querySelector);
          iframe.addEventListener('load', () => {
            iframe.contentWindow.handleProtocolMessage(function(msg, send) {
              chai.expect(msg.protocol).to.equal('runtime');
              chai.expect(msg.command).to.equal('getruntime');
              send('runtime', 'runtime', {
                id: runtimeDefinition.id,
                type: runtimeDefinition.type,
                capabilities,
                version: '0.7',
              });
              setTimeout(() => {
                done();
              }, 1000);
            });
          });
          return;
        }
        if (tries >= maxTries) {
          return done(new Error('No iframe found'));
        }
        setTimeout(waitForIframe, 100);
      };
      mw.send(action, payload, {
        runtimes: [
          runtimeDefinition,
        ],
        compatible: [
          runtimeDefinition,
        ],
        projects: [
          payload.project,
        ],
      });
      waitForIframe();
    }).timeout(4000);
    it('should have added properties from runtime to the definition', () => {
      chai.expect(runtimeDefinition.capabilities).to.be.an('array');
      chai.expect(runtimeDefinition.version).to.equal('0.7');
    });
    it('should have requested components from runtime', () => {
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('list');
        send('component', 'componentsready', 0);
      });
    });
  });
  describe('receiving a context:edges action', () => {
    it('should pass it out as-is', (done) => {
      const sentEdges = [{
        from: {
          node: 'Foo',
          port: 'out'
        },
        to: {
          node: 'Bar',
          port: 'in'
        }
      }];
      mw.receivePassCheck('context:edges', (received) => {
        chai.expect(received).to.eql(sentEdges);
      }, done);
      mw.send('context:edges', sentEdges, {
        graphs: [
          {
             name: 'foo'
          }
        ],
        runtime: runtimeDefinition,
      });
    });
    it('should send selected edges to the runtime', function(done) {
      const expectedEdges = [{
        src: {
          node: 'Foo',
          port: 'out'
        },
        tgt: {
          node: 'Bar',
          port: 'in'
        },
      }];
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('network');
        chai.expect(msg.command).to.equal('edges');
        chai.expect(msg.payload.graph).to.equal('foo');
        chai.expect(msg.payload.edges).to.eql(expectedEdges);
        done();
      });
    }).timeout(4000);
  });
});
<|endoftext|>


<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      options: {
        livereload: true,
        spawn: false
      },

      // Styling
      scss: {
        files: 'components/**/*.scss',
        tasks: ['newer:imagemin', 'sync', 'compass:development', 'modernizr', 'newer:csslint']
      },

      // Scripting
      js: {
        files: ['components/*.js', 'components/app/**/*.js', '!components/app/_deferred/**/*.js'],
        tasks: ['requirejs:development', 'modernizr', 'newer:jshint'],
      },
      js_deferred: {
        files: ['components/app/_deferred/**/*.js'],
        tasks: ['newer:uglify:deferred_development', 'modernizr', 'newer:jshint'],
      },
      js_bower: {
        files: ['components/libs/**/*.js'],
        tasks: ['newer:uglify:external', 'requirejs:development'],
      },

      // HTML
      html: {
        files: ['*.html', 'components/app/**/*.html' , '!components/libs/**/*.html', '!build/**/*.html'],
        tasks: ['replace', 'newer:accessibility'],
      },

      // Images
      img_content: {
        files: 'img/**/*.{png,gif,jpg,svg}',
        tasks: ['newer:imagemin:content'],
      },
      img_background: {
        files: 'components/**/*.{png,gif,jpg,svg}',
        tasks: ['clean:css', 'newer:imagemin:backgrounds' , 'compass:development', 'clean:css', 'clean:svg', 'newer:csslint'],
      }
    },

    compass: {
      options: {
        asset_cache_buster: false,
        cssDir: 'build/assets/css',
        httpImagesPath: '/assets/img',
        imagesDir: 'build/assets/img',
        noLineComments: true,
        require: 'sass-css-importer',
        sassDir: 'components',
        specify: 'components/*.scss'
      },
      development: {
        options: {
          sourcemap: true,
          environment: 'development'
        }
      },
      production: {
        options: {
          httpPath: "/", // . = relative
          environment: 'production'
        }
      }
    },

    replace: {
      modules: {
        options: {
          patterns: [
            {
              match: /{app:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/' + placeholder + '/' + placeholder + '.html');
              }
            },
            {
              match: /{deferred:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/_deferred/' + placeholder + '/' + placeholder + '.html');
              }
            }
          ]
        },
        files: [
          {
            expand: true,
            flatten: true,
            src: ['*.html'],
            dest: 'build/'
          }
        ]
      }
    },

    requirejs: {
      options: {
        mainConfigFile: "components/<%= _.slugify(ProjectName) %>.js",
        name: "<%= _.slugify(ProjectName) %>",
        out: "build/assets/js/<%= _.slugify(ProjectName) %>.js",
        useStrict: true
      },
      development: {
        options: {
          generateSourceMaps: true,
          optimize: 'none'
        }
      },
      production: {
        options: {
          generateSourceMaps: false,
          optimize: 'uglify'
        }
      }
    },

    uglify: {
      deferred_development: {
        options: {
          sourceMap: true
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      deferred_production: {
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      external: {
        files: {
          'build/assets/js/libs/modernizr.js': ['components/libs/modernizr-shim/modernizr.min.js'],
          'build/assets/js/libs/require.js': ['components/libs/requirejs/require.js']
        }
      }
    },

    imagemin: {
      content: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'img',
          src: ['**/*.{png,jpg,gif,svg}'],
          dest: 'build/img'
        }]
      },
      backgrounds: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.{jpg,gif,png,svg}'],
          dest: 'build/assets/img'
        }]
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: ['components/app/**/*.js']
    },

    csslint: {
      options: {
        csslintrc: '.csslintrc',
        import: false
      },
      lax: {
        src: ['build/assets/css/**/*.css']
      }
    },

    accessibility: {
      options : {
        accessibilityLevel: 'WCAG2<%= WCAG2 %>',
        accessibilityrc: true,
        domElement: true
      },
      development : {
        files: [{
          expand  : true,
          cwd     : 'build/',
          src     : ['*.html']
        }]
      }
    },

    clean: {
      svg: {
        src: ["build/assets/img/**/*.svg"]
      },
      css: {
        src: ["build/assets/css/**/*.css"]
      },
      build: {
        src: ["build"]
      }
    },

    qunit: {
      all: ['qunit/qunit-test-suite.html']
    },

    sync: {
      webfonts: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/font/*.{ttf,eot,woff,svg}'],
          dest: 'build/assets/font'
        }],
        verbose: true
      },
      json: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.json'],
          dest: 'build/assets/json'
        }],
        verbose: true
      },
      favicon: {
        files: [{
          flatten: true,
          expand: true,
          cwd: '.',
          src: ['favicon.ico', 'apple-touch-icon.png'],
          dest: 'build'
        }],
        verbose: true
      }
    },

    modernizr: {
      dist: {
        "devFile" : "components/libs/modernizr-shim/modernizr.min.js",
        "outputFile" : "build/assets/js/libs/modernizr.js",
        "extra" : {
          "shiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "printshiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "load" : false,
          "mq" : false,
          "cssclasses" : true
        },
        "files" : {
          "src": ['components/app/**/*.js', 'build/**/*.css']
        }
      }
    }

  });

  grunt.loadNpmTasks('grunt-accessibility');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks("grunt-modernizr");
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-replace');
  grunt.loadNpmTasks('grunt-sync');
  grunt.loadNpmTasks('grunt-newer');

  grunt.registerTask('default', [
    'replace',
    'imagemin',
    'sync',
    'compass:development',
    'requirejs:development',
    'uglify:deferred_development',
    'uglify:external',
    'clean:svg',
    'clean:css',
    'modernizr',
    'csslint',
    'jshint',
    'accessibility'
  ]);

  grunt.registerTask('production', [
    'clean:build',
    'replace',
    'imagemin',
    'sync',
    'compass:production',
    'requirejs:production',
    'uglify:deferred_production',
    'uglify:external',
    'clean',
    'modernizr'
   ]);

};
<commit_msg>[FEATURE] render deferred css<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      options: {
        livereload: true,
        spawn: false
      },

      // Styling
      scss: {
        files: 'components/**/*.scss',
        tasks: ['newer:imagemin', 'sync', 'compass:development', 'modernizr', 'newer:csslint']
      },

      // Scripting
      js: {
        files: ['components/*.js', 'components/app/**/*.js', '!components/app/_deferred/**/*.js'],
        tasks: ['requirejs:development', 'modernizr', 'newer:jshint'],
      },
      js_deferred: {
        files: ['components/app/_deferred/**/*.js'],
        tasks: ['newer:uglify:deferred_development', 'modernizr', 'newer:jshint'],
      },
      js_bower: {
        files: ['components/libs/**/*.js'],
        tasks: ['newer:uglify:external', 'requirejs:development'],
      },

      // HTML
      html: {
        files: ['*.html', 'components/app/**/*.html' , '!components/libs/**/*.html', '!build/**/*.html'],
        tasks: ['replace', 'newer:accessibility'],
      },

      // Images
      img_content: {
        files: 'img/**/*.{png,gif,jpg,svg}',
        tasks: ['newer:imagemin:content'],
      },
      img_background: {
        files: 'components/**/*.{png,gif,jpg,svg}',
        tasks: ['clean:css', 'newer:imagemin:backgrounds' , 'compass:development', 'clean:css', 'clean:svg', 'newer:csslint'],
      }
    },

    compass: {
      options: {
        asset_cache_buster: false,
        cssDir: 'build/assets/css',
        httpImagesPath: '/assets/img',
        imagesDir: 'build/assets/img',
        noLineComments: true,
        require: 'sass-css-importer',
        sassDir: 'components',
        specify: ['components/*.scss', 'components/app/_deferred/**/*.scss']
      },
      development: {
        options: {
          sourcemap: true,
          environment: 'development'
        }
      },
      production: {
        options: {
          httpPath: "/", // . = relative
          environment: 'production'
        }
      }
    },

    replace: {
      modules: {
        options: {
          patterns: [
            {
              match: /{app:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/' + placeholder + '/' + placeholder + '.html');
              }
            },
            {
              match: /{deferred:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/_deferred/' + placeholder + '/' + placeholder + '.html');
              }
            }
          ]
        },
        files: [
          {
            expand: true,
            flatten: true,
            src: ['*.html'],
            dest: 'build/'
          }
        ]
      }
    },

    requirejs: {
      options: {
        mainConfigFile: "components/<%= _.slugify(ProjectName) %>.js",
        name: "<%= _.slugify(ProjectName) %>",
        out: "build/assets/js/<%= _.slugify(ProjectName) %>.js",
        useStrict: true
      },
      development: {
        options: {
          generateSourceMaps: true,
          optimize: 'none'
        }
      },
      production: {
        options: {
          generateSourceMaps: false,
          optimize: 'uglify'
        }
      }
    },

    uglify: {
      deferred_development: {
        options: {
          sourceMap: true
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      deferred_production: {
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      external: {
        files: {
          'build/assets/js/libs/modernizr.js': ['components/libs/modernizr-shim/modernizr.min.js'],
          'build/assets/js/libs/require.js': ['components/libs/requirejs/require.js']
        }
      }
    },

    imagemin: {
      content: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'img',
          src: ['**/*.{png,jpg,gif,svg}'],
          dest: 'build/img'
        }]
      },
      backgrounds: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.{jpg,gif,png,svg}'],
          dest: 'build/assets/img'
        }]
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: ['components/app/**/*.js']
    },

    csslint: {
      options: {
        csslintrc: '.csslintrc',
        import: false
      },
      lax: {
        src: ['build/assets/css/**/*.css']
      }
    },

    accessibility: {
      options : {
        accessibilityLevel: 'WCAG2<%= WCAG2 %>',
        accessibilityrc: true,
        domElement: true
      },
      development : {
        files: [{
          expand  : true,
          cwd     : 'build/',
          src     : ['*.html']
        }]
      }
    },

    clean: {
      svg: {
        src: ["build/assets/img/**/*.svg"]
      },
      css: {
        src: ["build/assets/css/**/*.css"]
      },
      build: {
        src: ["build"]
      }
    },

    qunit: {
      all: ['qunit/qunit-test-suite.html']
    },

    sync: {
      webfonts: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/font/*.{ttf,eot,woff,svg}'],
          dest: 'build/assets/font'
        }],
        verbose: true
      },
      json: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.json'],
          dest: 'build/assets/json'
        }],
        verbose: true
      },
      favicon: {
        files: [{
          flatten: true,
          expand: true,
          cwd: '.',
          src: ['favicon.ico', 'apple-touch-icon.png'],
          dest: 'build'
        }],
        verbose: true
      }
    },

    modernizr: {
      dist: {
        "devFile" : "components/libs/modernizr-shim/modernizr.min.js",
        "outputFile" : "build/assets/js/libs/modernizr.js",
        "extra" : {
          "shiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "printshiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "load" : false,
          "mq" : false,
          "cssclasses" : true
        },
        "files" : {
          "src": ['components/app/**/*.js', 'build/**/*.css']
        }
      }
    }

  });

  grunt.loadNpmTasks('grunt-accessibility');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks("grunt-modernizr");
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-replace');
  grunt.loadNpmTasks('grunt-sync');
  grunt.loadNpmTasks('grunt-newer');

  grunt.registerTask('default', [
    'replace',
    'imagemin',
    'sync',
    'compass:development',
    'requirejs:development',
    'uglify:deferred_development',
    'uglify:external',
    'clean:svg',
    'clean:css',
    'modernizr',
    'csslint',
    'jshint',
    'accessibility'
  ]);

  grunt.registerTask('production', [
    'clean:build',
    'replace',
    'imagemin',
    'sync',
    'compass:production',
    'requirejs:production',
    'uglify:deferred_production',
    'uglify:external',
    'clean',
    'modernizr'
   ]);

};
<|endoftext|>


<commit_before>describe('Runtime Middleware', function() {
  const baseDir = 'noflo-ui';
  let mw = null;
  let iframe = null;
  let runtimeDefinition = {
    id: '7695e97e-79a5-4a22-879d-847ec9592136',
    protocol: 'iframe',
    type: 'noflo-nodejs',
    address: '/base/spec/mockruntime.html',
    project: '090356f9-dfa6-4b10-b4ea-03038faf68be',
  };
  before(function(done) {
    this.timeout(4000);
    mw = window.middleware('ui/RuntimeMiddleware', baseDir);
    mw.before(done);
  });
  beforeEach(() => mw.beforeEach());
  afterEach(() => mw.afterEach());

  // Set up a fake runtime connection and test that we can play both ends
  describe('receiving a storage:ready action', () => {
    it('should pass it out as-is', (done) => {
      const action = 'storage:ready';
      const payload = {
        runtimes: [
          runtimeDefinition,
        ],
      };
      mw.receivePassCheck(action, (received) => {
        chai.expect(received.runtimes).to.be.an('array');
        chai.expect(received.runtimes.length).to.equal(2);
        chai.expect(received.runtimes[0]).to.eql(runtimeDefinition);
      }, done);
      mw.send(action, payload, payload);
    });
  });
  describe('receiving a storage:opened action', () => {
    it('should connect and pass the storage:opened action', (done) => {
      const action = 'storage:opened';
      const payload = {
        state: 'ok',
        project: {
          id: '090356f9-dfa6-4b10-b4ea-03038faf68be',
          graphs: [],
          components: [],
          type: 'noflo-nodejs',
        },
        graphs: [],
        remote: [],
      };
      const capabilities = [
        'protocol:graph',
        'protocol:component',
        'protocol:network',
        'protocol:runtime'
      ];
      let tries = 0;
      let maxTries = 100;
      const waitForIframe = () => {
        if (runtimeDefinition.querySelector) {
          iframe = document.body.querySelector(runtimeDefinition.querySelector);
          iframe.addEventListener('load', () => {
            iframe.contentWindow.handleProtocolMessage(function(msg, send) {
              chai.expect(msg.protocol).to.equal('runtime');
              chai.expect(msg.command).to.equal('getruntime');
              send('runtime', 'runtime', {
                id: runtimeDefinition.id,
                type: runtimeDefinition.type,
                capabilities,
                version: '0.7',
              });
              setTimeout(() => {
                done();
              }, 1000);
            });
          });
          return;
        }
        if (tries >= maxTries) {
          return done(new Error('No iframe found'));
        }
        setTimeout(waitForIframe, 100);
      };
      mw.send(action, payload, {
        runtimes: [
          runtimeDefinition,
        ],
        compatible: [
          runtimeDefinition,
        ],
        projects: [
          payload.project,
        ],
      });
      waitForIframe();
    }).timeout(4000);
    it('should have added properties from runtime to the definition', (done) => {
      nofloWaitFor(() => {
        if (runtimeDefinition.version) {
          return true;
        }
        return false;
      }, (err) => {
        if (err) {
          done(err);
          return;
        }
        chai.expect(runtimeDefinition.capabilities).to.be.an('array');
        chai.expect(runtimeDefinition.version).to.equal('0.7');
        done();
      });
    });
    it('should have requested components from runtime', (done) => {
      mw.receiveAction('runtime:components', (message) => {
        chai.expect(message.runtime).to.equal(runtimeDefinition.id);
        chai.expect(message.components).to.eql([]);
      }, done);
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('list');
        send('component', 'componentsready', 0);
      });
    });
  });
  describe('receiving a context:edges action', () => {
    it('should pass it out as-is', (done) => {
      const sentEdges = [{
        from: {
          node: 'Foo',
          port: 'out'
        },
        to: {
          node: 'Bar',
          port: 'in'
        }
      }];
      mw.receivePassCheck('context:edges', (received) => {
        chai.expect(received).to.eql(sentEdges);
      }, done);
      mw.send('context:edges', sentEdges, {
        graphs: [
          {
             name: 'foo'
          }
        ],
        runtime: runtimeDefinition,
      });
    });
    it('should send selected edges to the runtime', function(done) {
      const expectedEdges = [{
        src: {
          node: 'Foo',
          port: 'out'
        },
        tgt: {
          node: 'Bar',
          port: 'in'
        },
      }];
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('network');
        chai.expect(msg.command).to.equal('edges');
        chai.expect(msg.payload.graph).to.equal('foo');
        chai.expect(msg.payload.edges).to.eql(expectedEdges);
        done();
      });
    }).timeout(4000);
  });
});
<commit_msg>Handle already-loaded iframe<commit_after>describe('Runtime Middleware', function() {
  const baseDir = 'noflo-ui';
  let mw = null;
  let iframe = null;
  let runtimeDefinition = {
    id: '7695e97e-79a5-4a22-879d-847ec9592136',
    protocol: 'iframe',
    type: 'noflo-nodejs',
    address: '/base/spec/mockruntime.html',
    project: '090356f9-dfa6-4b10-b4ea-03038faf68be',
  };
  before(function(done) {
    this.timeout(4000);
    mw = window.middleware('ui/RuntimeMiddleware', baseDir);
    mw.before(done);
  });
  beforeEach(() => mw.beforeEach());
  afterEach(() => mw.afterEach());

  // Set up a fake runtime connection and test that we can play both ends
  describe('receiving a storage:ready action', () => {
    it('should pass it out as-is', (done) => {
      const action = 'storage:ready';
      const payload = {
        runtimes: [
          runtimeDefinition,
        ],
      };
      mw.receivePassCheck(action, (received) => {
        chai.expect(received.runtimes).to.be.an('array');
        chai.expect(received.runtimes.length).to.equal(2);
        chai.expect(received.runtimes[0]).to.eql(runtimeDefinition);
      }, done);
      mw.send(action, payload, payload);
    });
  });
  describe('receiving a storage:opened action', () => {
    it('should connect and pass the storage:opened action', (done) => {
      const action = 'storage:opened';
      const payload = {
        state: 'ok',
        project: {
          id: '090356f9-dfa6-4b10-b4ea-03038faf68be',
          graphs: [],
          components: [],
          type: 'noflo-nodejs',
        },
        graphs: [],
        remote: [],
      };
      const capabilities = [
        'protocol:graph',
        'protocol:component',
        'protocol:network',
        'protocol:runtime'
      ];
      let tries = 0;
      let maxTries = 100;
      const waitForIframe = () => {
        if (runtimeDefinition.querySelector) {
          iframe = document.body.querySelector(runtimeDefinition.querySelector);
          const callIframe = () => {
            iframe.contentWindow.handleProtocolMessage(function(msg, send) {
              chai.expect(msg.protocol).to.equal('runtime');
              chai.expect(msg.command).to.equal('getruntime');
              send('runtime', 'runtime', {
                id: runtimeDefinition.id,
                type: runtimeDefinition.type,
                capabilities,
                version: '0.7',
              });
              setTimeout(() => {
                done();
              }, 1000);
            });
          };
          if (typeof iframe.contentWindow.handleProtocolMessage === 'function') {
            callIframe();
            return;
          }
          iframe.addEventListener('load', callIframe);
          return;
        }
        if (tries >= maxTries) {
          return done(new Error('No iframe found'));
        }
        setTimeout(waitForIframe, 100);
      };
      mw.send(action, payload, {
        runtimes: [
          runtimeDefinition,
        ],
        compatible: [
          runtimeDefinition,
        ],
        projects: [
          payload.project,
        ],
      });
      waitForIframe();
    }).timeout(4000);
    it('should have added properties from runtime to the definition', (done) => {
      nofloWaitFor(() => {
        if (runtimeDefinition.version) {
          return true;
        }
        return false;
      }, (err) => {
        if (err) {
          done(err);
          return;
        }
        chai.expect(runtimeDefinition.capabilities).to.be.an('array');
        chai.expect(runtimeDefinition.version).to.equal('0.7');
        done();
      });
    });
    it('should have requested components from runtime', (done) => {
      mw.receiveAction('runtime:components', (message) => {
        chai.expect(message.runtime).to.equal(runtimeDefinition.id);
        chai.expect(message.components).to.eql([]);
      }, done);
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('list');
        send('component', 'componentsready', 0);
      });
    });
  });
  describe('receiving a context:edges action', () => {
    it('should pass it out as-is', (done) => {
      const sentEdges = [{
        from: {
          node: 'Foo',
          port: 'out'
        },
        to: {
          node: 'Bar',
          port: 'in'
        }
      }];
      mw.receivePassCheck('context:edges', (received) => {
        chai.expect(received).to.eql(sentEdges);
      }, done);
      mw.send('context:edges', sentEdges, {
        graphs: [
          {
             name: 'foo'
          }
        ],
        runtime: runtimeDefinition,
      });
    });
    it('should send selected edges to the runtime', function(done) {
      const expectedEdges = [{
        src: {
          node: 'Foo',
          port: 'out'
        },
        tgt: {
          node: 'Bar',
          port: 'in'
        },
      }];
      iframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('network');
        chai.expect(msg.command).to.equal('edges');
        chai.expect(msg.payload.graph).to.equal('foo');
        chai.expect(msg.payload.edges).to.eql(expectedEdges);
        done();
      });
    }).timeout(4000);
  });
});
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var path = require('path')
  , Module = require('../module')
  , resolvers = require('../resolvers')
  , utils = require('../utils')
  , debug = require('debug')('jsmt:middleware');

/**
 * Serve JavaScript to browsers in AMD format.
 *
 * @param {String} root
 * @param {Object} options
 * @return {Function}
 * @api public
 */
module.exports = function(root, options) {
  options = options || {};

  var resolve = resolvers[options.resolve || 'amd']({ baseDir: root })
    , mime = options.mime || 'text/javascript';

  return function modules(req, res, next) {
    var mid = req.path
      , ext = path.extname(mid);
    if (mid[0] == '/') {
      mid = mid.slice(1);
    }
    mid = mid.slice(0, mid.length - ext.length);

    // Core modules are compiled into a JavaScript engine (ex: Node).  As such,
    // they cannot be resolved to a file and are expected to be included via
    // other mechanisms.
    if (resolve.isBuiltIn(mid)) {
      debug('core module, deferring: ' + mid);
      return next();
    }

    debug('resolving: ' + mid);
    var filename;
    try {
      filename = resolve(mid);
    } catch(e) {
    }
    debug('resolved to: ' + filename);

    // Failed to resolve module.  Proceed to next middleware, which may be able
    // to resolve the module and service the request.  If not, the request will
    // eventually 404.
    if (!filename) { return next(); }

    // TODO: Implement inline option

    var mod = new Module(mid, null);
    var opts = {};
    utils.merge(opts, options);
    utils.merge(opts, { baseDir: root });

    mod.load(filename, opts, function(err) {
      if (err) { return next(err); }

      if (options.burnID) {
        utils.merge(opts, { burnID: true });
        if (!mod.parent) {
          // If the module has no parent, burn the ID specified by the client in
          // order to keep state consistent between the client and server.
          //
          // In practice, the only time these would differ is when requesting a
          // top-level Node module in which the main JavaScript file resolves to
          // an internal lib file (referenced through package.json main
          // property).
          utils.merge(opts, { moduleID: mod.id });
        }
      }

      var js = mod.toAMD(opts);
      res.setHeader('Content-Type', mime);
      res.end(js);
    });
  }
}
<commit_msg>Implement transitive support in modules middleware.<commit_after>/**
 * Module dependencies.
 */
var path = require('path')
  , Module = require('../module')
  , resolvers = require('../resolvers')
  , utils = require('../utils')
  , debug = require('debug')('jsmt:middleware');

/**
 * Serve JavaScript to browsers in AMD format.
 *
 * @param {String} root
 * @param {Object} options
 * @return {Function}
 * @api public
 */
module.exports = function(root, options) {
  options = options || {};

  var resolve = resolvers[options.resolve || 'amd']({ baseDir: root })
    , transitive = options.transitive || false
    , mime = options.mime || 'text/javascript';

  return function modules(req, res, next) {
    var mid = req.path
      , ext = path.extname(mid);
    if (mid[0] == '/') {
      mid = mid.slice(1);
    }
    mid = mid.slice(0, mid.length - ext.length);

    // Core modules are compiled into a JavaScript engine (ex: Node).  As such,
    // they cannot be resolved to a file and are expected to be included via
    // other mechanisms.
    if (resolve.isBuiltIn(mid)) {
      debug('core module, deferring: ' + mid);
      return next();
    }

    debug('resolving: ' + mid);
    var filename;
    try {
      filename = resolve(mid);
    } catch(e) {
    }
    debug('resolved to: ' + filename);

    // Failed to resolve module.  Proceed to next middleware, which may be able
    // to resolve the module and service the request.  If not, the request will
    // eventually 404.
    if (!filename) { return next(); }

    var mod = Module.get(mid, filename);
    var opts = {};
    utils.merge(opts, options);
    utils.merge(opts, { baseDir: root });
    // Multiple module middleware are typically in use to construct a "virtual"
    // module space.  Allow unresolved modules within any single instance, under
    // the assumption that a different instance will resolve the module.
    utils.merge(opts, { allowAllUnresolved: true });
    // Module IDs must be burned when transporting multiple modules in a single
    // response.
    if (transitive) { utils.merge(opts, { burnID: true }); }

    mod.load(filename, opts, function(err) {
      if (err) { return next(err); }

      var js = '';

      // Traverse the module tree, constructing AMD-compatible JavaScript.  If
      // the `transitive` option is disabled, the tree will consist of just the
      // requested module.
      traverse(mod, function(m) {
        if (!m.filename) { return; }

        var mopts = {};
        utils.merge(mopts, opts);
        if (transitive && !m.parent) {
          // If the module has no parent, burn the ID specified by the client in
          // order to keep state consistent between the client and server.
          //
          // In practice, the only time these would differ is when requesting a
          // top-level Node module in which the main JavaScript file resolves to
          // an internal file inside a lib directory (referenced through the
          // `main` property of package.json).
          utils.merge(mopts, { moduleID: m.id });
        }

        js += m.toAMD(mopts) + '\r\n';
      });

      res.setHeader('Content-Type', mime);
      res.end(js);
    });
  }
}

function traverse(m, fn) {
  m.children.forEach(function(child) {
    traverse(child, fn);
  });
  fn(m);
}

<|endoftext|>


<commit_before>import moment from 'moment';

import statesDataset from 'app/data/states.json!';
import recallClassificationsDataset from 'app/data/recall-classifications.json!';
import recallStatusesDataset from 'app/data/recall-statuses.json!';

export default class ListingController {

  static get $inject() { return ['recalls', '$state', '$stateParams', 'API_INFO']; }

  constructor(recalls, $state, $stateParams, API_INFO) {

    this.recalls = recalls;

    this.$state = $state;
    this.API_INFO = API_INFO;

    this.criteria = {
      month: parseInt($stateParams.month, 10),
      year: parseInt($stateParams.year, 10),
      state: $stateParams.state
    };

    // Build a structure for the momths
    this.months = [];
    for(let month = 0; month < 12; month++) {
      let date = moment().month(month);
      this.months.push({
        month: month + 1,
        name: date.format('MMM')
      });
    }

    // Build a structure for the valid years
    this.years = [ ];
    for(let year = 2012; year <= moment().year(); year++) {
      this.years.push(year);
    }

    // The list of states
    this.states = statesDataset;

  }

  selectMonth(month) {
    return this.$state.go('home.listing', {
      month: month.month,
      year: this.criteria.year,
      state: this.criteria.state
    });
  }

  selectYear(year) {
    return this.$state.go('home.listing', {
      month: this.criteria.month,
      year: year,
      state: this.criteria.state
    });
  }

  selectState(state) {
    return this.$state.go('home.listing', {
      month: this.criteria.month,
      year: this.criteria.year,
      state: state.abbr
    });
  }

  isMonthSelected(month) {
    return month.month === this.criteria.month;
  }

  isYearSelected(year) {
    return year === this.criteria.year;
  }

  isStateSelected(state) {
    return state.abbr === this.criteria.state;
  }

  isValidMonth(month) {
    let period = moment({ year: this.criteria.year, month: month.month - 1, day: 1 });
    return period.isBetween(this.API_INFO.dataset.periodStart, this.API_INFO.dataset.periodEnd);
  }

  isValidYear(year) {
    let period = moment({ year: year, month: this.criteria.month - 1, day: 1 });
    return period.isAfter(this.API_INFO.dataset.periodStart)
      && period.isBefore(this.API_INFO.dataset.periodEnd);
  }

  // Class I = Dangerous or defective products that predictably could cause
  //  serious health problems or death. Examples include: food found to contain
  //  botulinum toxin, food with undeclared allergens, a label mix-up on a
  //  lifesaving drug, or a defective artificial heart valve.
  // Class II = Products that might cause a temporary health problem, or pose
  //  only a slight threat of a serious nature. Example: a drug that is
  //  under-strength but that is not used to treat life-threatening situations.
  // Class III = Products that are unlikely to cause any adverse health reaction,
  //  but that violate FDA labeling or manufacturing laws. Examples include: a
  //  minor container defect and lack of English labeling in a retail food.
  getClassificationStyle(classification) {

    let match = recallClassificationsDataset[classification];
    if (match) {
      return match.style;
    }
    return 'default';
  }

  getClassificationDescription(classification) {
    let match = recallClassificationsDataset[classification];
    if (match) {
      return match.description;
    }
    return 'No description available';
  }

  // On-Going = A recall which is currently in progress.
  // Completed = The recall action reaches the point at which the firm has actually
  //  retrieved and impounded all outstanding product that could reasonably be expected
  //  to be recovered, or has completed all product corrections.
  // Terminated = FDA has determined that all reasonable efforts have been made to
  //  remove or correct the violative product in accordance with the recall strategy,
  //  and proper disposition has been made according to the degree of hazard.
  // Pending = Actions that have been determined to be recalls, but that remain
  //  in the process of being classified.
  getStatusStyle(status) {

    let match = recallStatusesDataset[status];
    if (match) {
      return match.style;
    }
    return 'default';
  }

  getStatusDescription(status) {
    let match = recallStatusesDataset[status];
    if (match) {
      return match.description;
    }
    return 'No description available';
  }

}
<commit_msg>Use multiline function comments<commit_after>import moment from 'moment';

import statesDataset from 'app/data/states.json!';
import recallClassificationsDataset from 'app/data/recall-classifications.json!';
import recallStatusesDataset from 'app/data/recall-statuses.json!';

export default class ListingController {

  static get $inject() { return ['recalls', '$state', '$stateParams', 'API_INFO']; }

  constructor(recalls, $state, $stateParams, API_INFO) {

    this.recalls = recalls;

    this.$state = $state;
    this.API_INFO = API_INFO;

    this.criteria = {
      month: parseInt($stateParams.month, 10),
      year: parseInt($stateParams.year, 10),
      state: $stateParams.state
    };

    // Build a structure for the momths
    this.months = [];
    for(let month = 0; month < 12; month++) {
      let date = moment().month(month);
      this.months.push({
        month: month + 1,
        name: date.format('MMM')
      });
    }

    // Build a structure for the valid years
    this.years = [ ];
    for(let year = 2012; year <= moment().year(); year++) {
      this.years.push(year);
    }

    // The list of states
    this.states = statesDataset;

  }

  selectMonth(month) {
    return this.$state.go('home.listing', {
      month: month.month,
      year: this.criteria.year,
      state: this.criteria.state
    });
  }

  selectYear(year) {
    return this.$state.go('home.listing', {
      month: this.criteria.month,
      year: year,
      state: this.criteria.state
    });
  }

  selectState(state) {
    return this.$state.go('home.listing', {
      month: this.criteria.month,
      year: this.criteria.year,
      state: state.abbr
    });
  }

  isMonthSelected(month) {
    return month.month === this.criteria.month;
  }

  isYearSelected(year) {
    return year === this.criteria.year;
  }

  isStateSelected(state) {
    return state.abbr === this.criteria.state;
  }

  isValidMonth(month) {
    let period = moment({ year: this.criteria.year, month: month.month - 1, day: 1 });
    return period.isBetween(this.API_INFO.dataset.periodStart, this.API_INFO.dataset.periodEnd);
  }

  isValidYear(year) {
    let period = moment({ year: year, month: this.criteria.month - 1, day: 1 });
    return period.isAfter(this.API_INFO.dataset.periodStart)
      && period.isBefore(this.API_INFO.dataset.periodEnd);
  }

  /**
   * Class I = Dangerous or defective products that predictably could cause
   *   serious health problems or death. Examples include: food found to contain
   *   botulinum toxin, food with undeclared allergens, a label mix-up on a
   *   lifesaving drug, or a defective artificial heart valve.
   * Class II = Products that might cause a temporary health problem, or pose
   *   only a slight threat of a serious nature. Example: a drug that is
   *   under-strength but that is not used to treat life-threatening situations.
   * Class III = Products that are unlikely to cause any adverse health reaction,
   *   but that violate FDA labeling or manufacturing laws. Examples include: a
   *   minor container defect and lack of English labeling in a retail food.
   */
  getClassificationStyle(classification) {

    let match = recallClassificationsDataset[classification];
    if (match) {
      return match.style;
    }
    return 'default';
  }

  getClassificationDescription(classification) {
    let match = recallClassificationsDataset[classification];
    if (match) {
      return match.description;
    }
    return 'No description available';
  }

  /**
  * On-Going = A recall which is currently in progress.
  * Completed = The recall action reaches the point at which the firm has actually
  *   retrieved and impounded all outstanding product that could reasonably be expected
  *   to be recovered, or has completed all product corrections.
  * Terminated = FDA has determined that all reasonable efforts have been made to
  *   remove or correct the violative product in accordance with the recall strategy,
  *   and proper disposition has been made according to the degree of hazard.
  * Pending = Actions that have been determined to be recalls, but that remain
  *   in the process of being classified.
  */
  getStatusStyle(status) {
    let match = recallStatusesDataset[status];
    if (match) {
      return match.style;
    }
    return 'default';
  }

  getStatusDescription(status) {
    let match = recallStatusesDataset[status];
    if (match) {
      return match.description;
    }
    return 'No description available';
  }

}
<|endoftext|>


<commit_before>'use strict';

var utils = require('../helpers/utils');
var conf = utils.readJson('conf.json');

var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
var sdb = new AWS.SimpleDB();

var ip = function (req) {
    if (req == null) return 'null';
    return req.ip;
};

var log = function (req, action) {
    var attributes = [];

    attributes.push({ Name: 'aSource', Value: '1' });
    attributes.push({ Name: 'bDate', Value: currentDateFormatted() });
    attributes.push({ Name: 'cIP', Value: ip(req) });
    attributes.push({ Name: 'dAction', Value: action });

    if (arguments.length > 2) {
        for (var i = 2; i < arguments.length; i++) {
            attributes.push({ Name: 'eArg_' + (i - 2), Value: arguments[i] });
        }
    }

    var uniqueName = utils.random2(16);
    var simpleDbParams = {
        DomainName: conf.Sdb.Domain,
        ItemName: conf.Sdb.LogItemPrefix + uniqueName,
        Attributes: attributes
    };

    sdb.putAttributes(simpleDbParams, function (err, data) {
        if (err) console.log(err.stack);
    });
};

function currentDateFormatted() {
    var date = new Date();

    return date.getUTCFullYear()
        + '-'
        + utils.pad(date.getUTCMonth(), 2)
        + '-'
        + utils.pad(date.getUTCDate(), 2)
        + ' '
        + utils.pad(date.getUTCHours(), 2)
        + ':'
        + utils.pad(date.getUTCMinutes(), 2)
        + ':'
        + utils.pad(date.getUTCSeconds(), 2);
}

exports.log = log;<commit_msg>(cc-app) fix in date formatting - get(UTC)Month() returns 0-11, not 1-12<commit_after>'use strict';

var utils = require('../helpers/utils');
var conf = utils.readJson('conf.json');

var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
var sdb = new AWS.SimpleDB();

var ip = function (req) {
    if (req == null) return 'null';
    return req.ip;
};

var log = function (req, action) {
    var attributes = [];

    attributes.push({ Name: 'aSource', Value: '1' });
    attributes.push({ Name: 'bDate', Value: currentDateFormatted() });
    attributes.push({ Name: 'cIP', Value: ip(req) });
    attributes.push({ Name: 'dAction', Value: action });

    if (arguments.length > 2) {
        for (var i = 2; i < arguments.length; i++) {
            attributes.push({ Name: 'eArg_' + (i - 2), Value: arguments[i] });
        }
    }

    var uniqueName = utils.random2(16);
    var simpleDbParams = {
        DomainName: conf.Sdb.Domain,
        ItemName: conf.Sdb.LogItemPrefix + uniqueName,
        Attributes: attributes
    };

    sdb.putAttributes(simpleDbParams, function (err, data) {
        if (err) console.log(err.stack);
    });
};

function currentDateFormatted() {
    var date = new Date();

    return date.getUTCFullYear()
        + '-'
        + utils.pad(date.getUTCMonth() + 1, 2)
        + '-'
        + utils.pad(date.getUTCDate(), 2)
        + ' '
        + utils.pad(date.getUTCHours(), 2)
        + ':'
        + utils.pad(date.getUTCMinutes(), 2)
        + ':'
        + utils.pad(date.getUTCSeconds(), 2);
}

exports.log = log;<|endoftext|>