<commit_before>import {List, Map} from 'immutable';

import {
  SELECT_TOOL_DRAWING_LINE,
  BEGIN_DRAWING_LINE,
  UPDATE_DRAWING_LINE,
  END_DRAWING_LINE,
  BEGIN_DRAGGING_LINE,
  UPDATE_DRAGGING_LINE,
  END_DRAGGING_LINE,

  MODE_IDLE,
  MODE_WAITING_DRAWING_LINE,
  MODE_DRAWING_LINE,
  MODE_DRAGGING_LINE
} from '../constants';

import * as Geometry from '../utils/geometry';
import {
  addLine,
  replaceLineVertex,
  removeLine,
  select,
  unselect,
  addLineAvoidingIntersections,
  unselectAll,
  detectAndUpdateAreas,
} from '../utils/layer-operations';
import {nearestSnap, addPointSnap, addLineSnap, addLineSegmentSnap} from '../utils/snap';
import {sceneSnapElements, vertexSnapElements} from '../utils/snap-scene';

export default function (state, action) {
  switch (action.type) {
    case SELECT_TOOL_DRAWING_LINE:
      return selectToolDrawingLine(state, action.sceneComponentType);

    case BEGIN_DRAWING_LINE:
      return beginDrawingLine(state, action.layerID, action.x, action.y);

    case UPDATE_DRAWING_LINE:
      return updateDrawingLine(state, action.x, action.y);

    case END_DRAWING_LINE:
      return endDrawingLine(state, action.x, action.y);

    case BEGIN_DRAGGING_LINE:
      return beginDraggingLine(state, action.layerID, action.lineID, action.x, action.y);

    case UPDATE_DRAGGING_LINE:
      return updateDraggingLine(state, action.x, action.y);

    case END_DRAGGING_LINE:
      return endDraggingLine(state, action.x, action.y);

    default:
      return state;
  }
}

function selectToolDrawingLine(state, sceneComponentType) {
  return state.merge({
    mode: MODE_WAITING_DRAWING_LINE,
    drawingSupport: Map({
      type: sceneComponentType
    })
  });
}

/** lines operations **/
function beginDrawingLine(state, layerID, x, y) {

  //calculate snap and overwrite coords if needed
  let snapElements = sceneSnapElements(state.scene);
  let snap = nearestSnap(snapElements, x, y);
  if (snap) ({x, y} = snap.point);

  snapElements = snapElements.withMutations(snapElements => {
    let a, b, c;
    ({a, b, c} = Geometry.horizontalLine(y));
    addLineSnap(snapElements, a, b, c, 10, 3, null);
    ({a, b, c} = Geometry.verticalLine(x));
    addLineSnap(snapElements, a, b, c, 10, 3, null);
  });

  let drawingSupport = state.get('drawingSupport').set('layerID', layerID);
  let scene = state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
    unselectAll(layer);
    let {line} = addLine(layer, drawingSupport.get('type'), x, y, x, y);
    select(layer, 'lines', line.id);
    select(layer, 'vertices', line.vertices.get(0));
    select(layer, 'vertices', line.vertices.get(1));
  }));

  return state.merge({
    mode: MODE_DRAWING_LINE,
    scene,
    snapElements,
    activeSnapElement: snap ? snap.snap : null,
    drawingSupport
  });
}

function updateDrawingLine(state, x, y) {

  //calculate snap and overwrite coords if needed
  let snap = nearestSnap(state.snapElements, x, y);
  if (snap) ({x, y} = snap.point);

  let layerID = state.getIn(['drawingSupport', 'layerID']);
  let scene = state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
    let lineID = layer.getIn(['selected', 'lines']).first();
    let vertex;
    ({layer, vertex} = replaceLineVertex(layer, lineID, 1, x, y));
    select(layer, 'vertices', vertex.id);
    return layer;
  }));

  return state.merge({
    scene,
    activeSnapElement: snap ? snap.snap : null,
  });
}

function endDrawingLine(state, x, y) {
  //calculate snap and overwrite coords if needed
  let snap = nearestSnap(state.snapElements, x, y);
  if (snap) ({x, y} = snap.point);

  let layerID = state.getIn(['drawingSupport', 'layerID']);
  let scene = state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
    let lineID = layer.getIn(['selected', 'lines']).first();
    let line = layer.getIn(['lines', lineID]);
    let v0 = layer.vertices.get(line.vertices.get(0));

    unselect(layer, 'lines', lineID);
    unselect(layer, 'vertices', line.vertices.get(0));
    unselect(layer, 'vertices', line.vertices.get(1));
    removeLine(layer, lineID);
    addLineAvoidingIntersections(layer, line.type, v0.x, v0.y, x, y);
    detectAndUpdateAreas(layer);
  }));

  return state.merge({
    mode: MODE_WAITING_DRAWING_LINE,
    scene,
    snapElements: new List(),
    activeSnapElement: null,
  });
}

function beginDraggingLine(state, layerID, lineID, x, y) {
  let layer = state.scene.layers.get(layerID);
  let line = layer.lines.get(lineID);

  let vertex0 = layer.vertices.get(line.vertices.get(0));
  let vertex1 = layer.vertices.get(line.vertices.get(1));

  return state.merge({
    mode: MODE_DRAGGING_LINE,
    draggingSupport: Map({
      layerID, lineID,
      startPointX: x,
      startPointY: y,
      startVertex0X: vertex0.x,
      startVertex0Y: vertex0.y,
      startVertex1X: vertex1.x,
      startVertex1Y: vertex1.y,
    })
  })
}

function updateDraggingLine(state, x, y) {
  let draggingSupport = state.draggingSupport;

  let layerID = draggingSupport.get('layerID');
  let lineID = draggingSupport.get('lineID');
  let diffX = x - draggingSupport.get('startPointX');
  let diffY = y - draggingSupport.get('startPointY');
  let newVertex0X = draggingSupport.get('startVertex0X') + diffX;
  let newVertex0Y = draggingSupport.get('startVertex0Y') + diffY;
  let newVertex1X = draggingSupport.get('startVertex1X') + diffX;
  let newVertex1Y = draggingSupport.get('startVertex1Y') + diffY;

  return state.updateIn(['scene', 'layers', layerID], layer => layer.withMutations(layer => {
    let lineVertices = layer.getIn(['lines', lineID, 'vertices']);
    layer.updateIn(['vertices', lineVertices.get(0)], vertex => vertex.merge({x: newVertex0X, y: newVertex0Y}));
    layer.updateIn(['vertices', lineVertices.get(1)], vertex => vertex.merge({x: newVertex1X, y: newVertex1Y}));
    return layer;
  }));
}

function endDraggingLine(state, x, y) {
  return state.withMutations(state => {
    updateDraggingLine(state, x, y);
    state.merge({
      mode: MODE_IDLE,
      draggingSupport: null,
    });
  });
}
<commit_msg>adds snap on dragging line<commit_after>import {List, Map} from 'immutable';

import {
  SELECT_TOOL_DRAWING_LINE,
  BEGIN_DRAWING_LINE,
  UPDATE_DRAWING_LINE,
  END_DRAWING_LINE,
  BEGIN_DRAGGING_LINE,
  UPDATE_DRAGGING_LINE,
  END_DRAGGING_LINE,

  MODE_IDLE,
  MODE_WAITING_DRAWING_LINE,
  MODE_DRAWING_LINE,
  MODE_DRAGGING_LINE
} from '../constants';

import * as Geometry from '../utils/geometry';
import {
  addLine,
  replaceLineVertex,
  removeLine,
  select,
  unselect,
  addLineAvoidingIntersections,
  unselectAll,
  detectAndUpdateAreas,
} from '../utils/layer-operations';
import {nearestSnap, addPointSnap, addLineSnap, addLineSegmentSnap} from '../utils/snap';
import {sceneSnapElements, vertexSnapElements} from '../utils/snap-scene';

export default function (state, action) {
  switch (action.type) {
    case SELECT_TOOL_DRAWING_LINE:
      return selectToolDrawingLine(state, action.sceneComponentType);

    case BEGIN_DRAWING_LINE:
      return beginDrawingLine(state, action.layerID, action.x, action.y);

    case UPDATE_DRAWING_LINE:
      return updateDrawingLine(state, action.x, action.y);

    case END_DRAWING_LINE:
      return endDrawingLine(state, action.x, action.y);

    case BEGIN_DRAGGING_LINE:
      return beginDraggingLine(state, action.layerID, action.lineID, action.x, action.y);

    case UPDATE_DRAGGING_LINE:
      return updateDraggingLine(state, action.x, action.y);

    case END_DRAGGING_LINE:
      return endDraggingLine(state, action.x, action.y);

    default:
      return state;
  }
}

