<commit_before>/**
 * import the http observer module for listening to calls to privly servers
 */
Components.utils.import("resource://privly/observers.jsm");

/**
 * import privly constants
 */
Components.utils.import("resource://privly/constants.jsm");

/**
 * @namespace
 * Handles interaction with the host page, including injecting the content
 * script, privly.js.
 */
var privlyExtension = {

  /**
   * Interface object to the extension preferences.
   */
  preferences: Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefService)
                         .getBranch("extensions.privly."),

  /**
   * Installs toolbar button in the navigation bar
   */
  installToolbarButton: function () {

    "use strict";

    var currentset = document.getElementById("nav-bar").currentSet;
    currentset = currentset + ",privly-tlbr-btn";
    document.getElementById("nav-bar").setAttribute("currentset", currentset);
    document.getElementById("nav-bar").currentSet = currentset;
    document.persist("nav-bar", "currentset");
    var tlbrbtn = document.getElementById("privly-tlbr-btn");
  },

  /**
   * Installs the toolbar button if it is not installed.
   * This function is called only once immediately after the extension is
   * installed
   */
  checkToolbarButton: function () {

    "use strict";

    var firstRun = "firstRunDone";
    if (!this.preferences.prefHasUserValue(firstRun)) {
      setTimeout(
        function(){
          privlyExtension.installToolbarButton();
        },
        2000);
      this.preferences.setBoolPref(firstRun, true);
    }
  },

  /**
   * Send data anonymously from the right-clicked form element to the content server, then
   * assign the form element to the returned URL.
   */
  postAnonymouslyToPrivly: function () {

    "use strict";

    var target = document.popupNode;

    var value = target.value;
    if (value === undefined) {
      value = target.textContent;
    }
    var contentServerUrl = this.preferences.getCharPref("contentServerUrl");
    if (value === "") {
      alert("Sorry. You can not post empty content to Privly");
    }
    else {
      var data = {"post":{ "content": value,
            "public": true
      }};
      var xmlhttp = new XMLHttpRequest();
      var url = contentServerUrl + "/posts/posts_anonymous.json";
      xmlhttp.open("POST", url, true);
      xmlhttp.setRequestHeader("Content-type", "application/json; charset=UTF-8");
      xmlhttp.setRequestHeader('Accept', 'application/json');
      xmlhttp.onreadystatechange = function(){
        // process the server response
        if(xmlhttp.readyState === 4 ){
          if(xmlhttp.status === 200 || xmlhttp.status === 201){
            target.value = xmlhttp.getResponseHeader("X-Privly-Url");
            target.textContent = xmlhttp.getResponseHeader("X-Privly-Url");
          }
        }
      };
      xmlhttp.send(JSON.stringify(data));
    }
  },

  /**
   * Variable used during a posting transaction to save where the
   * resulting URL will be pasted to.
   */
  currentTargetNode: undefined,

  /**
   * Variable used furing posting transaction to save which tab
   * contains the currentTargetNode.
   */
   tabReceivingPost: undefined,

  /**
   * Begins encrypted posting dialog.
   * This function opens an iframe from the current content server
   * for the user to type their content into.
   *
   * @see privlyExtension.handleEncryptedUrlEvent
   *
   * @see privlyExtension.cancelEncryptedPost
   */
  postEncryptedToPrivly: function () {

    "use strict";

    //Remember which tab the post is going to
    privlyExtension.tabReceivingPost = gBrowser.selectedTab;

    //Open the form from the selected content server
    var contentServerUrl = this.preferences.getCharPref("contentServerUrl");
    document.getElementById('encryption-iframe').setAttribute("src", contentServerUrl + "/zero_bin/");

    //display the form elements in the bottom of the browser chrome
    document.getElementById('encryption-splitter').hidden = false;
    document.getElementById('encryption-iframe-vbox').hidden = false;
    document.getElementById('encryption-cancel-button').hidden = false;

    //Save the destination for the encrypted URL
    privlyExtension.currentTargetNode = document.popupNode;
  },

  /**
   * Receive URL to encrypted post for posting to selected form element.
   * This function also closes the posting iframe and chnages its source
   * so it no longer contains the content.
   *
   * @param {event} evt An event dispatched from the encryption application
   * containing a string variable, "privlyUrl", bound to the url intended to
   * be pasted to the relevent form element.
   */
  handleEncryptedUrlEvent: function(evt) {

    //Switch to the tab initiating the post
    gBrowser.selectedTab = privlyExtension.tabReceivingPost;

    // Focus the DOM Node, then fire keydown and keypress events
    privlyExtension.currentTargetNode.focus();
    var keydownEvent = document.createEvent("KeyboardEvent");
    keydownEvent.initKeyEvent('keydown', true, true, window, 0,
                            false, 0, false, 0, 0);
    privlyExtension.currentTargetNode.dispatchEvent(keydownEvent);
    var keypressEvent = document.createEvent("KeyboardEvent");
    keypressEvent.initKeyEvent('keypress', true, true, window, 0,
                            false, 0, false, 0, 0);
    privlyExtension.currentTargetNode.dispatchEvent(keypressEvent);

    // Some sites need time to execute form initialization
    // callbacks following focus and keydown events.
    // One example includes Facebook.com's wall update
    // form and message page.
    setTimeout(function(){

      privlyExtension.currentTargetNode.value = evt.target.getAttribute("privlyUrl");
      privlyExtension.currentTargetNode.textContent = evt.target.getAttribute("privlyUrl");

      var event = document.createEvent("KeyboardEvent");
      event.initKeyEvent('keyup', true, true, window,
                              0, false, 0, false, 0, 0);
      privlyExtension.currentTargetNode.dispatchEvent(event);

      // Hide the posting window
      document.getElementById('encryption-splitter').hidden = true;
      document.getElementById('encryption-iframe-vbox').hidden = true;
      document.getElementById('encryption-cancel-button').hidden = true;
      document.getElementById('encryption-iframe').setAttribute("src", "");
      privlyExtension.currentTargetNode = undefined;
      privlyExtension.tabReceivingPost = undefined;
    },500);
  },

  /**
   * Cancel the encrypted post dialog after the form frame popped up. This
   * should only be called after postEncryptedToPrivly is called.
   */
  cancelEncryptedPost: function() {
    privlyExtension.tabReceivingPost = undefined;
    document.getElementById('encryption-splitter').hidden = true;
    document.getElementById('encryption-iframe-vbox').hidden = true;
    document.getElementById('encryption-cancel-button').hidden = true;
    document.getElementById('encryption-iframe').setAttribute("src", "");
    privlyExtension.currentTargetNode = undefined;
  },

  /**
   * Send data from the right-clicked form element to the content server, then
   * assign the form element to the returned URL.
   *
   * @param {string} privacySetting Indicates the privacy level of the post.
   * Accepted values are 'public', and anything else. If the extension is set
   * to "allPostsArePublic", then this parameter is ignored.
   * If "allPostsArePublic" is not true, and privacySetting is anything other
   * than public, the post is made as private.
   */
  postToPrivly: function (privacySetting) {

    "use strict";

    var target = document.popupNode;
    var value = target.value;
    var allPostsPublic = this.preferences.getBoolPref("allPostsPublic");
    var contentServerUrl = this.preferences.getCharPref("contentServerUrl");
    // the post can be either public or private (shared only with specific users)
    var postPrivacySetting = allPostsPublic || (privacySetting === 'public');
    var authToken = this.preferences.getCharPref(privlyConstants.Strings.authToken);
    if (value === "") {
      alert("Sorry. You can not post empty content to Privly");
    }
    else{
      var data = {auth_token: authToken,
        "post":{ "content": value,
            "public": postPrivacySetting
      }};
      var xmlhttp = new XMLHttpRequest();
      var url = contentServerUrl + "/posts.json";
      xmlhttp.open("POST", url, true);
      xmlhttp.setRequestHeader("Content-type", "application/json; charset=UTF-8");
      xmlhttp.setRequestHeader('Accept', 'application/json');
      xmlhttp.onreadystatechange = function(){
        // process the server response
        if ( xmlhttp.readyState === 4 ) {
          if ( xmlhttp.status === 200 || xmlhttp.status === 201 ) {
            target.value = xmlhttp.getResponseHeader("X-Privly-Url");
            target.textContent = xmlhttp.getResponseHeader("X-Privly-Url");
          }
        }
      };
      xmlhttp.send(JSON.stringify(data));
    }
  },

  /**
   * Determines which menu options are shown in the right-click menu.
   *
   * @param {event} evt A right click event.
   *
   */
  checkContextForPrivly: function (evt) {

    "use strict";

    var loginToPrivlyMenuItem = document.getElementById('loginToPrivlyMenuItem');
    var logoutFromPrivlyMenuItem = document.getElementById('logoutFromPrivlyMenuItem');
    var publicPostToPrivlyMenuItem = document.getElementById('publicPostToPrivlyMenuItem');
    var encryptedPostToPrivlyMenuItem = document.getElementById('encryptedPostToPrivlyMenuItem');

    loginToPrivlyMenuItem.hidden = true;
    logoutFromPrivlyMenuItem.hidden = true;
    publicPostToPrivlyMenuItem.hidden = true;
    encryptedPostToPrivlyMenuItem.hidden = true;

    var disablePosts = this.preferences.getBoolPref("disablePosts");
    var authToken = this.preferences.prefHasUserValue(privlyConstants.
          Strings.authToken) ? this.preferences.getCharPref(
          privlyConstants.Strings.authToken) : "";
    var loggedIn =  (authToken!== "");

    var postable = false;
    if (!disablePosts && evt.target.nodeName !== null) {
      if (evt.target.nodeName.toLowerCase() === 'input' ||
        evt.target.nodeName.toLowerCase() === 'textarea') {
          postable = true;
      }
      else if(evt.target.nodeName.toLowerCase() === 'div') {
        if (evt.target.getAttribute("contenteditable") === 'true') {
          postable = true;
        }
      }
    }

    if (postable) {
      encryptedPostToPrivlyMenuItem.hidden = false;
      publicPostToPrivlyMenuItem.hidden = false;
    }

    if (loggedIn) {
      logoutFromPrivlyMenuItem.hidden = false;
    } else {
      loginToPrivlyMenuItem.hidden = false;
    }
  },

  /**
   * Toggle the extension mode between active and passive modes.
   */
  toggleExtensionMode: function () {

    "use strict";

    var extensionMode = this.preferences.getIntPref("extensionMode");
    //when the extension is in active mode and user clicks the toolbar
    //button toggle to passive mode
    if (extensionMode === privlyConstants.extensionModeEnum.ACTIVE) {
      extensionMode = privlyConstants.extensionModeEnum.CLICKTHROUGH;
    }
    //when the extension is in either click through or passive mode and user
    //clicks the toolbar button toggle to active mode
    else if (extensionMode === privlyConstants.extensionModeEnum.PASSIVE ||
              extensionMode === privlyConstants.extensionModeEnum.CLICKTHROUGH) {
      extensionMode = privlyConstants.extensionModeEnum.ACTIVE;
    }
    this.updateExtensionMode(extensionMode);
  },

  /**
   * update the toolbar button's image and tooltip based on the current
   * extension mode.
   */
  updateToolbarButtonIcon: function () {

    "use strict";

    var privlyToolbarButton = document.getElementById('privly-tlbr-btn');
    var extensionMode = this.preferences.getIntPref("extensionMode");
    if (privlyToolbarButton) {
      if (extensionMode === privlyConstants.extensionModeEnum.ACTIVE) {
        privlyToolbarButton.style.listStyleImage = "url('chrome://privly/skin/logo_16.png')";
        privlyToolbarButton.tooltipText = "Privly is in active mode";
      }
      else if (extensionMode === privlyConstants.extensionModeEnum.PASSIVE) {
        privlyToolbarButton.style.listStyleImage = "url('chrome://privly/skin/logo_16_dis.png')";
        privlyToolbarButton.tooltipText = "Privly is in passive mode";
      }
      else if (extensionMode === privlyConstants.extensionModeEnum.CLICKTHROUGH) {
        privlyToolbarButton.style.listStyleImage = "url('chrome://privly/skin/logo_16_dis.png')";
        privlyToolbarButton.tooltipText = "Privly is in require-clickthrough mode";
      }
    }
  },

  /**
   * Inserts an html element - 'privModeElement' with the current mode
   * of operation
   *
   * @param {document} doc The HTML document to insert the mode element.
   *
   */
  insertPrivModeElement: function (doc) {

    "use strict";

    var extensionMode = this.preferences.getIntPref("extensionMode");

    var elements = doc.getElementsByTagName("privModeElement");
    if (elements !== undefined && elements !== null && elements.length !== 0) {
      elements[0].setAttribute("mode", extensionMode);

      //Trigger a mutation event, which will make privly.js run
      var modeChange = doc.createElement("modeChange");
      elements[0].appendChild(modeChange);
    }
    else {
      var element = doc.createElement("privModeElement");
      element.setAttribute("mode", extensionMode);
      doc.documentElement.appendChild(element);
    }
  },

  /**
    * Inserts or updates the html element, 'privModeElement' with mode attribute
    * on the host page and all iframes
    */
   updatePrivModeElement: function () {

     "use strict";

     this.updateToolbarButtonIcon();

     this.insertPrivModeElement(content.document);

     //when the host page is done loading
     content.document.defaultView.addEventListener("load",
       function (e) {

         "use strict";

         //get all iframes on the hostpage.
         var iframes = content.document.getElementsByTagName('iframe');
         if (iframes) {
           //loop through each iframe in the host page
           for (var frameIndex in iframes) {
             var currentIframe = iframes[frameIndex];
             if (currentIframe && currentIframe.contentDocument) {
               // if the iframe is done loading, insert the privModeElement into its DOM
               // else, insert the privModeElement into the iframe's DOM once it is loaded
               if (currentIframe.contentDocument.readyState === 'complete') {
                 privlyExtension.insertPrivModeElement(currentIframe.contentDocument);
               } else {
                 //when the host page is done loading
                 currentIframe.contentDocument.defaultView.addEventListener("load",
                   function (e) {
                      privlyExtension.insertPrivModeElement(currentIframe.contentDocument);
                   },
                   false);
               }
             }
           }
         }
       },
       false);
   },

  /**
   * Change the mode of operation for the extension.
   * @param {int} extensionMode The integer identifier of the extension mode
   */
  updateExtensionMode: function (extensionMode) {

    "use strict";

    this.preferences.setIntPref("extensionMode", extensionMode);
    this.updatePrivModeElement();
  }
};

