<commit_before>define(["dojo/_base/declare", "ppwcode-util-contracts/_Mixin", "dojo/_base/lang", "dijit/registry", "dojo/dom-class",
        "dijit/_WidgetBase", "../../SemanticObject",
        "dijit/form/ValidationTextBox", "dojox/mvc/Output", "dojox/form/CheckedMultiSelect", "dijit/form/SimpleTextarea",
         "dijit/form/CheckBox",
         "xstyle/css!./_SemanticObjectPane.css"],
    function(declare, _ContractMixin, lang, registry, domClass,
             _WidgetBase, SemanticObject,
             ValidationTextBox, Output, CheckedMultiSelect, SimpleTextarea,
             CheckBox) {

      var presentationModes = [
        // presentationMode and stylePresentationMode for viewing the data. No interaction allowed.
        "VIEW",

        // presentationMode and stylePresentationMode for editing the data. Interaction allowed.
        "EDIT",

        // presentationMode and stylePresentationMode while the SemanticObject is busy. No interaction allowed.
        "BUSY",

        // presentationMode and stylePresentationMode representing unacceptable data (the object is
        // not civilized, or we have other means of knowing the data is unacceptable).
        // Interaction must be allowed to reset the object, or ammeliorate the data/
        // This means this is a sub-state of EDIT.
        "WILD",

        // presentationMode and stylePresentationMode representing an error occured. We cannot proceed. The widget
        // and its object must be destroyed.
        "ERROR"];

      var stylePresentationModes = presentationModes.slice(0); // copy
      // stylePresentationMode for when there is no target
      stylePresentationModes.push("NOTARGET");

      function setStylepresentationMode(sop, stylePresentationMode) {
        var domNode = sop.get("domNode");
        var innerWidgets = registry.findWidgets(domNode);
        var widgetState = null;
        //noinspection FallthroughInSwitchStatementJS
        switch (stylePresentationMode) {
          case _SemanticObjectPane.prototype.NOTARGET:
            widgetState = { readOnly:false, disabled:true };
            break;
          case _SemanticObjectPane.prototype.EDIT:
          case _SemanticObjectPane.prototype.WILD:
            widgetState = { readOnly:false, disabled:false };
            break;
          case _SemanticObjectPane.prototype.BUSY:
          case _SemanticObjectPane.prototype.ERROR:
            widgetState = { readOnly:false, disabled:true };
            break;
          default: // VIEW
            widgetState = { readOnly:true, disabled:false };
        }
        innerWidgets.forEach(function (w) {
          if (w.isInstanceOf(ValidationTextBox) || w.isInstanceOf(Output)
              || w.isInstanceOf(CheckedMultiSelect) || w.isInstanceOf(SimpleTextarea) || w.isInstanceOf(CheckBox)) {
            w.set("readOnly", widgetState.readOnly);
            w.set("disabled", widgetState.disabled);
          }
        });
        if (stylePresentationMode == _SemanticObjectPane.prototype.VIEW ||
            stylePresentationMode == _SemanticObjectPane.prototype.EDIT) {
          domClass.replace(domNode,
            "SemanticObjectPane_enabled",
            "SemanticObjectPane_busy SemanticObjectPane_wild SemanticObjectPane_disabled SemanticObjectPane_error SemanticObjectPane_notarget");
        }
        else if (stylePresentationMode == _SemanticObjectPane.prototype.BUSY) {
          domClass.replace(domNode,
            "SemanticObjectPane_busy",
            "SemanticObjectPane_enabled SemanticObjectPane_wild SemanticObjectPane_disabled SemanticObjectPane_error SemanticObjectPane_notarget");
        }
        else if (stylePresentationMode == _SemanticObjectPane.prototype.WILD) {
          domClass.replace(domNode,
            "SemanticObjectPane_wild",
            "SemanticObjectPane_enabled SemanticObjectPane_busy SemanticObjectPane_disabled SemanticObjectPane_error SemanticObjectPane_notarget");
        }
        else if (stylePresentationMode == _SemanticObjectPane.prototype.ERROR) {
          domClass.replace(domNode,
            "SemanticObjectPane_error",
            "SemanticObjectPane_enabled SemanticObjectPane_busy SemanticObjectPane_wild SemanticObjectPane_disabled SemanticObjectPane_notarget");
        }
        else { // NOTARGET
          domClass.replace(domNode,
            " SemanticObjectPane_notarget",
            "SemanticObjectPane_enabled SemanticObjectPane_busy SemanticObjectPane_wild SemanticObjectPane_error SemanticObjectPane_disabled");
        }
      }

      var _SemanticObjectPane = declare([_WidgetBase, _ContractMixin], {
        // summary:
        //   Widget that represents a SemanticObject in detail, and that gives the opportunity
        //   to the user the view the details, edit the details, and create a new object.
        //   Abstract class to be extended for particular subtypes of SemanticObject.
        // description:
        //   What is common to all subtypes is that the widget:
        //   - has a `target` that is a SemanticObject; getTargetType() returns the top-most supported
        //     Constructor of supported targets. All targets must be instances of this type.
        //   - has an `presentationMode` (view, edit, busy, wild, error)
        //   - has a `stylePresentationMode`
        //
        //   The representation should reflect the presentationMode in a clear visual way to the user.
        //   This is the `stylePresentationModel`. It is the `presentationMode` if `target !== null`,
        //   and `NOTARGET` otherwise.
        //   Even when the information shown is completely read-only, widgets should extend
        //   this class, to change the representation of the displayed information consistently
        //   with other information in different presentationModes, e.g., in "busy" mode.
        //   The available presentation modes are defined in _SemanticObjectPane.prototype.presentationModes.
        //
        //   Instances can be wrapped around zero or more _SemanticObjectPanes, recursively (no loops!).
        //   We take care of propagating `presentationMode`. Subclasses need to override
        //   getWrappedDetails to return the wrapped details. All instances need to be instances of this class.
        //   The default implementation returns an empty array.
        //   The target of a wrapped detail might be the same target as our target, but it might be
        //   another related object, of a different type. set("target", ...) will call _propagateTarget, which is
        //   chained, so that subclasses can add propagation of setting the target. Our implementation only sets our
        //   target.
        //
        //   This class is concerned with presentation. Other classes might add presentation
        //   and functionality to support interaction with the user (save and cancel buttons, etc. -
        //   see e.g. ppwcode persistence).

        _c_invar: [
          function() {return this.get("presentationMode");},
          function() {return this.presentationModes.indexOf(this.get("presentationMode")) >= 0;},
          function() {return this.getTargetType() != null;},
          // TODO getTargetType is a subtype of SemanticObject
          function() {return this.get("target") == null ||
                        (this.get("target").isInstanceOf && this.get("target").isInstanceOf(this.getTargetType()));},
          function() {return this.get("stylePresentationMode");},
          function() {return this.stylePresentationModes.indexOf(this.get("stylePresentationMode")) >= 0;},
          function() {return (this.get("stylePresentationMode") === this.NOTARGET) === (this.get("target") === null);},
          function() {return this.get("target") !== null ? this.get("stylePresentationMode") === this.get("presentationMode") : true;},
          function() {return this._wrappedDetails() != null;},
          function() {return lang.isArray(this._wrappedDetails());},
          {
            objectSelector: function() {
              return this._wrappedDetails();
            },
            invars: [
              function(wd) {
                return wd && wd != null &&
                  wd.isInstanceOf && wd.isInstanceOf(_SemanticObjectPane);
              },
              // wrapped details might contain other objects of other types as target,
              // or null, but the presentationMode needs to be in sync. The stylePresentationMode
              // can differ.
              function(wd) {
                return wd.get("presentationMode") === this.get("presentationMode");
              }
            ]
          }
        ],

        "-chains-": {
          _propagateTarget: "after",
          _propagateOpener: "after",
          _localPresentationModeChange: "after"
        },

        // target: SemanticObject
        //    SemanticObject that is represented.
        //    Access in declarative template with  ... data-dojo-props="value: at('rel:', BINDING_PROPERTY_NAME)
        target: null,

        // presentationMode: String
        //    The presentation mode is either view, edit, busy, wild, or error
        presentationMode: stylePresentationModes[0], // default value

        // opener: Function
        //   Function that attempts to open a new "window" or "pane" for another PersistentObject
        //   (which is mostly linked to the current one)
        opener: null,

        widgetSize: 0,

        postCreate: function() {
          this.inherited(arguments);
          domClass.add(this.get("domNode"), "SemanticObjectPane");
        },

        // stylePresentationMode: String
        //    The stylePresentationMode is the same as the presentationMode, except when there is no target.
        //    Then it is NOTARGET.
        _getStylePresentationModeAttr: function() {
          return this.target ? this.get("presentationMode") : this.NOTARGET;
        },

        isInEditMode: function() {
          // summary:
          //    This is in a `stylePresentationMode` that allows the user to change the values, if there is a target and
          //    it is editable.
          return this.target &&
            (this.presentationMode === this.EDIT || this.presentationMode === this.BUSY || this.presentationMode === this.WILD);
        },

        _wrappedDetails: function() {
          // summary:
          //   Array containing the wrapped details, a subclass wants the presentationMode propagated to.
          // tags:
          //   protected

          return []; // return Array
        },

        getTargetType: function() {
          // summary:
          //    The supported type of SemanticObjects. All targets must be an instance of this type.
          // description:
          //    Subclasses should overwrite to return the correct type.

          return SemanticObject;
        },

        _propagateTarget: function(/*SemanticObject*/ so) {
          // summary:
          //   Propagate the target as appropriate to wrapped details.
          //   Chained. Subtypes could add propagation to wrapped details.
          // tags:
          //   protected
          // description:
          //   Does nothing in _SemanticObjectPane.

          this._c_NOP(so);
        },

        _setTargetAttr: function(so) {
          // summary:
          //    Sets the target of this instance. Chained. Subtypes could add propagation to wrapped details.
          this._c_pre(function() {return so == null || (so.isInstanceOf && so.isInstanceOf(this.getTargetType()));});

          if (so !== this.get("target")) {
            this._set("target", so);
          }
          this._propagateTarget(so);
          this.set("presentationMode", so !== null && so.persistenceId === null ? this.EDIT : this.VIEW);
        },

        _propagateOpener: function(/*Function*/ opener) {
          // summary:
          //   Propagate the opener function as appropriate to wrapped details.
          //   Chained. Subtypes could add propagation to wrapped details.
          // tags:
          //   protected
          // description:
          //   Does nothing in _SemanticObjectPane.

          this._c_NOP(opener);
        },

        _setOpenerAttr: function(opener) {
          if (opener !== this.get("opener")) {
            this._set("opener", opener);
          }
          this._propagateOpener(opener);
        },

        _setPresentationModeAttr: function(value) {
          // summary:
          //    Set the presentationMode, and propagate to the wrapped details.
          //    Also makes all innerWidgets read-only in presentationMode VIEW,
          //    disabled in presentationMode BUSY, and not-read-only and enabled
          //    in the other presentationModes.

          // Called during create by _WidgetBase with default value automatically
          this._c_pre(function() {return value != null});
          this._c_pre(function() {return _SemanticObjectPane.prototype.presentationModes.indexOf(value) >= 0});

          this._set("presentationMode", value);
          this._wrappedDetails().forEach(function(wd) {
            wd.set("presentationMode", value);
          });
          var myDomNode = this.get("domNode");
          var stylePresentationMode = this.get("stylePresentationMode");
          setStylepresentationMode(this, stylePresentationMode);
          this._localPresentationModeChange(value);
        },

        _localPresentationModeChange: function(/*String*/ presentationMode) {
          // summary:
          //   Make changes to representation to represent the
          //   new edit mode. Chained. Overwrite when needed.
          // tags:
          //   protected
          // description:
          //   Does nothing in _SemanticObjectPane

          this._c_NOP(presentationMode);
        },

        getWidgetSize: function() {
          return this.widgetSize;
        }

      });

      // All supported presentationModes
      _SemanticObjectPane.prototype.presentationModes = presentationModes;
      // All supported stylePresentationModes
      _SemanticObjectPane.prototype.stylePresentationModes = stylePresentationModes;
      stylePresentationModes.forEach(function(em) {
        _SemanticObjectPane.prototype[em] = em;
      });

      return _SemanticObjectPane; // return _SemanticObjectPane

    });