function selectToolDrawingLine(state, sceneComponentType) {
  return state.merge({
    mode: MODE_WAITING_DRAWING_LINE,
    drawingSupport: Map({
      type: sceneComponentType
    })
  });
}

/** lines operations **/
function beginDrawingLine(state, layerID, x, y) {

  //calculate snap and overwrite coords if needed
  let snapElements = sceneSnapElements(state.scene);
  let snap = nearestSnap(snapElements, x, y);
  if (snap) ({x, y} = snap.point);

  snapElements = snapElements.withMutations(snapElements => {
    let a, b, c;
    ({a, b, c} = Geometry.horizontalLine(y));
    addLineSnap(snapElements, a, b, c, 10, 3, null);
    ({a, b, c} = Geometry.verticalLine(x));
    addLineSnap(snapElements, a, b, c, 10, 3, null);
  });

  let drawingSupport = state.get('drawingSupport').set('layerID', layerID);
  let scene = state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
    unselectAll(layer);
    let {line} = addLine(layer, drawingSupport.get('type'), x, y, x, y);
    select(layer, 'lines', line.id);
    select(layer, 'vertices', line.vertices.get(0));
    select(layer, 'vertices', line.vertices.get(1));
  }));

  return state.merge({
    mode: MODE_DRAWING_LINE,
    scene,
    snapElements,
    activeSnapElement: snap ? snap.snap : null,
    drawingSupport
  });
}

function updateDrawingLine(state, x, y) {

  //calculate snap and overwrite coords if needed
  let snap = nearestSnap(state.snapElements, x, y);
  if (snap) ({x, y} = snap.point);

  let layerID = state.getIn(['drawingSupport', 'layerID']);
  let scene = state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
    let lineID = layer.getIn(['selected', 'lines']).first();
    let vertex;
    ({layer, vertex} = replaceLineVertex(layer, lineID, 1, x, y));
    select(layer, 'vertices', vertex.id);
    return layer;
  }));

  return state.merge({
    scene,
    activeSnapElement: snap ? snap.snap : null,
  });
}

function endDrawingLine(state, x, y) {
  //calculate snap and overwrite coords if needed
  let snap = nearestSnap(state.snapElements, x, y);
  if (snap) ({x, y} = snap.point);

  let layerID = state.getIn(['drawingSupport', 'layerID']);
  let scene = state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
    let lineID = layer.getIn(['selected', 'lines']).first();
    let line = layer.getIn(['lines', lineID]);
    let v0 = layer.vertices.get(line.vertices.get(0));

    unselect(layer, 'lines', lineID);
    unselect(layer, 'vertices', line.vertices.get(0));
    unselect(layer, 'vertices', line.vertices.get(1));
    removeLine(layer, lineID);
    addLineAvoidingIntersections(layer, line.type, v0.x, v0.y, x, y);
    detectAndUpdateAreas(layer);
  }));

  return state.merge({
    mode: MODE_WAITING_DRAWING_LINE,
    scene,
    snapElements: new List(),
    activeSnapElement: null,
  });
}

function beginDraggingLine(state, layerID, lineID, x, y) {

  let snapElements = sceneSnapElements(state.scene);

  let layer = state.scene.layers.get(layerID);
  let line = layer.lines.get(lineID);

  let vertex0 = layer.vertices.get(line.vertices.get(0));
  let vertex1 = layer.vertices.get(line.vertices.get(1));

  return state.merge({
    mode: MODE_DRAGGING_LINE,
    snapElements,
    draggingSupport: Map({
      layerID, lineID,
      startPointX: x,
      startPointY: y,
      startVertex0X: vertex0.x,
      startVertex0Y: vertex0.y,
      startVertex1X: vertex1.x,
      startVertex1Y: vertex1.y,
    })
  })
}

function updateDraggingLine(state, x, y) {
  let draggingSupport = state.draggingSupport;
  let snapElements = state.snapElements;

  let layerID = draggingSupport.get('layerID');
  let lineID = draggingSupport.get('lineID');
  let diffX = x - draggingSupport.get('startPointX');
  let diffY = y - draggingSupport.get('startPointY');
  let newVertex0X = draggingSupport.get('startVertex0X') + diffX;
  let newVertex0Y = draggingSupport.get('startVertex0Y') + diffY;
  let newVertex1X = draggingSupport.get('startVertex1X') + diffX;
  let newVertex1Y = draggingSupport.get('startVertex1Y') + diffY;

  let activeSnapElement = null;
  let curSnap0 = nearestSnap(snapElements, newVertex0X, newVertex0Y);
  let curSnap1 = nearestSnap(snapElements, newVertex1X, newVertex1Y);

  let deltaX = 0, deltaY = 0;
  if (curSnap0 && curSnap1) {
    if (curSnap0.point.distance < curSnap1.point.distance) {
      deltaX = curSnap0.point.x - newVertex0X;
      deltaY = curSnap0.point.y - newVertex0Y;
      activeSnapElement = curSnap0.snap;
    } else {
      deltaX = curSnap1.point.x - newVertex1X;
      deltaY = curSnap1.point.y - newVertex1Y;
      activeSnapElement = curSnap1.snap;
    }
  } else {
    if (curSnap0) {
      deltaX = curSnap0.point.x - newVertex0X;
      deltaY = curSnap0.point.y - newVertex0Y;
      activeSnapElement = curSnap0.snap;
    }
    if (curSnap1) {
      deltaX = curSnap1.point.x - newVertex1X;
      deltaY = curSnap1.point.y - newVertex1Y;
      activeSnapElement = curSnap1.snap;
    }
  }

  newVertex0X += deltaX;
  newVertex0Y += deltaY;
  newVertex1X += deltaX;
  newVertex1Y += deltaY;

  return state.merge({
    activeSnapElement,
    scene: state.scene.updateIn(['layers', layerID], layer => layer.withMutations(layer => {
      let lineVertices = layer.getIn(['lines', lineID, 'vertices']);
      layer.updateIn(['vertices', lineVertices.get(0)], vertex => vertex.merge({x: newVertex0X, y: newVertex0Y}));
      layer.updateIn(['vertices', lineVertices.get(1)], vertex => vertex.merge({x: newVertex1X, y: newVertex1Y}));
      return layer;
    }))
  });
}

function endDraggingLine(state, x, y) {
  return state.withMutations(state => {
    updateDraggingLine(state, x, y);
    state.merge({
      mode: MODE_IDLE,
      draggingSupport: null,
      activeSnapElement: null,
      snapElements: new List()
    });
  });
}
<|endoftext|>


<commit_before>/*!
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 *  Author: Wesley Hales
 *
 *  version: 1.0.0.Alpha
 */