/**
 * register observers for http requests and responses. Handles privly headers
 */
privlyObservers.httpRequestObserver.register();
//privlyObservers.httpResponseObserver.register();

//change the displayed menus on right clicks
window.addEventListener("contextmenu",
  function (e) {
    "use strict";
    privlyExtension.checkContextForPrivly(e);
  },
  false);

/*
 * user could change the mode from the preferences menu in the add-on page.
 * So, update toolbar button and dispatch an event to alert privly.js about
 * the mode change whenever tab is switched
 */
gBrowser.addEventListener("select",
  function (event) {
    "use strict";
    privlyExtension.updatePrivModeElement();
  },
  true);

gBrowser.addEventListener("load",
  function (event) {

    "use strict";

    //load privly.js to all the doms on the host page including iframes
    var doc = event.originalTarget;
    var wnd = doc.defaultView;
    var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                      .getService(Components.interfaces.mozIJSSubScriptLoader);
    if (doc.nodeName === '#document') {
      privlyExtension.insertPrivModeElement(doc);
      loader.loadSubScript("chrome://privly/content/privly.js", wnd);
    }

    if ((doc.nodeName === '#document') &&
        (wnd.location.href === gBrowser.currentURI.spec)) {
      setTimeout(
        function(){
          privlyExtension.checkToolbarButton();
        },
        3000);
      privlyExtension.updatePrivModeElement();
    }
  },
  true);

/**
 * Watch for encrypted URLs sent by the encryption iframe.
 */
window.addEventListener("load", function load(event){
    document.getElementById('encryption-iframe')
      .addEventListener("PrivlyUrlEvent",
        function(e) { privlyExtension.handleEncryptedUrlEvent(e); }, false, true);
  },false);
<commit_msg>changed context menu to reflect the fact that people need to be logged in<commit_after>/**
 * import the http observer module for listening to calls to privly servers
 */
Components.utils.import("resource://privly/observers.jsm");

/**
 * import privly constants
 */
Components.utils.import("resource://privly/constants.jsm");

/**
 * @namespace
 * Handles interaction with the host page, including injecting the content
 * script, privly.js.
 */
