<commit_before>'use strict';

murmures.Renderer = function () {
    this.tileset = {
        color: {
            imgElement : {},
            blobUrl : {}
        },
        gray: {
            canvas : {},
            imgElement : {},
            blobUrl : {}
        },
    };
    this.renderHeroes = true;
};

murmures.Renderer.prototype = {
    init : function () {
        const instance = this;
        window.addEventListener('requestTileset', function (e) {
            instance.downloadColorTileset();
        }, false);
        window.addEventListener('requestHighlight', function (e) {
            instance.highlightLevel();
        }, false);
        window.addEventListener('colorTilesetReady', function (e) {
            instance.initGrayscaleTileset();
        }, false);
        window.addEventListener('grayscaleTilesetCreated', function (e) {
            instance.paintGrayscaleTileset();
        }, false);
        window.addEventListener('grayscaleTilesetPainted', function (e) {
            instance.storeGrayscaleTileset();
        }, false);
        window.addEventListener('grayscaleTilesetReady', function (e) {
            gameEngine.client.eventDispatcher.emitEvent('tilesetReady');
        }, false);
        window.addEventListener('requestRenderFullEngine', function (e) {
            instance.resetCanvas();
            instance.drawTiles(gameEngine);
            instance.drawCharacters();
        }, false);
        window.addEventListener('requestRenderPartialEngine', function (e) {
            instance.drawTiles(e.detail);
            instance.clearCharacterLayer();
            instance.drawCharacters();
        }, false);
    },

    // #region tileset
    downloadColorTileset : function () {
        const instance = this;
        let xhr = new XMLHttpRequest();
        xhr.addEventListener("error", gameEngine.client.eventDispatcher.onXhrError);
        xhr.addEventListener("abort", gameEngine.client.eventDispatcher.onXhrError);
        xhr.addEventListener("progress", function (evt) {
            if (evt.lengthComputable) {
                let percentComplete = parseInt(50.0 * evt.loaded / evt.total, 10);
                gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', percentComplete);
            }
        });
        xhr.addEventListener("load", function (evt) {
            let img = new Image();
            img.onload = function () {
                instance.tileset.color.imgElement = img;
                gameEngine.client.eventDispatcher.emitEvent('colorTilesetReady');
            }
            instance.tileset.color.blobUrl = window.URL.createObjectURL(this.response); // closure is needed, otherwise at this point 'this' would be xhr
            img.src = instance.tileset.color.blobUrl;
        });
        xhr.open('GET', './src/img/murmures.png', true);
        xhr.responseType = "blob";
        xhr.send(null);
    },

    initGrayscaleTileset : function () {
        let canvas = document.createElement('canvas');
        this.tileset.gray.canvas = canvas;
        canvas.width = this.tileset.color.imgElement.width;
        canvas.height = this.tileset.color.imgElement.height;
        let ctx = canvas.getContext('2d');
        ctx.drawImage(this.tileset.color.imgElement, 0, 0);
        gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', 55);
        window.setTimeout(function () { gameEngine.client.eventDispatcher.emitEvent('grayscaleTilesetCreated') }, 0);
    },

    paintGrayscaleTileset : function () {
        let canvas = this.tileset.gray.canvas;
        let ctx = canvas.getContext('2d');
        let imageData = ctx.getImageData(0, 2239, canvas.width, 2465 - 2239);
        let data = imageData.data;
        for (let i = 0; i < data.length; i += 4) {
            let avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
            data[i] = avg; // red
            data[i + 1] = avg; // green
            data[i + 2] = avg; // blue
            // do not change alpha value
        }
        ctx.putImageData(imageData, 0, 2239);
        gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', 80);
        window.setTimeout(function () { gameEngine.client.eventDispatcher.emitEvent('grayscaleTilesetPainted') }, 0);
    },

    storeGrayscaleTileset : function () {
        let canvas = this.tileset.gray.canvas;
        // Code below is slightly faster (than toDataURL) on chrome51 but breaks IE11 compatibility.
        // Keeping it in comment for now.
        //canvas.toBlob(function (blob) {
        //    gameEngine.client.tilesetGray = window.URL.createObjectURL(blob);
        //    let img = new Image();
        //    img.onload = function () {
        //        gameEngine.client.tilesetImgGray = img;
        //        screenLog('loaded2');
        //        tilesetLoaded();
        //    }
        //    img.src = gameEngine.client.tilesetGray;
        //});
        const instance = this;
        let img = new Image();
        img.onload = function () {
            instance.tileset.gray.imgElement = img;
            gameEngine.client.eventDispatcher.emitEvent('grayscaleTilesetReady');
        }
        instance.tileset.gray.blobUrl = canvas.toDataURL();
        img.src = instance.tileset.gray.blobUrl;
        gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', 95);
    },
    // #endregion

    resetCanvas : function () {
        // TODO : have a window the size of the viewport that hides canvas overflow and centers on the heroes
        // http://jsfiddle.net/NUNNf/4/
        // https://www.kirupa.com/html5/clipping_content_using_css.htm

        [].forEach.call(document.getElementsByTagName('canvas'), function (canvas) {
            canvas.width = gameEngine.level.width * gameEngine.tileSize; // This is a hard reset of all canvas and is quite time consumming.
            canvas.height = gameEngine.level.height * gameEngine.tileSize;
            let context = canvas.getContext('2d');
            context.imageSmoothingEnabled = false;
        });
        document.getElementById('corridor').style.width = '' + gameEngine.level.width * gameEngine.tileSize + 'px';
    },

    highlightLevel : function () {
        for (let x = 0; x < gameEngine.level.width; x++) {
            for (let y = 0; y < gameEngine.level.height; y++) {
                gameEngine.level.tiles[y][x].state = murmures.C.TILE_FOG_OF_WAR;
            }
        }
        if (gameEngine.level.power === 0) {
            document.getElementById('fogOfWarLayer').style.opacity = '0';
        } else if (gameEngine.level.power >= 3) {
            document.getElementById('fogOfWarLayer').style.opacity = '1';
        } else {
            document.getElementById('fogOfWarLayer').style.opacity = '0.7';
        }
        if (gameEngine.level.power === 2) {
            if (gameEngine.heros[0].powerCharge < 10) {
                document.getElementById('fogOfWarLayer').className = 'blinkingFog';
            } else {
                document.getElementById('fogOfWarLayer').className = '';
                document.getElementById('fogOfWarLayer').style.opacity = '0';
            }
        }
        if (gameEngine.flash) {
            document.getElementById('fogOfWarLayer').style.opacity = '0';
        }
    },

    // #region tiles
    drawTiles : function (partialEngine) {
        for (let y = 0; y < gameEngine.level.height; y++) {
            for (let x = 0; x < gameEngine.level.width; x++) {
                if (gameEngine.level.tiles[y][x].state === murmures.C.TILE_HIGHLIGHTED) {
                    document.getElementById('fogOfWarLayer').getContext('2d').clearRect(gameEngine.tileSize * x, gameEngine.tileSize * y, gameEngine.tileSize, gameEngine.tileSize);
                }
            }
        }
        if (typeof partialEngine !== 'undefined' && typeof partialEngine.level !== 'undefined' && typeof partialEngine.level.tiles !== 'undefined') {
            partialEngine.level.tiles.forEach(function (tileRow) {
                tileRow.forEach(function (tile) {
                    this.drawOneTile(tile.x, tile.y);
                }, this);
            }, this);
        }
    },

    drawOneTile : function (x, y) {
        if (gameEngine.level.tiles[y][x].state !== murmures.C.TILE_NOT_DISCOVERED) {
            document.getElementById('tilesLayer').getContext('2d').clearRect(gameEngine.tileSize * x, gameEngine.tileSize * y, gameEngine.tileSize, gameEngine.tileSize);
            this.drawOneLayer(x, y, 'groundId');
            this.drawOneLayer(x, y, 'groundDeco');
            this.drawOneLayer(x, y, 'propId');
            this.drawOneLayer(x, y, 'propDeco');
            this.drawOneLayer(x, y, 'itemId');
            this.drawOneLayer(x, y, 'effectId');
        }
        if (gameEngine.level.tiles[y][x].state === murmures.C.TILE_FOG_OF_WAR) {
            this.drawOneSquare(document.getElementById('fogOfWarLayer').getContext('2d'), x, y, "#000000", true);
        }
    },

    drawOneLayer : function (x, y, layerId) {
        if (gameEngine.level.tiles[y][x][layerId] !== '') {
            let tilesetRank = gameEngine.bodies[gameEngine.level.tiles[y][x][layerId]].rank;
            let tilesetX = tilesetRank % 64;
            let tilesetY = (tilesetRank - tilesetX) / 64;
            document.getElementById('tilesLayer').getContext('2d').drawImage(this.tileset.color.imgElement,
                    tilesetX * gameEngine.tileSize, tilesetY * gameEngine.tileSize, gameEngine.tileSize, gameEngine.tileSize,
                    gameEngine.tileSize * x, gameEngine.tileSize * y, gameEngine.tileSize, gameEngine.tileSize);
        }
    },

    drawOneSquare : function (context, x, y, color, filled) {
        context.beginPath();
        if (filled || y === 0) {
            context.moveTo(gameEngine.tileSize * x, gameEngine.tileSize * y);
            context.lineTo(gameEngine.tileSize * x + gameEngine.tileSize, gameEngine.tileSize * y);
        } else {
            context.moveTo(gameEngine.tileSize * x + gameEngine.tileSize, gameEngine.tileSize * y);
        }
        context.lineTo(gameEngine.tileSize * x + gameEngine.tileSize, gameEngine.tileSize * y + gameEngine.tileSize);
        context.lineTo(gameEngine.tileSize * x, gameEngine.tileSize * y + gameEngine.tileSize);
        if (filled || x === 0) {
            context.lineTo(gameEngine.tileSize * x, gameEngine.tileSize * y);
        }
        context.strokeStyle = color;
        context.stroke();
        if (filled) {
            context.closePath();
            context.fillStyle = color;
            context.fill();
        }
    },
    // #endregion

    // #region characters
    clearCharacterLayer : function () {
        document.getElementById('characterLayer').getContext('2d').clearRect(0, 0, gameEngine.level.width * gameEngine.tileSize, gameEngine.level.height * gameEngine.tileSize);
    },

    drawCharacters : function () {
        if (typeof gameEngine.level.mobs !== 'undefined') {
            for (let i = 0; i < gameEngine.level.mobs.length; i++) {
                // TODO : move mobIsSeen to murmures.Character
                //let mobIsSeen = false;
                //for (let itVision in gameEngine.level.mobs[i].onVisionCharacters) {
                //    if (gameEngine.level.mobs[i].onVisionCharacters[itVision]) {
                //        mobIsSeen = true;
                //        break;
                //    }
                //}
                let mobIsSeen = (gameEngine.level.mobs[i].position.state === murmures.C.TILE_HIGHLIGHTED);
                if (gameEngine.level.mobs[i].hitPoints === 0 || !mobIsSeen) {
                } else {
                    this.drawCharacter(gameEngine.level.mobs[i]);
                }
            }
        }
        if (this.renderHeroes) {
            for (let i = 0; i < gameEngine.heros.length; i++) {
                this.drawCharacter(gameEngine.heros[i]);
            }
        }
    },

    drawCharacter : function (character) {
        let tilesetRank = gameEngine.bodies[character.mobTemplate].rank;
        let tilesetX = tilesetRank % 64;
        let tilesetY = (tilesetRank - tilesetX) / 64;
        if (true) {
            document.getElementById('characterLayer').getContext('2d').drawImage(
                !character.isHero || character.guid === gameEngine.getCurrentHero().guid ? this.tileset.color.imgElement : this.tileset.gray.imgElement,
                    tilesetX * gameEngine.tileSize, tilesetY * gameEngine.tileSize, gameEngine.tileSize, gameEngine.tileSize,
                    gameEngine.tileSize * character.position.x, gameEngine.tileSize * character.position.y, gameEngine.tileSize, gameEngine.tileSize);
        }
    },
    // #endregion

};<commit_msg>bug fixed when partialEngine is null<commit_after>'use strict';

