<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is goverened by a BSD-style
 * license that can be found in the LICENSE file.
 */

suite('HTMLCanvasElement', function() {

  var iconUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAHklEQVQ4T2Nk+A+EFADGUQMYRsOAYTQMgHloGKQDAJXkH/HZpKBrAAAAAElFTkSuQmCC';

  test('getContext null', function() {
    var canvas = document.createElement('canvas');
    // IE10 returns undefined instead of null
    assert.isTrue(canvas.getContext('unknown') == null);
  });

  test('getContext 2d', function() {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    assert.instanceOf(context, CanvasRenderingContext2D);
    assert.equal(context.canvas, canvas);
  });

  test('getContext webgl', function() {
    // IE10 does not have WebGL.
    if (typeof WebGLRenderingContext === 'undefined')
      return;

    var canvas = document.createElement('canvas');
    var context = null;
    // Firefox throws exception if graphics card is not supported
    try {
      context = canvas.getContext('webgl');
    }
    catch(ex) {
    }
    // Chrome returns null if the graphics card is not supported
    assert.isTrue(context === null || context instanceof WebGLRenderingContext);

    if (context != null)
      assert.equal(context.canvas, canvas);
  });

  test('context instance properties', function() {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    assert.isString(context.fillStyle);
    assert.isString(context.strokeStyle);
    assert.isString(context.textBaseline);
    assert.isString(context.textAlign);
    assert.isString(context.font);
    assert.isNumber(context.lineDashOffset);
    assert.isString(context.shadowColor);
    assert.isNumber(context.shadowBlur);
    assert.isNumber(context.shadowOffsetY);
    assert.isNumber(context.shadowOffsetX);
    assert.isNumber(context.miterLimit);
    assert.isString(context.lineJoin);
    assert.isString(context.lineCap);
    assert.isNumber(context.lineWidth);
    assert.isNumber(context.globalAlpha);
  });

  test('2d drawImage using new Image', function(done) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    // var img = new Image();
    var img = document.createElement('img');
    img.width = img.height = 32;
    img.onload = function() {
      context.drawImage(img, 0, 0);
      done();
    };
    img.src = iconUrl;
  });

  test('2d drawImage', function(done) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    var img = document.createElement('img');
    img.onload = function() {
      context.drawImage(img, 0, 0);
      done();
    };
    img.src = iconUrl;
  });

  test('2d createPattern', function(done) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var img = document.createElement('img');
    img.onload = function() {
      var pattern = context.createPattern(img, 'repeat');
      done();
    };
    img.src = iconUrl;
  });

  test('WebGL texImage2D', function(done) {
    var canvas = document.createElement('canvas');
    var gl = null;
    // Firefox throws exception if graphics card is not supported
    try {
      gl = canvas.getContext('webgl');
    } catch (ex) {
    }
    // IE10 does not have WebGL.
    // Chrome returns null if the graphics card is not supported
    if (!gl) {
      done();
      return;
    }

    var imageData = document.createElement('canvas').getContext('2d').
        createImageData(16, 16);
    var arrayBufferView = new Uint8Array(16 * 16 * 4);

    var img = document.createElement('img');
    img.onload = function() {
      var texture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
                    imageData);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                    16, 16, 0,
                    gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView);

      done();
    };
    img.src = iconUrl;
  });

  test('WebGL context instance properties', function() {
    var canvas = document.createElement('canvas');
    var gl = null;
    // Firefox throws exception if graphics card is not supported
    try {
      gl = canvas.getContext('webgl');
    } catch (ex) {
    }
    // IE10 does not have WebGL.
    // Chrome returns null if the graphics card is not supported
    if (!gl) {
      return;
    }

    assert.isNumber(gl.drawingBufferHeight);
    assert.isNumber(gl.drawingBufferWidth);
  });

  test('WebGL texSubImage2D', function(done) {
    var canvas = document.createElement('canvas');
    var gl = null;
    // Firefox throws exception if graphics card is not supported
    try {
      gl = canvas.getContext('webgl');
    } catch(ex) {
    }
    // IE10 does not have WebGL.
    // Chrome returns null if the graphics card is not supported
    if (!gl) {
      done();
      return;
    }

    var arrayBufferView = new Uint8Array(16 * 16 * 4);

    var img = document.createElement('img');
    img.onload = function() {
      var texture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0,
          16, 16,
          gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView);
      done();
    };
    img.src = iconUrl;
  });

  test('width', function() {
    var canvas = document.createElement('canvas');
    assert.isNumber(canvas.width);
  });

  test('height', function() {
    var canvas = document.createElement('canvas');
    assert.isNumber(canvas.height);
  });

});
<commit_msg>Disable the lineDashOffset test since it is not available in Firefox 25<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is goverened by a BSD-style
 * license that can be found in the LICENSE file.
 */

suite('HTMLCanvasElement', function() {

  var iconUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAHklEQVQ4T2Nk+A+EFADGUQMYRsOAYTQMgHloGKQDAJXkH/HZpKBrAAAAAElFTkSuQmCC';

  test('getContext null', function() {
    var canvas = document.createElement('canvas');
    // IE10 returns undefined instead of null
    assert.isTrue(canvas.getContext('unknown') == null);
  });

  test('getContext 2d', function() {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    assert.instanceOf(context, CanvasRenderingContext2D);
    assert.equal(context.canvas, canvas);
  });

  test('getContext webgl', function() {
    // IE10 does not have WebGL.
    if (typeof WebGLRenderingContext === 'undefined')
      return;

    var canvas = document.createElement('canvas');
    var context = null;
    // Firefox throws exception if graphics card is not supported
    try {
      context = canvas.getContext('webgl');
    }
    catch(ex) {
    }
    // Chrome returns null if the graphics card is not supported
    assert.isTrue(context === null || context instanceof WebGLRenderingContext);

    if (context != null)
      assert.equal(context.canvas, canvas);
  });

  test('context instance properties', function() {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    assert.isString(context.fillStyle);
    assert.isString(context.strokeStyle);
    assert.isString(context.textBaseline);
    assert.isString(context.textAlign);
    assert.isString(context.font);

    // lineDashOffset is not available in Firefox 25
    // assert.isNumber(context.lineDashOffset);

    assert.isString(context.shadowColor);
    assert.isNumber(context.shadowBlur);
    assert.isNumber(context.shadowOffsetY);
    assert.isNumber(context.shadowOffsetX);
    assert.isNumber(context.miterLimit);
    assert.isString(context.lineJoin);
    assert.isString(context.lineCap);
    assert.isNumber(context.lineWidth);
    assert.isNumber(context.globalAlpha);
  });

  test('2d drawImage using new Image', function(done) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    // var img = new Image();
    var img = document.createElement('img');
    img.width = img.height = 32;
    img.onload = function() {
      context.drawImage(img, 0, 0);
      done();
    };
    img.src = iconUrl;
  });

  test('2d drawImage', function(done) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    var img = document.createElement('img');
    img.onload = function() {
      context.drawImage(img, 0, 0);
      done();
    };
    img.src = iconUrl;
  });

  test('2d createPattern', function(done) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var img = document.createElement('img');
    img.onload = function() {
      var pattern = context.createPattern(img, 'repeat');
      done();
    };
    img.src = iconUrl;
  });

  test('WebGL texImage2D', function(done) {
    var canvas = document.createElement('canvas');
    var gl = null;
    // Firefox throws exception if graphics card is not supported
    try {
      gl = canvas.getContext('webgl');
    } catch (ex) {
    }
    // IE10 does not have WebGL.
    // Chrome returns null if the graphics card is not supported
    if (!gl) {
      done();
      return;
    }

    var imageData = document.createElement('canvas').getContext('2d').
        createImageData(16, 16);
    var arrayBufferView = new Uint8Array(16 * 16 * 4);

    var img = document.createElement('img');
    img.onload = function() {
      var texture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
                    imageData);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                    16, 16, 0,
                    gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView);

      done();
    };
    img.src = iconUrl;
  });

  test('WebGL context instance properties', function() {
    var canvas = document.createElement('canvas');
    var gl = null;
    // Firefox throws exception if graphics card is not supported
    try {
      gl = canvas.getContext('webgl');
    } catch (ex) {
    }
    // IE10 does not have WebGL.
    // Chrome returns null if the graphics card is not supported
    if (!gl) {
      return;
    }

    assert.isNumber(gl.drawingBufferHeight);
    assert.isNumber(gl.drawingBufferWidth);
  });

  test('WebGL texSubImage2D', function(done) {
    var canvas = document.createElement('canvas');
    var gl = null;
    // Firefox throws exception if graphics card is not supported
    try {
      gl = canvas.getContext('webgl');
    } catch(ex) {
    }
    // IE10 does not have WebGL.
    // Chrome returns null if the graphics card is not supported
    if (!gl) {
      done();
      return;
    }

    var arrayBufferView = new Uint8Array(16 * 16 * 4);

    var img = document.createElement('img');
    img.onload = function() {
      var texture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0,
          16, 16,
          gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView);
      done();
    };
    img.src = iconUrl;
  });

  test('width', function() {
    var canvas = document.createElement('canvas');
    assert.isNumber(canvas.width);
  });

  test('height', function() {
    var canvas = document.createElement('canvas');
    assert.isNumber(canvas.height);
  });

});
<|endoftext|>


<commit_before>var Article = mongoose.model('Article')
  , Comment = mongoose.model('Comment')