var privlyExtension = {

  /**
   * Interface object to the extension preferences.
   */
  preferences: Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefService)
                         .getBranch("extensions.privly."),

  /**
   * Installs toolbar button in the navigation bar
   */
  installToolbarButton: function () {

    "use strict";

    var currentset = document.getElementById("nav-bar").currentSet;
    currentset = currentset + ",privly-tlbr-btn";
    document.getElementById("nav-bar").setAttribute("currentset", currentset);
    document.getElementById("nav-bar").currentSet = currentset;
    document.persist("nav-bar", "currentset");
    var tlbrbtn = document.getElementById("privly-tlbr-btn");
  },

  /**
   * Installs the toolbar button if it is not installed.
   * This function is called only once immediately after the extension is
   * installed
   */
  checkToolbarButton: function () {

    "use strict";

    var firstRun = "firstRunDone";
    if (!this.preferences.prefHasUserValue(firstRun)) {
      setTimeout(
        function(){
          privlyExtension.installToolbarButton();
        },
        2000);
      this.preferences.setBoolPref(firstRun, true);
    }
  },

  /**
   * Send data anonymously from the right-clicked form element to the content server, then
   * assign the form element to the returned URL.
   */
  postAnonymouslyToPrivly: function () {

    "use strict";

    var target = document.popupNode;

    var value = target.value;
    if (value === undefined) {
      value = target.textContent;
    }
    var contentServerUrl = this.preferences.getCharPref("contentServerUrl");
    if (value === "") {
      alert("Sorry. You can not post empty content to Privly");
    }
    else {
      var data = {"post":{ "content": value,
            "public": true
      }};
      var xmlhttp = new XMLHttpRequest();
      var url = contentServerUrl + "/posts/posts_anonymous.json";
      xmlhttp.open("POST", url, true);
      xmlhttp.setRequestHeader("Content-type", "application/json; charset=UTF-8");
      xmlhttp.setRequestHeader('Accept', 'application/json');
      xmlhttp.onreadystatechange = function(){
        // process the server response
        if(xmlhttp.readyState === 4 ){
          if(xmlhttp.status === 200 || xmlhttp.status === 201){
            target.value = xmlhttp.getResponseHeader("X-Privly-Url");
            target.textContent = xmlhttp.getResponseHeader("X-Privly-Url");
          }
        }
      };
      xmlhttp.send(JSON.stringify(data));
    }
  },

  /**
   * Variable used during a posting transaction to save where the
   * resulting URL will be pasted to.
   */
  currentTargetNode: undefined,

  /**
   * Variable used furing posting transaction to save which tab
   * contains the currentTargetNode.
   */
   tabReceivingPost: undefined,

  /**
   * Begins encrypted posting dialog.
   * This function opens an iframe from the current content server
   * for the user to type their content into.
   *
   * @see privlyExtension.handleEncryptedUrlEvent
   *
   * @see privlyExtension.cancelEncryptedPost
   */
  postEncryptedToPrivly: function () {

    "use strict";

    //Remember which tab the post is going to
    privlyExtension.tabReceivingPost = gBrowser.selectedTab;

    //Open the form from the selected content server
    var contentServerUrl = this.preferences.getCharPref("contentServerUrl");
    document.getElementById('encryption-iframe').setAttribute("src", contentServerUrl + "/zero_bin/");

    //display the form elements in the bottom of the browser chrome
    document.getElementById('encryption-splitter').hidden = false;
    document.getElementById('encryption-iframe-vbox').hidden = false;
    document.getElementById('encryption-cancel-button').hidden = false;

    //Save the destination for the encrypted URL
    privlyExtension.currentTargetNode = document.popupNode;
  },

  /**
   * Receive URL to encrypted post for posting to selected form element.
   * This function also closes the posting iframe and chnages its source
   * so it no longer contains the content.
   *
   * @param {event} evt An event dispatched from the encryption application
   * containing a string variable, "privlyUrl", bound to the url intended to
   * be pasted to the relevent form element.
   */
  handleEncryptedUrlEvent: function(evt) {

    //Switch to the tab initiating the post
    gBrowser.selectedTab = privlyExtension.tabReceivingPost;

    // Focus the DOM Node, then fire keydown and keypress events
    privlyExtension.currentTargetNode.focus();
    var keydownEvent = document.createEvent("KeyboardEvent");
    keydownEvent.initKeyEvent('keydown', true, true, window, 0,
                            false, 0, false, 0, 0);
    privlyExtension.currentTargetNode.dispatchEvent(keydownEvent);
    var keypressEvent = document.createEvent("KeyboardEvent");
    keypressEvent.initKeyEvent('keypress', true, true, window, 0,
                            false, 0, false, 0, 0);
    privlyExtension.currentTargetNode.dispatchEvent(keypressEvent);

    // Some sites need time to execute form initialization
    // callbacks following focus and keydown events.
    // One example includes Facebook.com's wall update
    // form and message page.
    setTimeout(function(){

      privlyExtension.currentTargetNode.value = evt.target.getAttribute("privlyUrl");
      privlyExtension.currentTargetNode.textContent = evt.target.getAttribute("privlyUrl");

      var event = document.createEvent("KeyboardEvent");
      event.initKeyEvent('keyup', true, true, window,
                              0, false, 0, false, 0, 0);
      privlyExtension.currentTargetNode.dispatchEvent(event);

      // Hide the posting window
      document.getElementById('encryption-splitter').hidden = true;
      document.getElementById('encryption-iframe-vbox').hidden = true;
      document.getElementById('encryption-cancel-button').hidden = true;
      document.getElementById('encryption-iframe').setAttribute("src", "");
      privlyExtension.currentTargetNode = undefined;
      privlyExtension.tabReceivingPost = undefined;
    },500);
  },

  /**
   * Cancel the encrypted post dialog after the form frame popped up. This
   * should only be called after postEncryptedToPrivly is called.
   */
  cancelEncryptedPost: function() {
    privlyExtension.tabReceivingPost = undefined;
    document.getElementById('encryption-splitter').hidden = true;
    document.getElementById('encryption-iframe-vbox').hidden = true;
    document.getElementById('encryption-cancel-button').hidden = true;
    document.getElementById('encryption-iframe').setAttribute("src", "");
    privlyExtension.currentTargetNode = undefined;
  },

  /**
   * Send data from the right-clicked form element to the content server, then
   * assign the form element to the returned URL.
   *
   * @param {string} privacySetting Indicates the privacy level of the post.
   * Accepted values are 'public', and anything else. If the extension is set
   * to "allPostsArePublic", then this parameter is ignored.
   * If "allPostsArePublic" is not true, and privacySetting is anything other
   * than public, the post is made as private.
   */
  postToPrivly: function (privacySetting) {

    "use strict";

    var target = document.popupNode;
    var value = target.value;
    var allPostsPublic = this.preferences.getBoolPref("allPostsPublic");
    var contentServerUrl = this.preferences.getCharPref("contentServerUrl");
    // the post can be either public or private (shared only with specific users)
    var postPrivacySetting = allPostsPublic || (privacySetting === 'public');
    var authToken = this.preferences.getCharPref(privlyConstants.Strings.authToken);
    if (value === "") {
      alert("Sorry. You can not post empty content to Privly");
    }
    else{
      var data = {auth_token: authToken,
        "post":{ "content": value,
            "public": postPrivacySetting
      }};
      var xmlhttp = new XMLHttpRequest();
      var url = contentServerUrl + "/posts.json";
      xmlhttp.open("POST", url, true);
      xmlhttp.setRequestHeader("Content-type", "application/json; charset=UTF-8");
      xmlhttp.setRequestHeader('Accept', 'application/json');
      xmlhttp.onreadystatechange = function(){
        // process the server response
        if ( xmlhttp.readyState === 4 ) {
          if ( xmlhttp.status === 200 || xmlhttp.status === 201 ) {
            target.value = xmlhttp.getResponseHeader("X-Privly-Url");
            target.textContent = xmlhttp.getResponseHeader("X-Privly-Url");
          }
        }
      };
      xmlhttp.send(JSON.stringify(data));
    }
  },

  /**
   * Determines which menu options are shown in the right-click menu.
   *
   * @param {event} evt A right click event.
   *
   */
  checkContextForPrivly: function (evt) {

    "use strict";

    var loginToPrivlyMenuItem = document.getElementById('loginToPrivlyMenuItem');
    var logoutFromPrivlyMenuItem = document.getElementById('logoutFromPrivlyMenuItem');
    var publicPostToPrivlyMenuItem = document.getElementById('publicPostToPrivlyMenuItem');
    var encryptedPostToPrivlyMenuItem = document.getElementById('encryptedPostToPrivlyMenuItem');

    loginToPrivlyMenuItem.hidden = true;
    logoutFromPrivlyMenuItem.hidden = true;
    publicPostToPrivlyMenuItem.hidden = true;
    encryptedPostToPrivlyMenuItem.hidden = true;

    var disablePosts = this.preferences.getBoolPref("disablePosts");
    var authToken = this.preferences.prefHasUserValue(privlyConstants.
          Strings.authToken) ? this.preferences.getCharPref(
          privlyConstants.Strings.authToken) : "";
    var loggedIn =  (authToken !== "");

    var postable = false;
    if (!disablePosts && evt.target.nodeName !== null) {
      if (evt.target.nodeName.toLowerCase() === 'input' ||
        evt.target.nodeName.toLowerCase() === 'textarea') {
          postable = true;
      }
      else if(evt.target.nodeName.toLowerCase() === 'div') {
        if (evt.target.getAttribute("contenteditable") === 'true') {
          postable = true;
        }
      }
    }

    if (loggedIn && postable) {
      logoutFromPrivlyMenuItem.hidden = false;
      encryptedPostToPrivlyMenuItem.hidden = false;
      publicPostToPrivlyMenuItem.hidden = false;
    } else {
      loginToPrivlyMenuItem.hidden = false;
    }
  },

  /**
   * Toggle the extension mode between active and passive modes.
   */
  toggleExtensionMode: function () {

    "use strict";

    var extensionMode = this.preferences.getIntPref("extensionMode");
    //when the extension is in active mode and user clicks the toolbar
    //button toggle to passive mode
    if (extensionMode === privlyConstants.extensionModeEnum.ACTIVE) {
      extensionMode = privlyConstants.extensionModeEnum.CLICKTHROUGH;
    }
    //when the extension is in either click through or passive mode and user
    //clicks the toolbar button toggle to active mode
    else if (extensionMode === privlyConstants.extensionModeEnum.PASSIVE ||
              extensionMode === privlyConstants.extensionModeEnum.CLICKTHROUGH) {
      extensionMode = privlyConstants.extensionModeEnum.ACTIVE;
    }
    this.updateExtensionMode(extensionMode);
  },

  /**
   * update the toolbar button's image and tooltip based on the current
   * extension mode.
   */
  updateToolbarButtonIcon: function () {

    "use strict";

    var privlyToolbarButton = document.getElementById('privly-tlbr-btn');
    var extensionMode = this.preferences.getIntPref("extensionMode");
    if (privlyToolbarButton) {
      if (extensionMode === privlyConstants.extensionModeEnum.ACTIVE) {
        privlyToolbarButton.style.listStyleImage = "url('chrome://privly/skin/logo_16.png')";
        privlyToolbarButton.tooltipText = "Privly is in active mode";
      }
      else if (extensionMode === privlyConstants.extensionModeEnum.PASSIVE) {
        privlyToolbarButton.style.listStyleImage = "url('chrome://privly/skin/logo_16_dis.png')";
        privlyToolbarButton.tooltipText = "Privly is in passive mode";
      }
      else if (extensionMode === privlyConstants.extensionModeEnum.CLICKTHROUGH) {
        privlyToolbarButton.style.listStyleImage = "url('chrome://privly/skin/logo_16_dis.png')";
        privlyToolbarButton.tooltipText = "Privly is in require-clickthrough mode";
      }
    }
  },

  /**
   * Inserts an html element - 'privModeElement' with the current mode
   * of operation
   *
   * @param {document} doc The HTML document to insert the mode element.
   *
   */
  insertPrivModeElement: function (doc) {

    "use strict";

    var extensionMode = this.preferences.getIntPref("extensionMode");

    var elements = doc.getElementsByTagName("privModeElement");
    if (elements !== undefined && elements !== null && elements.length !== 0) {
      elements[0].setAttribute("mode", extensionMode);

      //Trigger a mutation event, which will make privly.js run
      var modeChange = doc.createElement("modeChange");
      elements[0].appendChild(modeChange);
    }
    else {
      var element = doc.createElement("privModeElement");
      element.setAttribute("mode", extensionMode);
      doc.documentElement.appendChild(element);
    }
  },

  /**
    * Inserts or updates the html element, 'privModeElement' with mode attribute
    * on the host page and all iframes
    */
   updatePrivModeElement: function () {

     "use strict";

     this.updateToolbarButtonIcon();

     this.insertPrivModeElement(content.document);

     //when the host page is done loading
     content.document.defaultView.addEventListener("load",
       function (e) {

         "use strict";

         //get all iframes on the hostpage.
         var iframes = content.document.getElementsByTagName('iframe');
         if (iframes) {
           //loop through each iframe in the host page
           for (var frameIndex in iframes) {
             var currentIframe = iframes[frameIndex];
             if (currentIframe && currentIframe.contentDocument) {
               // if the iframe is done loading, insert the privModeElement into its DOM
               // else, insert the privModeElement into the iframe's DOM once it is loaded
               if (currentIframe.contentDocument.readyState === 'complete') {
                 privlyExtension.insertPrivModeElement(currentIframe.contentDocument);
               } else {
                 //when the host page is done loading
                 currentIframe.contentDocument.defaultView.addEventListener("load",
                   function (e) {
                      privlyExtension.insertPrivModeElement(currentIframe.contentDocument);
                   },
                   false);
               }
             }
           }
         }
       },
       false);
   },

  /**
   * Change the mode of operation for the extension.
   * @param {int} extensionMode The integer identifier of the extension mode
   */
  updateExtensionMode: function (extensionMode) {

    "use strict";

    this.preferences.setIntPref("extensionMode", extensionMode);
    this.updatePrivModeElement();
  }
};