<commit_msg>get the size from css<commit_after>define(["dojo/_base/declare", "ppwcode-util-contracts/_Mixin", "dojo/_base/lang", "dijit/registry", "dojo/dom-class",
        "dijit/_WidgetBase", "../../SemanticObject",
        "dijit/form/ValidationTextBox", "dojox/mvc/Output", "dojox/form/CheckedMultiSelect", "dijit/form/SimpleTextarea",
         "dijit/form/CheckBox",
         "xstyle/css!./_SemanticObjectPane.css"],
    function(declare, _ContractMixin, lang, registry, domClass,
             _WidgetBase, SemanticObject,
             ValidationTextBox, Output, CheckedMultiSelect, SimpleTextarea,
             CheckBox) {

      var presentationModes = [
        // presentationMode and stylePresentationMode for viewing the data. No interaction allowed.
        "VIEW",

        // presentationMode and stylePresentationMode for editing the data. Interaction allowed.
        "EDIT",

        // presentationMode and stylePresentationMode while the SemanticObject is busy. No interaction allowed.
        "BUSY",

        // presentationMode and stylePresentationMode representing unacceptable data (the object is
        // not civilized, or we have other means of knowing the data is unacceptable).
        // Interaction must be allowed to reset the object, or ammeliorate the data/
        // This means this is a sub-state of EDIT.
        "WILD",

        // presentationMode and stylePresentationMode representing an error occured. We cannot proceed. The widget
        // and its object must be destroyed.
        "ERROR"];

      var stylePresentationModes = presentationModes.slice(0); // copy
      // stylePresentationMode for when there is no target
      stylePresentationModes.push("NOTARGET");

      function setStylepresentationMode(sop, stylePresentationMode) {
        var domNode = sop.get("domNode");
        var innerWidgets = registry.findWidgets(domNode);
        var widgetState = null;
        //noinspection FallthroughInSwitchStatementJS
        switch (stylePresentationMode) {
          case _SemanticObjectPane.prototype.NOTARGET:
            widgetState = { readOnly:false, disabled:true };
            break;
          case _SemanticObjectPane.prototype.EDIT:
          case _SemanticObjectPane.prototype.WILD:
            widgetState = { readOnly:false, disabled:false };
            break;
          case _SemanticObjectPane.prototype.BUSY:
          case _SemanticObjectPane.prototype.ERROR:
            widgetState = { readOnly:false, disabled:true };
            break;
          default: // VIEW
            widgetState = { readOnly:true, disabled:false };
        }
        innerWidgets.forEach(function (w) {
          if (w.isInstanceOf(ValidationTextBox) || w.isInstanceOf(Output)
              || w.isInstanceOf(CheckedMultiSelect) || w.isInstanceOf(SimpleTextarea) || w.isInstanceOf(CheckBox)) {
            w.set("readOnly", widgetState.readOnly);
            w.set("disabled", widgetState.disabled);
          }
        });
        if (stylePresentationMode == _SemanticObjectPane.prototype.VIEW ||
            stylePresentationMode == _SemanticObjectPane.prototype.EDIT) {
          domClass.replace(domNode,
            "SemanticObjectPane_enabled",
            "SemanticObjectPane_busy SemanticObjectPane_wild SemanticObjectPane_disabled SemanticObjectPane_error SemanticObjectPane_notarget");
        }
        else if (stylePresentationMode == _SemanticObjectPane.prototype.BUSY) {
          domClass.replace(domNode,
            "SemanticObjectPane_busy",
            "SemanticObjectPane_enabled SemanticObjectPane_wild SemanticObjectPane_disabled SemanticObjectPane_error SemanticObjectPane_notarget");
        }
        else if (stylePresentationMode == _SemanticObjectPane.prototype.WILD) {
          domClass.replace(domNode,
            "SemanticObjectPane_wild",
            "SemanticObjectPane_enabled SemanticObjectPane_busy SemanticObjectPane_disabled SemanticObjectPane_error SemanticObjectPane_notarget");
        }
        else if (stylePresentationMode == _SemanticObjectPane.prototype.ERROR) {
          domClass.replace(domNode,
            "SemanticObjectPane_error",
            "SemanticObjectPane_enabled SemanticObjectPane_busy SemanticObjectPane_wild SemanticObjectPane_disabled SemanticObjectPane_notarget");
        }
        else { // NOTARGET
          domClass.replace(domNode,
            " SemanticObjectPane_notarget",
            "SemanticObjectPane_enabled SemanticObjectPane_busy SemanticObjectPane_wild SemanticObjectPane_error SemanticObjectPane_disabled");
        }
      }

      var _SemanticObjectPane = declare([_WidgetBase, _ContractMixin], {
        // summary:
        //   Widget that represents a SemanticObject in detail, and that gives the opportunity
        //   to the user the view the details, edit the details, and create a new object.
        //   Abstract class to be extended for particular subtypes of SemanticObject.
        // description:
        //   What is common to all subtypes is that the widget:
        //   - has a `target` that is a SemanticObject; getTargetType() returns the top-most supported
        //     Constructor of supported targets. All targets must be instances of this type.
        //   - has an `presentationMode` (view, edit, busy, wild, error)
        //   - has a `stylePresentationMode`
        //
        //   The representation should reflect the presentationMode in a clear visual way to the user.
        //   This is the `stylePresentationModel`. It is the `presentationMode` if `target !== null`,
        //   and `NOTARGET` otherwise.
        //   Even when the information shown is completely read-only, widgets should extend
        //   this class, to change the representation of the displayed information consistently
        //   with other information in different presentationModes, e.g., in "busy" mode.
        //   The available presentation modes are defined in _SemanticObjectPane.prototype.presentationModes.
        //
        //   Instances can be wrapped around zero or more _SemanticObjectPanes, recursively (no loops!).
        //   We take care of propagating `presentationMode`. Subclasses need to override
        //   getWrappedDetails to return the wrapped details. All instances need to be instances of this class.
        //   The default implementation returns an empty array.
        //   The target of a wrapped detail might be the same target as our target, but it might be
        //   another related object, of a different type. set("target", ...) will call _propagateTarget, which is
        //   chained, so that subclasses can add propagation of setting the target. Our implementation only sets our
        //   target.
        //
        //   This class is concerned with presentation. Other classes might add presentation
        //   and functionality to support interaction with the user (save and cancel buttons, etc. -
        //   see e.g. ppwcode persistence).

        _c_invar: [
          function() {return this.get("presentationMode");},
          function() {return this.presentationModes.indexOf(this.get("presentationMode")) >= 0;},
          function() {return this.getTargetType() != null;},
          // TODO getTargetType is a subtype of SemanticObject
          function() {return this.get("target") == null ||
                        (this.get("target").isInstanceOf && this.get("target").isInstanceOf(this.getTargetType()));},
          function() {return this.get("stylePresentationMode");},
          function() {return this.stylePresentationModes.indexOf(this.get("stylePresentationMode")) >= 0;},
          function() {return (this.get("stylePresentationMode") === this.NOTARGET) === (this.get("target") === null);},
          function() {return this.get("target") !== null ? this.get("stylePresentationMode") === this.get("presentationMode") : true;},
          function() {return this._wrappedDetails() != null;},
          function() {return lang.isArray(this._wrappedDetails());},
          {
            objectSelector: function() {
              return this._wrappedDetails();
            },
            invars: [
              function(wd) {
                return wd && wd != null &&
                  wd.isInstanceOf && wd.isInstanceOf(_SemanticObjectPane);
              },
              // wrapped details might contain other objects of other types as target,
              // or null, but the presentationMode needs to be in sync. The stylePresentationMode
              // can differ.
              function(wd) {
                return wd.get("presentationMode") === this.get("presentationMode");
              }
            ]
          }
        ],

        "-chains-": {
          _propagateTarget: "after",
          _propagateOpener: "after",
          _localPresentationModeChange: "after"
        },

        // target: SemanticObject
        //    SemanticObject that is represented.
        //    Access in declarative template with  ... data-dojo-props="value: at('rel:', BINDING_PROPERTY_NAME)
        target: null,

        // presentationMode: String
        //    The presentation mode is either view, edit, busy, wild, or error
        presentationMode: stylePresentationModes[0], // default value

        // opener: Function
        //   Function that attempts to open a new "window" or "pane" for another PersistentObject
        //   (which is mostly linked to the current one)
        opener: null,

        widgetSize: 0,

        postCreate: function() {
          this.inherited(arguments);
          domClass.add(this.get("domNode"), "SemanticObjectPane");
        },

        // stylePresentationMode: String
        //    The stylePresentationMode is the same as the presentationMode, except when there is no target.
        //    Then it is NOTARGET.
        _getStylePresentationModeAttr: function() {
          return this.target ? this.get("presentationMode") : this.NOTARGET;
        },

        isInEditMode: function() {
          // summary:
          //    This is in a `stylePresentationMode` that allows the user to change the values, if there is a target and
          //    it is editable.
          return this.target &&
            (this.presentationMode === this.EDIT || this.presentationMode === this.BUSY || this.presentationMode === this.WILD);
        },

        _wrappedDetails: function() {
          // summary:
          //   Array containing the wrapped details, a subclass wants the presentationMode propagated to.
          // tags:
          //   protected

          return []; // return Array
        },

        getTargetType: function() {
          // summary:
          //    The supported type of SemanticObjects. All targets must be an instance of this type.
          // description:
          //    Subclasses should overwrite to return the correct type.

          return SemanticObject;
        },

        _propagateTarget: function(/*SemanticObject*/ so) {
          // summary:
          //   Propagate the target as appropriate to wrapped details.
          //   Chained. Subtypes could add propagation to wrapped details.
          // tags:
          //   protected
          // description:
          //   Does nothing in _SemanticObjectPane.

          this._c_NOP(so);
        },

        _setTargetAttr: function(so) {
          // summary:
          //    Sets the target of this instance. Chained. Subtypes could add propagation to wrapped details.
          this._c_pre(function() {return so == null || (so.isInstanceOf && so.isInstanceOf(this.getTargetType()));});

          if (so !== this.get("target")) {
            this._set("target", so);
          }
          this._propagateTarget(so);
          this.set("presentationMode", so !== null && so.persistenceId === null ? this.EDIT : this.VIEW);
        },

        _propagateOpener: function(/*Function*/ opener) {
          // summary:
          //   Propagate the opener function as appropriate to wrapped details.
          //   Chained. Subtypes could add propagation to wrapped details.
          // tags:
          //   protected
          // description:
          //   Does nothing in _SemanticObjectPane.

          this._c_NOP(opener);
        },

        _setOpenerAttr: function(opener) {
          if (opener !== this.get("opener")) {
            this._set("opener", opener);
          }
          this._propagateOpener(opener);
        },

        _setPresentationModeAttr: function(value) {
          // summary:
          //    Set the presentationMode, and propagate to the wrapped details.
          //    Also makes all innerWidgets read-only in presentationMode VIEW,
          //    disabled in presentationMode BUSY, and not-read-only and enabled
          //    in the other presentationModes.

          // Called during create by _WidgetBase with default value automatically
          this._c_pre(function() {return value != null});
          this._c_pre(function() {return _SemanticObjectPane.prototype.presentationModes.indexOf(value) >= 0});

          this._set("presentationMode", value);
          this._wrappedDetails().forEach(function(wd) {
            wd.set("presentationMode", value);
          });
          var myDomNode = this.get("domNode");
          var stylePresentationMode = this.get("stylePresentationMode");
          setStylepresentationMode(this, stylePresentationMode);
          this._localPresentationModeChange(value);
        },

        _localPresentationModeChange: function(/*String*/ presentationMode) {
          // summary:
          //   Make changes to representation to represent the
          //   new edit mode. Chained. Overwrite when needed.
          // tags:
          //   protected
          // description:
          //   Does nothing in _SemanticObjectPane

          this._c_NOP(presentationMode);
        }

      });

      // All supported presentationModes
      _SemanticObjectPane.prototype.presentationModes = presentationModes;
      // All supported stylePresentationModes
      _SemanticObjectPane.prototype.stylePresentationModes = stylePresentationModes;
      stylePresentationModes.forEach(function(em) {
        _SemanticObjectPane.prototype[em] = em;
      });

      return _SemanticObjectPane; // return _SemanticObjectPane

    });
