<commit_before>(function()
{
    if (!window.requestAnimationFrame)
    {
        window.requestAnimationFrame = window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        window.oRequestAnimationFrame      ||
        window.msRequestAnimationFrame     ||

        function(callback, element)
        {
            window.setTimeout(callback, 1000 / FRAME_RATE);
        }
    }
})();
console.log("Animation frame requested.");

var canvas = document.getElementById("canvas");
console.log("Canvas loaded.");
var context = (check(canvas)) ? canvas.getContext("2d") : null;
console.log("Context loaded.");
check(context);

canvas.style.background = "rgb(52, 55, 60)";
console.log("Background colour set to " + canvas.style.background + ".");

var boxes = [];
var heldKeys = [];
const FRAMERATE = 60;
const BOX_SIZE = 20;
const GRAVITY = 0.9;
const JUMP_VELOCITY = 10;
const SPEED = 10;
const ACCELERATION = 1;
const FRICTION = 0.9;

var playerSpawnX, playerSpawnY;
playerSpawnX = playerSpawnY = 0;
console.log("Values set for properties.");

player = new Player(0, 0, BOX_SIZE, BOX_SIZE * 2, "white");
console.log("Player created.");
player.toString();
check(player);

box = new Box(0, canvas.height - BOX_SIZE, canvas.width, BOX_SIZE, "red");

function Player(xPos, yPos, _width, _height, _renderColour) {
   this.x = xPos;
   this.y = yPos;
   this.width = _width;
   this.height = _height;
   this.colour = _renderColour;
   this.xVelocity = 0;
   this.yVelocity = 0;
   this.grounded = false;
   this.jumping = false;

   this.toString = function() {
      console.log("Player's position: (" + this.x + ", " + this.y + ")");
      console.log("Player's dimensions: (" + this.width + ", " + this.height + ")");
      console.log("Player's colour: " + this.colour);
      console.log("Player's velocity: (" + this.xVelocity + ", " + this.yVelocity + ")");
   }

   this.respawn = function() {
      this.x = playerSpawnX;
      this.y = playerSpawnY;
   }

   this.respawn = function(x, y) {
      this.x = x;
      this.y = y;
   }

   this.setVelocity = function(x, y) {
      this.xVelocity = x;
      this.yVelocity = y;
   }

   this.calculateVelocity = function() {
      if(input.getKeyDown(keyCode.upArrow) && this.grounded)
         this.setVelocity(0, -SPEED);

      if(input.getKeyDown(keyCode.rightArrow))
         this.setVelocity(SPEED, 0);

      if(input.getKeyDown(keyCode.leftArrow))
         this.setVelocity(-SPEED, 0);
   }

   this.adjustVelocityByCollision = function(toTest) {
      if((collisionChecker.testCollision(this, toTest) === "b") || this.y === canvas.height - BOX_SIZE) {
         this.setVelocity(this.xVelocity, 0);
         this.grounded = true;
         this.jumping = false;
      }
   }

   this.applyVelocity = function() {
      this.x += this.xVelocity;
      this.y += this.yVelocity;
      this.y += GRAVITY;
   }

   this.resetVelocity = function() {
      this.xVelocity = 0;
      this.yVelocity = 0;
   }

   this.constrain = function() {
      this.x = clamp(this.x, 0, canvas.width - BOX_SIZE);
      this.y = clamp(this.y, 0, canvas.height - BOX_SIZE);
   }

   this.update = function() {
      this.resetVelocity();
      this.calculateVelocity();
      this.applyVelocity();
      this.constrain();
      this.resetVelocity();
   }

   this.move = function() {
      if(input.getKeyDown(keyCode.upArrow) || input.getKeyDown(keyCode.spacebarKey)) {
         if(!player.jumping && player.grounded) {
            player.yVelocity = -JUMP_VELOCITY;
            player.grounded = false;
            player.jumping = true;
         }
      }

      if(input.getKeyDown(keyCode.leftArrow) && player.xVelocity > -SPEED)
         player.xVelocity -= ACCELERATION;

      if(input.getKeyDown(keyCode.rightArrow) && player.xVelocity < SPEED)
         player.xVelocity += ACCELERATION;

      player.xVelocity *= FRICTION;
      player.yVelocity += GRAVITY;

      player.y += player.yVelocity;
      player.x += player.xVelocity;
   }

   this.render = function() {
      context.fillStyle = this.colour;
      context.fillRect(this.x, this.y, this.width, this.height);
   }
}

function Box(xPos, yPos, _width, _height, _renderColour) {
   this.x = xPos;
   this.y = yPos;
   this.width = _width;
   this.height = _height;
   this.colour = _renderColour;

   boxes.push(this);

   this.toString = function() {
      console.log("Box's position: (" + this.x + ", " + this.y + ")");
      console.log("Box's dimensions: (" + this.width + ", " + this.height + ")");
      console.log("Box's colour: " + this.colour);
   }

   this.constrain = function() {
      this.x = clamp(this.x, 0, canvas.width - BOX_SIZE);
      this.y = clamp(this.y, 0, canvas.height - BOX_SIZE);
   }

   this.render = function() {
      context.fillStyle = this.colour;
      context.fillRect(this.x, this.y, this.width, this.height);
   }
}

function onKeyDown(key) {
    if(key.target == document.body) {
        key.preventDefault();
        heldKeys[key.keyCode] = true;
    }
}
window.addEventListener("keydown", onKeyDown, false);
console.log("keydown Event Listener set.");

function onKeyUp(key) {
   delete heldKeys[key.keyCode];
}
window.addEventListener("keyup", onKeyUp, false);
console.log("keyup Event Listener set.");

console.log("About to render first frame!");
function update() {
   for(var i = 0; i < boxes.length; i++)
      boxes[i].render();

   player.move();

   context.clearRect(0, 0, canvas.width, canvas.height);

   for(var i = 0; i < boxes.length; i++) {

      player.grounded = true;

      var collDir = collisionChecker.testCollision(player, boxes[i]);

      if(collDir === "r" || collDir === "l" || player.y === (canvas.height - BOX_SIZE)) {
         player.xVelocity = 0;
         player.jumping = false;
         console.log("Player received a collision on the " + ((collDir === "r") ? "right" : "left") + "!");
      }
      if(collDir === "b") {
         player.grounded = true;
         player.yVelocity = 0;
         player.jumping = false;
         console.log("Player received a collision on the bottom!");
      }
      if(collDir === "t") {
         player.yVelocity = 0;
      }
      render(boxes[i]);
   }
   render(player);
}

function game() {
   update();
   requestAnimationFrame(game);
}
window.addEventListener("load", game);

function clamp(value, min, max) {
   if(value > max)
      return max;
   else if(value < min)
      return min

   return value;
}

function render(object) {
   object.x = clamp(object.x, 0, canvas.width - BOX_SIZE);
   object.y = clamp(object.y, 0, canvas.height - BOX_SIZE);
   context.fillStyle = object.colour;
   context.fillRect(object.x, object.y, object.width, object.height, object.colour);
}

function check(object) {
   if(!object || object === null) {
      console.error(object.constructor.name + " is NULL.");
      return false;
   } else {
      //console.group("Properties of " + object.constructor.name + ": ");
      console.log(object.constructor.name + " has been created.")
      return true;
   }
}

var collisionChecker = {
   quickBoxTest: function(boxA, boxB) {
      if(boxA.x < boxB.x + boxB.width && boxA.x + boxA.width > boxB.x && boxA.y < boxB.y + boxB.height && boxA.height + boxA.y > boxB.y)
         return true;

      return false;
   },

   testCollision: function(objectA, objectB) {
      //Find the collision vectors
      var vectorX = (objectA.x + (objectA.width / 2)) - (objectB.x + (objectB.width / 2));
      var vectorY = (objectA.y + (objectA.height / 2)) - (objectB.y + (objectB.height / 2));

      //Find the distance between the two objects
      var deltaWidth = (objectA.width / 2) + (objectB.width / 2);
      var deltaHeight = (objectA.height / 2) + (objectB.height / 2);

      //Stores the direction of collision
      var collisionDir = null;

      //Check if the two objects are intersecting on the x and y axis
      if(Math.abs(vectorX) < deltaWidth && Math.abs(vectorY) < deltaHeight)
      {
         //The direction of collision
         var directionX = deltaWidth - Math.abs(vectorX);
         var directionY = deltaHeight - Math.abs(vectorY);

         //Check for vertical collision
         if(directionX >= directionY)
         {
            //Check for collisions from the top
            if(vectorY > 0)
            {
               objectA.y += directionY;
               collisionDir = "t";
            }

            //Collisions form the botttom
            else
            {
               objectA.y -= directionY;
               collisionDir = "b";
            }
         }
         else
         {
            //Check for collisions from the left
            if(vectorX > 0)
            {
               objectA.x += directionX;
               collisionDir = "l";
            }

            //Collisions form the right side
            else
            {
               objectA.x -= directionX;
               collisionDir = "r";
            }
         }
      }

      //Return the direction.
      return collisionDir;
   }
}

var input = {
   getKeyDown: function(keyToCheck) {
      if(heldKeys[keyToCheck] === true)
         return true
      else
         return false;
   }
}

var keyCode = {
   upArrow: 38,
   downArrow: 40,
   leftArrow: 37,
   rightArrow: 39,

   wKey: 87,
   aKey: 65,
   sKey: 83,
   dKey: 68,

   spacebarKey: 32
}
<commit_msg>Updated Player<commit_after>(function()
{
    if (!window.requestAnimationFrame)
    {
        window.requestAnimationFrame = window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        window.oRequestAnimationFrame      ||
        window.msRequestAnimationFrame     ||

        function(callback, element)
        {
            window.setTimeout(callback, 1000 / FRAME_RATE);
        }
    }
})();
console.log("Animation frame requested.");

var canvas = document.getElementById("canvas");
console.log("Canvas loaded.");
var context = (check(canvas)) ? canvas.getContext("2d") : null;
console.log("Context loaded.");
check(context);

canvas.style.background = "rgb(52, 55, 60)";
console.log("Background colour set to " + canvas.style.background + ".");

var boxes = [];
var heldKeys = [];
const FRAMERATE = 10;
const BOX_SIZE = 20;
const GRAVITY = 0.9;
const JUMP_VELOCITY = 10;
const SPEED = 10;
const ACCELERATION = 1;
const FRICTION = 0.9;

var playerSpawnX, playerSpawnY;
playerSpawnX = canvas.width / 2;
playerSpawnY = 0;
console.log("Values set for properties.");

player = new Player(playerSpawnX, playerSpawnY, BOX_SIZE, BOX_SIZE * 2, "rgb(255, 100, 100)");
console.log("Player created.");
player.toString();
check(player);

box = new Box(0, canvas.height - BOX_SIZE, canvas.width, BOX_SIZE, "rgb(100, 100, 255)");

function Player(xPos, yPos, _width, _height, _renderColour) {
   this.x = xPos;
   this.y = yPos;
   this.width = _width;
   this.height = _height;
   this.colour = _renderColour;
   this.xVelocity = 0;
   this.yVelocity = 0;
   this.grounded = false;
   this.jumping = false;

   this.toString = function() {
      console.log("Player's position: (" + this.x + ", " + this.y + ")");
      console.log("Player's dimensions: (" + this.width + ", " + this.height + ")");
      console.log("Player's colour: " + this.colour);
      console.log("Player's velocity: (" + this.xVelocity + ", " + this.yVelocity + ")");
   }

   this.respawn = function() {
      this.x = playerSpawnX;
      this.y = playerSpawnY;
   }

   this.respawn = function(x, y) {
      this.x = x;
      this.y = y;
   }

   this.setVelocity = function(x, y) {
      this.xVelocity = x;
      this.yVelocity = y;
   }

   this.calculateVelocity = function() {
      if(input.getKeyDown(keyCode.upArrow) && this.grounded)
         this.setVelocity(0, -SPEED);

      if(input.getKeyDown(keyCode.rightArrow))
         this.setVelocity(SPEED, 0);

      if(input.getKeyDown(keyCode.leftArrow))
         this.setVelocity(-SPEED, 0);
   }

   this.adjustVelocityByCollision = function(toTest) {
      if((collisionChecker.testCollision(this, toTest) === "b") || this.y === canvas.height - BOX_SIZE) {
         this.setVelocity(this.xVelocity, 0);
         this.grounded = true;
         this.jumping = false;
      }
   }

   this.applyVelocity = function() {
      this.x += this.xVelocity;
      this.y += this.yVelocity;
      this.y += GRAVITY;
   }

   this.resetVelocity = function() {
      this.xVelocity = 0;
      this.yVelocity = 0;
   }

   this.constrain = function() {
      this.x = clamp(this.x, 0, canvas.width - BOX_SIZE);
      this.y = clamp(this.y, 0, canvas.height - BOX_SIZE);
   }

   this.update = function() {
      this.resetVelocity();
      this.calculateVelocity();
      this.applyVelocity();
      this.constrain();
      this.resetVelocity();
   }

   this.move = function() {
      if(input.getKeyDown(keyCode.upArrow) || input.getKeyDown(keyCode.spacebarKey)) {
         if(!player.jumping && player.grounded) {
            player.yVelocity = -JUMP_VELOCITY;
            player.grounded = false;
            player.jumping = true;
         }
      }

      if(input.getKeyDown(keyCode.leftArrow) && player.xVelocity > -SPEED)
         player.xVelocity -= ACCELERATION;

      if(input.getKeyDown(keyCode.rightArrow) && player.xVelocity < SPEED)
         player.xVelocity += ACCELERATION;

      player.xVelocity *= FRICTION;
      player.yVelocity += GRAVITY;

      player.y += player.yVelocity;
      player.x += player.xVelocity;
   }

   this.render = function() {
      context.fillStyle = this.colour;
      context.fillRect(this.x, this.y, this.width, this.height);
   }
}