(function(window,document,undefined){

    var slidfast = (function(){

        var slidfast = function(startupOptions){
            options = startupOptions;
            return new slidfast.core.init();
        },

        options,

        defaultPageID = "",

        callback = null;

        backButtonID = "",

        focusPage =  null,
        focusPage =  null,

        isReady = false;

        slidfast.core = slidfast.prototype = {

            constructor: slidfast,

            start: function() {
                if(options){
                    try{
                        defaultPageID = options.defaultPageID;
                        if(options.callback){
                            callback = window[options.callback];
                        }
                        backButtonID = options.backButtonID;
                    }catch(e){
                        alert('Problem with configuration options.')
                    }
                }
                try{
                    slidfast.core.hideURLBar();
                    slidfast.core.locationChange();
                }catch(e){
                    alert('You must define the page ID and location hash as default parameters. \n Error:' + e)
                }
            },

            hideURLBar: function() {
                //hide the url bar on mobile devices
                setTimeout(scrollTo, 100, 0, 1)
            },

            slideTo :   function (id) {
                if(!focusPage) {
                    focusPage = document.getElementById(defaultPageID);
                }

                //1.)the page we are bringing into focus dictates how
                // the current page will exit. So let's see what classes
                // our incoming page is using. We know it will have stage[right|left|etc...]
                var classes = document.getElementById(id).className.split(' ');

                //2.)decide if the incoming page is assigned to right or left
                // (-1 if no match)
                var stageType = classes.indexOf('stage-left');

                //3.) decide how this focused page should exit.
                if (stageType > 0) {
                    focusPage.className = 'page transition stage-right';
                } else {
                    focusPage.className = 'page transition stage-left';
                }

                //4. refresh/set the variable
                focusPage = document.getElementById(id);

                //5. Bring in the new page and set the global.
                focusPage.className = 'page transition stage-center';

                slidfast.core.hideURLBar();
            },

            init: function() {

                window.addEventListener('load', function(e) {
                    isReady = true;
                    slidfast.core.start(defaultPageID);
                }, false);

                window.addEventListener('hashchange', function(e) {
                    slidfast.core.locationChange();
                }, false);

                return slidfast.core;

            },

            locationChange: function() {
                var locationHash = location.hash;
                if (locationHash === "#" + defaultPageID || locationHash == '') {
                    slidfast.core.slideTo(defaultPageID);
                    location.hash = defaultPageID;

                    //todo - instead of manually tracking backbutton, lets dispatch an event
                    //this is hard-coded for now
                    if(backButtonID){
                        //we're on the default page, so no need for back button
                        document.getElementById(backButtonID).className = 'hide-button';
                    }
                } else {

                    var hashArray = locationHash.split(':');
                    var param1;
                    var param2;
                    if (hashArray.length === 2) {
                        param1 = hashArray[0].replace('#', '');
                        param2 = hashArray[1];
                    }else{
                        param1 = locationHash.replace('#', '');
                        param2 = null;
                    }
                    //todo accomodate more (or less) than 2 level breadcrumb

                    if(callback != null){
                        try{
                        //after location changes, call this method supplied in config
                        //if using RichFaces, this would be the method name supplied in the
                        //a4j:jsFunction component...
                        callback(param1, param2);
                        }catch(e){
                           alert('you must define an a4j:jsFunction component with name=' + callback)
                        }
                    }else{
                        //attempt to slide to a page id if not using a callback
                        slidfast.core.slideTo(param1);
                    }

                    //todo - instead of manually tracking backbutton, lets dispatch an event
                    if(backButtonID){
                        //show the back button and attach functions
                        document.getElementById(backButtonID).className = 'basic-button left-header-button';
                        document.getElementById(backButtonID).onclick = function() {
                            //todo should (possibly) go back in history
                            location.hash = defaultPageID;
                        };
                    }

                }
            },

            flip: function() {
                //get a handle on the flippable region
                var front = document.getElementById('front');
                var back = document.getElementById('back');

                //just a simple way to see what the state is
                var classes = front.className.split(' ');
                var flipped = classes.indexOf('flipped');

                if (flipped >= 0) {
                    //already flipped, so return to original
                    front.className = 'normal';
                    back.className = 'flipped';
                } else {
                    //do the flip
                    front.className = 'flipped';
                    back.className = 'normal';

                }
            }

        };
        slidfast.core.init.prototype = slidfast.core;
        return slidfast;

    })();

window.slidfast = slidfast;
})(window,document);

<commit_msg>Added console.log output in the error handling<commit_after>/*!
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 *  Author: Wesley Hales
 *
 *  version: 1.0.0.Alpha
 */

(function(window,document,undefined){

    var slidfast = (function(){

        var slidfast = function(startupOptions){
            options = startupOptions;
            return new slidfast.core.init();
        },

        options,

        defaultPageID = "",

        callback = null;

        backButtonID = "",

        focusPage =  null,
        focusPage =  null,

        isReady = false;

        slidfast.core = slidfast.prototype = {

            constructor: slidfast,

            start: function() {
                if(options){
                    try{
                        defaultPageID = options.defaultPageID;
                        if(options.callback){
                            callback = window[options.callback];
                        }
                        backButtonID = options.backButtonID;
                    }catch(e){
                        console.log('Problem with configuration options.');
                        console.log(e);
                        alert('Problem with configuration options.');
                    }
                }
                try{
                    slidfast.core.hideURLBar();
                    slidfast.core.locationChange();
                }catch(e){
                    console.log('You must define the page ID and location hash as default parameters. \n Error:' + e);
                    console.log(e);
                    alert('You must define the page ID and location hash as default parameters. \n Error:' + e);
                }
            },

            hideURLBar: function() {
                //hide the url bar on mobile devices
                setTimeout(scrollTo, 100, 0, 1)
            },

            slideTo :   function (id) {
                if(!focusPage) {
                    focusPage = document.getElementById(defaultPageID);
                }

                //1.)the page we are bringing into focus dictates how
                // the current page will exit. So let's see what classes
                // our incoming page is using. We know it will have stage[right|left|etc...]
                var classes = document.getElementById(id).className.split(' ');

                //2.)decide if the incoming page is assigned to right or left
                // (-1 if no match)
                var stageType = classes.indexOf('stage-left');

                //3.) decide how this focused page should exit.
                if (stageType > 0) {
                    focusPage.className = 'page transition stage-right';
                } else {
                    focusPage.className = 'page transition stage-left';
                }

                //4. refresh/set the variable
                focusPage = document.getElementById(id);

                //5. Bring in the new page and set the global.
                focusPage.className = 'page transition stage-center';

                slidfast.core.hideURLBar();
            },

            init: function() {

                window.addEventListener('load', function(e) {
                    isReady = true;
                    slidfast.core.start(defaultPageID);
                }, false);

                window.addEventListener('hashchange', function(e) {
                    slidfast.core.locationChange();
                }, false);

                return slidfast.core;

            },

            locationChange: function() {
                var locationHash = location.hash;
                if (locationHash === "#" + defaultPageID || locationHash == '') {
                    slidfast.core.slideTo(defaultPageID);
                    location.hash = defaultPageID;

                    //todo - instead of manually tracking backbutton, lets dispatch an event
                    //this is hard-coded for now
                    if(backButtonID){
                        //we're on the default page, so no need for back button
                        document.getElementById(backButtonID).className = 'hide-button';
                    }
                } else {

                    var hashArray = locationHash.split(':');
                    var param1;
                    var param2;
                    if (hashArray.length === 2) {
                        param1 = hashArray[0].replace('#', '');
                        param2 = hashArray[1];
                    }else{
                        param1 = locationHash.replace('#', '');
                        param2 = null;
                    }
                    //todo accomodate more (or less) than 2 level breadcrumb

                    if(callback != null){
                        try{
                        //after location changes, call this method supplied in config
                        //if using RichFaces, this would be the method name supplied in the
                        //a4j:jsFunction component...
                        callback(param1, param2);
                        }catch(e){
                           console.log('you must define an a4j:jsFunction component with name=' + callback);
                           console.log(e);
                           alert('you must define an a4j:jsFunction component with name=' + callback);
                        }
                    }else{
                        //attempt to slide to a page id if not using a callback
                        slidfast.core.slideTo(param1);
                    }

                    //todo - instead of manually tracking backbutton, lets dispatch an event
                    if(backButtonID){
                        //show the back button and attach functions
                        document.getElementById(backButtonID).className = 'basic-button left-header-button';
                        document.getElementById(backButtonID).onclick = function() {
                            //todo should (possibly) go back in history
                            location.hash = defaultPageID;
                        };
                    }

                }
            },

            flip: function() {
                //get a handle on the flippable region
                var front = document.getElementById('front');
                var back = document.getElementById('back');

                //just a simple way to see what the state is
                var classes = front.className.split(' ');
                var flipped = classes.indexOf('flipped');

                if (flipped >= 0) {
                    //already flipped, so return to original
                    front.className = 'normal';
                    back.className = 'flipped';
                } else {
                    //do the flip
                    front.className = 'flipped';
                    back.className = 'normal';

                }
            }

        };
        slidfast.core.init.prototype = slidfast.core;
        return slidfast;

    })();

window.slidfast = slidfast;
})(window,document);

<|endoftext|>


<commit_before>const express = require('express');
const request = require('request');
const moment = require('moment');
var bu;

var app;
var e = module.exports;
var bot;
var server;