<|endoftext|>


<commit_before>angular.module('olwSection', [
    'olwConfigurationService'
  , 'olwSectionsService'
  , 'olwUsernameFilter'
  , 'olwLiDirective'
  , 'olwLiBodyDirective'
  , 'olwMetaService'
  , 'pascalprecht.translate'
  , 'seo'
  , 'ngRoute'
  , 'ng'
])

.config(['$routeProvider', function($routeProvider) {
	$routeProvider.when('/section/:nameWithSlug', {
		controller: 'SectionCtrl',
		templateUrl: 'section/section.tpl.html'
	});
}])

.controller('SectionCtrl', function($scope, $http, $routeParams, $timeout, $filter, $translate, conf, sections, meta) {
	$scope.$parent.slug = $scope.slug = $routeParams.nameWithSlug.substring($routeParams.nameWithSlug.lastIndexOf('-') + 1);
	$translate('SECTION_' + $scope.slug).then(function(title) {
        $scope.title = title;
        meta.title($scope.title);
    });
    meta.description(false);

	$scope.filter = { language : { german : { id : 1, enabled : true}, english : {id : 2, enabled : true} } };
	$scope.isEnabled = function(filter, prop) { return $scope.filter[filter][prop].enabled; };
	$scope.toggleFilter = function(filter, prop) {
		var p1
          , p2
          , eachDisabled = true;

		$scope.filter[filter][prop].enabled = !$scope.filter[filter][prop].enabled;

		if (!$scope.filter[filter][prop].enabled) {
			for(p1 in $scope.filter[filter]) {
				if($scope.filter[filter].hasOwnProperty(p1) && $scope.filter[filter][p1].enabled) {
					eachDisabled = false;
					break;
				}
			}
		} else {
			eachDisabled = false;
		}

		if (eachDisabled) {
			for (p2 in $scope.filter[filter]) {
				if ($scope.filter[filter].hasOwnProperty(p2) && prop !== p2) {
					$scope.filter[filter][p2].enabled = true;
				}
			}
		}

		$scope.fetch($scope.amount, true);
	};

	$scope.amount = 10;
	$scope.page = 0;

	$scope.collections = [];
	$scope.highlights = [];

	$scope.moreAvailable = true;
	$scope.getSlugFor = sections.getSlugForArea;

	// Randomgenerator used for random Highlights - returns random integer value of intervall [0,x]
	var rh = function(x) { return Math.round(Math.random() * x);}
	    // Prepare area ids for query - ?area=1&area=2
	  , filterByArea = sections.sections[$scope.slug].content.map(function(a) { return "area=" + a.id; } ).join('&')
	  , filterByLanguage = function() {
		var lang
          , filterByLanguage = [];

		for (lang in $scope.filter.language) {
			if ($scope.filter.language.hasOwnProperty(lang) && $scope.filter.language[lang].enabled) {
				filterByLanguage.push('language='+$scope.filter.language[lang].id);
			}
		}
		filterByLanguage = filterByLanguage.join('&');

		return filterByLanguage;
	};

	$scope.badges = function(collection) {
		return collection.areas.map(function(area) {
            return $translate('AREA_' + area.id).then(function(title) {
                return {
                    title: title,
                    classes: 'badge-' + sections.getSlugForArea(area.name)
                };
            });
		});
	};

	$scope.fetch = function(amount, update) {
		if (!amount) { amount = $scope.amount; }
		if (update) { $scope.page = 0; $scope.collections = [];	$scope.highlights = []; }

		$http
			.jsonp(conf.urls.api + '/collection-overview/filter/' + conf.urls.apiIndexPathElement +'?&elements=' + amount + '&' + filterByLanguage() + '&page=' + ($scope.page++) + '&' + filterByArea + '&callback=JSON_CALLBACK')
			.success(function(result) {
                var pot
                  , i
                  , r;

				$scope.totalElements = result.totalElements;
				$scope.moreAvailable = result.totalElements > amount * $scope.page;

				angular.forEach(result.elements, function(collection) {
					$scope.collections.push({
							url: sections.getPathElement(collection.name, collection.id),
							title: collection.name,
							users: collection.users.map($filter('username')),
							areas: collection.areas,
							numberOfResources : collection.uuids.length
					});
				});

				if(update) {
					// make copy of $scope.collections
					pot = $scope.collections.slice();
					// Take/draw randomly 3 collections as highlights
					for(i = 0; i < Math.min(3, pot.length); i++) {
						r = rh(pot.length - 1);
						$scope.highlights.push(pot[r]);
						pot.splice(r, 1);
					}
				}
			});
	};
	$scope.fetch(10, true);

	$scope.$on('$locationChangeStart', function(event, next) {
		if (next.indexOf('collection') > -1) {
			$scope.$parent.animation = 'to-right';
		} else {
			$scope.$parent.animation = 'none';
		}
	});
});

<commit_msg>fixes broken section view<commit_after>angular.module('olwSection', [
    'olwConfigurationService'
  , 'olwSectionsService'
  , 'olwUsernameFilter'
  , 'olwLiDirective'
  , 'olwLiBodyDirective'
  , 'olwMetaService'
  , 'pascalprecht.translate'
  , 'seo'
  , 'ngRoute'
  , 'ng'
])

.config(function($routeProvider) {
	$routeProvider.when('/section/:nameWithSlug', {
		controller: 'SectionCtrl',
		templateUrl: 'section/section.tpl.html'
	});
})