function Box(xPos, yPos, _width, _height, _renderColour) {
   this.x = xPos;
   this.y = yPos;
   this.width = _width;
   this.height = _height;
   this.colour = _renderColour;

   boxes.push(this);

   this.toString = function() {
      console.log("Box's position: (" + this.x + ", " + this.y + ")");
      console.log("Box's dimensions: (" + this.width + ", " + this.height + ")");
      console.log("Box's colour: " + this.colour);
   }

   this.constrain = function() {
      this.x = clamp(this.x, 0, canvas.width - BOX_SIZE);
      this.y = clamp(this.y, 0, canvas.height - BOX_SIZE);
   }

   this.render = function() {
      context.fillStyle = this.colour;
      context.fillRect(this.x, this.y, this.width, this.height);
   }
}

function onKeyDown(key) {
    if(key.target == document.body) {
        key.preventDefault();
        heldKeys[key.keyCode] = true;
    }
}
window.addEventListener("keydown", onKeyDown, false);
console.log("keydown Event Listener set.");

function onKeyUp(key) {
   delete heldKeys[key.keyCode];
}
window.addEventListener("keyup", onKeyUp, false);
console.log("keyup Event Listener set.");

console.log("About to render first frame!");
function update() {
   for(var i = 0; i < boxes.length; i++)
      boxes[i].render();

   player.move();

   context.clearRect(0, 0, canvas.width, canvas.height);

   for(var i = 0; i < boxes.length; i++) {

      player.grounded = true;

      var collDir = collisionChecker.testCollision(player, boxes[i]);

      if(collDir === "r" || collDir === "l" || player.y === (canvas.height - BOX_SIZE)) {
         player.xVelocity = 0;
         player.jumping = false;
         console.log("Player received a collision on the " + ((collDir === "r") ? "right" : "left") + "!");
      }
      if(collDir === "b") {
         player.grounded = true;
         player.yVelocity = 0;
         player.jumping = false;
         console.log("Player received a collision on the bottom!");
      }
      if(collDir === "t") {
         player.yVelocity = 0;
      }
      render(boxes[i]);
   }
   render(player);
}

function game() {
   update();
   requestAnimationFrame(game);
}
window.addEventListener("load", game);

function clamp(value, min, max) {
   if(value > max)
      return max;
   else if(value < min)
      return min

   return value;
}

function render(object) {
   object.x = clamp(object.x, 0, canvas.width - BOX_SIZE);
   object.y = clamp(object.y, 0, canvas.height - BOX_SIZE);
   context.fillStyle = object.colour;
   context.fillRect(object.x, object.y, object.width, object.height, object.colour);
}

function check(object) {
   if(!object || object === null) {
      console.error(object.constructor.name + " is NULL.");
      return false;
   } else {
      //console.group("Properties of " + object.constructor.name + ": ");
      console.log(object.constructor.name + " has been created.")
      return true;
   }
}

var collisionChecker = {
   quickBoxTest: function(boxA, boxB) {
      if(boxA.x < boxB.x + boxB.width && boxA.x + boxA.width > boxB.x && boxA.y < boxB.y + boxB.height && boxA.height + boxA.y > boxB.y)
         return true;

      return false;
   },

   testCollision: function(objectA, objectB) {
      //Find the collision vectors
      var vectorX = (objectA.x + (objectA.width / 2)) - (objectB.x + (objectB.width / 2));
      var vectorY = (objectA.y + (objectA.height / 2)) - (objectB.y + (objectB.height / 2));

      //Find the distance between the two objects
      var deltaWidth = (objectA.width / 2) + (objectB.width / 2);
      var deltaHeight = (objectA.height / 2) + (objectB.height / 2);

      //Stores the direction of collision
      var collisionDir = null;

      //Check if the two objects are intersecting on the x and y axis
      if(Math.abs(vectorX) < deltaWidth && Math.abs(vectorY) < deltaHeight)
      {
         //The direction of collision
         var directionX = deltaWidth - Math.abs(vectorX);
         var directionY = deltaHeight - Math.abs(vectorY);

         //Check for vertical collision
         if(directionX >= directionY)
         {
            //Check for collisions from the top
            if(vectorY > 0)
            {
               objectA.y += directionY;
               collisionDir = "t";
            }

            //Collisions form the botttom
            else
            {
               objectA.y -= directionY;
               collisionDir = "b";
            }
         }
         else
         {
            //Check for collisions from the left
            if(vectorX > 0)
            {
               objectA.x += directionX;
               collisionDir = "l";
            }

            //Collisions form the right side
            else
            {
               objectA.x -= directionX;
               collisionDir = "r";
            }
         }
      }

      //Return the direction.
      return collisionDir;
   }
}

var input = {
   getKeyDown: function(keyToCheck) {
      if(heldKeys[keyToCheck] === true)
         return true
      else
         return false;
   }
}

var keyCode = {
   upArrow: 38,
   downArrow: 40,
   leftArrow: 37,
   rightArrow: 39,

   wKey: 87,
   aKey: 65,
   sKey: 83,
   dKey: 68,

   spacebarKey: 32
}
<|endoftext|>


<commit_before>  /**
  * @author Christopher Klpap
  * @description This component displays the Verse so selection, edit and comments can be made
  */
import React from 'react'
import View from './components/View'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import {optimizeSelections, normalizeString} from './utils/selectionHelpers'

class VerseCheck extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      mode: props.selectionsReducer.selections.length > 0 ? 'default' : 'select',
      comment: undefined,
      commentChanged: false,
      verseText: undefined,
      verseChanged: false,
      selections: [],
      tags: [],
      dialogModalVisibility: false,
      goToNextOrPrevious: null
    }

    let that = this

    this.tagList = [
      ["spelling", "Spelling"],
      ["punctuation", "Punctuation"],
      ["grammar", "Grammar"],
      ["meaning", "Meaning"],
      ["wordChoice", "Word Choice"],
      ["other", "Other"]
    ]

    this.actions = {
      handleGoToNext: function() {
        if (!that.props.loginReducer.loggedInUser) {
          that.props.actions.selectModalTab(1, 1, true);
          that.props.actions.openAlertDialog("You must be logged in to save progress");
          return;
        }
        props.actions.goToNext()
      },
      handleGoToPrevious: function() {
        if (!that.props.loginReducer.loggedInUser) {
          that.props.actions.selectModalTab(1, 1, true);
          that.props.actions.openAlertDialog("You must be logged in to save progress");
          return;
        }
        props.actions.goToPrevious()
      },
      handleOpenDialog(goToNextOrPrevious) {
        that.setState({goToNextOrPrevious})
        that.setState({dialogModalVisibility: true});
      },
      handleCloseDialog() {
        that.setState({dialogModalVisibility: false});
      },
      skipToNext() {
        that.setState({dialogModalVisibility: false});
        props.actions.goToNext()
      },
      skipToPrevious() {
        that.setState({dialogModalVisibility: false});
        props.actions.goToPrevious()
      },
      changeSelectionsInLocalState: function(selections) {
        that.setState({ selections });
      },
      changeMode: function(mode) {
        let newState = that.state
        newState.mode = mode
        that.setState(newState)
      },
      handleComment: function(e) {
        const comment = e.target.value
        let newState = that.state
        newState.comment = comment
        that.setState(newState)
      },
      checkComment: function(e) {
        const newcomment = e.target.value || "";
        const oldcomment = that.props.commentsReducer.text || "";

        that.setState({
          commentChanged: newcomment !== oldcomment
        })
      },
      cancelComment: function(e) {
        that.setState({
          mode: 'default',
          comment: undefined,
          commentChanged: false
        })
      },
      saveComment: function() {
        if (!that.props.loginReducer.loggedInUser) {
          that.props.actions.selectModalTab(1, 1, true);
          that.props.actions.openAlertDialog("You must be logged in to leave a comment", 5);
          return;
        }
        that.props.actions.addComment(that.state.comment, that.props.loginReducer.userdata.username)
        that.setState({
          mode: 'default',
          comment: undefined,
          commentChanged: false
        })
      },
      handleTagsCheckbox: function(tag, e) {
        let newState = that.state
        if (newState.tags === undefined) newState.tags = []
        if (!newState.tags.includes(tag)) {
          newState.tags.push(tag)
        } else {
          newState.tags = newState.tags.filter( _tag => _tag !== tag)
        }
        that.setState(newState)
      },
      handleEditVerse: function(e) {
        const verseText = e.target.value
        let newState = that.state
        newState.verseText = verseText
        that.setState(newState)
      },
      checkVerse: function(e) {
        let {chapter, verse} = that.props.contextIdReducer.contextId.reference;
        const newverse = e.target.value || "";
        const oldverse = that.props.resourcesReducer.bibles.targetLanguage[chapter][verse] || "";

        if (newverse === oldverse) {
          that.setState({
            verseChanged: false,
            tags: []
          })
        } else {
          that.setState({
            verseChanged: true
          })
        }
      },
      cancelEditVerse: function() {
        that.setState({
          mode: 'default',
          verseText: undefined,
          verseChanged: false,
          tags: []
        })
      },
      saveEditVerse: function() {
        let {loginReducer, actions, contextIdReducer, resourcesReducer} = that.props;
        let {chapter, verse} = contextIdReducer.contextId.reference;
        let before = resourcesReducer.bibles.targetLanguage[chapter][verse];
        let username = loginReducer.userdata.username;
        // verseText state is undefined if no changes are made in the text box.
        if (!loginReducer.loggedInUser) {
          that.props.actions.selectModalTab(1, 1, true);
          that.props.actions.openAlertDialog("You must be logged in to edit a verse");
          return;
        }

        const save = () => {
          actions.addVerseEdit(before, that.state.verseText, that.state.tags, username);
          that.setState({
            mode: 'default',
            verseText: undefined,
            verseChanged: false,
            tags: []
          });
        }

        if (that.state.verseText) {  // if verseText === "" is false
          save();
        } else {
          // alert the user if the text is blank
          let message = 'You are saving a blank verse. Please confirm.';
          that.props.actions.openOptionDialog(message, (option)=> {
            if (option !== "Cancel") save();
            that.props.actions.closeAlertDialog();
          }, "Save Blank Verse", "Cancel");
        }

      },
      validateSelections: (verseText) => {
        that.props.actions.validateSelections(verseText)
      },
      toggleReminder: () => {
        that.props.actions.toggleReminder(that.props.loginReducer.userdata.username)
      },
      openAlertDialog: (message) => {
        that.props.actions.openAlertDialog(message)
      },
      selectModalTab: (tab, section, vis) => {
        that.props.actions.selectModalTab(tab, section, vis);
      }
    }
  }

  componentWillMount() {
    let selections = Array.from(this.props.selectionsReducer.selections);
    this.setState({selections});
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.contextIdReducer.contextId != this.props.contextIdReducer.contextId) {
      let selections = Array.from(nextProps.selectionsReducer.selections);
      this.setState({
        mode: nextProps.selectionsReducer.selections.length > 0 ? 'default' : 'select',
        comments: undefined,
        verseText: undefined,
        selections,
        tags: []
      })
    }
  }

  cancelSelection() {
    this.setState({
      mode: 'default',
      selections: this.props.selectionsReducer.selections
    })
  }

  clearSelection() {
    this.setState({
      selections: []
    })
  }

  saveSelection() {
    let verseText = this.verseText();
    // optimize the selections to address potential issues and save
    let selections = optimizeSelections(verseText, this.state.selections);
    this.props.actions.changeSelections(selections, this.props.loginReducer.userdata.username);
    this.setState({
      mode: 'default'
    })
  }

  verseText() {
    const { chapter, verse, bookId } = this.props.contextIdReducer.contextId.reference;
    const bookAbbr = this.props.projectDetailsReducer.manifest.project.id;
    const { targetLanguage } = this.props.resourcesReducer.bibles;
    let verseText = "";
    if (targetLanguage && targetLanguage[chapter] && bookId == bookAbbr) {
      verseText = targetLanguage[chapter][verse] || "";
      // normalize whitespace in case selection has contiguous whitespace that isn't captured
      verseText = normalizeString(verseText);
    }
    return verseText
  }

  render() {
    return (
      <MuiThemeProvider>
        <View {...this.props} actions={this.actions}
          cancelSelection={this.cancelSelection.bind(this)}
          clearSelection={this.clearSelection.bind(this)}
          saveSelection={this.saveSelection.bind(this)}
          mode={this.state.mode}
          comment={this.props.commentsReducer.text}
          commentChanged={this.state.commentChanged}
          verseText={this.verseText()}
          verseChanged={this.state.verseChanged}
          selections={this.state.selections}
          tags={this.state.tags}
          dialogModalVisibility={this.state.dialogModalVisibility}
          goToNextOrPrevious={this.state.goToNextOrPrevious}
        />
      </MuiThemeProvider>
    );
  }
}