e.init = (b, blargutil) => {
    bot = b;
    bu = blargutil;
    app = express();

    app.post('/gitlog/push', (req, res) => {
        var responseObj = {
            err: 401,
            desc: 'no u'
        };
        console.log(req.get('X-Hub-Signature'), bu.config.general.gitlogHash);
        if (req.get('X-Hub-Signature') == bu.config.general.gitlogHash) {
            console.dir(req);
            let body = JSON.parse(req.body);
            responseObj = {
                err: 418,
                desc: 'whew such a professional interface'
            };
            let toSend = {
                username: 'Gumdrop',
                text: '**__New Commit__**',
                attachments: [
                    {
                        author_icon: body.sender.avatar_url,
                        author_name: body.sender.login,
                        text: `From \`${body.before}\` to \`${body.after}\``,
                        color: '#36a64f',
                        mrkdwn_in: ['text', 'fields'],
                        fields: []
                    }
                ],
                mrkdwn: true
            };
            for (let i = 0; i < body.commits.length; i++) {
                let commit = {
                    title: '',
                    value: '',
                    short: true
                };
                commit.title = body.commits[i].message;
                commit.value = moment(body.commits[i].timestamp).format('LLLL');
                toSend.attachments[0].fields.push(commit);
            }
            console.log(`Sending a POST request to webhook`);
            request({
                url: bu.config.general.gitlogWebhook,
                method: 'POST',
                json: true,
                headers: {
                    'content-type': 'application/json'
                },
                body: JSON.stringify(toSend)
            });
        }
        console.log(`Ending POST request to /gitlog/push with ${JSON.stringify(responseObj, null, 4)}`);
        res.end(JSON.stringify(responseObj, null, 4));
    });

    app.get('/user/:id', (req, res) => {
        //console.log()
        //   console.dir(req.params)
        var user = bot.users.get(req.params.id);
        var objectToSend;
        if (user) {
            objectToSend = {
                id: user.id,
                username: user.username,
                discriminator: user.discriminator,
                avatarURL: user.avatarURL,
                bot: user.bot
            };
            res.end(checkAuth(objectToSend, req, res));

        } else {
            bu.db.query(`select username, isbot, discriminator from user where userid = ?`, [req.params.id], (err, rows) => {
                if (rows && rows[0]) {
                    objectToSend = {
                        id: req.param.id,
                        username: rows[0].username,
                        discriminator: rows[0].discriminator || '????',
                        avatarURL: 'not found',
                        bot: rows[0].isbot
                    };
                } else {
                    objectToSend = notFound;
                }
                res.end(checkAuth(objectToSend, req, res));

            });
        }
    });

    app.get('/channel/:id', (req, res) => {
        var channel = bot.getChannel(req.params.id);
        var objectToSend = {};
        if (channel) {
            objectToSend = {
                id: channel.id,
                name: channel.name,
                guildid: channel.guild.id,
                guildname: channel.guild.name
            };
        } else {
            objectToSend = notFound;
        }
        res.end(checkAuth(objectToSend, req));
    });

    app.get('/guild/:id', (req, res) => {
        var guild = bot.guilds.get(req.params.id);
        var objectToSend;
        if (guild) {
            objectToSend = {
                id: guild.id,
                name: guild.name
            };
        } else {
            objectToSend = notFound;
        }
        res.end(checkAuth(objectToSend, req));
    });

    server = app.listen(8081, function () {
        var host = server.address().address;
        var port = server.address().port;
        console.log('Interface listening at http://%s:%s', host, port);
    });
};

e.kill = () => {
    server.close();
};

function checkAuth(object, req, res) {
    //  console.dir(req.get('key'), bu.config.general.interface_key);
    if (bu.config.general.interface_key != req.get('key'))
        object = {
            error: 401,
            desc: 'who the fuck are you get off my lawn'
        };
    return JSON.stringify(object, null, 4);
}

var notFound = {
    error: 404,
    desc: 'you fucked up kthx'
};<commit_msg>oWo whats this<commit_after>const express = require('express');
const request = require('request');
const moment = require('moment');
var bu;

var app;
var e = module.exports;
var bot;
var server;

e.init = (b, blargutil) => {
    bot = b;
    bu = blargutil;
    app = express();

    app.configure(() => {
        app.use(express.bodyParser());
        app.use(app.router);
    });

    server = app.listen(8081, function () {
        var host = server.address().address;
        var port = server.address().port;
        console.log('Interface listening at http://%s:%s', host, port);
    });

    app.post('/gitlog/push', (req, res) => {
        var responseObj = {
            err: 401,
            desc: 'no u'
        };
        console.log(req.get('X-Hub-Signature'), bu.config.general.gitlogHash);
        if (req.get('X-Hub-Signature') == bu.config.general.gitlogHash) {
            console.dir(req);
            let body = JSON.parse(req.body);
            responseObj = {
                err: 418,
                desc: 'whew such a professional interface'
            };
            let toSend = {
                username: 'Gumdrop',
                text: '**__New Commit__**',
                attachments: [
                    {
                        author_icon: body.sender.avatar_url,
                        author_name: body.sender.login,
                        text: `From \`${body.before}\` to \`${body.after}\``,
                        color: '#36a64f',
                        mrkdwn_in: ['text', 'fields'],
                        fields: []
                    }
                ],
                mrkdwn: true
            };
            for (let i = 0; i < body.commits.length; i++) {
                let commit = {
                    title: '',
                    value: '',
                    short: true
                };
                commit.title = body.commits[i].message;
                commit.value = moment(body.commits[i].timestamp).format('LLLL');
                toSend.attachments[0].fields.push(commit);
            }
            console.log(`Sending a POST request to webhook`);
            request({
                url: bu.config.general.gitlogWebhook,
                method: 'POST',
                json: true,
                headers: {
                    'content-type': 'application/json'
                },
                body: JSON.stringify(toSend)
            });
        }
        console.log(`Ending POST request to /gitlog/push with ${JSON.stringify(responseObj, null, 4)}`);
        res.end(JSON.stringify(responseObj, null, 4));
    });

    app.get('/user/:id', (req, res) => {
        //console.log()
        //   console.dir(req.params)
        var user = bot.users.get(req.params.id);
        var objectToSend;
        if (user) {
            objectToSend = {
                id: user.id,
                username: user.username,
                discriminator: user.discriminator,
                avatarURL: user.avatarURL,
                bot: user.bot
            };
            res.end(checkAuth(objectToSend, req, res));

        } else {
            bu.db.query(`select username, isbot, discriminator from user where userid = ?`, [req.params.id], (err, rows) => {
                if (rows && rows[0]) {
                    objectToSend = {
                        id: req.param.id,
                        username: rows[0].username,
                        discriminator: rows[0].discriminator || '????',
                        avatarURL: 'not found',
                        bot: rows[0].isbot
                    };
                } else {
                    objectToSend = notFound;
                }
                res.end(checkAuth(objectToSend, req, res));

            });
        }
    });

    app.get('/channel/:id', (req, res) => {
        var channel = bot.getChannel(req.params.id);
        var objectToSend = {};
        if (channel) {
            objectToSend = {
                id: channel.id,
                name: channel.name,
                guildid: channel.guild.id,
                guildname: channel.guild.name
            };
        } else {
            objectToSend = notFound;
        }
        res.end(checkAuth(objectToSend, req));
    });

    app.get('/guild/:id', (req, res) => {
        var guild = bot.guilds.get(req.params.id);
        var objectToSend;
        if (guild) {
            objectToSend = {
                id: guild.id,
                name: guild.name
            };
        } else {
            objectToSend = notFound;
        }
        res.end(checkAuth(objectToSend, req));
    });
};

e.kill = () => {
    server.close();
};

function checkAuth(object, req, res) {
    //  console.dir(req.get('key'), bu.config.general.interface_key);
    if (bu.config.general.interface_key != req.get('key'))
        object = {
            error: 401,
            desc: 'who the fuck are you get off my lawn'
        };
    return JSON.stringify(object, null, 4);
}

var notFound = {
    error: 404,
    desc: 'you fucked up kthx'
};<|endoftext|>


<commit_before>//////////////////////////////////////////////////////
///     Load Required Plugins
/////////////////////////////////////////////////////

var gulp = require('gulp'),
    gutil = require('gulp-util'),
    notify = require( 'gulp-notify' ),                   // Pop-up notifications.
    plumber = require('gulp-plumber'),                   // Prevents gulp.watch from crashing.
    watch = require('gulp-watch'),
    jshint = require('gulp-jshint'),
	uglify = require('gulp-uglify'),
    size = require('gulp-size'),                         // Logs out the total size of files in the stream
    autoprefixer = require('gulp-autoprefixer'),         // Parses CSS files and adds vendor prefixes to CSS rules
    minifyCSS = require('gulp-minify-css'),
    less = require('gulp-less'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),                     // Concats JS files in a single file (in case we have more than one JS library)
    minifyHTML = require('gulp-minify-html'),
    browserSync = require('browser-sync'),
    browserReload = browserSync.reload;

//////////////////////////////////////////////////////
///     Set File Paths
//////////////////////////////////////////////////////

var basePath = {
  dev  : './builds/dev/',
  prod : './builds/prod/'
};