.controller('SectionCtrl', function($scope, $http, $routeParams, $timeout, $filter, $translate, conf, sections, meta) {
	$scope.$parent.slug = $scope.slug = $routeParams.nameWithSlug.substring($routeParams.nameWithSlug.lastIndexOf('-') + 1);
	$translate('SECTION_' + $scope.slug).then(function(title) {
        $scope.title = title;
        meta.title($scope.title);
    });
    meta.description(false);

	$scope.filter = { language : { german : { id : 1, enabled : true}, english : {id : 2, enabled : true} } };
	$scope.isEnabled = function(filter, prop) { return $scope.filter[filter][prop].enabled; };
	$scope.toggleFilter = function(filter, prop) {
		var p1
          , p2
          , eachDisabled = true;

		$scope.filter[filter][prop].enabled = !$scope.filter[filter][prop].enabled;

		if (!$scope.filter[filter][prop].enabled) {
			for(p1 in $scope.filter[filter]) {
				if($scope.filter[filter].hasOwnProperty(p1) && $scope.filter[filter][p1].enabled) {
					eachDisabled = false;
					break;
				}
			}
		} else {
			eachDisabled = false;
		}

		if (eachDisabled) {
			for (p2 in $scope.filter[filter]) {
				if ($scope.filter[filter].hasOwnProperty(p2) && prop !== p2) {
					$scope.filter[filter][p2].enabled = true;
				}
			}
		}

		$scope.fetch($scope.amount, true);
	};

	$scope.amount = 10;
	$scope.page = 0;

	$scope.collections = [];
	$scope.highlights = [];

	$scope.moreAvailable = true;
	$scope.getSlugFor = sections.getSlugForArea;

	// Randomgenerator used for random Highlights - returns random integer value of intervall [0,x]
	var rh = function(x) { return Math.round(Math.random() * x);}
	    // Prepare area ids for query - ?area=1&area=2
	  , filterByArea = sections.sections[$scope.slug].content.map(function(a) { return "area=" + a.id; } ).join('&')
	  , filterByLanguage = function() {
		var lang
          , filterByLanguage = [];

		for (lang in $scope.filter.language) {
			if ($scope.filter.language.hasOwnProperty(lang) && $scope.filter.language[lang].enabled) {
				filterByLanguage.push('language='+$scope.filter.language[lang].id);
			}
		}
		filterByLanguage = filterByLanguage.join('&');

		return filterByLanguage;
	};

	$scope.badges = function(collection) {
		return collection.areas.map(function(area) {
            return $translate('AREA_' + area.id).then(function(title) {
                return {
                    title: title,
                    classes: 'badge-' + sections.getSlugForArea(area.name)
                };
            });
		});
	};

	$scope.fetch = function(amount, update) {
		if (!amount) { amount = $scope.amount; }
		if (update) { $scope.page = 0; $scope.collections = [];	$scope.highlights = []; }

		$http
			.jsonp(conf.urls.api + '/collection-overview/filter/' + conf.urls.apiIndexPathElement +'?&elements=' + amount + '&' + filterByLanguage() + '&page=' + ($scope.page++) + '&' + filterByArea + '&callback=JSON_CALLBACK')
			.success(function(result) {
                var pot
                  , i
                  , r;

				$scope.totalElements = result.totalElements;
				$scope.moreAvailable = result.totalElements > amount * $scope.page;

				angular.forEach(result.elements, function(collection) {
					$scope.collections.push({
							url: sections.getPathElement(collection.name, collection.id),
							title: collection.name,
							users: collection.users.map($filter('username')),
							areas: collection.areas,
							numberOfResources : collection.uuids.length
					});
				});

				if(update) {
					// make copy of $scope.collections
					pot = $scope.collections.slice();
					// Take/draw randomly 3 collections as highlights
					for(i = 0; i < Math.min(3, pot.length); i++) {
						r = rh(pot.length - 1);
						$scope.highlights.push(pot[r]);
						pot.splice(r, 1);
					}
				}
			});
	};
	$scope.fetch(10, true);

	$scope.$on('$locationChangeStart', function(event, next) {
		if (next.indexOf('collection') > -1) {
			$scope.$parent.animation = 'to-right';
		} else {
			$scope.$parent.animation = 'none';
		}
	});
});

<|endoftext|>


<commit_before>(function($) {
	var decodeHTML = function (html_str) {
		return $("<div />").html(html_str).text();
	}
	$.fn.superSubscribe = function(opts) {
		var superSubscribe = {
			wrapper: null,
			init: function(wrapper, opts){
				this.wrapper = wrapper;
				this.opts = $.extend({},opts);
				this.action = $(this.wrapper).attr('super-subscribe');

				$(this.wrapper).find('[super-subscribe-submit]').on('click', $.proxy(this.submit, this));
				$(this.wrapper).find('[super-subscribe-email]').on('keypress', $.proxy(this.detectEnter, this));

			},
			detectEnter: function(e){
				if(e.which == 13) {
					e.preventDefault();
					this.submit();
				}
			},
			ajaxResponse: function (jqXHR, status, statusMSG) {
				console.log(jqXHR.responseText);
				if (jqXHR.responseText) {
					try {
						res = $.parseJSON(jqXHR.responseText);
					} catch (err) {};
					if (res.status) {
						if (res.status == 'ok') {
							var addClass = 'alert-success';
						} else if(res.status == 'mail_already_exists') {
							var addClass = 'alert-info';
						} else {
							var addClass = 'alert-danger';
						}

						$(this.wrapper).find('.output')
							.hide()
							.removeClass('alert-success alert-info alert-danger')
							.addClass('alert '+addClass)
							.html(decodeHTML(res.data))
							.fadeIn();
						// setTimeout($.proxy(function(e){
						// 	$(this.wrapper).find('.output').fadeOut(300, $.proxy(function(e){
						// 		$(this.wrapper).find('.output').html('');
						// 		$(this.wrapper).find('input[type="text"]').val('');
						// 	},this));
						// }), 2000);

					};

				}
			},
			submit: function(e){
				e && e.preventDefault();
				$.ajax({
					method: 'post',
					url: this.action,
					data: {
						email: $(this.wrapper).find('[super-subscribe-email]').val()
					},
					complete: $.proxy(this.ajaxResponse, this)
				});
			}
		};
		if (this.length>1) {
			var objects = [];
			$(this).each(function(){
				var instance = Object.create(superSubscribe);
				instance.init(this,opts);
				objects.push(instance);
			});
			return objects;
		} else {
			var instance = Object.create(superSubscribe);
			instance.init(this,opts);
			return instance;
		}
	}
	$(function(){
		$("[super-subscribe]").superSubscribe();
	});
})(jQuery);

<commit_msg>fix code style<commit_after>(function($) {
	var decodeHTML = function(html_str) {
		return $("<div />").html(html_str).text();
	}
	$.fn.superSubscribe = function(opts) {
		var superSubscribe = {
			wrapper: null,
			init: function(wrapper, opts) {
				this.wrapper = wrapper;
				this.opts = $.extend({}, opts);
				this.action = $(this.wrapper).attr('super-subscribe');

				$(this.wrapper).find('[super-subscribe-submit]').on('click', $.proxy(this.submit, this));
				$(this.wrapper).find('[super-subscribe-email]').on('keypress', $.proxy(this.detectEnter, this));

			},
			detectEnter: function(e) {
				if (e.which == 13) {
					e.preventDefault();
					this.submit();
				}
			},
			ajaxResponse: function(jqXHR, status, statusMSG) {
				console.log(jqXHR.responseText);
				if (jqXHR.responseText) {
					try {
						res = $.parseJSON(jqXHR.responseText);
					} catch (err) {};
					if (res.status) {
						if (res.status == 'ok') {
							var addClass = 'alert-success';
						} else if (res.status == 'mail_already_exists') {
							var addClass = 'alert-info';
						} else {
							var addClass = 'alert-danger';
						}

						$(this.wrapper).find('.output')
							.hide()
							.removeClass('alert-success alert-info alert-danger')
							.addClass('alert ' + addClass)
							.html(decodeHTML(res.data))
							.fadeIn();
						// setTimeout($.proxy(function(e){
						// 	$(this.wrapper).find('.output').fadeOut(300, $.proxy(function(e){
						// 		$(this.wrapper).find('.output').html('');
						// 		$(this.wrapper).find('input[type="text"]').val('');
						// 	},this));
						// }), 2000);

					};

				}
			},
			submit: function(e) {
				e && e.preventDefault();
				$.ajax({
					method: 'post',
					url: this.action,
					data: {
						email: $(this.wrapper).find('[super-subscribe-email]').val()
					},
					complete: $.proxy(this.ajaxResponse, this)
				});
			}
		};
		if (this.length > 1) {
			var objects = [];
			$(this).each(function() {
				var instance = Object.create(superSubscribe);
				instance.init(this, opts);
				objects.push(instance);
			});
			return objects;
		} else {
			var instance = Object.create(superSubscribe);
			instance.init(this, opts);
			return instance;
		}
	}
	$(function() {
		$("[super-subscribe]").superSubscribe();
	});
})(jQuery);
<|endoftext|>


<commit_before>/*
 * GridGallery is a plugin that will generate a grid depending on
 * the elements width and height. it is not required to have the same height
 * also you can enable/disable show lightbox effect to load content
 *
 * license: under MIT
 *          https://github.com/pencilpix/grid-gallery/blob/master/LICENSE
 * Author: Mohamed Hassan
 * Author Url: mohamedhassan@me
 */
(function($doc, $win){
  'use strict';

  /*=========================
   * @private helper functions
   *========================/

   /*
    * _extend Private method that extends an object using
    * properties of another object.
    * @param { Object } obj1 The object that will be extended
    * @param { Object } obj2 The object that will be used to extend another.
    *
    * @return { Object } obj1 The first object after being extended.
    */
  function _extend(obj1, obj2) {
    for ( var prop in obj2 ) {
      if ( obj2.hasOwnProperty(prop) ) {
        obj1[prop] = obj2[prop];
      }
    }

    return obj1;
  }

  /*
   * _checkItems Private method that check if GridGallery enabled on items
   * @param { Array-like } items The grid elements.
   * @return { Array-like } notEnabled The grid items that not set yet.
   */
  function _checkItems(items) {
    var notEnabled = Array.prototype.map.call(items, function(item) {
      if(!item.dataset.grid && item.className === 'grid-gallery__item'){
        return item;
      }
    });

    if (notEnabled.length){
      return notEnabled;
    }
  }

  /*
   * class constructor of GridGallery component
   * @param { HTMLElement } element The element that will be the container.
   * @param { Object } options The options to initialize the component.
   */
  function GridGallery(element, options) {
    var _defaultOptions = { lightBox: false };

    this.element = element;

    this.options = _extend({}, _defaultOptions); // extend options to default
    this.options = _extend(this.options, options); // extend default to custom

    this.init();
  }

  /*
   * init this method that do the rest of initialization
   * work and updates the dom.
   */
  GridGallery.prototype.init = function() {

  };

  $win.GridGallery = GridGallery; // makes the component globally exist.
})(document, window);

<commit_msg>fix comment of private section<commit_after>/*
 * GridGallery is a plugin that will generate a grid depending on
 * the elements width and height. it is not required to have the same height
 * also you can enable/disable show lightbox effect to load content
 *
 * license: under MIT
 *          https://github.com/pencilpix/grid-gallery/blob/master/LICENSE
 * Author: Mohamed Hassan
 * Author Url: mohamedhassan@me
 */