export default VerseCheck;
<commit_msg>Reload state selections on mode change and minor syntax refactor<commit_after>  /**
  * @author Christopher Klpap
  * @description This component displays the Verse so selection, edit and comments can be made
  */
import React from 'react';
import View from './components/View';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {optimizeSelections, normalizeString} from './utils/selectionHelpers';

class VerseCheck extends React.Component {
  constructor(props) {
    super(props);
    const mode = props.selectionsReducer.selections.length > 0 ? 'default' : 'select';
    this.state = {
      mode: mode,
      comment: undefined,
      commentChanged: false,
      verseText: undefined,
      verseChanged: false,
      selections: [],
      tags: [],
      dialogModalVisibility: false,
      goToNextOrPrevious: null
    };

    let _this = this;

    this.tagList = [
      ["spelling", "Spelling"],
      ["punctuation", "Punctuation"],
      ["grammar", "Grammar"],
      ["meaning", "Meaning"],
      ["wordChoice", "Word Choice"],
      ["other", "Other"]
    ]

    this.actions = {
      handleGoToNext() {
        if (!_this.props.loginReducer.loggedInUser) {
          _this.props.actions.selectModalTab(1, 1, true);
          _this.props.actions.openAlertDialog("You must be logged in to save progress");
          return;
        }
        props.actions.goToNext();
      },
      handleGoToPrevious() {
        if (!_this.props.loginReducer.loggedInUser) {
          _this.props.actions.selectModalTab(1, 1, true);
          _this.props.actions.openAlertDialog("You must be logged in to save progress");
          return;
        }
        props.actions.goToPrevious();
      },
      handleOpenDialog(goToNextOrPrevious) {
        _this.setState({goToNextOrPrevious})
        _this.setState({dialogModalVisibility: true});
      },
      handleCloseDialog() {
        _this.setState({dialogModalVisibility: false});
      },
      skipToNext() {
        _this.setState({dialogModalVisibility: false});
        props.actions.goToNext();
      },
      skipToPrevious() {
        _this.setState({dialogModalVisibility: false});
        props.actions.goToPrevious();
      },
      changeSelectionsInLocalState(selections) {
        _this.setState({ selections });
      },
      changeMode(mode) {
        _this.setState({
          mode: mode,
          selections: _this.props.selectionsReducer.selections
        });
      },
      handleComment(e) {
        const comment = e.target.value;
        _this.setState({
          comment: comment
        });
      },
      checkComment(e) {
        const newcomment = e.target.value || "";
        const oldcomment = _this.props.commentsReducer.text || "";
        _this.setState({
          commentChanged: newcomment !== oldcomment
        })
      },
      cancelComment(e) {
        _this.setState({
          mode: 'default',
          selections: _this.props.selectionsReducer.selections,
          comment: undefined,
          commentChanged: false
        });
      },
      saveComment() {
        if (!_this.props.loginReducer.loggedInUser) {
          _this.props.actions.selectModalTab(1, 1, true);
          _this.props.actions.openAlertDialog("You must be logged in to leave a comment", 5);
          return;
        }
        _this.props.actions.addComment(_this.state.comment, _this.props.loginReducer.userdata.username);
        _this.setState({
          mode: 'default',
          selections: _this.props.selectionsReducer.selections,
          comment: undefined,
          commentChanged: false
        });
      },
      handleTagsCheckbox(tag, e) {
        let newState = _this.state;
        if (newState.tags === undefined) newState.tags = [];
        if (!newState.tags.includes(tag)) {
          newState.tags.push(tag);
        } else {
          newState.tags = newState.tags.filter( _tag => _tag !== tag);
        }
        _this.setState(newState);
      },
      handleEditVerse(e) {
        const verseText = e.target.value;
        _this.setState({
          verseText: verseText
        });
      },
      checkVerse(e) {
        let {chapter, verse} = _this.props.contextIdReducer.contextId.reference;
        const newverse = e.target.value || "";
        const oldverse = _this.props.resourcesReducer.bibles.targetLanguage[chapter][verse] || "";
        if (newverse === oldverse) {
          _this.setState({
            verseChanged: false,
            tags: []
          });
        } else {
          _this.setState({
            verseChanged: true
          });
        }
      },
      cancelEditVerse() {
        _this.setState({
          mode: 'default',
          selections: _this.props.selectionsReducer.selections,
          verseText: undefined,
          verseChanged: false,
          tags: []
        });
      },
      saveEditVerse() {
        let {loginReducer, actions, contextIdReducer, resourcesReducer} = _this.props;
        let {chapter, verse} = contextIdReducer.contextId.reference;
        let before = resourcesReducer.bibles.targetLanguage[chapter][verse];
        let username = loginReducer.userdata.username;
        // verseText state is undefined if no changes are made in the text box.
        if (!loginReducer.loggedInUser) {
          _this.props.actions.selectModalTab(1, 1, true);
          _this.props.actions.openAlertDialog("You must be logged in to edit a verse");
          return;
        }

        const save = () => {
          actions.addVerseEdit(before, _this.state.verseText, _this.state.tags, username);
          _this.setState({
            mode: 'default',
            selections: _this.props.selectionsReducer.selections,
            verseText: undefined,
            verseChanged: false,
            tags: []
          });
        }
        if (_this.state.verseText) {  // if verseText === "" is false
          save();
        } else {
          // alert the user if the text is blank
          let message = 'You are saving a blank verse. Please confirm.';
          _this.props.actions.openOptionDialog(message, (option)=> {
            if (option !== "Cancel") save();
            _this.props.actions.closeAlertDialog();
          }, "Save Blank Verse", "Cancel");
        }
      },
      validateSelections(verseText) {
        _this.props.actions.validateSelections(verseText)
      },
      toggleReminder() {
        _this.props.actions.toggleReminder(_this.props.loginReducer.userdata.username)
      },
      openAlertDialog(message) {
        _this.props.actions.openAlertDialog(message)
      },
      selectModalTab(tab, section, vis) {
        _this.props.actions.selectModalTab(tab, section, vis);
      }
    }
  }

  componentWillMount() {
    let selections = Array.from(this.props.selectionsReducer.selections);
    this.setState({selections});
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.contextIdReducer.contextId != this.props.contextIdReducer.contextId) {
      let selections = Array.from(nextProps.selectionsReducer.selections);
      const mode = nextProps.selectionsReducer.selections.length > 0 ? 'default' : 'select';
      this.setState({
        mode: mode,
        comments: undefined,
        verseText: undefined,
        selections,
        tags: []
      });
    }
  }

  cancelSelection() {
    this.actions.changeSelectionsInLocalState(this.props.selectionsReducer.selections);
    this.actions.changeMode('default');
  }

  clearSelection() {
    this.setState({
      selections: []
    });
  }

  saveSelection() {
    let verseText = this.verseText();
    // optimize the selections to address potential issues and save
    let selections = optimizeSelections(verseText, this.state.selections);
    this.props.actions.changeSelections(selections, this.props.loginReducer.userdata.username);
    this.actions.changeMode('default');
  }

  verseText() {
    const { chapter, verse, bookId } = this.props.contextIdReducer.contextId.reference;
    const bookAbbr = this.props.projectDetailsReducer.manifest.project.id;
    const { targetLanguage } = this.props.resourcesReducer.bibles;
    let verseText = "";
    if (targetLanguage && targetLanguage[chapter] && bookId == bookAbbr) {
      verseText = targetLanguage[chapter][verse] || "";
      // normalize whitespace in case selection has contiguous whitespace _this isn't captured
      verseText = normalizeString(verseText);
    }
    return verseText;
  }

  render() {
    return (
      <MuiThemeProvider>
        <View {...this.props} actions={this.actions}
          cancelSelection={this.cancelSelection.bind(this)}
          clearSelection={this.clearSelection.bind(this)}
          saveSelection={this.saveSelection.bind(this)}
          mode={this.state.mode}
          comment={this.props.commentsReducer.text}
          commentChanged={this.state.commentChanged}
          verseText={this.verseText()}
          verseChanged={this.state.verseChanged}
          selections={this.state.selections}
          tags={this.state.tags}
          dialogModalVisibility={this.state.dialogModalVisibility}
          goToNextOrPrevious={this.state.goToNextOrPrevious}
        />
      </MuiThemeProvider>
    );
  }
}

export default VerseCheck;
<|endoftext|>


