<commit_before>$(function() {

  // Storage of note model/properties.
  var notes = {};

  var currentQuery;
  var lgQuery = window.matchMedia("(min-width:1200px)");
  var mdQuery = window.matchMedia("(min-width:980px) and (max-width:1199px)");
  var smQuery = window.matchMedia("(min-width:768px) and (max-width:979px)");
  var xsQuery = window.matchMedia("(max-width:767px)");

  var resizeTimer; //set resizeTimer to empty so it resets on page load

  //entry point
  //caches note & image width, sets up resize handler
  var init = function() {
    findNotes();
    //on resize, run the function and reset the timeout
    //250 is the delay in milliseconds. Can be adjust as you see fit.
    $(window).resize(function() {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(checkSize, 250);
    });
  }

  var findNotes = function() {
    $(".DC-note-container").each(function() { getCoordinates($(this)); /*swapURL(this);*/ });
  }

  //link notes to wapo embedder pages instead of document cloud
  //var swapURL = function(note) {
  //    var note = $(note);
  //    if (note.data('wapo')) {
  //        var newLink = note.data('wapo');
  //        note.find('a').attr('href', newLink);
  //        note.find('a').attr('target', '_blank');
  //    }
  //}

  // gets default/canonical positioning data from the DOM for note & stores it.
  var getCoordinates = function(noteEl) {
    var noteID = $(noteEl).attr('id');

    var wrapWidth     = noteEl.find(".DC-note-excerpt").width();
    var docWidth      = noteEl.find(".DC-note-image").width();
    var docTop        = noteEl.find(".DC-note-image").position().top;
    var lCoverWidth   = noteEl.find(".DC-left-cover").width();
    var rCoverWidth   = noteEl.find(".DC-right-cover").width();
    var excerptHeight = noteEl.find(".DC-note-excerpt").height();
    var excerptLeft   = noteEl.find(".DC-note-excerpt").position().left;
    var excerptWidth  = noteEl.find(".DC-note-excerpt").width();

    if (docWidth != 0 && !(notes[noteID])) { //don't store notes that are set to display none
      //var x1 = lCoverWidth;
      //var y1 = (docTop) * -1;
      //
      //var x2 = x1 + (750 - (lCoverWidth + rCoverWidth));
      //var y2 = y1 + excerptHeight;
      //
      //var noteWidth = 750 - (lCoverWidth + rCoverWidth);//(x2 - x1);

      var note = {
        x1: lCoverWidth,
        x2: 750 - rCoverWidth,
        y1: -1* docTop,
        y2: -1* docTop + excerptHeight,

        noteID: noteID,
        wrapWidth: wrapWidth,
        docWidth: docWidth,
        docTop: docTop,
        lCoverWidth: lCoverWidth,
        rCoverWidth: rCoverWidth,
        excerptHeight: excerptHeight,
        excerptLeft: excerptLeft,
        excerptWidth: excerptWidth,

        noteWidth: 750 - (lCoverWidth + rCoverWidth)
      }

      notes[noteID] = note;
    }
    setMatchMedia();
  }

  //set up media event listeners
  var setMatchMedia = function() {
    //initial call of handleMatchMedia for each breakpoint
    handleMatchMedia(lgQuery);
    handleMatchMedia(mdQuery);
    handleMatchMedia(smQuery);
    handleMatchMedia(xsQuery);

    //add listeners for when viewport size changes
    lgQuery.addListener(handleMatchMedia);
    mdQuery.addListener(handleMatchMedia);
    smQuery.addListener(handleMatchMedia);
    xsQuery.addListener(handleMatchMedia);

    //orientation change listener
    window.addEventListener("orientationchange", function() {
      console.debug("orientation change = " + window.orientation);
      checkSize();
    }, false);
  }

  var handleMatchMedia = function(mediaQuery) {
    if (mediaQuery.matches) {
      console.log("mediaQuery.media = " + mediaQuery.media);
      currentQuery = mediaQuery.media;
      checkSize();
    }
  }

  //diffs the note's natural width with its current width and decides what to do
  var checkSize = function() {
    $.each(notes, function() {
      var noteElem = $("#" + this.noteID); // the notes lookup should just cache the element.
      var newWrapWidth = noteElem.find('.DC-note-excerpt-wrap').width(); // Get viewable width
      var checkWidth = this.noteWidth / newWrapWidth; // calculate the ration of the note's width to the veiwable width

      //// If we're at the smallest media width size just resize the doc/note
      //// otherwise check whether the note is larger or smaller than the viewerable width
      //if (currentQuery != xsQuery.media) {
      //  if (checkWidth > 1) { // note width is larger than viewable width
      //    resizeDoc(this.noteID);
      //  } else if (checkWidth < 1) { // note width is smaller than viewable width
      //    restoreDoc(this.noteID);
      //  }
      //} else {
      //  resizeDoc(this.noteID);
      //}
      resizeDoc(this.noteID);
    });
  }

  //calculates scaling factor based on the new note width & updates the note element's attributes
  var resizeDoc = function(noteID) {
    //original values
    var natNoteWidth = notes[noteID].noteWidth;
    var natWrapWidth = notes[noteID].wrapWidth;
    var natDocWidth  = notes[noteID].docWidth;

    //new values after resize of browser
    var newWrapWidth = $("#" + noteID + " .DC-note-excerpt-wrap").width();

    //calculate new width of document image
    var newDocWidth = natDocWidth - natNoteWidth + newWrapWidth;

    var scaling_factor   = newDocWidth / natDocWidth;
    var newExcerptWidth  = (notes[noteID].excerptWidth)  * scaling_factor;
    var newExcerptHeight = (notes[noteID].excerptHeight) * scaling_factor;

    //new x1,x2,y1,y2
    var newX1 = (notes[noteID].x1) * scaling_factor;
    var newX2 = (notes[noteID].x2) * scaling_factor;

    //apply calculations to elements
    scaleNoteImage(noteID, {
      imageHeight:     newExcerptHeight,
      imageWidth:      newDocWidth,
      leftCoverWidth:  newX1,
      excerptWidth:    newExcerptWidth,
      rightCoverWidth: newExcerptWidth - newX2,
      imageTop:        (notes[noteID].docTop) * scaling_factor,
      excerptLeft:     -1 * newX1
    });
  }

  //sets note element's attributes back to default
  var restoreDoc = function(noteID) {
    scaleNoteImage(noteID, {
      imageHeight:     notes[noteID].excerptHeight,
      imageWidth:      notes[noteID].docWidth,
      leftCoverWidth:  notes[noteID].lCoverWidth,
      excerptWidth:    notes[noteID].excerptWidth,
      rightCoverWidth: notes[noteID].rCoverWidth,
      imageTop:        notes[noteID].docTop,
      excerptLeft:     notes[noteID].excerptLeft
    });
  }

  var scaleNoteImage = function(noteID,dimensions){
    // set heights for note images.
    var noteEl = $("#"+noteID);
    noteEl.find(".DC-note-excerpt").height(dimensions.imageHeight);
    noteEl.find(".DC-left-cover"  ).height(dimensions.imageHeight);
    noteEl.find(".DC-right-cover" ).height(dimensions.imageHeight);

    // Set widths of viewable area, left cover, note excerpt, and right cover.
    noteEl.find(".DC-note-image"  ).width(dimensions.imageWidth);
    noteEl.find(".DC-left-cover"  ).width(dimensions.leftCoverWidth);
    noteEl.find(".DC-note-excerpt").width(dimensions.excerptWidth);
    noteEl.find(".DC-right-cover" ).width(dimensions.rightCoverWidth);

    // position left cover & note excerpt
    noteEl.find(".DC-note-image"  ).css('top', dimensions.imageTop);
    noteEl.find(".DC-note-excerpt").css('left', dimensions.excerptLeft);
  }

  //footnote click
  $(document).on('click', '.link-fn', function() {
    var fnLink = $(this);
    var fnLinkIcon = $(this).find('.fa');
    var fnID = $(this).data('fn');
    var footnote = $('#footnote' + fnID);
    if (footnote.hasClass('show')) {
      footnote.removeClass('show');
      footnote.slideUp({
        duration: 800,
        easing: 'swing'
      });
      fnLink.removeClass('reverse');
    } else {
      footnote.addClass('show');
      footnote.slideDown({
        duration: 800,
        easing: 'swing'
      });
      fnLink.addClass('reverse');
      //add note to notes and run subsequent functions
      var note = $(footnote).find('.DC-note-container');
      getCoords(note);
    }
    if (fnLinkIcon.hasClass('fa-caret-down')) {
      fnLinkIcon.removeClass('fa-caret-down').addClass('fa-caret-up');
    } else {
      fnLinkIcon.removeClass('fa-caret-up').addClass('fa-caret-down');
    }
  });

  $(window).load(function() {
    init();
  });

});
<commit_msg>Resize based on viewable area width vs note width.<commit_after>$(function() {

  // Storage of note model/properties.
  var notes = {};

  var currentQuery;
  var lgQuery = window.matchMedia("(min-width:1200px)");
  var mdQuery = window.matchMedia("(min-width:980px) and (max-width:1199px)");
  var smQuery = window.matchMedia("(min-width:768px) and (max-width:979px)");
  var xsQuery = window.matchMedia("(max-width:767px)");

  var resizeTimer; //set resizeTimer to empty so it resets on page load

  //entry point
  //caches note & image width, sets up resize handler
  var init = function() {
    findNotes();
    //on resize, run the function and reset the timeout
    //250 is the delay in milliseconds. Can be adjust as you see fit.
    $(window).resize(function() {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(checkSize, 250);
    });
  }

  var findNotes = function() {
    $(".DC-note-container").each(function() { getCoordinates($(this)); /*swapURL(this);*/ });
  }

  //link notes to wapo embedder pages instead of document cloud
  //var swapURL = function(note) {
  //    var note = $(note);
  //    if (note.data('wapo')) {
  //        var newLink = note.data('wapo');
  //        note.find('a').attr('href', newLink);
  //        note.find('a').attr('target', '_blank');
  //    }
  //}

  // gets default/canonical positioning data from the DOM for note & stores it.
  var getCoordinates = function(noteEl) {
    var noteID = $(noteEl).attr('id');

    var wrapWidth     = noteEl.find(".DC-note-excerpt").width();
    var docWidth      = noteEl.find(".DC-note-image").width();
    var docTop        = noteEl.find(".DC-note-image").position().top;
    var lCoverWidth   = noteEl.find(".DC-left-cover").width();
    var rCoverWidth   = noteEl.find(".DC-right-cover").width();
    var excerptHeight = noteEl.find(".DC-note-excerpt").height();
    var excerptLeft   = noteEl.find(".DC-note-excerpt").position().left;
    var excerptWidth  = noteEl.find(".DC-note-excerpt").width();

    if (docWidth != 0 && !(notes[noteID])) { //don't store notes that are set to display none
      //var x1 = lCoverWidth;
      //var y1 = (docTop) * -1;
      //
      //var x2 = x1 + (750 - (lCoverWidth + rCoverWidth));
      //var y2 = y1 + excerptHeight;
      //
      //var noteWidth = 750 - (lCoverWidth + rCoverWidth);//(x2 - x1);

      var note = {
        x1: lCoverWidth,
        x2: 750 - rCoverWidth,
        y1: -1* docTop,
        y2: -1* docTop + excerptHeight,

        noteID: noteID,
        wrapWidth: wrapWidth,
        docWidth: docWidth,
        docTop: docTop,
        lCoverWidth: lCoverWidth,
        rCoverWidth: rCoverWidth,
        excerptHeight: excerptHeight,
        excerptLeft: excerptLeft,
        excerptWidth: excerptWidth,

        noteWidth: 750 - (lCoverWidth + rCoverWidth)
      }

      notes[noteID] = note;
    }
    setMatchMedia();
  }

  //set up media event listeners
  var setMatchMedia = function() {
    //initial call of handleMatchMedia for each breakpoint
    handleMatchMedia(lgQuery);
    handleMatchMedia(mdQuery);
    handleMatchMedia(smQuery);
    handleMatchMedia(xsQuery);

    //add listeners for when viewport size changes
    lgQuery.addListener(handleMatchMedia);
    mdQuery.addListener(handleMatchMedia);
    smQuery.addListener(handleMatchMedia);
    xsQuery.addListener(handleMatchMedia);

    //orientation change listener
    window.addEventListener("orientationchange", function() {
      console.debug("orientation change = " + window.orientation);
      checkSize();
    }, false);
  }

  var handleMatchMedia = function(mediaQuery) {
    if (mediaQuery.matches) {
      console.log("mediaQuery.media = " + mediaQuery.media);
      currentQuery = mediaQuery.media;
      checkSize();
    }
  }

  //diffs the note's natural width with its current width and decides what to do
  var checkSize = function() {
    $.each(notes, function() {
      var noteElem = $("#" + this.noteID); // the notes lookup should just cache the element.
      var newWrapWidth = noteElem.find('.DC-note-excerpt-wrap').width(); // Get viewable width
      var checkWidth = this.noteWidth / newWrapWidth; // calculate the ration of the note's width to the veiwable width

      //// If we're at the smallest media width size just resize the doc/note
      //// otherwise check whether the note is larger or smaller than the viewerable width
      //if (currentQuery != xsQuery.media) {
      //  if (checkWidth > 1) { // note width is larger than viewable width
      //    resizeDoc(this.noteID);
      //  } else if (checkWidth < 1) { // note width is smaller than viewable width
      //    restoreDoc(this.noteID);
      //  }
      //} else {
      //  resizeDoc(this.noteID);
      //}

      //if viewable width < excerpt width, kill left cover & scale!
      if ( newWrapWidth < this.noteWidth ){ console.log("resizing", newWrapWidth, this.noteWidth); resizeDoc(this.noteID); } else { console.log("restoring"); restoreDoc(this.noteID); }
    });
  }

  //calculates scaling factor based on the new note width & updates the note element's attributes
  var resizeDoc = function(noteID) {
    //original values
    var natNoteWidth = notes[noteID].noteWidth;
    var natWrapWidth = notes[noteID].wrapWidth;
    var natDocWidth  = notes[noteID].docWidth;

    //new values after resize of browser
    var newWrapWidth = $("#" + noteID + " .DC-note-excerpt-wrap").width();

    //calculate new width of document image
    var newDocWidth = natDocWidth - natNoteWidth + newWrapWidth;

    var scaling_factor   = newDocWidth / natDocWidth;
    var newExcerptWidth  = (notes[noteID].excerptWidth)  * scaling_factor;
    var newExcerptHeight = (notes[noteID].excerptHeight) * scaling_factor;

    //new x1,x2,y1,y2
    var newX1 = (notes[noteID].x1) * scaling_factor;
    var newX2 = (notes[noteID].x2) * scaling_factor;

    //apply calculations to elements
    scaleNoteImage(noteID, {
      imageHeight:     newExcerptHeight,
      imageWidth:      newDocWidth,
      leftCoverWidth:  newX1,
      excerptWidth:    newExcerptWidth,
      rightCoverWidth: newExcerptWidth - newX2,
      imageTop:        (notes[noteID].docTop) * scaling_factor,
      excerptLeft:     -1 * newX1
    });
  }

  //sets note element's attributes back to default
  var restoreDoc = function(noteID) {
    scaleNoteImage(noteID, {
      imageHeight:     notes[noteID].excerptHeight,
      imageWidth:      notes[noteID].docWidth,
      leftCoverWidth:  notes[noteID].lCoverWidth,
      excerptWidth:    notes[noteID].excerptWidth,
      rightCoverWidth: notes[noteID].rCoverWidth,
      imageTop:        notes[noteID].docTop,
      excerptLeft:     notes[noteID].excerptLeft
    });
  }

  var scaleNoteImage = function(noteID,dimensions){
    // set heights for note images.
    var noteEl = $("#"+noteID);
    noteEl.find(".DC-note-excerpt").height(dimensions.imageHeight);
    noteEl.find(".DC-left-cover"  ).height(dimensions.imageHeight);
    noteEl.find(".DC-right-cover" ).height(dimensions.imageHeight);

    // Set widths of viewable area, left cover, note excerpt, and right cover.
    noteEl.find(".DC-note-image"  ).width(dimensions.imageWidth);
    noteEl.find(".DC-left-cover"  ).width(dimensions.leftCoverWidth);
    noteEl.find(".DC-note-excerpt").width(dimensions.excerptWidth);
    noteEl.find(".DC-right-cover" ).width(dimensions.rightCoverWidth);

    // position left cover & note excerpt
    noteEl.find(".DC-note-image"  ).css('top', dimensions.imageTop);
    noteEl.find(".DC-note-excerpt").css('left', dimensions.excerptLeft);
  }

  //footnote click
  $(document).on('click', '.link-fn', function() {
    var fnLink = $(this);
    var fnLinkIcon = $(this).find('.fa');
    var fnID = $(this).data('fn');
    var footnote = $('#footnote' + fnID);
    if (footnote.hasClass('show')) {
      footnote.removeClass('show');
      footnote.slideUp({
        duration: 800,
        easing: 'swing'
      });
      fnLink.removeClass('reverse');
    } else {
      footnote.addClass('show');
      footnote.slideDown({
        duration: 800,
        easing: 'swing'
      });
      fnLink.addClass('reverse');
      //add note to notes and run subsequent functions
      var note = $(footnote).find('.DC-note-container');
      getCoords(note);
    }
    if (fnLinkIcon.hasClass('fa-caret-down')) {
      fnLinkIcon.removeClass('fa-caret-down').addClass('fa-caret-up');
    } else {
      fnLinkIcon.removeClass('fa-caret-up').addClass('fa-caret-down');
    }
  });

  $(window).load(function() {
    init();
  });

});
<|endoftext|>