(function($doc, $win){
  'use strict';

  /*=========================
   * @private helper functions
   *=========================*/

   /*
    * _extend Private method that extends an object using
    * properties of another object.
    * @param { Object } obj1 The object that will be extended
    * @param { Object } obj2 The object that will be used to extend another.
    *
    * @return { Object } obj1 The first object after being extended.
    */
  function _extend(obj1, obj2) {
    for ( var prop in obj2 ) {
      if ( obj2.hasOwnProperty(prop) ) {
        obj1[prop] = obj2[prop];
      }
    }

    return obj1;
  }

  /*
   * _checkItems Private method that check if GridGallery enabled on items
   * @param { Array-like } items The grid elements.
   * @return { Array-like } notEnabled The grid items that not set yet.
   */
  function _checkItems(items) {
    var notEnabled = Array.prototype.map.call(items, function(item) {
      if(!item.dataset.grid && item.className === 'grid-gallery__item'){
        return item;
      }
    });

    if (notEnabled.length){
      return notEnabled;
    }
  }

  /*
   * class constructor of GridGallery component
   * @param { HTMLElement } element The element that will be the container.
   * @param { Object } options The options to initialize the component.
   */
  function GridGallery(element, options) {
    var _defaultOptions = { lightBox: false };

    this.element = element;

    this.options = _extend({}, _defaultOptions); // extend options to default
    this.options = _extend(this.options, options); // extend default to custom

    this.init();
  }

  /*
   * init this method that do the rest of initialization
   * work and updates the dom.
   */
  GridGallery.prototype.init = function() {

  };

  $win.GridGallery = GridGallery; // makes the component globally exist.
})(document, window);

<|endoftext|>


<commit_before>import detectIndent from "detect-indent";
import Whitespace from "./whitespace";
import repeating from "repeating";
import SourceMap from "./source-map";
import Position from "./position";
import * as messages from "../messages";
import Buffer from "./buffer";
import extend from "lodash/object/extend";
import each from "lodash/collection/each";
import n from "./node";
import * as t from "../types";

class CodeGenerator {
  constructor(ast, opts, code) {
    opts = opts || {};

    this.comments = ast.comments || [];
    this.tokens   = ast.tokens || [];
    this.format   = CodeGenerator.normalizeOptions(code, opts, this.tokens);
    this.opts     = opts;
    this.ast      = ast;

    this.whitespace = new Whitespace(this.tokens, this.comments, this.format);
    this.position   = new Position;
    this.map        = new SourceMap(this.position, opts, code);
    this.buffer     = new Buffer(this.position, this.format);
  }

  static normalizeOptions(code, opts, tokens) {
    var style = "  ";
    if (code) {
      var indent = detectIndent(code).indent;
      if (indent && indent !== " ") style = indent;
    }

    var format = {
      retainLines: opts.retainLines,
      comments: opts.comments == null || opts.comments,
      compact: opts.compact,
      quotes: CodeGenerator.findCommonStringDelimiter(code, tokens),
      indent: {
        adjustMultilineComment: true,
        style: style,
        base: 0
      }
    };

    if (format.compact === "auto") {
      format.compact = code.length > 100000; // 100KB

      if (format.compact) {
        console.error("[BABEL] " + messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
      }
    }

    return format;
  }

  static findCommonStringDelimiter(code, tokens) {
    var occurences = {
      single: 0,
      double: 0
    };

    var checked = 0;

    for (var i = 0; i < tokens.length; i++) {
      var token = tokens[i];
      if (token.type.label !== "string") continue;
      if (checked >= 3) continue;

      var raw = code.slice(token.start, token.end);
      if (raw[0] === "'") {
        occurences.single++;
      } else {
        occurences.double++;
      }

      checked++;
    }

    if (occurences.single > occurences.double) {
      return "single";
    } else {
      return "double";
    }
  }

  static generators = {
    templateLiterals: require("./generators/template-literals"),
    comprehensions:   require("./generators/comprehensions"),
    expressions:      require("./generators/expressions"),
    statements:       require("./generators/statements"),
    classes:          require("./generators/classes"),
    methods:          require("./generators/methods"),
    modules:          require("./generators/modules"),
    types:            require("./generators/types"),
    flow:             require("./generators/flow"),
    base:             require("./generators/base"),
    jsx:              require("./generators/jsx")
  };

  generate() {
    var ast = this.ast;

    this.print(ast);

    var comments = [];
    for (var comment of (ast.comments: Array)) {
      if (!comment._displayed) comments.push(comment);
    }
    this._printComments(comments);

    return {
      map:  this.map.get(),
      code: this.buffer.get()
    };
  }

  buildPrint(parent) {
    var print = (node, opts) => {
      return this.print(node, parent, opts);
    };

    print.sequence = (nodes, opts = {}) => {
      opts.statement = true;
      return this.printJoin(print, nodes, opts);
    };

    print.join = (nodes, opts) => {
      return this.printJoin(print, nodes, opts);
    };

    print.list = function (items, opts = {}) {
      if (opts.separator == null) opts.separator = ", ";
      print.join(items, opts);
    };

    print.block = (node) => {
      return this.printBlock(print, node);
    };

    print.indentOnComments = (node) => {
      return this.printAndIndentOnComments(print, node);
    };

    return print;
  }

  catchUp(node, parent) {
    // catch up to this nodes newline if we're behind
    if (node.loc && this.format.retainLines && this.buffer.buf) {
      var needsParens = false;
      if (parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
        needsParens = true;
        this._push("(");
      }
      while (this.position.line < node.loc.start.line) {
        this._push("\n");
      }
      return needsParens;
    }
    return false;
  }

  print(node, parent, opts = {}) {
    if (!node) return;

    if (parent && parent._compact) {
      node._compact = true;
    }

    var oldConcise = this.format.concise;
    if (node._compact) {
      this.format.concise = true;
    }

    var newline = (leading) => {
      if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
        return;
      }

      var lines = 0;

      if (node.start != null && !node._ignoreUserWhitespace) {
        // user node
        if (leading) {
          lines = this.whitespace.getNewlinesBefore(node);
        } else {
          lines = this.whitespace.getNewlinesAfter(node);
        }
      } else {
        // generated node
        if (!leading) lines++; // always include at least a single line after
        if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;

        var needs = n.needsWhitespaceAfter;
        if (leading) needs = n.needsWhitespaceBefore;
        if (needs(node, parent)) lines++;

        // generated nodes can't add starting file whitespace
        if (!this.buffer.buf) lines = 0;
      }

      this.newline(lines);
    };

    if (this[node.type]) {
      var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
      var needsParens           = needsNoLineTermParens || n.needsParens(node, parent);

      if (needsParens) this.push("(");
      if (needsNoLineTermParens) this.indent();

      this.printLeadingComments(node, parent);

      var needsParensFromCatchup = this.catchUp(node, parent);

      newline(true);

      if (opts.before) opts.before();
      this.map.mark(node, "start");

      this[node.type](node, this.buildPrint(node), parent);

      if (needsNoLineTermParens) {
        this.newline();
        this.dedent();
      }
      if (needsParens || needsParensFromCatchup) this.push(")");

      this.map.mark(node, "end");
      if (opts.after) opts.after();

      this.format.concise = oldConcise;

      newline(false);

      this.printTrailingComments(node, parent);
    } else {
      throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`);
    }
  }

  printJoin(print, nodes, opts = {}) {
    if (!nodes || !nodes.length) return;

    var len = nodes.length;

    if (opts.indent) this.indent();

    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      print(node, {
        statement: opts.statement,
        addNewlines: opts.addNewlines,
        after: () => {
          if (opts.iterator) {
            opts.iterator(node, i);
          }

          if (opts.separator && i < len - 1) {
            this.push(opts.separator);
          }
        }
      });
    }

    if (opts.indent) this.dedent();
  }

  printAndIndentOnComments(print, node) {
    var indent = !!node.leadingComments;
    if (indent) this.indent();
    print(node);
    if (indent) this.dedent();
  }

  printBlock(print, node) {
    if (t.isEmptyStatement(node)) {
      this.semicolon();
    } else {
      this.push(" ");
      print(node);
    }
  }

  generateComment(comment) {
    var val = comment.value;
    if (comment.type === "Line") {
      val = `//${val}`;
    } else {
      val = `/*${val}*/`;
    }
    return val;
  }

  printTrailingComments(node, parent) {
    this._printComments(this.getComments("trailingComments", node, parent));
  }

  printLeadingComments(node, parent) {
    this._printComments(this.getComments("leadingComments", node, parent));
  }

  getComments(key, node, parent) {
    if (t.isExpressionStatement(parent)) {
      return [];
    }

    var comments = [];
    var nodes    = [node];

    if (t.isExpressionStatement(node)) {
      nodes.push(node.argument);
    }

    for (var node of (nodes: Array)) {
      comments = comments.concat(this._getComments(key, node));
    }

    return comments;
  }

  _getComments(key, node) {
    return (node && node[key]) || [];
  }

  _printComments(comments) {
    if (this.format.compact) return;

    if (!this.format.comments) return;
    if (!comments || !comments.length) return;

    for (var comment of (comments: Array)) {
      var skip = false;

      // find the original comment in the ast and set it as displayed
      for (var origComment of (this.ast.comments: Array)) {
        if (origComment.start === comment.start) {
          // comment has already been output
          if (origComment._displayed) skip = true;

          origComment._displayed = true;
          break;
        }
      }

      if (skip) return;

      this.catchUp(comment);

      // whitespace before
      this.newline(this.whitespace.getNewlinesBefore(comment));

      var column = this.position.column;
      var val    = this.generateComment(comment);

      if (column && !this.isLast(["\n", " ", "[", "{"])) {
        this._push(" ");
        column++;
      }

      //
      if (comment.type === "Block" && this.format.indent.adjustMultilineComment) {
        var offset = comment.loc.start.column;
        if (offset) {
          var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
          val = val.replace(newlineRegex, "\n");
        }

        var indent = Math.max(this.indentSize(), column);
        val = val.replace(/\n/g, `\n${repeating(" ", indent)}`);
      }

      if (column === 0) {
        val = this.getIndent() + val;
      }

      // force a newline for line comments when retainLines is set in case the next printed node
      // doesn't catch up
      if (this.format.retainLines && comment.type === "Line") {
        val += "\n";
      }

      //
      this._push(val);

      // whitespace after
      this.newline(this.whitespace.getNewlinesAfter(comment));
    }
  }
}

each(Buffer.prototype, function (fn, key) {
  CodeGenerator.prototype[key] = function () {
    return fn.apply(this.buffer, arguments);
  };
});

each(CodeGenerator.generators, function (generator) {
  extend(CodeGenerator.prototype, generator);
});

module.exports = function (ast, opts, code) {
  var gen = new CodeGenerator(ast, opts, code);
  return gen.generate();
};

module.exports.CodeGenerator = CodeGenerator;
<commit_msg>only print misisng ast.comments when available<commit_after>import detectIndent from "detect-indent";
import Whitespace from "./whitespace";
import repeating from "repeating";
import SourceMap from "./source-map";
import Position from "./position";
import * as messages from "../messages";
import Buffer from "./buffer";
import extend from "lodash/object/extend";
import each from "lodash/collection/each";
import n from "./node";
import * as t from "../types";