<commit_before>(function(){var e=window,f=document,g="push",h="exec",i="createElement",k="addEventListener",l="setAttribute",m="attachEvent",n="documentElement",o="toString",p="length",q="prototype",r="call",s="getAttribute",t="querySelectorAll",u="parentNode",v="",y="\n",z='");',A="*",B=":not([psa_not_processed])",C="
_
",D='=document.getElementById("',E="Add to queue str: ",F="Add to queue url: ",G="DOMContentLoaded",H="Evaluated: ",I="Exception while evaluating.",J="Exception while overriding document.readyState.",
aa="Executed: ",ba="Firefox",ca="HTMLEvents",da="PSA ERROR: ",K="SCRIPT",ea="Unable to insert nodes, no context element found",fa="[psa_not_processed]",ga="application/ecmascript",ha="application/javascript",ia="application/x-ecmascript",ja="application/x-javascript",ka="complete",la="data:text/javascript,",ma="div",na="domready: ",oa="dw: ",pa="error",qa="executing domready: ",ra="executing pageload: ",sa="handle_dw: ",L="id",M="language",N="load",ta="loaded",ua="loading",O="on",va="onDOMContentLoaded",
wa="onload",xa="onload: ",ya="onreadystatechange",P="orig_src",za="orig_type",Aa="psa_dw_target",Q="psa_not_processed",Ba="readyState",R="readystatechange",S="script",Ca="span",T="src",Da="text/",Ea="text/ecmascript",U="text/javascript",Fa="text/javascript1.0",Ga="text/javascript1.1",Ha="text/javascript1.2",Ia="text/javascript1.3",Ja="text/javascript1.4",Ka="text/javascript1.5",La="text/jscript",Ma="text/livescript",V="text/psajs",Na="text/x-ecmascript",Oa="text/x-javascript",Pa="true",W="type",Qa=
"var ",X;e.pagespeed=e.pagespeed||{};var Y=e.pagespeed,Z=function(){this.i=[];this.f=[];this.g=0;this.a=null;this.b=v;this.j=[];this.h=[];this.n=[];this.m=[];this.s=[ga,ha,ia,ja,Ea,U,Fa,Ga,Ha,Ia,Ja,Ka,La,Ma,Na,Oa];this.q=f.getElementById;this.r=f.getElementsByTagName;this.e=0},$=!1;X=Z[q];X.log=function(a,b){this.f&&(this.f[g](v+a),b&&(this.f[g](b),"undefined"!=typeof console&&"undefined"!=typeof console.log&&console.log(da+a+b.message)))};X.u=function(a,b){this.i.splice(b?b:this.i[p],0,a)};
X.B=function(a){var b=f[i](S);b.text=a;b[l](W,U);this.a[u].insertBefore(b,this.a)};X.K=function(){for(var a=f.getElementsByTagName(A),b=v,c=0;c<a[p];c++)if(a[c].hasAttribute(L)){var d=a[c][s](L);d&&-1==d.search(/[-:.]/)&&-1==d.search(/^[0-9]/)&&e[d]&&e[d].tagName&&(b+=Qa+d+D+d+z)}b&&this.B(b)};X.F=function(a,b){var c=a[s](P)||a[s](T);c&&this.addUrl(c,a,b);if(!c||!$)(c=a.innerHTML||a.textContent||a.data)&&this.G(c,a,b)};
X.G=function(a,b,c){if(this.M())this.addUrl(la+encodeURIComponent(a),b,c);else{this.f[g](E+a);var d=this;this.u(function(){d.a=b;d.l(b);try{d.B(a)}catch(c){d.log(I,c)}d.log(H+a);d.o()},c)}};Z[q].addStr=Z[q].G;
Z[q].addUrl=function(a,b,c){this.f[g](F+a);var d=this;this.u(function(){d.a=b;d.l(b);var c=f[i](S);c[l](W,U);var j=function(){d.log(aa+a);d.o()};Y.z(c,j);Y.k(c,pa,j);9>d.d()&&Y.k(c,R,function(){if(c.readyState==ka||c.readyState==ta)c.onreadystatechange=null,j()});c[l](T,a);if($){var x=b.innerHTML||b.textContent||b.data;x&&c.appendChild(f.createTextNode(x))}d.a[u].insertBefore(c,d.a)},c)};Z[q].addUrl=Z[q].addUrl;X=Z[q];
X.l=function(a){if($&&f[t]&&!(8>=this.d()))for(var b=f[t](fa),c=0;c<b[p];c++){var d=b.item(c);if(d==a)break;d[s](W)!=V&&d.removeAttribute(Q)}};X.L=function(){if($)for(var a=this.r[r](f,A),b=0;b=this.d())&&(f.getElementsByTagName=this.r));f.a?(f.addEventListener=f.a,e.addEventListener=e.a):f.b&&(f.attachEvent=f.b,e.attachEvent=e.b);this.I();this.J();this.e=3;this.H()};X.o=function(){this.t();this.g<this.i[p]?(this.g++,this.i[this.g-1][r](e)):this.P()};
X.D=function(a){for(var b=[],c=a[p],d=0;d<c;++d)b[g](a.item(d));return b};
X.Q=function(){var a=f[i](Ca);a[l](Aa,Pa);f.body.appendChild(a);this.a=a;this.d()&&this.K();this.L();if(Object.defineProperty)try{Object.defineProperty(f,Ba,{configurable:!0,get:function(){return ua}})}catch(b){this.log(J,b)}this.d()&&(f[n].originalDoScroll=f[n].doScroll,f[n].doScroll=function(){throw"psa exception";});this.v(f);this.v(e);f.writeln=function(a){Y.c.w(a+y)};f.write=function(a){Y.c.w(a)};f.open=function(){};f.close=function(){};$&&(f.getElementById=function(a){Y.c.t();return Y.c.q[r](f,
a)},f[t]&&!(8>=Y.c.d())&&(f.getElementsByTagName=function(a){return f[t](a+B)}))};X.$=function(){2<=this.e||(this.O(),this.e=2,this.Q(),this.o())};Z[q].run=Z[q].$;X=Z[q];X.T=function(a){var b=f[i](ma);b.innerHTML=C+a;b.removeChild(b.firstChild);return b};X.V=function(a){var b=a[u];b&&b.removeChild(a)};X.S=function(a,b){for(var c=this.D(a),d=c[p],w=b[u],j=0;j<d;++j){var x=c[j];this.V(x);w.insertBefore(x,b)}};
X.U=function(a){return a.nodeName!=K?!1:a.hasAttribute(W)?(a=a[s](W),!a||-1!=this.s.indexOf(a)):a.hasAttribute(M)?(a=a[s](M),!a||-1!=this.s.indexOf(Da+a.toLowerCase())):!0};X.C=function(a,b){if(a.childNodes)for(var c=this.D(a.childNodes),d=c[p],w=0;w<d;++w){var j=c[w];$&&1==j.nodeType&&j[l](Q,v);j.nodeName==K?this.U(j)&&(b[g](j),j[l](za,j.type),j[l](W,V),j[l](P,j.src),j[l](T,v)):this.C(j,b)}};X.R=function(a,b){for(var c=a[p],d=0;d<c;++d)this.F(a[d],b+d)};
X.N=function(a,b,c){var a=this.T(a),d=[];this.C(a,d);c?this.S(a.childNodes,c):this.log(ea);this.R(d,b)};X.t=function(){if(this.b!=v){this.log(sa+this.b);var a=this.b;this.b=v;this.N(a,this.g,this.a)}};X.w=function(a){this.log(oa+a);this.b+=a};X.A=function(a,b){this.log(na+b[o]());this.j[g](function(){b[r](a)})};X.p=function(a,b){this.log(xa+b[o]());if(3==this.e)b[r](a);else{var c;8>=this.d()||(c=f.createEvent(ca),c.initEvent(N,!1,!1));this.h[g](function(){b[r](a,c)})}};Z[q].addOnloadListeners=Z[q].p;
Z[q].Y=function(a){this.n[g](a)};Z[q].addBeforeDeferRunFunctions=Z[q].Y;Z[q].X=function(a){this.m[g](a)};Z[q].addAfterDeferRunFunctions=Z[q].X;X=Z[q];X.I=function(){for(var a=0;a<this.j[p];a++)this.log(qa+this.j[a][o]()),this[h](this.j[a]);f.onreadystatechange&&this[h](f.onreadystatechange,f)};X.J=function(){for(var a=0;a<this.h[p];a++)this.log(ra+this.h[a][o]()),this[h](this.h[a])};X.O=function(){for(var a=0;a<this.n[p];a++)this[h](this.n[a])};X.H=function(){for(var a=0;a<this.m[p];a++)this[h](this.m[a])};
X.exec=function(a,b){try{a[r](b||e)}catch(c){this.log(I,c)}};X.v=function(a){a[k]&&!a.a?(a.a=a[k],a.addEventListener=function(b,c,d){b==G||b==R?Y.c.A(a,c):b==N?Y.c.p(a,c):a.a(b,c,d)}):a[m]&&!a.b&&(a.b=a[m],a.attachEvent=function(b,c){b==va||b==ya?Y.c.A(a,c):b==wa?Y.c.p(a,c):a.b(b,c)})};X.Z=function(){if(!(1<=this.e)){this.e=1;for(var a=f.getElementsByTagName(S),b=a[p],c=0;c<b;++c){var d=a[c];d[s](W)==V&&this.F(d)}}};Z[q].registerScriptTags=Z[q].Z;Y.z=function(a,b){Y.k(a,N,b)};Y.addOnload=Y.z;
Y.k=function(a,b,c){if(a[k])a[k](b,c,!1);else if(a[m])a[m](O+b,c);else{var d=a[O+b];a[O+b]=function(){c[r](this);d&&d[r](this)}}};Y.addHandler=Y.k;Y.outerHTML=function(a){return a.outerHTML||(new XMLSerializer).serializeToString(a)};Z[q].M=function(){return-1!=navigator.userAgent.indexOf(ba)};Z[q].d=function(){var a=/(?:MSIE.(\d+\.\d+))/[h](navigator.userAgent);return a&&a[1]?f.documentMode||parseFloat(a[1]):NaN};
Y.W=function(){Y.c||(e.localStorage&&($=e.localStorage.defer_js_experimental),Y.c=new Z,Y.deferJs=Y.c)};Y.deferInit=Y.W;})();
<commit_msg>JS compile change<commit_after>(function(){var d=window,f=document;function g(a,b){return a.addEventListener=b}function h(a,b){return a.attachEvent=b}
var i="push",j="createElement",l="addEventListener",m="setAttribute",n="attachEvent",o="documentElement",p="length",r="prototype",s="call",t="getAttribute",u="querySelectorAll",v="fireEvent",w="parentNode",x="",y="\n",z='");',B="*",C=":not([psa_not_processed])",D="
_
",E='=document.getElementById("',F="Add to queue str: ",aa="Add to queue url: ",ba="Evaluated: ",G="Exception while evaluating.",ca="Exception while overriding document.readyState.",da="Executed: ",ea="Firefox",fa="Firing Event: ",
ga="HTMLEvents",ha="PSA ERROR: ",H="SCRIPT",ia="Unable to insert nodes, no context element found",ja="[psa_not_processed]",ka="application/ecmascript",la="application/javascript",ma="application/x-ecmascript",na="application/x-javascript",oa="complete",pa="data:text/javascript,",qa="div",ra="dw: ",sa="error",ta="handle_dw: ",I="id",J="language",K="load",ua="loaded",va="loading",L="on",wa="onDOMContentLoaded",M="onafterscripts",N="onbeforescripts",O="onload",xa="onload: ",ya="onreadystatechange",P=
"orig_src",za="orig_type",Aa="psa_dw_target",Q="psa_not_processed",Ba="readyState",Ca="readystatechange",R="script",Da="span",S="src",Ea="text/",Fa="text/ecmascript",T="text/javascript",Ga="text/javascript1.0",Ha="text/javascript1.1",Ia="text/javascript1.2",Ja="text/javascript1.3",Ka="text/javascript1.4",La="text/javascript1.5",Ma="text/jscript",Na="text/livescript",U="text/psajs",Oa="text/x-ecmascript",Pa="text/x-javascript",Qa="true",V="type",Ra="var ",W;d.pagespeed=d.pagespeed||{};
var X=d.pagespeed,Y=function(){this.i=[];this.f=[];this.h=0;this.b=null;this.e=x;this.g={};this.s=[ka,la,ma,na,Fa,T,Ga,Ha,Ia,Ja,Ka,La,Ma,Na,Oa,Pa];this.m=f.getElementById;this.n=f.getElementsByTagName;this.H=f.write;this.I=f.writeln;this.G=f.open;this.F=f.close;this.o=f[l];this.q=d[l];this.p=f[n];this.r=d[n];this.d=0},Z=!1;W=Y[r];W.log=function(a,b){this.f&&(this.f[i](x+a),b&&(this.f[i](b),"undefined"!=typeof console&&"undefined"!=typeof console.log&&console.log(ha+a+b.message)))};
W.u=function(a,b){this.i.splice(b?b:this.i[p],0,a)};W.z=function(a){var b=f[j](R);b.text=a;b[m](V,T);this.b[w].insertBefore(b,this.b)};W.J=function(){for(var a=f.getElementsByTagName(B),b=x,c=0;c<a[p];c++)if(a[c].hasAttribute(I)){var e=a[c][t](I);e&&-1==e.search(/[-:.]/)&&-1==e.search(/^[0-9]/)&&d[e]&&d[e].tagName&&(b+=Ra+e+E+e+z)}b&&this.z(b)};W.C=function(a,b){var c=a[t](P)||a[t](S);c&&this.addUrl(c,a,b);if(!c||!Z)(c=a.innerHTML||a.textContent||a.data)&&this.D(c,a,b)};
W.D=function(a,b,c){if(this.N())this.addUrl(pa+encodeURIComponent(a),b,c);else{this.f[i](F+a);var e=this;this.u(function(){e.b=b;e.k(b);try{e.z(a)}catch(c){e.log(G,c)}e.log(ba+a);e.l()},c)}};Y[r].addStr=Y[r].D;
Y[r].addUrl=function(a,b,c){this.f[i](aa+a);var e=this;this.u(function(){e.b=b;e.k(b);var c=f[j](R);c[m](V,T);var k=function(){e.log(da+a);e.l()};X.w(c,k);X.j(c,sa,k);9>e.c()&&X.j(c,Ca,function(){if(c.readyState==oa||c.readyState==ua)c.onreadystatechange=null,k()});c[m](S,a);if(Z){var A=b.innerHTML||b.textContent||b.data;A&&c.appendChild(f.createTextNode(A))}e.b[w].insertBefore(c,e.b)},c)};Y[r].addUrl=Y[r].addUrl;W=Y[r];
W.k=function(a){if(Z&&f[u]&&!(8>=this.c()))for(var b=f[u](ja),c=0;c<b[p];c++){var e=b.item(c);if(e==a)break;e[t](V)!=U&&e.removeAttribute(Q)}};W.L=function(){if(Z)for(var a=this.n[s](f,B),b=0;b=this.c())&&(f.getElementsByTagName=this.n));this.M();f.open=this.G;f.close=this.F;f.write=this.H;f.writeln=this.I;this[v](0);f.onreadystatechange&&this.exec(f.onreadystatechange,f);this[v](1);this.d=3;this[v](3)};W.l=function(){this.t();this.h<this.i[p]?(this.h++,this.i[this.h-1][s](d)):this.P()};
W.B=function(a){for(var b=[],c=a[p],e=0;e<c;++e)b[i](a.item(e));return b};
W.Q=function(){var a=f[j](Da);a[m](Aa,Qa);f.body.appendChild(a);this.b=a;this.c()&&this.J();this.L();if(Object.defineProperty)try{Object.defineProperty(f,Ba,{configurable:!0,get:function(){return va}})}catch(b){this.log(ca,b)}this.c()&&(f[o].originalDoScroll=f[o].doScroll,f[o].doScroll=function(){throw"psa exception";});this.K();f.writeln=function(a){X.a.v(a+y)};f.write=function(a){X.a.v(a)};f.open=function(){};f.close=function(){};Z&&(f.getElementById=function(a){X.a.t();return X.a.m[s](f,a)},f[u]&&
!(8>=X.a.c())&&(f.getElementsByTagName=function(a){return f[u](a+C)}))};W.aa=function(){2<=this.d||(this[v](2),this.d=2,this.Q(),this.l())};Y[r].run=Y[r].aa;W=Y[r];W.T=function(a){var b=f[j](qa);b.innerHTML=D+a;b.removeChild(b.firstChild);return b};W.V=function(a){var b=a[w];b&&b.removeChild(a)};W.S=function(a,b){for(var c=this.B(a),e=c[p],q=b[w],k=0;k<e;++k){var A=c[k];this.V(A);q.insertBefore(A,b)}};
W.U=function(a){return a.nodeName!=H?!1:a.hasAttribute(V)?(a=a[t](V),!a||-1!=this.s.indexOf(a)):a.hasAttribute(J)?(a=a[t](J),!a||-1!=this.s.indexOf(Ea+a.toLowerCase())):!0};W.A=function(a,b){if(a.childNodes)for(var c=this.B(a.childNodes),e=c[p],q=0;q<e;++q){var k=c[q];Z&&1==k.nodeType&&k[m](Q,x);k.nodeName==H?this.U(k)&&(b[i](k),k[m](za,k.type),k[m](V,U),k[m](P,k.src),k[m](S,x)):this.A(k,b)}};W.R=function(a,b){for(var c=a[p],e=0;e<c;++e)this.C(a[e],b+e)};
W.O=function(a,b,c){var a=this.T(a),e=[];this.A(a,e);c?this.S(a.childNodes,c):this.log(ia);this.R(e,b)};W.t=function(){if(this.e!=x){this.log(ta+this.e);var a=this.e;this.e=x;this.O(a,this.h,this.b)}};W.v=function(a){this.log(ra+a);this.e+=a};W.W=function(a,b){this.log(xa+b.toString());if(3==this.d)b[s](a);else{var c;8>=this.c()||(c=f.createEvent(ga),c.initEvent(K,!1,!1));$(a,O,function(){b[s](a,c)})}};Y[r].addOnloadListeners=Y[r].W;Y[r].Z=function(a){$(d,N,a)};Y[r].addBeforeDeferRunFunctions=Y[r].Z;
Y[r].Y=function(a){$(d,M,a)};Y[r].addAfterDeferRunFunctions=Y[r].Y;Y[r].fireEvent=function(a){this.log(fa+a);for(var a=this.g[a]||[],b=0;b<a[p];++b)this.exec(a[b])};Y[r].exec=function(a,b){try{a[s](b||d)}catch(c){this.log(G,c)}};Y[r].K=function(){d[l]?(g(f,function(a,b,c){$(f,L+a,b,c,X.a.o)}),g(d,function(a,b,c){$(d,L+a,b,c,X.a.q)})):d[n]&&(h(f,function(a,b){$(f,a,b,void 0,X.a.p)}),h(d,function(a,b){$(d,a,b,void 0,X.a.r)}))};
Y[r].M=function(){d[l]?(g(f,this.o),g(d,this.q)):d[n]&&(h(f,this.p),h(d,this.r))};var $=function(a,b,c,e,q){if(!(3<=X.a.d)){if(b==wa||b==ya)b=0;else if(b==O)b=1;else if(b==N)b=2;else if(b==M)b=3;else{q&&q(b,c,e);return}X.a.g[b]||(X.a.g[b]=[]);X.a.g[b][i](function(){c[s](a)})}};Y[r].$=function(){if(!(1<=this.d)){this.d=1;for(var a=f.getElementsByTagName(R),b=a[p],c=0;c<b;++c){var e=a[c];e[t](V)==U&&this.C(e)}}};Y[r].registerScriptTags=Y[r].$;X.w=function(a,b){X.j(a,K,b)};X.addOnload=X.w;
X.j=function(a,b,c){if(a[l])a[l](b,c,!1);else if(a[n])a[n](L+b,c);else{var e=a[L+b];a[L+b]=function(){c[s](this);e&&e[s](this)}}};X.addHandler=X.j;X.outerHTML=function(a){return a.outerHTML||(new XMLSerializer).serializeToString(a)};Y[r].N=function(){return-1!=navigator.userAgent.indexOf(ea)};Y[r].c=function(){var a=/(?:MSIE.(\d+\.\d+))/.exec(navigator.userAgent);return a&&a[1]?f.documentMode||parseFloat(a[1]):NaN};
X.X=function(){X.a||(d.localStorage&&(Z=d.localStorage.defer_js_experimental),X.a=new Y,X.deferJs=X.a)};X.deferInit=X.X;})();
<|endoftext|>