murmures.Renderer = function () {
    this.tileset = {
        color: {
            imgElement : {},
            blobUrl : {}
        },
        gray: {
            canvas : {},
            imgElement : {},
            blobUrl : {}
        },
    };
    this.renderHeroes = true;
};

murmures.Renderer.prototype = {
    init : function () {
        const instance = this;
        window.addEventListener('requestTileset', function (e) {
            instance.downloadColorTileset();
        }, false);
        window.addEventListener('requestHighlight', function (e) {
            instance.highlightLevel();
        }, false);
        window.addEventListener('colorTilesetReady', function (e) {
            instance.initGrayscaleTileset();
        }, false);
        window.addEventListener('grayscaleTilesetCreated', function (e) {
            instance.paintGrayscaleTileset();
        }, false);
        window.addEventListener('grayscaleTilesetPainted', function (e) {
            instance.storeGrayscaleTileset();
        }, false);
        window.addEventListener('grayscaleTilesetReady', function (e) {
            gameEngine.client.eventDispatcher.emitEvent('tilesetReady');
        }, false);
        window.addEventListener('requestRenderFullEngine', function (e) {
            instance.resetCanvas();
            instance.drawTiles(gameEngine);
            instance.drawCharacters();
        }, false);
        window.addEventListener('requestRenderPartialEngine', function (e) {
            instance.drawTiles(e.detail);
            instance.clearCharacterLayer();
            instance.drawCharacters();
        }, false);
    },

    // #region tileset
    downloadColorTileset : function () {
        const instance = this;
        let xhr = new XMLHttpRequest();
        xhr.addEventListener("error", gameEngine.client.eventDispatcher.onXhrError);
        xhr.addEventListener("abort", gameEngine.client.eventDispatcher.onXhrError);
        xhr.addEventListener("progress", function (evt) {
            if (evt.lengthComputable) {
                let percentComplete = parseInt(50.0 * evt.loaded / evt.total, 10);
                gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', percentComplete);
            }
        });
        xhr.addEventListener("load", function (evt) {
            let img = new Image();
            img.onload = function () {
                instance.tileset.color.imgElement = img;
                gameEngine.client.eventDispatcher.emitEvent('colorTilesetReady');
            }
            instance.tileset.color.blobUrl = window.URL.createObjectURL(this.response); // closure is needed, otherwise at this point 'this' would be xhr
            img.src = instance.tileset.color.blobUrl;
        });
        xhr.open('GET', './src/img/murmures.png', true);
        xhr.responseType = "blob";
        xhr.send(null);
    },

    initGrayscaleTileset : function () {
        let canvas = document.createElement('canvas');
        this.tileset.gray.canvas = canvas;
        canvas.width = this.tileset.color.imgElement.width;
        canvas.height = this.tileset.color.imgElement.height;
        let ctx = canvas.getContext('2d');
        ctx.drawImage(this.tileset.color.imgElement, 0, 0);
        gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', 55);
        window.setTimeout(function () { gameEngine.client.eventDispatcher.emitEvent('grayscaleTilesetCreated') }, 0);
    },

    paintGrayscaleTileset : function () {
        let canvas = this.tileset.gray.canvas;
        let ctx = canvas.getContext('2d');
        let imageData = ctx.getImageData(0, 2239, canvas.width, 2465 - 2239);
        let data = imageData.data;
        for (let i = 0; i < data.length; i += 4) {
            let avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
            data[i] = avg; // red
            data[i + 1] = avg; // green
            data[i + 2] = avg; // blue
            // do not change alpha value
        }
        ctx.putImageData(imageData, 0, 2239);
        gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', 80);
        window.setTimeout(function () { gameEngine.client.eventDispatcher.emitEvent('grayscaleTilesetPainted') }, 0);
    },

    storeGrayscaleTileset : function () {
        let canvas = this.tileset.gray.canvas;
        // Code below is slightly faster (than toDataURL) on chrome51 but breaks IE11 compatibility.
        // Keeping it in comment for now.
        //canvas.toBlob(function (blob) {
        //    gameEngine.client.tilesetGray = window.URL.createObjectURL(blob);
        //    let img = new Image();
        //    img.onload = function () {
        //        gameEngine.client.tilesetImgGray = img;
        //        screenLog('loaded2');
        //        tilesetLoaded();
        //    }
        //    img.src = gameEngine.client.tilesetGray;
        //});
        const instance = this;
        let img = new Image();
        img.onload = function () {
            instance.tileset.gray.imgElement = img;
            gameEngine.client.eventDispatcher.emitEvent('grayscaleTilesetReady');
        }
        instance.tileset.gray.blobUrl = canvas.toDataURL();
        img.src = instance.tileset.gray.blobUrl;
        gameEngine.client.eventDispatcher.emitEvent('tilesetLoadProgress', 95);
    },
    // #endregion

    resetCanvas : function () {
        // TODO : have a window the size of the viewport that hides canvas overflow and centers on the heroes
        // http://jsfiddle.net/NUNNf/4/
        // https://www.kirupa.com/html5/clipping_content_using_css.htm

        [].forEach.call(document.getElementsByTagName('canvas'), function (canvas) {
            canvas.width = gameEngine.level.width * gameEngine.tileSize; // This is a hard reset of all canvas and is quite time consumming.
            canvas.height = gameEngine.level.height * gameEngine.tileSize;
            let context = canvas.getContext('2d');
            context.imageSmoothingEnabled = false;
        });
        document.getElementById('corridor').style.width = '' + gameEngine.level.width * gameEngine.tileSize + 'px';
    },

    highlightLevel : function () {
        for (let x = 0; x < gameEngine.level.width; x++) {
            for (let y = 0; y < gameEngine.level.height; y++) {
                gameEngine.level.tiles[y][x].state = murmures.C.TILE_FOG_OF_WAR;
            }
        }
        if (gameEngine.level.power === 0) {
            document.getElementById('fogOfWarLayer').style.opacity = '0';
        } else if (gameEngine.level.power >= 3) {
            document.getElementById('fogOfWarLayer').style.opacity = '1';
        } else {
            document.getElementById('fogOfWarLayer').style.opacity = '0.7';
        }
        if (gameEngine.level.power === 2) {
            if (gameEngine.heros[0].powerCharge < 10) {
                document.getElementById('fogOfWarLayer').className = 'blinkingFog';
            } else {
                document.getElementById('fogOfWarLayer').className = '';
                document.getElementById('fogOfWarLayer').style.opacity = '0';
            }
        }
        if (gameEngine.flash) {
            document.getElementById('fogOfWarLayer').style.opacity = '0';
        }
    },

    // #region tiles
    drawTiles : function (partialEngine) {
        for (let y = 0; y < gameEngine.level.height; y++) {
            for (let x = 0; x < gameEngine.level.width; x++) {
                if (gameEngine.level.tiles[y][x].state === murmures.C.TILE_HIGHLIGHTED) {
                    document.getElementById('fogOfWarLayer').getContext('2d').clearRect(gameEngine.tileSize * x, gameEngine.tileSize * y, gameEngine.tileSize, gameEngine.tileSize);
                }
            }
        }

        if (typeof partialEngine !== 'undefined' && partialEngine !== null && typeof partialEngine.level !== 'undefined' && typeof partialEngine.level.tiles !== 'undefined') {
            partialEngine.level.tiles.forEach(function (tileRow) {
                tileRow.forEach(function (tile) {
                    this.drawOneTile(tile.x, tile.y);
                }, this);
            }, this);
        }
    },

    drawOneTile : function (x, y) {
        if (gameEngine.level.tiles[y][x].state !== murmures.C.TILE_NOT_DISCOVERED) {
            document.getElementById('tilesLayer').getContext('2d').clearRect(gameEngine.tileSize * x, gameEngine.tileSize * y, gameEngine.tileSize, gameEngine.tileSize);
            this.drawOneLayer(x, y, 'groundId');
            this.drawOneLayer(x, y, 'groundDeco');
            this.drawOneLayer(x, y, 'propId');
            this.drawOneLayer(x, y, 'propDeco');
            this.drawOneLayer(x, y, 'itemId');
            this.drawOneLayer(x, y, 'effectId');
        }
        if (gameEngine.level.tiles[y][x].state === murmures.C.TILE_FOG_OF_WAR) {
            this.drawOneSquare(document.getElementById('fogOfWarLayer').getContext('2d'), x, y, "#000000", true);
        }
    },

    drawOneLayer : function (x, y, layerId) {
        if (gameEngine.level.tiles[y][x][layerId] !== '') {
            let tilesetRank = gameEngine.bodies[gameEngine.level.tiles[y][x][layerId]].rank;
            let tilesetX = tilesetRank % 64;
            let tilesetY = (tilesetRank - tilesetX) / 64;
            document.getElementById('tilesLayer').getContext('2d').drawImage(this.tileset.color.imgElement,
                    tilesetX * gameEngine.tileSize, tilesetY * gameEngine.tileSize, gameEngine.tileSize, gameEngine.tileSize,
                    gameEngine.tileSize * x, gameEngine.tileSize * y, gameEngine.tileSize, gameEngine.tileSize);
        }
    },

    drawOneSquare : function (context, x, y, color, filled) {
        context.beginPath();
        if (filled || y === 0) {
            context.moveTo(gameEngine.tileSize * x, gameEngine.tileSize * y);
            context.lineTo(gameEngine.tileSize * x + gameEngine.tileSize, gameEngine.tileSize * y);
        } else {
            context.moveTo(gameEngine.tileSize * x + gameEngine.tileSize, gameEngine.tileSize * y);
        }
        context.lineTo(gameEngine.tileSize * x + gameEngine.tileSize, gameEngine.tileSize * y + gameEngine.tileSize);
        context.lineTo(gameEngine.tileSize * x, gameEngine.tileSize * y + gameEngine.tileSize);
        if (filled || x === 0) {
            context.lineTo(gameEngine.tileSize * x, gameEngine.tileSize * y);
        }
        context.strokeStyle = color;
        context.stroke();
        if (filled) {
            context.closePath();
            context.fillStyle = color;
            context.fill();
        }
    },
    // #endregion

    // #region characters
    clearCharacterLayer : function () {
        document.getElementById('characterLayer').getContext('2d').clearRect(0, 0, gameEngine.level.width * gameEngine.tileSize, gameEngine.level.height * gameEngine.tileSize);
    },

    drawCharacters : function () {
        if (typeof gameEngine.level.mobs !== 'undefined') {
            for (let i = 0; i < gameEngine.level.mobs.length; i++) {
                // TODO : move mobIsSeen to murmures.Character
                //let mobIsSeen = false;
                //for (let itVision in gameEngine.level.mobs[i].onVisionCharacters) {
                //    if (gameEngine.level.mobs[i].onVisionCharacters[itVision]) {
                //        mobIsSeen = true;
                //        break;
                //    }
                //}
                let mobIsSeen = (gameEngine.level.mobs[i].position.state === murmures.C.TILE_HIGHLIGHTED);
                if (gameEngine.level.mobs[i].hitPoints === 0 || !mobIsSeen) {
                } else {
                    this.drawCharacter(gameEngine.level.mobs[i]);
                }
            }
        }
        if (this.renderHeroes) {
            for (let i = 0; i < gameEngine.heros.length; i++) {
                this.drawCharacter(gameEngine.heros[i]);
            }
        }
    },

    drawCharacter : function (character) {
        let tilesetRank = gameEngine.bodies[character.mobTemplate].rank;
        let tilesetX = tilesetRank % 64;
        let tilesetY = (tilesetRank - tilesetX) / 64;
        if (true) {
            document.getElementById('characterLayer').getContext('2d').drawImage(
                !character.isHero || character.guid === gameEngine.getCurrentHero().guid ? this.tileset.color.imgElement : this.tileset.gray.imgElement,
                    tilesetX * gameEngine.tileSize, tilesetY * gameEngine.tileSize, gameEngine.tileSize, gameEngine.tileSize,
                    gameEngine.tileSize * character.position.x, gameEngine.tileSize * character.position.y, gameEngine.tileSize, gameEngine.tileSize);
        }
    },
    // #endregion

};<|endoftext|>