class CodeGenerator {
  constructor(ast, opts, code) {
    opts = opts || {};

    this.comments = ast.comments || [];
    this.tokens   = ast.tokens || [];
    this.format   = CodeGenerator.normalizeOptions(code, opts, this.tokens);
    this.opts     = opts;
    this.ast      = ast;

    this.whitespace = new Whitespace(this.tokens, this.comments, this.format);
    this.position   = new Position;
    this.map        = new SourceMap(this.position, opts, code);
    this.buffer     = new Buffer(this.position, this.format);
  }

  static normalizeOptions(code, opts, tokens) {
    var style = "  ";
    if (code) {
      var indent = detectIndent(code).indent;
      if (indent && indent !== " ") style = indent;
    }

    var format = {
      retainLines: opts.retainLines,
      comments: opts.comments == null || opts.comments,
      compact: opts.compact,
      quotes: CodeGenerator.findCommonStringDelimiter(code, tokens),
      indent: {
        adjustMultilineComment: true,
        style: style,
        base: 0
      }
    };

    if (format.compact === "auto") {
      format.compact = code.length > 100000; // 100KB

      if (format.compact) {
        console.error("[BABEL] " + messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
      }
    }

    return format;
  }

  static findCommonStringDelimiter(code, tokens) {
    var occurences = {
      single: 0,
      double: 0
    };

    var checked = 0;

    for (var i = 0; i < tokens.length; i++) {
      var token = tokens[i];
      if (token.type.label !== "string") continue;
      if (checked >= 3) continue;

      var raw = code.slice(token.start, token.end);
      if (raw[0] === "'") {
        occurences.single++;
      } else {
        occurences.double++;
      }

      checked++;
    }

    if (occurences.single > occurences.double) {
      return "single";
    } else {
      return "double";
    }
  }

  static generators = {
    templateLiterals: require("./generators/template-literals"),
    comprehensions:   require("./generators/comprehensions"),
    expressions:      require("./generators/expressions"),
    statements:       require("./generators/statements"),
    classes:          require("./generators/classes"),
    methods:          require("./generators/methods"),
    modules:          require("./generators/modules"),
    types:            require("./generators/types"),
    flow:             require("./generators/flow"),
    base:             require("./generators/base"),
    jsx:              require("./generators/jsx")
  };

  generate() {
    var ast = this.ast;

    this.print(ast);

    if (ast.comments) {
      var comments = [];
      for (var comment of (ast.comments: Array)) {
        if (!comment._displayed) comments.push(comment);
      }
      this._printComments(comments);
    }

    return {
      map:  this.map.get(),
      code: this.buffer.get()
    };
  }

  buildPrint(parent) {
    var print = (node, opts) => {
      return this.print(node, parent, opts);
    };

    print.sequence = (nodes, opts = {}) => {
      opts.statement = true;
      return this.printJoin(print, nodes, opts);
    };

    print.join = (nodes, opts) => {
      return this.printJoin(print, nodes, opts);
    };

    print.list = function (items, opts = {}) {
      if (opts.separator == null) opts.separator = ", ";
      print.join(items, opts);
    };

    print.block = (node) => {
      return this.printBlock(print, node);
    };

    print.indentOnComments = (node) => {
      return this.printAndIndentOnComments(print, node);
    };

    return print;
  }

  catchUp(node, parent) {
    // catch up to this nodes newline if we're behind
    if (node.loc && this.format.retainLines && this.buffer.buf) {
      var needsParens = false;
      if (parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
        needsParens = true;
        this._push("(");
      }
      while (this.position.line < node.loc.start.line) {
        this._push("\n");
      }
      return needsParens;
    }
    return false;
  }

  print(node, parent, opts = {}) {
    if (!node) return;

    if (parent && parent._compact) {
      node._compact = true;
    }

    var oldConcise = this.format.concise;
    if (node._compact) {
      this.format.concise = true;
    }

    var newline = (leading) => {
      if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
        return;
      }

      var lines = 0;

      if (node.start != null && !node._ignoreUserWhitespace) {
        // user node
        if (leading) {
          lines = this.whitespace.getNewlinesBefore(node);
        } else {
          lines = this.whitespace.getNewlinesAfter(node);
        }
      } else {
        // generated node
        if (!leading) lines++; // always include at least a single line after
        if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;

        var needs = n.needsWhitespaceAfter;
        if (leading) needs = n.needsWhitespaceBefore;
        if (needs(node, parent)) lines++;

        // generated nodes can't add starting file whitespace
        if (!this.buffer.buf) lines = 0;
      }

      this.newline(lines);
    };

    if (this[node.type]) {
      var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
      var needsParens           = needsNoLineTermParens || n.needsParens(node, parent);

      if (needsParens) this.push("(");
      if (needsNoLineTermParens) this.indent();

      this.printLeadingComments(node, parent);

      var needsParensFromCatchup = this.catchUp(node, parent);

      newline(true);

      if (opts.before) opts.before();
      this.map.mark(node, "start");

      this[node.type](node, this.buildPrint(node), parent);

      if (needsNoLineTermParens) {
        this.newline();
        this.dedent();
      }
      if (needsParens || needsParensFromCatchup) this.push(")");

      this.map.mark(node, "end");
      if (opts.after) opts.after();

      this.format.concise = oldConcise;

      newline(false);

      this.printTrailingComments(node, parent);
    } else {
      throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`);
    }
  }

  printJoin(print, nodes, opts = {}) {
    if (!nodes || !nodes.length) return;

    var len = nodes.length;

    if (opts.indent) this.indent();

    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      print(node, {
        statement: opts.statement,
        addNewlines: opts.addNewlines,
        after: () => {
          if (opts.iterator) {
            opts.iterator(node, i);
          }

          if (opts.separator && i < len - 1) {
            this.push(opts.separator);
          }
        }
      });
    }

    if (opts.indent) this.dedent();
  }

  printAndIndentOnComments(print, node) {
    var indent = !!node.leadingComments;
    if (indent) this.indent();
    print(node);
    if (indent) this.dedent();
  }

  printBlock(print, node) {
    if (t.isEmptyStatement(node)) {
      this.semicolon();
    } else {
      this.push(" ");
      print(node);
    }
  }

  generateComment(comment) {
    var val = comment.value;
    if (comment.type === "Line") {
      val = `//${val}`;
    } else {
      val = `/*${val}*/`;
    }
    return val;
  }

  printTrailingComments(node, parent) {
    this._printComments(this.getComments("trailingComments", node, parent));
  }

  printLeadingComments(node, parent) {
    this._printComments(this.getComments("leadingComments", node, parent));
  }

  getComments(key, node, parent) {
    if (t.isExpressionStatement(parent)) {
      return [];
    }

    var comments = [];
    var nodes    = [node];

    if (t.isExpressionStatement(node)) {
      nodes.push(node.argument);
    }

    for (var node of (nodes: Array)) {
      comments = comments.concat(this._getComments(key, node));
    }

    return comments;
  }

  _getComments(key, node) {
    return (node && node[key]) || [];
  }

  _printComments(comments) {
    if (this.format.compact) return;

    if (!this.format.comments) return;
    if (!comments || !comments.length) return;

    for (var comment of (comments: Array)) {
      var skip = false;

      // find the original comment in the ast and set it as displayed
      for (var origComment of (this.ast.comments: Array)) {
        if (origComment.start === comment.start) {
          // comment has already been output
          if (origComment._displayed) skip = true;

          origComment._displayed = true;
          break;
        }
      }

      if (skip) return;

      this.catchUp(comment);

      // whitespace before
      this.newline(this.whitespace.getNewlinesBefore(comment));

      var column = this.position.column;
      var val    = this.generateComment(comment);

      if (column && !this.isLast(["\n", " ", "[", "{"])) {
        this._push(" ");
        column++;
      }

      //
      if (comment.type === "Block" && this.format.indent.adjustMultilineComment) {
        var offset = comment.loc.start.column;
        if (offset) {
          var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
          val = val.replace(newlineRegex, "\n");
        }

        var indent = Math.max(this.indentSize(), column);
        val = val.replace(/\n/g, `\n${repeating(" ", indent)}`);
      }

      if (column === 0) {
        val = this.getIndent() + val;
      }

      // force a newline for line comments when retainLines is set in case the next printed node
      // doesn't catch up
      if (this.format.retainLines && comment.type === "Line") {
        val += "\n";
      }

      //
      this._push(val);

      // whitespace after
      this.newline(this.whitespace.getNewlinesAfter(comment));
    }
  }
}

each(Buffer.prototype, function (fn, key) {
  CodeGenerator.prototype[key] = function () {
    return fn.apply(this.buffer, arguments);
  };
});

each(CodeGenerator.generators, function (generator) {
  extend(CodeGenerator.prototype, generator);
});

module.exports = function (ast, opts, code) {
  var gen = new CodeGenerator(ast, opts, code);
  return gen.generate();
};

module.exports.CodeGenerator = CodeGenerator;
<|endoftext|>


<commit_before>weh.inspect = (function() {

    var inspectorId = null;

    browser.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
        switch(message.type) {
            case "weh#ping":
                inspectorId = sender.id;
                sendResponse({
                    type: "weh#pong",
                    version: 1,
                    manifest: browser.runtime.getManifest(),
                    monitorBgUi: exports.monitorBgUi
                });
                break;
            case "weh#monitor-bgui":
                exports.monitorBgUi = message.status;
                break;
        }
    });

    var exports = {
        monitorBgUi: false,
        send: function(message) {
            if(!inspectorId)
                return;
            message.timestamp = Date.now();
            browser.runtime.sendMessage(inspectorId,message);
        }
    }

    return exports;

})();
<commit_msg>fixed inspect message type<commit_after>weh.inspect = (function() {

    var inspectorId = null;

    browser.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
        switch(message.type) {
            case "weh#ping":
                inspectorId = sender.id;
                sendResponse({
                    type: "weh#pong",
                    version: 1,
                    manifest: browser.runtime.getManifest(),
                    monitorBgUi: exports.monitorBgUi
                });
                break;
            case "weh#inspect-bgui":
                exports.monitorBgUi = message.status;
                break;
        }
    });

    var exports = {
        monitorBgUi: false,
        send: function(message) {
            if(!inspectorId)
                return;
            message.timestamp = Date.now();
            browser.runtime.sendMessage(inspectorId,message);
        }
    }

    return exports;

})();
<|endoftext|>