<commit_before>import { addStaticRoute, getUserFromReq } from 'meteor/vulcan:lib'
import { Posts } from '../lib/collections/posts'
import { getCKEditorDocumentId } from '../lib/ckEditorUtils'
import Users from 'meteor/vulcan:users';
import { getSetting } from 'meteor/vulcan:core';
import jwt from 'jsonwebtoken'

const environmentId = getSetting('ckEditor.environmentId', null)
const secretKey = getSetting('ckEditor.secretKey', null)

addStaticRoute('/ckeditor-token', async ({ query }, req, res, next) => {
  const documentId = req.headers['document-id']
  const userId = req.headers['user-id']
  const formType = req.headers['form-type']

  const ckEditorId = getCKEditorDocumentId(documentId, userId, formType)

  const user = await getUserFromReq(req)
  const post = await Posts.findOne(documentId)

  const canEdit = Posts.canEdit(user, post)
  const canView = Posts.checkAccess(user, post)

  let permissions = {}
  if (formType === "new" && userId) {
    permissions = {
      [ckEditorId]: 'write'
    }
  } else if (canEdit) {
    permissions = {
      [ckEditorId]: 'write'
    }
  } else if (canView) {
    permissions = {
      [ckEditorId]: 'view'
    }
  }

  const payload = {
    iss: environmentId,
    user: {
      id: user._id,
      name: Users.getDisplayName(user)
    },
    services: {
      'ckeditor-collaboration': {
        permissions
      }
    }
  };

  const result = jwt.sign( payload, secretKey, { algorithm: 'HS256' } );

  res.end( result );
})<commit_msg>Small fix for CKEditor token<commit_after>import { addStaticRoute, getUserFromReq } from 'meteor/vulcan:lib'
import { Posts } from '../lib/collections/posts'
import { getCKEditorDocumentId } from '../lib/ckEditorUtils'
import Users from 'meteor/vulcan:users';
import { getSetting } from 'meteor/vulcan:core';
import jwt from 'jsonwebtoken'

addStaticRoute('/ckeditor-token', async ({ query }, req, res, next) => {
  const environmentId = getSetting('ckEditor.environmentId', null)
  const secretKey = getSetting('ckEditor.secretKey', null)

  const documentId = req.headers['document-id']
  const userId = req.headers['user-id']
  const formType = req.headers['form-type']

  const ckEditorId = getCKEditorDocumentId(documentId, userId, formType)

  const user = await getUserFromReq(req)
  const post = await Posts.findOne(documentId)

  const canEdit = post && Posts.canEdit(user, post)
  const canView = post && Posts.checkAccess(user, post)

  let permissions = {}
  if (formType === "new" && userId) {
    permissions = {
      [ckEditorId]: 'write'
    }
  } else if (canEdit) {
    permissions = {
      [ckEditorId]: 'write'
    }
  } else if (canView) {
    permissions = {
      [ckEditorId]: 'view'
    }
  }

  const payload = {
    iss: environmentId,
    user: {
      id: user._id,
      name: Users.getDisplayName(user)
    },
    services: {
      'ckeditor-collaboration': {
        permissions
      }
    }
  };

  const result = jwt.sign( payload, secretKey, { algorithm: 'HS256' } );

  res.end( result );
})<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import uniqueId from 'lodash/uniqueId';
import classNames from 'classnames';
import { DefaultAccordionHeader } from './headers';
import css from './Accordion.css';
import { HotKeys } from '../HotKeys';

const propTypes = {
  open: PropTypes.bool,
  id: PropTypes.string,
  contentId: PropTypes.string,
  label: PropTypes.oneOfType([PropTypes.element, PropTypes.string]).isRequired, // eslint-disable-line react/no-unused-prop-types
  displayWhenOpen: PropTypes.element, // eslint-disable-line react/no-unused-prop-types
  displayWhenClosed: PropTypes.element, // eslint-disable-line react/no-unused-prop-types
  onToggle: PropTypes.func, // eslint-disable-line react/no-unused-prop-types
  header: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.func]),
  contentRef: PropTypes.func,
  separator: PropTypes.bool,
  disabled: PropTypes.bool,
  toggleKeyHandlers: PropTypes.object,
  toggleKeyMap: PropTypes.object,
  children: PropTypes.oneOfType([
    PropTypes.node,
  ]).isRequired,
  closedByDefault: PropTypes.bool,
};

class Accordion extends React.Component {
  static defaultProps = {
    header: DefaultAccordionHeader,
    separator: true,
  }

  constructor(props) {
    super(props);

    this.uncontrolledToggle = this.uncontrolledToggle.bind(this);
    this.initializeAccordion = this.initializeAccordion.bind(this);
    this.setContentRef = this.setContentRef.bind(this);
    this.tearDownHandlers = this.tearDownHandlers.bind(this);
    this.syncMaxHeight = this.syncMaxHeight.bind(this);
    this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
    this.collapseRaf = this.collapseRaf.bind(this);

    // ref to content div.
    this.content = null;
    // ref to toggle.
    this.toggle = null;

    // tracked scrollHeight of content div
    this.contentHeight = 0;
    // whether this.contentHeight should be updated (false indicates difference.)
    this.syncedHeight = true;

    // animation callback for expansion requestAnimationFrame (RAF)
    this.expandRAFCallback = null;
    // animation callback for collapsing requestAnimationFrame (RAF)
    this.collapseRAFCallback = null;

    // callback for syncing
    this.syncHeightCallback = null;

    // status indicators for transition - true = mid transition.
    this.transitioningOpen = false;
    this.transitioningClosed = false;

    // id for content div needed for proper area support - either supplied or auto-generated.
    this.contentId = this.initializeContentId();

    // local state may or may not be set up if open prop is passed.
    this.state = this.initializeAccordion();
  }

  componentDidMount() {
    this.syncMaxHeight();
    // fix issue with accordion not animating open if closed on mount.
    if ((Object.prototype.hasOwnProperty.call(this.props, 'open') && this.props.open === false) ||
        (Object.prototype.hasOwnProperty.call(this.state, 'isOpen') && !this.state.isOpen)) {
      this.content.style.maxHeight = '0';
    }
  }

  componentWillUpdate(nextProps, nextState) {
    // prop/state changes to open status set off the animation callbacks.
    let shouldAdjust = false;
    // if using state...
    if (typeof nextState.isOpen === 'boolean') {
      if (nextState.isOpen !== this.state.isOpen) {
        if (nextState.isOpen) {
          this.transitioningOpen = true;
          this.syncedHeight = false;
          this.expandRaf();
        } else {
          shouldAdjust = true;
          this.transitioningClosed = true;
          this.collapseRaf();
        }
      }
    } else if (nextProps.open !== this.props.open) {
      if (nextProps.open) {
        this.transitioningOpen = true;
        this.syncedHeight = false;
        this.expandRaf();
      } else {
        shouldAdjust = true;
        this.transitioningClosed = true;
        this.collapseRaf();
      }
    }

    if (shouldAdjust) {
      this.syncMaxHeight();
    }
  }

  componentWillUnmount() {
    this.tearDownHandlers();
  }