var devAssets = {
  styles  : basePath.dev + 'less/',
  scripts : basePath.dev + 'js/',
  images  : basePath.dev + 'images/'
};

var prodAssets = {
  styles  : basePath.prod + 'css/',
  scripts : basePath.prod + 'js/',
  images  : basePath.prod + 'images/'
};

// Array of Javascript assets listed in the order you want to concatenate
var jsAssets = [ devAssets.scripts + 'script.js'];

//////////////////////////////////////////////////////
///     Gulp Tasks
//////////////////////////////////////////////////////

// Less Task
gulp.task('pre-process', function(){
      return gulp.src( devAssets.styles + 'project.less')
      .pipe(plumber({errorHandler: onError}))
      .pipe(size({ title: "Source file", showFiles: true}))
      .pipe(less())
      .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
      .pipe(minifyCSS())
      .pipe(rename('styles.min.css'))
      .pipe(gulp.dest(prodAssets.styles))
      .pipe(size({ title: "Compressed file", showFiles: true}))
      .pipe(browserSync.reload({stream:true}))
      .pipe(notify({ message: 'Less task complete' }));
});

// Scripts Task
gulp.task('scripts', function() {
	return gulp.src(jsAssets)
    .pipe(plumber({errorHandler: onError}))
    .pipe(size({ title: "Source file", showFiles: true}))
	.pipe(jshint())
	.pipe(jshint.reporter('default'))
	.pipe(uglify())
    .pipe(concat('script.min.js'))
	.pipe(gulp.dest(prodAssets.scripts))
    .pipe(size({ title: "Compressed file", showFiles: true}))
    .pipe(browserSync.reload({stream:true}))
	.pipe(notify({ message: 'Scripts task complete' }));
});

// Initialize Browser-sync
gulp.task('set-server', function() {
    browserSync.init(null, {
        server: {
            baseDir: basePath.prod
        },
        port: 3000
    });
});

// Reload Browsers
gulp.task('reload', function () {
    browserSync.reload();
});

// Minify HTML Task
gulp.task('minify-html', function() {
    return gulp.src( basePath.dev + '*.html')
    .pipe(plumber({errorHandler: onError}))
    .pipe(size({ title: "Source file", showFiles: true}))
    .pipe(minifyHTML({
          conditionals: true,
          spare:true
    }))
    .pipe(gulp.dest(basePath.prod))
    .pipe(size({ title: "Compressed file", showFiles: true}))
    .pipe(browserSync.reload({stream:true}))
	.pipe(notify({ message: 'HTML task complete' }));
});

// Error Handler
var onError = function(err) {
    notify.onError({
        title:    "Gulp",
        subtitle: "Failure!",
        message:  "Error: <%= error.message %>",
        sound:    "Beep"
    })(err);

    this.emit('end');
    console.log(err);
};

// Default Task
gulp.task('default', ['pre-process', 'scripts', 'minify-html', 'set-server'], function(){
      gulp.watch( devAssets.styles + '*.less', ['pre-process']);
      gulp.watch( devAssets.scripts + '*.js', ['scripts']);
      gulp.watch(basePath.dev + '*.html', ['minify-html']);
});
<commit_msg>Added watch task that monitors any image changes in the production image folder.<commit_after>//////////////////////////////////////////////////////
///     Load Required Plugins
/////////////////////////////////////////////////////

var gulp = require('gulp'),
    gutil = require('gulp-util'),
    notify = require( 'gulp-notify' ),                   // Pop-up notifications.
    plumber = require('gulp-plumber'),                   // Prevents gulp.watch from crashing.
    watch = require('gulp-watch'),
    jshint = require('gulp-jshint'),
	uglify = require('gulp-uglify'),
    size = require('gulp-size'),                         // Logs out the total size of files in the stream
    autoprefixer = require('gulp-autoprefixer'),         // Parses CSS files and adds vendor prefixes to CSS rules
    minifyCSS = require('gulp-minify-css'),
    less = require('gulp-less'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),                     // Concats JS files in a single file (in case we have more than one JS library)
    minifyHTML = require('gulp-minify-html'),
    browserSync = require('browser-sync'),
    browserReload = browserSync.reload;

//////////////////////////////////////////////////////
///     Set File Paths
//////////////////////////////////////////////////////

var basePath = {
  dev  : './builds/dev/',
  prod : './builds/prod/'
};

var devAssets = {
  styles  : basePath.dev + 'less/',
  scripts : basePath.dev + 'js/',
  images  : basePath.dev + 'images/'
};

var prodAssets = {
  styles  : basePath.prod + 'css/',
  scripts : basePath.prod + 'js/',
  images  : basePath.prod + 'images/'
};

// Array of Javascript assets listed in the order you want to concatenate
var jsAssets = [ devAssets.scripts + 'script.js'];

//////////////////////////////////////////////////////
///     Gulp Tasks
//////////////////////////////////////////////////////

// Less Task
gulp.task('pre-process', function(){
      return gulp.src( devAssets.styles + 'project.less')
      .pipe(plumber({errorHandler: onError}))
      .pipe(size({ title: "Source file", showFiles: true}))
      .pipe(less())
      .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
      .pipe(minifyCSS())
      .pipe(rename('styles.min.css'))
      .pipe(gulp.dest(prodAssets.styles))
      .pipe(size({ title: "Compressed file", showFiles: true}))
      .pipe(browserSync.reload({stream:true}))
      .pipe(notify({ message: 'Less task complete' }));
});

// Scripts Task
gulp.task('scripts', function() {
	return gulp.src(jsAssets)
    .pipe(plumber({errorHandler: onError}))
    .pipe(size({ title: "Source file", showFiles: true}))
	.pipe(jshint())
	.pipe(jshint.reporter('default'))
	.pipe(uglify())
    .pipe(concat('script.min.js'))
	.pipe(gulp.dest(prodAssets.scripts))
    .pipe(size({ title: "Compressed file", showFiles: true}))
    .pipe(browserSync.reload({stream:true}))
	.pipe(notify({ message: 'Scripts task complete' }));
});

// Initialize Browser-sync
gulp.task('set-server', function() {
    browserSync.init(null, {
        server: {
            baseDir: basePath.prod
        },
        port: 3000
    });
});

// Reload Browsers
gulp.task('reload', function () {
    browserSync.reload();
});

// Minify HTML Task
gulp.task('minify-html', function() {
    return gulp.src( basePath.dev + '*.html')
    .pipe(plumber({errorHandler: onError}))
    .pipe(size({ title: "Source file", showFiles: true}))
    .pipe(minifyHTML({
          conditionals: true,
          spare:true
    }))
    .pipe(gulp.dest(basePath.prod))
    .pipe(size({ title: "Compressed file", showFiles: true}))
    .pipe(browserSync.reload({stream:true}))
	.pipe(notify({ message: 'HTML task complete' }));
});

// Error Handler
var onError = function(err) {
    notify.onError({
        title:    "Gulp",
        subtitle: "Failure!",
        message:  "Error: <%= error.message %>",
        sound:    "Beep"
    })(err);

    this.emit('end');
    console.log(err);
};

// Default Task
gulp.task('default', ['pre-process', 'scripts', 'minify-html', 'set-server'], function(){
      gulp.watch( devAssets.styles + '*.less', ['pre-process']);
      gulp.watch( devAssets.scripts + '*.js', ['scripts']);
      gulp.watch(basePath.dev + '*.html', ['minify-html']);
      gulp.watch(prodAssets.images + '**', ['reload']);
});
<|endoftext|>


<commit_before>var MainController = function ($scope, $http) {
    var onSuccess = function (res) {
        $scope.stocks = res.data;
    }
    var onError = function (err) {
        $scope.error = err;
    }

    $http.get('/stocks')
        .then(onSuccess, onError);

    $scope.addStock = function (s, c, p) {
        $http({
            method: "post",
            url: "/stocks",
            data: {
                symbol: s,
                count: c,
                purchasePrice: p
            }
        });
    }
}

var ngPortfolioApp = angular.module("ngPortfolioApp", []);

ngPortfolioApp.controller("MainController", MainController);
<commit_msg>list gets updated on post of new data<commit_after>var MainController = function ($scope, $http) {
    var onSuccess = function (res) {
        $scope.stocks = res.data;
    }
    var onError = function (err) {
        $scope.error = err;
    }

    var updateList = function (res) {
        $scope.stocks.push(res.data);
    }

    $http.get('/stocks')
        .then(onSuccess, onError);

    $scope.addStock = function (s, c, p) {
        $http({
            method: "post",
            url: "/stocks",
            data: {
                symbol: s,
                count: c,
                purchasePrice: p
            }
        }).then(updateList, onError);
    }
}