<commit_before>
var BitmapText = (function () {

    var TextAlign = (function (t) {
        t[t.left = 0] = 'Left';
        t[t.center = 1] = 'Center';
        t[t.right = 2] = 'Right';
        return t;
    })({});

    var TextAnchor = (function (t) {
        t[t.topLeft = 0] = 'Top Left';
        t[t.topCenter = 1] = 'Top Center';
        t[t.topRight = 2] = 'Top Right';
        t[t.midLeft = 3] = 'Middle Left';
        t[t.midCenter = 4] = 'Middle Center';
        t[t.midRight = 5] = 'Middle Right';
        t[t.botLeft = 6] = 'Bottom Left';
        t[t.botCenter = 7] = 'Bottom Center';
        t[t.botRight = 8] = 'Bottom Right';
        return t;
    })({});

    //-- 增加 Bitmap Text 到 组件菜单上
    var BitmapText = Fire.define("Fire.BitmapText", Renderer, function () {
        Renderer.call(this);
        RenderContext.initRenderer(this);
    });

    BitmapText.TextAlign = TextAlign;
    BitmapText.TextAnchor = TextAnchor;

    //-- 增加 Bitmap Text 到 组件菜单上
    Fire.addComponentMenu(BitmapText, 'BitmapText');

    BitmapText.prop('_bitmapFont', null, Fire.HideInInspector);
    BitmapText.getset('bitmapFont',
        function () {
            return this._bitmapFont;
        },
        function (value) {
            if (this._bitmapFont !== value) {
                this._bitmapFont = value;
                this.face = this._bitmapFont ? this._bitmapFont.face : 'None';
                Engine._renderContext.setBitmapFont(this);
            }
        },
        Fire.ObjectType(Fire.BitmapFont)
    );

    BitmapText.prop('_text', 'hello\nworld!', Fire.HideInInspector);
    BitmapText.getset('text',
        function () {
            return this._text;
        },
        function (value) {
            if (this._text !== value) {
                this._text = value;
                Engine._renderContext.setText(this, value);
            }
        },
        Fire.MultiText
    );

    BitmapText.prop('_anchor', BitmapText.TextAnchor.midCenter, Fire.HideInInspector);
    BitmapText.getset('anchor',
        function () {
            return this._anchor;
        },
        function (value) {
            if (this._anchor !== value) {
                this._anchor = value;
            }
        },
        Fire.Enum(BitmapText.TextAnchor)
    );

    BitmapText.prop('_align', BitmapText.TextAlign.left, Fire.HideInInspector);
    BitmapText.getset('align',
        function () {
            return this._align;
        },
        function (value) {
            if (this._align !== value) {
                this._align = value;
                Engine._renderContext.setAlign(this, value);
            }
        },
        Fire.Enum(BitmapText.TextAlign)
    );

    BitmapText.prototype.onLoad = function () {
        Engine._renderContext.addBitmapText(this);
    };

    BitmapText.prototype.onEnable = function () {
        Engine._renderContext.show(this, true);
    };

    BitmapText.prototype.onDisable = function () {
        Engine._renderContext.show(this, false);
    };

    BitmapText.prototype.onDestroy = function () {
        Engine._renderContext.remove(this);
    };

    BitmapText.prototype.getWorldSize = function () {
        var size = new Fire.Vec2(0, 0);
        size.x = this._renderObj ? this._renderObj.textWidth : 0;
        size.y = this._renderObj ? this._renderObj.textHeight : 0;
        return size;
    };

    var tempMatrix = new Fire.Matrix23();

    BitmapText.prototype.onPreRender = function () {
        this.getSelfMatrix(tempMatrix);
        tempMatrix.prepend(this.transform._worldTransform);
        PixiBitmapFontUtil.updateTransform(this, tempMatrix);
    };

    BitmapText.prototype.getSelfMatrix = function (out) {
        var w = this._renderObj ? this._renderObj.textWidth : 0;
        var h = this._renderObj ? this._renderObj.textHeight : 0;

        var anchorOffset = {
            tx:0,
            ty:0
        };

        switch (this._anchor) {
            case BitmapText.TextAnchor.topLeft:
                anchorOffset.tx = 0;
                anchorOffset.ty = 0;
                break;
            case BitmapText.TextAnchor.topCenter:
                anchorOffset.tx -= w * 0.5;
                anchorOffset.ty = 0;
                break;
            case BitmapText.TextAnchor.topRight:
                anchorOffset.tx -= w;
                anchorOffset.ty = 0;
                break;
            case BitmapText.TextAnchor.midLeft:
                anchorOffset.tx = 0;
                anchorOffset.ty = h * (1.0 - 0.5);
                break;
            case BitmapText.TextAnchor.midCenter:
                anchorOffset.tx -= w * 0.5;
                anchorOffset.ty = h * (1.0 - 0.5);
                break;
            case BitmapText.TextAnchor.midRight:
                anchorOffset.tx -= w;
                anchorOffset.ty = h * (1.0 - 0.5) ;
                break;
            case BitmapText.TextAnchor.botLeft:
                anchorOffset.tx = 0;
                anchorOffset.ty = h;
                break;
            case BitmapText.TextAnchor.botCenter:
                anchorOffset.tx -= w * 0.5;
                anchorOffset.ty = h;
                break;
            case BitmapText.TextAnchor.botRight:
                anchorOffset.tx -= w;
                anchorOffset.ty = h;
                break;
            default:
                break;
        }
        out.a = 1;
        out.b = 0;
        out.c = 0;
        out.d = 1;
        out.tx = anchorOffset.tx;
        out.ty = anchorOffset.ty;
    };

    return BitmapText;
})();

Fire.BitmapText = BitmapText;
<commit_msg>修改 bitmap-text 初始化 文本<commit_after>
var BitmapText = (function () {

    var TextAlign = (function (t) {
        t[t.left = 0] = 'Left';
        t[t.center = 1] = 'Center';
        t[t.right = 2] = 'Right';
        return t;
    })({});

    var TextAnchor = (function (t) {
        t[t.topLeft = 0] = 'Top Left';
        t[t.topCenter = 1] = 'Top Center';
        t[t.topRight = 2] = 'Top Right';
        t[t.midLeft = 3] = 'Middle Left';
        t[t.midCenter = 4] = 'Middle Center';
        t[t.midRight = 5] = 'Middle Right';
        t[t.botLeft = 6] = 'Bottom Left';
        t[t.botCenter = 7] = 'Bottom Center';
        t[t.botRight = 8] = 'Bottom Right';
        return t;
    })({});

    //-- 增加 Bitmap Text 到 组件菜单上
    var BitmapText = Fire.define("Fire.BitmapText", Renderer, function () {
        Renderer.call(this);
        RenderContext.initRenderer(this);
    });

    BitmapText.TextAlign = TextAlign;
    BitmapText.TextAnchor = TextAnchor;

    //-- 增加 Bitmap Text 到 组件菜单上
    Fire.addComponentMenu(BitmapText, 'BitmapText');

    BitmapText.prop('_bitmapFont', null, Fire.HideInInspector);
    BitmapText.getset('bitmapFont',
        function () {
            return this._bitmapFont;
        },
        function (value) {
            if (this._bitmapFont !== value) {
                this._bitmapFont = value;
                this.face = this._bitmapFont ? this._bitmapFont.face : 'None';
                Engine._renderContext.setBitmapFont(this);
            }
        },
        Fire.ObjectType(Fire.BitmapFont)
    );

    BitmapText.prop('_text', 'Text', Fire.HideInInspector);
    BitmapText.getset('text',
        function () {
            return this._text;
        },
        function (value) {
            if (this._text !== value) {
                this._text = value;
                Engine._renderContext.setText(this, value);
            }
        },
        Fire.MultiText
    );

    BitmapText.prop('_anchor', BitmapText.TextAnchor.midCenter, Fire.HideInInspector);
    BitmapText.getset('anchor',
        function () {
            return this._anchor;
        },
        function (value) {
            if (this._anchor !== value) {
                this._anchor = value;
            }
        },
        Fire.Enum(BitmapText.TextAnchor)
    );

    BitmapText.prop('_align', BitmapText.TextAlign.left, Fire.HideInInspector);
    BitmapText.getset('align',
        function () {
            return this._align;
        },
        function (value) {
            if (this._align !== value) {
                this._align = value;
                Engine._renderContext.setAlign(this, value);
            }
        },
        Fire.Enum(BitmapText.TextAlign)
    );

    BitmapText.prototype.onLoad = function () {
        Engine._renderContext.addBitmapText(this);
    };

    BitmapText.prototype.onEnable = function () {
        Engine._renderContext.show(this, true);
    };

    BitmapText.prototype.onDisable = function () {
        Engine._renderContext.show(this, false);
    };

    BitmapText.prototype.onDestroy = function () {
        Engine._renderContext.remove(this);
    };

    BitmapText.prototype.getWorldSize = function () {
        var size = new Fire.Vec2(0, 0);
        size.x = this._renderObj ? this._renderObj.textWidth : 0;
        size.y = this._renderObj ? this._renderObj.textHeight : 0;
        return size;
    };

    var tempMatrix = new Fire.Matrix23();

    BitmapText.prototype.onPreRender = function () {
        this.getSelfMatrix(tempMatrix);
        tempMatrix.prepend(this.transform._worldTransform);
        PixiBitmapFontUtil.updateTransform(this, tempMatrix);
    };

    BitmapText.prototype.getSelfMatrix = function (out) {
        var w = this._renderObj ? this._renderObj.textWidth : 0;
        var h = this._renderObj ? this._renderObj.textHeight : 0;

        var anchorOffset = {
            tx:0,
            ty:0
        };

        switch (this._anchor) {
            case BitmapText.TextAnchor.topLeft:
                anchorOffset.tx = 0;
                anchorOffset.ty = 0;
                break;
            case BitmapText.TextAnchor.topCenter:
                anchorOffset.tx -= w * 0.5;
                anchorOffset.ty = 0;
                break;
            case BitmapText.TextAnchor.topRight:
                anchorOffset.tx -= w;
                anchorOffset.ty = 0;
                break;
            case BitmapText.TextAnchor.midLeft:
                anchorOffset.tx = 0;
                anchorOffset.ty = h * (1.0 - 0.5);
                break;
            case BitmapText.TextAnchor.midCenter:
                anchorOffset.tx -= w * 0.5;
                anchorOffset.ty = h * (1.0 - 0.5);
                break;
            case BitmapText.TextAnchor.midRight:
                anchorOffset.tx -= w;
                anchorOffset.ty = h * (1.0 - 0.5) ;
                break;
            case BitmapText.TextAnchor.botLeft:
                anchorOffset.tx = 0;
                anchorOffset.ty = h;
                break;
            case BitmapText.TextAnchor.botCenter:
                anchorOffset.tx -= w * 0.5;
                anchorOffset.ty = h;
                break;
            case BitmapText.TextAnchor.botRight:
                anchorOffset.tx -= w;
                anchorOffset.ty = h;
                break;
            default:
                break;
        }
        out.a = 1;
        out.b = 0;
        out.c = 0;
        out.d = 1;
        out.tx = anchorOffset.tx;
        out.ty = anchorOffset.ty;
    };

    return BitmapText;
})();