  syncMaxHeight() {
    this.syncHeightCallback = window.requestAnimationFrame(() => {
      this.contentHeight = this.content.scrollHeight;
      this.syncedHeight = true;
      this.forceUpdate();
    });
  }

  collapseRaf() {
    if (this.collapseCallback) { // if there's a collapse in progress, let it finish...
      this.transitioningClosed = false;
      return;
    }
    this.transitioningOpen = false;
    this.collapseCallback = window.requestAnimationFrame(() => {
      this.content.style.maxHeight = `${this.contentHeight}px`;
      window.cancelAnimationFrame(this.collapseCallback);
      this.collapseCallback = window.requestAnimationFrame(() => {
        this.content.style.maxHeight = '0';
        window.cancelAnimationFrame(this.collapseCallback);
        this.collapseCallback = null;
      });
    });
  }

  expandRaf() {
    if (this.expandCallback) {
      this.transitioningOpen = false;
      return;
    }
    this.transitioningClosed = false;
    this.expandCallback = window.requestAnimationFrame(() => {
      // update contentHeight...
      this.contentHeight = this.content.scrollHeight;
      this.content.style.maxHeight = `${this.contentHeight}px`;
      window.cancelAnimationFrame(this.expandCallback);
      this.expandCallback = null;
    });
  }

  initializeAccordion() {
    // if no 'open' boolean is provided, set up our own state...
    if (this.props.open === undefined) {
      if (this.props.closedByDefault) {
        return {};
      }
      return { isOpen: true };
    }
    return {};
  }

  initializeContentId() {
    // generate unique id if no id is provided.
    if (this.props.contentId === undefined) {
      this.contentId = uniqueId('accordion');
    } else {
      this.contentId = this.props.contentId;
    }
  }

  tearDownHandlers() {
    window.cancelAnimationFrame(this.syncHeightCallback);
    window.cancelAnimationFrame(this.expandCallback);
    window.cancelAnimationFrame(this.collapseCallback);
  }

  uncontrolledToggle() {
    this.setState((curState) => {
      const newState = { ...curState };
      newState.isOpen = !curState.isOpen;
      return newState;
    });
  }

  setContentRef(ref) {
    this.content = ref;
    if (this.props.contentRef) {
      this.props.contentRef(ref);
    }
  }

  handleTransitionEnd() {
    if (this.transitioningOpen) {
      this.transitioningOpen = false;
      this.content.style.maxHeight = 'none';
    }
    if (this.transitioningClosed) {
      this.transitioningClosed = false;
    }
  }

  // eslint-disable-next-line class-methods-use-this
  getContentClass(open) {
    return classNames(
      css.content,
      { [`${css.expanded}`]: open },
    );
  }

  // eslint-disable-next-line class-methods-use-this
  getRootClasses() {
    return classNames(
      css.accordion,
      { [css.hasSeparator]: this.props.separator },
      { [`${css.disabled}`]: this.props.disabled },
    );
  }

  render() {
    let open;
    if (this.props.open !== undefined) {
      open = this.props.open;
    } else {
      open = this.state.isOpen;
    }

    let onToggle;
    if (this.props.onToggle && this.props.open !== undefined) {
      onToggle = this.props.onToggle;
    } else {
      onToggle = this.uncontrolledToggle;
    }

    const headerProps = Object.assign({}, this.props, { contentId: this.contentId, toggleRef: (ref) => { this.toggle = ref; }, open, onToggle });
    const headerElement = React.createElement(this.props.header, headerProps);

    return (

        <HotKeys keyMap={this.props.toggleKeyMap} handlers={this.props.toggleKeyHandlers} noWrapper >
          {headerElement}
        </HotKeys>

          {this.props.children}

    );
  }
}
// {this.props.separator &&
}

Accordion.propTypes = propTypes;

export default Accordion;
<commit_msg>Fix flakey accordion ref<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import uniqueId from 'lodash/uniqueId';
import classNames from 'classnames';
import { DefaultAccordionHeader } from './headers';
import css from './Accordion.css';
import { HotKeys } from '../HotKeys';

const propTypes = {
  open: PropTypes.bool,
  id: PropTypes.string,
  contentId: PropTypes.string,
  label: PropTypes.oneOfType([PropTypes.element, PropTypes.string]).isRequired, // eslint-disable-line react/no-unused-prop-types
  displayWhenOpen: PropTypes.element, // eslint-disable-line react/no-unused-prop-types
  displayWhenClosed: PropTypes.element, // eslint-disable-line react/no-unused-prop-types
  onToggle: PropTypes.func, // eslint-disable-line react/no-unused-prop-types
  header: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.func]),
  contentRef: PropTypes.func,
  separator: PropTypes.bool,
  disabled: PropTypes.bool,
  toggleKeyHandlers: PropTypes.object,
  toggleKeyMap: PropTypes.object,
  children: PropTypes.oneOfType([
    PropTypes.node,
  ]).isRequired,
  closedByDefault: PropTypes.bool,
};

class Accordion extends React.Component {
  static defaultProps = {
    header: DefaultAccordionHeader,
    separator: true,
  }

  constructor(props) {
    super(props);

    this.uncontrolledToggle = this.uncontrolledToggle.bind(this);
    this.initializeAccordion = this.initializeAccordion.bind(this);
    this.setContentRef = this.setContentRef.bind(this);
    this.tearDownHandlers = this.tearDownHandlers.bind(this);
    this.syncMaxHeight = this.syncMaxHeight.bind(this);
    this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
    this.collapseRaf = this.collapseRaf.bind(this);

    // ref to content div.
    this.content = null;
    // ref to toggle.
    this.toggle = null;

    // tracked scrollHeight of content div
    this.contentHeight = 0;
    // whether this.contentHeight should be updated (false indicates difference.)
    this.syncedHeight = true;

    // animation callback for expansion requestAnimationFrame (RAF)
    this.expandRAFCallback = null;
    // animation callback for collapsing requestAnimationFrame (RAF)
    this.collapseRAFCallback = null;

    // callback for syncing
    this.syncHeightCallback = null;

    // status indicators for transition - true = mid transition.
    this.transitioningOpen = false;
    this.transitioningClosed = false;

    // id for content div needed for proper area support - either supplied or auto-generated.
    this.contentId = this.initializeContentId();

    // local state may or may not be set up if open prop is passed.
    this.state = this.initializeAccordion();
  }

  componentDidMount() {
    this.syncMaxHeight();
    // fix issue with accordion not animating open if closed on mount.
    if ((Object.prototype.hasOwnProperty.call(this.props, 'open') && this.props.open === false) ||
        (Object.prototype.hasOwnProperty.call(this.state, 'isOpen') && !this.state.isOpen)) {
      this.content.style.maxHeight = '0';
    }
  }

  componentWillUpdate(nextProps, nextState) {
    // prop/state changes to open status set off the animation callbacks.
    let shouldAdjust = false;
    // if using state...
    if (typeof nextState.isOpen === 'boolean') {
      if (nextState.isOpen !== this.state.isOpen) {
        if (nextState.isOpen) {
          this.transitioningOpen = true;
          this.syncedHeight = false;
          this.expandRaf();
        } else {
          shouldAdjust = true;
          this.transitioningClosed = true;
          this.collapseRaf();
        }
      }
    } else if (nextProps.open !== this.props.open) {
      if (nextProps.open) {
        this.transitioningOpen = true;
        this.syncedHeight = false;
        this.expandRaf();
      } else {
        shouldAdjust = true;
        this.transitioningClosed = true;
        this.collapseRaf();
      }
    }

    if (shouldAdjust) {
      this.syncMaxHeight();
    }
  }

  componentWillUnmount() {
    this.tearDownHandlers();
  }

  syncMaxHeight() {
    this.syncHeightCallback = window.requestAnimationFrame(() => {
      this.contentHeight = this.content ? this.content.scrollHeight : 0;
      this.syncedHeight = true;
      this.forceUpdate();
    });
  }

  collapseRaf() {
    if (this.collapseCallback) { // if there's a collapse in progress, let it finish...
      this.transitioningClosed = false;
      return;
    }

    // if there is no content ref, we might get errors
    if (!this.content) return;

    this.transitioningOpen = false;
    this.collapseCallback = window.requestAnimationFrame(() => {
      this.content.style.maxHeight = `${this.contentHeight}px`;
      window.cancelAnimationFrame(this.collapseCallback);
      this.collapseCallback = window.requestAnimationFrame(() => {
        this.content.style.maxHeight = '0';
        window.cancelAnimationFrame(this.collapseCallback);
        this.collapseCallback = null;
      });
    });
  }

  expandRaf() {
    if (this.expandCallback) {
      this.transitioningOpen = false;
      return;
    }
    this.transitioningClosed = false;
    this.expandCallback = window.requestAnimationFrame(() => {
      // update contentHeight...
      this.contentHeight = this.content.scrollHeight;
      this.content.style.maxHeight = `${this.contentHeight}px`;
      window.cancelAnimationFrame(this.expandCallback);
      this.expandCallback = null;
    });
  }

  initializeAccordion() {
    // if no 'open' boolean is provided, set up our own state...
    if (this.props.open === undefined) {
      if (this.props.closedByDefault) {
        return {};
      }
      return { isOpen: true };
    }
    return {};
  }

  initializeContentId() {
    // generate unique id if no id is provided.
    if (this.props.contentId === undefined) {
      this.contentId = uniqueId('accordion');
    } else {
      this.contentId = this.props.contentId;
    }
  }

  tearDownHandlers() {
    window.cancelAnimationFrame(this.syncHeightCallback);
    window.cancelAnimationFrame(this.expandCallback);
    window.cancelAnimationFrame(this.collapseCallback);
  }

  uncontrolledToggle() {
    this.setState((curState) => {
      const newState = { ...curState };
      newState.isOpen = !curState.isOpen;
      return newState;
    });
  }

  setContentRef(ref) {
    this.content = ref;
    if (this.props.contentRef) {
      this.props.contentRef(ref);
    }
  }

  handleTransitionEnd() {
    if (this.transitioningOpen) {
      this.transitioningOpen = false;
      this.content.style.maxHeight = 'none';
    }
    if (this.transitioningClosed) {
      this.transitioningClosed = false;
    }
  }

  // eslint-disable-next-line class-methods-use-this
  getContentClass(open) {
    return classNames(
      css.content,
      { [`${css.expanded}`]: open },
    );
  }

  // eslint-disable-next-line class-methods-use-this
  getRootClasses() {
    return classNames(
      css.accordion,
      { [css.hasSeparator]: this.props.separator },
      { [`${css.disabled}`]: this.props.disabled },
    );
  }

  render() {
    let open;
    if (this.props.open !== undefined) {
      open = this.props.open;
    } else {
      open = this.state.isOpen;
    }

    let onToggle;
    if (this.props.onToggle && this.props.open !== undefined) {
      onToggle = this.props.onToggle;
    } else {
      onToggle = this.uncontrolledToggle;
    }

    const headerProps = Object.assign({}, this.props, { contentId: this.contentId, toggleRef: (ref) => { this.toggle = ref; }, open, onToggle });
    const headerElement = React.createElement(this.props.header, headerProps);

    return (

        <HotKeys keyMap={this.props.toggleKeyMap} handlers={this.props.toggleKeyHandlers} noWrapper >
          {headerElement}
        </HotKeys>

          {this.props.children}

    );
  }
}
// {this.props.separator &&
}

Accordion.propTypes = propTypes;

export default Accordion;
<|endoftext|>