<commit_before>'use strict';

const gulp = require('gulp');
const eslint = require('gulp-eslint');
const browserSync = require('browser-sync').create();
const concat = require('gulp-concat');
const sass = require('gulp-sass');
const runSequence = require('run-sequence');
const addSrc = require('gulp-add-src');
const gutil = require('gulp-util');
const del = require('del');

const paths = {
  DIST: './dist',
  DIST_SKINS: './dist/skins',
  DIST_FONTS: './dist/font',
  SRC_JS: './src/js/*.js',
  SRC_SCSS: './src/scss/*.scss',
  SRC_SCSS_SKINS: './src/scss/skins/*.scss'
};

const distName = 'wjplayer';
const distName360 = 'wjplayer-360';

const deps = ['core', 'ads', 'switcher', 'share', 'download', 'ga'];
const deps360 = ['360'];

let includesJs = [];
let includesCss = [];
let includesJs360 = [];
let includesCss360 = [];

const includes = {
  js: {
    core: [
      'node_modules/video.js/dist/video.js',
      'node_modules/videojs5-hlsjs-source-handler/lib/videojs5-hlsjs-source-handler.js',
      paths.SRC_JS
    ],
    ads: [
      'node_modules/videojs-contrib-ads/src/videojs.ads.js',
      'node_modules/videojs-ima/src/videojs.ima.js'
    ],
    switcher: [
      'node_modules/videojs-resolution-switcher/lib/videojs-resolution-switcher.js'
    ],
    share: [
      'node_modules/videojs-social/videojs-social.js'
    ],
    download: [
      'node_modules/videojs-download-button/dist/videojs-download-button.js'
    ],
    ga: [
      'node_modules/videojs-ga/dist/videojs.ga.js'
    ],
    360: [
      'node_modules/three/build/three.js',
      'node_modules/videojs-panorama/dist/videojs-panorama.v5.js'
    ]
  },
  css: {
    core: [
      'node_modules/video.js/dist/video-js.css'
    ],
    ads: [
      'node_modules/videojs-ima/src/videojs.ima.css'
    ],
    switcher: [
      'node_modules/videojs-resolution-switcher/lib/videojs-resolution-switcher.css'
    ],
    share: [
      'node_modules/videojs-social/videojs-social.css'
    ],
    download: [
      'node_modules/videojs-download-button/dist/videojs-download-button.css'
    ],
    ga: [],
    360: [
      'node_modules/videojs-panorama/dist/videojs-panorama.css'
    ]
  },
  fonts: 'node_modules/video.js/dist/font/*',
  swf: 'node_modules/video.js/dist/video-js.swf'
};

deps.forEach(function(inc) {
  includesJs = includesJs.concat(includes.js[inc]);
  includesCss = includesCss.concat(includes.css[inc]);
});

deps360.forEach(function(inc) {
  includesJs360 = includesJs360.concat(includes.js[inc]);
  includesCss360 = includesCss360.concat(includes.css[inc]);
});

gulp.task('default', () => {
  runSequence('scripts-360', 'styles', 'fonts', 'swf');
});

// Open in browser for testing
gulp.task('browse', ['server', 'watch']);

gulp.task('build', ['clean-dist'], () => {
  gulp.start('scripts', 'styles');
});