/**
 * register observers for http requests and responses. Handles privly headers
 */
privlyObservers.httpRequestObserver.register();
//privlyObservers.httpResponseObserver.register();

//change the displayed menus on right clicks
window.addEventListener("contextmenu",
  function (e) {
    "use strict";
    privlyExtension.checkContextForPrivly(e);
  },
  false);

/*
 * user could change the mode from the preferences menu in the add-on page.
 * So, update toolbar button and dispatch an event to alert privly.js about
 * the mode change whenever tab is switched
 */
gBrowser.addEventListener("select",
  function (event) {
    "use strict";
    privlyExtension.updatePrivModeElement();
  },
  true);

gBrowser.addEventListener("load",
  function (event) {

    "use strict";

    //load privly.js to all the doms on the host page including iframes
    var doc = event.originalTarget;
    var wnd = doc.defaultView;
    var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                      .getService(Components.interfaces.mozIJSSubScriptLoader);
    if (doc.nodeName === '#document') {
      privlyExtension.insertPrivModeElement(doc);
      loader.loadSubScript("chrome://privly/content/privly.js", wnd);
    }

    if ((doc.nodeName === '#document') &&
        (wnd.location.href === gBrowser.currentURI.spec)) {
      setTimeout(
        function(){
          privlyExtension.checkToolbarButton();
        },
        3000);
      privlyExtension.updatePrivModeElement();
    }
  },
  true);

/**
 * Watch for encrypted URLs sent by the encryption iframe.
 */
window.addEventListener("load", function load(event){
    document.getElementById('encryption-iframe')
      .addEventListener("PrivlyUrlEvent",
        function(e) { privlyExtension.handleEncryptedUrlEvent(e); }, false, true);
  },false);
<|endoftext|>


<commit_before>FLOW.CurrentDevicesTabView = Em.View.extend({
	showDeleteDevicesDialogBool: false,
	showAddToGroupDialogBool: false,
	showRemoveFromGroupDialogBool: false,
	showManageDeviceGroupsDialogBool: false,
	newDeviceGroupName:null, // bound to devices-list.handlebars
	changedDeviceGroupName:null,
	selectedDeviceGroup:null, // bound to devices-list.handlebars

	showAddToGroupDialog: function(){
		this.set('selectedDeviceGroup',null);
		this.set('showAddToGroupDialogBool',true);
	},

	showRemoveFromGroupDialog: function(){
		this.set('showRemoveFromGroupDialogBool',true);
	},

	cancelAddToGroup: function(){
		this.set('showAddToGroupDialogBool',false);
	},

	showManageDeviceGroupsDialog: function(){
		this.set('newDeviceGroupName',null);
		this.set('changedDeviceGroupName',null);
		this.set('selectedDeviceGroup',null);
		this.set('showManageDeviceGroupsDialogBool',true);
	},

	cancelManageDeviceGroups: function(){
		this.set('showManageDeviceGroupsDialogBool',false);
	},

	assignDisplayNames:function(){
		var allDevices;
		if ((FLOW.deviceControl.content.get('isLoaded') === true) && (FLOW.deviceGroupControl.content.get('isLoaded') === true)) {
			allDevices = FLOW.store.filter(FLOW.Device,function(data){return true;});
			allDevices.forEach(function(item){
				var deviceId=parseInt(item.get('deviceGroup'),10);
				var deviceGroup = FLOW.store.filter(FLOW.DeviceGroup,function(data){
					if (data.get('keyId') === deviceId) {return true;} else {return false;}
				});
				if (typeof deviceGroup.get('firstObject') !== "undefined"){
					item.set('deviceGroupName',deviceGroup.get('firstObject').get('code'));
				}
			});
		}
    }.observes('FLOW.deviceGroupControl.content.isLoaded','FLOW.deviceControl.content.isLoaded'),

	doAddToGroup: function(){
		if (this.get('selectedDeviceGroup') !== null) {
			var selectedDeviceGroupId=this.selectedDeviceGroup.get('keyId');
			var selectedDeviceGroupName=this.selectedDeviceGroup.get('code');
			var selectedDevices = FLOW.store.filter(FLOW.Device,function(data){
				if (data.get('isSelected') === true) {return true;} else {return false;}
			});
			selectedDevices.forEach(function(item){
				item.set('deviceGroupName',selectedDeviceGroupName);
				item.set('deviceGroup',selectedDeviceGroupId);
			});
		}
		FLOW.store.commit();
		this.set('showAddToGroupDialogBool',false);
	},

	// TODO repopulate list after update
	doRemoveFromGroup: function(){
		var selectedDevices = FLOW.store.filter(FLOW.Device,function(data){
			if (data.get('isSelected') === true) {return true;} else {return false;}
		});
		selectedDevices.forEach(function(item){
			item.set('deviceGroupName',null);
			item.set('deviceGroup',null);
		});

		FLOW.store.commit();
		this.set('showRemoveFromGroupDialogBool',false);
	},

	cancelRemoveFromGroup: function(){
		this.set('showRemoveFromGroupDialogBool',false);
	},

	copyDeviceGroupName:function(){
		if (this.get('selectedDeviceGroup') !== null){
			this.set('changedDeviceGroupName',this.selectedDeviceGroup.get('code'));
		}
	}.observes('this.selectedDeviceGroup'),

	// TODO update device group name in tabel.
	doManageDeviceGroups: function(){
		var allDevices;
		if (this.get('selectedDeviceGroup') !== null) {
			var selectedDeviceGroupId = this.selectedDeviceGroup.get('keyId');

			// this could have been changed in the UI
			var originalSelectedDeviceGroup = FLOW.store.find(FLOW.DeviceGroup,selectedDeviceGroupId);

			if (originalSelectedDeviceGroup.get('code') != this.get('changedDeviceGroupName')) {
				var newName=this.get('changedDeviceGroupName');
				originalSelectedDeviceGroup.set('code',newName);

				allDevices = FLOW.store.filter(FLOW.Device,function(data){return true;});
				allDevices.forEach(function(item){
					if (parseInt(item.get('deviceGroup'),10) == selectedDeviceGroupId){
						item.set('deviceGroupName',newName);
					}
				});
			}
		}

		this.set('selectedDeviceGroup',null);
		this.set('newDeviceGroupName',null);
		this.set('changedDeviceGroupName',null);

		FLOW.store.commit();
		this.set('showManageDeviceGroupsDialogBool',false);
	},

	showDeleteDevicesDialog: function(){
		console.log("show delete devices dialog");
	},

	doDeleteDevices: function(){

	},

	cancelDeleteDevices: function(){

	}
});

FLOW.SavingDeviceGroupView = Ember.View.extend({
	showDGSavingDialogBool:false,

	showDGSavingDialog:function(){
		if (FLOW.DeviceGroupControl.get('allRecordsSaved')){
			this.set('showDGSavingDialogBool', false);
		} else {
			this.set('showDGSavingDialogBool', true);
		}
	}.observes('FLOW.deviceGroupControl.allRecordsSaved')
});<commit_msg>add save new device group<commit_after>FLOW.CurrentDevicesTabView = Em.View.extend({
	showDeleteDevicesDialogBool: false,
	showAddToGroupDialogBool: false,
	showRemoveFromGroupDialogBool: false,
	showManageDeviceGroupsDialogBool: false,
	newDeviceGroupName:null, // bound to devices-list.handlebars
	changedDeviceGroupName:null,
	selectedDeviceGroup:null, // bound to devices-list.handlebars

	showAddToGroupDialog: function(){
		this.set('selectedDeviceGroup',null);
		this.set('showAddToGroupDialogBool',true);
	},

	showRemoveFromGroupDialog: function(){
		this.set('showRemoveFromGroupDialogBool',true);
	},

	cancelAddToGroup: function(){
		this.set('showAddToGroupDialogBool',false);
	},

	showManageDeviceGroupsDialog: function(){
		this.set('newDeviceGroupName',null);
		this.set('changedDeviceGroupName',null);
		this.set('selectedDeviceGroup',null);
		this.set('showManageDeviceGroupsDialogBool',true);
	},

	cancelManageDeviceGroups: function(){
		this.set('showManageDeviceGroupsDialogBool',false);
	},

	assignDisplayNames:function(){
		var allDevices;
		if ((FLOW.deviceControl.content.get('isLoaded') === true) && (FLOW.deviceGroupControl.content.get('isLoaded') === true)) {
			allDevices = FLOW.store.filter(FLOW.Device,function(data){return true;});
			allDevices.forEach(function(item){
				var deviceId=parseInt(item.get('deviceGroup'),10);
				var deviceGroup = FLOW.store.filter(FLOW.DeviceGroup,function(data){
					if (data.get('keyId') === deviceId) {return true;} else {return false;}
				});
				if (typeof deviceGroup.get('firstObject') !== "undefined"){
					item.set('deviceGroupName',deviceGroup.get('firstObject').get('code'));
				}
			});
		}
    }.observes('FLOW.deviceGroupControl.content.isLoaded','FLOW.deviceControl.content.isLoaded'),

	doAddToGroup: function(){
		if (this.get('selectedDeviceGroup') !== null) {
			var selectedDeviceGroupId=this.selectedDeviceGroup.get('keyId');
			var selectedDeviceGroupName=this.selectedDeviceGroup.get('code');
			var selectedDevices = FLOW.store.filter(FLOW.Device,function(data){
				if (data.get('isSelected') === true) {return true;} else {return false;}
			});
			selectedDevices.forEach(function(item){
				item.set('deviceGroupName',selectedDeviceGroupName);
				item.set('deviceGroup',selectedDeviceGroupId);
			});
		}
		FLOW.store.commit();
		this.set('showAddToGroupDialogBool',false);
	},

	// TODO repopulate list after update
	doRemoveFromGroup: function(){
		var selectedDevices = FLOW.store.filter(FLOW.Device,function(data){
			if (data.get('isSelected') === true) {return true;} else {return false;}
		});
		selectedDevices.forEach(function(item){
			item.set('deviceGroupName',null);
			item.set('deviceGroup',null);
		});

		FLOW.store.commit();
		this.set('showRemoveFromGroupDialogBool',false);
	},

	cancelRemoveFromGroup: function(){
		this.set('showRemoveFromGroupDialogBool',false);
	},

	copyDeviceGroupName:function(){
		if (this.get('selectedDeviceGroup') !== null){
			this.set('changedDeviceGroupName',this.selectedDeviceGroup.get('code'));
		}
	}.observes('this.selectedDeviceGroup'),

	// TODO update device group name in tabel.
	doManageDeviceGroups: function(){
		var allDevices, newDeviceGroup;
		if (this.get('selectedDeviceGroup') !== null) {
			var selectedDeviceGroupId = this.selectedDeviceGroup.get('keyId');

			// this could have been changed in the UI
			var originalSelectedDeviceGroup = FLOW.store.find(FLOW.DeviceGroup,selectedDeviceGroupId);

			if (originalSelectedDeviceGroup.get('code') != this.get('changedDeviceGroupName')) {
				var newName=this.get('changedDeviceGroupName');
				originalSelectedDeviceGroup.set('code',newName);

				allDevices = FLOW.store.filter(FLOW.Device,function(data){return true;});
				allDevices.forEach(function(item){
					if (parseInt(item.get('deviceGroup'),10) == selectedDeviceGroupId){
						item.set('deviceGroupName',newName);
					}
				});
			}
		} else if (this.get('newDeviceGroupName') !== null){
			newDeviceGroup = FLOW.store.createRecord(FLOW.DeviceGroup,{
				"code":this.get('newDeviceGroupName')
			});
		}

		this.set('selectedDeviceGroup',null);
		this.set('newDeviceGroupName',null);
		this.set('changedDeviceGroupName',null);

		FLOW.store.commit();
		this.set('showManageDeviceGroupsDialogBool',false);
	},

	showDeleteDevicesDialog: function(){
		console.log("show delete devices dialog");
	},

	doDeleteDevices: function(){

	},

	cancelDeleteDevices: function(){

	}
});