var ngPortfolioApp = angular.module("ngPortfolioApp", []);

ngPortfolioApp.controller("MainController", MainController);
<|endoftext|>


<commit_before>/**
 * Created by oleksiypolshchak on 6/3/16.
 */
'use strict';

angular.
module('core.grain').
factory('Grain', ['$resource',
    function($resource) {
        return $resource('data/:pageId.json', {}, {
            query: {
                method: 'GET',
                params: {phoneId: 'resources'},
                isArray: true
            }
        });
    }
]);<commit_msg>core changes<commit_after>/**
 * Created by oleksiypolshchak on 6/3/16.
 */
'use strict';

angular.
module('core.grain').
factory('Grain', ['$resource',
    function($resource) {
        return $resource('data/:jsonId.json', {}, {
            query: {
                method: 'GET',
                params: {jsonId: 'resources'},
                isArray: true
            }
        });
    }
]);<|endoftext|>


<commit_before>var locastyle = (function() {
  'use strict';

  // Used to run scripts when the HTML is ready
  function fastInit() {
    locastyle.sidebarToggle.init();
    locastyle.sidebars.init();
  }

  // Used to run scripts that just when all things are ready
  function init() {
    locastyle.breakpoints.init();
    loadModules();
    locastyle.general.init();
    locastyle.btnGroup.init();
    locastyle.alert.init();
    locastyle.datepicker.init();
    locastyle.form.togglePasswordField();
    checkClassForTrack();
    locastyle.browserDetect.init();
  }

  function loadModules() {
    var modules = getModules();
    for (var i in modules) {
      locastyle[modules[i]].init();
      console.info("Locastyle: module [" + modules[i] + "] successfully initialized.");
    }
  }

  function checkClassForTrack() {
    if($("html").hasClass("ls-trackevent-on")){
      locastyle.trackEvents.init();
    }
  }

  function getModules() {
    var modules = [];
    $("[data-ls-module]").each(function () {
      var module = $(this).data("ls-module");
      if ( modules.indexOf(module) === -1 ) {
        modules.push(module);
      }
    });
    return modules;
  }

  return {
    init: init,
    fastInit: fastInit
  };

}());

var ls = locastyle;

$(window).load(function() {
  'use strict';
  ls.init();
});

$(document).ready(function(){
  'use strict';
  ls.fastInit();
});<commit_msg>wrapping for statement within an if to check unwanted properties from prototype<commit_after>var locastyle = (function() {
  'use strict';

  // Used to run scripts when the HTML is ready
  function fastInit() {
    locastyle.sidebarToggle.init();
    locastyle.sidebars.init();
  }

  // Used to run scripts that just when all things are ready
  function init() {
    locastyle.breakpoints.init();
    loadModules();
    locastyle.general.init();
    locastyle.btnGroup.init();
    locastyle.alert.init();
    locastyle.datepicker.init();
    locastyle.form.togglePasswordField();
    checkClassForTrack();
    locastyle.browserDetect.init();
  }

  function loadModules() {
    var modules = getModules();
    for (var i in modules) {
      if (modules.hasOwnProperty(i)) {
        locastyle[modules[i]].init();
        console.info("Locastyle: module [" + modules[i] + "] successfully initialized.");
      }
    }
  }

  function checkClassForTrack() {
    if($("html").hasClass("ls-trackevent-on")){
      locastyle.trackEvents.init();
    }
  }

  function getModules() {
    var modules = [];
    $("[data-ls-module]").each(function () {
      var module = $(this).data("ls-module");
      if ( modules.indexOf(module) === -1 ) {
        modules.push(module);
      }
    });
    return modules;
  }

  return {
    init: init,
    fastInit: fastInit
  };

}());

var ls = locastyle;

$(window).load(function() {
  'use strict';
  ls.init();
});

$(document).ready(function(){
  'use strict';
  ls.fastInit();
});
<|endoftext|>


