<commit_before>// framework/entities/router/outlet.js
// ------------------

var noParentViewModelError = { $namespace: { getName: function() { return 'NO-VIEWMODEL-IN-CONTEXT'; } } };

// This custom binding binds the outlet element to the $outlet on the router, changes on its 'route' (component definition observable) will be applied
// to the UI and load in various views
fw.virtualElements.allowedBindings.$outletBinder = true;
fw.bindingHandlers.$outletBinder = {
  init: function(element, valueAccessor, allBindings, outletViewModel, bindingContext) {
    var $parentViewModel = (isObject(bindingContext) ? (bindingContext.$parent || noParentViewModelError) : noParentViewModelError);
    var $parentRouter = nearestParentRouter(bindingContext);
    var outletName = outletViewModel.outletName;

    if(isRouter($parentRouter)) {
      // register the viewModel with the outlet for future use when its route is changed
      $parentRouter.__private('registerViewModelForOutlet')(outletName, outletViewModel);
      fw.utils.domNodeDisposal.addDisposeCallback(element, function() {
        // tell the router to clean up its reference to the outletViewModel
        $parentRouter.__private('unregisterViewModelForOutlet')(outletName);
        outletViewModel.dispose();
      });

      // register this outlet with its $parentRouter
      outletViewModel.route = $parentRouter.outlet(outletName);
    } else {
      throw new Error('Outlet [' + outletName + '] defined inside of viewModel [' + $parentViewModel.$namespace.getName() + '] but no router was defined.');
    }
  }
};

function registerViewModelForOutlet(outletName, outletViewModel) {
  var outletProperties = this.outlets[outletName] || {};
  outletProperties.outletViewModel = outletViewModel;
}

function unregisterViewModelForOutlet(outletName) {
  var outletProperties = this.outlets[outletName] || {};
  delete outletProperties.outletViewModel;
}

function routerOutlet(outletName, componentToDisplay, options) {
  options = options || {};
  if(isFunction(options)) {
    options = { onComplete: options, onFailure: noop };
  }

  var router = this;
  var viewModelParameters = options.params;
  var onComplete = options.onComplete || noop;
  var onFailure = options.onFailure || noop;
  var configParams = router.__private('configParams');
  var outlets = router.outlets;
  var outletProperties = outlets[outletName] || {};
  var outlet = outletProperties.routeObservable;
  var outletViewModel = outletProperties.outletViewModel;

  if(!isObservable(outlet)) {
    // router outlet observable not found, we must create a new one
    outlet = fw.observable({
      name: noComponentSelected,
      params: {},
      __getOnCompleteCallback: function() { return noop; },
      __onFailure: onFailure.bind(router)
    }).broadcastAs({
      name: outletName,
      namespace: router.$namespace
    });

    // register the new outlet under its outletName
    outlets[outletName] = {
      outletViewModel: outletProperties.outletViewModel || null,
      routeObservable: outlet
    };
  }

  var currentOutletDef = outlet();
  var valueHasMutated = false;

  if(arguments.length > 1 && !componentToDisplay) {
    componentToDisplay = nullComponent;
  }

  if(!isUndefined(componentToDisplay)) {
    if(currentOutletDef.name !== componentToDisplay) {
      currentOutletDef.name = componentToDisplay;
      valueHasMutated = true;
    }

    if(isObject(viewModelParameters)) {
      currentOutletDef.params = viewModelParameters;
      valueHasMutated = true;
    }
  }

  if(outletViewModel) {
    // Show the loading component (if one is defined)
    var showDuringLoadComponent = resultBound(configParams, 'showDuringLoad', router, [outletName, componentToDisplay || currentOutletDef.name]);
    if(showDuringLoadComponent) {
      outletViewModel.loadingDisplay(showDuringLoadComponent);
    }
  }

  if(valueHasMutated) {
    clearSequenceQueue();

    currentOutletDef.minTransitionPeriod = resultBound(configParams, 'minTransitionPeriod', router, [outletName, componentToDisplay]);
    if(outletViewModel) {
      outletViewModel.routeIsLoading(true);
    }

    currentOutletDef.__getOnCompleteCallback = function(element) {
      var changeIsComplete = !!element.children.length;
      var outletElement = element.parentNode;

      if(changeIsComplete) {
        activeOutlets.remove(outlet);
        outletElement.setAttribute('rendered', (componentToDisplay === nullComponent ? '' : componentToDisplay));

        return function addBindingOnComplete() {
          var outletViewModel = router.outlets[outletName].outletViewModel;
          if(outletViewModel) {
            outletViewModel.routeIsLoading(false);
          }

          onComplete.call(router, outletElement);
        };
      } else {
        removeClass(outletElement, entityAnimateClass);
        return noop;
      }
    };

    if(activeOutlets().indexOf(outlet) === -1) {
      activeOutlets.push(outlet);
    }

    outlet.valueHasMutated();
  }

  return outlet;
};

var outletLoadingDisplay = 'fw-loading-display';
var outletLoadedDisplay = 'fw-loaded-display';
var visibleCSS = { 'height': '', 'overflow': '' };
var hiddenCSS = { 'height': '0px', 'overflow': 'hidden' };
var removeAnimation = {};
removeAnimation[entityAnimateClass] = false;
var addAnimation = {};
addAnimation[entityAnimateClass] = true;

function registerOutletComponent() {
  internalComponents.push('outlet');
  fw.components.register('outlet', {
    viewModel: function(params) {
      var outlet = this;

      this.outletName = fw.unwrap(params.name);
      this.__isOutlet = true;

      this.loadingDisplay = fw.observable(nullComponent);
      this.inFlightChildren = fw.observableArray();
      this.routeIsLoading = fw.observable(true);
      this.routeIsResolving = fw.observable(true);

      var resolvedCallbacks = [];
      this.addResolvedCallbackOrExecute = function(callback) {
        if(outlet.routeIsResolving()) {
          resolvedCallbacks.push(callback);
        } else {
          callback();
        }
      };

      this.routeIsLoadingSub = this.routeIsLoading.subscribe(function(routeIsLoading) {
        if(routeIsLoading) {
          outlet.routeIsResolving(true);
        } else {
          if(outlet.flightWatch && isFunction(outlet.flightWatch.dispose)) {
            outlet.flightWatch.dispose();
          }

          // must call setTimeout to allow binding to begin on any subcomponents/etc
          setTimeout(function() {
            if(outlet.inFlightChildren().length) {
              outlet.flightWatch = outlet.inFlightChildren.subscribe(function(inFlightChildren) {
                if(!inFlightChildren.length) {
                  outlet.routeIsResolving(false);
                }
              });
            } else {
              outlet.routeIsResolving(false);
            }
          }, 0);
        }
      });

      this.loadingStyle = fw.observable();
      this.loadedStyle = fw.observable();
      this.loadingClass = fw.observable();
      this.loadedClass = fw.observable();

      function showLoader() {
        outlet.loadingClass(removeAnimation);
        outlet.loadedClass(removeAnimation);
        outlet.loadedStyle(hiddenCSS);
        outlet.loadingStyle(visibleCSS);

        setTimeout(function() {
          outlet.loadingClass(addAnimation);
        }, 0);
      }

      function showLoadedAfterMinimumTransition() {
        outlet.loadingClass(removeAnimation);
        outlet.loadedClass(removeAnimation);
        outlet.loadedStyle(visibleCSS);
        outlet.loadingStyle(hiddenCSS);
        outlet.loadedClass(addAnimation);

        if(resolvedCallbacks.length) {
          each(resolvedCallbacks, function(callback) {
            callback();
          });
          resolvedCallbacks = [];
        }
      }

      var transitionTriggerTimeout;
      function showLoaded() {
        clearTimeout(transitionTriggerTimeout);
        var minTransitionPeriod = outlet.route.peek().minTransitionPeriod;
        if(minTransitionPeriod) {
          transitionTriggerTimeout = setTimeout(showLoadedAfterMinimumTransition, minTransitionPeriod);
        } else {
          showLoadedAfterMinimumTransition();
        }
      }

      this.transitionTrigger = fw.computed(function() {
        var routeIsResolving = this.routeIsResolving();
        if(routeIsResolving) {
          showLoader();
        } else {
          showLoaded();
        }
      }, this);

      this.dispose = function() {
        each(outlet, function(outletProperty) {
          if(outletProperty && isFunction(outletProperty.dispose)) {
            outletProperty.dispose();
          }
        });
      };
    },
    template: '' +
                '
' +
                  '' +
                '
' +
                '
' +
                  '' +
                '
' +
              ''
  });

  internalComponents.push(noComponentSelected);
  fw.components.register(noComponentSelected, {
    template: '

'
  });
  fw.components.register(nullComponent, {
    template: '

'
  });
};

runPostInit.push(registerOutletComponent);
<commit_msg>removed broadcastable from outlet route<commit_after>// framework/entities/router/outlet.js
// ------------------

var noParentViewModelError = { $namespace: { getName: function() { return 'NO-VIEWMODEL-IN-CONTEXT'; } } };

// This custom binding binds the outlet element to the $outlet on the router, changes on its 'route' (component definition observable) will be applied
// to the UI and load in various views
fw.virtualElements.allowedBindings.$outletBinder = true;
fw.bindingHandlers.$outletBinder = {
  init: function(element, valueAccessor, allBindings, outletViewModel, bindingContext) {
    var $parentViewModel = (isObject(bindingContext) ? (bindingContext.$parent || noParentViewModelError) : noParentViewModelError);
    var $parentRouter = nearestParentRouter(bindingContext);
    var outletName = outletViewModel.outletName;

    if(isRouter($parentRouter)) {
      // register the viewModel with the outlet for future use when its route is changed
      $parentRouter.__private('registerViewModelForOutlet')(outletName, outletViewModel);
      fw.utils.domNodeDisposal.addDisposeCallback(element, function() {
        // tell the router to clean up its reference to the outletViewModel
        $parentRouter.__private('unregisterViewModelForOutlet')(outletName);
        outletViewModel.dispose();
      });

      // register this outlet with its $parentRouter
      outletViewModel.route = $parentRouter.outlet(outletName);
    } else {
      throw new Error('Outlet [' + outletName + '] defined inside of viewModel [' + $parentViewModel.$namespace.getName() + '] but no router was defined.');
    }
  }
};