// TODO not used?
FLOW.SavingDeviceGroupView = Ember.View.extend({
	showDGSavingDialogBool:false,

	showDGSavingDialog:function(){
		if (FLOW.DeviceGroupControl.get('allRecordsSaved')){
			this.set('showDGSavingDialogBool', false);
		} else {
			this.set('showDGSavingDialogBool', true);
		}
	}.observes('FLOW.deviceGroupControl.allRecordsSaved')
});<|endoftext|>


<commit_before>// Copyright 2012 Selenium committers
// Copyright 2012 Software Freedom Conservancy
//
// 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.

/**
 * @fileoverview The main user facing module. Exports WebDriver's primary
 * public API and provides convenience assessors to certain sub-modules.
 */

var base = require('./_base');
var builder = require('./builder');
var error = require('./error');

// NOTE: the remainder of this file is nasty and verbose, but the annotations
// are necessary to guide the Closure Compiler's type analysis. Without them,
// we would not be able to extract any meaningful API documentation.

/** @type {function(new: webdriver.ActionSequence)} */
exports.ActionSequence = base.require('webdriver.ActionSequence');

/** @type {function(new: builder.Builder)} */
exports.Builder = builder.Builder;

/** @type {webdriver.By.} */
exports.By = base.require('webdriver.By');

/** @type {function(new: webdriver.Capabilities)} */
exports.Capabilities = base.require('webdriver.Capabilities');

/** @type {function(new: webdriver.Command)} */
exports.Command = base.require('webdriver.Command');

/** @type {function(new: webdriver.EventEmitter)} */
exports.EventEmitter = base.require('webdriver.EventEmitter');

/** @type {function(new: webdriver.Session)} */
exports.Session = base.require('webdriver.Session');

/** @type {function(new: webdriver.WebDriver)} */
exports.WebDriver = base.require('webdriver.WebDriver');

/** @type {function(new: webdriver.WebElement)} */
exports.WebElement = base.require('webdriver.WebElement');

// Export the remainder of our API through getters to keep things cleaner
// when this module is used in a REPL environment.

/** @type {webdriver.Browser.} */
(exports.__defineGetter__('Browser', function() {
  return base.require('webdriver.Browser');
}));

/** @type {webdriver.Button.} */
(exports.__defineGetter__('Button', function() {
  return base.require('webdriver.Button');
}));

/** @type {webdriver.Capability.} */
(exports.__defineGetter__('Capability', function() {
  return base.require('webdriver.Capability');
}));

/** @type {webdriver.CommandName.} */
(exports.__defineGetter__('CommandName', function() {
  return base.require('webdriver.CommandName');
}));

/** @type {webdriver.Key.} */
(exports.__defineGetter__('Key', function() {
  return base.require('webdriver.Key');
}));

/** @type {error.} */
(exports.__defineGetter__('error', function() {
  return error;
}));

/** @type {error.} */
(exports.__defineGetter__('error', function() {
  return error;
}));

/** @type {webdriver.logging.} */
(exports.__defineGetter__('logging', function() {
  return base.exportPublicApi('webdriver.logging');
}));

/** @type {webdriver.promise.} */
(exports.__defineGetter__('promise', function() {
  return base.exportPublicApi('webdriver.promise');
}));

/** @type {webdriver.stacktrace.} */
(exports.__defineGetter__('stacktrace', function() {
  return base.exportPublicApi('webdriver.stacktrace');
}));
<commit_msg>Making webdriver.WebElementPromise public for higher level frameworks to use; e.g. Protractror.<commit_after>// Copyright 2012 Selenium committers
// Copyright 2012 Software Freedom Conservancy
//
// 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.

/**
 * @fileoverview The main user facing module. Exports WebDriver's primary
 * public API and provides convenience assessors to certain sub-modules.
 */

var base = require('./_base');
var builder = require('./builder');
var error = require('./error');

// NOTE: the remainder of this file is nasty and verbose, but the annotations
// are necessary to guide the Closure Compiler's type analysis. Without them,
// we would not be able to extract any meaningful API documentation.

/** @type {function(new: webdriver.ActionSequence)} */
exports.ActionSequence = base.require('webdriver.ActionSequence');

/** @type {function(new: builder.Builder)} */
exports.Builder = builder.Builder;

/** @type {webdriver.By.} */
exports.By = base.require('webdriver.By');

/** @type {function(new: webdriver.Capabilities)} */
exports.Capabilities = base.require('webdriver.Capabilities');

/** @type {function(new: webdriver.Command)} */
exports.Command = base.require('webdriver.Command');

/** @type {function(new: webdriver.EventEmitter)} */
exports.EventEmitter = base.require('webdriver.EventEmitter');

/** @type {function(new: webdriver.Session)} */
exports.Session = base.require('webdriver.Session');

/** @type {function(new: webdriver.WebDriver)} */
exports.WebDriver = base.require('webdriver.WebDriver');

/** @type {function(new: webdriver.WebElement)} */
exports.WebElement = base.require('webdriver.WebElement');

/** @type {function(new: webdriver.WebElementPromise)} */
exports.WebElementPromise = base.require('webdriver.WebElementPromise');

// Export the remainder of our API through getters to keep things cleaner
// when this module is used in a REPL environment.

/** @type {webdriver.Browser.} */
(exports.__defineGetter__('Browser', function() {
  return base.require('webdriver.Browser');
}));

/** @type {webdriver.Button.} */
(exports.__defineGetter__('Button', function() {
  return base.require('webdriver.Button');
}));

/** @type {webdriver.Capability.} */
(exports.__defineGetter__('Capability', function() {
  return base.require('webdriver.Capability');
}));

/** @type {webdriver.CommandName.} */
(exports.__defineGetter__('CommandName', function() {
  return base.require('webdriver.CommandName');
}));

/** @type {webdriver.Key.} */
(exports.__defineGetter__('Key', function() {
  return base.require('webdriver.Key');
}));

/** @type {error.} */
(exports.__defineGetter__('error', function() {
  return error;
}));

/** @type {error.} */
(exports.__defineGetter__('error', function() {
  return error;
}));

/** @type {webdriver.logging.} */
(exports.__defineGetter__('logging', function() {
  return base.exportPublicApi('webdriver.logging');
}));

/** @type {webdriver.promise.} */
(exports.__defineGetter__('promise', function() {
  return base.exportPublicApi('webdriver.promise');
}));

/** @type {webdriver.stacktrace.} */
(exports.__defineGetter__('stacktrace', function() {
  return base.exportPublicApi('webdriver.stacktrace');
}));
<|endoftext|>


<commit_before>import moment from 'moment';

import './campaign.scss';
import templateAdmin from './campaign-admin.tpl.html';
import templateJury from './campaign-jury.tpl.html';
import templateNewRound from './new-round.tpl.html';
import templateEditRound from './edit-round.tpl.html';