<commit_before>(function($) {

	function defaultHandler(endpoint, data, callback) {
		$.post(endpoint, data)
			.done(function () {
		    callback();
		  })
		  .fail(function () {
		    alert("Something went wrong :/");
		    callback(true);
		  });
	}

	$.dingdong = function(options) {

		// parse options
		var opts = {};
		if (options) {
			if ($.type(options) === "object") {
				opts = options;
			} else if ($.type(options) === "string") {
				opts.endpoint = options;
			} else if ($.type(options) === "function") {
				opts.handler = options;
			} else {
				console.error("dingdong argument should be object (options), string (custom endpoint), or function (custom handler) :/");
			}
		}

		// fade options
		var fade = !!opts.fade;
		var fadeOpen = opts.openFadeDuration || 100;
		var fadeCancel = opts.cancelFadeDuration || 100;
		var fadeSubmit = opts.submitFadeDuration || 1000;

		// custom text options
		var buttonText = opts.buttonText = "Feedback";
		var emailPlaceholder = opts.emailPlaceholder || "Your email address";
		var messagePlaceholder = opts.messagePlaceholder || "Send us your feedback or report an issue";
		var submitButtonText = opts.submitButtonText || "Send message";
		var submittedText = opts.submittedText || "Thanks!";
		var subscribeButtonText = opts.subscribeButtonText || "Subscribe";
		var fnamePlaceholder = opts.fnamePlaceholder || "First name";
		var lnamePlaceholder = opts.lnamePlaceholder || "Last name";

		// misc
		var messageRows = opts.messageRows || 7;
		var disableEscapeToCancel = !!opts.disableEscapeToCancel;
		var endpoint = opts.endpoint || "/dingdong";
		var showSubscribe = !!opts.showSubscribe;
		var showMessage = !!opts.showMessage;

		// helper function for showing
		$.dingdongShow = function (mode) {
			$("#dingdong-submit").prop("disabled", false);
			$("#dingdong-submit").text(submitButtonText);
			$("#dingdong-message").val("");
			// intentionally dont clear email, fname, lname

			if (mode === "subscribeOnly") {
				$("#dingdong-subscribe").prop("checked", true);
				$("#dingdong-name-row").show();
				$("#dingdong-subscribe-row").hide();
				$("#dingdong-message-row").hide();
				$("#dingdong-submit").text(subscribeButtonText);
			} else {
				$("#dingdong-subscribe").prop("checked", false);
				$("#dingdong-name-row").hide();
				if (mode == "messageOnly") {
					$("#dingdong-subscribe-row").hide();
				} else {
					$("#dingdong-subscribe-row").show();
				}
				$("#dingdong-message-row").show();
				$("#dingdong-submit").text(submitButtonText);
			}

			if (fade) {
				$("#dingdong").fadeIn(fadeOpen);
			} else {
				$("#dingdong").show();
			}
		}

		// helper function for canceling
		$.dingdongCancel = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeCancel);
			} else {
				$("#dingdong").hide();
			}
		}

		// helper function for hiding (aka after submit)
		$.dingdongHide = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeSubmit);
			} else {
				$("#dingdong").hide();
			}
			$("#dingdong-submit").text(submittedText).prop("disabled", true);
		}

		// maybe build header option
		var header;
		if (opts.header) {
			header = [
				$("<div/>", { "class": "dingdong-row" }).append(
					$("<div/>", { id: "dingdong-header", html: opts.header })
				)
			];
		}

		// maybe build subscribe section
		var subscribe;
		if (showSubscribe) {
			subscribe = [
				$("<div/>", { id: "dingdong-subscribe-row", "class": "dingdong-row" }).append(
					$("<label/>", { for: "dingdong-subscribe", text: "Subscribe to newsletter" }).append(
						$("<span/>", { "class": "dingdong-switch" }).append(
							$("<input/>", { id: "dingdong-subscribe", name: "subscribe", type: "checkbox" }),
							$("<div/>", { "class": "dingdong-switch-slider" })
						)
					)
				),
				$("<div/>", { id: "dingdong-name-row", "class": "dingdong-row" }).append(
					$("<input/>", { id: "dingdong-fname", name: "fname", type: "text", placeholder: fnamePlaceholder, required: "required", width: "50%" }),
					$("<input/>", { id: "dingdong-lname", name: "lname", type: "text", placeholder: lnamePlaceholder, required: "required", width: "50%" })
				)
			];
		}

		var message;
		if (showMessage) {
			message = [
				$("<div/>", { id: "dingdong-message-row", "class": "dingdong-row" }).append(
					$("<textarea/>", { id: "dingdong-message", name: "message", rows: messageRows, placeholder: messagePlaceholder, required: "required" })
				)
			];
		}

		var email = [
			$("<div/>", { "class": "dingdong-row" }).append(
				$("<input/>", { id: "dingdong-email", name: "email", type: "email", placeholder: emailPlaceholder, required: "required" })
			)
		];

		var submit = [
			$("<button/>", { id: "dingdong-submit", type: "submit", text: submitButtonText })
		];

		// remove existing if $.dingdong has already been called
		$("#dingdong-button").remove();
		$("#dingdong").remove();

		// add dingdong button
		$("body").append(
			$("<button />", { id: "dingdong-button", style: "display: none", text: buttonText })
		);

		// add dingdong modal
		$("body").append(
			$("<div/>", { id: "dingdong", style: "display: none" }).append(
				$("<div/>", { id: "dingdong-box" }).append(
					$("<div/>", { id: "dingdong-close", text: "\u00D7" }),
					$("<form/>", { id: "dingdong-form" }).append(
						header,
						email,
						message,
						subscribe,
						submit
					)
				)
			)
		);

		// maybe listen for esc to cancel
		if (!disableEscapeToCancel) {
			$(document).keydown(function(e) {
		    if (e.keyCode == 27) {
		        $.dingdongCancel();
		    }
			});
		}

		// toggle name fields when subscribe checkbox changes
		$("#dingdong-subscribe").change(function () {
			var checked = $(this).is(":checked");
			if (checked) {
				$("#dingdong-name-row").slideDown();
			} else {
				$("#dingdong-name-row").slideUp();
			}
			$("#dingdong-fname").prop("required", checked);
			$("#dingdong-lname").prop("required", checked);
		});

		// show dingdong when button is clicked
		$("#dingdong-button").click(function () {
			$.dingdongShow();
		});

		// cancel dingdong when backdrop or close is clicked
		$("#dingdong, #dingdong-close").click(function () {
			$.dingdongCancel();
		});

		// prevent clicks inside the box from propagating
		// (otherwise any click inside will trigger above cancel)
		$("#dingdong-box").click(function (e) {
			e.stopPropagation();
		});

		// handle form submission (prevent default behavior since ajax)
		$("#dingdong-form").submit(function (e) {
			e.preventDefault();
			var data = {
				message: $("#dingdong-message").val(),
				email: $("#dingdong-email").val(),
				subscribe: $("#dingdong-subscribe").is(":checked"),
				fname: $("#dingdong-fname").val(),
				lname: $("#dingdong-lname").val()
			};
			function callback(err) {
				if (err) {
					$("#dingdong-submit").prop("disabled", false);
				} else {
					$.dingdongHide();
				}
			}
			$("#dingdong-submit").prop("disabled", true);
			if (opts.handler) {
				opts.handler(data, callback);
			} else {
				defaultHandler(opts.endpoint, data, callback);
			}
			return false;
		});

	}

}(jQuery));
<commit_msg>Updating options and defaults<commit_after>(function($) {

	function defaultHandler(endpoint, data, callback) {
		$.post(endpoint, data)
			.done(function () {
		    callback();
		  })
		  .fail(function () {
		    alert("Something went wrong :/");
		    callback(true);
		  });
	}

	$.dingdong = function(options) {

		// parse options
		var opts = {};
		if (options) {
			if ($.type(options) === "object") {
				opts = options;
			} else if ($.type(options) === "string") {
				opts.endpoint = options;
			} else if ($.type(options) === "function") {
				opts.handler = options;
			} else {
				console.error("dingdong argument should be object (options), string (custom endpoint), or function (custom handler) :/");
			}
		}

		// fade options
		var fade = opts.fade !== false;
		var fadeOpen = opts.openFadeDuration || 100;
		var fadeCancel = opts.cancelFadeDuration || 100;
		var fadeSubmit = opts.submitFadeDuration || 1000;

		// custom text options
		var buttonText = opts.buttonText = "Feedback";
		var emailPlaceholder = opts.emailPlaceholder || "Your email address";
		var messagePlaceholder = opts.messagePlaceholder || "Send us your feedback or report an issue";
		var submitButtonText = opts.submitButtonText || "Send message";
		var submittedText = opts.submittedText || "Thanks!";
		var subscribeButtonText = opts.subscribeButtonText || "Subscribe";
		var fnamePlaceholder = opts.fnamePlaceholder || "First name";
		var lnamePlaceholder = opts.lnamePlaceholder || "Last name";
		var subscribeLabel = opts.subscribeLabel || "Subscribe to newsletter";

		// misc
		var messageRows = opts.messageRows || 7;
		var escapeToCancel = opts.disableEscapeToCancel !== false;
		var endpoint = opts.endpoint || "/dingdong";

		// helper function for showing
		$.dingdongShow = function (mode) {
			$("#dingdong-submit").prop("disabled", false);
			$("#dingdong-submit").text(submitButtonText);
			$("#dingdong-message").val("");
			// intentionally dont clear email, fname, lname

			if (mode === "subscribeOnly") {
				$("#dingdong-subscribe").prop("checked", true);
				$("#dingdong-name-row").show();
				$("#dingdong-subscribe-row").hide();
				$("#dingdong-message-row").hide();
				$("#dingdong-submit").text(subscribeButtonText);
			} else {
				$("#dingdong-subscribe").prop("checked", false);
				$("#dingdong-name-row").hide();
				if (mode == "messageOnly") {
					$("#dingdong-subscribe-row").hide();
				} else {
					$("#dingdong-subscribe-row").show();
				}
				$("#dingdong-message-row").show();
				$("#dingdong-submit").text(submitButtonText);
			}

			if (fade) {
				$("#dingdong").fadeIn(fadeOpen);
			} else {
				$("#dingdong").show();
			}
		}

		// helper function for canceling
		$.dingdongCancel = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeCancel);
			} else {
				$("#dingdong").hide();
			}
		}

		// helper function for hiding (aka after submit)
		$.dingdongHide = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeSubmit);
			} else {
				$("#dingdong").hide();
			}
			$("#dingdong-submit").text(submittedText).prop("disabled", true);
		}

		// maybe build header option
		var header;
		if (opts.header) {
			header = [
				$("<div/>", { "class": "dingdong-row" }).append(
					$("<div/>", { id: "dingdong-header", html: opts.header })
				)
			];
		}

		// maybe build subscribe section
		var subscribe;
		if (showSubscribe) {
			subscribe = [
				$("<div/>", { id: "dingdong-subscribe-row", "class": "dingdong-row" }).append(
					$("<label/>", { for: "dingdong-subscribe", text: "Subscribe to newsletter" }).append(
						$("<span/>", { "class": "dingdong-switch" }).append(
							$("<input/>", { id: "dingdong-subscribe", name: "subscribe", type: "checkbox" }),
							$("<div/>", { "class": "dingdong-switch-slider" })
						)
					)
				),
				$("<div/>", { id: "dingdong-name-row", "class": "dingdong-row" }).append(
					$("<input/>", { id: "dingdong-fname", name: "fname", type: "text", placeholder: fnamePlaceholder, required: "required", width: "50%" }),
					$("<input/>", { id: "dingdong-lname", name: "lname", type: "text", placeholder: lnamePlaceholder, required: "required", width: "50%" })
				)
			];
		}

		var message;
		if (showMessage) {
			message = [
				$("<div/>", { id: "dingdong-message-row", "class": "dingdong-row" }).append(
					$("<textarea/>", { id: "dingdong-message", name: "message", rows: messageRows, placeholder: messagePlaceholder, required: "required" })
				)
			];
		}

		var email = [
			$("<div/>", { "class": "dingdong-row" }).append(
				$("<input/>", { id: "dingdong-email", name: "email", type: "email", placeholder: emailPlaceholder, required: "required" })
			)
		];

		var submit = [
			$("<button/>", { id: "dingdong-submit", type: "submit", text: submitButtonText })
		];

		// remove existing if $.dingdong has already been called
		$("#dingdong-button").remove();
		$("#dingdong").remove();

		// add dingdong button
		$("body").append(
			$("<button />", { id: "dingdong-button", style: "display: none", text: buttonText })
		);

		// add dingdong modal
		$("body").append(
			$("<div/>", { id: "dingdong", style: "display: none" }).append(
				$("<div/>", { id: "dingdong-box" }).append(
					$("<div/>", { id: "dingdong-close", text: "\u00D7" }),
					$("<form/>", { id: "dingdong-form" }).append(
						header,
						email,
						message,
						subscribe,
						submit
					)
				)
			)
		);

		// maybe listen for esc to cancel
		if (!disableEscapeToCancel) {
			$(document).keydown(function(e) {
		    if (e.keyCode == 27) {
		        $.dingdongCancel();
		    }
			});
		}

		// toggle name fields when subscribe checkbox changes
		$("#dingdong-subscribe").change(function () {
			var checked = $(this).is(":checked");
			if (checked) {
				$("#dingdong-name-row").slideDown();
			} else {
				$("#dingdong-name-row").slideUp();
			}
			$("#dingdong-fname").prop("required", checked);
			$("#dingdong-lname").prop("required", checked);
		});

		// show dingdong when button is clicked
		$("#dingdong-button").click(function () {
			$.dingdongShow();
		});

		// cancel dingdong when backdrop or close is clicked
		$("#dingdong, #dingdong-close").click(function () {
			$.dingdongCancel();
		});

		// prevent clicks inside the box from propagating
		// (otherwise any click inside will trigger above cancel)
		$("#dingdong-box").click(function (e) {
			e.stopPropagation();
		});

		// handle form submission (prevent default behavior since ajax)
		$("#dingdong-form").submit(function (e) {
			e.preventDefault();
			var data = {
				message: $("#dingdong-message").val(),
				email: $("#dingdong-email").val(),
				subscribe: $("#dingdong-subscribe").is(":checked"),
				fname: $("#dingdong-fname").val(),
				lname: $("#dingdong-lname").val()
			};
			function callback(err) {
				if (err) {
					$("#dingdong-submit").prop("disabled", false);
				} else {
					$.dingdongHide();
				}
			}
			$("#dingdong-submit").prop("disabled", true);
			if (opts.handler) {
				opts.handler(data, callback);
			} else {
				defaultHandler(opts.endpoint, data, callback);
			}
			return false;
		});

	}

}(jQuery));
<|endoftext|>