gulp.task('scripts', ['scripts-360', 'lint'], () => {
  return gulp.src(includesJs)
    .pipe(concat(distName + '.js'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('scripts-360', () => {
  return gulp.src(includesJs360)
    .pipe(concat(distName360 + '.js'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('styles', ['skins', 'styles-360'], () => {
  return gulp.src(paths.SRC_SCSS)
    .pipe(sass({
      outputStyle: 'nested'
    }).on('error', gutil.log))
    .pipe(addSrc.prepend(includesCss))
    .pipe(concat(distName + '.css'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('styles-360', () => {
  return gulp.src(includesCss360)
    .pipe(concat(distName360 + '.css'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('skins', () => {
  return gulp.src(paths.SRC_SCSS_SKINS)
    .pipe(sass({
      outputStyle: 'nested'
    }).on('error', gutil.log))
    .pipe(gulp.dest(paths.DIST_SKINS));
});

gulp.task('fonts', () => {
  return gulp.src(includes.fonts)
    .pipe(gulp.dest(paths.DIST_FONTS));
});

gulp.task('swf', () => {
  return gulp.src(includes.swf)
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('clean-js', () => {
  return del(paths.SRC_JS);
});

gulp.task('clean-dist', () => {
  return del(paths.DIST + '/**/*.{js,css}');
});

gulp.task('lint', () => {
  return gulp.src(paths.SRC_JS)
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

gulp.task('server', () => {
  browserSync.init({
    server: {
      baseDir: './'
    },
    port: 3030,
    https: true,
    open: true,
    notify: false
  });
});

gulp.task('watch', () => {
  gulp.watch('index.html').on('change', browserSync.reload);
  gulp.watch(paths.SRC_JS, ['scripts']);
  gulp.watch(paths.DIST + '/*.js', ['sync-js']);
  gulp.watch(paths.SRC_SCSS, ['styles']);
  gulp.watch(paths.DIST + '/*.css', ['sync-css']);
});

gulp.task('sync-js', () => {
  gulp.src(paths.DIST + '/*.js')
    .pipe(browserSync.stream());
});

gulp.task('sync-css', () => {
  gulp.src(paths.DIST + '/*.css')
    .pipe(browserSync.stream());
});
<commit_msg>make port and https configurable via process.env<commit_after>'use strict';

const gulp = require('gulp');
const eslint = require('gulp-eslint');
const browserSync = require('browser-sync').create();
const concat = require('gulp-concat');
const sass = require('gulp-sass');
const runSequence = require('run-sequence');
const addSrc = require('gulp-add-src');
const gutil = require('gulp-util');
const del = require('del');

const paths = {
  DIST: './dist',
  DIST_SKINS: './dist/skins',
  DIST_FONTS: './dist/font',
  SRC_JS: './src/js/*.js',
  SRC_SCSS: './src/scss/*.scss',
  SRC_SCSS_SKINS: './src/scss/skins/*.scss'
};

const distName = 'wjplayer';
const distName360 = 'wjplayer-360';

const deps = ['core', 'ads', 'switcher', 'share', 'download', 'ga'];
const deps360 = ['360'];

let includesJs = [];
let includesCss = [];
let includesJs360 = [];
let includesCss360 = [];

const includes = {
  js: {
    core: [
      'node_modules/video.js/dist/video.js',
      'node_modules/videojs5-hlsjs-source-handler/lib/videojs5-hlsjs-source-handler.js',
      paths.SRC_JS
    ],
    ads: [
      'node_modules/videojs-contrib-ads/src/videojs.ads.js',
      'node_modules/videojs-ima/src/videojs.ima.js'
    ],
    switcher: [
      'node_modules/videojs-resolution-switcher/lib/videojs-resolution-switcher.js'
    ],
    share: [
      'node_modules/videojs-social/videojs-social.js'
    ],
    download: [
      'node_modules/videojs-download-button/dist/videojs-download-button.js'
    ],
    ga: [
      'node_modules/videojs-ga/dist/videojs.ga.js'
    ],
    360: [
      'node_modules/three/build/three.js',
      'node_modules/videojs-panorama/dist/videojs-panorama.v5.js'
    ]
  },
  css: {
    core: [
      'node_modules/video.js/dist/video-js.css'
    ],
    ads: [
      'node_modules/videojs-ima/src/videojs.ima.css'
    ],
    switcher: [
      'node_modules/videojs-resolution-switcher/lib/videojs-resolution-switcher.css'
    ],
    share: [
      'node_modules/videojs-social/videojs-social.css'
    ],
    download: [
      'node_modules/videojs-download-button/dist/videojs-download-button.css'
    ],
    ga: [],
    360: [
      'node_modules/videojs-panorama/dist/videojs-panorama.css'
    ]
  },
  fonts: 'node_modules/video.js/dist/font/*',
  swf: 'node_modules/video.js/dist/video-js.swf'
};

deps.forEach(function(inc) {
  includesJs = includesJs.concat(includes.js[inc]);
  includesCss = includesCss.concat(includes.css[inc]);
});

deps360.forEach(function(inc) {
  includesJs360 = includesJs360.concat(includes.js[inc]);
  includesCss360 = includesCss360.concat(includes.css[inc]);
});

gulp.task('default', () => {
  runSequence('scripts-360', 'styles', 'fonts', 'swf');
});

// Open in browser for testing
gulp.task('browse', ['server', 'watch']);

gulp.task('build', ['clean-dist'], () => {
  gulp.start('scripts', 'styles');
});

gulp.task('scripts', ['scripts-360', 'lint'], () => {
  return gulp.src(includesJs)
    .pipe(concat(distName + '.js'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('scripts-360', () => {
  return gulp.src(includesJs360)
    .pipe(concat(distName360 + '.js'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('styles', ['skins', 'styles-360'], () => {
  return gulp.src(paths.SRC_SCSS)
    .pipe(sass({
      outputStyle: 'nested'
    }).on('error', gutil.log))
    .pipe(addSrc.prepend(includesCss))
    .pipe(concat(distName + '.css'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('styles-360', () => {
  return gulp.src(includesCss360)
    .pipe(concat(distName360 + '.css'))
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('skins', () => {
  return gulp.src(paths.SRC_SCSS_SKINS)
    .pipe(sass({
      outputStyle: 'nested'
    }).on('error', gutil.log))
    .pipe(gulp.dest(paths.DIST_SKINS));
});

gulp.task('fonts', () => {
  return gulp.src(includes.fonts)
    .pipe(gulp.dest(paths.DIST_FONTS));
});

gulp.task('swf', () => {
  return gulp.src(includes.swf)
    .pipe(gulp.dest(paths.DIST));
});

gulp.task('clean-js', () => {
  return del(paths.SRC_JS);
});

gulp.task('clean-dist', () => {
  return del(paths.DIST + '/**/*.{js,css}');
});

gulp.task('lint', () => {
  return gulp.src(paths.SRC_JS)
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

gulp.task('server', () => {
  browserSync.init({
    server: {
      baseDir: './'
    },
    port: process.env.PORT || 3000,
    https: !!process.env.HTTPS,
    open: true,
    notify: false
  });
});

gulp.task('watch', () => {
  gulp.watch('index.html').on('change', browserSync.reload);
  gulp.watch(paths.SRC_JS, ['scripts']);
  gulp.watch(paths.DIST + '/*.js', ['sync-js']);
  gulp.watch(paths.SRC_SCSS, ['styles']);
  gulp.watch(paths.DIST + '/*.css', ['sync-css']);
});

gulp.task('sync-js', () => {
  gulp.src(paths.DIST + '/*.js')
    .pipe(browserSync.stream());
});

gulp.task('sync-css', () => {
  gulp.src(paths.DIST + '/*.css')
    .pipe(browserSync.stream());
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var ngconfig = require('./ngauto-config.js');
var ngAutoBootstrap = require('gulp-ng-autobootstrap');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var babelify = require('babelify');

var watchify = require('watchify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var gutil = require('gulp-util');
var sourcemaps = require('gulp-sourcemaps');
var assign = require('lodash.assign');

gulp.task('default', ['task-module', 'user-module', 'views', 'browserify', 'browser-sync']);

// add custom browserify options here
var customOpts = {
  entries: ['./app/main.js'],
  debug: true
};
var opts = assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts).transform(babelify));

//Autobootstrap
gulp.task('task-module', function() {
  return gulp
    .src('app/test/**/*.js')
    .pipe(ngAutoBootstrap(ngconfig))
    .pipe(gulp.dest('app/test'));
});

gulp.task('user-module', function() {
  return gulp
    .src('app/user/**/*.js')
    .pipe(ngAutoBootstrap(ngconfig))
    .pipe(gulp.dest('app/user'));
});

gulp.task('views', function() {
  return gulp.src('app/**/*.html')
    .pipe(gulp.dest('dist/'));
});

gulp.task('browser-sync', function() {
  browserSync({
    server: {
      baseDir: "dist/"
    }
  });
})

gulp.task('browserify', bundle);
b.on('update', bundle);
b.on('log', gutil.log);

function bundle() {
  return b.bundle()
    // log errors if they happen
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('js/bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
    .pipe(sourcemaps.write('./')) // writes .map file
    .pipe(gulp.dest('./dist'))
    .pipe(reload({stream: true, once: true}));
}
<commit_msg>moved transform to bundle to fix reload with polyfills<commit_after>var gulp = require('gulp');
var ngconfig = require('./ngauto-config.js');
var ngAutoBootstrap = require('gulp-ng-autobootstrap');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var babelify = require('babelify');

var watchify = require('watchify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var gutil = require('gulp-util');
var sourcemaps = require('gulp-sourcemaps');
var assign = require('lodash.assign');

gulp.task('default', ['task-module', 'user-module', 'views', 'browserify', 'browser-sync']);

// add custom browserify options here
var customOpts = {
  entries: ['./app/main.js'],
  debug: true
};
var opts = assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts));

//Autobootstrap
gulp.task('task-module', function() {
  return gulp
    .src('app/test/**/*.js')
    .pipe(ngAutoBootstrap(ngconfig))
    .pipe(gulp.dest('app/test'));
});

gulp.task('user-module', function() {
  return gulp
    .src('app/user/**/*.js')
    .pipe(ngAutoBootstrap(ngconfig))
    .pipe(gulp.dest('app/user'));
});

gulp.task('views', function() {
  return gulp.src('app/**/*.html')
    .pipe(gulp.dest('dist/'));
});

gulp.task('browser-sync', function() {
  browserSync({
    server: {
      baseDir: "dist/"
    }
  });
})

gulp.task('browserify', bundle);
b.on('update', bundle);
b.on('log', gutil.log);

function bundle() {
  return b.bundle()
    // log errors if they happen
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('js/bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
    .pipe(sourcemaps.write('./')) // writes .map file
    .transform(babelify)
    .pipe(gulp.dest('./dist'))
    .pipe(reload({stream: true, once: true}));
}
<|endoftext|>


<commit_before>
import React, { Component } from 'react'
import { Router, Route, browserHistory, } from 'react-router'
import { Provider } from 'react-redux'
import configureStore from '../store/configure-store'
import ClassificationExplorer from './classification-explorer'
import ClassificationDetails from './classification-details'
import ItemDetails from './item-details'
import { path } from '../router-mapping'

const store = configureStore()

export default class Root extends Component {
  render() {
    return (
      <Provider store={store}>
        <Router history={browserHistory}>
          <Route path="/" component={ClassificationExplorer} />
          <Route path={path.classificationDetails}
                 component={ClassificationDetails} />
          <Route path={path.itemDetails.pattern}
                 component={ItemDetails} />
        </Router>
      </Provider>
    )
  }
}
<commit_msg>Fix issue in item details route<commit_after>
import React, { Component } from 'react'
import { Router, Route, browserHistory, } from 'react-router'
import { Provider } from 'react-redux'
import configureStore from '../store/configure-store'
import ClassificationExplorer from './classification-explorer'
import ClassificationDetails from './classification-details'
import ItemDetails from './item-details'
import { path } from '../router-mapping'

const store = configureStore()

export default class Root extends Component {
  render() {
    return (
      <Provider store={store}>
        <Router history={browserHistory}>
          <Route path="/" component={ClassificationExplorer} />
          <Route path={path.classificationDetails}
                 component={ClassificationDetails} />
          <Route path={path.itemDetails}
                 component={ItemDetails} />
        </Router>
      </Provider>
    )
  }
}
<|endoftext|>


<commit_before>/*Gulp JS code*/
const gulp = require("gulp"),
  del = require("del"),
  util = require("util"),
  exec = util.promisify(require("child_process").exec),
  imageminMozjpeg = require("imagemin-mozjpeg"),
  zopfli = require("imagemin-zopfli"),
  parallel = require("concurrent-transform"),
  combiner = require("stream-combiner2"),
  filesize = require("filesize"),
  fs = require("fs"),
  os = require("os"),
  $ = require("gulp-load-plugins")(), //load all gulp plugins
  cfg = "./config.json",
  defConfig = {
    in_dir: "./in",
    out_dir: "./out",
    width: 1024,
    height: 1024,
    createWebP: false,
    watermark: "./watermark.png"
  };

function fileExists(path) {
  try {
    return fs.statSync(path).isFile();
  } catch (e) {
    if (e.code == "ENOENT") {
      // no such file or directory. File really does not exist
      //console.log("File does not exist.");
      return false;
    }

    //console.log("Exception fs.statSync (" + path + "): " + e);
    throw e; // something else went wrong, we don't have rights, ...
  }
}

let userConfig = {},
  config = {};

//Load config from config file
if (fileExists(cfg)) {
  userConfig = JSON.parse(fs.readFileSync(cfg));
}
Object.assign(config, defConfig, userConfig);

//special check for watermark file
if (config.watermark.length && !fileExists(config.watermark)) {
  //skip watermark step
  config.watermark = "";
}

let SRC = config.in_dir + "/**/*.{jpg,jpeg,png,svg,gif}",
  DEST = config.out_dir;

/*image processing pipeline
  - Resize the image.
  - Minify the image with imagemin
  - Mozjpeg compression is used for jpg files
*/
const processImages = combiner.obj(
  $.imageResize({
    width: config.width,
    height: config.height
  }),
  config.watermark.length
    ? $.watermark({
      image: config.watermark,
      resize: "100x100"
    })
    : $.util.noop(),
  $.imagemin([
    $.imagemin.gifsicle({ interlaced: true }),
    $.imagemin.jpegtran({ progressive: true }),
    $.imagemin.optipng({ optimizationLevel: 5 }),
    $.imagemin.svgo({ plugins: [{ removeViewBox: true }] }),
    imageminMozjpeg({ progressive: true }),
    zopfli({ more: true })
  ])
);

/*eslint-disable no-console */
processImages.on("error", console.error.bind(console));

/*eslint-enable no-console */

gulp.task("testGM", () => {
  //GraphicsMagick is one of the required binary/library. Check for it's presence
  return exec("gm version");
});

gulp.task("clean", () => {
  return del(config.out_dir + "/**/*"); //delete all destination files, just to be clean
});
gulp.task("processImg", () => {
  // place code here
  return gulp
    .src(SRC, { nocase: true, base: config.in_dir })
    .pipe($.plumber()) //node stream related error handling
    .pipe($.changed(DEST))
    .pipe($.sizediff.start())
    .pipe(parallel(processImages, os.cpus().length))
    .pipe(gulp.dest(DEST))
    .pipe(config.createWebP ? $.webp() : $.util.noop())
    .pipe(gulp.dest(DEST))
    .pipe(
      $.sizediff.stop({
        title: "Saved",
        formatFn: data => {
          return (
            filesize(data.diff) +
            " (" +
            (100 - Math.round((data.diffPercent || 1) * 100)) +
            "%)"
          );
        }
      })
    )
    .pipe($.plumber.stop());
});

gulp.task("default", gulp.series("testGM", "processImg"));
<commit_msg>prettier fix<commit_after>/*Gulp JS code*/
const gulp = require("gulp"),
  del = require("del"),
  util = require("util"),
  exec = util.promisify(require("child_process").exec),
  imageminMozjpeg = require("imagemin-mozjpeg"),
  zopfli = require("imagemin-zopfli"),
  parallel = require("concurrent-transform"),
  combiner = require("stream-combiner2"),
  filesize = require("filesize"),
  fs = require("fs"),
  os = require("os"),
  $ = require("gulp-load-plugins")(), //load all gulp plugins
  cfg = "./config.json",
  defConfig = {
    in_dir: "./in",
    out_dir: "./out",
    width: 1024,
    height: 1024,
    createWebP: false,
    watermark: "./watermark.png"
  };

function fileExists(path) {
  try {
    return fs.statSync(path).isFile();
  } catch (e) {
    if (e.code == "ENOENT") {
      // no such file or directory. File really does not exist
      //console.log("File does not exist.");
      return false;
    }

    //console.log("Exception fs.statSync (" + path + "): " + e);
    throw e; // something else went wrong, we don't have rights, ...
  }
}

let userConfig = {},
  config = {};

//Load config from config file
if (fileExists(cfg)) {
  userConfig = JSON.parse(fs.readFileSync(cfg));
}
Object.assign(config, defConfig, userConfig);

//special check for watermark file
if (config.watermark.length && !fileExists(config.watermark)) {
  //skip watermark step
  config.watermark = "";
}

let SRC = config.in_dir + "/**/*.{jpg,jpeg,png,svg,gif}",
  DEST = config.out_dir;

/*image processing pipeline
  - Resize the image.
  - Minify the image with imagemin
  - Mozjpeg compression is used for jpg files
*/
const processImages = combiner.obj(
  $.imageResize({
    width: config.width,
    height: config.height
  }),
  config.watermark.length
    ? $.watermark({
        image: config.watermark,
        resize: "100x100"
      })
    : $.util.noop(),
  $.imagemin([
    $.imagemin.gifsicle({ interlaced: true }),
    $.imagemin.jpegtran({ progressive: true }),
    $.imagemin.optipng({ optimizationLevel: 5 }),
    $.imagemin.svgo({ plugins: [{ removeViewBox: true }] }),
    imageminMozjpeg({ progressive: true }),
    zopfli({ more: true })
  ])
);

/*eslint-disable no-console */
processImages.on("error", console.error.bind(console));

/*eslint-enable no-console */

gulp.task("testGM", () => {
  //GraphicsMagick is one of the required binary/library. Check for it's presence
  return exec("gm version");
});

gulp.task("clean", () => {
  return del(config.out_dir + "/**/*"); //delete all destination files, just to be clean
});
gulp.task("processImg", () => {
  // place code here
  return gulp
    .src(SRC, { nocase: true, base: config.in_dir })
    .pipe($.plumber()) //node stream related error handling
    .pipe($.changed(DEST))
    .pipe($.sizediff.start())
    .pipe(parallel(processImages, os.cpus().length))
    .pipe(gulp.dest(DEST))
    .pipe(config.createWebP ? $.webp() : $.util.noop())
    .pipe(gulp.dest(DEST))
    .pipe(
      $.sizediff.stop({
        title: "Saved",
        formatFn: data => {
          return (
            filesize(data.diff) +
            " (" +
            (100 - Math.round((data.diffPercent || 1) * 100)) +
            "%)"
          );
        }
      })
    )
    .pipe($.plumber.stop());
});

gulp.task("default", gulp.series("testGM", "processImg"));
<|endoftext|>


<commit_before>/*global FormFiller, JSONF, jQuery, Logger, Libs */
/*eslint complexity:0 */

// This listens for messages coming from the background page
// This is a long running communication channel
chrome.runtime.onConnect.addListener(function (port) {
  var errors = [];
  var currentError = null;
  var workingOverlayId = "form-o-fill-working-overlay";

  var workingTimeout = null;
  var takingLongTimeout = null;
  var wontFinishTimeout = null;
  var displayTimeout = null;

  Logger.info("[content.js] Got a connection from " + port.name);

  if (port.name !== "FormOFill") {
    return;
  }

  // Returns the HTML used for the throbbing overlay
  var overlayHtml = function(text, isVisible) {
    if (typeof text === "undefined") {
      text = chrome.i18n.getMessage("content_fof_is_working");
    }

    if (typeof isVisible === "undefined") {
      isVisible = false;
    }
    return "
" + text + "
";
  };

  // Hide overlay and cancel all timers
  var hideOverlay = function() {
    jQuery("#" + workingOverlayId).remove();
    clearTimeout(workingTimeout);
    clearTimeout(takingLongTimeout);
    clearTimeout(wontFinishTimeout);
    clearTimeout(displayTimeout);
  };

  // Shows and hides a customized overlay throbber
  var showOverlay = function(message) {
    hideOverlay();
    jQuery("body").find("#" + workingOverlayId).remove().end().append(overlayHtml(message, true));
    displayTimeout = setTimeout(hideOverlay, 3000);
  };

  // Connect to background.js which opens a long running port connection
  port.onMessage.addListener(function (message) {
    Logger.info("[content.js] Got message via port.onMessage : " + JSONF.stringify(message) + " from bg.js");

    // Request to fill one field with a value
    if (message.action === "fillField" && message.selector && message.value) {
      Logger.info("[content.js] Filling " + message.selector + " with value " + JSONF.stringify(message.value) + "; flags : " + JSONF.stringify(message.flags));

      // REMOVE START
      if (message.within && message.within !== null) {
        Logger.info("[content.js] Using within selector " + message.within);
      }

      if (message.beforeData && message.beforeData !== null) {
        Logger.info("[content.js] Also got beforeData = " + JSONF.stringify(message.beforeData));
      }
      // REMOVE END

      currentError = FormFiller.fill(message.selector, message.value, message.beforeData, message.flags, message.meta);

      // Remember the error
      if (typeof currentError !== "undefined" && currentError !== null) {
        Logger.info("[content.js] Got error " + JSONF.stringify(currentError));
        errors.push(currentError);
      }

      // Send a message that we are done filling the form
      if (message.meta.lastField) {
        Logger.info("[content.js] Sending fillFieldFinished since we are done with the last field definition");

        chrome.runtime.sendMessage({
          "action": "fillFieldFinished",
          "errors": JSONF.stringify(errors)
        });
      }
    }

    // request to return all accumulated errors
    if (message.action === "getErrors") {
      Logger.info("[content.js] Returning " + errors.length + " errors to bg.js");
      var response = {
        "action": "getErrors",
        "errors": JSONF.stringify(errors)
      };
      port.postMessage(response);
    }

    // Show Working overlay
    // This should only be triggered for the default "WORKING"
    // overlay.
    // For the customized Lib.halt() message see down below
    if (message.action === "showOverlay" && typeof message.message === "undefined") {
      Logger.info("[content.js] Showing working overlay");
      if (document.querySelectorAll("#" + workingOverlayId).length === 0) {
        jQuery("body").append(overlayHtml());
      }

      // Show working overlay after some time
      workingTimeout = setTimeout(function() {
        jQuery("#" + workingOverlayId).show();
      }, 350);

      // Show another overlay when things take REALLY long to finish
      takingLongTimeout = setTimeout(function () {
        jQuery("#" + workingOverlayId).html(chrome.i18n.getMessage("content_fof_is_working_2"));
      }, 5000);

      // Finally if everything fails, clear overlay after 12 seconds
      wontFinishTimeout = setTimeout(hideOverlay, 12000);
    }

    // Hide the overlay
    if (message.action === "hideWorkingOverlay") {
      Logger.info("[content.js] Hiding working overlay");
      hideOverlay();
    }

    // Show a custom message
    if (message.action === "showMessage" && typeof message.message !== "undefined") {
      showOverlay(message.message);
    }

    // Reload the libraries
    if (message.action === "reloadLibs") {
      Libs.import();
    }

    // Execute setupContent function
    // It has jQuery available
    if (message.action === "setupContent" && message.value) {
      Logger.info("[content.js] Executing setupContent function", message.value);

      // Parse and execute function
      var error = null;

      var setupContentFunctionPr = Promise.resolve(function(r) {
        r();
      });

      try {
        var setupContentFunction = JSONF.parse(message.value);

        // Check if promises should be used:
        if (setupContentFunction.length > 0) {
          setupContentFunctionPr = new Promise(function(resolve) {
            setupContentFunction(resolve);
          });
        } else {
          setupContentFunctionPr = Promise.resolve(setupContentFunction);
        }
      } catch (e) {
        Logger.error("[content.js] error while executing setupContent function");
        error = e.message;
      }

      setupContentFunctionPr.then(function() {
        port.postMessage({action: "setupContentDone", value: JSONF.stringify(error)});
      });
    }

    // Execute teardownContent function
    // It has jQuery available and the context object from value functions and setupContent
    if (message.action === "teardownContent" && message.value) {
      Logger.info("[content.js] Executing teardownContent function", message.value);

      try {
        JSONF.parse(message.value)();
      } catch (e) {
        Logger.error("[content.js] error while executing teardownContent function");
      }
    }
  });

  // Simple one-shot callbacks
  chrome.runtime.onMessage.addListener(function (message, sender, responseCb) {
    Logger.info("[content.js] Got message via runtime.onMessage : " + JSONF.stringify(message) + " from bg.j");

    // This is the content grabber available as context.findHtml() in before functions
    if (message.action === "grabContentBySelector") {
      Logger.info("[content.js] Grabber asked for '" + message.message + "'");
      var domElements = jQuery(message.message).map(function (index, $el) {
        return $el;
      });
      if (domElements.length === 0) {
        responseCb({count: 0, nodes: []});
      } else if (domElements.length === 1) {
        responseCb({count: 1, nodes: domElements[0].outerHTML});
      } else {
        var elements = domElements.map(function(index, el) {
          return el.outerHTML;
        });
        responseCb({count: elements.length, nodes: jQuery.makeArray(elements)});
      }
    }

    // Show a custom message
    // This appears twice in c/content.js because it uses a port and a one-shot
    // listener
    if (message.action === "showOverlay" && typeof message.message !== "undefined") {
      showOverlay(message.message);
      responseCb();
    }

    // Save a variable set in background via storage.set in the context of the content script
    // This makes the storage usable in value functions
    if (message.action === "storageSet" && typeof message.key !== "undefined" && typeof message.value !== "undefined") {
      Logger.info("[content.js] Saving " + message.key + " = " + message.value);
      window.sessionStorage.setItem(message.key, message.value);
    }

    // Inject a
    // Only works with simple data, not functions :(
    if (message.action === "getVar" && typeof message.key !== "undefined") {
      var id = "fof-get-variable-" + message.key.replace(/[^a-zA-Z0-9_-]/g, "-");

      // Insert the node only if not present
      if (document.querySelectorAll("#" + id).length === 0) {
        var elem = document.createElement("script");
        elem.id = id;
        elem.type = "text/javascript";
        elem.dataset.purpose = "Used by Form-O-Fill to access JS variables on the site.";
        elem.className = "fof-get-variable";
        document.head.appendChild(elem);
        elem.innerHTML = "var c = '**JSONF-UNDEFINED**'; try { c = JSON.stringify(" + message.key + "); } catch(e) {}; document.querySelector('#" + id + "').innerHTML = c;";
      }

      // Now return the JSON to the caller
      var jsonNode = document.querySelector("#" + id);
      Logger.info("[content.js] getVar received " + jsonNode.innerText);
      responseCb(JSONF.parse(jsonNode.innerText));

      // ... and remove the node
      jsonNode.remove();
    }

    // Must return true to signal chrome that we do some work
    // asynchronously (see https://developer.chrome.com/extensions/runtime#event-onMessage)
    return true;
  });

});

<commit_msg>restructure promise usage in setupContent<commit_after>/*global FormFiller, JSONF, jQuery, Logger, Libs */
/*eslint complexity:0 */

// This listens for messages coming from the background page
// This is a long running communication channel
chrome.runtime.onConnect.addListener(function (port) {
  var errors = [];
  var currentError = null;
  var workingOverlayId = "form-o-fill-working-overlay";

  var workingTimeout = null;
  var takingLongTimeout = null;
  var wontFinishTimeout = null;
  var displayTimeout = null;

  Logger.info("[content.js] Got a connection from " + port.name);

  if (port.name !== "FormOFill") {
    return;
  }

  // Returns the HTML used for the throbbing overlay
  var overlayHtml = function(text, isVisible) {
    if (typeof text === "undefined") {
      text = chrome.i18n.getMessage("content_fof_is_working");
    }

    if (typeof isVisible === "undefined") {
      isVisible = false;
    }
    return "
" + text + "
";
  };

  // Hide overlay and cancel all timers
  var hideOverlay = function() {
    jQuery("#" + workingOverlayId).remove();
    clearTimeout(workingTimeout);
    clearTimeout(takingLongTimeout);
    clearTimeout(wontFinishTimeout);
    clearTimeout(displayTimeout);
  };

  // Shows and hides a customized overlay throbber
  var showOverlay = function(message) {
    hideOverlay();
    jQuery("body").find("#" + workingOverlayId).remove().end().append(overlayHtml(message, true));
    displayTimeout = setTimeout(hideOverlay, 3000);
  };

  // Connect to background.js which opens a long running port connection
  port.onMessage.addListener(function (message) {
    Logger.info("[content.js] Got message via port.onMessage : " + JSONF.stringify(message) + " from bg.js");

    // Request to fill one field with a value
    if (message.action === "fillField" && message.selector && message.value) {
      Logger.info("[content.js] Filling " + message.selector + " with value " + JSONF.stringify(message.value) + "; flags : " + JSONF.stringify(message.flags));

      // REMOVE START
      if (message.within && message.within !== null) {
        Logger.info("[content.js] Using within selector " + message.within);
      }

      if (message.beforeData && message.beforeData !== null) {
        Logger.info("[content.js] Also got beforeData = " + JSONF.stringify(message.beforeData));
      }
      // REMOVE END

      currentError = FormFiller.fill(message.selector, message.value, message.beforeData, message.flags, message.meta);

      // Remember the error
      if (typeof currentError !== "undefined" && currentError !== null) {
        Logger.info("[content.js] Got error " + JSONF.stringify(currentError));
        errors.push(currentError);
      }

      // Send a message that we are done filling the form
      if (message.meta.lastField) {
        Logger.info("[content.js] Sending fillFieldFinished since we are done with the last field definition");

        chrome.runtime.sendMessage({
          "action": "fillFieldFinished",
          "errors": JSONF.stringify(errors)
        });
      }
    }

    // request to return all accumulated errors
    if (message.action === "getErrors") {
      Logger.info("[content.js] Returning " + errors.length + " errors to bg.js");
      var response = {
        "action": "getErrors",
        "errors": JSONF.stringify(errors)
      };
      port.postMessage(response);
    }

    // Show Working overlay
    // This should only be triggered for the default "WORKING"
    // overlay.
    // For the customized Lib.halt() message see down below
    if (message.action === "showOverlay" && typeof message.message === "undefined") {
      Logger.info("[content.js] Showing working overlay");
      if (document.querySelectorAll("#" + workingOverlayId).length === 0) {
        jQuery("body").append(overlayHtml());
      }

      // Show working overlay after some time
      workingTimeout = setTimeout(function() {
        jQuery("#" + workingOverlayId).show();
      }, 350);

      // Show another overlay when things take REALLY long to finish
      takingLongTimeout = setTimeout(function () {
        jQuery("#" + workingOverlayId).html(chrome.i18n.getMessage("content_fof_is_working_2"));
      }, 5000);

      // Finally if everything fails, clear overlay after 12 seconds
      wontFinishTimeout = setTimeout(hideOverlay, 12000);
    }

    // Hide the overlay
    if (message.action === "hideWorkingOverlay") {
      Logger.info("[content.js] Hiding working overlay");
      hideOverlay();
    }

    // Show a custom message
    if (message.action === "showMessage" && typeof message.message !== "undefined") {
      showOverlay(message.message);
    }

    // Reload the libraries
    if (message.action === "reloadLibs") {
      Libs.import();
    }

    // Execute setupContent function
    // It has jQuery available
    if (message.action === "setupContent" && message.value) {
      Logger.info("[content.js] Executing setupContent function", message.value);

      // Parse and execute function
      var error = null;

      try {
        var setupContentFunction = JSONF.parse(message.value);

        // Check if promises should be used:
        if (setupContentFunction.length > 0) {
          var setupContentFunctionPr = new Promise(function(resolve) {
            setupContentFunction(resolve);
          });

          setupContentFunctionPr.then(function() {
            port.postMessage({action: "setupContentDone", value: JSONF.stringify(error)});
          });
        } else {
          setupContentFunction();
          port.postMessage({action: "setupContentDone", value: JSONF.stringify(error)});
        }
      } catch (e) {
        Logger.error("[content.js] error while executing setupContent function");
        error = e.message;
      }

    }

    // Execute teardownContent function
    // It has jQuery available and the context object from value functions and setupContent
    if (message.action === "teardownContent" && message.value) {
      Logger.info("[content.js] Executing teardownContent function", message.value);

      try {
        JSONF.parse(message.value)();
      } catch (e) {
        Logger.error("[content.js] error while executing teardownContent function");
      }
    }
  });

  // Simple one-shot callbacks
  chrome.runtime.onMessage.addListener(function (message, sender, responseCb) {
    Logger.info("[content.js] Got message via runtime.onMessage : " + JSONF.stringify(message) + " from bg.j");

    // This is the content grabber available as context.findHtml() in before functions
    if (message.action === "grabContentBySelector") {
      Logger.info("[content.js] Grabber asked for '" + message.message + "'");
      var domElements = jQuery(message.message).map(function (index, $el) {
        return $el;
      });
      if (domElements.length === 0) {
        responseCb({count: 0, nodes: []});
      } else if (domElements.length === 1) {
        responseCb({count: 1, nodes: domElements[0].outerHTML});
      } else {
        var elements = domElements.map(function(index, el) {
          return el.outerHTML;
        });
        responseCb({count: elements.length, nodes: jQuery.makeArray(elements)});
      }
    }

    // Show a custom message
    // This appears twice in c/content.js because it uses a port and a one-shot
    // listener
    if (message.action === "showOverlay" && typeof message.message !== "undefined") {
      showOverlay(message.message);
      responseCb();
    }

    // Save a variable set in background via storage.set in the context of the content script
    // This makes the storage usable in value functions
    if (message.action === "storageSet" && typeof message.key !== "undefined" && typeof message.value !== "undefined") {
      Logger.info("[content.js] Saving " + message.key + " = " + message.value);
      window.sessionStorage.setItem(message.key, message.value);
    }

    // Inject a
    // Only works with simple data, not functions :(
    if (message.action === "getVar" && typeof message.key !== "undefined") {
      var id = "fof-get-variable-" + message.key.replace(/[^a-zA-Z0-9_-]/g, "-");

      // Insert the node only if not present
      if (document.querySelectorAll("#" + id).length === 0) {
        var elem = document.createElement("script");
        elem.id = id;
        elem.type = "text/javascript";
        elem.dataset.purpose = "Used by Form-O-Fill to access JS variables on the site.";
        elem.className = "fof-get-variable";
        document.head.appendChild(elem);
        elem.innerHTML = "var c = '**JSONF-UNDEFINED**'; try { c = JSON.stringify(" + message.key + "); } catch(e) {}; document.querySelector('#" + id + "').innerHTML = c;";
      }

      // Now return the JSON to the caller
      var jsonNode = document.querySelector("#" + id);
      Logger.info("[content.js] getVar received " + jsonNode.innerText);
      responseCb(JSONF.parse(jsonNode.innerText));

      // ... and remove the node
      jsonNode.remove();
    }

    // Must return true to signal chrome that we do some work
    // asynchronously (see https://developer.chrome.com/extensions/runtime#event-onMessage)
    return true;
  });

});

<|endoftext|>


<commit_before>/* =========================================================================
 * Dependencies
 * ========================================================================= */
const packageJson = require('./package.json');

const gulp = require('gulp');
const jshint = require('gulp-jshint');
const less = require('gulp-less');
const sh = require('shelljs');
const runSequence = require('run-sequence');
const mocha = require('gulp-mocha');
const _ = require('underscore');
const childProcess = require('child_process');

const appConfig = require('src/config/appConfig');

require('gulp-task-list')(gulp);

/* =========================================================================
 * Constants
 * ========================================================================= */
const APP_NAME = packageJson.name;

const SRC_DIR = 'src';
const DOCS_DIR = 'docs';
const RELEASE_DIR = 'release';
const RELEASE_IGNORE_PKGS = [ //any npm packages that should not be included in the release
  'electron-packager',
  'electron-prebuilt',
  'electron-connect',
  'gulp|gulp-jshint',
  'gulp-less',
  'gulp-mocha',
  'gulp-task-list',
  'jshint-stylish',
  'run-sequence',
  'bower',
  'should',
  'sinon',
  'supertest'
].join('|');
const RELEASE_IMAGE_ICON = __dirname + '/src/ui/images/logo_icon.icns';

const LESSOPTIONS = {
  compress: false
};

const MOCHA_SETTINGS = {
  reporter: 'spec',
  growl: true,
  useColors: true,
  useInlineDiffs: true
};

/* =========================================================================
 * Tasks
 * ========================================================================= */
/**
 * List gulp tasks
 */
gulp.task('?', function(next) {
  sh.exec('gulp task-list');
  next();
});

gulp.task('clean', function(next) {
  sh.rm('-rf', RELEASE_DIR);
  next();
});

gulp.task('css', function() {
  return gulp.src(SRC_DIR + '/ui/less/main.less')
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(SRC_DIR + '/ui/css'));
});

gulp.task('site-css', function() {
  return gulp.src(DOCS_DIR + '/less/main.less')
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(DOCS_DIR + '/css'));
});

gulp.task('jshint', function() {
  return _init(gulp.src(['src/**/*.js', '!src/ui/vendor/**/*.js']))
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('release', function(done) {
  runSequence('build', 'pre-release', function() {
    var cmd = './node_modules/.bin/electron-packager ' + '.' + ' ' + APP_NAME + ' --out=' + RELEASE_DIR + ' --platform=darwin  --arch=x64 --version=0.30.2 --ignore="node_modules/(' + RELEASE_IGNORE_PKGS + ')" --icon=' + RELEASE_IMAGE_ICON;

    console.log(cmd);

    sh.exec(cmd, done);
  });
});

gulp.task('pre-release', function(done) {
  var cmd = './node_modules/.bin/electron-compile . -v -t=' + appConfig.builddir;

  console.log(cmd);

  sh.exec(cmd, done);
});

gulp.task('build', ['clean', 'css']);

gulp.task('serve', ['build'], function() {

  var env = _.extend({}, process.env);
  // env.NODE_ENV = 'production';

  var child = childProcess.spawn('./node_modules/.bin/electron', ['./'], {
    env: env
  });

  child.stdout.on('data',
    function(data) {
      console.log('tail output: ' + data);
    }
  );

  child.on('exit', function(exitCode) {
    console.log('Child exited with code: ' + exitCode);
  });
});

gulp.task('serve-site', function() {
  gulp.watch(DOCS_DIR + '/less/*.less', function() {
    gulp.src(DOCS_DIR + '/less/main.less')
      .pipe(less(LESSOPTIONS))
      .pipe(gulp.dest(DOCS_DIR + '/css'));
  });
});

gulp.task('default', ['serve']);

gulp.task('test', function(next) {
  runSequence('jshint', 'test-int', 'test-unit', function() {
    process.exit(0);
    next();
  });
});

gulp.task('test-int', function() {
  return gulp.src('tests/integration/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

gulp.task('test-unit', function() {
  return gulp.src('tests/unit/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

/* =========================================================================
 * Helper Functions
 * ========================================================================= */
function _init(stream) {
  stream.setMaxListeners(0);
  return stream;
}
<commit_msg>use child_process spawn instead of sh.exec - that way we can set NODE_ENV when releasing<commit_after>/* =========================================================================
 * Dependencies
 * ========================================================================= */
const packageJson = require('./package.json');

const gulp = require('gulp');
const jshint = require('gulp-jshint');
const less = require('gulp-less');
const sh = require('shelljs');
const runSequence = require('run-sequence');
const mocha = require('gulp-mocha');
const _ = require('underscore');
const childProcess = require('child_process');

const appConfig = require('src/config/appConfig');

require('gulp-task-list')(gulp);

/* =========================================================================
 * Constants
 * ========================================================================= */
const APP_NAME = packageJson.name;

const SRC_DIR = 'src';
const DOCS_DIR = 'docs';
const RELEASE_DIR = 'release';
const RELEASE_IGNORE_PKGS = [ //any npm packages that should not be included in the release
  'electron-packager',
  'electron-prebuilt',
  'electron-connect',
  'gulp|gulp-jshint',
  'gulp-less',
  'gulp-mocha',
  'gulp-task-list',
  'jshint-stylish',
  'run-sequence',
  'bower',
  'babel',
  'should',
  'sinon',
  'supertest'
].join('|');
const RELEASE_IMAGE_ICON = __dirname + '/src/ui/images/logo_icon.icns';

const LESSOPTIONS = {
  compress: false
};

const MOCHA_SETTINGS = {
  reporter: 'spec',
  growl: true,
  useColors: true,
  useInlineDiffs: true
};

/* =========================================================================
 * Tasks
 * ========================================================================= */
/**
 * List gulp tasks
 */
gulp.task('?', function(next) {
  sh.exec('gulp task-list');
  next();
});

gulp.task('clean', function(next) {
  sh.rm('-rf', RELEASE_DIR);
  next();
});

gulp.task('css', function() {
  return gulp.src(SRC_DIR + '/ui/less/main.less')
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(SRC_DIR + '/ui/css'));
});

gulp.task('site-css', function() {
  return gulp.src(DOCS_DIR + '/less/main.less')
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(DOCS_DIR + '/css'));
});

gulp.task('jshint', function() {
  return _init(gulp.src(['src/**/*.js', '!src/ui/vendor/**/*.js']))
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('release', function() {
  runSequence('build', function() {
    var env = _.extend({}, process.env);
    env.NODE_ENV = 'production';

    var child = childProcess.spawn('./node_modules/.bin/electron-packager', [
      '.',
      APP_NAME,
      '--out',
      RELEASE_DIR,
      '--platform',
      'darwin',
      '--arch',
      'x64',
      '--version',
      '0.30.2',
      '--ignore', ('node_modules/(' + RELEASE_IGNORE_PKGS + ')'),
      '--icon',
      RELEASE_IMAGE_ICON
    ], {
      env: env
    });

    child.stdout.on('data',
      function(data) {
        console.log('tail output: ' + data);
      }
    );

    child.on('exit', function(exitCode) {
      console.log('Child exited with code: ' + exitCode);
    });
  });
});

/*
 * @task pre-release - compile ES6 to ES5 using babel
 */
gulp.task('pre-release', function() {
  var env = _.extend({}, process.env);
  env.NODE_ENV = 'production';

  var child = childProcess.spawn('./node_modules/.bin/electron-compile', [
    '.',
    '-v',
    '-t',
    appConfig.builddir
  ], {
    env: env
  });

  child.stdout.on('data',
    function(data) {
      console.log('tail output: ' + data);
    }
  );

  child.on('exit', function(exitCode) {
    console.log('Child exited with code: ' + exitCode);
  });
});

gulp.task('build', ['clean', 'css']);

gulp.task('serve', ['build'], function() {

  var env = _.extend({}, process.env);
  // env.NODE_ENV = 'production';

  var child = childProcess.spawn('./node_modules/.bin/electron', ['./'], {
    env: env
  });

  child.stdout.on('data',
    function(data) {
      console.log('tail output: ' + data);
    }
  );

  child.on('exit', function(exitCode) {
    console.log('Child exited with code: ' + exitCode);
  });
});

gulp.task('serve-site', function() {
  gulp.watch(DOCS_DIR + '/less/*.less', function() {
    gulp.src(DOCS_DIR + '/less/main.less')
      .pipe(less(LESSOPTIONS))
      .pipe(gulp.dest(DOCS_DIR + '/css'));
  });
});

gulp.task('default', ['serve']);

gulp.task('test', function(next) {
  runSequence('jshint', 'test-int', 'test-unit', function() {
    process.exit(0);
    next();
  });
});

gulp.task('test-int', function() {
  return gulp.src('tests/integration/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

gulp.task('test-unit', function() {
  return gulp.src('tests/unit/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

/* =========================================================================
 * Helper Functions
 * ========================================================================= */
function _init(stream) {
  stream.setMaxListeners(0);
  return stream;
}
<|endoftext|>


<commit_before>/**
 * Created by nuintun on 2015/5/5.
 */

'use strict';

var path = require('path');
var gulp = require('gulp');
var rimraf = require('del');
var transport = require('gulp-cmd');
var uglify = require('gulp-uglify');
var css = require('gulp-minify-css');
var plumber = require('gulp-plumber');
var colors = transport.colors;

// alias
var alias = {
  'jquery': 'base/jquery/1.11.2/jquery',
  'base': 'base/base/1.2.0/base',
  'class': 'base/class/1.2.0/class',
  'events': 'base/events/1.2.0/events',
  'widget': 'base/widget/1.2.0/widget',
  'template': 'base/template/3.0.3/template',
  'templatable': 'base/templatable/0.10.0/templatable',
  'iframe-shim': 'util/iframe-shim/1.1.0/iframe-shim',
  'position': 'util/position/1.1.0/position',
  'messenger': 'util/messenger/2.1.0/messenger',
  'mask': 'common/overlay/1.2.0/mask',
  'overlay': 'common/overlay/1.2.0/overlay',
  'dialog': 'common/dialog/1.5.1/dialog',
  'confirmbox': 'common/dialog/1.5.1/confirmbox'
};

var startTime = Date.now();

// complete callback
function complete(){
  var now = new Date();

  console.log(
    '  %s [%s] build complete ... %s%s',
    colors.cyan.bold('gulp-cmd'),
    now.toLocaleString(),
    colors.green(now - startTime),
    colors.cyan('ms')
  );
}

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

// runtime task
gulp.task('runtime', ['clean'], function (){
  gulp.src('assets/loader/**/*.js', { base: 'assets' })
    .pipe(uglify())
    .pipe(gulp.dest('online'));

  gulp.src('assets/?(loader|images)/**/*.!(js)', { base: 'assets' })
    .pipe(gulp.dest('online'));
});

// online task
gulp.task('online', ['runtime'], function (){
  // all js
  gulp.src('assets/js/**/*.js', { base: 'assets/js' })
    .pipe(transport({
      alias: alias,
      ignore: ['jquery'],
      include: function (id){
        return id.indexOf('view') === 0 ? 'all' : 'relative';
      },
      css: {
        onpath: function (path){
          return path.replace('assets/', 'online/')
        }
      }
    }))
    .pipe(uglify())
    .pipe(gulp.dest('online/js'))
    .on('end', complete);

  // other file
  gulp.src('assets/js/**/*.!(js|css|json|tpl|html)')
    .pipe(gulp.dest('online/js'));

  // css
  gulp.src('assets/css/**/*.*')
    .pipe(css({ compatibility: 'ie8' }))
    .pipe(gulp.dest('online/css'));
});

// develop task
gulp.task('default', ['runtime'], function (){
  // all file
  gulp.src('assets/js/**/*.*', { base: 'assets/js' })
    .pipe(transport({
      alias: alias,
      include: 'self',
      oncsspath: function (path){
        return path.replace('assets/', 'online/')
      }
    }))
    .pipe(gulp.dest('online/js'))
    .on('end', complete);

  gulp.src('assets/css/**/*.*', { base: 'assets' })
    .pipe(gulp.dest('online'));
});

// develop watch task
gulp.task('watch', ['default'], function (){
  var base = path.join(process.cwd(), 'assets');

  // watch all file
  gulp.watch('assets/js/**/*.*', function (e){
    if (e.type === 'deleted') {
      rimraf(path.resolve('online', path.relative(base, e.path)));
    } else {
      startTime = Date.now();

      gulp.src(e.path, { base: 'assets/js' })
        .pipe(plumber())
        .pipe(transport({
          alias: alias,
          include: 'self',
          cache: false,
          oncsspath: function (path){
            return path.replace('assets/', 'online/')
          }
        }))
        .pipe(gulp.dest('online/js'))
        .on('end', complete);
    }
  });

  // watch all file
  gulp.watch('assets/?(images|loader|css)/**/*.*', function (e){
    if (e.type === 'deleted') {
      rimraf(path.resolve('online', path.relative(base, e.path)));
    } else {
      startTime = Date.now();

      gulp.src(e.path, { base: 'assets' })
        .pipe(plumber())
        .pipe(gulp.dest('online'))
        .on('end', complete);
    }
  });
});
<commit_msg>add source<commit_after>/**
 * Created by nuintun on 2015/5/5.
 */

'use strict';

var path = require('path');
var gulp = require('gulp');
var rimraf = require('del');
var transport = require('gulp-cmd');
var uglify = require('gulp-uglify');
var css = require('gulp-minify-css');
var plumber = require('gulp-plumber');
var colors = transport.colors;

// alias
var alias = {
  'jquery': 'base/jquery/1.11.2/jquery',
  'base': 'base/base/1.2.0/base',
  'class': 'base/class/1.2.0/class',
  'events': 'base/events/1.2.0/events',
  'widget': 'base/widget/1.2.0/widget',
  'template': 'base/template/3.0.3/template',
  'templatable': 'base/templatable/0.10.0/templatable',
  'iframe-shim': 'util/iframe-shim/1.1.0/iframe-shim',
  'position': 'util/position/1.1.0/position',
  'messenger': 'util/messenger/2.1.0/messenger',
  'mask': 'common/overlay/1.2.0/mask',
  'overlay': 'common/overlay/1.2.0/overlay',
  'dialog': 'common/dialog/1.5.1/dialog',
  'confirmbox': 'common/dialog/1.5.1/confirmbox'
};

var startTime = Date.now();

// complete callback
function complete(){
  var now = new Date();

  console.log(
    '  %s [%s] build complete ... %s%s',
    colors.cyan.bold('gulp-cmd'),
    now.toLocaleString(),
    colors.green(now - startTime),
    colors.cyan('ms')
  );
}

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

// runtime task
gulp.task('runtime', ['clean'], function (){
  gulp.src('assets/loader/**/*.js', { base: 'assets' })
    .pipe(uglify())
    .pipe(gulp.dest('online'));

  gulp.src('assets/?(loader|images)/**/*.!(js)', { base: 'assets' })
    .pipe(gulp.dest('online'));
});

// online task
gulp.task('online', ['runtime'], function (){
  // all js
  gulp.src('assets/js/**/*.js', { base: 'assets/js' })
    .pipe(transport({
      alias: alias,
      ignore: ['jquery'],
      include: function (id){
        return id.indexOf('view') === 0 ? 'all' : 'relative';
      },
      css: {
        onpath: function (path){
          return path.replace('assets/', 'online/')
        }
      }
    }))
    .pipe(uglify())
    .pipe(gulp.dest('online/js'))
    .on('end', complete);

  // other file
  gulp.src('assets/js/**/*.!(js|css|json|tpl|html)')
    .pipe(gulp.dest('online/js'));

  // css
  gulp.src('assets/css/**/*.*')
    .pipe(css({ compatibility: 'ie8' }))
    .pipe(gulp.dest('online/css'));
});

// develop task
gulp.task('default', ['runtime'], function (){
  // all file
  gulp.src('assets/js/**/*.*', { base: 'assets/js' })
    .pipe(transport({
      alias: alias,
      include: 'self',
      css: {
        onpath: function (path){
          return path.replace('assets/', 'online/')
        }
      }
    }))
    .pipe(gulp.dest('online/js'))
    .on('end', complete);

  gulp.src('assets/css/**/*.*', { base: 'assets' })
    .pipe(gulp.dest('online'));
});

// develop watch task
gulp.task('watch', ['default'], function (){
  var base = path.join(process.cwd(), 'assets');

  // watch all file
  gulp.watch('assets/js/**/*.*', function (e){
    if (e.type === 'deleted') {
      rimraf(path.resolve('online', path.relative(base, e.path)));
    } else {
      startTime = Date.now();

      gulp.src(e.path, { base: 'assets/js' })
        .pipe(plumber())
        .pipe(transport({
          alias: alias,
          include: 'self',
          cache: false,
          css: {
            onpath: function (path){
              return path.replace('assets/', 'online/')
            }
          }
        }))
        .pipe(gulp.dest('online/js'))
        .on('end', complete);
    }
  });

  // watch all file
  gulp.watch('assets/?(images|loader|css)/**/*.*', function (e){
    if (e.type === 'deleted') {
      rimraf(path.resolve('online', path.relative(base, e.path)));
    } else {
      startTime = Date.now();

      gulp.src(e.path, { base: 'assets' })
        .pipe(plumber())
        .pipe(gulp.dest('online'))
        .on('end', complete);
    }
  });
});
<|endoftext|>


<commit_before>"use strict";

var Builder = require('systemjs-builder');
var del = require('del');
var fs = require('fs');
var path = require('path');
var join = path.join;
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var superstatic = require('superstatic');

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();

// Functions

function root(_path) {
  return (_path.indexOf('!')>=0 ? '!':'') + path.join(__dirname, _path);
}

function rootDir(dir) {
  return dir.map(root);
}

function transformPath() {
  return function (filepath) {
    arguments[0] = join('vendor', filepath.split('/').pop());
    return $.inject.transform.apply($.inject.transform, arguments);
  };
}

// Configuration

var DEST_FOLDER = '__build__';
var serverport = 3000;
var paths = {

  config: {
    tsconfig: root('src/tsconfig.json')
  },

  dest: {
    folder: root(DEST_FOLDER),
    vendor: root(DEST_FOLDER + '/vendor'),
    fonts: root(DEST_FOLDER + '/fonts'),
    images: root(DEST_FOLDER + '/images'),
    styles: root(DEST_FOLDER + '/styles'),
    test: root('test')
  },

  src: {
    everything: root('src/app/**'),
    index: root('src/app/index.html'),
    ts: rootDir([
      'src/app/**/*.ts',
      '!app/init.ts',
      '!app/**/*_spec.ts'
    ]),
    html: rootDir([
      'src/app/**/*.html'
    ]),
    styles: rootDir([
      'src/app/styles/**/*.css'
    ]),
    images: rootDir([
      'images/**/*'
    ]),
    fonts: rootDir([
      'fonts/**/*'
    ]),
    vendor: [
      'node_modules/angular2/node_modules/traceur/bin/traceur-runtime.js',
      'node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.js',
      'node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.js.map',
      'node_modules/reflect-metadata/Reflect.js',
      'node_modules/reflect-metadata/Reflect.js.map',
      'node_modules/systemjs/dist/system.src.js',

      'node_modules/angular2/bundles/angular2.dev.js',
      'node_modules/angular2/bundles/router.dev.js',
      'node_modules/angular2/bundles/http.dev.js',

      'node_modules/chance/dist/chance.min.js',

      'bower_components/material-design-lite/material.js',
      'bower_components/material-design-lite/material.css',

      'src/app/styles/app.css',
      'src/app/system.config.js'
    ]
  },

  clean: {
    dev: DEST_FOLDER,
    app: rootDir([
      DEST_FOLDER,
      '!' + DEST_FOLDER + '/vendor'
    ]),
    typings: root('tsd_typings/'),
    everything: rootDir([
      DEST_FOLDER
    ])
  }
};

var tsProject = $.typescript.createProject(paths.config.tsconfig, {
  typescript: require('typescript')
});

// Default task

gulp.task('default', ['serve']);

// Clean

gulp.task('clean', function (done) {
  del(paths.clean.everything, done);
});

gulp.task('clean:typings', function(done) {
  del(paths.clean.typings, done);
});

gulp.task('clean:app', function(done) {
  del(paths.clean.app, done);
});

gulp.task('clean:dev', function(done) {
  del(paths.clean.dev, done);
});

// Build dev

gulp.task('build:vendor', function () {
  return gulp.src(paths.src.vendor)
    .pipe(gulp.dest(paths.dest.vendor));
});

gulp.task('build:fonts', function () {
  return gulp.src(paths.src.fonts)
    .pipe(gulp.dest(paths.dest.fonts));
});

gulp.task('build:images', function () {
  return gulp.src(paths.src.images)
    .pipe(gulp.dest(paths.dest.images));
});

gulp.task('build:typescript', function () {
  var result = gulp.src(paths.src.ts)
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.typescript(tsProject));

  return result.js
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(paths.dest.folder));
});

gulp.task('build:html', function () {
  return gulp.src(paths.src.html)
    .pipe(gulp.dest(paths.dest.folder))
    .pipe(browserSync.stream());
});

gulp.task('build:styles', function () {
  return gulp.src(paths.src.styles)
    .pipe(gulp.dest(paths.dest.styles))
    .pipe(browserSync.stream());
});

gulp.task('build:index', function () {
  var target = gulp.src(paths.src.index);
  var sources = gulp.src(paths.src.vendor, { read: false, relative: true});
  return target.pipe($.inject(sources, {transform: transformPath()}))
    .pipe(gulp.dest(paths.dest.folder));
});

gulp.task('build:app', function (done) {
  runSequence('build:fonts', 'build:images', 'build:html', 'build:styles', 'build:typescript', 'build:index', done);
});

gulp.task('build', function (done) {
  runSequence('clean', 'build:app', 'build:vendor', done);
});

// Post install (NPM lifecycle)

gulp.task('install:typings', ['clean:typings'], $.shell.task([
  'tsd reinstall --overwrite',
  'tsd link',
  'tsd rebundle'
]));

gulp.task('postinstall', function (done) {
  runSequence('install:typings', done);
});

// Serve dev.

gulp.task('serve', ['build'], function () {

  browserSync.init({
    port: serverport,
    files: paths.dest.folder,
    injectChanges: true,
    logFileChanges: true,
    logLevel: 'info',
    logPrefix: 'DevFest-2015',
    notify: true,
    server: {
      baseDir: DEST_FOLDER
    }
  });

  $.watch([].concat(paths.src.ts, paths.src.html, paths.src.styles, paths.src.vendor), function() {
    gulp.start('build');
  }).on('change', browserSync.reload);

});
<commit_msg>fix browser sync issues after TS transpilation<commit_after>"use strict";

var Builder = require('systemjs-builder');
var del = require('del');
var fs = require('fs');
var path = require('path');
var join = path.join;
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var superstatic = require('superstatic');

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();

// Functions

function root(_path) {
  return (_path.indexOf('!')>=0 ? '!':'') + path.join(__dirname, _path);
}

function rootDir(dir) {
  return dir.map(root);
}

function transformPath() {
  return function (filepath) {
    arguments[0] = join('vendor', filepath.split('/').pop());
    return $.inject.transform.apply($.inject.transform, arguments);
  };
}

// Configuration

var DEST_FOLDER = '__build__';
var serverport = 3000;
var paths = {

  config: {
    tsconfig: root('src/tsconfig.json')
  },

  dest: {
    folder: root(DEST_FOLDER),
    vendor: root(DEST_FOLDER + '/vendor'),
    fonts: root(DEST_FOLDER + '/fonts'),
    images: root(DEST_FOLDER + '/images'),
    styles: root(DEST_FOLDER + '/styles'),
    test: root('test')
  },

  src: {
    everything: root('src/app/**'),
    index: root('src/app/index.html'),
    ts: rootDir([
      'src/app/**/*.ts',
      '!app/init.ts',
      '!app/**/*_spec.ts'
    ]),
    html: rootDir([
      'src/app/**/*.html'
    ]),
    styles: rootDir([
      'src/app/styles/**/*.css'
    ]),
    images: rootDir([
      'images/**/*'
    ]),
    fonts: rootDir([
      'fonts/**/*'
    ]),
    vendor: [
      'node_modules/angular2/node_modules/traceur/bin/traceur-runtime.js',
      'node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.js',
      'node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.js.map',
      'node_modules/reflect-metadata/Reflect.js',
      'node_modules/reflect-metadata/Reflect.js.map',
      'node_modules/systemjs/dist/system.src.js',

      'node_modules/angular2/bundles/angular2.dev.js',
      'node_modules/angular2/bundles/router.dev.js',
      'node_modules/angular2/bundles/http.dev.js',

      'node_modules/chance/dist/chance.min.js',

      'bower_components/material-design-lite/material.js',
      'bower_components/material-design-lite/material.css',

      'src/app/styles/app.css',
      'src/app/system.config.js'
    ]
  },

  clean: {
    dev: DEST_FOLDER,
    app: rootDir([
      DEST_FOLDER,
      '!' + DEST_FOLDER + '/vendor'
    ]),
    typings: root('tsd_typings/'),
    everything: rootDir([
      DEST_FOLDER
    ])
  }
};

var tsProject = $.typescript.createProject(paths.config.tsconfig, {
  typescript: require('typescript')
});

// Default task

gulp.task('default', ['serve']);

// Clean

gulp.task('clean', function (done) {
  del(paths.clean.everything, done);
});

gulp.task('clean:typings', function(done) {
  del(paths.clean.typings, done);
});

gulp.task('clean:app', function(done) {
  del(paths.clean.app, done);
});

gulp.task('clean:dev', function(done) {
  del(paths.clean.dev, done);
});

// Build dev

gulp.task('build:vendor', function () {
  return gulp.src(paths.src.vendor)
    .pipe(gulp.dest(paths.dest.vendor))
    .pipe(browserSync.stream());
});

gulp.task('build:fonts', function () {
  return gulp.src(paths.src.fonts)
    .pipe(gulp.dest(paths.dest.fonts))
    .pipe(browserSync.stream());
});

gulp.task('build:images', function () {
  return gulp.src(paths.src.images)
    .pipe(gulp.dest(paths.dest.images))
    .pipe(browserSync.stream());
});

gulp.task('build:typescript', function () {
  var result = gulp.src(paths.src.ts)
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.typescript(tsProject));

  return result.js
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(paths.dest.folder))
    .pipe(browserSync.stream());
});

gulp.task('build:html', function () {
  return gulp.src(paths.src.html)
    .pipe(gulp.dest(paths.dest.folder))
    .pipe(browserSync.stream());
});

gulp.task('build:styles', function () {
  return gulp.src(paths.src.styles)
    .pipe(gulp.dest(paths.dest.styles))
    .pipe(browserSync.stream());
});

gulp.task('build:index', function () {
  var target = gulp.src(paths.src.index);
  var sources = gulp.src(paths.src.vendor, { read: false, relative: true});

  return target.pipe($.inject(sources, {transform: transformPath()}))
    .pipe(gulp.dest(paths.dest.folder))
    .pipe(browserSync.stream());
});

gulp.task('build:app', function (done) {
  runSequence('build:fonts', 'build:images', 'build:html', 'build:styles', 'build:typescript', 'build:index', done);
});

gulp.task('build', function (done) {
  runSequence('clean', 'build:app', 'build:vendor', done);
});

// Post install (NPM lifecycle)

gulp.task('install:typings', ['clean:typings'], $.shell.task([
  'tsd reinstall --overwrite',
  'tsd link',
  'tsd rebundle'
]));

gulp.task('postinstall', function (done) {
  runSequence('install:typings', done);
});

// Serve dev.

gulp.task('serve', ['build'], function () {

  browserSync.init({
    port: serverport,
    watchOptions: {
      awaitWriteFinish: {
        stabilityThreshold: 2000,
        pollInterval: 100
      }
    },
    files: paths.dest.folder,
    injectChanges: true,
    logFileChanges: true,
    logLevel: 'info',
    logPrefix: 'DevFest-2015',
    notify: true,
    server: {
      baseDir: DEST_FOLDER
    }
  });

  gulp.watch(paths.src.ts, ['build:typescript']);
  gulp.watch(paths.src.html, ['build:html']);
  gulp.watch(paths.src.styles, ['build:styles']);
  gulp.watch(paths.src.vendor, ['build:vendor']);
  gulp.watch(paths.src.index, ['build:index']);

  /*gulp.watch([].concat(paths.src.ts, paths.src.html, paths.src.styles, paths.src.vendor), function() {
    gulp.start('build');
  }).on('change', browserSync.reload);*/

});
<|endoftext|>