function registerViewModelForOutlet(outletName, outletViewModel) {
  var outletProperties = this.outlets[outletName] || {};
  outletProperties.outletViewModel = outletViewModel;
}

function unregisterViewModelForOutlet(outletName) {
  var outletProperties = this.outlets[outletName] || {};
  delete outletProperties.outletViewModel;
}

function routerOutlet(outletName, componentToDisplay, options) {
  options = options || {};
  if(isFunction(options)) {
    options = { onComplete: options, onFailure: noop };
  }

  var router = this;
  var viewModelParameters = options.params;
  var onComplete = options.onComplete || noop;
  var onFailure = options.onFailure || noop;
  var configParams = router.__private('configParams');
  var outlets = router.outlets;
  var outletProperties = outlets[outletName] || {};
  var outlet = outletProperties.routeObservable;
  var outletViewModel = outletProperties.outletViewModel;

  if(!isObservable(outlet)) {
    // router outlet observable not found, we must create a new one
    outlet = fw.observable({
      name: noComponentSelected,
      params: {},
      __getOnCompleteCallback: function() { return noop; },
      __onFailure: onFailure.bind(router)
    });

    // register the new outlet under its outletName
    outlets[outletName] = {
      outletViewModel: outletProperties.outletViewModel || null,
      routeObservable: outlet
    };
  }

  var currentOutletDef = outlet();
  var valueHasMutated = false;

  if(arguments.length > 1 && !componentToDisplay) {
    componentToDisplay = nullComponent;
  }

  if(!isUndefined(componentToDisplay)) {
    if(currentOutletDef.name !== componentToDisplay) {
      currentOutletDef.name = componentToDisplay;
      valueHasMutated = true;
    }

    if(isObject(viewModelParameters)) {
      currentOutletDef.params = viewModelParameters;
      valueHasMutated = true;
    }
  }

  if(outletViewModel) {
    // Show the loading component (if one is defined)
    var showDuringLoadComponent = resultBound(configParams, 'showDuringLoad', router, [outletName, componentToDisplay || currentOutletDef.name]);
    if(showDuringLoadComponent) {
      outletViewModel.loadingDisplay(showDuringLoadComponent);
    }
  }

  if(valueHasMutated) {
    clearSequenceQueue();

    currentOutletDef.minTransitionPeriod = resultBound(configParams, 'minTransitionPeriod', router, [outletName, componentToDisplay]);
    if(outletViewModel) {
      outletViewModel.routeIsLoading(true);
    }

    currentOutletDef.__getOnCompleteCallback = function(element) {
      var changeIsComplete = !!element.children.length;
      var outletElement = element.parentNode;

      if(changeIsComplete) {
        activeOutlets.remove(outlet);
        outletElement.setAttribute('rendered', (componentToDisplay === nullComponent ? '' : componentToDisplay));

        return function addBindingOnComplete() {
          var outletViewModel = router.outlets[outletName].outletViewModel;
          if(outletViewModel) {
            outletViewModel.routeIsLoading(false);
          }

          onComplete.call(router, outletElement);
        };
      } else {
        removeClass(outletElement, entityAnimateClass);
        return noop;
      }
    };

    if(activeOutlets().indexOf(outlet) === -1) {
      activeOutlets.push(outlet);
    }

    outlet.valueHasMutated();
  }

  return outlet;
};

var outletLoadingDisplay = 'fw-loading-display';
var outletLoadedDisplay = 'fw-loaded-display';
var visibleCSS = { 'height': '', 'overflow': '' };
var hiddenCSS = { 'height': '0px', 'overflow': 'hidden' };
var removeAnimation = {};
removeAnimation[entityAnimateClass] = false;
var addAnimation = {};
addAnimation[entityAnimateClass] = true;

function registerOutletComponent() {
  internalComponents.push('outlet');
  fw.components.register('outlet', {
    viewModel: function(params) {
      var outlet = this;

      this.outletName = fw.unwrap(params.name);
      this.__isOutlet = true;

      this.loadingDisplay = fw.observable(nullComponent);
      this.inFlightChildren = fw.observableArray();
      this.routeIsLoading = fw.observable(true);
      this.routeIsResolving = fw.observable(true);

      var resolvedCallbacks = [];
      this.addResolvedCallbackOrExecute = function(callback) {
        if(outlet.routeIsResolving()) {
          resolvedCallbacks.push(callback);
        } else {
          callback();
        }
      };

      this.routeIsLoadingSub = this.routeIsLoading.subscribe(function(routeIsLoading) {
        if(routeIsLoading) {
          outlet.routeIsResolving(true);
        } else {
          if(outlet.flightWatch && isFunction(outlet.flightWatch.dispose)) {
            outlet.flightWatch.dispose();
          }

          // must call setTimeout to allow binding to begin on any subcomponents/etc
          setTimeout(function() {
            if(outlet.inFlightChildren().length) {
              outlet.flightWatch = outlet.inFlightChildren.subscribe(function(inFlightChildren) {
                if(!inFlightChildren.length) {
                  outlet.routeIsResolving(false);
                }
              });
            } else {
              outlet.routeIsResolving(false);
            }
          }, 0);
        }
      });

      this.loadingStyle = fw.observable();
      this.loadedStyle = fw.observable();
      this.loadingClass = fw.observable();
      this.loadedClass = fw.observable();

      function showLoader() {
        outlet.loadingClass(removeAnimation);
        outlet.loadedClass(removeAnimation);
        outlet.loadedStyle(hiddenCSS);
        outlet.loadingStyle(visibleCSS);

        setTimeout(function() {
          outlet.loadingClass(addAnimation);
        }, 0);
      }

      function showLoadedAfterMinimumTransition() {
        outlet.loadingClass(removeAnimation);
        outlet.loadedStyle(visibleCSS);
        outlet.loadingStyle(hiddenCSS);
        outlet.loadedClass(addAnimation);

        if(resolvedCallbacks.length) {
          each(resolvedCallbacks, function(callback) {
            callback();
          });
          resolvedCallbacks = [];
        }
      }

      var transitionTriggerTimeout;
      function showLoaded() {
        clearTimeout(transitionTriggerTimeout);
        var minTransitionPeriod = outlet.route.peek().minTransitionPeriod;
        if(minTransitionPeriod) {
          transitionTriggerTimeout = setTimeout(showLoadedAfterMinimumTransition, minTransitionPeriod);
        } else {
          showLoadedAfterMinimumTransition();
        }
      }

      this.transitionTrigger = fw.computed(function() {
        var routeIsResolving = this.routeIsResolving();
        if(routeIsResolving) {
          showLoader();
        } else {
          showLoaded();
        }
      }, this);

      this.dispose = function() {
        each(outlet, function(outletProperty) {
          if(outletProperty && isFunction(outletProperty.dispose)) {
            outletProperty.dispose();
          }
        });
      };
    },
    template: '' +
                '
' +
                  '' +
                '
' +
                '
' +
                  '' +
                '
' +
              ''
  });

  internalComponents.push(noComponentSelected);
  fw.components.register(noComponentSelected, {
    template: '

'
  });
  fw.components.register(nullComponent, {
    template: '

'
  });
};

runPostInit.push(registerOutletComponent);
<|endoftext|>


<commit_before>Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

// Based on:
// https://bug549539.bugzilla.mozilla.org/attachment.cgi?id=429661
// https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_1.9.3
// http://mxr.mozilla.org/mozilla-central/source/toolkit/components/console/hudservice/HUDService.jsm#3240
// https://developer.mozilla.org/en/how_to_build_an_xpcom_component_in_javascript

const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/NetUtil.jsm");

function dumpln(s) { dump(s + "\n"); }

function DOMFuzzHelper() {}

DOMFuzzHelper.prototype = {
  classDescription: "DOM fuzz helper",
  classID:          Components.ID("{59a52458-13e0-4d90-9d85-a637344f29a1}"),
  contractID:       "@squarefree.com/dom-fuzz-helper;1",

  QueryInterface:   XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
  _xpcom_categories: [{category: "profile-after-change", service: true }],

  observe: function(aSubject, aTopic, aData)
  {
    if (aTopic == "profile-after-change") {
      this.init();
    } else if (aTopic == "content-document-global-created") {
      var w = aSubject.wrappedJSObject;

      if (w) {
        w.goQuitApplication = function() { runSoon(goQuitApplication); }; // using runSoon avoids leaks (bug 593541)
        w.fuzzPrivRunSoon = runSoon;
        //w.fuzzPrivEnableAccessibility = enableAccessibility; // bug 571613, bug 404077, bug 571530
        w.fuzzPrivGC = function() { Components.utils.forceGC(); };
        w.fuzzPrivMP = sendMemoryPressureNotification;
        w.fuzzPrivCC = cycleCollect(aSubject);
        w.fuzzPrivZoom = setZoomLevel(aSubject);
        w.fuzzPrivPrintToFile = printToFile(aSubject);
        w.fuzzPrivQuitWithLeakCheck = quitWithLeakCheck;
      } else {
        // I don't understand why this happens.  Some chrome windows sneak in here?
      }
    } else if (aTopic == "xpcom-shutdown") {
      this.uninit();
    }
  },

  init: function()
  {
    var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
    obs.addObserver(this, "xpcom-shutdown", false);
    obs.addObserver(this, "content-document-global-created", false);
  },

  uninit: function()
  {
    var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
    obs.removeObserver(this, "content-document-global-created");
  },
};

const NSGetFactory = XPCOMUtils.generateNSGetFactory([DOMFuzzHelper]);

/*****************************
 * MISC PRIVILEGED FUNCTIONS *
 *****************************/