<commit_before>asynctest(
  'tinymce.plugins.paste.webdriver.CutTest',
  [
    'ephox.agar.api.Pipeline',
    'ephox.agar.api.RealMouse',
    'ephox.agar.api.Waiter',
    'ephox.mcagar.api.TinyApis',
    'ephox.mcagar.api.TinyLoader',
    'ephox.mcagar.api.TinyUi',
    'global!window',
    'ephox.sand.api.PlatformDetection',
    'tinymce.plugins.paste.Plugin',
    'tinymce.themes.modern.Theme'
  ],
  function (Pipeline, RealMouse, Waiter, TinyApis, TinyLoader, TinyUi, window, PlatformDetection, PastePlugin, Theme) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];

    Theme();
    PastePlugin();

    var platform = PlatformDetection.detect();

    /* Test does not work on Phantom */
    if (window.navigator.userAgent.indexOf('PhantomJS') > -1) {
      return success();
    }

    TinyLoader.setup(function (editor, onSuccess, onFailure) {
      var api = TinyApis(editor);
      var ui = TinyUi(editor);

      // Cut doesn't seem to work in webdriver mode on ie, firefox is producing moveto not supported
      Pipeline.async({}, (platform.browser.isIE() || platform.browser.isFirefox()) ? [] : [
        api.sSetContent('
abc
'),
        api.sSetSelection([0, 0], 1, [0, 0], 2),
        ui.sClickOnMenu("Click Edit menu", 'button:contains("Edit")'),
        ui.sWaitForUi("Wait for dropdown", '.mce-floatpanel[role="application"]'),
        RealMouse.sClickOn('.mce-i-cut'),
        Waiter.sTryUntil('Cut is async now, so need to wait for content', api.sAssertContent('
ac
'), 100, 1000)
      ], onSuccess, onFailure);
    }, {
      skin_url: '/project/src/skins/lightgray/dist/lightgray',
      plugins: 'paste'
    }, success, failure);
  }
);<commit_msg>disabled cut test for edge since it was failing at random<commit_after>asynctest(
  'tinymce.plugins.paste.webdriver.CutTest',
  [
    'ephox.agar.api.Pipeline',
    'ephox.agar.api.RealMouse',
    'ephox.agar.api.Waiter',
    'ephox.mcagar.api.TinyApis',
    'ephox.mcagar.api.TinyLoader',
    'ephox.mcagar.api.TinyUi',
    'global!window',
    'ephox.sand.api.PlatformDetection',
    'tinymce.plugins.paste.Plugin',
    'tinymce.themes.modern.Theme'
  ],
  function (Pipeline, RealMouse, Waiter, TinyApis, TinyLoader, TinyUi, window, PlatformDetection, PastePlugin, Theme) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];

    Theme();
    PastePlugin();

    var platform = PlatformDetection.detect();

    /* Test does not work on Phantom */
    if (window.navigator.userAgent.indexOf('PhantomJS') > -1) {
      return success();
    }

    TinyLoader.setup(function (editor, onSuccess, onFailure) {
      var api = TinyApis(editor);
      var ui = TinyUi(editor);

      // Cut doesn't seem to work in webdriver mode on ie, firefox is producing moveto not supported, edge fails if it's not observed
      Pipeline.async({}, (platform.browser.isIE() || platform.browser.isFirefox() || platform.browser.isEdge()) ? [] : [
        api.sSetContent('
abc
'),
        api.sSetSelection([0, 0], 1, [0, 0], 2),
        ui.sClickOnMenu("Click Edit menu", 'button:contains("Edit")'),
        ui.sWaitForUi("Wait for dropdown", '.mce-floatpanel[role="application"]'),
        RealMouse.sClickOn('.mce-i-cut'),
        Waiter.sTryUntil('Cut is async now, so need to wait for content', api.sAssertContent('
ac
'), 100, 1000)
      ], onSuccess, onFailure);
    }, {
      skin_url: '/project/src/skins/lightgray/dist/lightgray',
      plugins: 'paste'
    }, success, failure);
  }
);<|endoftext|>


<commit_before>var mongodb = require("mongodb");

exports.Driver = Driver;

function Driver(config, connection, opts) {
	this.client = new mongodb.MongoClient();
	this.db     = null;
	this.config = config || {};
	this.opts   = opts || {};
}

Driver.prototype.sync = function (opts, cb) {
	if (typeof cb == "function") {
		return process.nextTick(cb);
	}
};

Driver.prototype.drop = function (opts, cb) {
	if (typeof cb == "function") {
		return process.nextTick(cb);
	}
};

Driver.prototype.ping = function (cb) {
	return process.nextTick(cb);
};

Driver.prototype.on = function (ev, cb) {
	// if (ev == "error") {
	// 	this.db.on("error", cb);
	// 	this.db.on("unhandledError", cb);
	// }
	return this;
};

Driver.prototype.connect = function (cb) {
	console.log("connecting...");
	this.client.connect(this.config.href, function (err, db) {
		console.log("err", err);
		if (err) {
			return cb(err);
		}

		this.db = db;

		return cb();
	}.bind(this));
};

Driver.prototype.close = function (cb) {
	if (this.db) {
		this.db.close();
	}
	if (typeof cb == "function") {
		cb();
	}
	return;
};

Driver.prototype.find = function (fields, table, conditions, opts, cb) {
	var collection = this.db.collection(table);
	var cursor     = collection.find(conditions, fields);

	if (opts.order) {
		var orders = [];

		for (var i = 0; i < opts.order.length; i++) {
			orders.push([ opts.order[i][0], (opts.order[i][1] == 'Z' ? 'desc' : 'asc') ]);
		}
		cursor.sort(orders);
	}
	if (opts.offset) {
		cursor.skip(opts.offset);
	}
	if (opts.limit) {
		cursor.limit(opts.limit);
	}

	return cursor.toArray(function (err, docs) {
		for (var i = 0; i < docs.length; i++) {
			docs[i]._id = docs[i]._id.toString();
		}
		return cb(err, docs);
	});
};

Driver.prototype.count = function (table, conditions, opts, cb) {
	var collection = this.db.collection(table);
	var cursor     = collection.find(conditions);

	if (opts.order) {
		var orders = [];

		for (var i = 0; i < opts.order.length; i++) {
			orders.push([ opts.order[i][0], (opts.order[i][1] == 'Z' ? 'desc' : 'asc') ]);
		}
		cursor.sort(orders);
	}
	if (opts.offset) {
		cursor.skip(opts.offset);
	}
	if (opts.limit) {
		cursor.limit(opts.limit);
	}

	return cursor.count(true, cb);
};

Driver.prototype.insert = function (table, data, id_prop, cb) {
	convertToDB(data);

	return this.db.collection(table).insert(
		data,
		{
			w : 1
		},
		function (err, docs) {
			if (err) return cb(err);

			var ids = {};

			if (id_prop !== null && docs.length) {
				for (var k in docs[0]) {
					if (id_prop.indexOf(k) >= 0) {
						ids[k] = docs[0][k];
					}
				}
				convertFromDB(ids);
			}

			return cb(null, ids);
		}
	);
};

Driver.prototype.update = function (table, changes, conditions, cb) {
	convertToDB(conditions);

	return this.db.collection(table).update(
		conditions,
		{
			$set   : changes
		},
		{
			safe   : true,
			upsert : true
		},
		cb
	);
};

Driver.prototype.remove = function (table, conditions, cb) {
	return this.db.collection(table).remove(conditions, cb);
};

Driver.prototype.clear = function (table, cb) {
	return this.db.collection(table).drop(cb);
};

function convertToDB(obj) {
	for (var k in obj) {
		if (k == "_id") {
			if (obj[k] instanceof mongodb.ObjectID) {
				console.log("!!!!!!!!");
			}
			obj[k] = new mongodb.ObjectID(obj[k]);
		}
	}
}

function convertFromDB(obj) {
	for (var k in obj) {
		if (obj[k] instanceof mongodb.ObjectID) {
			obj[k] = obj[k].toString();
		}
	}
}
<commit_msg>Removes debug log lines<commit_after>var mongodb = require("mongodb");

exports.Driver = Driver;

function Driver(config, connection, opts) {
	this.client = new mongodb.MongoClient();
	this.db     = null;
	this.config = config || {};
	this.opts   = opts || {};
}

Driver.prototype.sync = function (opts, cb) {
	if (typeof cb == "function") {
		return process.nextTick(cb);
	}
};

Driver.prototype.drop = function (opts, cb) {
	if (typeof cb == "function") {
		return process.nextTick(cb);
	}
};

Driver.prototype.ping = function (cb) {
	return process.nextTick(cb);
};

Driver.prototype.on = function (ev, cb) {
	// if (ev == "error") {
	// 	this.db.on("error", cb);
	// 	this.db.on("unhandledError", cb);
	// }
	return this;
};

Driver.prototype.connect = function (cb) {
	this.client.connect(this.config.href, function (err, db) {
		if (err) {
			return cb(err);
		}

		this.db = db;

		return cb();
	}.bind(this));
};

Driver.prototype.close = function (cb) {
	if (this.db) {
		this.db.close();
	}
	if (typeof cb == "function") {
		cb();
	}
	return;
};

Driver.prototype.find = function (fields, table, conditions, opts, cb) {
	var collection = this.db.collection(table);
	var cursor     = collection.find(conditions, fields);

	if (opts.order) {
		var orders = [];

		for (var i = 0; i < opts.order.length; i++) {
			orders.push([ opts.order[i][0], (opts.order[i][1] == 'Z' ? 'desc' : 'asc') ]);
		}
		cursor.sort(orders);
	}
	if (opts.offset) {
		cursor.skip(opts.offset);
	}
	if (opts.limit) {
		cursor.limit(opts.limit);
	}

	return cursor.toArray(function (err, docs) {
		for (var i = 0; i < docs.length; i++) {
			docs[i]._id = docs[i]._id.toString();
		}
		return cb(err, docs);
	});
};

Driver.prototype.count = function (table, conditions, opts, cb) {
	var collection = this.db.collection(table);
	var cursor     = collection.find(conditions);

	if (opts.order) {
		var orders = [];

		for (var i = 0; i < opts.order.length; i++) {
			orders.push([ opts.order[i][0], (opts.order[i][1] == 'Z' ? 'desc' : 'asc') ]);
		}
		cursor.sort(orders);
	}
	if (opts.offset) {
		cursor.skip(opts.offset);
	}
	if (opts.limit) {
		cursor.limit(opts.limit);
	}

	return cursor.count(true, cb);
};

Driver.prototype.insert = function (table, data, id_prop, cb) {
	convertToDB(data);

	return this.db.collection(table).insert(
		data,
		{
			w : 1
		},
		function (err, docs) {
			if (err) return cb(err);

			var ids = {};

			if (id_prop !== null && docs.length) {
				for (var k in docs[0]) {
					if (id_prop.indexOf(k) >= 0) {
						ids[k] = docs[0][k];
					}
				}
				convertFromDB(ids);
			}

			return cb(null, ids);
		}
	);
};

Driver.prototype.update = function (table, changes, conditions, cb) {
	convertToDB(conditions);

	return this.db.collection(table).update(
		conditions,
		{
			$set   : changes
		},
		{
			safe   : true,
			upsert : true
		},
		cb
	);
};

Driver.prototype.remove = function (table, conditions, cb) {
	return this.db.collection(table).remove(conditions, cb);
};

Driver.prototype.clear = function (table, cb) {
	return this.db.collection(table).drop(cb);
};

function convertToDB(obj) {
	for (var k in obj) {
		if (k == "_id") {
			obj[k] = new mongodb.ObjectID(obj[k]);
		}
	}
}

function convertFromDB(obj) {
	for (var k in obj) {
		if (obj[k] instanceof mongodb.ObjectID) {
			obj[k] = obj[k].toString();
		}
	}
}
<|endoftext|>


<commit_before>sap.ui.define([
	"sap/ui/rta/RuntimeAuthoring",
	"sap/ui/rta/plugin/Plugin",
	"sap/ui/dt/DesignTime",
	"sap/ui/fl/Utils",
	"sap/ui/fl/registry/Settings",
	"sap/ui/fl/write/api/PersistenceWriteAPI",
	"sap/ui/thirdparty/sinon-4"
], function(
	RuntimeAuthoring,
	Plugin,
	DesignTime,
	FlexUtils,
	FlexSettings,
	PersistenceWriteAPI,
	sinon
) {
	"use strict";

	var sandbox = sinon.sandbox.create();
	var oManifest = {
		"sap.app" : {
			applicationVersion : {
				version : "1.2.3"
			}
		}
	};

	var oMockedAppComponent = {
		getManifestEntry: function () {
			return {};
		},
		getMetadata: function () {
			return {
				getName: function () {
					return "someName";
				},
				getManifest: function () {
					return oManifest;
				}
			};
		},
		getManifest: function () {
			return oManifest;
		},
		getModel: function () {},
		getLocalId: function() {}
	};

	var Util = {

		_createStartRtaFunction: function(oRuntimeAuthoring) {
			return function() {
				return Promise.all([
					new Promise(function (fnResolve) {
						oRuntimeAuthoring.attachStart(fnResolve);
					}),
					oRuntimeAuthoring.start()
				]);
			};
		},

		_defineTestStubs: function() {
			sandbox.stub(FlexSettings, "getInstance").returns(Promise.resolve({
				isProductiveSystem: function() { return false; }
			}));
			sandbox.stub(FlexUtils, "getAppComponentForControl").returns(oMockedAppComponent);
			sandbox.stub(PersistenceWriteAPI, "hasChangesToPublish").resolves(false);
		},

		startRta: function(oHorizontalLayout, aPlugins) {
			var oRuntimeAuthoring = new RuntimeAuthoring({
				rootControl: oHorizontalLayout,
				showToolbars: false
			});
			if (aPlugins && Array.isArray(aPlugins)) {
				if (!aPlugins.length) {
					aPlugins.push(new Plugin("abc"));
				}
				oRuntimeAuthoring.setPlugins(aPlugins);
			}
			Util._defineTestStubs(oRuntimeAuthoring);

			// will result in custom timer in webPageTest
			window.performance.mark("rta.start.starts");

			return oRuntimeAuthoring.start()
			.then(function() {
				var sMeasureName = "RTA start function called";
				//will result in custom timer in webPageTest
				window.performance.mark("rta.start.ends");
				window.performance.measure(sMeasureName, "rta.start.starts", "rta.start.ends");
				sap.ui.rta.startTime = window.performance.getEntriesByName(sMeasureName)[0].duration;
				jQuery.sap.log.info(sMeasureName, sap.ui.rta.startTime + "ms");
				//visual change at the end
				var oOverlay = sap.ui.dt.OverlayRegistry.getOverlay(oHorizontalLayout);
				oOverlay.setSelected(true);
			})
			.then(function() {
				sandbox.restore();
			});
		},

		startRtaWithoutStretch: function(oRootControl) {
			var oRuntimeAuthoring = new RuntimeAuthoring({
				rootControl: oRootControl
			});
			var mPlugins = oRuntimeAuthoring.getDefaultPlugins();
			delete mPlugins["stretch"];
			oRuntimeAuthoring.setPlugins(mPlugins);

			Util._defineTestStubs(oRuntimeAuthoring);

			// will result in custom timer in webPageTest
			window.performance.mark("rta.start.starts");

			return oRuntimeAuthoring.start()
			.then(function() {
				var sMeasureName = "RTA start function called";
				//will result in custom timer in webPageTest
				window.performance.mark("rta.start.ends");
				window.performance.measure(sMeasureName, "rta.start.starts", "rta.start.ends");
				sap.ui.rta.startTime = window.performance.getEntriesByName(sMeasureName)[0].duration;
				jQuery.sap.log.info(sMeasureName, sap.ui.rta.startTime + "ms");
				//visual change at the end
				var oOverlay = sap.ui.dt.OverlayRegistry.getOverlay(oRootControl);
				oOverlay.setSelected(true);
			})
			.then(function() {
				sandbox.restore();
			});
		},

		startRtaConstructorOnly: function(oHorizontalLayout) {
			var iRtaStartCounter = 1000;
			var sMeasureName = "RTA init function called " + iRtaStartCounter + " times";
			window.performance.clearMeasures();

			// will result in custom timer in webPageTest
			window.performance.mark("rta.init.starts");

			for (var i = 0; i < iRtaStartCounter; i++) {
				/* eslint no-new: 0 */
				new RuntimeAuthoring({
					rootControl : oHorizontalLayout
				});
			}

			//will result in custom timer in webPageTest
			window.performance.mark("rta.init.ends");
			window.performance.measure(sMeasureName, "rta.init.starts", "rta.init.ends");
			sap.ui.rta.creationTime = window.performance.getEntriesByName(sMeasureName)[0].duration;
			jQuery.sap.log.info(sMeasureName, sap.ui.rta.creationTime + "ms");
		}
	};

	window.startRta = Util.startRta;
	window.startRtaConstructorOnly = Util.startRtaConstructorOnly;

	return Util;
}, true);
<commit_msg>[INTERNAL] sap.ui.dt: fix performance tests<commit_after>sap.ui.define([
	"sap/ui/rta/RuntimeAuthoring",
	"sap/ui/rta/plugin/Plugin",
	"sap/ui/fl/Utils",
	"sap/ui/fl/registry/Settings",
	"sap/ui/fl/write/api/PersistenceWriteAPI",
	"sap/ui/thirdparty/sinon-4"
], function(
	RuntimeAuthoring,
	Plugin,
	FlexUtils,
	FlexSettings,
	PersistenceWriteAPI,
	sinon
) {
	"use strict";

	var sandbox = sinon.sandbox.create();
	var oManifest = {
		"sap.app" : {
			applicationVersion : {
				version : "1.2.3"
			}
		}
	};

	var oMockedAppComponent = {
		getManifestEntry: function () {
			return {};
		},
		getMetadata: function () {
			return {
				getName: function () {
					return "someName";
				},
				getManifest: function () {
					return oManifest;
				}
			};
		},
		getManifest: function () {
			return oManifest;
		},
		getModel: function () {},
		getLocalId: function() {}
	};

	var Util = {
		_createStartRtaFunction: function(oRuntimeAuthoring) {
			return function() {
				return Promise.all([
					new Promise(function (fnResolve) {
						oRuntimeAuthoring.attachStart(fnResolve);
					}),
					oRuntimeAuthoring.start()
				]);
			};
		},

		_defineTestStubs: function() {
			sandbox.stub(FlexSettings, "getInstance").returns(Promise.resolve({
				isProductiveSystem: function() { return false; }
			}));
			sandbox.stub(FlexUtils, "getAppComponentForControl").returns(oMockedAppComponent);
			sandbox.stub(PersistenceWriteAPI, "isPublishEnabled").resolves(false);
		},

		startRta: function(oHorizontalLayout, aPlugins) {
			var oRuntimeAuthoring = new RuntimeAuthoring({
				rootControl: oHorizontalLayout,
				showToolbars: false
			});
			if (aPlugins && Array.isArray(aPlugins)) {
				if (!aPlugins.length) {
					aPlugins.push(new Plugin("abc"));
				}
				oRuntimeAuthoring.setPlugins(aPlugins);
			}
			Util._defineTestStubs(oRuntimeAuthoring);

			// will result in custom timer in webPageTest
			window.performance.mark("rta.start.starts");

			return oRuntimeAuthoring.start()
			.then(function() {
				var sMeasureName = "RTA start function called";
				//will result in custom timer in webPageTest
				window.performance.mark("rta.start.ends");
				window.performance.measure(sMeasureName, "rta.start.starts", "rta.start.ends");
				sap.ui.rta.startTime = window.performance.getEntriesByName(sMeasureName)[0].duration;
				jQuery.sap.log.info(sMeasureName, sap.ui.rta.startTime + "ms");
				//visual change at the end
				var oOverlay = sap.ui.dt.OverlayRegistry.getOverlay(oHorizontalLayout);
				oOverlay.setSelected(true);
			})
			.then(function() {
				sandbox.restore();
			});
		},

		startRtaWithoutStretch: function(oRootControl) {
			var oRuntimeAuthoring = new RuntimeAuthoring({
				rootControl: oRootControl
			});
			var mPlugins = oRuntimeAuthoring.getDefaultPlugins();
			delete mPlugins["stretch"];
			oRuntimeAuthoring.setPlugins(mPlugins);

			Util._defineTestStubs(oRuntimeAuthoring);

			// will result in custom timer in webPageTest
			window.performance.mark("rta.start.starts");

			return oRuntimeAuthoring.start()
			.then(function() {
				var sMeasureName = "RTA start function called";
				//will result in custom timer in webPageTest
				window.performance.mark("rta.start.ends");
				window.performance.measure(sMeasureName, "rta.start.starts", "rta.start.ends");
				sap.ui.rta.startTime = window.performance.getEntriesByName(sMeasureName)[0].duration;
				jQuery.sap.log.info(sMeasureName, sap.ui.rta.startTime + "ms");
				//visual change at the end
				var oOverlay = sap.ui.dt.OverlayRegistry.getOverlay(oRootControl);
				oOverlay.setSelected(true);
			})
			.then(function() {
				sandbox.restore();
			});
		},

		startRtaConstructorOnly: function(oHorizontalLayout) {
			var iRtaStartCounter = 1000;
			var sMeasureName = "RTA init function called " + iRtaStartCounter + " times";
			window.performance.clearMeasures();

			// will result in custom timer in webPageTest
			window.performance.mark("rta.init.starts");

			for (var i = 0; i < iRtaStartCounter; i++) {
				/* eslint no-new: 0 */
				new RuntimeAuthoring({
					rootControl : oHorizontalLayout
				});
			}

			//will result in custom timer in webPageTest
			window.performance.mark("rta.init.ends");
			window.performance.measure(sMeasureName, "rta.init.starts", "rta.init.ends");
			sap.ui.rta.creationTime = window.performance.getEntriesByName(sMeasureName)[0].duration;
			jQuery.sap.log.info(sMeasureName, sap.ui.rta.creationTime + "ms");
		}
	};

	window.startRta = Util.startRta;
	window.startRtaConstructorOnly = Util.startRtaConstructorOnly;

	return Util;
}, true);
<|endoftext|>


<commit_before>var RawSource = require("webpack-core/lib/RawSource");

function EntryManifestPlugin(options) {
  options = options || {};
  this.manifestFilename = options.filename || "manifest.json";
  this.manifestVariable = options.manifestVariable || "webpackManifest";
}
module.exports = EntryManifestPlugin;

EntryManifestPlugin.prototype.constructor = EntryManifestPlugin;
EntryManifestPlugin.prototype.apply = function(compiler) {
  var manifestFilename = this.manifestFilename;
  var manifestVariable = this.manifestVariable;

  compiler.plugin("this-compilation", function(compilation) {
    var mainTemplate = compilation.mainTemplate;
    mainTemplate.plugin("require-ensure", function(_, chunk, hash) {
      var filename = this.outputOptions.filename;
      var chunkManifest;

      if (filename) {
        chunkManifest = [chunk].reduce(function registerChunk(manifest, c) {
          if(c.id in manifest) return manifest;

          if(c.entry) {
            manifest[c.id] = undefined;
          } else {
            manifest[c.id] = mainTemplate.applyPluginsWaterfall("asset-path", filename, {
              hash: hash,
              chunk: c
            });
          }
          return c.chunks.reduce(registerChunk, manifest);
        }, {});
        this.outputOptions.chunkFilename = "__ENTRY_MANIFEST__";
        // mark as asset for emitting
        compilation.assets[manifestFilename] = new RawSource(JSON.stringify(chunkManifest));
      }

      return _;
    });
  });

  compiler.plugin("compilation", function(compilation) {
    compilation.mainTemplate.plugin("require-ensure", function(_, chunk, hash, chunkIdVar) {
      return _.replace("\"__ENTRY_MANIFEST__\"",
        "window[\"" + manifestVariable + "\"][" + chunkIdVar + "]");
    });
  });
};
<commit_msg>Fix issue with recompiling bundles<commit_after>var RawSource = require("webpack-core/lib/RawSource");

function EntryManifestPlugin(options) {
  options = options || {};
  this.manifestFilename = options.filename || "manifest.json";
  this.manifestVariable = options.manifestVariable || "webpackManifest";
}
module.exports = EntryManifestPlugin;

EntryManifestPlugin.prototype.constructor = EntryManifestPlugin;
EntryManifestPlugin.prototype.apply = function(compiler) {
  var manifestFilename = this.manifestFilename;
  var manifestVariable = this.manifestVariable;
  var oldChunkFilename;

  compiler.plugin("this-compilation", function(compilation) {
    var mainTemplate = compilation.mainTemplate;
    mainTemplate.plugin("require-ensure", function(_, chunk, hash) {
      var filename = this.outputOptions.filename;
      var chunkManifest;

      if (filename) {
        chunkManifest = [chunk].reduce(function registerChunk(manifest, c) {
          if(c.id in manifest) return manifest;

          if(c.entry) {
            manifest[c.id] = undefined;
          } else {
            manifest[c.id] = mainTemplate.applyPluginsWaterfall("asset-path", filename, {
              hash: hash,
              chunk: c
            });
          }
          return c.chunks.reduce(registerChunk, manifest);
        }, {});
        oldChunkFilename = this.outputOptions.chunkFilename;
        this.outputOptions.chunkFilename = "__CHUNK_MANIFEST__";
        // mark as asset for emitting
        compilation.assets[manifestFilename] = new RawSource(JSON.stringify(chunkManifest));
      }

      return _;
    });
  });

  compiler.plugin("compilation", function(compilation) {
    compilation.mainTemplate.plugin("require-ensure", function(_, chunk, hash, chunkIdVar) {
      if (oldChunkFilename) {
        this.outputOptions.chunkFilename = oldChunkFilename;
      }

      return _.replace("\"__CHUNK_MANIFEST__\"",
        "window[\"" + manifestVariable + "\"][" + chunkIdVar + "]");
    });
  });
};
<|endoftext|>