<commit_before>import {graphql, createPaginationContainer} from 'react-relay';
import PropTypes from 'prop-types';
import React from 'react';

import {PAGE_SIZE, PAGINATION_WAIT_TIME_MS} from '../helpers';

export class BarePullRequestReviewCommentsContainer extends React.Component {

  static propTypes = {
    collectComments: PropTypes.func.isRequired,
    review: PropTypes.shape({
      id: PropTypes.string.isRequired,
      submittedAt: PropTypes.string.isRequired,
      comments: PropTypes.arrayOf(PropTypes.object).isRequired,
    }),
    relay: PropTypes.shape({
      hasMore: PropTypes.func.isRequired,
      loadMore: PropTypes.func.isRequired,
      isLoading: PropTypes.func.isRequired,
    }).isRequired,
  }

  componentDidMount() {
    this._attemptToLoadMoreComments();
    const {submittedAt, comments, id} = this.props.review;
    this.props.collectComments({reviewId: id, submittedAt, comments, hasMore: this.props.relay.hasMore()});
  }

  _loadMoreComments = () => {
    this.props.relay.loadMore(
      PAGE_SIZE,
      error => {
        const {submittedAt, comments, id} = this.props.review;
        this.props.collectComments({reviewId: id, submittedAt, comments, hasMore: this.props.relay.hasMore()});
        this._attemptToLoadMoreComments();
        if (error) {
          // eslint-disable-next-line no-console
          console.error(error);
        }
      },
    );
  }

  _attemptToLoadMoreComments = () => {
    if (!this.props.relay.hasMore()) {
      return;
    }

    if (this.props.relay.isLoading()) {
      setTimeout(() => {
        this._loadMoreComments();
      }, PAGINATION_WAIT_TIME_MS);
    } else {
      this._loadMoreComments();
    }
  }

  render() {
    return null;
  }
}

export default createPaginationContainer(BarePullRequestReviewCommentsContainer, {
  review: graphql`
    fragment prReviewCommentsContainer_review on PullRequestReview
    @argumentDefinitions(
      commentCount: {type: "Int!"},
      commentCursor: {type: "String"}
    ) {
      id
      submittedAt
      comments(
        first: $commentCount,
        after: $commentCursor
      ) @connection(key: "PrReviewCommentsContainer_comments") {
        pageInfo {
          hasNextPage
          endCursor
        }

        edges {
          cursor
          node {
            id
            author {
              avatarUrl
              login
            }
            bodyHTML
            path
            position
            replyTo {
              id
            }
            createdAt
            url
          }
        }
      }
    }
  `,
}, {
  direction: 'forward',
  getConnectionFromProps(props) {
    return props.review.comments;
  },
  getFragmentVariables(prevVars, totalCount) {
    return {
      ...prevVars,
      commentCount: totalCount,
    };
  },
  getVariables(props, {count, cursor}, fragmentVariables) {
    return {
      id: props.review.id,
      commentCount: count,
      commentCursor: cursor,
    };
  },
  query: graphql`
    query prReviewCommentsContainerQuery($commentCount: Int!, $commentCursor: String, $id: ID!) {
      node(id: $id) {
        ... on PullRequestReview {
          ...prReviewCommentsContainer_review @arguments(
            commentCount: $commentCount,
            commentCursor: $commentCursor
          )
        }
      }
    }
  `,
});
<commit_msg>to the PropTypes mobile, batman!!<commit_after>import {graphql, createPaginationContainer} from 'react-relay';
import PropTypes from 'prop-types';
import React from 'react';

import {PAGE_SIZE, PAGINATION_WAIT_TIME_MS} from '../helpers';

export class BarePullRequestReviewCommentsContainer extends React.Component {

  static propTypes = {
    collectComments: PropTypes.func.isRequired,
    review: PropTypes.shape({
      id: PropTypes.string.isRequired,
      submittedAt: PropTypes.string.isRequired,
      comments: PropTypes.object.isRequired,
    }),
    relay: PropTypes.shape({
      hasMore: PropTypes.func.isRequired,
      loadMore: PropTypes.func.isRequired,
      isLoading: PropTypes.func.isRequired,
    }).isRequired,
  }

  componentDidMount() {
    this._attemptToLoadMoreComments();
    const {submittedAt, comments, id} = this.props.review;
    this.props.collectComments({reviewId: id, submittedAt, comments, hasMore: this.props.relay.hasMore()});
  }

  _loadMoreComments = () => {
    this.props.relay.loadMore(
      PAGE_SIZE,
      error => {
        const {submittedAt, comments, id} = this.props.review;
        this.props.collectComments({reviewId: id, submittedAt, comments, hasMore: this.props.relay.hasMore()});
        this._attemptToLoadMoreComments();
        if (error) {
          // eslint-disable-next-line no-console
          console.error(error);
        }
      },
    );
  }

  _attemptToLoadMoreComments = () => {
    if (!this.props.relay.hasMore()) {
      return;
    }

    if (this.props.relay.isLoading()) {
      setTimeout(() => {
        this._loadMoreComments();
      }, PAGINATION_WAIT_TIME_MS);
    } else {
      this._loadMoreComments();
    }
  }

  render() {
    return null;
  }
}

export default createPaginationContainer(BarePullRequestReviewCommentsContainer, {
  review: graphql`
    fragment prReviewCommentsContainer_review on PullRequestReview
    @argumentDefinitions(
      commentCount: {type: "Int!"},
      commentCursor: {type: "String"}
    ) {
      id
      submittedAt
      comments(
        first: $commentCount,
        after: $commentCursor
      ) @connection(key: "PrReviewCommentsContainer_comments") {
        pageInfo {
          hasNextPage
          endCursor
        }

        edges {
          cursor
          node {
            id
            author {
              avatarUrl
              login
            }
            bodyHTML
            path
            position
            replyTo {
              id
            }
            createdAt
            url
          }
        }
      }
    }
  `,
}, {
  direction: 'forward',
  getConnectionFromProps(props) {
    return props.review.comments;
  },
  getFragmentVariables(prevVars, totalCount) {
    return {
      ...prevVars,
      commentCount: totalCount,
    };
  },
  getVariables(props, {count, cursor}, fragmentVariables) {
    return {
      id: props.review.id,
      commentCount: count,
      commentCursor: cursor,
    };
  },
  query: graphql`
    query prReviewCommentsContainerQuery($commentCount: Int!, $commentCursor: String, $id: ID!) {
      node(id: $id) {
        ... on PullRequestReview {
          ...prReviewCommentsContainer_review @arguments(
            commentCount: $commentCount,
            commentCursor: $commentCursor
          )
        }
      }
    }
  `,
});
<|endoftext|>