const CampaignComponent = {
    bindings: {
        campaign: '<',
        user: '<',
        type: '<'
    },
    controller: function ($filter, $mdDialog, $mdToast, $state, $templateCache,
        $timeout, alertService, dataService, dialogService, userService) {
        let vm = this;
        vm.activateRound = activateRound;
        vm.addRound = addRound;
        vm.cancelCampaignName = cancelCampaignName;
        vm.editCampaignName = editCampaignName;
        vm.editRound = editRound;
        vm.isNameEdited = false;
        vm.isLastRoundCompleted = isLastRoundCompleted;
        vm.isRoundActive = isRoundActive;
        vm.nameEdit = '';
        vm.openRound = openRound;
        vm.pauseRound = pauseRound;
        vm.saveCampaignName = saveCampaignName;
        vm.showRoundMenu = ($mdOpenMenu, ev) => { $mdOpenMenu(ev); };

        const voteMethods = {
            'yesno': {
                label: 'Yes/No',
                value: 'yesno',
                icon: 'thumbs_up_down'
            },
            'rating': {
                label: 'Rating',
                value: 'rating',
                icon: 'star_border'
            }
            /*
            'ranking': {
                label: 'Ranking',
                value: 'ranking',
                icon: 'sort'
            }
            */
        };

        $templateCache.put('campaign-template', isAdmin() ? templateAdmin : templateJury);

        // functions

        function activateRound(round) {
            round.loading = true;
            userService.admin.activateRound(round.id).then((response) => {
                round.loading = false;
                response.error ?
                    alertService.error(response.error) :
                    $state.reload();
            });
        }

        function createRound(round, loading) {
            let round_ = angular.copy(round);
            round_ = angular.extend(round_, {
                jurors: round.jurors.map((element) => element.name),
                deadline_date: $filter('date')(round.deadline_date, 'yyyy-MM-ddTHH:mm:ss', 'UTC')
            });

            if (!round_.name) {
                alertService.error({
                    message: 'Error',
                    detail: 'Name cannot be empty'
                });
                return;
            }
            if (!round_.deadline_date) {
                alertService.error({
                    message: 'Error',
                    detail: 'Deadline date cannot be empty'
                });
                return;
            }
            if (!round_.jurors.length) {
                alertService.error({
                    message: 'Error',
                    detail: 'Jurors must be added'
                });
                return;
            }
            if (!round_.quorum) {
                alertService.error({
                    message: 'Error',
                    detail: 'Quorum value is empty on invalid'
                });
                return;
            }

            loading.window = true;
            userService.admin.addRound(vm.campaign.id, round_).then((response) => {
                if(response.error) {
                    loading.window = false;
                    alertService.error(response.error);
                    return;
                }

                const id = response.data.id;
                userService.admin.populateRound(id, round_.imports).then((response) => {
                    if(response.error) {
                        loading.window = false;
                        alertService.error(response.error);
                        return;
                    }

                    alertService.success('New round added');
                    $mdDialog.hide(true);
                    $state.reload();
                });
            });
        }

        function addRound(event) {
            dialogService.show({
                template: templateNewRound,
                scope: {
                    round: {
                        name: 'Round ' + (vm.campaign.rounds.length + 1),
                        vote_method: 'rating',
                        quorum: 2,
                        jurors: [],
                        config: {show_link: true},
                        imports: {
                            import_method: 'category',
                            category: ''
                        }
                    },
                    createRound: createRound,
                    searchCategory: (name) => dataService.searchCategory(name).then((response) => {
                        return response.data[1].map((element) => element.substring(9));
                    }),
                    voteMethods: voteMethods,
                    today: new Date()
                }
            });
        }

        function cancelCampaignName() {
            vm.isNameEdited = false;
            vm.nameEdit = '';
        }

        function editCampaignName($event) {
            vm.nameEdit = vm.campaign.name;
            vm.isNameEdited = true;
            $timeout(() => {
                let input = angular.element($event.target).parent().parent().find('input')[0];
                input.focus();
            });
        }

        function editRound(round) {
            let round_ = angular.extend(angular.copy(round), {
                deadline_date: new Date(round.deadline_date)
            });

            dialogService.show({
                template: templateEditRound,
                scope: {
                    round: round_,
                    voteMethods: voteMethods,
                    saveEditRound: saveEditRound,
                }
            });
        }

        function isAdmin() {
            return vm.type === 'admin';
        }

        function isLastRoundCompleted() {
            const rounds = vm.campaign.rounds;
            const isCompleted = rounds.length && rounds[rounds.length - 1].status === 'completed';
            return !rounds.length || isCompleted;
        }

        function isRoundActive(round) {
            return round.status === 'active' && round.total_tasks;
        }

        function openRound(round) {
            if (!isRoundActive(round)) {
                return;
            }

            if (round.voteMethod === 'voting') {
                $state.go('main.juror.image');
            } else {
                $state.go(isAdmin() ? 'main.admin.round' : 'main.juror.round', { id: round.id });
            }
        }

        function pauseRound(round) {
            round.loading = true;
            userService.admin.pauseRound(round.id).then((response) => {
                round.loading = false;
                response.error ?
                    alertService.error(response.error) :
                    $state.reload();
            });
        }

        function saveEditRound(round, loading) {
            loading.window = true;
            userService.admin.editRound(round.id, round).then((response) => {
                if(response.error) {
                    loading.window = false;
                    alertService.error(response.error);
                    return;
                }

                alertService.success('Round settings saved');
                $mdDialog.hide(true);
                $state.reload();
            });
        }

        function saveCampaignName() {
            vm.campaign.name = vm.nameEdit;
            vm.isNameEdited = false;

            userService.admin.editCampaign(vm.campaign.id, {
                name: vm.campaign.name
            }).then((response) => {
                response.error ?
                    alertService.error(response.error) :
                    alertService.success('Campaign name changed');
            });
        }
    },
    template: `<ng-include src="'campaign-template'"/>`
};

export default () => {
    angular
        .module('montage')
        .component('montCampaign', CampaignComponent)
        .filter('fromNow', () => (input) => moment.utc(input).fromNow());
};
<commit_msg>frontend: enable new round after cancelled round<commit_after>import moment from 'moment';

import './campaign.scss';
import templateAdmin from './campaign-admin.tpl.html';
import templateJury from './campaign-jury.tpl.html';
import templateNewRound from './new-round.tpl.html';
import templateEditRound from './edit-round.tpl.html';

const CampaignComponent = {
    bindings: {
        campaign: '<',
        user: '<',
        type: '<'
    },
    controller: function ($filter, $mdDialog, $mdToast, $state, $templateCache,
        $timeout, alertService, dataService, dialogService, userService) {
        let vm = this;
        vm.activateRound = activateRound;
        vm.addRound = addRound;
        vm.cancelCampaignName = cancelCampaignName;
        vm.editCampaignName = editCampaignName;
        vm.editRound = editRound;
        vm.isNameEdited = false;
        vm.isLastRoundCompleted = isLastRoundCompleted;
        vm.isRoundActive = isRoundActive;
        vm.nameEdit = '';
        vm.openRound = openRound;
        vm.pauseRound = pauseRound;
        vm.saveCampaignName = saveCampaignName;
        vm.showRoundMenu = ($mdOpenMenu, ev) => { $mdOpenMenu(ev); };

        const voteMethods = {
            'yesno': {
                label: 'Yes/No',
                value: 'yesno',
                icon: 'thumbs_up_down'
            },
            'rating': {
                label: 'Rating',
                value: 'rating',
                icon: 'star_border'
            }
            /*
            'ranking': {
                label: 'Ranking',
                value: 'ranking',
                icon: 'sort'
            }
            */
        };

        $templateCache.put('campaign-template', isAdmin() ? templateAdmin : templateJury);

        // functions

        function activateRound(round) {
            round.loading = true;
            userService.admin.activateRound(round.id).then((response) => {
                round.loading = false;
                response.error ?
                    alertService.error(response.error) :
                    $state.reload();
            });
        }

        function createRound(round, loading) {
            let round_ = angular.copy(round);
            round_ = angular.extend(round_, {
                jurors: round.jurors.map((element) => element.name),
                deadline_date: $filter('date')(round.deadline_date, 'yyyy-MM-ddTHH:mm:ss', 'UTC')
            });

            if (!round_.name) {
                alertService.error({
                    message: 'Error',
                    detail: 'Name cannot be empty'
                });
                return;
            }
            if (!round_.deadline_date) {
                alertService.error({
                    message: 'Error',
                    detail: 'Deadline date cannot be empty'
                });
                return;
            }
            if (!round_.jurors.length) {
                alertService.error({
                    message: 'Error',
                    detail: 'Jurors must be added'
                });
                return;
            }
            if (!round_.quorum) {
                alertService.error({
                    message: 'Error',
                    detail: 'Quorum value is empty on invalid'
                });
                return;
            }

            loading.window = true;
            userService.admin.addRound(vm.campaign.id, round_).then((response) => {
                if(response.error) {
                    loading.window = false;
                    alertService.error(response.error);
                    return;
                }

                const id = response.data.id;
                userService.admin.populateRound(id, round_.imports).then((response) => {
                    if(response.error) {
                        loading.window = false;
                        alertService.error(response.error);
                        return;
                    }

                    alertService.success('New round added');
                    $mdDialog.hide(true);
                    $state.reload();
                });
            });
        }

        function addRound(event) {
            dialogService.show({
                template: templateNewRound,
                scope: {
                    round: {
                        name: 'Round ' + (vm.campaign.rounds.length + 1),
                        vote_method: 'rating',
                        quorum: 2,
                        jurors: [],
                        config: {show_link: true},
                        imports: {
                            import_method: 'category',
                            category: ''
                        }
                    },
                    createRound: createRound,
                    searchCategory: (name) => dataService.searchCategory(name).then((response) => {
                        return response.data[1].map((element) => element.substring(9));
                    }),
                    voteMethods: voteMethods,
                    today: new Date()
                }
            });
        }

        function cancelCampaignName() {
            vm.isNameEdited = false;
            vm.nameEdit = '';
        }

        function editCampaignName($event) {
            vm.nameEdit = vm.campaign.name;
            vm.isNameEdited = true;
            $timeout(() => {
                let input = angular.element($event.target).parent().parent().find('input')[0];
                input.focus();
            });
        }

        function editRound(round) {
            let round_ = angular.extend(angular.copy(round), {
                deadline_date: new Date(round.deadline_date)
            });

            dialogService.show({
                template: templateEditRound,
                scope: {
                    round: round_,
                    voteMethods: voteMethods,
                    saveEditRound: saveEditRound,
                }
            });
        }

        function isAdmin() {
            return vm.type === 'admin';
        }

        function isLastRoundCompleted() {
            const rounds = vm.campaign.rounds;
            const isCompleted = rounds.length && (rounds[rounds.length - 1].status === 'completed' || rounds[rounds.length - 1].status === 'cancelled');
            return !rounds.length || isCompleted;
        }

        function isRoundActive(round) {
            return round.status === 'active' && round.total_tasks;
        }

        function openRound(round) {
            if (!isRoundActive(round)) {
                return;
            }

            if (round.voteMethod === 'voting') {
                $state.go('main.juror.image');
            } else {
                $state.go(isAdmin() ? 'main.admin.round' : 'main.juror.round', { id: round.id });
            }
        }

        function pauseRound(round) {
            round.loading = true;
            userService.admin.pauseRound(round.id).then((response) => {
                round.loading = false;
                response.error ?
                    alertService.error(response.error) :
                    $state.reload();
            });
        }

        function saveEditRound(round, loading) {
            loading.window = true;
            userService.admin.editRound(round.id, round).then((response) => {
                if(response.error) {
                    loading.window = false;
                    alertService.error(response.error);
                    return;
                }

                alertService.success('Round settings saved');
                $mdDialog.hide(true);
                $state.reload();
            });
        }

        function saveCampaignName() {
            vm.campaign.name = vm.nameEdit;
            vm.isNameEdited = false;

            userService.admin.editCampaign(vm.campaign.id, {
                name: vm.campaign.name
            }).then((response) => {
                response.error ?
                    alertService.error(response.error) :
                    alertService.success('Campaign name changed');
            });
        }
    },
    template: `<ng-include src="'campaign-template'"/>`
};