Fire.BitmapText = BitmapText;
<|endoftext|>


<commit_before>import _ from "lodash"
import umd from "umd"
import through from "through2"
import md5 from "md5"
import {readFileSync} from "fs"
import {resolve} from "path"
import convertSourceMaps from 'convert-source-map'
import offsetSourceMaps from 'offset-sourcemap-lines'
import {startServer} from "./server"
import {log} from "./console"
import loader from "../reloading"

function LiveReactloadPlugin(b, opts = {}) {
  const {
    port = 4474,
    host = null,
    client = true,
    dedupe = true,
    debug = false,
    basedir = process.cwd(),
    'ssl-cert': sslCert = null,
    'ssl-key': sslKey = null,
    } = opts

  // server is alive as long as watchify is running
  const server = opts.server !== false ? startServer({port: Number(port), sslCert, sslKey}) : null

  const clientOpts = {
    // assuming that livereload package is in global mdule directory (node_modules)
    // and this file is in ./lib/babel-plugin folder
    nodeModulesRoot: resolve(__dirname, "../../.."),
    port: Number(port),
    host: host,
    clientEnabled: client,
    debug: debug
  }

  b.on("reset", addHooks)
  addHooks()

  function addHooks() {
    // this cache object is preserved over single bundling
    // pipeline so when next bundling occurs, this cache
    // object is thrown away
    const mappings = {}, pathById = {}, pathByIdx = {}
    const entries = []
    let standalone = null

    const idToPath = id =>
      pathById[id] || (_.isString(id) && id) || throws("Full path not found for id: " + id)

    const idxToPath = idx =>
      pathByIdx[idx] || (_.isString(idx) && idx) || throws("Full path not found for index: " + idx)

    if (server) {
      b.pipeline.on("error", server.notifyBundleError)
    }

    b.pipeline.get("record").push(through.obj(
      function transform(row, enc, next) {
        const s = _.get(row, "options._flags.standalone")
        if (s) {
          standalone = s
        }
        next(null, row)
      }
    ))

    b.pipeline.get("sort").push(through.obj(
      function transform(row, enc, next) {
        const {id, index, file} = row
        pathById[id] = file
        pathByIdx[index] = file
        next(null, row)
      }
    ))

    if (!dedupe) {
      b.pipeline.splice("dedupe", 1, through.obj())
      if (b.pipeline.get("dedupe")) {
        log("Other plugins have added de-duplicate transformations. --no-dedupe is not effective")
      }
    } else {
      b.pipeline.splice("dedupe", 0, through.obj(
        function transform(row, enc, next) {
          const cloned = _.extend({}, row)
          if (row.dedupeIndex) {
            cloned.dedupeIndex = idxToPath(row.dedupeIndex)
          }
          if (row.dedupe) {
            cloned.dedupe = idToPath(row.dedupe)
          }
          next(null, cloned)
        }
      ))
    }

    b.pipeline.get("label").push(through.obj(
      function transform(row, enc, next) {
        const {id, file, source, deps, entry} = row
        const converter = convertSourceMaps.fromSource(source)
        let sourceWithoutMaps = source
        let adjustedSourcemap = ''
        let hash;

        if (converter) {
          sourceWithoutMaps = convertSourceMaps.removeComments(source)
          hash = md5(sourceWithoutMaps)
          converter.setProperty('sources', [file.replace(basedir, hash)])
          adjustedSourcemap = convertSourceMaps.fromObject(offsetSourceMaps(converter.toObject(), 1)).toComment()
        } else {
          hash = md5(source)
        }

        if (entry) {
          entries.push(file)
        }
        mappings[file] = [sourceWithoutMaps, deps, {id: file, hash: md5(sourceWithoutMaps), browserifyId: id, sourcemap: adjustedSourcemap}]
        next(null, row)
      },
      function flush(next) {
        next()
      }
    ))

    b.pipeline.get("wrap").push(through.obj(
      function transform(row, enc, next) {
        next(null)
      },
      function flush(next) {
        const pathById = _.fromPairs(_.toPairs(mappings).map(([file, [s, d, {browserifyId: id}]]) => [id, file]))
        const idToPath = id =>
          pathById[id] || (_.isString(id) && id)

        const depsToPaths = deps =>
          _.reduce(deps, (m, v, k) => {
            let id = idToPath(v);
            if (id) {
              m[k] = id;
            }
            return m;
          }, {})

        const withFixedDepsIds = _.mapValues(mappings, ([src, deps, meta]) => [
          src,
          depsToPaths(deps),
          meta
        ])
        const args = [
          withFixedDepsIds,
          entries,
          clientOpts
        ]
        let bundleSrc =
          `(${loader.toString()})(${args.map(a => JSON.stringify(a, null, 2)).join(", ")});`
        if (standalone) {
          bundleSrc = umd(standalone, `return ${bundleSrc}`)
        }

        this.push(new Buffer(bundleSrc, "utf8"))
        if (server) {
          server.notifyReload(withFixedDepsIds)
        }
        next()
      }
    ))
  }

  function throws(msg) {
    throw new Error(msg)
  }
}

module.exports = LiveReactloadPlugin
<commit_msg>Fix hash<commit_after>import _ from "lodash"
import umd from "umd"
import through from "through2"
import md5 from "md5"
import {readFileSync} from "fs"
import {resolve} from "path"
import convertSourceMaps from 'convert-source-map'
import offsetSourceMaps from 'offset-sourcemap-lines'
import {startServer} from "./server"
import {log} from "./console"
import loader from "../reloading"

function LiveReactloadPlugin(b, opts = {}) {
  const {
    port = 4474,
    host = null,
    client = true,
    dedupe = true,
    debug = false,
    basedir = process.cwd(),
    'ssl-cert': sslCert = null,
    'ssl-key': sslKey = null,
    } = opts

  // server is alive as long as watchify is running
  const server = opts.server !== false ? startServer({port: Number(port), sslCert, sslKey}) : null

  const clientOpts = {
    // assuming that livereload package is in global mdule directory (node_modules)
    // and this file is in ./lib/babel-plugin folder
    nodeModulesRoot: resolve(__dirname, "../../.."),
    port: Number(port),
    host: host,
    clientEnabled: client,
    debug: debug
  }

  b.on("reset", addHooks)
  addHooks()

  function addHooks() {
    // this cache object is preserved over single bundling
    // pipeline so when next bundling occurs, this cache
    // object is thrown away
    const mappings = {}, pathById = {}, pathByIdx = {}
    const entries = []
    let standalone = null

    const idToPath = id =>
      pathById[id] || (_.isString(id) && id) || throws("Full path not found for id: " + id)

    const idxToPath = idx =>
      pathByIdx[idx] || (_.isString(idx) && idx) || throws("Full path not found for index: " + idx)

    if (server) {
      b.pipeline.on("error", server.notifyBundleError)
    }

    b.pipeline.get("record").push(through.obj(
      function transform(row, enc, next) {
        const s = _.get(row, "options._flags.standalone")
        if (s) {
          standalone = s
        }
        next(null, row)
      }
    ))

    b.pipeline.get("sort").push(through.obj(
      function transform(row, enc, next) {
        const {id, index, file} = row
        pathById[id] = file
        pathByIdx[index] = file
        next(null, row)
      }
    ))

    if (!dedupe) {
      b.pipeline.splice("dedupe", 1, through.obj())
      if (b.pipeline.get("dedupe")) {
        log("Other plugins have added de-duplicate transformations. --no-dedupe is not effective")
      }
    } else {
      b.pipeline.splice("dedupe", 0, through.obj(
        function transform(row, enc, next) {
          const cloned = _.extend({}, row)
          if (row.dedupeIndex) {
            cloned.dedupeIndex = idxToPath(row.dedupeIndex)
          }
          if (row.dedupe) {
            cloned.dedupe = idToPath(row.dedupe)
          }
          next(null, cloned)
        }
      ))
    }

    b.pipeline.get("label").push(through.obj(
      function transform(row, enc, next) {
        const {id, file, source, deps, entry} = row
        const converter = convertSourceMaps.fromSource(source)
        let sourceWithoutMaps = source
        let adjustedSourcemap = ''
        let hash;

        if (converter) {
          sourceWithoutMaps = convertSourceMaps.removeComments(source)
          hash = md5(sourceWithoutMaps)
          converter.setProperty('sources', [file.replace(basedir, hash)])
          adjustedSourcemap = convertSourceMaps.fromObject(offsetSourceMaps(converter.toObject(), 1)).toComment()
        } else {
          hash = md5(source)
        }

        if (entry) {
          entries.push(file)
        }
        mappings[file] = [sourceWithoutMaps, deps, {id: file, hash: hash, browserifyId: id, sourcemap: adjustedSourcemap}]
        next(null, row)
      },
      function flush(next) {
        next()
      }
    ))

    b.pipeline.get("wrap").push(through.obj(
      function transform(row, enc, next) {
        next(null)
      },
      function flush(next) {
        const pathById = _.fromPairs(_.toPairs(mappings).map(([file, [s, d, {browserifyId: id}]]) => [id, file]))
        const idToPath = id =>
          pathById[id] || (_.isString(id) && id)

        const depsToPaths = deps =>
          _.reduce(deps, (m, v, k) => {
            let id = idToPath(v);
            if (id) {
              m[k] = id;
            }
            return m;
          }, {})

        const withFixedDepsIds = _.mapValues(mappings, ([src, deps, meta]) => [
          src,
          depsToPaths(deps),
          meta
        ])
        const args = [
          withFixedDepsIds,
          entries,
          clientOpts
        ]
        let bundleSrc =
          `(${loader.toString()})(${args.map(a => JSON.stringify(a, null, 2)).join(", ")});`
        if (standalone) {
          bundleSrc = umd(standalone, `return ${bundleSrc}`)
        }

        this.push(new Buffer(bundleSrc, "utf8"))
        if (server) {
          server.notifyReload(withFixedDepsIds)
        }
        next()
      }
    ))
  }

  function throws(msg) {
    throw new Error(msg)
  }
}

module.exports = LiveReactloadPlugin
<|endoftext|>