module.exports = function(app, auth){

  // New article
  app.get('/articles/new', auth.requiresLogin, function(req, res){
    res.render('articles/new', {
      title: 'New Article',
      article: new Article({})
    })
  })

  app.param('id', function(req, res, next, id){
    Article
      .findOne({ _id : req.params.id })
      .populate('user')
      .run(function(err,article) {
        if (err) return next(err)
        if (!article) return next(new Error('Failed to load article ' + id))
        req.article = article
        Comment
          .find({article : req.article})
          .populate('user')
          .run(function (err, comments) {
            if (err) throw err
            req.comments = comments
            next()
          })
      })
  })

  // Create an article
  app.post('/articles', function(req, res){
    var article = new Article(req.body.article)
    article.user = req.session.auth.userId

    article.save(function(err){
      if (err) {
        utils.mongooseErrorHandler(err, req)
        res.render('articles/new', {
            title: 'New Article'
          , article: article
        })
      }
      else {
        req.flash('notice', 'Created successfully')
        res.redirect('/article/'+article._id)
      }
    })
  })

  // Edit an article
  app.get('/article/:id/edit', auth.requiresLogin, auth.article.hasAuthorization, function(req, res){
    res.render('articles/edit', {
      title: 'Edit '+req.article.title,
      article: req.article
    })
  })

  // Update article
  app.put('/articles/:id', auth.requiresLogin, auth.article.hasAuthorization, function(req, res){
    var article = req.article

    article.title = req.body.article.title
    article.body = req.body.article.body

    article.save(function(err, doc) {
      if (err) {
        utils.mongooseErrorHandler(err, req)
        res.render('articles/edit', {
            title: 'Edit Article'
          , article: article
        })
      }
      else {
        req.flash('notice', 'Updated successfully')
        res.redirect('/article/'+article._id)
      }
    })
  })

  // View an article
  app.get('/article/:id', function(req, res){
    res.render('articles/show', {
      title: req.article.title,
      article: req.article,
      comments: req.comments
    })
  })

  // Delete an article
  app.del('/article/:id', auth.requiresLogin, auth.article.hasAuthorization, function(req, res){
    var article = req.article
    article.remove(function(err){
      // req.flash('notice', 'Deleted successfully')
      res.redirect('/articles')
    })
  })

  // Listing of Articles
  app.get('/articles', function(req, res){
    Article
      .find({})
      .populate('user')
      .desc('created_at') // sort by date
      .run(function(err, articles) {
        if (err) throw err
        res.render('articles/index', {
          title: 'List of Articles',
          articles: articles
        })
      })
  })

  // home
  app.get('/', function(req, res){
    res.redirect('/articles')
  })
}
<commit_msg>redo articles controller<commit_after>
var mongoose = require('mongoose')
  , Article = mongoose.model('Article')

// New article
exports.new = function(req, res){
  res.render('articles/new', {
    title: 'New Article',
    article: new Article({})
  })
}

// Create an article
exports.create = function (req, res) {
  var article = new Article(req.body.article)
  article.user = req.user

  article.save(function(err){
    if (err) {
      res.render('articles/new', {
          title: 'New Article'
        , article: article
        , errors: err.errors
      })
    }
    else {
      res.redirect('/article/'+article._id)
    }
  })
}

// Edit an article
exports.edit = function (req, res) {
  res.render('articles/edit', {
    title: 'Edit '+req.article.title,
    article: req.article
  })
}

// Update article
exports.update = function(req, res){
  var article = req.article

  article.save(function(err, doc) {
    if (err) {
      utils.mongooseErrorHandler(err, req)
      res.render('articles/edit', {
          title: 'Edit Article'
        , article: article
        , errors: err.errors
      })
    }
    else {
      res.redirect('/article/'+article._id)
    }
  })
}

// View an article
exports.show = function(req, res){
  res.render('articles/show', {
    title: req.article.title,
    article: req.article,
    comments: req.comments
  })
}

// Delete an article
exports.destroy = function(req, res){
  var article = req.article
  article.remove(function(err){
    // req.flash('notice', 'Deleted successfully')
    res.redirect('/articles')
  })
}

// Listing of Articles
exports.index = function(req, res){
  Article
    .find({})
    .populate('user')
    .populate('comments')
    .sort({'created_at': -1}) // sort by date
    .exec(function(err, articles) {
      if (err) throw err
      res.render('articles/index', {
        title: 'List of Articles',
        articles: articles
      })
    })
}

<|endoftext|>


<commit_before>require("should");

var dailyOperationDataUtil = require("../../data-util/production/finishing-printing/daily-operation-data-util");
var shipmentDocumentDataUtil = require("../../data-util/inventory/finishing-printing/fp-shipment-document-data-util");

var helper = require("../../helper");
var validate = require("dl-models").validator;
var codeGenerator = require('../../../src/utils/code-generator');
var moment = require('moment');

var ProductionOrderManager = require("../../../src/managers/sales/production-order-manager");
var manager = null;

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            manager = new ProductionOrderManager(db, { username: 'dev' });
            done();
        })
        .catch(e => {
            done(e);
        });
});

// it("#01. should success when get all data", function (done) {
//     Promise.all([dailyOperationDataUtil.getNewWhiteOrderTypeData("input"), dailyOperationDataUtil.getNewPrintingOrderTypeData("input"), shipmentDocumentDataUtil.getNewWhiteOrderTypeData(), shipmentDocumentDataUtil.getNewPrintingOrderTypeData()])
//         .then((results) => {
//             done();
//         })
//         .catch(e => {
//             done(e);
//         });
// });