export default () => {
    angular
        .module('montage')
        .component('montCampaign', CampaignComponent)
        .filter('fromNow', () => (input) => moment.utc(input).fromNow());
};
<|endoftext|>


<commit_before>import React from 'react';
import { Link } from 'react-router';
import { Menu, Segment } from 'semantic-ui-react';

export const Navbar = ({location}) => {
  console.log('location', location);
  return (
    <Segment inverted>
      <Menu inverted pointing secondary>
        <Menu.Item header>Our Company</Menu.Item>
        <Menu.Item as={Link} to='landing' name='About' active={location === 'landing'} />
        <Menu.Item as={Link} to='/customer/dashboard' name='customer dashboard' active={location === '/customer/dashboard'} />

          <Menu.Menu position='right'>
            <Link to='signup' className='item'>
              Sign Up
            </Link>
          <Menu.Item as={Link} to='login' name='login'>
            Login
          </Menu.Item>
        </Menu.Menu>
      </Menu>
    </Segment>
  )
};

      // import React, { Component } from 'react'
      // import { Menu } from 'semantic-ui-react'

      // export default class MenuExampleHeader extends Component {
        //   state = {}

        //   handleItemClick = (e, { name }) => this.setState({ activeItem: name })

        //   render() {
        //     const { activeItem } = this.state

        //     return (
        //       <Menu>
        //         <Menu.Item header>Our Company</Menu.Item>
        //         <Menu.Item name='aboutUs' active={activeItem === 'aboutUs'} onClick={this.handleItemClick} />
        //         <Menu.Item name='jobs'  onClick={this.handleItemClick} />
        //         <Menu.Item name='locations' active={activeItem === 'locations'} onClick={this.handleItemClick} />
        //       </Menu>
        //     )
        //   }
        // }
<commit_msg>Remove log<commit_after>import React from 'react';
import { Link } from 'react-router';
import { Menu, Segment } from 'semantic-ui-react';

export const Navbar = ({location}) => {
  return (
    <Segment inverted>
      <Menu inverted pointing secondary>
        <Menu.Item header>Our Company</Menu.Item>
        <Menu.Item as={Link} to='landing' name='About' active={location === 'landing'} />
        <Menu.Item as={Link} to='/customer/dashboard' name='customer dashboard' active={location === '/customer/dashboard'} />

          <Menu.Menu position='right'>
            <Link to='signup' className='item'>
              Sign Up
            </Link>
          <Menu.Item as={Link} to='login' name='login'>
            Login
          </Menu.Item>
        </Menu.Menu>
      </Menu>
    </Segment>
  )
};

      // import React, { Component } from 'react'
      // import { Menu } from 'semantic-ui-react'

      // export default class MenuExampleHeader extends Component {
        //   state = {}

        //   handleItemClick = (e, { name }) => this.setState({ activeItem: name })

        //   render() {
        //     const { activeItem } = this.state

        //     return (
        //       <Menu>
        //         <Menu.Item header>Our Company</Menu.Item>
        //         <Menu.Item name='aboutUs' active={activeItem === 'aboutUs'} onClick={this.handleItemClick} />
        //         <Menu.Item name='jobs'  onClick={this.handleItemClick} />
        //         <Menu.Item name='locations' active={activeItem === 'locations'} onClick={this.handleItemClick} />
        //       </Menu>
        //     )
        //   }
        // }
<|endoftext|>


<commit_before>const cookie = require('react-cookie')
const axios = require('axios');
const React = require('react');
const EditInfo = require('./profile/edit-info');
const UserInfo = require('./profile/user-info');

const Profile = React.createClass({
    componentWillMount() {
        // Fetch user data prior to component mounting
        const user = cookie.load('user');
        console.log(user);
        if (user == undefined) {
            window.location.href = 'http://localhost:3000/login';
        } else {
            const userId = user._id;

            this.setState({
                firstName: user.firstName,
                lastInitial: user.lastInitial,
                age: user.age,
                age_pref_min: user.age_pref_min,
                age_pref_max: user.age_pref_max,
                is_male: user.is_male,
                seeking_male: user.seeking_male,
            })
        }
        // // console.log("userID", userId);
        // function fetchMyProfile(uid) {

        //     axios.get(`${API_URL}/user/${uid}`, {
        //         headers: { Authorization: cookie.load('token') },
        //     })
        //         .then((response) => {
        //             console.log("response:", response)
        //         })
        //         .catch((err) => {
        //             console.log("error", err)
        //         });

        // }
    },

    // check() {

    //     if (window.location.href.indexOf("edit-info") > -1) {
    //         return (
    //             <EditInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     } else {
    //         return (
    //             <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     }
    // },

    render: function () {
        return (

                <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />

        );
    }
})

module.exports = Profile;<commit_msg>more grabs from cookie - testing<commit_after>const cookie = require('react-cookie')
const axios = require('axios');
const React = require('react');
const EditInfo = require('./profile/edit-info');
const UserInfo = require('./profile/user-info');

const Profile = React.createClass({
    componentWillMount() {
        // Fetch user data prior to component mounting
        const user = cookie.load('user');
        console.log(user);
        if (user == undefined) {
            window.location.href = 'http://localhost:3000/login';
        } else {
            const userId = user._id;

            this.setState({
                firstName: user.firstName,
                lastInitial: user.lastInitial,
                age: user.age,
                age_pref_min: user.age_pref_min,
                age_pref_max: user.age_pref_max,
                is_male: user.is_male,
                seeking_male: user.seeking_male,
            })
        }
        // // console.log("userID", userId);
        // function fetchMyProfile(uid) {

        //     axios.get(`${API_URL}/user/${uid}`, {
        //         headers: { Authorization: cookie.load('token') },
        //     })
        //         .then((response) => {
        //             console.log("response:", response)
        //         })
        //         .catch((err) => {
        //             console.log("error", err)
        //         });

        // }
    },

    // check() {

    //     if (window.location.href.indexOf("edit-info") > -1) {
    //         return (
    //             <EditInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     } else {
    //         return (
    //             <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     }
    // },

    render: function () {
        return (

                <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} is_male={this.state.is_male} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />

        );
    }
})

module.exports = Profile;<|endoftext|>


<commit_before>import * as ModelActions from './../constants/ModelActions';

export default class Submit {

    /**
     * @param {ApiHandler} apiHandler
     */
    constructor(apiHandler) {
        this.apiHandler = apiHandler;
    }

    /**
     * ModelActions.VALIDATED callback.
     *
     * @param {string} event
     * @param {Model} model
     */
    update(event, model) {
        // The event is always ModelActions.VALIDATED
        if (model.hasErrors()) {
            return;
        }
        this.apiHandler.submit(model.className, this.asMap(model), this.getMethod(model), model.id)
            .then((result) => {
                model.trigger(ModelActions.SUBMIT_SUCCEEDED, model, result);
            })
            .catch(() => {
                model.trigger(ModelActions.SUBMIT_FAILED, model);
            });
    }

    /**
     * Returns key-value representation of the given Model.
     *
     * @param {Model} model
     */
    asMap(model) {
        let map = {};
        let attributes = model.attributes;
        Object.keys(attributes).forEach((key) => {
            // We don't want to send primary attributes
            if (!attributes[key].isPrimary()) {
                map[key] = attributes[key].value;
            }
        });
        // TODO: send relations
        //let relations = model.relations;
        //Object.keys(relations).forEach((key) => {
        //    map[key] = relations[key].value;
        //});

        return map;
    }

    /**
     * Returns name of the submission method.
     *
     * @param {Model} model
     */
    getMethod(model) {
        if (model.id !== null) {
            return "PUT";
        }
        return "POST";
    }

    /**
     * Binds the Submit instance to the given Model.
     *
     * @param {Model} model
     * @return {Submit}
     */
    bind(model) {
        model.listen(ModelActions.VALIDATED, this);
        return this;
    }

}
<commit_msg>Submit now handles errors better<commit_after>import * as ModelActions from './../constants/ModelActions';

export default class Submit {

    /**
     * @param {ApiHandler} apiHandler
     */
    constructor(apiHandler) {
        this.apiHandler = apiHandler;
    }

    /**
     * ModelActions.VALIDATED callback.
     *
     * @param {string} event
     * @param {Model} model
     */
    update(event, model) {
        // The event is always ModelActions.VALIDATED
        if (model.hasErrors()) {
            return;
        }
        this.apiHandler.submit(model.className, this.asMap(model), this.getMethod(model), model.id)
            .then((result) => {
                if (result.status >= 200 && result.status < 300) {
                    model.trigger(ModelActions.SUBMIT_SUCCEEDED, model, result);
                } else {
                    model.trigger(ModelActions.SUBMIT_FAILED, model, result);
                }
            })
            .catch(() => {
                model.trigger(ModelActions.SUBMIT_FAILED, model);
            });
    }

    /**
     * Returns key-value representation of the given Model.
     *
     * @param {Model} model
     */
    asMap(model) {
        let map = {};
        let attributes = model.attributes;
        Object.keys(attributes).forEach((key) => {
            // We don't want to send primary attributes
            if (!attributes[key].isPrimary()) {
                map[key] = attributes[key].value;
            }
        });
        // TODO: send relations
        //let relations = model.relations;
        //Object.keys(relations).forEach((key) => {
        //    map[key] = relations[key].value;
        //});

        return map;
    }

    /**
     * Returns name of the submission method.
     *
     * @param {Model} model
     */
    getMethod(model) {
        if (model.id !== null) {
            return "PUT";
        }
        return "POST";
    }