function runSoon(f)
{
  var tm = Components.classes["@mozilla.org/thread-manager;1"]
             .getService(Components.interfaces.nsIThreadManager);

  tm.mainThread.dispatch({
    run: function() {
      f();
    }
  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
}

function enableAccessibility()
{
  try {
    Components.classes["@mozilla.org/accessibilityService;1"]
      .getService(Components.interfaces.nsIAccessibleRetrieval);
    dump("Enabled accessibility!\n");
  } catch(e) {
    dump("Couldn't enable accessibility: " + e + "\n");
  }
}

function sendMemoryPressureNotification()
{
  var os = Components.classes["@mozilla.org/observer-service;1"]
           .getService(Components.interfaces.nsIObserverService);
  os.notifyObservers(null, "memory-pressure", "heap-minimize");
}

function cycleCollect(window)
{
  return function cycleCollectInner() {
    window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
          .getInterface(Components.interfaces.nsIDOMWindowUtils)
          .garbageCollect();
  }
}

function setZoomLevel(window)
{
  return function setZoomLevelInner(textOrFull, factor) {
    var viewer = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                       .getInterface(Components.interfaces.nsIWebNavigation)
                       .QueryInterface(Components.interfaces.nsIDocShell)
                       .contentViewer
                       .QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);

    if (textOrFull == "text")
      viewer.textZoom = +factor;
    else if (textOrFull == "full")
      viewer.fullZoom = +factor;
  }
}

function printToFile(window)
{
  // Linux: tested, works for PDF and PS, oddly asynchronous.
  // Mac: tested, printToFile is ignored and it goes to a printer!
  // Windows: untested.
  var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
                             .getService(Components.interfaces.nsIXULRuntime);
  if (xulRuntime.OS != "Linux") return function() { };

  var fired = false;

  return function printToFileInner(showHeaders, showBGColor, showBGImages, ps) {
    runSoon(function() {
        // Don't print more than once, it gets messy fast.
        if (fired) { return false; }
        fired = true;

        // Based on https://addons.mozilla.org/en-US/firefox/addon/5971/ by pav and bho

        var webBrowserPrint = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
        .getInterface(Components.interfaces.nsIWebBrowserPrint);

        var nsIPrintSettings = Components.interfaces.nsIPrintSettings;

        var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"]
        .getService(Components.interfaces.nsIPrintSettingsService);

        var printSettings = PSSVC.newPrintSettings;

        var file = Components.classes["@mozilla.org/file/directory_service;1"].
                              getService(Components.interfaces.nsIProperties).
                              get("ProfD", Components.interfaces.nsIFile);
        file.append(ps ? "a.ps" : "a.pdf");
        dumpln("Printing to: " + file.path);

        printSettings.printToFile = true;
        printSettings.toFileName  = file.path;
        printSettings.printSilent = true;
        printSettings.outputFormat = ps ? nsIPrintSettings.kOutputFormatPS : nsIPrintSettings.kOutputFormatPDF;
        printSettings.printBGColors   = !!showBGColor;
        printSettings.printBGImages   = !!showBGImages;
        if (!showHeaders) {
            printSettings.footerStrCenter = '';
            printSettings.footerStrLeft   = '';
            printSettings.footerStrRight  = '';
            printSettings.headerStrCenter = '';
            printSettings.headerStrLeft   = '';
            printSettings.headerStrRight  = '';
        }

        webBrowserPrint.print(printSettings, null);
    });
  }
}

/************************
 * QUIT WITH LEAK CHECK *
 ************************/

function quitWithLeakCheck()
{
  runSoon(a);
  function a() { dumpln("QA"); closeAllWindows(); runOnTimer(b); dumpln("QAA"); }
  function b() { dumpln("QB"); mpUntilDone(); runSoon(c); }
  function c() { dumpln("QC"); bloatStats(d); }
  function d(objectCounts) {
    dumpln("QD");

    dumpln("Windows: " + objectCounts["nsGlobalWindow"]);
    dumpln("Documents: " + objectCounts["nsDocument"]);

    //if (objectCounts["nsGlobalWindow"] > 4) { dumpln("OMGLEAK"); }
    //if (objectCounts["nsDocument"] > 4) { dumpln("OMGLEAK"); }
    runSoon(e);
  }
  function e() { dumpln("QE"); goQuitApplication(); }
}

function runOnTimer(f)
{
    var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
    timer.initWithCallback({notify: function(){f();}}, 2000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}

function closeAllWindows()
{
  var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                     .getService(Ci.nsIWindowWatcher);
  var enumerator = ww.getWindowEnumerator();

  var windowsToClose = [];

  while (enumerator.hasMoreElements()) {
    windowsToClose.push(enumerator.getNext().QueryInterface(Ci.nsIDOMWindow));
  }

  // if not mac...
  ww.openWindow(null, "about:blank", null, "width=200,height=200", null);

  for (var i = 0; i < windowsToClose.length; ++i) {
    windowsToClose[i].close();
  }

  dumpln("1");
}

function mpUntilDone()
{
    for (var j = 0; j < 10; ++j) {
      dumpln("MP " + j);
      sendMemoryPressureNotification();
    }
}

/*
     |<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->|
                                              Per-Inst   Leaked    Total      Rem      Mean       StdDev     Total      Rem      Mean       StdDev

*/
// Grab the class name and the number of remaining objects.
var bloatRex = /\s*\d+\s+(\S+)\s+\d+\s+\d+\s+\d+\s+(\d+)\s+.*/;
const SET_QUOTA = false;
const USE_QUOTA = false;

function bloatStats(callback)
{
  var objectCounts = {};

  try {
    //d.d.d;
    NetUtil.asyncFetch("about:bloat", fetched);
  } catch(e) {
    dumpln("Can't open about:bloat -- maybe you forgot to use XPCOM_MEM_LEAK_LOG");
    callback(objectCounts);
  }

  function fetched(aInputStream, aResult)
  {
    var r = NetUtil.readInputStreamToString(aInputStream, aInputStream.available());
    var lines = r.split("\n");
    for (var i = 0; i < lines.length; ++i)
    {
      var a = bloatRex.exec(lines[i]);
      if (a) {
        if (SET_QUOTA) {
          dumpln("'" + a[1] + "': " + a[2] + ",");
        } else if (USE_QUOTA) {
          quotaA = QUOTA[a[1]] || 0;
          if (a[2] > quotaA) { dumpln("Leak? Too many " + a[1] + " (" + a[2] + " > " + quotaA + ")"); }
        }
        objectCounts[a[1]] = a[2];
      }
    }
    runSoon(callCallback);
  }

  function callCallback()
  {
    callback(objectCounts)
  }
}

/********
 * QUIT *
 ********/

// From quit.js, which Bob Clary extracted from mozilla/toolkit/content

function canQuitApplication()
{
  var os = Components.classes["@mozilla.org/observer-service;1"]
    .getService(Components.interfaces.nsIObserverService);
  if (!os)
  {
    return true;
  }

  try
 {
    var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
      .createInstance(Components.interfaces.nsISupportsPRBool);
    os.notifyObservers(cancelQuit, "quit-application-requested", null);

    // Something aborted the quit process.
    if (cancelQuit.data)
    {
      return false;
    }
  }
  catch (ex)
  {
  }
  os.notifyObservers(null, "quit-application-granted", null);
  return true;
}

function goQuitApplication()
{
  dumpln("goQuitApplication (js component)");

  if (!canQuitApplication())
  {
    return false;
  }

  var kAppStartup = '@mozilla.org/toolkit/app-startup;1';
  var kAppShell   = '@mozilla.org/appshell/appShellService;1';
  var   appService;
  var   forceQuit;

  if (kAppStartup in Components.classes)
  {
    appService = Components.classes[kAppStartup].
      getService(Components.interfaces.nsIAppStartup);
    forceQuit  = Components.interfaces.nsIAppStartup.eForceQuit;

  }
  else if (kAppShell in Components.classes)
  {
    appService = Components.classes[kAppShell].
      getService(Components.interfaces.nsIAppShellService);
    forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
  }
  else
  {
    throw 'goQuitApplication: no AppStartup/appShell';
  }

  var windowManager = Components.
    classes['@mozilla.org/appshell/window-mediator;1'].getService();

  var windowManagerInterface = windowManager.
    QueryInterface(Components.interfaces.nsIWindowMediator);

  var enumerator = windowManagerInterface.getEnumerator(null);

  while (enumerator.hasMoreElements())
  {
    var domWindow = enumerator.getNext();
    if (("tryToClose" in domWindow) && !domWindow.tryToClose())
    {
      return false;
    }
    domWindow.close();
  }

  try
  {
    appService.quit(forceQuit);
  }
  catch(ex)
  {
    throw('goQuitApplication: ' + ex);
  }

  return true;
}

<commit_msg>Prevent double-running of quitWithLeakCheck<commit_after>Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

// Based on:
// https://bug549539.bugzilla.mozilla.org/attachment.cgi?id=429661
// https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_1.9.3
// http://mxr.mozilla.org/mozilla-central/source/toolkit/components/console/hudservice/HUDService.jsm#3240
// https://developer.mozilla.org/en/how_to_build_an_xpcom_component_in_javascript

const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/NetUtil.jsm");

function dumpln(s) { dump(s + "\n"); }

function DOMFuzzHelper() {}

DOMFuzzHelper.prototype = {
  classDescription: "DOM fuzz helper",
  classID:          Components.ID("{59a52458-13e0-4d90-9d85-a637344f29a1}"),
  contractID:       "@squarefree.com/dom-fuzz-helper;1",

  QueryInterface:   XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
  _xpcom_categories: [{category: "profile-after-change", service: true }],

  observe: function(aSubject, aTopic, aData)
  {
    if (aTopic == "profile-after-change") {
      this.init();
    } else if (aTopic == "content-document-global-created") {
      var w = aSubject.wrappedJSObject;

      if (w) {
        w.goQuitApplication = function() { runSoon(goQuitApplication); }; // using runSoon avoids leaks (bug 593541)
        w.fuzzPrivRunSoon = runSoon;
        //w.fuzzPrivEnableAccessibility = enableAccessibility; // bug 571613, bug 404077, bug 571530
        w.fuzzPrivGC = function() { Components.utils.forceGC(); };
        w.fuzzPrivMP = sendMemoryPressureNotification;
        w.fuzzPrivCC = cycleCollect(aSubject);
        w.fuzzPrivZoom = setZoomLevel(aSubject);
        w.fuzzPrivPrintToFile = printToFile(aSubject);
        w.fuzzPrivQuitWithLeakCheck = quitWithLeakCheck;
      } else {
        // I don't understand why this happens.  Some chrome windows sneak in here?
      }
    } else if (aTopic == "xpcom-shutdown") {
      this.uninit();
    }
  },

  init: function()
  {
    var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
    obs.addObserver(this, "xpcom-shutdown", false);
    obs.addObserver(this, "content-document-global-created", false);
  },

  uninit: function()
  {
    var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
    obs.removeObserver(this, "content-document-global-created");
  },
};

const NSGetFactory = XPCOMUtils.generateNSGetFactory([DOMFuzzHelper]);

/*****************************
 * MISC PRIVILEGED FUNCTIONS *
 *****************************/

function runSoon(f)
{
  var tm = Components.classes["@mozilla.org/thread-manager;1"]
             .getService(Components.interfaces.nsIThreadManager);

  tm.mainThread.dispatch({
    run: function() {
      f();
    }
  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
}

function enableAccessibility()
{
  try {
    Components.classes["@mozilla.org/accessibilityService;1"]
      .getService(Components.interfaces.nsIAccessibleRetrieval);
    dump("Enabled accessibility!\n");
  } catch(e) {
    dump("Couldn't enable accessibility: " + e + "\n");
  }
}

function sendMemoryPressureNotification()
{
  var os = Components.classes["@mozilla.org/observer-service;1"]
           .getService(Components.interfaces.nsIObserverService);
  os.notifyObservers(null, "memory-pressure", "heap-minimize");
}

function cycleCollect(window)
{
  return function cycleCollectInner() {
    window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
          .getInterface(Components.interfaces.nsIDOMWindowUtils)
          .garbageCollect();
  }
}

function setZoomLevel(window)
{
  return function setZoomLevelInner(textOrFull, factor) {
    var viewer = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                       .getInterface(Components.interfaces.nsIWebNavigation)
                       .QueryInterface(Components.interfaces.nsIDocShell)
                       .contentViewer
                       .QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);

    if (textOrFull == "text")
      viewer.textZoom = +factor;
    else if (textOrFull == "full")
      viewer.fullZoom = +factor;
  }
}

function printToFile(window)
{
  // Linux: tested, works for PDF and PS, oddly asynchronous.
  // Mac: tested, printToFile is ignored and it goes to a printer!
  // Windows: untested.
  var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
                             .getService(Components.interfaces.nsIXULRuntime);
  if (xulRuntime.OS != "Linux") return function() { };

  var fired = false;

  return function printToFileInner(showHeaders, showBGColor, showBGImages, ps) {
    runSoon(function() {
        // Don't print more than once, it gets messy fast.
        if (fired) { return false; }
        fired = true;

        // Based on https://addons.mozilla.org/en-US/firefox/addon/5971/ by pav and bho

        var webBrowserPrint = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
        .getInterface(Components.interfaces.nsIWebBrowserPrint);

        var nsIPrintSettings = Components.interfaces.nsIPrintSettings;

        var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"]
        .getService(Components.interfaces.nsIPrintSettingsService);

        var printSettings = PSSVC.newPrintSettings;

        var file = Components.classes["@mozilla.org/file/directory_service;1"].
                              getService(Components.interfaces.nsIProperties).
                              get("ProfD", Components.interfaces.nsIFile);
        file.append(ps ? "a.ps" : "a.pdf");
        dumpln("Printing to: " + file.path);

        printSettings.printToFile = true;
        printSettings.toFileName  = file.path;
        printSettings.printSilent = true;
        printSettings.outputFormat = ps ? nsIPrintSettings.kOutputFormatPS : nsIPrintSettings.kOutputFormatPDF;
        printSettings.printBGColors   = !!showBGColor;
        printSettings.printBGImages   = !!showBGImages;
        if (!showHeaders) {
            printSettings.footerStrCenter = '';
            printSettings.footerStrLeft   = '';
            printSettings.footerStrRight  = '';
            printSettings.headerStrCenter = '';
            printSettings.headerStrLeft   = '';
            printSettings.headerStrRight  = '';
        }

        webBrowserPrint.print(printSettings, null);
    });
  }
}

/************************
 * QUIT WITH LEAK CHECK *
 ************************/

var quitting = false;

function quitWithLeakCheck()
{
  if (quitting)
    return;
  quitting = true;

  runSoon(a);
  function a() { dumpln("QA"); closeAllWindows(); runOnTimer(b); dumpln("QAA"); }
  function b() { dumpln("QB"); mpUntilDone(); runSoon(c); }
  function c() { dumpln("QC"); bloatStats(d); }
  function d(objectCounts) {
    dumpln("QD");

    dumpln("Windows: " + objectCounts["nsGlobalWindow"]);
    dumpln("Documents: " + objectCounts["nsDocument"]);

    //if (objectCounts["nsGlobalWindow"] > 4) { dumpln("OMGLEAK"); }
    //if (objectCounts["nsDocument"] > 4) { dumpln("OMGLEAK"); }
    runSoon(e);
  }
  function e() { dumpln("QE"); goQuitApplication(); }
}

function runOnTimer(f)
{
    var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
    timer.initWithCallback({notify: function(){f();}}, 2000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}

function closeAllWindows()
{
  var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                     .getService(Ci.nsIWindowWatcher);
  var enumerator = ww.getWindowEnumerator();

  var windowsToClose = [];

  while (enumerator.hasMoreElements()) {
    windowsToClose.push(enumerator.getNext().QueryInterface(Ci.nsIDOMWindow));
  }

  // if not mac...
  ww.openWindow(null, "about:blank", null, "width=200,height=200", null);

  for (var i = 0; i < windowsToClose.length; ++i) {
    windowsToClose[i].close();
  }

  dumpln("1");
}

function mpUntilDone()
{
    for (var j = 0; j < 10; ++j) {
      dumpln("MP " + j);
      sendMemoryPressureNotification();
    }
}

/*
     |<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->|
                                              Per-Inst   Leaked    Total      Rem      Mean       StdDev     Total      Rem      Mean       StdDev

*/
// Grab the class name and the number of remaining objects.
var bloatRex = /\s*\d+\s+(\S+)\s+\d+\s+\d+\s+\d+\s+(\d+)\s+.*/;
const SET_QUOTA = false;
const USE_QUOTA = false;

function bloatStats(callback)
{
  var objectCounts = {};

  try {
    //d.d.d;
    NetUtil.asyncFetch("about:bloat", fetched);
  } catch(e) {
    dumpln("Can't open about:bloat -- maybe you forgot to use XPCOM_MEM_LEAK_LOG");
    callback(objectCounts);
  }

  function fetched(aInputStream, aResult)
  {
    var r = NetUtil.readInputStreamToString(aInputStream, aInputStream.available());
    var lines = r.split("\n");
    for (var i = 0; i < lines.length; ++i)
    {
      var a = bloatRex.exec(lines[i]);
      if (a) {
        if (SET_QUOTA) {
          dumpln("'" + a[1] + "': " + a[2] + ",");
        } else if (USE_QUOTA) {
          quotaA = QUOTA[a[1]] || 0;
          if (a[2] > quotaA) { dumpln("Leak? Too many " + a[1] + " (" + a[2] + " > " + quotaA + ")"); }
        }
        objectCounts[a[1]] = a[2];
      }
    }
    runSoon(callCallback);
  }

  function callCallback()
  {
    callback(objectCounts)
  }
}

/********
 * QUIT *
 ********/

// From quit.js, which Bob Clary extracted from mozilla/toolkit/content

function canQuitApplication()
{
  var os = Components.classes["@mozilla.org/observer-service;1"]
    .getService(Components.interfaces.nsIObserverService);
  if (!os)
  {
    return true;
  }

  try
 {
    var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
      .createInstance(Components.interfaces.nsISupportsPRBool);
    os.notifyObservers(cancelQuit, "quit-application-requested", null);

    // Something aborted the quit process.
    if (cancelQuit.data)
    {
      return false;
    }
  }
  catch (ex)
  {
  }
  os.notifyObservers(null, "quit-application-granted", null);
  return true;
}

function goQuitApplication()
{
  dumpln("goQuitApplication (js component)");

  if (!canQuitApplication())
  {
    return false;
  }

  var kAppStartup = '@mozilla.org/toolkit/app-startup;1';
  var kAppShell   = '@mozilla.org/appshell/appShellService;1';
  var   appService;
  var   forceQuit;

  if (kAppStartup in Components.classes)
  {
    appService = Components.classes[kAppStartup].
      getService(Components.interfaces.nsIAppStartup);
    forceQuit  = Components.interfaces.nsIAppStartup.eForceQuit;

  }
  else if (kAppShell in Components.classes)
  {
    appService = Components.classes[kAppShell].
      getService(Components.interfaces.nsIAppShellService);
    forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
  }
  else
  {
    throw 'goQuitApplication: no AppStartup/appShell';
  }

  var windowManager = Components.
    classes['@mozilla.org/appshell/window-mediator;1'].getService();

  var windowManagerInterface = windowManager.
    QueryInterface(Components.interfaces.nsIWindowMediator);

  var enumerator = windowManagerInterface.getEnumerator(null);

  while (enumerator.hasMoreElements())
  {
    var domWindow = enumerator.getNext();
    if (("tryToClose" in domWindow) && !domWindow.tryToClose())
    {
      return false;
    }
    domWindow.close();
  }

  try
  {
    appService.quit(forceQuit);
  }
  catch(ex)
  {
    throw('goQuitApplication: ' + ex);
  }

  return true;
}

<|endoftext|>


<commit_before>'use strict';

module.exports = ButtonControl;

var util    = require('util');
var path    = require('path');
var Promise = require('bluebird');

var server   = require('../../../../../server');
var Control  = require('../Control');

util.inherits(ButtonControl, Control);

////////////////////////////////////////////////////////////////////////////////////////////////////
function ButtonControl(data, parent) {
    var self = this;
    ButtonControl.super_.call(self, data, parent);
    self.viewFilePath = path.join(
        server.get('public'),
        'viewer/class/Controller/ModelController/ControlController/ButtonControlController/view',
        self.parent.data['@class'] + this.data['@class'] + 'View.ejs'
    );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
ButtonControl.create = function(data, parent) {
    return Promise.resolve(new ButtonControl(data, parent));
};<commit_msg>ButtonControl<commit_after>'use strict';

var util    = require('util');
var path    = require('path');
var Promise = require('bluebird');

var server   = require('../../../../../server');
var Control  = require('../Control');

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ButtonControl extends Control {

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    constructor(data, parent) {
        super(data, parent);
        var self = this;
        self.viewFilePath = path.join(
            server.get('public'),
            'viewer/class/Controller/ModelController/ControlController/ButtonControlController/view',
            self.parent.data['@class'] + this.data['@class'] + 'View.ejs'
        );
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static async create(data, parent) {
        return new ButtonControl(data, parent);
    }

}

module.exports = ButtonControl;<|endoftext|>


<commit_before>import React, {
  useState, useRef, useEffect, useCallback
} from 'react';
import PropTypes from 'prop-types';
import throttle from 'lodash/throttle';

import Event from '../../utils/helpers/events';
import { StyledAnchorNavigation, StyledNavigation, StyledContent } from './anchor-navigation.style';
import AnchorNavigationItem from './anchor-navigation-item.component';

const SECTION_VISIBILITY_OFFSET = 200;
const SCROLL_THROTTLE = 100;

const AnchorNavigation = ({ children, stickyNavigation, styleOverride }) => {
  const [selectedIndex, setSelectedIndex] = useState(0);

  const sectionRefs = useRef(React.Children.map(stickyNavigation.props.children, child => child.props.target));

  const anchorRefs = useRef(Array.from({
    length: React.Children.count(stickyNavigation.props.children)
  }, () => React.createRef()));

  const contentRef = useRef();

  const navigationRef = useRef();

  const isUserScroll = useRef(true);

  const isUserScrollTimer = useRef();

  const setSelectedAnchorBasedOnScroll = useCallback(() => {
    const sectionsTopOffsets = sectionRefs.current.map(({ current }) => current.getBoundingClientRect().top);
    const { top: navTopOffset } = navigationRef.current.getBoundingClientRect();

    const indexOfSmallestNegativeTopOffset = sectionsTopOffsets.reduce((currentTopIndex, sectionTopOffset, index) => {
      if (sectionTopOffset - SECTION_VISIBILITY_OFFSET > navTopOffset) return currentTopIndex;
      return sectionTopOffset > sectionsTopOffsets[currentTopIndex] ? index : currentTopIndex;
    }, 0);

    setSelectedIndex(indexOfSmallestNegativeTopOffset);
  }, []);

  const scrollHandler = useCallback(throttle(() => {
    if (isUserScroll.current) {
      setSelectedAnchorBasedOnScroll();
    } else {
      window.clearTimeout(isUserScrollTimer.current);
      isUserScrollTimer.current = setTimeout(() => { isUserScroll.current = true; }, SCROLL_THROTTLE + 50);
    }
  }, SCROLL_THROTTLE), []);

  useEffect(() => {
    window.addEventListener('scroll', scrollHandler, true);
    return () => window.removeEventListener('scroll', scrollHandler, true);
  }, [scrollHandler]);

  const focusFirstFocusableChild = (section) => {
    // eslint-disable-next-line max-len
    const defaultFocusableSelectors = 'button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])';
    const firstFocusableElement = section.querySelector(defaultFocusableSelectors);
    if (firstFocusableElement) {
      firstFocusableElement.focus({ preventScroll: true });
    }
  };

  const scrollToSection = (section) => {
    isUserScroll.current = false;
    section.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' });
  };

  const handleClick = (event, index) => {
    event.preventDefault();
    const sectionToScroll = sectionRefs.current[index].current;

    focusFirstFocusableChild(sectionToScroll);

    // workaround due to preventScroll focus method option on firefox not working consistently
    window.setTimeout(() => {
      scrollToSection(sectionToScroll);
      setSelectedIndex(index);
    }, 10);
  };

  const focusNavItem = (event, index) => {
    event.preventDefault();
    let newIndex = index;
    if (index === -1) {
      newIndex = anchorRefs.current.length - 1;
    } else if (index === anchorRefs.current.length) {
      newIndex = 0;
    }
    anchorRefs.current[newIndex].current.focus();
  };

  const handleKeyDown = (event, index) => {
    if (Event.isUpKey(event)) {
      focusNavItem(event, index - 1);
    } else if (Event.isDownKey(event)) {
      focusNavItem(event, index + 1);
    } else if (Event.isEnterKey(event) || Event.isSpaceKey(event)) {
      handleClick(event, index);
    }
  };

  return (
    <StyledAnchorNavigation
      ref={ contentRef }
      data-component='anchor-navigation'
      styleOverride={ styleOverride.root }
    >
      <StyledNavigation
        ref={ navigationRef }
        data-element='anchor-sticky-navigation'
        styleOverride={ styleOverride.navigation }
      >
        {React.Children.map(
          stickyNavigation.props.children,
          (child, index) => React.cloneElement(child, {
            isSelected: index === selectedIndex,
            tabIndex: index === selectedIndex ? 0 : -1,
            onClick: ev => handleClick(ev, index),
            onKeyDown: ev => handleKeyDown(ev, index),
            ref: anchorRefs.current[index]
          })
        )}
      </StyledNavigation>
      <StyledContent styleOverride={ styleOverride.content }>
        {children}
      </StyledContent>
    </StyledAnchorNavigation>
  );
};

AnchorNavigation.propTypes = {
  children: PropTypes.node,
  /** The AnchorNavigationItems components to be rendered in the sticky navigation */
  stickyNavigation: (props, propName, componentName) => {
    let error;
    const prop = props[propName];

    React.Children.forEach(prop.props.children, (child) => {
      if (AnchorNavigationItem.displayName !== child.type.displayName) {
        error = new Error(
          `\`${componentName}\` only accepts children of type \`${AnchorNavigationItem.displayName}\`.`
        );
      }
    });

    return error;
  },
  /** Allows to override existing component styles */
  styleOverride: PropTypes.shape({
    root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
    navigation: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
    content: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
  })
};

AnchorNavigation.defaultProps = {
  styleOverride: {}
};

export default AnchorNavigation;
<commit_msg>refactor(anchor-navigation): add styleOverride deprecation warning<commit_after>import React, {
  useState, useRef, useEffect, useCallback
} from 'react';
import PropTypes from 'prop-types';
import throttle from 'lodash/throttle';

import Event from '../../utils/helpers/events';
import { StyledAnchorNavigation, StyledNavigation, StyledContent } from './anchor-navigation.style';
import AnchorNavigationItem from './anchor-navigation-item.component';
import Logger from '../../utils/logger/logger';

const SECTION_VISIBILITY_OFFSET = 200;
const SCROLL_THROTTLE = 100;

let deprecatedWarnTriggered = false;

const AnchorNavigation = ({ children, stickyNavigation, styleOverride }) => {
  if (!deprecatedWarnTriggered) {
    deprecatedWarnTriggered = true;
    // eslint-disable-next-line max-len
    Logger.deprecate('`styleOverride` that is used in the `AnchorNavigation` component is deprecated and will soon be removed.');
  }
  const [selectedIndex, setSelectedIndex] = useState(0);

  const sectionRefs = useRef(React.Children.map(stickyNavigation.props.children, child => child.props.target));

  const anchorRefs = useRef(Array.from({
    length: React.Children.count(stickyNavigation.props.children)
  }, () => React.createRef()));

  const contentRef = useRef();

  const navigationRef = useRef();

  const isUserScroll = useRef(true);

  const isUserScrollTimer = useRef();

  const setSelectedAnchorBasedOnScroll = useCallback(() => {
    const sectionsTopOffsets = sectionRefs.current.map(({ current }) => current.getBoundingClientRect().top);
    const { top: navTopOffset } = navigationRef.current.getBoundingClientRect();

    const indexOfSmallestNegativeTopOffset = sectionsTopOffsets.reduce((currentTopIndex, sectionTopOffset, index) => {
      if (sectionTopOffset - SECTION_VISIBILITY_OFFSET > navTopOffset) return currentTopIndex;
      return sectionTopOffset > sectionsTopOffsets[currentTopIndex] ? index : currentTopIndex;
    }, 0);

    setSelectedIndex(indexOfSmallestNegativeTopOffset);
  }, []);

  const scrollHandler = useCallback(throttle(() => {
    if (isUserScroll.current) {
      setSelectedAnchorBasedOnScroll();
    } else {
      window.clearTimeout(isUserScrollTimer.current);
      isUserScrollTimer.current = setTimeout(() => { isUserScroll.current = true; }, SCROLL_THROTTLE + 50);
    }
  }, SCROLL_THROTTLE), []);

  useEffect(() => {
    window.addEventListener('scroll', scrollHandler, true);
    return () => window.removeEventListener('scroll', scrollHandler, true);
  }, [scrollHandler]);

  const focusFirstFocusableChild = (section) => {
    // eslint-disable-next-line max-len
    const defaultFocusableSelectors = 'button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])';
    const firstFocusableElement = section.querySelector(defaultFocusableSelectors);
    if (firstFocusableElement) {
      firstFocusableElement.focus({ preventScroll: true });
    }
  };

  const scrollToSection = (section) => {
    isUserScroll.current = false;
    section.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' });
  };

  const handleClick = (event, index) => {
    event.preventDefault();
    const sectionToScroll = sectionRefs.current[index].current;

    focusFirstFocusableChild(sectionToScroll);

    // workaround due to preventScroll focus method option on firefox not working consistently
    window.setTimeout(() => {
      scrollToSection(sectionToScroll);
      setSelectedIndex(index);
    }, 10);
  };

  const focusNavItem = (event, index) => {
    event.preventDefault();
    let newIndex = index;
    if (index === -1) {
      newIndex = anchorRefs.current.length - 1;
    } else if (index === anchorRefs.current.length) {
      newIndex = 0;
    }
    anchorRefs.current[newIndex].current.focus();
  };

  const handleKeyDown = (event, index) => {
    if (Event.isUpKey(event)) {
      focusNavItem(event, index - 1);
    } else if (Event.isDownKey(event)) {
      focusNavItem(event, index + 1);
    } else if (Event.isEnterKey(event) || Event.isSpaceKey(event)) {
      handleClick(event, index);
    }
  };

  return (
    <StyledAnchorNavigation
      ref={ contentRef }
      data-component='anchor-navigation'
      styleOverride={ styleOverride.root }
    >
      <StyledNavigation
        ref={ navigationRef }
        data-element='anchor-sticky-navigation'
        styleOverride={ styleOverride.navigation }
      >
        {React.Children.map(
          stickyNavigation.props.children,
          (child, index) => React.cloneElement(child, {
            isSelected: index === selectedIndex,
            tabIndex: index === selectedIndex ? 0 : -1,
            onClick: ev => handleClick(ev, index),
            onKeyDown: ev => handleKeyDown(ev, index),
            ref: anchorRefs.current[index]
          })
        )}
      </StyledNavigation>
      <StyledContent styleOverride={ styleOverride.content }>
        {children}
      </StyledContent>
    </StyledAnchorNavigation>
  );
};

AnchorNavigation.propTypes = {
  children: PropTypes.node,
  /** The AnchorNavigationItems components to be rendered in the sticky navigation */
  stickyNavigation: (props, propName, componentName) => {
    let error;
    const prop = props[propName];

    React.Children.forEach(prop.props.children, (child) => {
      if (AnchorNavigationItem.displayName !== child.type.displayName) {
        error = new Error(
          `\`${componentName}\` only accepts children of type \`${AnchorNavigationItem.displayName}\`.`
        );
      }
    });

    return error;
  },
  /** Allows to override existing component styles */
  styleOverride: PropTypes.shape({
    root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
    navigation: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
    content: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
  })
};

AnchorNavigation.defaultProps = {
  styleOverride: {}
};

export default AnchorNavigation;
<|endoftext|>


<commit_before>import React from 'react';
import { DragDropContext } from 'react-dnd';
import DraggableContext from './draggable-context';

fdescribe('DraggableContext', () => {

  it('is wrapped in a DragDropContextContainer', () => {
    expect(DraggableContext.name).toBe('DragDropContextContainer');
  });

  it('has a DecoratedComponent pointing to the original component', () => {
    expect(DraggableContext.DecoratedComponent.name).toBe('DraggableContext');
  });
});
<commit_msg>Add test that child nodes are rendered.<commit_after>import React from 'react';
import { DragDropContext } from 'react-dnd';
import DraggableContext from './draggable-context';
import { mount } from 'enzyme';

describe('DraggableContext', () => {

  it('is wrapped in a DragDropContextContainer', () => {
    expect(DraggableContext.name).toBe('DragDropContextContainer');
  });

  it('has a DecoratedComponent pointing to the original component', () => {
    expect(DraggableContext.DecoratedComponent.name).toBe('DraggableContext');
  });

  describe('render', () => {
    it('renders this.props.children', () => {
      let wrapper = mount(
        <DraggableContext>

One

Two

        </DraggableContext>
      );

      expect(wrapper.find('div').length).toEqual(1);
      expect(wrapper.find('p').length).toEqual(2);
    });
  });
});
<|endoftext|>


<commit_before>// C O R E  server
var http = require('http')
, Router = require('./_route')
, surv = require('./_surv')
, bricoleur = require('./_brico')
, provision = require('./_prov')
, shoe = require('shoe');

var routes = [{url:"/",file:"./_wilds/frame.html"},{url:"/bundle.min.js",file:"./_wilds/bundle.min.js"}];
var router = new Router(routes);
var server = http.createServer(router.handleRoutes);
server.listen(8888);

// handle somekind of user model

var brico = new bricoleur();
var survey = new surv({dir:'./_wilds'});

survey.scan(function(map){
  // also compile / prep for client side
  brico.init(map);
  var prov = new provision({
    src : ['./_wilds/core.js'],
    dst : './_wilds/bundle.min.js',
    compress : true
  }, function (msg) {
    console.log(msg);
  }); // compile client side....
});

var sock = shoe(function(stream){
  stream.pipe(brico.stream).pipe(stream);
});
sock.install(server, '/bus');
sock.on('connection', function(conn) {
  // trigger create streams func in brico
});
<commit_msg>added _brico client side<commit_after>// C O R E  server
var http = require('http')
, Router = require('./_route')
, surv = require('./_surv')
, bricoleur = require('./_brico')
, provision = require('./_prov')
, shoe = require('shoe');

var routes = [{url:"/",file:"./_wilds/frame.html"},{url:"/bundle.min.js",file:"./_wilds/bundle.min.js"}];
var router = new Router(routes);
var server = http.createServer(router.handleRoutes);
server.listen(8888);

var brico = new bricoleur();
var survey = new surv({dir:'./_wilds'});

survey.scan(function(map){
  brico.init(map);
});

var prov = new provision({
  src : ['./_brico.js','./_wilds/core.js'],
  dst : './_wilds/bundle.min.js',
  compress : true
}, function (msg) {
  console.log(msg);
});

var sock = shoe(function(stream){
  stream.pipe(brico.stream).pipe(stream);
});
sock.install(server, '/bus');
sock.on('connection', function(conn) { // trigger create streams func in brico
});
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    'use strict';

    grunt.registerMultiTask('swagger-js-codegen', 'Swagger codegen for Javascript', function(){
        var fs = require('fs');
        var CodeGen = require('swagger-js-codegen').CodeGen;
        var request = require('request');
        var Q = require('q');
        var _ = require('lodash');

        var options = this.options();
        var dest = options.dest;
        var promises = [];
        var done = this.async();

        grunt.file.mkdir(dest);
        options.apis.forEach(function(api){
            var deferred = Q.defer();
            var fname = api.fileName || api.moduleName || api.className;
            if(api.swagger.substring(0, 'http://'.length) === 'http://' || api.swagger.substring(0, 'https://'.length) === 'https://') {
                request({
                    uri: api.swagger,
                    method: 'GET'
                }, function(error, response, body){
                    if(error || response.statusCode !== 200) {
                        deferred.reject('Error while fetching ' + api.swagger + ': ' + (error || body));
                    } else {
                        var swagger = JSON.parse(body),
                            source = null;

                        if (api.type === 'angular' || api.angularjs === true) {
                            source = CodeGen.getAngularCode({ moduleName: api.moduleName, className: api.className, swagger: swagger });
                        } else if (api.custom === true) {
                            source = CodeGen.getCustomCode({ className: api.className, template: api.template, swagger: swagger });
                        } else {
                            source = CodeGen.getNodeCode({ className: api.className, swagger: swagger });
                        }
                        grunt.log.writeln('Generated ' + fname + ' from ' + api.swagger);
                        fs.writeFileSync(dest + '/' + fname, source, 'UTF-8');
                        deferred.resolve();
                    }
                });
            } else {
                fs.readFile(api.swagger, 'UTF-8', function(err, data){
                    if(err) {
                        deferred.reject(err);
                    } else {
                        var swagger = JSON.parse(data),
                            source = null;

                        if (api.type === 'angular' || api.angularjs === true) {
                            source = CodeGen.getAngularCode({ moduleName: api.moduleName, className: api.className, swagger: swagger });
                        } else if (api.custom === true) {
                            source = CodeGen.getCustomCode({ className: api.className, template: api.template, swagger: swagger });
                        } else {
                            source = CodeGen.getNodeCode({ className: api.className, swagger: swagger });
                        }
                        grunt.log.writeln('Generated ' + fname + ' from ' + api.swagger);
                        fs.writeFileSync(dest + '/' + fname, source, 'UTF-8');
                        deferred.resolve();
                    }
                });
            }
            promises.push(deferred.promise);
        });
        Q.all(promises).then(function(){
            done();
        }).catch(function(error){
            var e;
            if(_.isObject(error) && error.body) {
                e = JSON.stringify(error.body, null, 2);
            } else if(_.isObject(error)) {
                e = JSON.stringify(error, null, 2);
            } else if(error instanceof Error || _.isString(error)) {
                e = error;
            } else {
                e = new Error('Unknown error');
            }
            grunt.fail.fatal(e);
        });
    });
};
<commit_msg>Implicit .js extension if no fileName provided<commit_after>module.exports = function (grunt) {
    'use strict';

    grunt.registerMultiTask('swagger-js-codegen', 'Swagger codegen for Javascript', function(){
        var fs = require('fs');
        var CodeGen = require('swagger-js-codegen').CodeGen;
        var request = require('request');
        var Q = require('q');
        var _ = require('lodash');

        var options = this.options();
        var dest = options.dest;
        var promises = [];
        var done = this.async();

        grunt.file.mkdir(dest);
        options.apis.forEach(function(api){
            var deferred = Q.defer();
            var fname = api.fileName || (api.moduleName || api.className) + '.js';
            if(api.swagger.substring(0, 'http://'.length) === 'http://' || api.swagger.substring(0, 'https://'.length) === 'https://') {
                request({
                    uri: api.swagger,
                    method: 'GET'
                }, function(error, response, body){
                    if(error || response.statusCode !== 200) {
                        deferred.reject('Error while fetching ' + api.swagger + ': ' + (error || body));
                    } else {
                        var swagger = JSON.parse(body),
                            source = null;

                        if (api.type === 'angular' || api.angularjs === true) {
                            source = CodeGen.getAngularCode({ moduleName: api.moduleName, className: api.className, swagger: swagger });
                        } else if (api.custom === true) {
                            source = CodeGen.getCustomCode({ className: api.className, template: api.template, swagger: swagger });
                        } else {
                            source = CodeGen.getNodeCode({ className: api.className, swagger: swagger });
                        }
                        grunt.log.writeln('Generated ' + fname + ' from ' + api.swagger);
                        fs.writeFileSync(dest + '/' + fname, source, 'UTF-8');
                        deferred.resolve();
                    }
                });
            } else {
                fs.readFile(api.swagger, 'UTF-8', function(err, data){
                    if(err) {
                        deferred.reject(err);
                    } else {
                        var swagger = JSON.parse(data),
                            source = null;

                        if (api.type === 'angular' || api.angularjs === true) {
                            source = CodeGen.getAngularCode({ moduleName: api.moduleName, className: api.className, swagger: swagger });
                        } else if (api.custom === true) {
                            source = CodeGen.getCustomCode({ className: api.className, template: api.template, swagger: swagger });
                        } else {
                            source = CodeGen.getNodeCode({ className: api.className, swagger: swagger });
                        }
                        grunt.log.writeln('Generated ' + fname + ' from ' + api.swagger);
                        fs.writeFileSync(dest + '/' + fname, source, 'UTF-8');
                        deferred.resolve();
                    }
                });
            }
            promises.push(deferred.promise);
        });
        Q.all(promises).then(function(){
            done();
        }).catch(function(error){
            var e;
            if(_.isObject(error) && error.body) {
                e = JSON.stringify(error.body, null, 2);
            } else if(_.isObject(error)) {
                e = JSON.stringify(error, null, 2);
            } else if(error instanceof Error || _.isString(error)) {
                e = error;
            } else {
                e = new Error('Unknown error');
            }
            grunt.fail.fatal(e);
        });
    });
};
<|endoftext|>


<commit_before>function addMessage(to_dl_id, from_dl_id, subject, link, content, done) {
	if(to_dl_id == null || from_dl_id == null || subject == null) {
		return -1;
	}
	var uid = getDL_id();
	var auth = getToken();
	var type = "message";
	addActivity({'uid': uid, 'auth':auth, 'to_dl_id':to_dl_id, 'from_dl_id':from_dl_id,
   'type':type, 'subject': subject, 'content':content, 'link':link},
   function(data){
      success(data);
      done();
  });
}

function addCommentToMessage(message_id, comment){
    if (comment==null || message_id==null){
      return -1;
    }
    var uid = getDL_id();
    var auth = getToken();
    var opts = {uid: uid, auth: auth, comment: comment,activity_id:message_id, dl_id:uid};
    var url = "comments";
    addCommentRest(opts,url,function(data) {
      result = data;
      success(data);
    },
    function(data) {
      result = data;
      error(data);
    });
}

function addEvent(to_dl_id, from_dl_id, subject, link, content, time_from, time_to, location, sub_type) {
  if(to_dl_id == null || from_dl_id == null || subject == null) {
    return -1;
  }
  var uid = getDL_id();
  var auth = getToken();
  var type = "cal";
  addActivity({'uid': uid, 'auth':auth, 'to_dl_id':to_dl_id, 'from_dl_id':from_dl_id, 'type':type, 'subject': subject,
               'content':content, 'link':link, 'time_from':time_from, 'time_to':time_to, 'location':location, 'sub_type':sub_type});

}

function getStream(opts,done){

    getActivityStream(opts,function(stream){
      var items =[];
      var dlids= [];
      var userHash={};

      //error retrieving the activity stream
      if(getStatus()!=1 || stream=="" || stream.responseText=="") {
        done(items);
      } else {
        /*
        Capture unique dlids from stream for retrieval of user data.
        */
        $.each(stream, function(i, item) {
              dlids.push(item.DL_id);
              dlids.push(item.from_DL_id);
        });
        dlids = $.unique(dlids);
        //Retrieve user data
        var users = {'uid': getDL_id(), 'auth': getToken(), 'dl_ids': dlids.join()};
        getUserArray(users,function(json){
        userHash=myHash(json);
        //parse and push each json entry into its own
 block
        $.each(stream, function(i, item) {
              items.push(parseItem(item, userHash, item.type));
        });

        done(items);
        });
      }
    //append
 blocks to appropriate container

    });
}

function getOtherStream(types,dlid,done) {
    var opts = {'uid': getDL_id(), 'auth': getToken(), 'offset': 0, 'limit': 15, 'types': types+',', 'dlid':dlid};
    getStream(opts,done);
}

function getOwnStream(types,done) {
    var opts = {'uid': getDL_id(), 'auth': getToken(), 'offset': 0, 'limit': 15, 'types': types, 'stream': true, 'dlid':dlid};
    getStream(opts,done);

}

function myHash(json) {
    var hash = {};
    $.each(json, function(i, item) {
        hash[item.DL_id]=item;
    });

    return hash;
}

function showMessages() {
    var messages=getOwnStream("message");
    if (messages !="") {
        $("#thelist").replaceWith("
" + messages.join('') + "
")
    }
    return messages;
}

function parseItem(item, userHash, type) {
    if(item==undefined || item==null || item=="" || $.isEmptyObject(userHash) || type==undefined || type==null || type=="" ) {
      return "";
    }
    var entry = "

"
                + ""
                + "

" +userHash[item.from_DL_id].name;

    if(item.DL_id != null && item.DL_id != undefined && item.DL_id != "" && item.DL_id != item.from_DL_id) {
        entry += ">>> " + userHash[item.DL_id].name;
    }
    entry += "

";
    if(type == "cal" && item.time_from != "0000-00-00 00:00:00"){
      entry += "
"+item.time_from+"
";
    }

    entry += "
"
          + "
" + item.subject + "
";

    if(item.content != null && item.content != undefined) {
        entry += "
" + item.content.substr(0,20);
    }

    entry += "

";

    return entry;
}

function datetimetoDate(date) {
	var year = date.substr(0,4);
	var month = date.substr(5,2);
	var day = date.substr(8,2);
	return "" + day + "." + month + "." + year;
}

function datetimetoTime(date) {
	return date.substr(11,5);
}
<commit_msg>dlid pois<commit_after>function addMessage(to_dl_id, from_dl_id, subject, link, content, done) {
	if(to_dl_id == null || from_dl_id == null || subject == null) {
		return -1;
	}
	var uid = getDL_id();
	var auth = getToken();
	var type = "message";
	addActivity({'uid': uid, 'auth':auth, 'to_dl_id':to_dl_id, 'from_dl_id':from_dl_id,
   'type':type, 'subject': subject, 'content':content, 'link':link},
   function(data){
      success(data);
      done();
  });
}

function addCommentToMessage(message_id, comment){
    if (comment==null || message_id==null){
      return -1;
    }
    var uid = getDL_id();
    var auth = getToken();
    var opts = {uid: uid, auth: auth, comment: comment,activity_id:message_id, dl_id:uid};
    var url = "comments";
    addCommentRest(opts,url,function(data) {
      result = data;
      success(data);
    },
    function(data) {
      result = data;
      error(data);
    });
}

function addEvent(to_dl_id, from_dl_id, subject, link, content, time_from, time_to, location, sub_type) {
  if(to_dl_id == null || from_dl_id == null || subject == null) {
    return -1;
  }
  var uid = getDL_id();
  var auth = getToken();
  var type = "cal";
  addActivity({'uid': uid, 'auth':auth, 'to_dl_id':to_dl_id, 'from_dl_id':from_dl_id, 'type':type, 'subject': subject,
               'content':content, 'link':link, 'time_from':time_from, 'time_to':time_to, 'location':location, 'sub_type':sub_type});

}

function getStream(opts,done){

    getActivityStream(opts,function(stream){
      var items =[];
      var dlids= [];
      var userHash={};

      //error retrieving the activity stream
      if(getStatus()!=1 || stream=="" || stream.responseText=="") {
        done(items);
      } else {
        /*
        Capture unique dlids from stream for retrieval of user data.
        */
        $.each(stream, function(i, item) {
              dlids.push(item.DL_id);
              dlids.push(item.from_DL_id);
        });
        dlids = $.unique(dlids);
        //Retrieve user data
        var users = {'uid': getDL_id(), 'auth': getToken(), 'dl_ids': dlids.join()};
        getUserArray(users,function(json){
        userHash=myHash(json);
        //parse and push each json entry into its own
 block
        $.each(stream, function(i, item) {
              items.push(parseItem(item, userHash, item.type));
        });

        done(items);
        });
      }
    //append
 blocks to appropriate container

    });
}

function getOtherStream(types,dlid,done) {
    var opts = {'uid': getDL_id(), 'auth': getToken(), 'offset': 0, 'limit': 15, 'types': types+',', 'dlid':dlid};
    getStream(opts,done);
}

function getOwnStream(types,done) {
    var opts = {'uid': getDL_id(), 'auth': getToken(), 'offset': 0, 'limit': 15, 'types': types, 'stream': true};
    getStream(opts,done);

}

function myHash(json) {
    var hash = {};
    $.each(json, function(i, item) {
        hash[item.DL_id]=item;
    });

    return hash;
}

function showMessages() {
    var messages=getOwnStream("message");
    if (messages !="") {
        $("#thelist").replaceWith("
" + messages.join('') + "
")
    }
    return messages;
}

function parseItem(item, userHash, type) {
    if(item==undefined || item==null || item=="" || $.isEmptyObject(userHash) || type==undefined || type==null || type=="" ) {
      return "";
    }
    var entry = "

"
                + ""
                + "

" +userHash[item.from_DL_id].name;

    if(item.DL_id != null && item.DL_id != undefined && item.DL_id != "" && item.DL_id != item.from_DL_id) {
        entry += ">>> " + userHash[item.DL_id].name;
    }
    entry += "

";
    if(type == "cal" && item.time_from != "0000-00-00 00:00:00"){
      entry += "
"+item.time_from+"
";
    }

    entry += "
"
          + "
" + item.subject + "
";

    if(item.content != null && item.content != undefined) {
        entry += "
" + item.content.substr(0,20);
    }

    entry += "

";

    return entry;
}

function datetimetoDate(date) {
	var year = date.substr(0,4);
	var month = date.substr(5,2);
	var day = date.substr(8,2);
	return "" + day + "." + month + "." + year;
}

function datetimetoTime(date) {
	return date.substr(11,5);
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	List = mongoose.model('List'),
	Users = mongoose.model('User'),
	_ = require('lodash');

/**
 * Reads all the sublists for the given list
 */
exports.getLists = function(req, res) {
	List.find().populate('user', 'username').exec(function(err, lists) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(lists);
		}
	});
};

/**
 * Creates a list for the current username
 */
exports.create = function(req, res) {
	var list = new List(req.body);
	list.user = req.user;

	// For some reason the server likes to insert escape characters here, so we
	// must remove them manually. Step 1, convert to string.
	var workingJson = JSON.stringify(list.access);

	// Removing all backslashes, they can't be in emails.
	workingJson = workingJson.replace("\\", "");

	// Removing the first and second-to-last character; these are unnecessary
	// quotes.
	workingJson = workingJson.replace("\"\"", "\"");
  var workingJsonArray = workingJson.split(", ");

	list.access = JSON.parse(workingJsonArray);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Update a list by ID
 */
exports.update = function(req, res) {
	var list = req.list;

 	list = _.extend(list, req.body);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Remove a list by ID
 */
exports.remove = function(req, res) {
	var list = req.list;

	list.remove(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

exports.rootID = function(req, res, username) {
	Users.find().exec(function(err, users) {
		if (err) {
			return res.status(404).send({
				message: 'Could not find any users'
			});
		}
		// Array of references to all root lists
		var allUsers = users.map(function(user) { return user._id; });

		List.findOne({$and: [{user: {$in: allUsers}}, {root: true}]}, function(err, doc) {
			if (err || doc == null) {
				return res.status(404).send({
					message: 'Root list not found'
				});
			}
			res.send(doc._id);
		});
	});
};

/**
 * Gets a single List based on its ID
 */
exports.getListByID = function(req, res, next, id) {
	if (!mongoose.Types.ObjectId.isValid(id)) {
		return res.status(400).send({
			message: 'Requested list is invalid'
		});
	}

	List.findById(id).exec(function(err, list) {
		if (err) return next(err);
		if (!list) {
			return res.status(404).send({
				message: 'List not found'
			});
		}
		req.list = list;
		next();
	});
};

/**
 * Returns the current level of authorization of the validated user
 */
exports.hasAuthorization = function(req, res, next) {
	next();
};
<commit_msg>Fixing query<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	List = mongoose.model('List'),
	Users = mongoose.model('User'),
	_ = require('lodash');

/**
 * Reads all the sublists for the given list
 */
exports.getLists = function(req, res) {
	List.find().populate('user', 'username').exec(function(err, lists) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(lists);
		}
	});
};

/**
 * Creates a list for the current username
 */
exports.create = function(req, res) {
	var list = new List(req.body);
	list.user = req.user;

	// For some reason the server likes to insert escape characters here, so we
	// must remove them manually. Step 1, convert to string.
	var workingJson = JSON.stringify(list.access);

	// Removing all backslashes, they can't be in emails.
	workingJson = workingJson.replace("\\", "");

	// Removing the first and second-to-last character; these are unnecessary
	// quotes.
	workingJson = workingJson.replace("\"\"", "\"");
  var workingJsonArray = workingJson.split(", ");

	list.access = JSON.parse(workingJsonArray);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Update a list by ID
 */
exports.update = function(req, res) {
	var list = req.list;

 	list = _.extend(list, req.body);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Remove a list by ID
 */
exports.remove = function(req, res) {
	var list = req.list;

	list.remove(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

exports.rootID = function(req, res, username) {
	Users.find().exec(function(err, users) {
		if (err) {
			return res.status(404).send({
				message: 'Could not find any users'
			});
		}
		// Array of references to all root lists
		var allUsers = users.map(function(user) { return user._id; });

		List.findOne({$and: [{user: {$in: allUsers}}, {root: true}]}).exec(function(err, doc) {
			if (err || doc == null) {
				return res.status(404).send({
					message: 'Root list not found'
				});
			}
			res.send(doc._id);
		});
	});
};

/**
 * Gets a single List based on its ID
 */
exports.getListByID = function(req, res, next, id) {
	if (!mongoose.Types.ObjectId.isValid(id)) {
		return res.status(400).send({
			message: 'Requested list is invalid'
		});
	}

	List.findById(id).exec(function(err, list) {
		if (err) return next(err);
		if (!list) {
			return res.status(404).send({
				message: 'List not found'
			});
		}
		req.list = list;
		next();
	});
};

/**
 * Returns the current level of authorization of the validated user
 */
exports.hasAuthorization = function(req, res, next) {
	next();
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	List = mongoose.model('List'),
	Users = mongoose.model('User'),
	_ = require('lodash');

/**
 * Reads all the sublists for the given list
 */
exports.getLists = function(req, res) {
	List.find().populate('user', 'username').exec(function(err, lists) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(lists);
		}
	});
};

/**
 * Creates a list for the current username
 */
exports.create = function(req, res) {
	var list = new List(req.body);
	list.user = req.user;

	// For some reason the server likes to insert escape characters here, so we
	// must remove them manually. Step 1, convert to string.
	var workingJson = JSON.stringify(list.access);

	// Removing all backslashes, they can't be in emails.
	workingJson = workingJson.replace("\\", "");

	// Removing the first and second-to-last character; these are unnecessary
	// quotes.
	workingJson = workingJson.replace("\"\"", "\"");
  var workingJsonArray = workingJson.split(", ");

	list.access = JSON.parse(workingJsonArray);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Update a list by ID
 */
exports.update = function(req, res) {
	var list = req.list;

 	list = _.extend(list, req.body);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Remove a list by ID
 */
exports.remove = function(req, res) {
	var list = req.list;

	list.remove(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

exports.rootID = function(req, res, username) {
	Users.find().exec(function(err, users) {
		if (err) {
			return res.status(404).send({
				message: 'Could not find any users'
			});
		}
		// Array of references to all root lists
		var allUsers = users.map(function(user) { return user._id; });

		List.findOne({$and: [{user: {$in: allUsers}}, {root: true}]}).exec(function(err, doc) {
			if (err || doc == null) {
				return res.status(404).send({
					message: 'Root list not found'
				});
			}
			res.send(doc._id);
		});
	});
};

/**
 * Gets a single List based on its ID
 */
exports.getListByID = function(req, res, next, id) {
	if (!mongoose.Types.ObjectId.isValid(id)) {
		return res.status(400).send({
			message: 'Requested list is invalid'
		});
	}

	List.findById(id).exec(function(err, list) {
		if (err) return next(err);
		if (!list) {
			return res.status(404).send({
				message: 'List not found'
			});
		}
		req.list = list;
		next();
	});
};

/**
 * Returns the current level of authorization of the validated user
 */
exports.hasAuthorization = function(req, res, next) {
	next();
};
<commit_msg>Authorization fix<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	List = mongoose.model('List'),
	Users = mongoose.model('User'),
	_ = require('lodash');

/**
 * Reads all the sublists for the given list
 */
exports.getLists = function(req, res) {
	List.find().populate('user', 'username').exec(function(err, lists) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(lists);
		}
	});
};

/**
 * Creates a list for the current username
 */
exports.create = function(req, res) {
	var list = new List(req.body);
	list.user = req.user;

	// For some reason the server likes to insert escape characters here, so we
	// must remove them manually. Step 1, convert to string.
	var workingJson = JSON.stringify(list.access);

	// Removing all backslashes, they can't be in emails.
	workingJson = workingJson.replace("\\", "");

	// Removing the first and second-to-last character; these are unnecessary
	// quotes.
	workingJson = workingJson.replace("\"\"", "\"");
  var workingJsonArray = workingJson.split(", ");

	list.access = JSON.parse(workingJsonArray);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Update a list by ID
 */
exports.update = function(req, res) {
	var list = req.list;

 	list = _.extend(list, req.body);

	list.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

/**
 * Remove a list by ID
 */
exports.remove = function(req, res) {
	var list = req.list;

	list.remove(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.json(list);
		}
	});
};

exports.rootID = function(req, res, username) {
	Users.find().exec(function(err, users) {
		if (err) {
			return res.status(404).send({
				message: 'Could not find any users'
			});
		}
		// Array of references to all root lists
		var allUsers = users.map(function(user) { return user._id; });

		List.findOne({$and: [{user: {$in: allUsers}}, {root: true}]}).exec(function(err, doc) {
			if (err || doc == null) {
				return res.status(404).send({
					message: 'Root list not found'
				});
			}
			res.send(doc._id);
		});
	});
};

/**
 * Gets a single List based on its ID
 */
exports.getListByID = function(req, res, next, id) {
	if (!mongoose.Types.ObjectId.isValid(id)) {
		return res.status(400).send({
			message: 'Requested list is invalid'
		});
	}

	List.findById(id).exec(function(err, list) {
		if (err) return next(err);
		if (!list) {
			return res.status(404).send({
				message: 'List not found'
			});
		}
		req.list = list;
		next();
	});
};

/**
 * Returns the current level of authorization of the validated user
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.list.user.id !== req.user.id) {
		return res.status(403).send({
			message: 'User is not authorized'
		});
	}
	next();
};
<|endoftext|>