<commit_before>/*jslint indent: 2,
         nomen: true,
         maxlen: 100,
         sloppy: true,
         vars: true,
         white: true,
         plusplus: true */
/*global require */

////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoStructure
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

(function () {
  var internal = require("internal");
  var console = require("console");

  var ArangoDatabase = internal.ArangoDatabase;
  var ArangoCollection = internal.ArangoCollection;
  var ArangoError = internal.ArangoError;

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup V8Shell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////

  function ArangoStructure (collection, lang) {
    this._id = collection._id;
    this._collection = collection;
    this._language = lang;
  }

  internal.ArangoStructure = ArangoStructure;

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup V8Shell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief prints a collection
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype._PRINT = function (context) {
    var status = "unknown";
    var type = "unknown";

    switch (this.status()) {
      case ArangoCollection.STATUS_NEW_BORN: status = "new born"; break;
      case ArangoCollection.STATUS_UNLOADED: status = "unloaded"; break;
      case ArangoCollection.STATUS_UNLOADING: status = "unloading"; break;
      case ArangoCollection.STATUS_LOADED: status = "loaded"; break;
      case ArangoCollection.STATUS_CORRUPTED: status = "corrupted"; break;
      case ArangoCollection.STATUS_DELETED: status = "deleted"; break;
    }

    switch (this.type()) {
      case ArangoCollection.TYPE_DOCUMENT: type = "document"; break;
      case ArangoCollection.TYPE_EDGE:     type = "edge"; break;
    }

    context.output += "[ArangoStructure " + this._id + ", \"", this.name()
                    + "\" (type " + type + ", status " + status +"lang "
                    + this._language + ")]";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief parses a single attribute
////////////////////////////////////////////////////////////////////////////////

  function parse (lang, info, value) {
    var error;
    var module;

    try {
      module = require(info.module);
    }
    catch (err) {
      error = new ArangoError();
      error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
      error.errorMessage = String(err);

      throw error;
    }

    return module[info['do']](value, info, lang);
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief validates a single attribute
////////////////////////////////////////////////////////////////////////////////

  function validate (lang, info, value) {
    var error;
    var module;

    try {
      module = require(info.module);
    }
    catch (err) {
      error = new ArangoError();
      error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
      error.errorMessage = String(err);

      throw error;
    }

    module[info['do']](value, info, lang);
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief parses and validates a single attribute
////////////////////////////////////////////////////////////////////////////////

  function parseAndValidate (lang, info, value) {
    var type;

    // parse the input
    if (info.hasOwnProperty("parser")) {
      if (info.parser.hasOwnProperty(lang)) {
        value = parse(lang, info.parser[lang], value);
      }
      else if (info.parser.hasOwnProperty('default')) {
        value = parse(lang, info.parser['default'], value);
      }
    }
    else if (info.hasOwnProperty("type")) {
      type = info.type;

      if (type === "number") {
        value = parseFloat(value);
      }
      else if (type === "string") {
        value = String(value);
      }
      else if (type === "boolean") {
        if (value === 1 || value === "1" || (/^true$/i).test(value)) {
          value = true;
        }
        else {
         value = false;
        }
      }
    }

    // validate the input
    if (info.hasOwnProperty("validator")) {
      if (info.validator.hasOwnProperty(lang)) {
        validate(lang, info.validator[lang], value);
      }
      else if (info.validator.hasOwnProperty('default')) {
        validate(lang, info.validator['default'], value);
      }
    }

    // and return
    return value;
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief parses and validates the structure information recursively
////////////////////////////////////////////////////////////////////////////////

  function parseStructureInformationRecursive (lang, info, path, key, value) {
    var k;
    var result;

    if (info.attributes.hasOwnProperty(path)) {
      value = parseAndValidate(lang, info.attributes[path], value);
    }

    if (value instanceof Array) {
      return value;
    }

    if (value instanceof Object) {
      result = {};

      for (k in value) {
        if (value.hasOwnProperty(k)) {
          result[k] = parseStructureInformationRecursive(lang, info, path + "." + k, k, value[k]);
        }
      }

      return result;
    }

    return value;
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief parses and validates the structure information
////////////////////////////////////////////////////////////////////////////////

  function parseStructureInformation (lang, name, data) {
    var info;
    var key;
    var validated;

    info = internal.db._collection("_structures").firstExample({ collection: name });

    if (info === null) {
      return data;
    }

    validated = {};

    for (key in data) {
      if (data.hasOwnProperty(key)) {
        validated[key] = parseStructureInformationRecursive(lang, info, key, key, data[key]);
      }
    }

    return validated;
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief formats a single attribute
////////////////////////////////////////////////////////////////////////////////

  function format (lang, info, value) {
    var error;
    var module;

    try {
      module = require(info.module);
    }
    catch (err) {
      error = new ArangoError();
      error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
      error.errorMessage = String(err);

      throw error;
    }

    return module[info['do']](value, info, lang);
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief formats a single attribute
////////////////////////////////////////////////////////////////////////////////

  function formatValue (lang, info, value) {
    var type;

    // parse the input
    if (info.hasOwnProperty("formatter")) {
      if (info.formatter.hasOwnProperty(lang)) {
        value = format(lang, info.formatter[lang], value);
      }
      else if (info.formatter.hasOwnProperty('default')) {
        value = format(lang, info.formatter['default'], value);
      }
    }

    // and return
    return value;
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief formats the structure information recursively
////////////////////////////////////////////////////////////////////////////////

  function formatStructureInformationRecursive (lang, info, path, key, value) {
    var k;
    var result;

    if (info.attributes.hasOwnProperty(path)) {
      value = formatValue(lang, info.attributes[path], value);
    }

    if (value instanceof Array) {
      return value;
    }

    if (value instanceof Object) {
      result = {};

      for (k in value) {
        if (value.hasOwnProperty(k)) {
          result[k] = formatStructureInformationRecursive(lang, info, path + "." + k, k, value[k]);
        }
      }

      return result;
    }

    return value;
  }

////////////////////////////////////////////////////////////////////////////////
/// @brief formats the structure information
////////////////////////////////////////////////////////////////////////////////

  function formatStructureInformation (lang, name, data) {
    var info;
    var key;
    var formatted;

    info = internal.db._collection("_structures").firstExample({ collection: name });

    if (info === null) {
      return data;
    }

    formatted = {};

    for (key in data) {
      if (data.hasOwnProperty(key)) {
        formatted[key] = formatStructureInformationRecursive(lang, info, key, key, data[key]);
      }
    }

    return formatted;
  }

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup V8Shell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief name of a structure
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.name = function () {
    return this._collection.name();
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief status of a structure
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.status = function () {
    return this._collection.status();
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief type of a structure
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.type = function () {
    return this._collection.type();
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief saves a document
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.save = function (data, waitForSync) {
    data = parseStructureInformation(this._language, this._collection.name(), data);

    return this._collection.save(data, waitForSync);
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief replaces a document
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.replace = function (document, data, overwrite, waitForSync) {
    data = parseStructureInformation(this._language, this._collection.name(), data);

    return this._collection.save(document, data, overwrite, waitForSync);
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief deletes a document
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.remove = function (document, overwrite, waitForSync) {
    return this._collection.remove(document, overwrite, waitForSync);
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief reads a document
////////////////////////////////////////////////////////////////////////////////

  ArangoStructure.prototype.document = function (handle) {
    var data;

    data = this._collection.document(handle);

    return formatStructureInformation(this._language, this._collection.name(), data);
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief database accessor
////////////////////////////////////////////////////////////////////////////////

  ArangoDatabase.prototype._structure = function (name, lang) {
    var collection;

    collection = internal.db._collection(name);

    if (collection === null) {
      return null;
    }

    if (lang === undefined || lang === null) {
      lang = "en";
    }

    return new ArangoStructure(collection, lang);
  };

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

}());

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:
<commit_msg>removed unused file<commit_after><|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////
// FileWidget
// 13 January 2016
//
//
// Developed by :
// Diego Guidotti
// Michele Mammini
/////////////////////////////////////////////////////////////////////

Dbmng.FileWidget = Dbmng.AbstractWidget.extend({
  createWidget: function(){
    this.aField.value = this.getFieldValue();
    if(typeof jQuery().fileupload !== 'undefined'){
      this.aField.field_type='hidden';
    }
    else{
      this.aField.field_type='file';
    }
    return this.theme.getInput(this.aField);
    /*
    var self=this;

    var fld=this._super();
    fld.type='file';
    fld.name="files[]";
    //fld.setAttribute('data-url',url);
    fld.multiple=true;
    return fld;
    */
  },

  createField: function(data_val){
    var self=this;
    // console.log(self);

    var url='server/php/';
    if(self.aParam.url){
      url=self.aParam.url+"file/"+self.field+"/";
    }
    if(self.aField.url){
      url=self.aField.url;
    }
    var weburl_file=url+"files/";
    if(self.aField.weburl_file){
      weburl_file=self.aField.weburl_file;
    }

    var el = this._super(data_val);

    if(typeof jQuery().fileupload !== 'undefined'){

      var aVField = {};
      aVField.field = this.aField.field + '_file';

      var elv = this.theme.getInput(aVField);
      elv.type='file';
      elv.name="files[]";

      var opt={};
      var btn_class="btn btn-success";
      var btn_icon="glyphicon glyphicon-plus";
      var btn_label="Select file...";
      var uploading_text="Uploading...";

      if( self.aField.class ) {
        btn_class = self.aField.class;
      }
      if( self.aField.add_icon ) {
        btn_icon = self.aField.add_icon;
      }
      if( self.aField.label_file ) {
        btn_label = self.aField.label_file;
      }
      if( self.aField.uploading_text ) {
        uploading_text = self.aField.uploading_text;
      }

      opt.class = btn_class;
      opt.icon  = btn_icon;
      opt.label_file = btn_label;

      el.appendChild(this.theme.createFileUploadField(elv,btn_label, opt));

      var info=jQuery(el).find('.dbmng_fileupload_container');

      var el_progress=jQuery(el).find('.progress');

      // var info=jQuery(el).find('.dbmng_fileupload_container');
      if(typeof data_val !== 'undefined' && data_val!=='' && data_val !==null ){
        self.addFile(info, weburl_file, data_val);
      }

      jQuery(elv).fileupload({
          url: url,
          dataType: 'json',
          add: function (e, data) {
            console.log(data);
            info.html(uploading_text);
            data.submit();
          },
          progressall: function (e, data) {
              var progress = parseInt(data.loaded / data.total * 100, 10);
              console.log(progress);
              jQuery(el_progress).find(".progress-bar").css(
                  'width',
                  progress + '%'
              );
          },
          fail:function (e, data) {
            console.log(data);
            info.html(self.theme.alertMessage("Error"));
          },
          done: function (e, data) {
            console.log(data);
            if(data.result.files){
              if(data.result.files.length>0){
                info.html("");
                jQuery.each(data.result.files, function (index, file) {
                  if(file.error){
                    info.append(self.theme.alertMessage(file.error));
                  }
                  else if (!file.completed){
                    info.append(self.theme.alertMessage("Not Completed!!!!"));
                  }
                  else{
                    console.log(data);
                    self.addFile(info, weburl_file, file.name);
                    self.setValue(file.name);
                  }
                });
              }
              else{
                  info.html("");
                  jQuery.each(data.messages, function(k,v){
                    info.append(self.theme.alertMessage(v));
                  });
              }
            }
            else{
              info.append(self.theme.alertMessage(data.result.message));
            }
          }
      });
    }
    else {
      jQuery(el).append(self.theme.alertMessage("Resources missing! Please load the following files: jquery-ui.js, jquery.iframe-transport and jquery.fileupload"));
    }

    return el;
  },

  addFile:function(info, weburl_file, file){
    var self=this;
    var btn_icon="glyphicon glyphicon-remove";
    if( self.aField.remove_icon ) {
      btn_icon = self.aField.remove_icon;
    }
    var btn_title = "Delete";
    if( self.aField.remove_title_icon ) {
      btn_title = self.aField.remove_title_icon;
    }

    info.append(""+this.assignFileTypeIcon(file)+" "+file+" ");
    var del=this.theme.getDeleteButton(btn_title, btn_icon);
    info.append(del);
    console.log("addFile");console.log(weburl_file);console.log(file);

    jQuery(del).click(function(){
      info.html("");
      self.setValue("");
    });
  },

  assignFileTypeIcon: function( file ) {
    console.log(typeof file);
    var aFile = file.split('.');
    var file_type_icon = "";
    if( aFile[1] == 'pdf' ) {
      file_type_icon = '';
    }
    return file_type_icon;
  }
});
<commit_msg>Update<commit_after>/////////////////////////////////////////////////////////////////////
// FileWidget
// 13 January 2016
//
//
// Developed by :
// Diego Guidotti
// Michele Mammini
/////////////////////////////////////////////////////////////////////

Dbmng.FileWidget = Dbmng.AbstractWidget.extend({
  createWidget: function(){
    this.aField.value = this.getFieldValue();
    if(typeof jQuery().fileupload !== 'undefined'){
      this.aField.field_type='hidden';
    }
    else{
      this.aField.field_type='file';
    }
    return this.theme.getInput(this.aField);
    /*
    var self=this;

    var fld=this._super();
    fld.type='file';
    fld.name="files[]";
    //fld.setAttribute('data-url',url);
    fld.multiple=true;
    return fld;
    */
  },

  createField: function(data_val){

    var self=this;
    // console.log(self);

    var url='server/php/';
    if(self.aParam.url){
      url=self.aParam.url+"file/"+self.field+"/";
    }
    if(self.aField.url){
      url=self.aField.url;
    }
    var weburl_file=url+"files/";
    if(self.aField.weburl_file){
      weburl_file=self.aField.weburl_file;
    }

    var el = this._super(data_val);

    if(typeof jQuery().fileupload !== 'undefined'){

      var aVField = {};
      aVField.field = this.aField.field + '_file';

      var elv = this.theme.getInput(aVField);
      elv.type='file';
      elv.name="files[]";

      var opt={};
      var btn_class="btn btn-success";
      var btn_icon="glyphicon glyphicon-plus";
      var btn_label="Select file...";
      var uploading_text="Uploading...";

      if( self.aField.class ) {
        btn_class = self.aField.class;
      }
      if( self.aField.add_icon ) {
        btn_icon = self.aField.add_icon;
      }
      if( self.aField.label_file ) {
        btn_label = self.aField.label_file;
      }
      if( self.aField.uploading_text ) {
        uploading_text = self.aField.uploading_text;
      }

      opt.class = btn_class;
      opt.icon  = btn_icon;
      opt.label_file = btn_label;

      el.appendChild(this.theme.createFileUploadField(elv,btn_label, opt));

      var info=jQuery(el).find('.dbmng_fileupload_container');

      var el_progress=jQuery(el).find('.progress');

      // var info=jQuery(el).find('.dbmng_fileupload_container');
      if(typeof data_val !== 'undefined' && data_val!=='' && data_val !==null ){
        self.addFile(info, weburl_file, data_val);
      }

      jQuery(elv).fileupload({
          url: url,
          dataType: 'json',
          add: function (e, data) {
            console.log(data);
            info.html(uploading_text);
            data.submit();
          },
          progressall: function (e, data) {
              var progress = parseInt(data.loaded / data.total * 100, 10);
              console.log(progress);
              jQuery(el_progress).find(".progress-bar").css(
                  'width',
                  progress + '%'
              );
          },
          fail:function (e, data) {
            console.log(data);
            info.html(self.theme.alertMessage("Error"));
          },
          done: function (e, data) {
            console.log(data);
            if(data.result.files){
              if(data.result.files.length>0){
                info.html("");
                jQuery.each(data.result.files, function (index, file) {
                  if(file.error){
                    info.append(self.theme.alertMessage(file.error));
                  }
                  else if (!file.completed){
                    info.append(self.theme.alertMessage("Not Completed!!!!"));
                  }
                  else{
                    console.log(data);
                    self.addFile(info, weburl_file, file.name);
                    self.setValue(file.name);
                  }
                });
              }
              else{
                  info.html("");
                  jQuery.each(data.messages, function(k,v){
                    info.append(self.theme.alertMessage(v));
                  });
              }
            }
            else{
              info.append(self.theme.alertMessage(data.result.message));
            }
          }
      });
    }
    else {
      jQuery(el).append(self.theme.alertMessage("Resources missing! Please load the following files: jquery-ui.js, jquery.iframe-transport and jquery.fileupload"));
    }

    return el;
  },

  addFile:function(info, weburl_file, file){
    var self=this;
    var btn_icon="glyphicon glyphicon-remove";
    if( self.aField.remove_icon ) {
      btn_icon = self.aField.remove_icon;
    }
    var btn_title = "Delete";
    if( self.aField.remove_title_icon ) {
      btn_title = self.aField.remove_title_icon;
    }

    info.append(""+this.assignFileTypeIcon(file)+" "+file+" ");
    var del=this.theme.getDeleteButton(btn_title, btn_icon);
    info.append(del);
    console.log("addFile");console.log(weburl_file);console.log(file);

    jQuery(del).click(function(){
      info.html("");
      self.setValue("");
    });
  },

  assignFileTypeIcon: function( file ) {
    console.log(typeof file);
    var aFile = file.split('.');
    var file_type_icon = "";
    if( aFile[1] == 'pdf' ) {
      file_type_icon = '';
    }
    return file_type_icon;
  }
});
<|endoftext|>


<commit_before>'use strict';

var AppDispatcher = require('../dispatcher/AppDispatcher');
var ResponseConstants = require('../constants/ResponseConstants');

var PromiseHandlers = {
  /**
   * (Simple) Function to handle success response from server.
   * Does not distinguish between different kinds of 20x responses.
   * Should be pre-bound with actionType.
   *
   * @param  {string} actionType The action type to dispatch.
   * @param  {any} response The data value from ajax success, will be dispatched as data in action.
   */
  handleSuccess: function(actionType, response) {
    AppDispatcher.handleStoreRefreshAction({
      actionType: actionType,
      data: response
    });
  },

  /**
   * (Simple) Function to handle not found response from server.
   * Should be pre-bound with targetValue and actionType.
   *
   * @param  {any} targetValue The value to dispatch as data in the action.
   * @param  {string} actionType The action type to dispatch.
   * @param  {jqXHR} response The response from the request.
   */
  handleNotFound: function(targetValue, actionType, response) {
    if (response.status == 404) {
      AppDispatcher.handleStoreRefreshAction({
        actionType: actionType,
        data: []
      });
    }
  },

  /**
   * Function to build error message object from server error response.

   * @param  {callback} receiver Called with the generated error object.
   * @param  {jqXHR} response The error response to handle.
   */
  handleError: function(receiver, response) {
    switch (response.status) {
      case 400:
      case 409:
        receiver({
          type: ResponseConstants.INVALID_DATA,
          messages: JSON.parse(response.responseText)
        });
        break;
      case 403:
        receiver({
          type: ResponseConstants.FORBIDDEN
        });
        break;
      case 404:
        receiver({
          type: ResponseConstants.NOT_FOUND
        });
        break;
      default:
        receiver({
          type: response.status + ' error',
          status: response.status,
          messages: response.responseText
        });
    }
  }
};

module.exports = PromiseHandlers;
<commit_msg>Fix default value bug in PromiseHandlers.handleNotFound<commit_after>'use strict';

var AppDispatcher = require('../dispatcher/AppDispatcher');
var ResponseConstants = require('../constants/ResponseConstants');

var PromiseHandlers = {
  /**
   * (Simple) Function to handle success response from server.
   * Does not distinguish between different kinds of 20x responses.
   * Should be pre-bound with actionType.
   *
   * @param  {string} actionType The action type to dispatch.
   * @param  {any} response The data value from ajax success, will be dispatched as data in action.
   */
  handleSuccess: function(actionType, response) {
    AppDispatcher.handleStoreRefreshAction({
      actionType: actionType,
      data: response
    });
  },

  /**
   * (Simple) Function to handle not found response from server.
   * Should be pre-bound with targetValue and actionType.
   *
   * @param  {any} targetValue The value to dispatch as data in the action.
   * @param  {string} actionType The action type to dispatch.
   * @param  {jqXHR} response The response from the request.
   */
  handleNotFound: function(targetValue, actionType, response) {
    if (response.status == 404) {
      AppDispatcher.handleStoreRefreshAction({
        actionType: actionType,
        data: targetValue
      });
    }
  },

  /**
   * Function to build error message object from server error response.

   * @param  {callback} receiver Called with the generated error object.
   * @param  {jqXHR} response The error response to handle.
   */
  handleError: function(receiver, response) {
    switch (response.status) {
      case 400:
      case 409:
        receiver({
          type: ResponseConstants.INVALID_DATA,
          messages: JSON.parse(response.responseText)
        });
        break;
      case 403:
        receiver({
          type: ResponseConstants.FORBIDDEN
        });
        break;
      case 404:
        receiver({
          type: ResponseConstants.NOT_FOUND
        });
        break;
      default:
        receiver({
          type: response.status + ' error',
          status: response.status,
          messages: response.responseText
        });
    }
  }
};

module.exports = PromiseHandlers;
<|endoftext|>


<commit_before>
"use strict";

var extobject = {

  initialize: function() {
    // some declarations for clearer structure

    this.mouseMode = "none";  // node, port, selectbox

    this.dragstartPos = [0, 0];
    this.draglastPos = [0, 0];
    this.dragstopPos = [0, 0];
    this.dragstartPara = {};
    this.dragstopPara = {};
    this.dropPossible = false;

    this.mousedownPos = [0, 0];
    this.mouseupPos = [0, 0];
    this.mouselastPos = [0, 0];

    this.jqdataflow = $("#dataflow");
    this.selectbox = {
      x1: 0,
      x2: 0,
      y1: 0,
      y2: 0
    };
    this.prepareInteraction();

    this.shifted = false;
    this.ctrled = false;
  },

  trackMousemove: function(disabled) {
    var manager = this;
    if (disabled) {
      this.jqdataflow.off("mousemove");
    } else {
      this.jqdataflow.mousemove(function(event, ui){
        manager.currentMouseX = event.pageX;
        manager.currentMouseY = event.pageY;
      });
    }
  },

  prepareInteraction: function() {
    this.trackMousemove();

    this.jqselectbox = $("#dataflow-selectbox");
    this.jqselectbox.hide();
    var manager = this;
    this.jqdataflow
      .mousedown(function(event, ui) {
        manager.mousedownHandler({
          type: "background",
          event: event
        });
      })
      .mousemove(function(event, ui) {
        manager.mousemoveHandler({
          type: "background",
          event: event
        });
      })
      .mouseup(function(event, ui) {
        manager.mouseupHandler({
          type: "background",
          event: event
        });
      });

    // track keyboard: shift key
    $(document).keydown(function(event) {
      if (event.keyCode == 16) {
        manager.shifted = true;
      } else if (event.keyCode == 17) {
        manager.ctrled = true;
        manager.jqdataflow.css("cursor", "move");
      }
      return true;
    });
    $(document).keyup(function(event) {
      if (event.keyCode == 16) {
        manager.shifted = false;
      } else if (event.keyCode == 17) {
        manager.ctrled = false;
        manager.jqdataflow.css("cursor", "");
      }
      return true;
    });

  },

  mousedownHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.mousedownPos = [event.pageX, event.pageY];
    this.mouselastPos = [event.pageX, event.pageY];

    if (this.mouseMode != "none")
      return;

    if (type == "background") {
      if (this.ctrled) {
        this.mouseMode = "pan";
      } else {
        this.selectbox.x1 = event.pageX;
        this.selectbox.y1 = event.pageY;
        this.mouseMode = "selectbox";
      }
    } else if (type == "node") {
      this.mouseMode = "node";
    }
  },
  mousemoveHandler: function(para) {
    var type = para.type,
        event = para.event;
    //if (this.mouseMode != type)
    //  return;
    if (type == "background") {
      if (this.mouseMode == "pan") {
        var dx = event.pageX - this.mouselastPos[0],
            dy = event.pageY - this.mouselastPos[1];
        core.dataflowManager.moveNodes(dx, dy, core.dataflowManager.nodes);
      } else if (this.mouseMode == "selectbox") {
        this.selectbox.x2 = event.pageX;
        this.selectbox.y2 = event.pageY;
        var w = Math.abs(this.selectbox.x2 - this.selectbox.x1),
            h = Math.abs(this.selectbox.y2 - this.selectbox.y1),
            l = Math.min(this.selectbox.x1, this.selectbox.x2),
            t = Math.min(this.selectbox.y1, this.selectbox.y2);
        var box = {
            width: w,
            height: h,
            left: l,
            top: t
        };
        this.jqselectbox
          .css(box)
          .show();
        var hovered = core.dataflowManager.getNodesInSelectbox(box);
        core.dataflowManager.clearNodeHover();
        core.dataflowManager.addNodeHover(hovered);
      }
    }
    this.mouselastPos = [event.pageX, event.pageY];
  },
  mouseupHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.mouseupPos = [event.pageX, event.pageY];
    var dx = this.mouseupPos[0] - this.mousedownPos[0],
        dy = this.mousedownPos[1] - this.mousedownPos[1];
    this.mouseMoved = Math.abs(dx) + Math.abs(dy) > 0;

    if (type == "background") {
      if (this.mouseMode == "pan") {
        this.jqdataflow.css("cursor", "");
      } else if (this.mouseMode == "selectbox") {
        this.jqselectbox.hide();
        if (!this.mouseMoved){
          // mouse not moved for select box
          // trigger empty click
          this.clickHandler({
            type: "empty",
            event: event
          });
        } else if (!this.ctrled) {  // not panning, then selecting
          if (!this.shifted)
            core.dataflowManager.clearNodeSelection();
          core.dataflowManager.addHoveredToSelection();
        }
      }
    } else if (type == "node") {
      if (!this.mouseMoved) {
        if (!this.shifted)
          core.dataflowManager.clearNodeSelection();
        core.dataflowManager.addNodeSelection(para.node);
      }
    }
    this.mouseMode = "none";
  },

  dragstartHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.dragstartPara = para;
    if (type == "port") {
      this.mouseMode = "port";
      var jqtarget = $(para.event.target);
      var x = jqtarget.offset().left + jqtarget.outerWidth() / 2,
          y = jqtarget.offset().top + jqtarget.outerHeight() / 2;
      //console.log(jqtarget,x,y, jqtarget.outerWidth());
      this.dragstartPos = [x, y];
      this.dropPossible = true;
    } else if (type == "node") {
      this.mouseMode = "node";

      if (core.dataflowManager.isNodeSelected(para.node)) {
        // already selected, then drag all selection
      } else {
        // make a new exclusive selection
        core.dataflowManager.clearNodeSelection();
        core.dataflowManager.addNodeSelection(para.node);
      }
      this.draglastPos = [event.pageX, event.pageY];
    }
  },

  dragmoveHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.dragstopPos = [para.event.pageX, para.event.pageY];
    if (this.mouseMode != type)
      return;
    if (type == "port") {
      var dx = this.dragstopPos[0] - this.dragstartPos[0],
          dy = this.dragstopPos[1] - this.dragstartPos[1];

      if (para.portId.substr(0,2) === "in") {
        dx = -dx;
        dy = -dy;
        $("#dataflow-edge-drawing")
          .css("left", this.dragstopPos[0])
          .css("top", this.dragstopPos[1]);
      } else {
        $("#dataflow-edge-drawing")
        .css("left", this.dragstartPos[0])
        .css("top", this.dragstartPos[1]);
      }
      var length = Math.sqrt(dx * dx + dy * dy);
      var angle = Math.atan2(dy, dx);
      //console.log(angle);
      $("#dataflow-edge-drawing")
        .css("width", length)
        .css("transform", "rotate("+ angle +"rad)")
        .css("visibility", "visible");
    } else if (type == "node") {
      var dx = event.pageX - this.draglastPos[0],
          dy = event.pageY - this.draglastPos[1];

      // the dragged node is moving together (with more offset)
      // the more offset will be reset immediately by jquery draggable however
      core.dataflowManager.moveNodes(dx, dy, core.dataflowManager.nodesSelected);  // delta & nodes
      this.draglastPos = [event.pageX, event.pageY];
    }
  },

  dragstopHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.dragstopPara = para;
    this.dragstopPos = [para.event.pageX, para.event.pageY];
    if (type == "port") {
      $("#dataflow-edge-drawing")
        .css("visibility", "hidden");
    } else if (type == "node"){
    }
    this.mouseMode = "none";
  },

  dropHandler: function(para) {
    var type = para.type,
        event = para.event;
    if (type === "port" && this.dropPossible) {
      // connect ports
      var port1 = {
        node: this.dragstartPara.node,
        portId: this.dragstartPara.portId,
      };
      var port2 = {
        node: para.node,
        portId: para.portId
      };
      if (port1.portId.substr(0,2) === "in") {
        // always connect from out to in
        var porttmp = port1;
        port1 = port2;
        port2 = porttmp;
      }
      core.dataflowManager.createEdge(port1, port2);
      this.dropPossible = false; // prevent dropped on overlapping droppable
    }
  },

  clickHandler: function(para) {
    var type = para.type,
        event = para.event;
    if (type == "empty") {
      core.dataflowManager.clearNodeSelection();
    }
  }

/*
  getDragstartPara: function() {
    return this.dragstartPara;
  },
  getDragstopPara: function() {
    return this.dragstopPara;
  }
  */
};

var InteractionManager = Base.extend(extobject);
<commit_msg>node drag cursor<commit_after>
"use strict";

var extobject = {

  initialize: function() {
    // some declarations for clearer structure

    this.mouseMode = "none";  // node, port, selectbox

    this.dragstartPos = [0, 0];
    this.draglastPos = [0, 0];
    this.dragstopPos = [0, 0];
    this.dragstartPara = {};
    this.dragstopPara = {};
    this.dropPossible = false;

    this.mousedownPos = [0, 0];
    this.mouseupPos = [0, 0];
    this.mouselastPos = [0, 0];

    this.jqdataflow = $("#dataflow");
    this.selectbox = {
      x1: 0,
      x2: 0,
      y1: 0,
      y2: 0
    };
    this.prepareInteraction();

    this.shifted = false;
    this.ctrled = false;
  },

  trackMousemove: function(disabled) {
    var manager = this;
    if (disabled) {
      this.jqdataflow.off("mousemove");
    } else {
      this.jqdataflow.mousemove(function(event, ui){
        manager.currentMouseX = event.pageX;
        manager.currentMouseY = event.pageY;
      });
    }
  },

  prepareInteraction: function() {
    this.trackMousemove();

    this.jqselectbox = $("#dataflow-selectbox");
    this.jqselectbox.hide();
    var manager = this;
    this.jqdataflow
      .mousedown(function(event, ui) {
        manager.mousedownHandler({
          type: "background",
          event: event
        });
      })
      .mousemove(function(event, ui) {
        manager.mousemoveHandler({
          type: "background",
          event: event
        });
      })
      .mouseup(function(event, ui) {
        manager.mouseupHandler({
          type: "background",
          event: event
        });
      });

    // track keyboard: shift key
    $(document).keydown(function(event) {
      if (event.keyCode == 16) {
        manager.shifted = true;
      } else if (event.keyCode == 17) {
        manager.ctrled = true;
        manager.jqdataflow.css("cursor", "move");
      }
      return true;
    });
    $(document).keyup(function(event) {
      if (event.keyCode == 16) {
        manager.shifted = false;
      } else if (event.keyCode == 17) {
        manager.ctrled = false;
        manager.jqdataflow.css("cursor", "");
      }
      return true;
    });

  },

  mousedownHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.mousedownPos = [event.pageX, event.pageY];
    this.mouselastPos = [event.pageX, event.pageY];

    if (this.mouseMode != "none")
      return;

    if (type == "background") {
      if (this.ctrled) {
        this.mouseMode = "pan";
      } else {
        this.selectbox.x1 = event.pageX;
        this.selectbox.y1 = event.pageY;
        this.mouseMode = "selectbox";
      }
    } else if (type == "node") {
      this.mouseMode = "node";
    }
  },
  mousemoveHandler: function(para) {
    var type = para.type,
        event = para.event;
    //if (this.mouseMode != type)
    //  return;
    if (type == "background") {
      if (this.mouseMode == "pan") {
        var dx = event.pageX - this.mouselastPos[0],
            dy = event.pageY - this.mouselastPos[1];
        core.dataflowManager.moveNodes(dx, dy, core.dataflowManager.nodes);
      } else if (this.mouseMode == "selectbox") {
        this.selectbox.x2 = event.pageX;
        this.selectbox.y2 = event.pageY;
        var w = Math.abs(this.selectbox.x2 - this.selectbox.x1),
            h = Math.abs(this.selectbox.y2 - this.selectbox.y1),
            l = Math.min(this.selectbox.x1, this.selectbox.x2),
            t = Math.min(this.selectbox.y1, this.selectbox.y2);
        var box = {
            width: w,
            height: h,
            left: l,
            top: t
        };
        this.jqselectbox
          .css(box)
          .show();
        var hovered = core.dataflowManager.getNodesInSelectbox(box);
        core.dataflowManager.clearNodeHover();
        core.dataflowManager.addNodeHover(hovered);
      }
    }
    this.mouselastPos = [event.pageX, event.pageY];
  },
  mouseupHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.mouseupPos = [event.pageX, event.pageY];
    var dx = this.mouseupPos[0] - this.mousedownPos[0],
        dy = this.mousedownPos[1] - this.mousedownPos[1];
    this.mouseMoved = Math.abs(dx) + Math.abs(dy) > 0;

    if (type == "background") {
      if (this.mouseMode == "pan") {
        this.jqdataflow.css("cursor", "");
      } else if (this.mouseMode == "selectbox") {
        this.jqselectbox.hide();
        if (!this.mouseMoved){
          // mouse not moved for select box
          // trigger empty click
          this.clickHandler({
            type: "empty",
            event: event
          });
        } else if (!this.ctrled) {  // not panning, then selecting
          if (!this.shifted)
            core.dataflowManager.clearNodeSelection();
          core.dataflowManager.addHoveredToSelection();
        }
      }
    } else if (type == "node") {
      if (!this.mouseMoved) {
        if (!this.shifted)
          core.dataflowManager.clearNodeSelection();
        core.dataflowManager.addNodeSelection(para.node);
      }
    }
    this.mouseMode = "none";
  },

  dragstartHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.dragstartPara = para;
    if (type == "port") {
      this.mouseMode = "port";
      var jqtarget = $(para.event.target);
      var x = jqtarget.offset().left + jqtarget.outerWidth() / 2,
          y = jqtarget.offset().top + jqtarget.outerHeight() / 2;
      //console.log(jqtarget,x,y, jqtarget.outerWidth());
      this.dragstartPos = [x, y];
      this.dropPossible = true;
    } else if (type == "node") {
      this.mouseMode = "node";
      this.jqdataflow.css("cursor", "move");

      if (core.dataflowManager.isNodeSelected(para.node)) {
        // already selected, then drag all selection
      } else {
        // make a new exclusive selection
        core.dataflowManager.clearNodeSelection();
        core.dataflowManager.addNodeSelection(para.node);
      }
    }
    this.draglastPos = [event.pageX, event.pageY];
  },

  dragmoveHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.dragstopPos = [para.event.pageX, para.event.pageY];
    if (this.mouseMode != type)
      return;
    if (type == "port") {
      var dx = this.dragstopPos[0] - this.dragstartPos[0],
          dy = this.dragstopPos[1] - this.dragstartPos[1];

      if (para.portId.substr(0,2) === "in") {
        dx = -dx;
        dy = -dy;
        $("#dataflow-edge-drawing")
          .css("left", this.dragstopPos[0])
          .css("top", this.dragstopPos[1]);
      } else {
        $("#dataflow-edge-drawing")
        .css("left", this.dragstartPos[0])
        .css("top", this.dragstartPos[1]);
      }
      var length = Math.sqrt(dx * dx + dy * dy);
      var angle = Math.atan2(dy, dx);
      //console.log(angle);
      $("#dataflow-edge-drawing")
        .css("width", length)
        .css("transform", "rotate("+ angle +"rad)")
        .css("visibility", "visible");
    } else if (type == "node") {
      var dx = event.pageX - this.draglastPos[0],
          dy = event.pageY - this.draglastPos[1];

      // the dragged node is moving together (with more offset)
      // the more offset will be reset immediately by jquery draggable however
      core.dataflowManager.moveNodes(dx, dy, core.dataflowManager.nodesSelected);  // delta & nodes
      this.draglastPos = [event.pageX, event.pageY];
    }
  },

  dragstopHandler: function(para) {
    var type = para.type,
        event = para.event;
    this.dragstopPara = para;
    this.dragstopPos = [para.event.pageX, para.event.pageY];
    if (type == "port") {
      $("#dataflow-edge-drawing")
        .css("visibility", "hidden");
    } else if (type == "node"){
      this.jqdataflow.css("cursor", "");
    }
    this.mouseMode = "none";
  },

  dropHandler: function(para) {
    var type = para.type,
        event = para.event;
    if (type === "port" && this.dropPossible) {
      // connect ports
      var port1 = {
        node: this.dragstartPara.node,
        portId: this.dragstartPara.portId,
      };
      var port2 = {
        node: para.node,
        portId: para.portId
      };
      if (port1.portId.substr(0,2) === "in") {
        // always connect from out to in
        var porttmp = port1;
        port1 = port2;
        port2 = porttmp;
      }
      core.dataflowManager.createEdge(port1, port2);
      this.dropPossible = false; // prevent dropped on overlapping droppable
    }
  },

  clickHandler: function(para) {
    var type = para.type,
        event = para.event;
    if (type == "empty") {
      core.dataflowManager.clearNodeSelection();
    }
  }

/*
  getDragstartPara: function() {
    return this.dragstartPara;
  },
  getDragstopPara: function() {
    return this.dragstopPara;
  }
  */
};

var InteractionManager = Base.extend(extobject);
<|endoftext|>


<commit_before>/******************************************
* Requests List View
*/
openstm.Views.RequestsListView = Backbone.View.extend({

	el : '#rowContainer',

	templateHTML: 'requestsList',

	numberListByPage: 25,

	btnOpenValidModalVisibility: "hidden",
	btnOpenModifyModalVisibility: "hidden",
	btnOpenCancelModalVisibility: "hidden",
	btnOpenToBeConfirmModalVisibility: "hidden",
	btnOpenConfirmModalVisibility: "hidden",

    // The DOM events //
    events: {
		'click li.active'		: 'preventDefault',
		'click li.disabled'		: 'preventDefault',

    	'click .btnOpenValidModal'		: 'openValidModal',
		'click #btnValidModal'			: 'validModal',

//		'click .btnOpenCancelModal'		: 'openCancelModal',
//		'click #btnCancelModal'			: 'cancelModal',
    },

	/** View Initialization
	*/
    initialize: function () {
		this.render();
    },

    openValidModal: function() {

    	$("#validModal #test").val( 'test' );

    	if( openstm.views.selectListServicesView  == null ) {
	    	openstm.views.selectListServicesView = new openstm.Views.DropdownSelectListView(
	    		{el: $("#requestService"), collection: openstm.collections.claimersServices})
	    	openstm.views.selectListServicesView.addAll();
	    }

	    if( openstm.views.selectListAssignementView  == null ) {
	    	openstm.views.selectListAssignementView = new openstm.Views.DropdownSelectListView(
	    		{el: $("#requestAssignement"), collection: openstm.collections.assignements})
	    	openstm.views.selectListAssignementView.addAll();
	    }

    	$("#validModal").modal();

    	//var model = new Backbone.Model({  title: 'Example Modal', body: 'Hello World' });
        //var view = new openstm.Views.ValidRequestModalView({ model: model });
        //view.show();
    },

    validModal: function() {
    	$("#validModal").modal('hide');

    },

    loadButtons : function() {
		var self = this;

		//userGroups = openstm.models.user.getGroups();
		//
		//$.each(userGroups, function(index, group) {
		//  	if ( jQuery.inArray( group, [18,19,16] ) == 0) {
		//		self.btnOpenValidModalVisibility = 'visible';
		//		self.btnOpenModifyModalVisibility = 'visible';
		//		self.btnOpenCancelModalVisibility = 'visible';
		//		return true;
		//  	}
		//  	if ( jQuery.inArray( group, [18] ) == 0 ) {
		//		self.btnOpenConfirmModalVisibility = 'visible';
		//		return true;
		//  	}
		//  	if ( jQuery.inArray( group, [19,16] ) == 0 ) {
		//		self.btnOpenToBeConfirmModalVisibility = 'visible';
		//		return true;
		//  	}
		//
		//});
		self.btnOpenValidModalVisibility = 'visible';
//		self.btnOpenModifyModalVisibility = 'visible';
//		self.btnOpenCancelModalVisibility = 'visible';
//		self.btnOpenConfirmModalVisibility = 'visible';
//		self.btnOpenToBeConfirmModalVisibility = 'visible';
    },

	/** Display the view
	*/
    render: function () {
		//openstm.Views.OpenstmView.prototype.render.call(this);
		var self = this;

		self.loadButtons();

		// Change the page title //
        openstm.router.setPageTitle(openstm.lang.viewsTitles.requestsList);

        // Change the active menu item //
        openstm.views.headerView.selectMenuItem(openstm.router.mainMenus.manageInterventions);

        // Change the Grid Mode of the view //
        openstm.views.headerView.switchGridMode('fluid');

		var requests = openstm.collections.requests.models;
		var len = requests.length;
		var startPos = (this.options.page - 1) * this.numberListByPage;
		var endPos = Math.min(startPos + this.numberListByPage, len);
		var pageCount = Math.ceil(len / this.numberListByPage);

        // Retrieve the number of waiting Interventions //
        var interventionsWaiting = _.filter(requests, function(item){ return item.attributes.state == openstm.Models.Request.state[1].value; });
        var nbInterventionsWaiting = _.size(interventionsWaiting);

		// Retrieve the template //
		$.get("templates/" + this.templateHTML + ".html", function(templateData){

			var template = _.template(templateData, {
				lang: openstm.lang,
				nbInterventionsWaiting: nbInterventionsWaiting,
				requests: openstm.collections.requests.toJSON(),
				requestsState: openstm.Models.Request.state,
				startPos: startPos, endPos: endPos,
				page: self.options.page,
				pageCount: pageCount,

				btnOpenValidModalVisibility: self.btnOpenValidModalVisibility,
				btnOpenModifyModalVisibility: self.btnOpenModifyModalVisibility,
				btnOpenCancelModalVisibility: self.btnOpenCancelModalVisibility,
				btnOpenToBeConfirmModalVisibility: self.btnOpenToBeConfirmModalVisibility,
				btnOpenConfirmModalVisibility: self.btnOpenConfirmModalVisibility,
			});

			console.debug(requests);

			$(self.el).html(template);

			// Display the Tooltip or Popover //
			$('*[rel="popover"]').popover({trigger: "hover"});
			$('*[rel="tooltip"]').tooltip({placement: "right"});
		});

		$(this.el).hide().fadeIn('slow');
        return this;
    },

    preventDefault: function(event){
    	event.preventDefault();
    },

});<commit_msg>bug request validation<commit_after>/******************************************
* Requests List View
*/
openstm.Views.RequestsListView = Backbone.View.extend({

	el : '#rowContainer',

	templateHTML: 'requestsList',

	numberListByPage: 25,

	btnOpenValidModalVisibility: "hidden",
	btnOpenModifyModalVisibility: "hidden",
	btnOpenCancelModalVisibility: "hidden",
	btnOpenToBeConfirmModalVisibility: "hidden",
	btnOpenConfirmModalVisibility: "hidden",

    // The DOM events //
    events: {
		'click li.active'		: 'preventDefault',
		'click li.disabled'		: 'preventDefault',

    	'click .btnOpenValidModal'		: 'openValidModal',
		'click #btnValidModal'			: 'validModal',

//		'click .btnOpenCancelModal'		: 'openCancelModal',
//		'click #btnCancelModal'			: 'cancelModal',
    },

	/** View Initialization
	*/
    initialize: function () {
		this.render();
    },

    openValidModal: function() {

    	$("#validModal #test").val( 'test' );

    	//if( openstm.views.selectListServicesView  == null ) {
	    	openstm.views.selectListServicesView = new openstm.Views.DropdownSelectListView(
	    		{el: $("#requestService"), collection: openstm.collections.claimersServices})
	    	openstm.views.selectListServicesView.clearAll();
	    	openstm.views.selectListServicesView.addAll();
	    //}

	    //if( openstm.views.selectListAssignementView  == null ) {
	    	openstm.views.selectListAssignementView = new openstm.Views.DropdownSelectListView(
	    		{el: $("#requestAssignement"), collection: openstm.collections.assignements})
	    	openstm.views.selectListAssignementView.clearAll();
	    	openstm.views.selectListAssignementView.addAll();
	    //}

    	$("#validModal").modal();

    	//var model = new Backbone.Model({  title: 'Example Modal', body: 'Hello World' });
        //var view = new openstm.Views.ValidRequestModalView({ model: model });
        //view.show();
    },

    validModal: function() {
    	$("#validModal").modal('hide');

    },

    loadButtons : function() {
		var self = this;

		//userGroups = openstm.models.user.getGroups();
		//
		//$.each(userGroups, function(index, group) {
		//  	if ( jQuery.inArray( group, [18,19,16] ) == 0) {
		//		self.btnOpenValidModalVisibility = 'visible';
		//		self.btnOpenModifyModalVisibility = 'visible';
		//		self.btnOpenCancelModalVisibility = 'visible';
		//		return true;
		//  	}
		//  	if ( jQuery.inArray( group, [18] ) == 0 ) {
		//		self.btnOpenConfirmModalVisibility = 'visible';
		//		return true;
		//  	}
		//  	if ( jQuery.inArray( group, [19,16] ) == 0 ) {
		//		self.btnOpenToBeConfirmModalVisibility = 'visible';
		//		return true;
		//  	}
		//
		//});
		self.btnOpenValidModalVisibility = 'visible';
//		self.btnOpenModifyModalVisibility = 'visible';
//		self.btnOpenCancelModalVisibility = 'visible';
//		self.btnOpenConfirmModalVisibility = 'visible';
//		self.btnOpenToBeConfirmModalVisibility = 'visible';
    },

	/** Display the view
	*/
    render: function () {
		//openstm.Views.OpenstmView.prototype.render.call(this);
		var self = this;

		self.loadButtons();

		// Change the page title //
        openstm.router.setPageTitle(openstm.lang.viewsTitles.requestsList);

        // Change the active menu item //
        openstm.views.headerView.selectMenuItem(openstm.router.mainMenus.manageInterventions);

        // Change the Grid Mode of the view //
        openstm.views.headerView.switchGridMode('fluid');

		var requests = openstm.collections.requests.models;
		var len = requests.length;
		var startPos = (this.options.page - 1) * this.numberListByPage;
		var endPos = Math.min(startPos + this.numberListByPage, len);
		var pageCount = Math.ceil(len / this.numberListByPage);

        // Retrieve the number of waiting Interventions //
        var interventionsWaiting = _.filter(requests, function(item){ return item.attributes.state == openstm.Models.Request.state[1].value; });
        var nbInterventionsWaiting = _.size(interventionsWaiting);

		// Retrieve the template //
		$.get("templates/" + this.templateHTML + ".html", function(templateData){

			var template = _.template(templateData, {
				lang: openstm.lang,
				nbInterventionsWaiting: nbInterventionsWaiting,
				requests: openstm.collections.requests.toJSON(),
				requestsState: openstm.Models.Request.state,
				startPos: startPos, endPos: endPos,
				page: self.options.page,
				pageCount: pageCount,

				btnOpenValidModalVisibility: self.btnOpenValidModalVisibility,
				btnOpenModifyModalVisibility: self.btnOpenModifyModalVisibility,
				btnOpenCancelModalVisibility: self.btnOpenCancelModalVisibility,
				btnOpenToBeConfirmModalVisibility: self.btnOpenToBeConfirmModalVisibility,
				btnOpenConfirmModalVisibility: self.btnOpenConfirmModalVisibility,
			});

			console.debug(requests);

			$(self.el).html(template);

			// Display the Tooltip or Popover //
			$('*[rel="popover"]').popover({trigger: "hover"});
			$('*[rel="tooltip"]').tooltip({placement: "right"});
		});

		$(this.el).hide().fadeIn('slow');
        return this;
    },

    preventDefault: function(event){
    	event.preventDefault();
    },

});<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {Table} from 'react-bootstrap';
import {connect} from 'react-redux';
import _ from 'lodash';

class ResultsTable extends Component {

  render() {
    const notVoted = _.difference(this.props.users, this.props.results.map(x => x['userName']));

    const voteFreqs = _.countBy(this.props.results, x => x['estimateValue']);
    const countedResults = this.props.results.map(x => ({...x, ...{'count': voteFreqs[parseInt(x['estimateValue'], 10)]}}));
    const sortedResults = _.orderBy(countedResults, ['count', 'userName']);

    return (

            User
            Vote

          {sortedResults.map(x => _renderVoteRow(x))}
          {notVoted.map((x) => _renderUserRow(x))}

    );
  }
}

function _renderUserRow(data) {
  return (

      {_.startCase(data)}
      -

  )
}

function _renderVoteRow(data) {
  return (

      {_.startCase(data.userName)}
      {data.estimateValue}

  )
}

function mapStateToProps(state) {
  return {
    results: state.results,
    users: state.users
  };
}

export default connect(mapStateToProps)(ResultsTable);
<commit_msg>order results table to show outliers first<commit_after>import React, {Component} from 'react';
import {Table} from 'react-bootstrap';
import {connect} from 'react-redux';
import _ from 'lodash';

class ResultsTable extends Component {

  render() {
    const notVoted = _.difference(this.props.users, this.props.results.map(x => x['userName']));

    const voteFreqs = _.countBy(this.props.results, x => x['estimateValue']);
    const countedResults = this.props.results.map(x => ({...x, ...{'count': voteFreqs[parseInt(x['estimateValue'], 10)]}}));
    const sortedResults = _.orderBy(countedResults, ['count', 'estimateValue', 'userName']);

    return (

            User
            Vote

          {sortedResults.map(x => _renderVoteRow(x))}
          {notVoted.map((x) => _renderUserRow(x))}

    );
  }
}

function _renderUserRow(data) {
  return (

      {_.startCase(data)}
      -

  )
}

function _renderVoteRow(data) {
  return (

      {_.startCase(data.userName)}
      {data.estimateValue}

  )
}

function mapStateToProps(state) {
  return {
    results: state.results,
    users: state.users
  };
}

export default connect(mapStateToProps)(ResultsTable);
<|endoftext|>


<commit_before>// Public API interface

function init() {
  console.log( 'is this working?' );
  let menuItems = $('.horizontal-menu .has-submenu')
  let menuItemsWithSub = $('.horizontal-menu .has-submenu')

  // menuItemsWithSub.on('click', (e)=>{
  //   e.preventDefault();
  //   console.log(e);
  //   e.
  // } )

  function buildSubNav() {

  }

    // // Expanding/Collapsing of the entire side menu on mobile devices
    // menuElement.children( `.${SIDEMENU_TOGGLE_CLASS}` ).children( 'a' ).on( 'click', function ( e ) {
    //   e.preventDefault();
    //   e.stopPropagation();
    //   $( this ).parent().toggleClass( SIDEMENU_EXPANDED_CLASS );
    // });

}

const horizontalNav = {
  init: init,
};

export default horizontalNav;
<commit_msg>Clean up old js<commit_after><|endoftext|>


<commit_before>// @noflow
'use strict';

const path = require('path');
const fs = require('fs');
const lookup = require('look-up');
const webpack = require('webpack');
const webpackFailPlugin = require('webpack-fail-plugin');

const findPackage = require('./src/find_package.js');

const resolve = require('resolve');
const mkdirp = require('mkdirp');

// We must place our files in a special folder for integration /w the android
// build system.
const destination = process.env.SILK_BUILDJS_DEST;
const modulePath = findPackage(process.env.SILK_BUILDJS_SOURCE);
const pkg = require(path.join(modulePath, 'package.json'));
const localWebpack = path.join(modulePath, 'webpack.config.js');
const ugly = process.env.SILK_BUILDJS_UGLY === 'true';
const target = process.env.SILK_BUILDJS_TARGET;
if (target !== 'node' && target !== 'web') {
  throw new Error(`Invalid webpack target: ${target}`);
}
const useExternals = process.env.SILK_BUILDJS_EXTERNALS === 'true';

// Walk up cwd looking for a project-level webpack.config.js
const projectWebpack = lookup(
  'webpack.config.js',
  {cwd: path.resolve(path.dirname(localWebpack), '..')}
);

let babelCache;
if (!process.env.BABEL_CACHE || process.env.BABEL_CACHE === '1') {
  babelCache = path.join(destination, '../.babelcache');
  mkdirp.sync(babelCache);
} else {
  console.log('~ babel cache has been disabled ~');
  babelCache = false;
}

let main = pkg.main || './index.js';
if (!path.extname(main)) {
  main += '.js';
}

if (main.indexOf('./') !== 0) {
  main = `./${main}`;
}

const absMain = path.resolve(modulePath, main);
let mainDir;

try {
  mainDir = fs.realpathSync(path.dirname(absMain));
} catch (err) {
  mainDir = path.dirname(absMain);
}

// XXX: Would be nicer to abort this in the bash script rather than after we
// have booted up node here...
if (
  main.indexOf('build/Release') === 0 ||
  main.indexOf('./build/Release') === 0 ||
  /\.node$/.test(main)
) {
  console.log(`Module contains no JS main skipping webpack ...`);
  process.exit(0);
}

if (!main) {
  throw new Error(`package.json must have main in ${process.cwd()}`);
}

const externals = {
  web: [
    'silk-alog',
  ],
  node: [
    // TODO: auto generate these ...
    'ab-neuter',
    'bleno',
    'lame',
    'mic',
    'noble',
    'node-hid',
    'node-wav',
    'node-nnpack',
    'opencv',
    'segfault-handler',
    'silk-alog',
    'silk-audioplayer',
    'silk-battery',
    'silk-bledroid',
    'silk-camera',
    'silk-capture',
    'silk-core-version',
    'silk-gc1',
    'silk-input',
    'silk-lights',
    'silk-log',
    'silk-movie',
    'silk-ntp',
    'silk-properties',
    'silk-sensors',
    'silk-speaker',
    'silk-sysutils',
    'silk-vibrator',
    'silk-volume',
    'silk-wifi',
    'sodium',
    (context, request, callback) => {
      if (target !== 'web' && resolve.isCore(request)) {
        callback(null, true);
        return;
      }

      // For extra fun node will allow resolving .main without a ./ this behavior
      // makes .main look nicer but is completely different than how requiring
      // without a specific path is handled elsewhere... To ensure we don't
      // accidentally resolve a node module to a local file we handle this case
      // very specifically.
      if (context === modulePath && pkg.main === request) {
        const resolvedPath = path.resolve(context, request);
        if (!fs.existsSync(resolvedPath)) {
          callback(new Error(`${modulePath} has a .main which is missing ...`));
          return;
        }
      }

      // Handle path rewriting for native modules
      if (
        /\.node$/.test(request) ||
        request.indexOf('build/Release') !== -1
      ) {
        if (path.isAbsolute(request)) {
          callback(null, true);
          return;
        }

        const absExternalPath = path.resolve(context, request);
        let relativeExternalPath = path.relative(mainDir, absExternalPath);
        if (relativeExternalPath.indexOf('.') !== 0) {
          relativeExternalPath = `./${relativeExternalPath}`;
        }
        callback(null, relativeExternalPath);
        return;
      }

      resolve(request, {
        basedir: context,
        package: pkg,
        extensions: ['.js', '.json'],
      }, (err, resolvedPath) => {
        if (err) {
          console.log(`\nMissing module imported from ${context} (${request})`);
          if (target === 'web') {
            callback(null, `var undefined`);
          } else {
            callback(null, true);
          }
          return;
        }
        callback(null, false);
      });
    },
  ],
};

const entry = {};
entry[main] = main;

const config = {
  context: modulePath,
  externals: useExternals ? externals[target] : [],
  target,
  node: {
    __dirname: false,
    __filename: false,
  },
  devtool: 'source-map',
  entry,
  output: {
    sourcePrefix: '',
    path: path.join(destination),
    libraryTarget: target === 'web' ? 'var' : 'commonjs2',
    filename: `[name]`,
  },
  resolve: {
    extensions: ['', '.js', '.json'],
    // Common "gotcha" modules ...
    alias: {
      'any-promise': require.resolve('./shims/any-promise.js'),
      'json3': require.resolve('./shims/json3.js'),
    },
  },
  babel: {
    cacheDirectory: babelCache,
    presets: target === 'web' ?
      [
        require('babel-preset-silk-node6'),
        require('babel-preset-react'),
      ]
      :
      [
        require('babel-preset-silk-node6'),
      ],
  },
  module: {
    loaders: [
      {test: /\.json$/, loader: require.resolve('json-loader')},
      {
        test: /\.js$/,
        loader: require.resolve('babel-loader'),
        include: (filename) => {
          if (target === 'web') {
            return require('silk-babeldeps')(filename);
          }
          return true;
        },
        query: {
          babelrc: false,
        },
      },
    ],
  },
  plugins: [webpackFailPlugin],
};

if (ugly) {
  config.plugins.push(new webpack.optimize.UglifyJsPlugin());
}

function applyWebpackConfig(webpackConfigFile) {
  if (fs.existsSync(webpackConfigFile)) {
    console.log(`${webpackConfigFile} found agumenting buildjs ...`);
    const localConfig = require(webpackConfigFile);

    if (typeof localConfig === 'function') {
      localConfig(pkg, target, config);
      return;
    }

    const rules = Object.assign({}, localConfig);
    if (rules.externals && Array.isArray(rules.externals)) {
      // Order is important here the rules should be ordered such that the
      // webpack.config comes from the module first and our global rules second.
      config.externals = rules.externals.concat(config.externals);
      delete rules.externals;
    }
    // We let individual webpack.config.js files define a top-level
    // `loaders` field that will get merged into `modules.loaders`.
    if (rules.loaders && Array.isArray(rules.loaders)) {
      config.module.loaders = rules.loaders.concat(config.module.loaders);
      delete rules.loaders;
    }
    if (rules.plugins && Array.isArray(rules.plugins)) {
      config.plugins = rules.plugins.concat(config.plugins);
      delete rules.plugins;
    }
    Object.assign(config, rules);
  }
}
[projectWebpack, localWebpack].map(applyWebpackConfig);

module.exports = config;
<commit_msg>Add option to pass custom webpack config on the command line<commit_after>// @noflow
'use strict';

const path = require('path');
const fs = require('fs');
const lookup = require('look-up');
const webpack = require('webpack');
const webpackFailPlugin = require('webpack-fail-plugin');

const findPackage = require('./src/find_package.js');

const resolve = require('resolve');
const mkdirp = require('mkdirp');

// We must place our files in a special folder for integration /w the android
// build system.
const destination = process.env.SILK_BUILDJS_DEST;
const modulePath = findPackage(process.env.SILK_BUILDJS_SOURCE);
const pkg = require(path.join(modulePath, 'package.json'));
const localWebpack = path.join(modulePath, 'webpack.config.js');
const ugly = process.env.SILK_BUILDJS_UGLY === 'true';
const target = process.env.SILK_BUILDJS_TARGET;
if (target !== 'node' && target !== 'web') {
  throw new Error(`Invalid webpack target: ${target}`);
}
const useExternals = process.env.SILK_BUILDJS_EXTERNALS === 'true';

let customWebpack;
const customWebpackEnv = process.env.SILK_BUILDJS_CUSTOM_CONFIG;
if (customWebpackEnv) {
  const customWebpackPath =
    path.isAbsolute(customWebpackEnv) ?
      customWebpackEnv :
      path.resolve(process.cwd(), customWebpackEnv);
  fs.accessSync(customWebpackPath, fs.constants.R_OK);
  customWebpack = customWebpackPath;
}

// Walk up cwd looking for a project-level webpack.config.js
const projectWebpack = lookup(
  'webpack.config.js',
  {cwd: path.resolve(path.dirname(localWebpack), '..')}
);

let babelCache;
if (!process.env.BABEL_CACHE || process.env.BABEL_CACHE === '1') {
  babelCache = path.join(destination, '../.babelcache');
  mkdirp.sync(babelCache);
} else {
  console.log('~ babel cache has been disabled ~');
  babelCache = false;
}

let main = pkg.main || './index.js';
if (!path.extname(main)) {
  main += '.js';
}

if (main.indexOf('./') !== 0) {
  main = `./${main}`;
}

const absMain = path.resolve(modulePath, main);
let mainDir;

try {
  mainDir = fs.realpathSync(path.dirname(absMain));
} catch (err) {
  mainDir = path.dirname(absMain);
}

// XXX: Would be nicer to abort this in the bash script rather than after we
// have booted up node here...
if (
  main.indexOf('build/Release') === 0 ||
  main.indexOf('./build/Release') === 0 ||
  /\.node$/.test(main)
) {
  console.log(`Module contains no JS main skipping webpack ...`);
  process.exit(0);
}

if (!main) {
  throw new Error(`package.json must have main in ${process.cwd()}`);
}

const externals = {
  web: [
    'silk-alog',
  ],
  node: [
    // TODO: auto generate these ...
    'ab-neuter',
    'bleno',
    'lame',
    'mic',
    'noble',
    'node-hid',
    'node-wav',
    'node-nnpack',
    'opencv',
    'segfault-handler',
    'silk-alog',
    'silk-audioplayer',
    'silk-battery',
    'silk-bledroid',
    'silk-camera',
    'silk-capture',
    'silk-core-version',
    'silk-gc1',
    'silk-input',
    'silk-lights',
    'silk-log',
    'silk-movie',
    'silk-ntp',
    'silk-properties',
    'silk-sensors',
    'silk-speaker',
    'silk-sysutils',
    'silk-vibrator',
    'silk-volume',
    'silk-wifi',
    'sodium',
    (context, request, callback) => {
      if (target !== 'web' && resolve.isCore(request)) {
        callback(null, true);
        return;
      }

      // For extra fun node will allow resolving .main without a ./ this behavior
      // makes .main look nicer but is completely different than how requiring
      // without a specific path is handled elsewhere... To ensure we don't
      // accidentally resolve a node module to a local file we handle this case
      // very specifically.
      if (context === modulePath && pkg.main === request) {
        const resolvedPath = path.resolve(context, request);
        if (!fs.existsSync(resolvedPath)) {
          callback(new Error(`${modulePath} has a .main which is missing ...`));
          return;
        }
      }

      // Handle path rewriting for native modules
      if (
        /\.node$/.test(request) ||
        request.indexOf('build/Release') !== -1
      ) {
        if (path.isAbsolute(request)) {
          callback(null, true);
          return;
        }

        const absExternalPath = path.resolve(context, request);
        let relativeExternalPath = path.relative(mainDir, absExternalPath);
        if (relativeExternalPath.indexOf('.') !== 0) {
          relativeExternalPath = `./${relativeExternalPath}`;
        }
        callback(null, relativeExternalPath);
        return;
      }

      resolve(request, {
        basedir: context,
        package: pkg,
        extensions: ['.js', '.json'],
      }, (err, resolvedPath) => {
        if (err) {
          console.log(`\nMissing module imported from ${context} (${request})`);
          if (target === 'web') {
            callback(null, `var undefined`);
          } else {
            callback(null, true);
          }
          return;
        }
        callback(null, false);
      });
    },
  ],
};

const entry = {};
entry[main] = main;

const config = {
  context: modulePath,
  externals: useExternals ? externals[target] : [],
  target,
  node: {
    __dirname: false,
    __filename: false,
  },
  devtool: 'source-map',
  entry,
  output: {
    sourcePrefix: '',
    path: path.join(destination),
    libraryTarget: target === 'web' ? 'var' : 'commonjs2',
    filename: `[name]`,
  },
  resolve: {
    extensions: ['', '.js', '.json'],
    // Common "gotcha" modules ...
    alias: {
      'any-promise': require.resolve('./shims/any-promise.js'),
      'json3': require.resolve('./shims/json3.js'),
    },
  },
  babel: {
    cacheDirectory: babelCache,
    presets: target === 'web' ?
      [
        require('babel-preset-silk-node6'),
        require('babel-preset-react'),
      ]
      :
      [
        require('babel-preset-silk-node6'),
      ],
  },
  module: {
    loaders: [
      {test: /\.json$/, loader: require.resolve('json-loader')},
      {
        test: /\.js$/,
        loader: require.resolve('babel-loader'),
        include: (filename) => {
          if (target === 'web') {
            return require('silk-babeldeps')(filename);
          }
          return true;
        },
        query: {
          babelrc: false,
        },
      },
    ],
  },
  plugins: [webpackFailPlugin],
};

if (ugly) {
  config.plugins.push(new webpack.optimize.UglifyJsPlugin());
}

function applyWebpackConfig(webpackConfigFile) {
  if (fs.existsSync(webpackConfigFile)) {
    console.log(`${webpackConfigFile} found agumenting buildjs ...`);
    const localConfig = require(webpackConfigFile);

    if (typeof localConfig === 'function') {
      localConfig(pkg, target, config);
      return;
    }

    const rules = Object.assign({}, localConfig);
    if (rules.externals && Array.isArray(rules.externals)) {
      // Order is important here the rules should be ordered such that the
      // webpack.config comes from the module first and our global rules second.
      config.externals = rules.externals.concat(config.externals);
      delete rules.externals;
    }
    // We let individual webpack.config.js files define a top-level
    // `loaders` field that will get merged into `modules.loaders`.
    if (rules.loaders && Array.isArray(rules.loaders)) {
      config.module.loaders = rules.loaders.concat(config.module.loaders);
      delete rules.loaders;
    }
    if (rules.plugins && Array.isArray(rules.plugins)) {
      config.plugins = rules.plugins.concat(config.plugins);
      delete rules.plugins;
    }
    Object.assign(config, rules);
  }
}
const configs = [projectWebpack, localWebpack];
if (customWebpack) {
  configs.push(customWebpack);
}
configs.map(applyWebpackConfig);

module.exports = config;
<|endoftext|>