it("#01. should success when get daily operation data", function (done) {
    dailyOperationDataUtil.getNewWhiteOrderTypeData("input")
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

it("#02. should success when get daily operation data", function (done) {
    dailyOperationDataUtil.getNewPrintingOrderTypeData("input")
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

it("#03. should success when get shipment data", function (done) {
    shipmentDocumentDataUtil.getNewWhiteOrderTypeData()
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

it("#04. should success when get shipment data", function (done) {
    shipmentDocumentDataUtil.getNewPrintingOrderTypeData()
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

var query = {};
var resultForExcelTest = {};
it('#05. should success when create report', function (done) {

    query.orderType = "";
    query.year = moment().format('YYYY');

    manager.getOrderStatusReport(query, 7)
        .then((result) => {
            resultForExcelTest.data = result;
            done();
        }).catch(e => {
            done(e);
        });
});

it('#06. should success when create report', function (done) {

    query.orderType = "PRINTING";
    query.year = moment().format('YYYY');

    manager.getOrderStatusReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#07. should success when create report', function (done) {

    query.orderType = "WHITE";
    query.year = moment().format('YYYY');

    manager.getOrderStatusReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#08. should success when get data for Excel Report', function (done) {

    manager.getOrderStatusXls(resultForExcelTest, query)
        .then((xlsData) => {
            xlsData.should.have.property('data');
            xlsData.should.have.property('options');
            xlsData.should.have.property('name');
            done();
        }).catch(e => {
            done(e);
        });
});

it('#08. should success when create report detail', function (done) {

    query.orderType = "PRINTING";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#09. should success when create report detail', function (done) {

    query.orderType = "WHITE";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#10. should success when create report detail', function (done) {

    query.orderType = "";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            resultForExcelTest = result;
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#11. should success when create report detail', function (done) {

    query.orderType = "PRINTING";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#12. should success when get data detail for Excel Report', function (done) {

    manager.getOrderStatusDetailXls(resultForExcelTest, query)
        .then((xlsData) => {
            xlsData.should.have.property('data');
            xlsData.should.have.property('options');
            xlsData.should.have.property('name');
            done();
        }).catch(e => {
            done(e);
        });
});<commit_msg>Order Status<commit_after>require("should");

var dailyOperationDataUtil = require("../../data-util/production/finishing-printing/daily-operation-data-util");
var shipmentDocumentDataUtil = require("../../data-util/inventory/finishing-printing/fp-shipment-document-data-util");

var helper = require("../../helper");
var validate = require("dl-models").validator;
var codeGenerator = require('../../../src/utils/code-generator');
var moment = require('moment');

var ProductionOrderManager = require("../../../src/managers/sales/production-order-manager");
var manager = null;

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            manager = new ProductionOrderManager(db, { username: 'dev' });
            done();
        })
        .catch(e => {
            done(e);
        });
});

// it("#01. should success when get all data", function (done) {
//     Promise.all([dailyOperationDataUtil.getNewWhiteOrderTypeData("input"), dailyOperationDataUtil.getNewPrintingOrderTypeData("input"), shipmentDocumentDataUtil.getNewWhiteOrderTypeData(), shipmentDocumentDataUtil.getNewPrintingOrderTypeData()])
//         .then((results) => {
//             done();
//         })
//         .catch(e => {
//             done(e);
//         });
// });

it("#01. should success when get daily operation data", function (done) {
    dailyOperationDataUtil.getNewWhiteOrderTypeData("input")
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

it("#02. should success when get daily operation data", function (done) {
    dailyOperationDataUtil.getNewPrintingOrderTypeData("input")
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

it("#03. should success when get shipment data", function (done) {
    shipmentDocumentDataUtil.getNewWhiteOrderTypeData()
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

it("#04. should success when get shipment data", function (done) {
    shipmentDocumentDataUtil.getNewPrintingOrderTypeData()
        .then((result) => {
            done();
        })
        .catch(e => {
            done(e);
        });
});

var query = {};
var resultForExcelTest = {};
it('#05. should success when create report', function (done) {

    query.orderType = "";
    query.year = moment().format('YYYY');

    manager.getOrderStatusReport(query, 7)
        .then((result) => {
            resultForExcelTest.data = result;
            done();
        }).catch(e => {
            done(e);
        });
});

it('#06. should success when create report', function (done) {

    query.orderType = "PRINTING";
    query.year = moment().format('YYYY');

    manager.getOrderStatusReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#07. should success when create report', function (done) {

    query.orderType = "WHITE";
    query.year = moment().format('YYYY');

    manager.getOrderStatusReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#08. should success when get data for Excel Report', function (done) {

    manager.getOrderStatusXls(resultForExcelTest, query)
        .then((xlsData) => {
            xlsData.should.have.property('data');
            xlsData.should.have.property('options');
            xlsData.should.have.property('name');
            done();
        }).catch(e => {
            done(e);
        });
});

it('#08. should success when create report detail', function (done) {

    query.orderType = "PRINTING";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#09. should success when create report detail', function (done) {

    query.orderType = "WHITE";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#10. should success when create report detail', function (done) {

    query.orderType = "";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            resultForExcelTest.data = result;
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#11. should success when create report detail', function (done) {

    query.orderType = "PRINTING";
    query.year = moment().year();
    query.month = moment().month();

    manager.getOrderStatusDetailReport(query, 7)
        .then((result) => {
            done();
        }).catch((e) => {
            done(e);
        });
});

it('#12. should success when get data detail for Excel Report', function (done) {

    manager.getOrderStatusDetailXls(resultForExcelTest, query)
        .then((xlsData) => {
            xlsData.should.have.property('data');
            xlsData.should.have.property('options');
            xlsData.should.have.property('name');
            done();
        }).catch(e => {
            done(e);
        });
});<|endoftext|>


<commit_before>/**
 * conjoon
 * (c) 2002-2012 siteartwork.de/conjoon.org
 * licensing@conjoon.org
 *
 * $Author$
 * $Id$
 * $Date$
 * $Revision$
 * $LastChangedDate$
 * $LastChangedBy$
 * $URL$
 */

Ext.namespace('com.conjoon.groupware.email');

/**
 * Controller for previewing Feed contents.
 * This is a singleton-object and used bycom.conjoon.groupware.feeds.FeedGrid
 * to enable previewing a feed in a panel sliding out left of the grid panel,
 * aligned to the current selected cell. The panel is closable and draggable.
 * Once a panel was created, it can not be closed such that the object gets
 * destroyed.
 *
 * The preview panel depends on record properties passed from the grid to the
 * showPreview-method. The needed properties are
 *
 *

 *
id - the id of the feed to preview

 *
title - the title of the feed

 *
link - the link of the feed  of the feed to preview

 *
pubDate - the publication date of the feed

 *

 *
 * @author Thorsten Suckow-Homberg <tsuckow@conjoon.org>
 */
com.conjoon.groupware.email.EmailPreview = function() {

// {{{ private members

    /**
     * @type {Ext.Element} gridEl The element of the grid the preview is attached to
     */
    var gridEl = null;

    /**
     * Initial width of the preview panel.
     * @param {Number}
     */
    var width = 330;

    /**
     * Initial height of the preview panel.
     * @param {Number}
     */
    var height = 250;

    /**
     * The y position of the last clicked cell.
     * @param {Number} clkCellY
     */
    var clkCellY = 0;

    /**
     * Stores the id of the last previewed feed. If a preview panel gets closed,
     * the property will be reset to <tt>null</tt>.
     */
    var activeEmailId = null;

    /**
     * The html container that is responsible for enabling animation effects
     * of the preview panel.
     */
    var container = null;

    /**
     * The panel that is used for previewing a feed content. The property will
     * hold an instance of <tt>Ext.Panel</tt> which is being reused for previewing
     * until the panel was detached from the grid.
     */
    var previewPanel = null;

    /**
     * Stores the active cell to which the preview panel is aligned.
     */
    var clkCell = null;

    /**
     * Stores the row index of the cell to which the preview panel is aligned.
     */
    var clkRowIndex = -1;

    /**
     * Stores the record information of the cell's row associated with previewing.
     * The record needs to have a id-property that holds a unique id of the
     * grid's record that was selected.
     */
    var clkRecord = null;

    var loadMask = null;

    var emailView = null;

    var lastRecord = null;

// }}}

// {{{ private methods

    /**
     * Returns the first left outermost columnIndex of the first column
     * that is not hidden in the grid.
     * This method is guaranteed to return a value in the range of [0, columnIndex].
     *
     * @param {Ext.grid.GridPanel} grid
     * @param {Numbe} columnIndex
     *
     * @return {Number}
     */
    var _getColumnIndex = function(grid, columnIndex)
    {
        var colModel = grid.getColumnModel();
        i = 0;
        while (i < columnIndex) {
            if (!colModel.isHidden(i)) {
                return i;
            }
            i++;
        }

        return i;
    };

    /**
     * Callback.
     * Called when the preview panel's show-animation is finished.
     */
    var onShow = function()
    {
        emailView.show();
        var viewHeight  = Ext.fly(document.body).getHeight();
        var panelHeight = previewPanel.el.getHeight();

        if (clkCellY + panelHeight > viewHeight) {
            container.shift({
                y : container.getY() - (((clkCellY + panelHeight) - viewHeight) + 4)
            });
        }
    };

    var onBeforeLoad = function()
    {
        loadMask.show();
        emailView.hide();
    };

    var onLoadFailure = function(response, options)
    {
        com.conjoon.groupware.ResponseInspector.handleFailure(response, {
            onLogin: {
                fn : function(){
                    decoratePreviewPanel();
                }
            }
        });
        previewPanel.close();
        loadMask.hide();
    };

    var onLoadSuccess = function()
    {
        lastRecord = emailView.emailRecord;

        loadMask.hide();
        previewPanel.setTitle(lastRecord.get('subject'));
    };

    /**
     * Inits any component that is needed for displaying/animating
     * the preview panel.
     * This method will only be called once.
     */
    var initComponents = function()
    {
        container = Ext.DomHelper.append(document.body, {
            id    : 'DOM:com.conjoon.groupware.email.EmailPreview.container',
            style : "position:absolute;overflow:hidden;height:"+(height+5)+"px;width:"+width+"px"
        }, true);
    };

    /**
     * Callback.
     * Called when the preview panel's hide-animation is finished.
     */
    var onHide = function(skipAlign)
    {
        emailView.abortRequest();

        previewPanel.setTitle(com.conjoon.Gettext.gettext("Loading..."));

        if (skipAlign === true) {
            return;
        }

        refreshAnimSettings();
    };

    /**
     * Loads the feed's data into the preview panel.
     */
    var decoratePreviewPanel = function()
    {
        if (clkRecord == null) {
            return;
        }

        var subject = clkRecord.get('subject');
        var rec = com.conjoon.groupware.email.EmailViewBaton.getRecord(clkRecord.id);
        if (rec) {
            lastRecord = rec;
            emailView.emailRecord = rec;
            emailView.renderView();
        } else {
            emailView.setEmailItem(clkRecord)
        }

        previewPanel.setTitle(subject);
    }

    /**
     * Callback.
     * Called after the panel was detached from the grid and dropped anywhere
     * on the document body.
     * Sets <tt>previewPanel</tt> to <tt>null</tt> to notify the <tt>show</tt> method
     * to create a new preview panel.
     *
     */
    var onMove = function()
    {
        if (lastRecord == null) {
            previewPanel.close();
            return;
        }
        var emailItem = lastRecord.copy();
        previewPanel.close();
        var view = com.conjoon.groupware.email.EmailViewBaton.showEmail(emailItem, {
            autoLoad : false
        }, true);

    };

    /**
     * Creates a window for displaying feed contents.
     *
     * @return {Ext.Window} The window used for previewing.
     */
    var createPreviewWindow = function()
    {
        var templateConfig = {
            header : new Ext.Template(
                '
',
                   '
',
                    '{date:date("d.m.Y H:i")}',
                    '{subject}',
                    '
',
                    '{from}',
                    '{replyTo}',
                    '{to}',
                    '{cc}',
                    '{bcc}',
                    '
',
                   '
',
                '
'
        )};

        emailView = new com.conjoon.groupware.email.EmailViewPanel({
            autoLoad     : false,
            refreshFrame : true,
            border       :  false,
            hideMode     : 'visibility',
            viewConfig   : {
                templates        : templateConfig,
                fromValue        : com.conjoon.Gettext.gettext("From"),
                toValue          : com.conjoon.Gettext.gettext("To"),
                ccValue          : com.conjoon.Gettext.gettext("CC"),
                bccValue         : com.conjoon.Gettext.gettext("BCC")
            }
        });

        var win =  new Ext.Window({
            bodyStyle  : 'background:white;',
            autoScroll : false,
            layout     : 'fit',
            title      : ("Loading..."),
            iconCls    : 'com-conjoon-groupware-email-EmailPreview-Icon',
            resizable  : false,
            shadow     : false,
            hideMode   : 'visibility',
            items      : [emailView],
            height     : height,
            width      : width
        });

        win.mon(emailView, 'emailload',        onLoadSuccess, com.conjoon.groupware.email.EmailPreview);
        win.mon(emailView, 'beforeemailload',  onBeforeLoad, com.conjoon.groupware.email.EmailPreview);
        win.mon(emailView, 'emailloadfailure', onLoadFailure, com.conjoon.groupware.email.EmailPreview);

        win.on('render', function() {
            this.mon(this.header, 'dblclick', function(){
               onMove();
            }, this);
        }, win, {single : true});

        win.initDraggable = function() {
            Ext.Window.prototype.initDraggable.call(this);

            this.dd.b4Drag = function(e) {
                container.dom.style.overflow = "visible";
            };

            this.dd.endDrag = function(e){
                this.win.unghost(true, false);
                this.win.setPosition(0, 0);
                this.win.saveState();
                container.dom.style.overflow = "hidden";
            };
        }

        return win;
    };

    var animConfig = 'r';

    var refreshAnimSettings = function()
    {
        var x = gridEl.getX();

        // this should work in most cases - determine if the panel is rendered
        // in the left side of the workbench
        if (x <= 50) {
            x += gridEl.getSize().width;
            animConfig = 'l';
        } else {
            x -= container.getSize().width;
            animConfig = 'r';
        }

        container.setY(clkCellY);
        container.setX(x);
    };

// }}}

    return {

        getLastRecord : function()
        {
            return lastRecord;
        },

        getActiveRecord : function()
        {
            return clkRecord;
        },

        /**
         * Shows the preview panel using a slide-in animation effect.
         * The preview will not been shown if ctrl or shift was pressed while
         * calling this method.
         *
         * @param {Ext.grid.GridPanel} The grid panel that calls this method.
         * @param {Number} The row index of the cell the panel is aligned to.
         * @param {Number} The column index of the cell the panel is aligned to.
         * @param {Ext.EventObject} The raw event object that triggered this method.
         */
        show : function(grid, record)
        {
            if (!record) {
                return;
            }
            clkRecord = record.copy();

            var rowIndex = grid.getStore().indexOf(record);

            var pId = clkRecord.id;
            if (activeEmailId == pId) {
                // previewing is already active for this record.
                return;
            }

            // lazy create needed components
            if (container == null) {
                initComponents.call(this);
            }

            clkRowIndex  = rowIndex;
            clkCell      = grid.view.getRow(rowIndex);
            clkCellY     = Ext.fly(clkCell).getY();
            gridEl       = grid.el;

            if (previewPanel !== null) {
                // preview panel can be reused for previewing another feed.
                // abort all pending operations
                previewPanel.el.stopFx();

                if (activeEmailId != null) {
                    // if the activeEmailId does not equal to zero, the
                    // previewPanel was hidden using the animation effect.
                    previewPanel.el.slideOut(animConfig, {
                                        duration : .4,
                                        useDisplay: false,
                                        callback : function(){
                                            onHide();
                                            decoratePreviewPanel();
                                            emailView.hide();
                                        },
                                        scope:this
                                   })
                                   .slideIn(animConfig, {callback : onShow, duration : .4, useDisplay: false});

                } else {
                    // the preview panel was hidden using the hide method
                    // reshow and slide in.
                    container.setDisplayed(true);
                    refreshAnimSettings();
                    decoratePreviewPanel();
                    previewPanel.el.slideIn(animConfig, {callback : onShow, duration : .4, useDisplay: false});
                }
            } else {
                refreshAnimSettings();
                previewPanel = createPreviewWindow();
                previewPanel.render(container);
                loadMask = new Ext.LoadMask(previewPanel.el.dom);
                previewPanel.show();
                decoratePreviewPanel();
                previewPanel.el.slideIn(animConfig, {callback : onShow, duration : .4, useDisplay: false});
                previewPanel.on('beforeclose', this.hide, this, [true, true]);
                previewPanel.on('move', onMove);
            }

            activeEmailId = pId;
        },

        isPreviewShownForRecord : function(record)
        {
            return record
                ? record.id === activeEmailId
                : false;
        },

        getCurrentlyShownRecordId : function()
        {
            return activeEmailId;
        },

        /**
         * Hides the preview panel.
         * Returns <tt>false</tt> to prevents bubbling the <tt>close</tt> event
         * to the Ext.Window based on the passed argument <tt>preventBubbling</tt>.
         *
         * @param {boolean} <tt>true</tt> to skip animation, <tt>false</tt>
         *                  to show.
         *
         * @todo update every call since second paramter is now deprecated!
         */
        hide : function(skipAnimation)
        {
            if (previewPanel == null || activeEmailId == null) {
                return;
            }
            if (!skipAnimation) {
                previewPanel.el.slideOut(animConfig, {
                    useDisplay : false,
                    duration   : .4,
                    callback   : function(){
                        emailView.hide();
                        onHide();
                        container.setDisplayed(false);
                    }
                });
            } else {
                container.setDisplayed(false);
                previewPanel.el.slideOut(animConfig, {callback : function(){emailView.hide();}, useDisplay : false, duration : .1});
                onHide(true);
            }

            lastRecord   = null;
            activeEmailId = null;

            return false;
        }

    };

}();<commit_msg>[Email module - client] - enhancement: minor doc comment updates<commit_after>/**
 * conjoon
 * (c) 2002-2012 siteartwork.de/conjoon.org
 * licensing@conjoon.org
 *
 * $Author$
 * $Id$
 * $Date$
 * $Revision$
 * $LastChangedDate$
 * $LastChangedBy$
 * $URL$
 */

Ext.namespace('com.conjoon.groupware.email');

/**
 * Controller for previewing Feed contents.
 * This is a singleton-object and used bycom.conjoon.groupware.feeds.FeedGrid
 * to enable previewing a feed in a panel sliding out left of the grid panel,
 * aligned to the current selected cell. The panel is closable and draggable.
 * Once a panel was created, it can not be closed such that the object gets
 * destroyed.
 *
 * The preview panel depends on record properties passed from the grid to the
 * showPreview-method. The needed properties are
 *
 *

 *
id - the id of the feed to preview

 *
title - the title of the feed

 *
link - the link of the feed  of the feed to preview

 *
pubDate - the publication date of the feed

 *

 *
 * @author Thorsten Suckow-Homberg <tsuckow@conjoon.org>
 */
com.conjoon.groupware.email.EmailPreview = function() {

// {{{ private members

    /**
     * @type {Ext.Element} gridEl The element of the grid the preview is attached to
     */
    var gridEl = null;

    /**
     * Initial width of the preview panel.
     * @param {Number}
     */
    var width = 330;

    /**
     * Initial height of the preview panel.
     * @param {Number}
     */
    var height = 250;

    /**
     * The y position of the last clicked cell.
     * @param {Number} clkCellY
     */
    var clkCellY = 0;

    /**
     * Stores the id of the last previewed feed. If a preview panel gets closed,
     * the property will be reset to <tt>null</tt>.
     */
    var activeEmailId = null;

    /**
     * The html container that is responsible for enabling animation effects
     * of the preview panel.
     */
    var container = null;

    /**
     * The panel that is used for previewing a feed content. The property will
     * hold an instance of <tt>Ext.Panel</tt> which is being reused for previewing
     * until the panel was detached from the grid.
     */
    var previewPanel = null;

    /**
     * Stores the active cell to which the preview panel is aligned.
     */
    var clkCell = null;

    /**
     * Stores the row index of the cell to which the preview panel is aligned.
     */
    var clkRowIndex = -1;

    /**
     * Stores the record information of the cell's row associated with previewing.
     * The record needs to have a id-property that holds a unique id of the
     * grid's record that was selected.
     */
    var clkRecord = null;

    var loadMask = null;

    var emailView = null;

    var lastRecord = null;

// }}}

// {{{ private methods

    /**
     * Returns the first left outermost columnIndex of the first column
     * that is not hidden in the grid.
     * This method is guaranteed to return a value in the range of [0, columnIndex].
     *
     * @param {Ext.grid.GridPanel} grid
     * @param {Numbe} columnIndex
     *
     * @return {Number}
     */
    var _getColumnIndex = function(grid, columnIndex)
    {
        var colModel = grid.getColumnModel();
        i = 0;
        while (i < columnIndex) {
            if (!colModel.isHidden(i)) {
                return i;
            }
            i++;
        }

        return i;
    };

    /**
     * Callback.
     * Called when the preview panel's show-animation is finished.
     */
    var onShow = function()
    {
        emailView.show();
        var viewHeight  = Ext.fly(document.body).getHeight();
        var panelHeight = previewPanel.el.getHeight();

        if (clkCellY + panelHeight > viewHeight) {
            container.shift({
                y : container.getY() - (((clkCellY + panelHeight) - viewHeight) + 4)
            });
        }
    };

    var onBeforeLoad = function()
    {
        loadMask.show();
        emailView.hide();
    };

    var onLoadFailure = function(response, options)
    {
        com.conjoon.groupware.ResponseInspector.handleFailure(response, {
            onLogin: {
                fn : function(){
                    decoratePreviewPanel();
                }
            }
        });
        previewPanel.close();
        loadMask.hide();
    };

    var onLoadSuccess = function()
    {
        lastRecord = emailView.emailRecord;

        loadMask.hide();
        previewPanel.setTitle(lastRecord.get('subject'));
    };

    /**
     * Inits any component that is needed for displaying/animating
     * the preview panel.
     * This method will only be called once.
     */
    var initComponents = function()
    {
        container = Ext.DomHelper.append(document.body, {
            id    : 'DOM:com.conjoon.groupware.email.EmailPreview.container',
            style : "position:absolute;overflow:hidden;height:"+(height+5)+"px;width:"+width+"px"
        }, true);
    };

    /**
     * Callback.
     * Called when the preview panel's hide-animation is finished.
     */
    var onHide = function(skipAlign)
    {
        emailView.abortRequest();

        previewPanel.setTitle(com.conjoon.Gettext.gettext("Loading..."));

        if (skipAlign === true) {
            return;
        }

        refreshAnimSettings();
    };

    /**
     * Loads the feed's data into the preview panel.
     */
    var decoratePreviewPanel = function()
    {
        if (clkRecord == null) {
            return;
        }

        var subject = clkRecord.get('subject');
        var rec = com.conjoon.groupware.email.EmailViewBaton.getRecord(clkRecord.id);
        if (rec) {
            lastRecord = rec;
            emailView.emailRecord = rec;
            emailView.renderView();
        } else {
            emailView.setEmailItem(clkRecord)
        }

        previewPanel.setTitle(subject);
    }

    /**
     * Callback.
     * Called after the panel was detached from the grid and dropped anywhere
     * on the document body.
     * Sets <tt>previewPanel</tt> to <tt>null</tt> to notify the <tt>show</tt> method
     * to create a new preview panel.
     *
     */
    var onMove = function()
    {
        if (lastRecord == null) {
            previewPanel.close();
            return;
        }
        var emailItem = lastRecord.copy();
        previewPanel.close();
        var view = com.conjoon.groupware.email.EmailViewBaton.showEmail(emailItem, {
            autoLoad : false
        }, true);

    };

    /**
     * Creates a window for displaying email contents.
     *
     * @return {Ext.Window} The window used for previewing.
     */
    var createPreviewWindow = function()
    {
        var templateConfig = {
            header : new Ext.Template(
                '
',
                   '
',
                    '{date:date("d.m.Y H:i")}',
                    '{subject}',
                    '
',
                    '{from}',
                    '{replyTo}',
                    '{to}',
                    '{cc}',
                    '{bcc}',
                    '
',
                   '
',
                '
'
        )};

        emailView = new com.conjoon.groupware.email.EmailViewPanel({
            autoLoad     : false,
            refreshFrame : true,
            border       :  false,
            hideMode     : 'visibility',
            viewConfig   : {
                templates        : templateConfig,
                fromValue        : com.conjoon.Gettext.gettext("From"),
                toValue          : com.conjoon.Gettext.gettext("To"),
                ccValue          : com.conjoon.Gettext.gettext("CC"),
                bccValue         : com.conjoon.Gettext.gettext("BCC")
            }
        });

        var win =  new Ext.Window({
            bodyStyle  : 'background:white;',
            autoScroll : false,
            layout     : 'fit',
            title      : ("Loading..."),
            iconCls    : 'com-conjoon-groupware-email-EmailPreview-Icon',
            resizable  : false,
            shadow     : false,
            hideMode   : 'visibility',
            items      : [emailView],
            height     : height,
            width      : width
        });

        win.mon(emailView, 'emailload',        onLoadSuccess, com.conjoon.groupware.email.EmailPreview);
        win.mon(emailView, 'beforeemailload',  onBeforeLoad, com.conjoon.groupware.email.EmailPreview);
        win.mon(emailView, 'emailloadfailure', onLoadFailure, com.conjoon.groupware.email.EmailPreview);

        win.on('render', function() {
            this.mon(this.header, 'dblclick', function(){
               onMove();
            }, this);
        }, win, {single : true});

        win.initDraggable = function() {
            Ext.Window.prototype.initDraggable.call(this);

            this.dd.b4Drag = function(e) {
                container.dom.style.overflow = "visible";
            };

            this.dd.endDrag = function(e){
                this.win.unghost(true, false);
                this.win.setPosition(0, 0);
                this.win.saveState();
                container.dom.style.overflow = "hidden";
            };
        }

        return win;
    };

    var animConfig = 'r';

    var refreshAnimSettings = function()
    {
        var x = gridEl.getX();

        // this should work in most cases - determine if the panel is rendered
        // in the left side of the workbench
        if (x <= 50) {
            x += gridEl.getSize().width;
            animConfig = 'l';
        } else {
            x -= container.getSize().width;
            animConfig = 'r';
        }

        container.setY(clkCellY);
        container.setX(x);
    };

// }}}

    return {

        getLastRecord : function()
        {
            return lastRecord;
        },

        getActiveRecord : function()
        {
            return clkRecord;
        },

        /**
         * Shows the preview panel using a slide-in animation effect.
         * The preview will not been shown if ctrl or shift was pressed while
         * calling this method.
         *
         * @param {Ext.grid.GridPanel} The grid panel that calls this method.
         * @param {Number} The row index of the cell the panel is aligned to.
         * @param {Number} The column index of the cell the panel is aligned to.
         * @param {Ext.EventObject} The raw event object that triggered this method.
         */
        show : function(grid, record)
        {
            if (!record) {
                return;
            }
            clkRecord = record.copy();

            var rowIndex = grid.getStore().indexOf(record);

            var pId = clkRecord.id;
            if (activeEmailId == pId) {
                // previewing is already active for this record.
                return;
            }

            // lazy create needed components
            if (container == null) {
                initComponents.call(this);
            }

            clkRowIndex  = rowIndex;
            clkCell      = grid.view.getRow(rowIndex);
            clkCellY     = Ext.fly(clkCell).getY();
            gridEl       = grid.el;

            if (previewPanel !== null) {
                // preview panel can be reused for previewing another feed.
                // abort all pending operations
                previewPanel.el.stopFx();

                if (activeEmailId != null) {
                    // if the activeEmailId does not equal to zero, the
                    // previewPanel was hidden using the animation effect.
                    previewPanel.el.slideOut(animConfig, {
                                        duration : .4,
                                        useDisplay: false,
                                        callback : function(){
                                            onHide();
                                            decoratePreviewPanel();
                                            emailView.hide();
                                        },
                                        scope:this
                                   })
                                   .slideIn(animConfig, {callback : onShow, duration : .4, useDisplay: false});

                } else {
                    // the preview panel was hidden using the hide method
                    // reshow and slide in.
                    container.setDisplayed(true);
                    refreshAnimSettings();
                    decoratePreviewPanel();
                    previewPanel.el.slideIn(animConfig, {callback : onShow, duration : .4, useDisplay: false});
                }
            } else {
                refreshAnimSettings();
                previewPanel = createPreviewWindow();
                previewPanel.render(container);
                loadMask = new Ext.LoadMask(previewPanel.el.dom);
                previewPanel.show();
                decoratePreviewPanel();
                previewPanel.el.slideIn(animConfig, {callback : onShow, duration : .4, useDisplay: false});
                previewPanel.on('beforeclose', this.hide, this, [true, true]);
                previewPanel.on('move', onMove);
            }

            activeEmailId = pId;
        },

        isPreviewShownForRecord : function(record)
        {
            return record
                ? record.id === activeEmailId
                : false;
        },

        getCurrentlyShownRecordId : function()
        {
            return activeEmailId;
        },

        /**
         * Hides the preview panel.
         * Returns <tt>false</tt> to prevents bubbling the <tt>close</tt> event
         * to the Ext.Window based on the passed argument <tt>preventBubbling</tt>.
         *
         * @param {boolean} <tt>true</tt> to skip animation, <tt>false</tt>
         *                  to show.
         *
         * @todo update every call since second paramter is now deprecated!
         */
        hide : function(skipAnimation)
        {
            if (previewPanel == null || activeEmailId == null) {
                return;
            }
            if (!skipAnimation) {
                previewPanel.el.slideOut(animConfig, {
                    useDisplay : false,
                    duration   : .4,
                    callback   : function(){
                        emailView.hide();
                        onHide();
                        container.setDisplayed(false);
                    }
                });
            } else {
                container.setDisplayed(false);
                previewPanel.el.slideOut(animConfig, {callback : function(){emailView.hide();}, useDisplay : false, duration : .1});
                onHide(true);
            }

            lastRecord   = null;
            activeEmailId = null;

            return false;
        }

    };

}();
<|endoftext|>


<commit_before>var grunt = require('grunt');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['jsmin-sourcemap'] = {
  setUp: function (done) {
    // setup here
    done();
  },
  'jsmin-sourcemap': function (test) {
    test.expect(9);

      var expectedCompact = grunt.file.read('expected/compact.min.js'),
          actualCompact = grunt.file.read('actual/compact.min.js'),
          actualCompactMap = grunt.file.read('actual/compact.min.js.map'),
          compactMapRegExp = /\/\/\s*@\s*sourceMappingURL\s*=\s*actual\/compact.min.js.map/,
          compactMapDeclarativeExists = compactMapRegExp.test(actualCompact);
        // outputs proper minified code
        test.strictEqual(actualCompact, expectedCompact, ' properly minifies a compact file');
        // which points to the map file
        test.ok(compactMapDeclarativeExists, ' points to the proper map location for the compact file');
        // as well as a sourcemap
        test.ok(actualCompactMap, ' generates a source map for a compact file');

      var expectedSingle = grunt.file.read('expected/jquery.min.js'),
          actualSingle = grunt.file.read('actual/jquery.min.js'),
          actualSingleMap = grunt.file.read('actual/jquery.js.map'),
          singleMapRegExp = /\/\/\s*@\s*sourceMappingURL\s*=\s*actual\/jquery.js.map/,
          singleMapDeclarativeExists = singleMapRegExp.test(actualSingle);
        // outputs proper minified code
        test.strictEqual(actualSingle, expectedSingle, ' properly minifies a single file');
        // which points to the map file
        test.ok(singleMapDeclarativeExists, ' points to the proper map location for the single file');
        // as well as a sourcemap
        test.ok(actualSingleMap, ' generates a source map for a single file');

    // Multiple files (jquery.js + underscore.js)
      // processed via JSMin (grunt jsmin-sourcemap:multi)
      var expectedMulti = grunt.file.read('expected/multi.min.js'),
          actualMulti = grunt.file.read('actual/multi.min.js'),
          actualMultiMap = grunt.file.read('actual/multi.js.map'),
          multiMapRegExp = /\/\/\s*@\s*sourceMappingURL\s*=\s*actual\/multi.js.map/,
          multiMapDeclarativeExists = multiMapRegExp.test(actualMulti);
        // outputs proper minified code
        test.strictEqual(actualMulti, expectedMulti, ' properly minifies multiple files');
        // which points to the map file
        test.ok(multiMapDeclarativeExists, ' points to the proper map location for the multiple files');
        // as well as a sourcemap
        test.ok(actualMultiMap, ' generates a source map for multiple files');

    test.done();
  }
};
<commit_msg>Fixed test to point to relative comments -- failing now<commit_after>var grunt = require('grunt');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['jsmin-sourcemap'] = {
  setUp: function (done) {
    // setup here
    done();
  },
  'jsmin-sourcemap': function (test) {
    test.expect(9);

      var expectedCompact = grunt.file.read('expected/compact.min.js'),
          actualCompact = grunt.file.read('actual/compact.min.js'),
          actualCompactMap = grunt.file.read('actual/compact.min.js.map'),
          compactMapComment = '//@ sourceMappingURL=compact.min.js.map',
          compactMapDeclarativeExists = actualCompact.indexOf(compactMapComment) > -1;
        // outputs proper minified code
        test.strictEqual(actualCompact, expectedCompact, ' properly minifies a compact file');
        // which points to the map file
        test.ok(compactMapDeclarativeExists, ' points to the proper map location for the compact file');
        // as well as a sourcemap
        test.ok(actualCompactMap, ' generates a source map for a compact file');

      var expectedSingle = grunt.file.read('expected/jquery.min.js'),
          actualSingle = grunt.file.read('actual/jquery.min.js'),
          actualSingleMap = grunt.file.read('actual/jquery.js.map'),
          singleMapComment = '//@ sourceMappingURL=jquery.js.map',
          singleMapDeclarativeExists = actualSingle.indexOf(singleMapComment) > -1;
        // outputs proper minified code
        test.strictEqual(actualSingle, expectedSingle, ' properly minifies a single file');
        // which points to the map file
        test.ok(singleMapDeclarativeExists, ' points to the proper map location for the single file');
        // as well as a sourcemap
        test.ok(actualSingleMap, ' generates a source map for a single file');

    // Multiple files (jquery.js + underscore.js)
      // processed via JSMin (grunt jsmin-sourcemap:multi)
      var expectedMulti = grunt.file.read('expected/multi.min.js'),
          actualMulti = grunt.file.read('actual/multi.min.js'),
          actualMultiMap = grunt.file.read('actual/multi.js.map'),
          multiMapComment = '//@ sourceMappingURL=multi.js.map',
          multiMapDeclarativeExists = actualMulti.indexOf(multiMapComment) > -1;
        // outputs proper minified code
        test.strictEqual(actualMulti, expectedMulti, ' properly minifies multiple files');
        // which points to the map file
        test.ok(multiMapDeclarativeExists, ' points to the proper map location for the multiple files');
        // as well as a sourcemap
        test.ok(actualMultiMap, ' generates a source map for multiple files');

    test.done();
  }
};
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var mongoose = require('mongoose')
var Article = mongoose.model('Article')
var utils = require('../../lib/utils')
var extend = require('util')._extend

/**
 * Load
 */

exports.load = function (req, res, next, id){
  var User = mongoose.model('User');

  Article.load(id, function (err, article) {
    if (err) return next(err);
    if (!article) return next(new Error('not found'));
    req.article = article;
    next();
  });
};

/**
 * List
 */

exports.index = function (req, res){
  var page = (req.param('page') > 0 ? req.param('page') : 1) - 1;
  var perPage = 30;
  var options = {
    perPage: perPage,
    page: page
  };

  Article.list(options, function (err, articles) {
    if (err) return res.render('500');
    Article.count().exec(function (err, count) {
      res.render('articles/index', {
        title: 'Articles',
        articles: articles,
        page: page + 1,
        pages: Math.ceil(count / perPage)
      });
    });
  });
};

/**
 * New article
 */

exports.new = function (req, res){
  res.render('articles/new', {
    title: 'New Article',
    article: new Article({})
  });
};

/**
 * Create an article
 * Upload an image
 */

exports.create = function (req, res) {
  var article = new Article(req.body);
  var images = req.files.image
    ? [req.files.image]
    : undefined;

  article.user = req.user;
  article.uploadAndSave(images, function (err) {
    if (!err) {
      req.flash('success', 'Successfully created article!');
      return res.redirect('/articles/'+article._id);
    }
    console.log(err);
    res.render('articles/new', {
      title: 'New Article',
      article: article,
      error: utils.errors(err.errors || err)
    });
  });
};

/**
 * Edit an article
 */

exports.edit = function (req, res) {
  res.render('articles/edit', {
    title: 'Edit ' + req.article.title,
    article: req.article
  });
};

/**
 * Update article
 */

exports.update = function (req, res){
  var article = req.article;
  var images = req.files.image
    ? [req.files.image]
    : undefined;

  // make sure no one changes the user
  delete req.body.user;
  article = extend(article, req.body);

  article.uploadAndSave(images, function (err) {
    if (!err) {
      return res.redirect('/articles/' + article._id);
    }

    res.render('articles/edit', {
      title: 'Edit Article',
      article: article,
      error: utils.errors(err.errors || err)
    });
  });
};

/**
 * Show
 */

exports.show = function (req, res){
  res.render('articles/show', {
    title: req.article.title,
    article: req.article
  });
};

/**
 * Delete an article
 */

exports.destroy = function (req, res){
  var article = req.article;
  article.remove(function (err){
    req.flash('info', 'Deleted successfully');
    res.redirect('/articles');
  });
};
<commit_msg>fix appearing of errors when article is not saved<commit_after>
/**
 * Module dependencies.
 */

var mongoose = require('mongoose')
var Article = mongoose.model('Article')
var utils = require('../../lib/utils')
var extend = require('util')._extend

/**
 * Load
 */

exports.load = function (req, res, next, id){
  var User = mongoose.model('User');

  Article.load(id, function (err, article) {
    if (err) return next(err);
    if (!article) return next(new Error('not found'));
    req.article = article;
    next();
  });
};

/**
 * List
 */

exports.index = function (req, res){
  var page = (req.param('page') > 0 ? req.param('page') : 1) - 1;
  var perPage = 30;
  var options = {
    perPage: perPage,
    page: page
  };

  Article.list(options, function (err, articles) {
    if (err) return res.render('500');
    Article.count().exec(function (err, count) {
      res.render('articles/index', {
        title: 'Articles',
        articles: articles,
        page: page + 1,
        pages: Math.ceil(count / perPage)
      });
    });
  });
};

/**
 * New article
 */

exports.new = function (req, res){
  res.render('articles/new', {
    title: 'New Article',
    article: new Article({})
  });
};

/**
 * Create an article
 * Upload an image
 */

exports.create = function (req, res) {
  var article = new Article(req.body);
  var images = req.files.image
    ? [req.files.image]
    : undefined;

  article.user = req.user;
  article.uploadAndSave(images, function (err) {
    if (!err) {
      req.flash('success', 'Successfully created article!');
      return res.redirect('/articles/'+article._id);
    }
    console.log(err);
    res.render('articles/new', {
      title: 'New Article',
      article: article,
      errors: utils.errors(err.errors || err)
    });
  });
};

/**
 * Edit an article
 */

exports.edit = function (req, res) {
  res.render('articles/edit', {
    title: 'Edit ' + req.article.title,
    article: req.article
  });
};

/**
 * Update article
 */

exports.update = function (req, res){
  var article = req.article;
  var images = req.files.image
    ? [req.files.image]
    : undefined;

  // make sure no one changes the user
  delete req.body.user;
  article = extend(article, req.body);

  article.uploadAndSave(images, function (err) {
    if (!err) {
      return res.redirect('/articles/' + article._id);
    }

    res.render('articles/edit', {
      title: 'Edit Article',
      article: article,
      errors: utils.errors(err.errors || err)
    });
  });
};

/**
 * Show
 */

exports.show = function (req, res){
  res.render('articles/show', {
    title: req.article.title,
    article: req.article
  });
};

/**
 * Delete an article
 */

exports.destroy = function (req, res){
  var article = req.article;
  article.remove(function (err){
    req.flash('info', 'Deleted successfully');
    res.redirect('/articles');
  });
};
<|endoftext|>


<commit_before>$(function() {

$('#song_content').on('mouseover', '.chord', function() {
    $(this).children('img').css('visibility', 'visible');
});

$('#song_content').on('mouseout', '.chord', function() {
    $(this).children('img').css('visibility', 'hidden');
});

$('#hide_chords').click(function() {
    $('.chordline').toggle();
    $('#hide_chords').text(
        $('#hide_chords').text() == 'Hide chords' ? 'Show chords' : 'Hide chords');
});

$('#hide_tabs').click(function() {
    $('.tabsline').toggle();
    $('#hide_tabs').text(
        $('#hide_tabs').text() == 'Hide tabs' ? 'Show tabs' : 'Hide tabs');
});

$('#semiton_change').change(function() {
    var semitonsMove = parseInt($(this).find(':selected').text(), 10);
    $('.chord').each(function() {
        var newSemiton = changeSemiton($(this).attr('origchord'), semitonsMove);
        $(this).children('.chordname').text(newSemiton);
        $(this).children('img').attr(
            'src', '/static/chords/img/chords/' +
            encodeURIComponent(alterFlatChords(newSemiton)) + '.png');
    });
});

/**
 * Perform an AJAX request to bookmark or unbookmark a song.
 */
$('#bookmark').click(function(event) {
    event.preventDefault();
    var url = $(this).attr('href');
    if ($(this).text().indexOf('Add') != -1)
        $.get(url + 'add_bookmark/', function(data) {
            $('#bookmark').text('(-) Remove from bookmarks')
        })
    else
        $.get(url + 'remove_bookmark/', function(data) {
            $('#bookmark').text('(+) Add to bookmarks')
        })
});

/**
 * If chord is a flat chord, return its non-flat equivalent.
 * Else, return the chord unchanged.
 *
 * eg. "Ab" -> "G#", "Cb" -> "B", "G" -> "G"
 *
 * @param chord {String} string representing a chord, eg. "Ab"
 */
function alterFlatChords(chord) {
    var regex = /([A-G]b)(.*)/;
    var match = regex.exec(chord);
    if (!match)
        return chord;

    var chordBase = match[1];
    var restChord = match[2];

    var map = {'Ab' : 'G#', 'Bb' : 'A#', 'Cb' : 'B', 'Db' : 'C#', 'Eb' : 'F#',
               'Fb' : 'E', 'Gb' : 'F#'};
    var chordBase = map[chordBase];

    return chordBase + restChord;
}

/**
 * Return the given chord, changed by semitonsMove semitons.
 *
 * @param chord {String} string representing a chord, eg. "A#5"
 * @param semitonsMove {Number} integer from -5 to 6
 * @return {String} the changed chord
 */
function changeSemiton(chord, semitonsMove) {
    if (semitonsMove === 0)
        return chord;

    var regex = /([A-G][#b]?)((maj|m|aug|dim|sus)?([245679]|11|13)?)/;
    var match = regex.exec(alterFlatChords(chord));
    var origSemiton = match[1];
    var restChord = match[2];

    var semitons = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
    var index = semitons.indexOf(origSemiton) + semitonsMove;

    if (index >= semitons.length)
        index = index % semitons.length;
    else if (index < 0)
        index = semitons.length + index;

    return semitons[index] + restChord;
}

/**
 * Replace html escaped  tags by real  tags.
 *
 * @param song {String} the whole song string
 * @return {String} parsed song
 */
function parseComments(song) {
    return song.replace(/<em>/g, '').replace(/<\/em>/g, '');
}

/**
 * Checks wether a song line contain tablatures.
 *
 * @param line {String} a song line
 * @return {Boolean}
 */
function isTabLine(line) {
    var regex = /^[A-Ga-g]:*\|{0,2}.*-.*-.*-/;
    if (regex.test(line))
            return true;
    return false;
}

/**
 * Encloses each line of the given song string containing tabs, in a div tag
 * of class "tabsline".
 *
 * @param song {String} the whole song string
 * @return {Array of Strings} the parsed lines
 */
function parseTabs(song) {
    var lines = song.split('\n');
    var newlines = [];

    for (i = 0; i < lines.length; i++) {
        if (isTabLine(lines[i]))
            lines[i] = '
' + lines[i] + '
';
        else
            lines[i] += '\n'
        newlines.push(lines[i]);
    }

    return newlines;
}

/**
 * In the given song, encloses each chord in a span tag of class "chord",
 * and assigns an appropriate image to it. Additionally, it encloses each line
 * containing chords in a div tag of class "chordline".
 *
 * eg. "Am" becomes ->
 *

 *
 *         Am
 *
 *
 *

 *
 * @param lines {Array of Strings} the initial song lines
 * @return {Array of Strings} the parsed lines
 */
function parseChords(lines) {
    var newlines = '';

    for (i = 0; i < lines.length; i++) {
        // Do not parse tab lines.
        if (lines[i].indexOf('
') != -1) {
            newlines += lines[i];
            continue;
        }

        // Enclose chords in span tags of class "chords".
        lines[i] = lines[i].replace(
            /\b([A-G][#b]?(maj|m|aug|dim|sus|add)?([245679]|11|13)?[#b]?([245679]|11|13)?)\b/g,
            function($0, $1) {
                return '' + $1 + '' +
                    ''
            }
        );

        // Enclose chords lines in div tags of class "chordline".
        if (lines[i].indexOf('<span class="chord"') != -1)
            newlines += '
' + lines[i] + '
';
        else
            newlines += lines[i];
    }

    return newlines;
}

function parseSong() {
    var song = $('#song_content');
    song.html(parseChords(parseTabs(parseComments(song.html()))));
}

/**
 * Fills the semiton_change select object, with the values from -5 to 6
 * followed by the base chord of the song at the specific semiton.
 *
 * eg. -1 (D), 0 (D#), +1 (E)
 */
function fillSemitonChange() {
    var songBase = $('.chord').first().attr('origchord');
    if (! songBase)
        return;
    for (i = 6; i >= -5; i--) {
        if (i != 0) {
            $('#semiton_change')
                .append($('<option></option>')
                .text((i>0 ? '+' : '') + i + ' (' + changeSemiton(songBase, i) + ')'));
        } else {
            $('#semiton_change')
                .append($('<option></option>')
                .attr('selected', 'selected')
                .text(i + ' (' + changeSemiton(songBase, i) + ')'));
        }
    }
}

if ($('#song_content').length)
    parseSong();
if ($('#semiton_change').length)
    fillSemitonChange();

});
<commit_msg>improve chords parsing<commit_after>$(function() {

$('#song_content').on('mouseover', '.chord', function() {
    $(this).children('img').css('visibility', 'visible');
});

$('#song_content').on('mouseout', '.chord', function() {
    $(this).children('img').css('visibility', 'hidden');
});

$('#hide_chords').click(function() {
    $('.chordline').toggle();
    $('#hide_chords').text(
        $('#hide_chords').text() == 'Hide chords' ? 'Show chords' : 'Hide chords');
});

$('#hide_tabs').click(function() {
    $('.tabsline').toggle();
    $('#hide_tabs').text(
        $('#hide_tabs').text() == 'Hide tabs' ? 'Show tabs' : 'Hide tabs');
});

$('#semiton_change').change(function() {
    var semitonsMove = parseInt($(this).find(':selected').text(), 10);
    $('.chord').each(function() {
        var newSemiton = changeSemiton($(this).attr('origchord'), semitonsMove);
        $(this).children('.chordname').text(newSemiton);
        $(this).children('img').attr(
            'src', '/static/chords/img/chords/' +
            encodeURIComponent(alterFlatChords(newSemiton)) + '.png');
    });
});

/**
 * Perform an AJAX request to bookmark or unbookmark a song.
 */
$('#bookmark').click(function(event) {
    event.preventDefault();
    var url = $(this).attr('href');
    if ($(this).text().indexOf('Add') != -1)
        $.get(url + 'add_bookmark/', function(data) {
            $('#bookmark').text('(-) Remove from bookmarks')
        })
    else
        $.get(url + 'remove_bookmark/', function(data) {
            $('#bookmark').text('(+) Add to bookmarks')
        })
});

/**
 * If chord is a flat chord, return its non-flat equivalent.
 * Else, return the chord unchanged.
 *
 * eg. "Ab" -> "G#", "Cb" -> "B", "G" -> "G"
 *
 * @param chord {String} string representing a chord, eg. "Ab"
 */
function alterFlatChords(chord) {
    var regex = /([A-G]b)(.*)/;
    var match = regex.exec(chord);
    if (!match)
        return chord;

    var chordBase = match[1];
    var restChord = match[2];

    var map = {'Ab' : 'G#', 'Bb' : 'A#', 'Cb' : 'B', 'Db' : 'C#', 'Eb' : 'F#',
               'Fb' : 'E', 'Gb' : 'F#'};
    var chordBase = map[chordBase];

    return chordBase + restChord;
}

/**
 * Return the given chord, changed by semitonsMove semitons.
 *
 * @param chord {String} string representing a chord, eg. "A#5"
 * @param semitonsMove {Number} integer from -5 to 6
 * @return {String} the changed chord
 */
function changeSemiton(chord, semitonsMove) {
    if (semitonsMove === 0)
        return chord;

    var regex = /([A-G][#b]?)((maj|m|aug|dim|sus)?([245679]|11|13)?)/;
    var match = regex.exec(alterFlatChords(chord));
    var origSemiton = match[1];
    var restChord = match[2];

    var semitons = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
    var index = semitons.indexOf(origSemiton) + semitonsMove;

    if (index >= semitons.length)
        index = index % semitons.length;
    else if (index < 0)
        index = semitons.length + index;

    return semitons[index] + restChord;
}

/**
 * Replace html escaped  tags by real  tags.
 *
 * @param song {String} the whole song string
 * @return {String} parsed song
 */
function parseComments(song) {
    return song.replace(/<em>/g, '').replace(/<\/em>/g, '');
}

/**
 * Checks wether a song line contain tablatures.
 *
 * @param line {String} a song line
 * @return {Boolean}
 */
function isTabLine(line) {
    var regex = /^[A-Ga-g]:*\|{0,2}.*-.*-.*-/;
    if (regex.test(line))
            return true;
    return false;
}

/**
 * Encloses each line of the given song string containing tabs, in a div tag
 * of class "tabsline".
 *
 * @param song {String} the whole song string
 * @return {Array of Strings} the parsed lines
 */
function parseTabs(song) {
    var lines = song.split('\n');
    var newlines = [];

    for (i = 0; i < lines.length; i++) {
        if (isTabLine(lines[i]))
            lines[i] = '
' + lines[i] + '
';
        else
            lines[i] += '\n'
        newlines.push(lines[i]);
    }

    return newlines;
}

/**
 * In the given song, encloses each chord in a span tag of class "chord",
 * and assigns an appropriate image to it. Additionally, it encloses each line
 * containing chords in a div tag of class "chordline".
 *
 * eg. "Am" becomes ->
 *

 *
 *         Am
 *
 *
 *

 *
 * @param lines {Array of Strings} the initial song lines
 * @return {Array of Strings} the parsed lines
 */
function parseChords(lines) {
    var newlines = '';

    for (i = 0; i < lines.length; i++) {
        // Do not parse tab lines.
        if (lines[i].indexOf('
') != -1) {
            newlines += lines[i];
            continue;
        }

        // Enclose chords in span tags of class "chords".
        lines[i] = lines[i].replace(
            /([A-G][#b]?(maj|m|aug|dim|sus|add)?([245679]|11|13)?[#b]?([245679]|11|13)?)/g,
            function($0, $1) {
                return '' + $1 + '' +
                    ''
            }
        );

        // Enclose chords lines in div tags of class "chordline".
        if (lines[i].indexOf('<span class="chord"') != -1) {
            var stripped = lines[i].replace(/<span class="chord".+<\/span>/g, '');
            var match = /[^\s\(\)\/\|x\d]/.exec(stripped)
            // Is it really a chord or does it simply look like one?
            if (!match)
                lines[i] = '
' + lines[i] + '
';
            else
                // Remove span tags from "false" chords.
                lines[i] = lines[i].replace(/.+?<img.+?<\/span>/g, '$1');
        }
        newlines += lines[i];
    }

    return newlines;
}

function parseSong() {
    var song = $('#song_content');
    song.html(parseChords(parseTabs(parseComments(song.html()))));
}

/**
 * Fills the semiton_change select object, with the values from -5 to 6
 * followed by the base chord of the song at the specific semiton.
 *
 * eg. -1 (D), 0 (D#), +1 (E)
 */
function fillSemitonChange() {
    var songBase = $('.chord').first().attr('origchord');
    if (! songBase)
        return;
    for (i = 6; i >= -5; i--) {
        if (i != 0) {
            $('#semiton_change')
                .append($('<option></option>')
                .text((i>0 ? '+' : '') + i + ' (' + changeSemiton(songBase, i) + ')'));
        } else {
            $('#semiton_change')
                .append($('<option></option>')
                .attr('selected', 'selected')
                .text(i + ' (' + changeSemiton(songBase, i) + ')'));
        }
    }
}

if ($('#song_content').length)
    parseSong();
if ($('#semiton_change').length)
    fillSemitonChange();

});
<|endoftext|>


<commit_before>/* eslint-disable */

import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { expect } from 'chai';
import { mount } from 'enzyme';
import MediaQueryProvider from '../src/media-query-provider';
import sinon from 'sinon';

describe('<MediaQueryProvider />', () => {
  let component;

  before(() => {
    // TODO see https://github.com/sinonjs/sinon/issues/1377
    Object.defineProperty(global, 'HTMLElement', {
      configurable: true,
      value: () => {},
    });
  });

  after(() => {
    Reflect.deleteProperty(global, 'HTMLElement');
  });

  it('should render app', () => {
    expect(() => {
      component = mount(
        <MediaQueryProvider>

Test123

        </MediaQueryProvider>,
      );
    }).to.not.throw();
  });

  it('should have a default queries prop', () => {
    expect(component.props().queries).to.be.an('object');
  });

  it('should have child context with default media', () => {
    expect(component.node.getChildContext().media).to.eql({
      desktop: false,
      largeDesktop: false,
      mobile: false,
      tablet: false,
    });
  });

  it('should have child context with other media', () => {
    const queries = {
      someMediaQuery: 'screen and (max-width: 1111px)',
      someMediaQuery2: 'screen and (min-width: 2222px) and (max-width: 33333px)',
      someMediaQuery3: 'screen and (min-width: 44444px) and (max-width: 55555px)',
      someMediaQuery4: 'screen and (min-width: 66666px)',
    };

    const otherComponent = mount(
      <MediaQueryProvider queries={queries}>

Test123

      </MediaQueryProvider>,
    );

    expect(otherComponent.node.getChildContext().media).to.eql({
      someMediaQuery: false,
      someMediaQuery2: false,
      someMediaQuery3: false,
      someMediaQuery4: false,
    });
  });

  context('when mobile matches', () => {
    let mobileComponent;

    before(() => {
      mobileComponent = mount(
        <MediaQueryProvider>

Test123

        </MediaQueryProvider>,
      );
    });

    it('should include mobile in the media context', () => {
      const { media } = mobileComponent.node.getChildContext();
      expect(media).to.eql({
        desktop: false,
        largeDesktop: false,
        mobile: false,
        tablet: false,
      });
    });
  });

  it('should render mobile when value specified from server', () => {

    const values = {
      width: 300,
      type: 'screen',
    };

    // dont want to do client mount
    const stub = sinon.stub(MediaQueryProvider.prototype, 'componentDidMount').returns('hi!');

    const componentWithValues = mount(
      <MediaQueryProvider values={values}>

Test123

      </MediaQueryProvider>,
    );

    expect(MediaQueryProvider.prototype.componentDidMount).to.have.property('callCount', 1);

    const { media } = componentWithValues.node.getChildContext();

    expect(media).to.eql({
      mobile: true,
      tablet: false,
      desktop: false,
      largeDesktop: false,
    });

    stub.restore();
  });

  context('when rendering server-side', () => {
    it('should render', () => {
      expect(() => {
        const html = ReactDOMServer.renderToString(
          <MediaQueryProvider>

Test123

          </MediaQueryProvider>,
        );
      }).to.not.throw();
    });
  });

  if (React.Fragment) {
    context('when React.Fragment is available', () => {
      it('should render a div', () => {
        const component = mount(
          <MediaQueryProvider>

Test123

          </MediaQueryProvider>,
        );
        expect(component.find('div').is('div')).to.eql(false);
        expect(component.find('p').is('p')).to.eql(true);
      });
    });
  } else {
    context('when React.Fragment is not available', () => {
      it('should render a div', () => {
        const component = mount(
          <MediaQueryProvider>

Test123

          </MediaQueryProvider>,
        );
        expect(component.find('div').is('div')).to.eql(true);
      });
    });
  }
});
<commit_msg>Updated tests per @willmendesneto's recommendation<commit_after>/* eslint-disable */

import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { expect } from 'chai';
import { mount } from 'enzyme';
import MediaQueryProvider from '../src/media-query-provider';
import sinon from 'sinon';

describe('<MediaQueryProvider />', () => {
  let component;

  before(() => {
    // TODO see https://github.com/sinonjs/sinon/issues/1377
    Object.defineProperty(global, 'HTMLElement', {
      configurable: true,
      value: () => {},
    });
  });

  after(() => {
    Reflect.deleteProperty(global, 'HTMLElement');
  });

  it('should render app', () => {
    expect(() => {
      component = mount(
        <MediaQueryProvider>

Test123

        </MediaQueryProvider>,
      );
    }).to.not.throw();
  });

  it('should have a default queries prop', () => {
    expect(component.props().queries).to.be.an('object');
  });

  it('should have child context with default media', () => {
    expect(component.node.getChildContext().media).to.eql({
      desktop: false,
      largeDesktop: false,
      mobile: false,
      tablet: false,
    });
  });

  it('should have child context with other media', () => {
    const queries = {
      someMediaQuery: 'screen and (max-width: 1111px)',
      someMediaQuery2: 'screen and (min-width: 2222px) and (max-width: 33333px)',
      someMediaQuery3: 'screen and (min-width: 44444px) and (max-width: 55555px)',
      someMediaQuery4: 'screen and (min-width: 66666px)',
    };

    const otherComponent = mount(
      <MediaQueryProvider queries={queries}>

Test123

      </MediaQueryProvider>,
    );

    expect(otherComponent.node.getChildContext().media).to.eql({
      someMediaQuery: false,
      someMediaQuery2: false,
      someMediaQuery3: false,
      someMediaQuery4: false,
    });
  });

  context('when mobile matches', () => {
    let mobileComponent;

    before(() => {
      mobileComponent = mount(
        <MediaQueryProvider>

Test123

        </MediaQueryProvider>,
      );
    });

    it('should include mobile in the media context', () => {
      const { media } = mobileComponent.node.getChildContext();
      expect(media).to.eql({
        desktop: false,
        largeDesktop: false,
        mobile: false,
        tablet: false,
      });
    });
  });

  it('should render mobile when value specified from server', () => {

    const values = {
      width: 300,
      type: 'screen',
    };

    // dont want to do client mount
    const stub = sinon.stub(MediaQueryProvider.prototype, 'componentDidMount').returns('hi!');

    const componentWithValues = mount(
      <MediaQueryProvider values={values}>

Test123

      </MediaQueryProvider>,
    );

    expect(MediaQueryProvider.prototype.componentDidMount).to.have.property('callCount', 1);

    const { media } = componentWithValues.node.getChildContext();

    expect(media).to.eql({
      mobile: true,
      tablet: false,
      desktop: false,
      largeDesktop: false,
    });

    stub.restore();
  });

  context('when rendering server-side', () => {
    it('should render', () => {
      expect(() => {
        const html = ReactDOMServer.renderToString(
          <MediaQueryProvider>

Test123

          </MediaQueryProvider>,
        );
      }).to.not.throw();
    });
  });

  context('when React.Fragment is available', () => {
    before(() => {
      Object.defineProperty(React, 'Fragment', {
        configurable: true,
        value: React.createClass({
          render: function() {
            return React.createElement(
              'span',
              {className: 'wrapper'},
              Array.isArray(this.props.children) ?
                this.props.children.map((el) => {el}) :
                this.props.children
            );
          }
        }),
      });
    });

    after(() => {
      Reflect.deleteProperty(React, 'Fragment');
    });

    it('should use React.Fragment component', () => {
      const fragmentChildren = [

Test123
,

Test123
,
      ];
      const component = mount(
        <MediaQueryProvider>
          <fragmentChildren />
        </MediaQueryProvider>,
      );
      expect(component.find('span').is('span')).to.eql(true);
    });
  });

  context('when React.Fragment is not available', () => {
    it('should render a div', () => {
      const component = mount(
        <MediaQueryProvider>

Test123

        </MediaQueryProvider>,
      );
      expect(component.find('div').is('div')).to.eql(true);
    });
  });
});
<|endoftext|>


<commit_before>////////////////////
// FILE FUNCTIONS //
////////////////////

function getDownloadLink(cookies) {
  var prefix = "https://mycourses.rit.edu";
  var viewer = document.getElementsByClassName("d2l-fileviewer")[0];

  if (viewer) {
    console.log("Trying to get download link directly");
    var divs = viewer.getElementsByTagName("div");
    var fileviewer = null;

    for (var i = 0; i < divs.length; i++) {
      if (divs[i].hasAttribute("data-location")) {
        fileviewer = divs[i];
        break;
      }
    }

    if (!fileviewer) {
      console.log("No direct link - must be be a Microsoft document");
      return generateDownloadLink(cookies);
    }

    console.log("Found direct link");

    var path = fileviewer.getAttribute("data-location");
    var path_part = path.split("?");

    var link = prefix + path_part[0] +
               "?d2lSecureSessionVal=" +
               cookies["d2lSecureSessionVal"] + // SecureSession must be first
               "&" + path_part[1]; // incluces d2lSessionVal and ou

    console.log("Direct link: " + link);

    return link;
  }

}

// Generates a download link (should work most of the time)
function generateDownloadLink(cookies) {
  console.log("Attempting to generate download link");

  var prefix = "https://mycourses.rit.edu/content/enforced2/";

  // make sure d2lSecureSession is first
  var cookie_suffix = "?d2lSecureSessionVal=" + cookies["d2lSecureSessionVal"] +
    "&" + "d2lSessionVal=" + cookies["d2lSessionVal"];

  // not sure why this is a parameter but including it anyway
  course_id_suffix = "&ou=" + getCourseIdNumber();

  var link = prefix +
             getCourseIdNumber() + "-" +
             getCourseLabel() + "/" +
             getFileName().replace(/ /g, "%20") +
             cookie_suffix +
             course_id_suffix;

  console.log("Generated link: " + link);

  return link;
}

// Return name of file
function getFileName() {
  var nametag = document.getElementsByClassName("vui-heading-1")[0];
  var no_preview = isNoPreviewFile();
  if (no_preview) {
    return no_preview;
  }

  var name = nametag.innerText;
  var ext = determineExt();

  return name + ext;
}

// Returns extension as string
// Ex: .pdf
// Or empty string if it's an other file
function determineExt() {
  var ext;

  if (isPDF()) {
    ext = ".pdf";
  } else if (isDOCX()) {
    ext = ".docx";
  } else if (isTXT()) {
    ext = ".txt";
  } else if (isHTML()) {
    ext = ".html";
  } else {
    ext = "";
  }
  return ext;
}

/*****************************************
 * TODO: Use regex instead of so many is...()
 *****************************************/

// Returns true if viewing PDF
function isPDF() {
  var pdfs = document.getElementsByClassName("d2l-fileviewer-pdf");
  if (pdfs.length == 1) {
    return true;
  }
  return false;
}

// Returns true if viewing .docx file
// I really couldn't think of a better way to do this
function isDOCX() {
  var body = document.getElementsByTagName("body")[0].innerHTML;
  if (body.indexOf(".docx") != -1) {
    return true;
  }
  return false;
}

// Returns true if viewing a .txt file
function isTXT() {
  var txt = document.getElementsByClassName("d2l-fileviewer-text");
  if (txt.length == 1) {
    if (txt[0].getAttribute("data-location").indexOf(".txt") != -1) {
      return true;
    } return false;
  }
  return false;
}

function isHTML() {
  var html = document.getElementsByClassName("d2l-fileviewer-text");
  if (html.length == 1) {
    if (html[0].getAttribute("data-location").indexOf(".html") != -1) {
      return true;
    } return false;
  }
  return false;
}

// Returns file name if it is a no preview file
// Returns null otherwise
function isNoPreviewFile() {
  var div = document.getElementsByClassName("d2l-textblock d2l-textblock-strong d2l-left")[0];
  if (div) {
    return div.innerText;
  }
  if (determineExt() === "") {
    console.error("Could not get file name!");
  }
  return null;
}

// Returns the mycourses course id number
function getCourseIdNumber() {
  return url_path.split("/")[4];
}

// Returns the mycourses course label
function getCourseLabel() {
  var regex = /\(([^)]+)\)/;
  var title = document.getElementsByClassName("d2l-navbar-title")[0].innerText;
  var label = regex.exec(title);
  return label[1];
}<commit_msg>Modified regex of getCourseLabel()<commit_after>////////////////////
// FILE FUNCTIONS //
////////////////////

function getDownloadLink(cookies) {
  var prefix = "https://mycourses.rit.edu";
  var viewer = document.getElementsByClassName("d2l-fileviewer")[0];

  if (viewer) {
    console.log("Trying to get download link directly");
    var divs = viewer.getElementsByTagName("div");
    var fileviewer = null;

    for (var i = 0; i < divs.length; i++) {
      if (divs[i].hasAttribute("data-location")) {
        fileviewer = divs[i];
        break;
      }
    }

    if (!fileviewer) {
      console.log("No direct link - must be be a Microsoft document");
      return generateDownloadLink(cookies);
    }

    console.log("Found direct link");

    var path = fileviewer.getAttribute("data-location");
    var path_part = path.split("?");

    var link = prefix + path_part[0] +
               "?d2lSecureSessionVal=" +
               cookies["d2lSecureSessionVal"] + // SecureSession must be first
               "&" + path_part[1]; // incluces d2lSessionVal and ou

    console.log("Direct link: " + link);

    return link;
  }

}

// Generates a download link (should work most of the time)
function generateDownloadLink(cookies) {
  console.log("Attempting to generate download link");

  var prefix = "https://mycourses.rit.edu/content/enforced2/";

  // make sure d2lSecureSession is first
  var cookie_suffix = "?d2lSecureSessionVal=" + cookies["d2lSecureSessionVal"] +
    "&" + "d2lSessionVal=" + cookies["d2lSessionVal"];

  // not sure why this is a parameter but including it anyway
  course_id_suffix = "&ou=" + getCourseIdNumber();

  var link = prefix +
             getCourseIdNumber() + "-" +
             getCourseLabel() + "/" +
             getFileName().replace(/ /g, "%20") +
             cookie_suffix +
             course_id_suffix;

  console.log("Generated link: " + link);

  return link;
}

// Return name of file
function getFileName() {
  var nametag = document.getElementsByClassName("vui-heading-1")[0];
  var no_preview = isNoPreviewFile();
  if (no_preview) {
    return no_preview;
  }

  var name = nametag.innerText;
  var ext = determineExt();

  return name + ext;
}

// Returns extension as string
// Ex: .pdf
// Or empty string if it's an other file
function determineExt() {
  var ext;

  if (isPDF()) {
    ext = ".pdf";
  } else if (isDOCX()) {
    ext = ".docx";
  } else if (isTXT()) {
    ext = ".txt";
  } else if (isHTML()) {
    ext = ".html";
  } else {
    ext = "";
  }
  return ext;
}

/*****************************************
 * TODO: Use regex instead of so many is...()
 *****************************************/

// Returns true if viewing PDF
function isPDF() {
  var pdfs = document.getElementsByClassName("d2l-fileviewer-pdf");
  if (pdfs.length == 1) {
    return true;
  }
  return false;
}

// Returns true if viewing .docx file
// I really couldn't think of a better way to do this
function isDOCX() {
  var body = document.getElementsByTagName("body")[0].innerHTML;
  if (body.indexOf(".docx") != -1) {
    return true;
  }
  return false;
}

// Returns true if viewing a .txt file
function isTXT() {
  var txt = document.getElementsByClassName("d2l-fileviewer-text");
  if (txt.length == 1) {
    if (txt[0].getAttribute("data-location").indexOf(".txt") != -1) {
      return true;
    } return false;
  }
  return false;
}

function isHTML() {
  var html = document.getElementsByClassName("d2l-fileviewer-text");
  if (html.length == 1) {
    if (html[0].getAttribute("data-location").indexOf(".html") != -1) {
      return true;
    } return false;
  }
  return false;
}

// Returns file name if it is a no preview file
// Returns null otherwise
function isNoPreviewFile() {
  var div = document.getElementsByClassName("d2l-textblock d2l-textblock-strong d2l-left")[0];
  if (div) {
    return div.innerText;
  }
  if (determineExt() === "") {
    console.error("Could not get file name!");
  }
  return null;
}

// Returns the mycourses course id number
function getCourseIdNumber() {
  return url_path.split("/")[4];
}

// Returns the mycourses course label
function getCourseLabel() {
  var regex = /([A-Z]{4}\d{4,5}\.\d{4})/;
  var title = document.getElementsByTagName("body")[0].innerText;
  var label = regex.exec(title);
  console.log("Course Label: " + label);
  return label[0];
}<|endoftext|>