    /**
     * Binds the Submit instance to the given Model.
     *
     * @param {Model} model
     * @return {Submit}
     */
    bind(model) {
        model.listen(ModelActions.VALIDATED, this);
        return this;
    }

}
<|endoftext|>


<commit_before>import { DATA_MSG, CMD_MSG, EVT_MSG } from 'constants';
import events from 'utils/genny/vertx-events';
import store from 'views/store';

class MessageHandler {

  onMessage( message ) {

    /* Check that the message isn't null */
    if ( !message ) {
      console.warn( '[MessageHandler] NULL message sent to message handler. Ignoring.' );
      return;
    }

    /* Determine message type */
    const { msg_type } = message;

    /* Check to ensure that the message type is a currently supported one */
    if ( msg_type !== DATA_MSG && msg_type !== CMD_MSG && msg_type !== EVT_MSG ) {
      console.warn( `[MessageHandler] ${msg_type} is currently unsupported.` );
      return;
    }

    /* Based upon the message type dispatch a redux action */
    let eventType = null;

    if ( msg_type === CMD_MSG ) {
      eventType = message.cmd_type;
    }

    if ( msg_type === DATA_MSG ) {
      eventType = message.data_type;
    }

    if ( msg_type === EVT_MSG ) {
      eventType = message.event_type;
    }

    /* Get the redux action to send */
    const action = events.incoming[eventType];

    if ( !action ) {
      console.warn( `[MessageHandler] No action creator for events of type ${eventType} `);
      console.warn ( message );
      return;
    }

    store.dispatch(action(message));
  }
}

export default MessageHandler;
<commit_msg>message handler<commit_after>import { DATA_MSG, CMD_MSG, EVT_MSG } from 'constants';
import events from 'utils/genny/vertx-events';
import store from 'views/store';

class MessageHandler {

    onMessage(message) {

        /* Check that the message isn't null */
        if (!message) {
            console.warn('[MessageHandler] NULL message sent to message handler. Ignoring.');
            return;
        }

        /* Determine message type */
        const { msg_type } = message;

        /* Check to ensure that the message type is a currently supported one */
        if (msg_type !== DATA_MSG && msg_type !== CMD_MSG && msg_type !== EVT_MSG) {
            console.warn(`[MessageHandler] ${msg_type} is currently unsupported.`);
            return;
        }

        /* Based upon the message type dispatch a redux action */
        let eventType = null;

        if (msg_type === CMD_MSG) {
            eventType = message.cmd_type;
        }

        if (msg_type === DATA_MSG) {
            eventType = message.data_type;
        }

        if (msg_type === EVT_MSG) {
            eventType = message.event_type;
        }

        const handleMessage = (message, eventType) => {

            /* Get the redux action to send */
            const action = events.incoming[eventType];

            if (!action) {
                console.warn(`[MessageHandler] No action creator for events of type ${eventType} `);
                console.warn(message);
                return;
            }

            store.dispatch(action(message));
        };

        /* handle bulk messages */
        if (message.data_type == 'QDataBulkMessage' && message.messages != null && message.messages.length) {

            message.messages.forEach(msg => {
                onMessage(msg);
            });

        } else {
            handleMessage(message, eventType);
        }

    }
}

export default MessageHandler;
<|endoftext|>


<commit_before>/*
 * $z.attach
 * Used for attaching components as if they were generated client-side after a server render.
 *
 * Simply render the expected HTML and place the following around the component:
 *
 * <!-- ensure css is loaded -->
 * <script src='require-inline.js' data-require='css!app/slideshow,css!app/slideshow,css!app/slideshow'></script>
 *
 * <!-- display html -->
 * <template html here>
 *
 * <!-- ensure module is loaded for immediate attachment -->
 * <script src='require-inline.js' data-require='zest,app/slideshow'></script>
 *
 * <!-- apply the attachment script -->
 * <script src='zest/attach.js' data-zid='zid' data-controllerid='app/slideshow' data-options='{optionsJSON}'></script>
 *
 * It relies on the fact that the component has the right id to detect its elements as the previous siblings until it reaches
 * the primary component element with the right id on it.
 *
 * If no controller is given, the component is simply registered as a static component.
 *
 * Finally, also ensure that there is a sync require to zest at the top of the page.
 *
 */

// make volo think this is an amd module
if (false) define({});

(function() {
  // get the script tag for this script
  var scriptTag = Array.prototype.pop.call(document.getElementsByTagName('script'));

  var zid = scriptTag.getAttribute('data-zid');

  if (zid == null)
    return;

  var controllerId = scriptTag.getAttribute('data-controllerid');

  var options = scriptTag.getAttribute('data-options');

  if (options) {
    options = JSON.parse(options);
    options.global = $z._global;
  }

  // find attach element
  var el = document.getElementById(zid);

  if (!el)
    throw 'No component with id ' + zid + ' found for attachment!';

  // main component HTML elements
  //var els = [curElement];

  // step down through siblings until we find this script
  //while (curElement != scriptTag && (curElement = curElement.nextSibling))
  //  els.push(curElement);

  //if (curElement != scriptTag)
  //  throw 'Unable to detect component template for ' + zid + '. Malformed HTML.';

  var requireInlineUrl = require.toUrl('require-inline');

  require(['zest'], function($z) {

    // note down that there is a controller for this zid. Any attachment attempts then given a callback.
    if ($z._nextComponentId <= zid.substr(1))
      $z.nextComponentId = parseInt(zid.substr(1)) + 1;
    $z._components[zid] = true;

    // require zest and the component id to do the enhancements
    require([controllerId, 'json/json'], function(controllerFunction, JSON) {
      var attach = controllerFunction.attach ? controllerFunction.attach : controllerFunction;

      var controller = attach.call(controllerFunction, el, options || { global: $z._global });

      // store the callback in case some attach hooks have been added
      var callback = $z._components[zid];
      $z._components[zid] = controller || el;

      if (!controller)
        return;

      var dispose = controller.dispose;

      if (dispose && $z.fn) {
        if (dispose.constructor == $z.fn)
          dispose.run = $z.fn.STOP_FIRST_DEFINED;
        else
          dispose = $z.fn([dispose], $z.fn.STOP_FIRST_DEFINED);
        dispose.first(function(system) {
          if (!system)
            return $z.dispose(el);
        })
      }
      else
        controller.dispose = function(system) {
          if (!system)
            return $z.dispose(el);
          if (dispose)
            dispose();
        }

      if (typeof controller.init == 'function')
        controller.init();

      // if we have any callback hooks, run them now
      if (callback && callback.constructor == $z.fn)
        callback(controller);
    });

  });

  // remove the attach script itself
  scriptTag.parentNode.removeChild(scriptTag);
})();
<commit_msg>added next component id correction<commit_after>/*
 * $z.attach
 * Used for attaching components as if they were generated client-side after a server render.
 *
 * Simply render the expected HTML and place the following around the component:
 *
 * <!-- ensure css is loaded -->
 * <script src='require-inline.js' data-require='css!app/slideshow,css!app/slideshow,css!app/slideshow'></script>
 *
 * <!-- display html -->
 * <template html here>
 *
 * <!-- ensure module is loaded for immediate attachment -->
 * <script src='require-inline.js' data-require='zest,app/slideshow'></script>
 *
 * <!-- apply the attachment script -->
 * <script src='zest/attach.js' data-zid='zid' data-controllerid='app/slideshow' data-options='{optionsJSON}'></script>
 *
 * It relies on the fact that the component has the right id to detect its elements as the previous siblings until it reaches
 * the primary component element with the right id on it.
 *
 * If no controller is given, the component is simply registered as a static component.
 *
 * Finally, also ensure that there is a sync require to zest at the top of the page.
 *
 */

// make volo think this is an amd module
if (false) define({});

(function() {
  // get the script tag for this script
  var scriptTag = Array.prototype.pop.call(document.getElementsByTagName('script'));

  var zid = scriptTag.getAttribute('data-zid');

  if (zid == null)
    return;

  var controllerId = scriptTag.getAttribute('data-controllerid');

  var options = scriptTag.getAttribute('data-options');

  if (options) {
    options = JSON.parse(options);
    options.global = $z._global;
  }

  // find attach element
  var el = document.getElementById(zid);

  if (!el)
    throw 'No component with id ' + zid + ' found for attachment!';

  // main component HTML elements
  //var els = [curElement];

  // step down through siblings until we find this script
  //while (curElement != scriptTag && (curElement = curElement.nextSibling))
  //  els.push(curElement);

  //if (curElement != scriptTag)
  //  throw 'Unable to detect component template for ' + zid + '. Malformed HTML.';

  var requireInlineUrl = require.toUrl('require-inline');

  require(['zest'], function($z) {

    // note down that there is a controller for this zid. Any attachment attempts then given a callback.
    if ($z._nextComponentId <= zid.substr(1))
      $z._nextComponentId = parseInt(zid.substr(1)) + 1;
    $z._components[zid] = true;

    // require zest and the component id to do the enhancements
    require([controllerId, 'json/json'], function(controllerFunction, JSON) {
      var attach = controllerFunction.attach ? controllerFunction.attach : controllerFunction;

      var controller = attach.call(controllerFunction, el, options || { global: $z._global });

      // store the callback in case some attach hooks have been added
      var callback = $z._components[zid];
      $z._components[zid] = controller || el;

      if (!controller)
        return;

      var dispose = controller.dispose;

      if (dispose && $z.fn) {
        if (dispose.constructor == $z.fn)
          dispose.run = $z.fn.STOP_FIRST_DEFINED;
        else
          dispose = $z.fn([dispose], $z.fn.STOP_FIRST_DEFINED);
        dispose.first(function(system) {
          if (!system)
            return $z.dispose(el);
        })
      }
      else
        controller.dispose = function(system) {
          if (!system)
            return $z.dispose(el);
          if (dispose)
            dispose();
        }

      if (typeof controller.init == 'function')
        controller.init();

      // if we have any callback hooks, run them now
      if (callback && callback.constructor == $z.fn)
        callback(controller);
    });

  });

  // remove the attach script itself
  scriptTag.parentNode.removeChild(scriptTag);
})();
<|endoftext|>